2 backend code for upgrading from Samba3
3 Copyright Jelmer Vernooij 2005
4 Released under the GNU GPL v2 or later
9 function regkey_to_dn(name)
14 var as = split("/", name);
18 dn = sprintf("key=%s,", as[i]) + dn;
25 /* Where prefix is any of:
33 function upgrade_registry(regdb,prefix,ldb)
35 assert(regdb != undefined);
36 var prefix_up = strupper(prefix);
37 var ldif = new Array();
39 for (var i in regdb.keys) {
40 var rk = regdb.keys[i];
41 var pts = split("/", rk.name);
43 /* Only handle selected hive */
44 if (strupper(pts[0]) != prefix_up) {
48 var keydn = regkey_to_dn(rk.name);
50 var pts = split("/", rk.name);
52 /* Convert key name to dn */
53 ldif[rk.name] = sprintf("
59 for (var j in rk.values) {
60 var rv = rk.values[j];
62 ldif[rk.name + " (" + rv.name + ")"] = sprintf("
66 data:: %s", keydn, rv.name, rv.name, rv.type, ldb.encode(rv.data));
73 function upgrade_sam_policy(samba3,dn)
84 samba3ResetCountMinutes: %d
85 samba3UserMustLogonToChangePassword: %d
86 samba3BadLockoutMinutes: %d
87 samba3DisconnectTime: %d
89 ", dn, samba3.policy.min_password_length,
90 samba3.policy.password_history, samba3.policy.minimum_password_age,
91 samba3.policy.maximum_password_age, samba3.policy.lockout_duration,
92 samba3.policy.reset_count_minutes, samba3.policy.user_must_logon_to_change_password,
93 samba3.policy.bad_lockout_minutes, samba3.policy.disconnect_time
99 function upgrade_sam_account(ldb,acc,domaindn,domainsid)
101 if (acc.nt_username == undefined) {
102 acc.nt_username = acc.username;
105 if (acc.nt_username == "") {
106 acc.nt_username = acc.username;
109 if (acc.fullname == undefined) {
110 var pw = nss.getpwnam(acc.fullname);
111 acc.fullname = pw.pw_gecos;
114 var pts = split(',', acc.fullname);
115 acc.fullname = pts[0];
117 if (acc.fullname == undefined) {
118 acc.fullname = acc.username;
121 assert(acc.fullname != undefined);
122 assert(acc.nt_username != undefined);
141 samba3LogonScript: %s
142 samba3ProfilePath: %s
143 samba3Workstations: %s
144 samba3KickOffTime: %d
146 samba3PassLastSetTime: %d
147 samba3PassCanChangeTime: %d
148 samba3PassMustChangeTime: %d
153 ", ldb.dn_escape(acc.fullname), domaindn, acc.logon_time, acc.logoff_time, acc.username, acc.nt_username, acc.nt_username,
155 acc.acct_desc, acc.group_rid, acc.bad_password_count, acc.logon_count,
156 acc.domain, acc.dir_drive, acc.munged_dial, acc.homedir, acc.logon_script,
157 acc.profile_path, acc.workstations, acc.kickoff_time, acc.bad_password_time,
158 acc.pass_last_set_time, acc.pass_can_change_time, acc.pass_must_change_time, domainsid, acc.user_rid,
159 ldb.encode(acc.lm_pw), ldb.encode(acc.nt_pw));
164 function upgrade_sam_group(grp,domaindn)
166 var nss = nss_init();
169 if (grp.sid_name_use == 5) { // Well-known group
173 if (grp.nt_name == "Domain Guests" ||
174 grp.nt_name == "Domain Users" ||
175 grp.nt_name == "Domain Admins") {
180 gr = nss.getgrnam(grp.nt_name);
182 gr = nss.getgrgid(grp.gid);
185 if (gr == undefined) {
186 grp.unixname = "UNKNOWN";
188 grp.unixname = gr.gr_name;
191 assert(grp.unixname != undefined);
202 ", grp.nt_name, domaindn,
203 grp.comment, grp.nt_name, grp.sid, grp.unixname, grp.sid_name_use);
208 function upgrade_winbind(samba3,domaindn)
216 ", samba3.idmap.user_hwm, samba3.idmap.group_hwm);
218 for (var i in samba3.idmap.mappings) {
219 var m = samba3.idmap.mappings[i];
220 ldif = ldif + sprintf("
224 unixID: %d", m.sid, domaindn, m.sid, m.type, m.unix_id);
231 function upgrade_wins(samba3)
236 for (i in samba3.winsentries) {
241 var e = samba3.winsentries[i];
242 var now = sys.nttime();
243 var ttl = sys.unix2nttime(e.ttl);
247 for (var i in e.ips) {
251 if (e.type == 0x1C) {
253 } else if (sys.bitAND(e.type, 0x80)) {
268 rState = 0x0;/* active */
270 rState = 0x1;/* released */
273 nType = (sys.bitAND(e.nb_flags,0x60)>>5);
275 ldif = ldif + sprintf("
276 dn: name=%s,type=0x%02X
279 objectClass: winsRecord
286 ", e.name, e.type, e.type, e.name,
287 rType, rState, nType,
288 sys.ldaptime(ttl), version_id);
290 for (var i in e.ips) {
291 ldif = ldif + sprintf("address: %s\n", e.ips[i]);
295 ldif = ldif + sprintf("
297 objectClass: winsMaxVersion
304 function upgrade_provision(samba3)
306 var subobj = new Object();
307 var nss = nss_init();
308 var lp = loadparm_init();
311 var domainname = samba3.configuration.get("workgroup");
313 if (domainname == undefined) {
314 domainname = samba3.secrets.domains[0].name;
315 println("No domain specified in smb.conf file, assuming '" + domainname + "'");
318 var domsec = samba3.find_domainsecrets(domainname);
319 var hostsec = samba3.find_domainsecrets(hostname());
320 var realm = samba3.configuration.get("realm");
322 if (realm == undefined) {
324 println("No realm specified in smb.conf file, assuming '" + realm + "'");
328 subobj.REALM = realm;
329 subobj.DOMAIN = domainname;
330 subobj.HOSTNAME = hostname();
332 assert(subobj.REALM);
333 assert(subobj.DOMAIN);
334 assert(subobj.HOSTNAME);
336 subobj.HOSTIP = hostip();
337 if (domsec != undefined) {
338 subobj.DOMAINGUID = domsec.guid;
339 subobj.DOMAINSID = domsec.sid;
341 println("Can't find domain secrets for '" + domainname + "'; using random SID and GUID");
342 subobj.DOMAINGUID = randguid();
343 subobj.DOMAINSID = randsid();
347 subobj.HOSTGUID = hostsec.guid;
349 subobj.HOSTGUID = randguid();
351 subobj.INVOCATIONID = randguid();
352 subobj.KRBTGTPASS = randpass(12);
353 subobj.MACHINEPASS = randpass(12);
354 subobj.ADMINPASS = randpass(12);
355 subobj.DEFAULTSITE = "Default-First-Site-Name";
356 subobj.NEWGUID = randguid;
357 subobj.NTTIME = nttime;
358 subobj.LDAPTIME = ldaptime;
359 subobj.DATESTRING = datestring;
360 subobj.USN = nextusn;
361 subobj.ROOT = findnss(nss.getpwnam, "root");
362 subobj.NOBODY = findnss(nss.getpwnam, "nobody");
363 subobj.NOGROUP = findnss(nss.getgrnam, "nogroup", "nobody");
364 subobj.WHEEL = findnss(nss.getgrnam, "wheel", "root");
365 subobj.USERS = findnss(nss.getgrnam, "users", "guest", "other");
366 subobj.DNSDOMAIN = strlower(subobj.REALM);
367 subobj.DNSNAME = sprintf("%s.%s",
368 strlower(subobj.HOSTNAME),
370 subobj.BASEDN = "DC=" + join(",DC=", split(".", subobj.REALM));
371 rdn_list = split(".", subobj.REALM);
375 smbconf_keep = new Array(
389 "bind interfaces only",
394 "obey pam restrictions",
402 "client NTLMv2 auth",
403 "client lanman auth",
404 "client plaintext auth",
424 "name resolve order",
433 "paranoid server security",
468 "winbind separator");
471 Remove configuration variables not present in Samba4
472 oldconf: Old configuration structure
473 mark: Whether removed configuration variables should be
474 kept in the new configuration as "samba3:<name>"
476 function upgrade_smbconf(oldconf,mark)
478 var data = oldconf.data();
479 var newconf = param_init();
481 for (var s in data) {
482 for (var p in data[s]) {
484 for (var k in smbconf_keep) {
485 if (smbconf_keep[k] == p) {
492 newconf.set(s, p, oldconf.get(s, p));
494 newconf.set(s, "samba3:"+p, oldconf.get(s,p));
499 if (oldconf.get("domain logons") == "True") {
500 newconf.set("server role", "domain controller");
502 if (oldconf.get("security") == "user") {
503 newconf.set("server role", "standalone");
505 newconf.set("server role", "member server");
512 function upgrade(subobj, samba3, message, paths, session_info, credentials)
515 var lp = loadparm_init();
516 var samdb = ldb_init();
517 samdb.session_info = session_info;
518 samdb.credentials = credentials;
519 var ok = samdb.connect(paths.samdb);
521 info.message("samdb connect failed: " + samdb.errstring() + "\n");
525 message("Writing configuration\n");
526 var newconf = upgrade_smbconf(samba3.configuration,true);
527 newconf.save(paths.smbconf);
529 message("Importing account policies\n");
530 var ldif = upgrade_sam_policy(samba3,subobj.BASEDN);
531 ok = samdb.modify(ldif);
533 message("samdb load failed: " + samdb.errstring() + "\n");
536 var regdb = ldb_init();
537 ok = regdb.connect(paths.hklm);
539 message("registry connect: " + regdb.errstring() + "\n");
543 ok = regdb.modify(sprintf("
544 dn: value=RefusePasswordChange,key=Parameters,key=Netlogon,key=Services,key=CurrentControlSet,key=System,HIVE=NONE
549 ", samba3.policy.refuse_machine_password_change));
551 message("registry load failed: " + regdb.errstring() + "\n");
555 message("Importing users\n");
556 for (var i in samba3.samaccounts) {
557 var msg = "... " + samba3.samaccounts[i].username;
558 var ldif = upgrade_sam_account(samdb,samba3.samaccounts[i],subobj.BASEDN,subobj.DOMAINSID);
559 ok = samdb.add(ldif);
560 if (!ok && samdb.errstring() != "Record exists") {
561 msg = msg + "... error: " + samdb.errstring();
567 message("Importing groups\n");
568 for (var i in samba3.groupmappings) {
569 var msg = "... " + samba3.groupmappings[i].nt_name;
570 var ldif = upgrade_sam_group(samba3.groupmappings[i],subobj.BASEDN);
571 if (ldif != undefined) {
572 ok = samdb.add(ldif);
573 if (!ok && samdb.errstring() != "Record exists") {
574 msg = msg + "... error: " + samdb.errstring();
581 message("Importing registry data\n");
582 var hives = new Array("hkcr","hkcu","hklm","hkpd","hku","hkpt");
583 for (var i in hives) {
585 message("... " + hn + "\n");
587 ok = regdb.connect(paths[hn]);
589 var ldif = upgrade_registry(samba3.registry, hn, regdb);
590 for (var j in ldif) {
591 var msg = "... ... " + j;
592 ok = regdb.add(ldif[j]);
593 if (!ok && regdb.errstring() != "Record exists") {
594 msg = msg + "... error: " + regdb.errstring();
602 message("Importing WINS data\n");
603 var winsdb = ldb_init();
604 ok = winsdb.connect(paths.winsdb);
608 var ldif = upgrade_wins(samba3);
609 ok = winsdb.add(ldif);
612 // figure out ldapurl, if applicable
613 var ldapurl = undefined;
614 var pdb = samba3.configuration.get_list("passdb backend");
615 if (pdb != undefined) {
617 if (strlen(pdb[b]) >= 7) {
618 if (substr(pdb[b], 0, 7) == "ldapsam") {
619 ldapurl = substr(pdb[b], 8);
625 // URL was not specified in passdb backend but ldap /is/ used
627 ldapurl = "ldap://" + samba3.configuration.get("ldap server");
630 // Enable samba3sam module if original passdb backend was ldap
631 if (ldapurl != undefined) {
632 message("Enabling Samba3 LDAP mappings for SAM database\n");
638 @LIST: samldb,operational,objectguid,rdn_name,samba3sam
641 message("Error enabling samba3sam module: " + samdb.errstring() + "\n");
645 ok = samdb.add(sprintf("
647 @MAP_URL: %s", ldapurl));
655 function upgrade_verify(subobj, samba3,paths,message)
657 message("Verifying account policies\n");
658 var samldb = ldb_init();
661 var ok = samldb.connect(paths.samdb);
664 for (var i in samba3.samaccounts) {
665 var msg = samldb.search("(&(sAMAccountName=" + samba3.samaccounts[i].nt_username + ")(objectclass=user))");
666 assert(msg.length >= 1);