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, session_info, credentials)
519 var lp = loadparm_init();
520 var samdb = ldb_init();
521 samdb.session_info = session_info;
522 samdb.credentials = credentials;
523 var ok = samdb.connect(paths.samdb);
525 info.message("samdb connect failed: " + samdb.errstring() + "\n");
529 message("Writing configuration\n");
530 var newconf = upgrade_smbconf(samba3.configuration,true);
531 newconf.save(paths.smbconf);
533 message("Importing account policies\n");
534 var ldif = upgrade_sam_policy(samba3,subobj.BASEDN);
535 ok = samdb.modify(ldif);
537 message("samdb load failed: " + samdb.errstring() + "\n");
540 var regdb = ldb_init();
541 ok = regdb.connect(paths.hklm);
543 message("registry connect: " + regdb.errstring() + "\n");
547 ok = regdb.modify(sprintf("
548 dn: value=RefusePasswordChange,key=Parameters,key=Netlogon,key=Services,key=CurrentControlSet,key=System,HIVE=NONE
553 ", samba3.policy.refuse_machine_password_change));
555 message("registry load failed: " + regdb.errstring() + "\n");
559 message("Importing users\n");
560 for (var i in samba3.samaccounts) {
561 var msg = "... " + samba3.samaccounts[i].username;
562 var ldif = upgrade_sam_account(samdb,samba3.samaccounts[i],subobj.BASEDN,subobj.DOMAINSID);
563 ok = samdb.add(ldif);
564 if (!ok && samdb.errstring() != "Record exists") {
565 msg = msg + "... error: " + samdb.errstring();
571 message("Importing groups\n");
572 for (var i in samba3.groupmappings) {
573 var msg = "... " + samba3.groupmappings[i].nt_name;
574 var ldif = upgrade_sam_group(samba3.groupmappings[i],subobj.BASEDN);
575 if (ldif != undefined) {
576 ok = samdb.add(ldif);
577 if (!ok && samdb.errstring() != "Record exists") {
578 msg = msg + "... error: " + samdb.errstring();
585 message("Importing registry data\n");
586 var hives = new Array("hkcr","hkcu","hklm","hkpd","hku","hkpt");
587 for (var i in hives) {
589 message("... " + hn + "\n");
591 ok = regdb.connect(paths[hn]);
593 var ldif = upgrade_registry(samba3.registry, hn, regdb);
594 for (var j in ldif) {
595 var msg = "... ... " + j;
596 ok = regdb.add(ldif[j]);
597 if (!ok && regdb.errstring() != "Record exists") {
598 msg = msg + "... error: " + regdb.errstring();
606 message("Importing WINS data\n");
607 var winsdb = ldb_init();
608 ok = winsdb.connect(paths.winsdb);
612 var ldif = upgrade_wins(samba3);
613 ok = winsdb.add(ldif);
616 // figure out ldapurl, if applicable
617 var ldapurl = undefined;
618 var pdb = samba3.configuration.get_list("passdb backend");
619 if (pdb != undefined) {
621 if (strlen(pdb[b]) >= 7) {
622 if (substr(pdb[b], 0, 7) == "ldapsam") {
623 ldapurl = substr(pdb[b], 8);
629 // URL was not specified in passdb backend but ldap /is/ used
631 ldapurl = "ldap://" + samba3.configuration.get("ldap server");
634 // Enable samba3sam module if original passdb backend was ldap
635 if (ldapurl != undefined) {
636 message("Enabling Samba3 LDAP mappings for SAM database\n");
642 @LIST: samldb,operational,objectguid,rdn_name,samba3sam
645 message("Error enabling samba3sam module: " + samdb.errstring() + "\n");
649 ok = samdb.add(sprintf("
651 @MAP_URL: %s", ldapurl));
659 function upgrade_verify(subobj, samba3,paths,message)
661 message("Verifying account policies\n");
662 var samldb = ldb_init();
665 var ok = samldb.connect(paths.samdb);
668 for (var i in samba3.samaccounts) {
669 var msg = samldb.search("(&(sAMAccountName=" + samba3.samaccounts[i].nt_username + ")(objectclass=user))");
670 assert(msg.length >= 1);