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 if (oldconf.get("domain master") == "True") {
501 newconf.set("server role", "pdc");
503 newconf.set("server role", "bdc");
506 if (oldconf.get("domain master") == "True") {
507 newconf.set("server role", "standalone");
509 newconf.set("server role", "member server");
516 function upgrade(subobj, samba3, message, paths)
519 var lp = loadparm_init();
520 var samdb = ldb_init();
521 var ok = samdb.connect(paths.samdb);
524 message("Writing configuration\n");
525 var newconf = upgrade_smbconf(samba3.configuration,true);
526 newconf.save(paths.smbconf);
528 message("Importing account policies\n");
529 var ldif = upgrade_sam_policy(samba3,subobj.BASEDN);
530 ok = samdb.modify(ldif);
533 var regdb = ldb_init();
534 ok = regdb.connect(paths.hklm);
536 ok = regdb.modify(sprintf("
537 dn: value=RefusePasswordChange,key=Parameters,key=Netlogon,key=Services,key=CurrentControlSet,key=System,HIVE=NONE
542 ", samba3.policy.refuse_machine_password_change));
545 message("Importing users\n");
546 for (var i in samba3.samaccounts) {
547 var msg = "... " + samba3.samaccounts[i].username;
548 var ldif = upgrade_sam_account(samdb,samba3.samaccounts[i],subobj.BASEDN,subobj.DOMAINSID);
549 ok = samdb.add(ldif);
550 if (!ok && samdb.errstring() != "Record exists") {
551 msg = msg + "... error: " + samdb.errstring();
557 message("Importing groups\n");
558 for (var i in samba3.groupmappings) {
559 var msg = "... " + samba3.groupmappings[i].nt_name;
560 var ldif = upgrade_sam_group(samba3.groupmappings[i],subobj.BASEDN);
561 if (ldif != undefined) {
562 ok = samdb.add(ldif);
563 if (!ok && samdb.errstring() != "Record exists") {
564 msg = msg + "... error: " + samdb.errstring();
571 message("Importing registry data\n");
572 var hives = new Array("hkcr","hkcu","hklm","hkpd","hku","hkpt");
573 for (var i in hives) {
575 message("... " + hn + "\n");
577 ok = regdb.connect(paths[hn]);
579 var ldif = upgrade_registry(samba3.registry, hn, regdb);
580 for (var j in ldif) {
581 var msg = "... ... " + j;
582 ok = regdb.add(ldif[j]);
583 if (!ok && regdb.errstring() != "Record exists") {
584 msg = msg + "... error: " + regdb.errstring();
592 message("Importing WINS data\n");
593 var winsdb = ldb_init();
594 ok = winsdb.connect(paths.winsdb);
598 var ldif = upgrade_wins(samba3);
599 ok = winsdb.add(ldif);
602 // figure out ldapurl, if applicable
603 var ldapurl = undefined;
604 var pdb = samba3.configuration.get_list("passdb backend");
605 if (pdb != undefined) {
607 if (strlen(pdb[b]) >= 7) {
608 if (substr(pdb[b], 0, 7) == "ldapsam") {
609 ldapurl = substr(pdb[b], 8);
615 // URL was not specified in passdb backend but ldap /is/ used
617 ldapurl = "ldap://" + samba3.configuration.get("ldap server");
620 // Enable samba3sam module if original passdb backend was ldap
621 if (ldapurl != undefined) {
622 message("Enabling Samba3 LDAP mappings for SAM database\n");
628 @LIST: samldb,operational,objectguid,rdn_name,samba3sam
631 message("Error enabling samba3sam module: " + samdb.errstring() + "\n");
635 ok = samdb.add(sprintf("
637 @MAP_URL: %s", ldapurl));
645 function upgrade_verify(subobj, samba3,paths,message)
647 message("Verifying account policies\n");
648 var samldb = ldb_init();
651 var ok = samldb.connect(paths.samdb);
654 for (var i in samba3.samaccounts) {
655 var msg = samldb.search("(&(sAMAccountName=" + samba3.samaccounts[i].nt_username + ")(objectclass=user))");
656 assert(msg.length >= 1);