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);
142 samba3LogonScript: %s
143 samba3ProfilePath: %s
144 samba3Workstations: %s
145 samba3KickOffTime: %d
147 samba3PassLastSetTime: %d
148 samba3PassCanChangeTime: %d
149 samba3PassMustChangeTime: %d
154 ", ldb.dn_escape(acc.fullname), domaindn, acc.logon_time, acc.logoff_time, acc.username, acc.nt_username, acc.nt_username,
156 acc.fullname, acc.acct_desc, acc.group_rid, acc.bad_password_count, acc.logon_count,
157 acc.domain, acc.dir_drive, acc.munged_dial, acc.homedir, acc.logon_script,
158 acc.profile_path, acc.workstations, acc.kickoff_time, acc.bad_password_time,
159 acc.pass_last_set_time, acc.pass_can_change_time, acc.pass_must_change_time, domainsid, acc.user_rid,
160 ldb.encode(acc.lm_pw), ldb.encode(acc.nt_pw));
165 function upgrade_sam_group(grp,domaindn)
167 var nss = nss_init();
170 if (grp.sid_name_use == 5) { // Well-known group
174 if (grp.nt_name == "Domain Guests" ||
175 grp.nt_name == "Domain Users" ||
176 grp.nt_name == "Domain Admins") {
181 gr = nss.getgrnam(grp.nt_name);
183 gr = nss.getgrgid(grp.gid);
186 if (gr == undefined) {
187 grp.unixname = "UNKNOWN";
189 grp.unixname = gr.gr_name;
192 assert(grp.unixname != undefined);
203 ", grp.nt_name, domaindn,
204 grp.comment, grp.nt_name, grp.sid, grp.unixname, grp.sid_name_use);
209 function upgrade_winbind(samba3,domaindn)
217 ", samba3.idmap.user_hwm, samba3.idmap.group_hwm);
219 for (var i in samba3.idmap.mappings) {
220 var m = samba3.idmap.mappings[i];
221 ldif = ldif + sprintf("
225 unixID: %d", m.sid, domaindn, m.sid, m.type, m.unix_id);
232 function upgrade_wins(samba3)
237 for (i in samba3.winsentries) {
242 var e = samba3.winsentries[i];
243 var now = sys.nttime();
244 var ttl = sys.unix2nttime(e.ttl);
248 for (var i in e.ips) {
252 if (e.type == 0x1C) {
254 } else if (sys.bitAND(e.type, 0x80)) {
269 rState = 0x0;/* active */
271 rState = 0x1;/* released */
274 nType = (sys.bitAND(e.nb_flags,0x60)>>5);
276 ldif = ldif + sprintf("
277 dn: name:%s,type=0x%02X
280 objectClass: winsRecord
287 ", e.name, e.type, e.type, e.name,
288 rType, rState, nType,
289 sys.ldaptime(ttl), version_id);
291 for (var i in e.ips) {
292 ldif = ldif + sprintf("address: %s\n", e.ips[i]);
296 ldif = ldif + sprintf("
298 objectClass: winsMaxVersion
305 function upgrade_provision(samba3)
307 var subobj = new Object();
308 var nss = nss_init();
309 var lp = loadparm_init();
312 var domainname = samba3.configuration.get("workgroup");
314 if (domainname == undefined) {
315 domainname = samba3.secrets.domains[0].name;
316 println("No domain specified in smb.conf file, assuming '" + domainname + "'");
319 var domsec = samba3.find_domainsecrets(domainname);
320 var hostsec = samba3.find_domainsecrets(hostname());
321 var realm = samba3.configuration.get("realm");
323 if (realm == undefined) {
325 println("No realm specified in smb.conf file, assuming '" + realm + "'");
329 subobj.REALM = realm;
330 subobj.DOMAIN = domainname;
331 subobj.HOSTNAME = hostname();
333 assert(subobj.REALM);
334 assert(subobj.DOMAIN);
335 assert(subobj.HOSTNAME);
337 subobj.HOSTIP = hostip();
338 if (domsec != undefined) {
339 subobj.DOMAINGUID = domsec.guid;
340 subobj.DOMAINSID = domsec.sid;
342 println("Can't find domain secrets for '" + domainname + "'; using random SID and GUID");
343 subobj.DOMAINGUID = randguid();
344 subobj.DOMAINSID = randsid();
348 subobj.HOSTGUID = hostsec.guid;
350 subobj.HOSTGUID = randguid();
352 subobj.INVOCATIONID = randguid();
353 subobj.KRBTGTPASS = randpass(12);
354 subobj.MACHINEPASS = randpass(12);
355 subobj.ADMINPASS = randpass(12);
356 subobj.DEFAULTSITE = "Default-First-Site-Name";
357 subobj.NEWGUID = randguid;
358 subobj.NTTIME = nttime;
359 subobj.LDAPTIME = ldaptime;
360 subobj.DATESTRING = datestring;
361 subobj.USN = nextusn;
362 subobj.ROOT = findnss(nss.getpwnam, "root");
363 subobj.NOBODY = findnss(nss.getpwnam, "nobody");
364 subobj.NOGROUP = findnss(nss.getgrnam, "nogroup", "nobody");
365 subobj.WHEEL = findnss(nss.getgrnam, "wheel", "root");
366 subobj.USERS = findnss(nss.getgrnam, "users", "guest", "other");
367 subobj.DNSDOMAIN = strlower(subobj.REALM);
368 subobj.DNSNAME = sprintf("%s.%s",
369 strlower(subobj.HOSTNAME),
371 subobj.BASEDN = "DC=" + join(",DC=", split(".", subobj.REALM));
372 rdn_list = split(".", subobj.REALM);
376 smbconf_keep = new Array(
390 "bind interfaces only",
395 "obey pam restrictions",
403 "client NTLMv2 auth",
404 "client lanman auth",
405 "client plaintext auth",
425 "name resolve order",
434 "paranoid server security",
469 "winbind separator");
472 Remove configuration variables not present in Samba4
473 oldconf: Old configuration structure
474 mark: Whether removed configuration variables should be
475 kept in the new configuration as "samba3:<name>"
477 function upgrade_smbconf(oldconf,mark)
479 var data = oldconf.data();
480 var newconf = param_init();
482 for (var s in data) {
483 for (var p in data[s]) {
485 for (var k in smbconf_keep) {
486 if (smbconf_keep[k] == p) {
493 newconf.set(s, p, oldconf.get(s, p));
495 newconf.set(s, "samba3:"+p, oldconf.get(s,p));
500 if (oldconf.get("domain logons") == "True") {
501 if (oldconf.get("domain master") == "True") {
502 newconf.set("role", "pdc");
504 newconf.set("role", "bdc");
507 if (oldconf.get("domain master") == "True") {
508 newconf.set("role", "standalone");
510 newconf.set("role", "member server");
517 function upgrade(subobj, samba3, message, paths)
520 var lp = loadparm_init();
521 var samdb = ldb_init();
522 var ok = samdb.connect(paths.samdb);
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);
534 var regdb = ldb_init();
535 ok = regdb.connect(paths.hklm);
537 ok = regdb.modify(sprintf("
538 dn: value=RefusePasswordChange,key=Parameters,key=Netlogon,key=Services,key=CurrentControlSet,key=System,HIVE=NONE
543 ", samba3.policy.refuse_machine_password_change));
546 message("Importing users\n");
547 for (var i in samba3.samaccounts) {
548 var msg = "... " + samba3.samaccounts[i].username;
549 var ldif = upgrade_sam_account(samdb,samba3.samaccounts[i],subobj.BASEDN,subobj.DOMAINSID);
550 ok = samdb.add(ldif);
551 if (!ok && samdb.errstring() != "Record exists") {
552 msg = msg + "... error: " + samdb.errstring();
558 message("Importing groups\n");
559 for (var i in samba3.groupmappings) {
560 var msg = "... " + samba3.groupmappings[i].nt_name;
561 var ldif = upgrade_sam_group(samba3.groupmappings[i],subobj.BASEDN);
562 if (ldif != undefined) {
563 ok = samdb.add(ldif);
564 if (!ok && samdb.errstring() != "Record exists") {
565 msg = msg + "... error: " + samdb.errstring();
572 message("Importing registry data\n");
573 var hives = new Array("hkcr","hkcu","hklm","hkpd","hku","hkpt");
574 for (var i in hives) {
576 message("... " + hn + "\n");
578 ok = regdb.connect(paths[hn]);
580 var ldif = upgrade_registry(samba3.registry, hn, regdb);
581 for (var j in ldif) {
582 var msg = "... ... " + j;
583 ok = regdb.add(ldif[j]);
584 if (!ok && regdb.errstring() != "Record exists") {
585 msg = msg + "... error: " + regdb.errstring();
593 message("Importing WINS data\n");
594 var winsdb = ldb_init();
595 ok = winsdb.connect(paths.winsdb);
599 var ldif = upgrade_wins(samba3);
600 ok = winsdb.add(ldif);
603 // figure out ldapurl, if applicable
604 var ldapurl = undefined;
605 var pdb = samba3.configuration.get_list("passdb backend");
606 if (pdb != undefined) {
608 if (strlen(pdb[b]) >= 7) {
609 if (substr(pdb[b], 0, 7) == "ldapsam") {
610 ldapurl = substr(pdb[b], 8);
616 // URL was not specified in passdb backend but ldap /is/ used
618 ldapurl = "ldap://" + samba3.configuration.get("ldap server");
621 // Enable samba3sam module if original passdb backend was ldap
622 if (ldapurl != undefined) {
623 message("Enabling Samba3 LDAP mappings for SAM database\n");
629 @LIST: samldb,operational,objectguid,rdn_name,samba3sam
632 message("Error enabling samba3sam module: " + samdb.errstring() + "\n");
636 ok = samdb.add(sprintf("
638 @MAP_URL: %s", ldapurl));
646 function upgrade_verify(subobj, samba3,paths,message)
648 message("Verifying account policies\n");
649 var samldb = ldb_init();
652 var ok = samldb.connect(paths.samdb);
655 for (var i in samba3.samaccounts) {
656 var msg = samldb.search("(&(sAMAccountName=" + samba3.samaccounts[i].nt_username + ")(objectclass=user))");
657 assert(msg.length >= 1);