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 assert(acc.fullname != undefined);
118 assert(acc.nt_username != undefined);
138 samba3LogonScript: %s
139 samba3ProfilePath: %s
140 samba3Workstations: %s
141 samba3KickOffTime: %d
143 samba3PassLastSetTime: %d
144 samba3PassCanChangeTime: %d
145 samba3PassMustChangeTime: %d
150 ", acc.fullname, domaindn, acc.logon_time, acc.logoff_time, acc.username, acc.nt_username, acc.nt_username,
152 acc.fullname, acc.acct_desc, acc.group_rid, acc.bad_password_count, acc.logon_count,
153 acc.domain, acc.dir_drive, acc.munged_dial, acc.homedir, acc.logon_script,
154 acc.profile_path, acc.workstations, acc.kickoff_time, acc.bad_password_time,
155 acc.pass_last_set_time, acc.pass_can_change_time, acc.pass_must_change_time, domainsid, acc.user_rid,
156 ldb.encode(acc.lm_pw), ldb.encode(acc.nt_pw));
161 function upgrade_sam_group(grp,domaindn)
163 var nss = nss_init();
166 if (grp.sid_name_use == 5) { // Well-known group
170 if (grp.nt_name == "Domain Guests" ||
171 grp.nt_name == "Domain Users" ||
172 grp.nt_name == "Domain Admins") {
177 gr = nss.getgrnam(grp.nt_name);
179 gr = nss.getgrgid(grp.gid);
182 if (gr == undefined) {
183 grp.unixname = "UNKNOWN";
185 grp.unixname = gr.gr_name;
188 assert(grp.unixname != undefined);
199 ", grp.nt_name, domaindn,
200 grp.comment, grp.nt_name, grp.sid, grp.unixname, grp.sid_name_use);
205 function upgrade_winbind(samba3,domaindn)
213 ", samba3.idmap.user_hwm, samba3.idmap.group_hwm);
215 for (var i in samba3.idmap.mappings) {
216 var m = samba3.idmap.mappings[i];
217 ldif = ldif + sprintf("
221 unixID: %d", m.sid, domaindn, m.sid, m.type, m.unix_id);
228 function upgrade_wins(samba3)
231 for (i in samba3.winsentries) {
232 var e = samba3.winsentries[i];
234 ldif = ldif + sprintf("
240 ", e.type, e.name, e.name, e.type, e.nb_flags, sys.ldaptime(e.ttl));
242 for (var i in e.ips) {
243 ldif = ldif + sprintf("address: %s\n", e.ips[i]);
250 function upgrade_provision(samba3)
252 var subobj = new Object();
253 var nss = nss_init();
254 var lp = loadparm_init();
257 var domainname = samba3.configuration.get("workgroup");
259 if (domainname == undefined) {
260 domainname = samba3.secrets.domains[0].name;
261 println("No domain specified in smb.conf file, assuming '" + domainname + "'");
264 var domsec = samba3.find_domainsecrets(domainname);
265 var hostsec = samba3.find_domainsecrets(hostname());
266 var realm = samba3.configuration.get("realm");
268 if (realm == undefined) {
270 println("No realm specified in smb.conf file, assuming '" + realm + "'");
274 subobj.REALM = realm;
275 subobj.DOMAIN = domainname;
276 subobj.HOSTNAME = hostname();
278 assert(subobj.REALM);
279 assert(subobj.DOMAIN);
280 assert(subobj.HOSTNAME);
282 subobj.HOSTIP = hostip();
283 if (domsec != undefined) {
284 subobj.DOMAINGUID = domsec.guid;
285 subobj.DOMAINSID = domsec.sid;
287 println("Can't find domain secrets for '" + domainname + "'; using random SID and GUID");
288 subobj.DOMAINGUID = randguid();
289 subobj.DOMAINSID = randsid();
293 subobj.HOSTGUID = hostsec.guid;
295 subobj.HOSTGUID = randguid();
297 subobj.INVOCATIONID = randguid();
298 subobj.KRBTGTPASS = randpass(12);
299 subobj.MACHINEPASS = randpass(12);
300 subobj.ADMINPASS = randpass(12);
301 subobj.DEFAULTSITE = "Default-First-Site-Name";
302 subobj.NEWGUID = randguid;
303 subobj.NTTIME = nttime;
304 subobj.LDAPTIME = ldaptime;
305 subobj.DATESTRING = datestring;
306 subobj.USN = nextusn;
307 subobj.ROOT = findnss(nss.getpwnam, "root");
308 subobj.NOBODY = findnss(nss.getpwnam, "nobody");
309 subobj.NOGROUP = findnss(nss.getgrnam, "nogroup", "nobody");
310 subobj.WHEEL = findnss(nss.getgrnam, "wheel", "root");
311 subobj.USERS = findnss(nss.getgrnam, "users", "guest", "other");
312 subobj.DNSDOMAIN = strlower(subobj.REALM);
313 subobj.DNSNAME = sprintf("%s.%s",
314 strlower(subobj.HOSTNAME),
316 subobj.BASEDN = "DC=" + join(",DC=", split(".", subobj.REALM));
317 rdn_list = split(".", subobj.REALM);
321 smbconf_keep = new Array(
335 "bind interfaces only",
340 "obey pam restrictions",
348 "client NTLMv2 auth",
349 "client lanman auth",
350 "client plaintext auth",
370 "name resolve order",
379 "paranoid server security",
414 "winbind separator");
417 Remove configuration variables not present in Samba4
418 oldconf: Old configuration structure
419 mark: Whether removed configuration variables should be
420 kept in the new configuration as "samba3:<name>"
422 function upgrade_smbconf(oldconf,mark)
424 var data = oldconf.data();
425 var newconf = param_init();
427 for (var s in data) {
428 for (var p in data[s]) {
430 for (var k in smbconf_keep) {
431 if (smbconf_keep[k] == p) {
438 newconf.set(s, p, oldconf.get(s, p));
440 newconf.set(s, "samba3:"+p, oldconf.get(s,p));
445 if (oldconf.get("domain logons") == "True") {
446 if (oldconf.get("domain master") == "True") {
447 newconf.set("role", "pdc");
449 newconf.set("role", "bdc");
452 if (oldconf.get("domain master") == "True") {
453 newconf.set("role", "standalone");
455 newconf.set("role", "member server");
462 function upgrade(subobj, samba3, message, paths)
465 var lp = loadparm_init();
466 var samdb = ldb_init();
467 var ok = samdb.connect(paths.samdb);
470 message("Writing configuration\n");
471 var newconf = upgrade_smbconf(samba3.configuration,true);
472 newconf.save(paths.smbconf);
474 message("Importing account policies\n");
475 var ldif = upgrade_sam_policy(samba3,subobj.BASEDN);
476 ok = samdb.modify(ldif);
479 var regdb = ldb_init();
480 ok = regdb.connect(paths.hklm);
482 ok = regdb.modify(sprintf("
483 dn: value=RefusePasswordChange,key=Parameters,key=Netlogon,key=Services,key=CurrentControlSet,key=System,HIVE=NONE
488 ", samba3.policy.refuse_machine_password_change));
491 message("Importing users\n");
492 for (var i in samba3.samaccounts) {
493 var msg = "... " + samba3.samaccounts[i].username;
494 var ldif = upgrade_sam_account(samdb,samba3.samaccounts[i],subobj.BASEDN,subobj.DOMAINSID);
495 ok = samdb.add(ldif);
496 if (!ok && samdb.errstring() != "Record exists") {
497 msg = msg + "... error: " + samdb.errstring();
503 message("Importing groups\n");
504 for (var i in samba3.groupmappings) {
505 var msg = "... " + samba3.groupmappings[i].nt_name;
506 var ldif = upgrade_sam_group(samba3.groupmappings[i],subobj.BASEDN);
507 if (ldif != undefined) {
508 ok = samdb.add(ldif);
509 if (!ok && samdb.errstring() != "Record exists") {
510 msg = msg + "... error: " + samdb.errstring();
517 message("Importing registry data\n");
518 var hives = new Array("hkcr","hkcu","hklm","hkpd","hku","hkpt");
519 for (var i in hives) {
521 message("... " + hn + "\n");
523 ok = regdb.connect(paths[hn]);
525 var ldif = upgrade_registry(samba3.registry, hn, regdb);
526 for (var j in ldif) {
527 var msg = "... ... " + j;
528 ok = regdb.add(ldif[j]);
529 if (!ok && regdb.errstring() != "Record exists") {
530 msg = msg + "... error: " + regdb.errstring();
538 message("Importing WINS data\n");
539 var winsdb = ldb_init();
540 ok = winsdb.connect(paths.winsdb);
544 var ldif = upgrade_wins(samba3);
545 ok = winsdb.add(ldif);
548 // figure out ldapurl, if applicable
549 var ldapurl = undefined;
550 var pdb = samba3.configuration.get_list("passdb backend");
551 if (pdb != undefined) {
553 if (substr(pdb[b], 0, 7) == "ldapsam") {
554 ldapurl = substr(pdb[b], 8);
559 // URL was not specified in passdb backend but ldap /is/ used
561 ldapurl = "ldap://" + samba3.configuration.get("ldap server");
564 // Enable samba3sam module if original passdb backend was ldap
565 if (ldapurl != undefined) {
566 message("Enabling Samba3 LDAP mappings for SAM database\n");
572 @LIST: samldb,timestamps,objectguid,rdn_name,samba3sam
575 message("Error enabling samba3sam module: " + samdb.errstring() + "\n");
579 ok = samdb.add(sprintf("
581 @MAP_URL: %s", ldapurl));
589 function upgrade_verify(subobj, samba3,paths,message)
591 message("Verifying account policies\n");
592 var samldb = ldb_init();
595 var ok = samldb.connect(paths.samdb);
598 for (var i in samba3.samaccounts) {
599 var msg = samldb.search("(&(sAMAccountName=" + samba3.samaccounts[i].nt_username + ")(objectclass=user))");
600 assert(msg.length >= 1);