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.ROOT = findnss(nss.getpwnam, "root");
361 subobj.NOBODY = findnss(nss.getpwnam, "nobody");
362 subobj.NOGROUP = findnss(nss.getgrnam, "nogroup", "nobody");
363 subobj.WHEEL = findnss(nss.getgrnam, "wheel", "root");
364 subobj.USERS = findnss(nss.getgrnam, "users", "guest", "other");
365 subobj.DNSDOMAIN = strlower(subobj.REALM);
366 subobj.DNSNAME = sprintf("%s.%s",
367 strlower(subobj.HOSTNAME),
369 subobj.BASEDN = "DC=" + join(",DC=", split(".", subobj.REALM));
370 rdn_list = split(".", subobj.DNSDOMAIN);
371 subobj.DOMAINDN = "DC=" + join(",DC=", rdn_list);
372 subobj.DOMAINDN_LDB = "users.ldb";
373 subobj.ROOTDN = subobj.DOMAINDN;
375 modules_list = new Array("rootdse",
388 subobj.MODULES_LIST = join(",", modules_list);
393 smbconf_keep = new Array(
407 "bind interfaces only",
412 "obey pam restrictions",
420 "client NTLMv2 auth",
421 "client lanman auth",
422 "client plaintext auth",
442 "name resolve order",
451 "paranoid server security",
486 "winbind separator");
489 Remove configuration variables not present in Samba4
490 oldconf: Old configuration structure
491 mark: Whether removed configuration variables should be
492 kept in the new configuration as "samba3:<name>"
494 function upgrade_smbconf(oldconf,mark)
496 var data = oldconf.data();
497 var newconf = param_init();
499 for (var s in data) {
500 for (var p in data[s]) {
502 for (var k in smbconf_keep) {
503 if (smbconf_keep[k] == p) {
510 newconf.set(s, p, oldconf.get(s, p));
512 newconf.set(s, "samba3:"+p, oldconf.get(s,p));
517 if (oldconf.get("domain logons") == "True") {
518 newconf.set("server role", "domain controller");
520 if (oldconf.get("security") == "user") {
521 newconf.set("server role", "standalone");
523 newconf.set("server role", "member server");
530 function upgrade(subobj, samba3, message, paths, session_info, credentials)
533 var lp = loadparm_init();
534 var samdb = ldb_init();
535 samdb.session_info = session_info;
536 samdb.credentials = credentials;
537 var ok = samdb.connect(paths.samdb);
539 info.message("samdb connect failed: " + samdb.errstring() + "\n");
543 message("Writing configuration\n");
544 var newconf = upgrade_smbconf(samba3.configuration,true);
545 newconf.save(paths.smbconf);
547 message("Importing account policies\n");
548 var ldif = upgrade_sam_policy(samba3,subobj.BASEDN);
549 ok = samdb.modify(ldif);
551 message("samdb load failed: " + samdb.errstring() + "\n");
554 var regdb = ldb_init();
555 ok = regdb.connect(paths.hklm);
557 message("registry connect: " + regdb.errstring() + "\n");
561 ok = regdb.modify(sprintf("
562 dn: value=RefusePasswordChange,key=Parameters,key=Netlogon,key=Services,key=CurrentControlSet,key=System,HIVE=NONE
567 ", samba3.policy.refuse_machine_password_change));
569 message("registry load failed: " + regdb.errstring() + "\n");
573 message("Importing users\n");
574 for (var i in samba3.samaccounts) {
575 var msg = "... " + samba3.samaccounts[i].username;
576 var ldif = upgrade_sam_account(samdb,samba3.samaccounts[i],subobj.BASEDN,subobj.DOMAINSID);
577 ok = samdb.add(ldif);
578 if (!ok && samdb.errstring() != "Record exists") {
579 msg = msg + "... error: " + samdb.errstring();
585 message("Importing groups\n");
586 for (var i in samba3.groupmappings) {
587 var msg = "... " + samba3.groupmappings[i].nt_name;
588 var ldif = upgrade_sam_group(samba3.groupmappings[i],subobj.BASEDN);
589 if (ldif != undefined) {
590 ok = samdb.add(ldif);
591 if (!ok && samdb.errstring() != "Record exists") {
592 msg = msg + "... error: " + samdb.errstring();
599 message("Importing registry data\n");
600 var hives = new Array("hkcr","hkcu","hklm","hkpd","hku","hkpt");
601 for (var i in hives) {
603 message("... " + hn + "\n");
605 ok = regdb.connect(paths[hn]);
607 var ldif = upgrade_registry(samba3.registry, hn, regdb);
608 for (var j in ldif) {
609 var msg = "... ... " + j;
610 ok = regdb.add(ldif[j]);
611 if (!ok && regdb.errstring() != "Record exists") {
612 msg = msg + "... error: " + regdb.errstring();
620 message("Importing WINS data\n");
621 var winsdb = ldb_init();
622 ok = winsdb.connect(paths.winsdb);
626 var ldif = upgrade_wins(samba3);
627 ok = winsdb.add(ldif);
630 // figure out ldapurl, if applicable
631 var ldapurl = undefined;
632 var pdb = samba3.configuration.get_list("passdb backend");
633 if (pdb != undefined) {
635 if (strlen(pdb[b]) >= 7) {
636 if (substr(pdb[b], 0, 7) == "ldapsam") {
637 ldapurl = substr(pdb[b], 8);
643 // URL was not specified in passdb backend but ldap /is/ used
645 ldapurl = "ldap://" + samba3.configuration.get("ldap server");
648 // Enable samba3sam module if original passdb backend was ldap
649 if (ldapurl != undefined) {
650 message("Enabling Samba3 LDAP mappings for SAM database\n");
656 @LIST: samldb,operational,objectguid,rdn_name,samba3sam
659 message("Error enabling samba3sam module: " + samdb.errstring() + "\n");
663 ok = samdb.add(sprintf("
665 @MAP_URL: %s", ldapurl));
673 function upgrade_verify(subobj, samba3,paths,message)
675 message("Verifying account policies\n");
676 var samldb = ldb_init();
679 var ok = samldb.connect(paths.samdb);
682 for (var i in samba3.samaccounts) {
683 var msg = samldb.search("(&(sAMAccountName=" + samba3.samaccounts[i].nt_username + ")(objectclass=user))");
684 assert(msg.length >= 1);