r20689: "pdc" and "bdc" have been replaced by "domain controller"
[ira/wip.git] / source / scripting / libjs / upgrade.js
index 0b5a71e50c935682b2be6af9fab4895912d3c107..adb958a236d8be121c78edd297e41c6eadd8e810 100644 (file)
@@ -30,7 +30,7 @@ function regkey_to_dn(name)
  *   HKPT
  */
 
-function upgrade_registry(regdb,prefix)
+function upgrade_registry(regdb,prefix,ldb)
 {
        assert(regdb != undefined);
        var prefix_up = strupper(prefix);
@@ -63,7 +63,7 @@ name: %s
 dn: %s,value=%s
 value: %s
 type: %d
-data:: %s", keydn, rv.value, rv.type, base64(rv.data));
+data:: %s", keydn, rv.name, rv.name, rv.type, ldb.encode(rv.data));
                }
        }
 
@@ -85,31 +85,50 @@ samba3ResetCountMinutes: %d
 samba3UserMustLogonToChangePassword: %d
 samba3BadLockoutMinutes: %d
 samba3DisconnectTime: %d
-samba3RefuseMachinePwdChange: %d
 
 ", dn, samba3.policy.min_password_length, 
        samba3.policy.password_history, samba3.policy.minimum_password_age,
        samba3.policy.maximum_password_age, samba3.policy.lockout_duration,
        samba3.policy.reset_count_minutes, samba3.policy.user_must_logon_to_change_password,
-       samba3.policy.bad_lockout_minutes, samba3.policy.disconnect_time, 
-       samba3.policy.refuse_machine_password_change
+       samba3.policy.bad_lockout_minutes, samba3.policy.disconnect_time
 );
-
+       
        return ldif;
 }
 
-function upgrade_sam_account(acc,domaindn)
+function upgrade_sam_account(ldb,acc,domaindn,domainsid)
 {
-       var ldb = ldb_init();
+       if (acc.nt_username == undefined) {
+               acc.nt_username = acc.username;
+       }       
+
+       if (acc.nt_username == "") {
+               acc.nt_username = acc.username;
+       }       
+
+       if (acc.fullname == undefined) {
+               var pw = nss.getpwnam(acc.fullname);
+               acc.fullname = pw.pw_gecos;
+       }
+
+       var pts = split(',', acc.fullname);
+       acc.fullname = pts[0];
+
+       if (acc.fullname == undefined) {
+               acc.fullname = acc.username;
+       }
+       
+       assert(acc.fullname != undefined);
+       assert(acc.nt_username != undefined);
+
        var ldif = sprintf(
 "dn: cn=%s,%s
 objectClass: top
-objectClass: person
 objectClass: user
 lastLogon: %d
 lastLogoff: %d
 unixName: %s
-name: %s
+sAMAccountName: %s
 cn: %s
 description: %s
 primaryGroupID: %d
@@ -127,15 +146,16 @@ samba3BadPwdTime: %d
 samba3PassLastSetTime: %d
 samba3PassCanChangeTime: %d
 samba3PassMustChangeTime: %d
-samba3Rid: %d
-ntPwdHash:: %s
+objectSid: %s-%d
 lmPwdHash:: %s
+ntPwdHash:: %s
+
+", ldb.dn_escape(acc.fullname), domaindn, acc.logon_time, acc.logoff_time, acc.username, acc.nt_username, acc.nt_username, 
 
-", acc.fullname, domaindn, acc.logon_time, acc.logoff_time, acc.username, acc.nt_username, 
-acc.fullname, acc.acct_desc, acc.group_rid, acc.bad_password_count, acc.logon_count,
+acc.acct_desc, acc.group_rid, acc.bad_password_count, acc.logon_count,
 acc.domain, acc.dir_drive, acc.munged_dial, acc.homedir, acc.logon_script, 
 acc.profile_path, acc.workstations, acc.kickoff_time, acc.bad_password_time, 
-acc.pass_last_set_time, acc.pass_can_change_time, acc.pass_must_change_time, acc.user_rid,
+acc.pass_last_set_time, acc.pass_can_change_time, acc.pass_must_change_time, domainsid, acc.user_rid,
        ldb.encode(acc.lm_pw), ldb.encode(acc.nt_pw)); 
 
        return ldif;
@@ -143,6 +163,33 @@ acc.pass_last_set_time, acc.pass_can_change_time, acc.pass_must_change_time, acc
 
 function upgrade_sam_group(grp,domaindn)
 {
+       var nss = nss_init();
+
+       var gr;
+       if (grp.sid_name_use == 5) { // Well-known group
+               return undefined;
+       }
+
+       if (grp.nt_name == "Domain Guests" ||
+           grp.nt_name == "Domain Users" ||
+           grp.nt_name == "Domain Admins") {
+               return undefined;
+       }
+       
+       if (grp.gid == -1) {
+               gr = nss.getgrnam(grp.nt_name);
+       } else {
+               gr = nss.getgrgid(grp.gid);
+       }
+
+       if (gr == undefined) {
+               grp.unixname = "UNKNOWN";
+       } else {
+               grp.unixname = gr.gr_name;
+       }
+
+       assert(grp.unixname != undefined);
+       
        var ldif = sprintf(
 "dn: cn=%s,%s
 objectClass: top
@@ -150,10 +197,10 @@ objectClass: group
 description: %s
 cn: %s
 objectSid: %s
-unixName: FIXME
+unixName: %s
 samba3SidNameUse: %d
 ", grp.nt_name, domaindn, 
-grp.comment, grp.nt_name, grp.sid, grp.sid_name_use);
+grp.comment, grp.nt_name, grp.sid, grp.unixname, grp.sid_name_use);
 
        return ldif;
 }
@@ -184,22 +231,73 @@ unixID: %d", m.sid, domaindn, m.sid, m.type, m.unix_id);
 function upgrade_wins(samba3)
 {
        var ldif = "";
+       var version_id = 0;
+
        for (i in samba3.winsentries) {
+               var rType;
+               var rState;
+               var nType;
+               var numIPs = 0;
                var e = samba3.winsentries[i];
-               
+               var now = sys.nttime();
+               var ttl = sys.unix2nttime(e.ttl);
+
+               version_id++;
+
+               for (var i in e.ips) {
+                       numIPs++;
+               }
+
+               if (e.type == 0x1C) {
+                       rType = 0x2;
+               } else if (sys.bitAND(e.type, 0x80)) {
+                       if (numIPs > 1) {
+                               rType = 0x2;
+                       } else {
+                               rType = 0x1;
+                       }
+               } else {
+                       if (numIPs > 1) {
+                               rType = 0x3;
+                       } else {
+                               rType = 0x0;
+                       }
+               }
+
+               if (ttl > now) {
+                       rState = 0x0;/* active */
+               } else {
+                       rState = 0x1;/* released */             
+               }
+
+               nType = (sys.bitAND(e.nb_flags,0x60)>>5);
+
                ldif = ldif + sprintf("
-dn: type=%d,name=%s
+dn: name=%s,type=0x%02X
+type: 0x%02X
 name: %s
-objectClass: wins
-nbFlags: %x
-expires: %s
-", e.type, e.name, e.name, e.type, e.nb_flags, sys.ldaptime(e.ttl));
+objectClass: winsRecord
+recordType: %u
+recordState: %u
+nodeType: %u
+isStatic: 0
+expireTime: %s
+versionID: %llu
+", e.name, e.type, e.type, e.name, 
+   rType, rState, nType, 
+   sys.ldaptime(ttl), version_id);
 
                for (var i in e.ips) {
                        ldif = ldif + sprintf("address: %s\n", e.ips[i]);
                }
        }
 
+       ldif = ldif + sprintf("
+dn: CN=VERSION
+objectClass: winsMaxVersion
+maxVersion: %llu
+", version_id);
+
        return ldif;
 }
 
@@ -343,11 +441,9 @@ smbconf_keep = new Array(
        "map system",
        "map hidden",
        "map archive",
-       "domain logons",
        "preferred master",
        "prefered master",
        "local master",
-       "domain master",
        "browseable",
        "browsable",
        "wins server",
@@ -400,16 +496,31 @@ function upgrade_smbconf(oldconf,mark)
                }
        }
 
+       if (oldconf.get("domain logons") == "True") {
+               newconf.set("server role", "domain controller");
+       } else {
+               if (oldconf.get("security") == "user") {
+                       newconf.set("server role", "standalone");
+               } else {
+                       newconf.set("server role", "member server");
+               }
+       }
+
        return newconf;
 }
 
-function upgrade(subobj, samba3, message, paths)
+function upgrade(subobj, samba3, message, paths, session_info, credentials)
 {
        var ret = 0;
        var lp = loadparm_init();
        var samdb = ldb_init();
+       samdb.session_info = session_info;
+       samdb.credentials = credentials;
        var ok = samdb.connect(paths.samdb);
-       assert(ok);
+       if (!ok) {
+               info.message("samdb connect failed: " + samdb.errstring() + "\n");
+               assert(ok);
+       }
 
        message("Writing configuration\n");
        var newconf = upgrade_smbconf(samba3.configuration,true);
@@ -418,58 +529,53 @@ function upgrade(subobj, samba3, message, paths)
        message("Importing account policies\n");
        var ldif = upgrade_sam_policy(samba3,subobj.BASEDN);
        ok = samdb.modify(ldif);
-       assert(ok);
-
-       // figure out ldapurl, if applicable
-       var ldapurl = undefined;
-       var pdb = samba3.configuration.get_list("passdb backend");
-       if (pdb != undefined) {
-               for (var b in pdb) {
-                       if (substr(pdb[b], 0, 7) == "ldapsam") {
-                               ldapurl = substr(pdb[b], 8);
-                       }
-               }
+       if (!ok) {
+               message("samdb load failed: " + samdb.errstring() + "\n");
+               assert(ok);
        }
-
-       // URL was not specified in passdb backend but ldap /is/ used
-       if (ldapurl == "") {
-               ldapurl = "ldap://" + samba3.configuration.get("ldap server");
+       var regdb = ldb_init();
+       ok = regdb.connect(paths.hklm);
+       if (!ok) {
+               message("registry connect: " + regdb.errstring() + "\n");
+               assert(ok);
        }
 
-       // Enable samba3sam module if original passdb backend was ldap
-       if (ldapurl != undefined) {
-               message("Enabling Samba3 LDAP mappings for SAM database\n");
-               var ldif = sprintf("
-dn: @MAP=samba3sam
-@MAP_URL: %s", ldapurl);
-               samdb.add(ldif);
-
-               samdb.modify("dn: @MODULES
-@LIST: samldb,timestamps,objectguid,rdn_name,samba3sam");
+       ok = regdb.modify(sprintf("
+dn: value=RefusePasswordChange,key=Parameters,key=Netlogon,key=Services,key=CurrentControlSet,key=System,HIVE=NONE
+replace: type
+type: 4
+replace: data
+data: %d
+", samba3.policy.refuse_machine_password_change));
+       if (!ok) {
+               message("registry load failed: " + regdb.errstring() + "\n");
+               assert(ok);
        }
 
        message("Importing users\n");
        for (var i in samba3.samaccounts) {
-               message("... " + samba3.samaccounts[i].username);
-               var ldif = upgrade_sam_account(samba3.samaccounts[i],subobj.BASEDN);
+               var msg = "... " + samba3.samaccounts[i].username;
+               var ldif = upgrade_sam_account(samdb,samba3.samaccounts[i],subobj.BASEDN,subobj.DOMAINSID);
                ok = samdb.add(ldif);
-               if (!ok) { 
-                       message("... error: " + samdb.errstring()); 
+               if (!ok && samdb.errstring() != "Record exists") { 
+                       msg = msg + "... error: " + samdb.errstring();
                        ret = ret + 1; 
                }
-               message("\n");
+               message(msg + "\n");
        }
 
        message("Importing groups\n");
        for (var i in samba3.groupmappings) {
-               message("... " + samba3.groupmappings[i].nt_name);
+               var msg = "... " + samba3.groupmappings[i].nt_name;
                var ldif = upgrade_sam_group(samba3.groupmappings[i],subobj.BASEDN);
-               ok = samdb.add(ldif);
-               if (!ok) { 
-                       message("... error: " + samdb.errstring()); 
-                       ret = ret + 1; 
+               if (ldif != undefined) {
+                       ok = samdb.add(ldif);
+                       if (!ok && samdb.errstring() != "Record exists") { 
+                               msg = msg + "... error: " + samdb.errstring();
+                               ret = ret + 1; 
+                       }
                }
-               message("\n");
+               message(msg + "\n");
        }
 
        message("Importing registry data\n");
@@ -477,21 +583,22 @@ dn: @MAP=samba3sam
        for (var i in hives) {
                var hn = hives[i];
                message("... " + hn + "\n");
-               var regdb = ldb_init();
+               regdb = ldb_init();
                ok = regdb.connect(paths[hn]);
                assert(ok);
-               var ldif = upgrade_registry(samba3.registry, hn);
+               var ldif = upgrade_registry(samba3.registry, hn, regdb);
                for (var j in ldif) {
-                       message("... ... " + j);
+                       var msg = "... ... " + j;
                        ok = regdb.add(ldif[j]);
-                       if (!ok) { 
-                               message("... error: " + regdb.errstring()); 
+                       if (!ok && regdb.errstring() != "Record exists") { 
+                               msg = msg + "... error: " + regdb.errstring();
                                ret = ret + 1; 
                        }
-                       message("\n");
+                       message(msg + "\n");
                }
        }
 
+
        message("Importing WINS data\n");
        var winsdb = ldb_init();
        ok = winsdb.connect(paths.winsdb);
@@ -502,5 +609,62 @@ dn: @MAP=samba3sam
        ok = winsdb.add(ldif);
        assert(ok);
 
+       // figure out ldapurl, if applicable
+       var ldapurl = undefined;
+       var pdb = samba3.configuration.get_list("passdb backend");
+       if (pdb != undefined) {
+               for (var b in pdb) {
+                       if (strlen(pdb[b]) >= 7) {
+                               if (substr(pdb[b], 0, 7) == "ldapsam") {
+                                       ldapurl = substr(pdb[b], 8);
+                               }
+                       }
+               }
+       }
+
+       // URL was not specified in passdb backend but ldap /is/ used
+       if (ldapurl == "") {
+               ldapurl = "ldap://" + samba3.configuration.get("ldap server");
+       }
+
+       // Enable samba3sam module if original passdb backend was ldap
+       if (ldapurl != undefined) {
+               message("Enabling Samba3 LDAP mappings for SAM database\n");
+
+               ok = samdb.modify("
+dn: @MODULES
+changetype: modify
+replace: @LIST
+@LIST: samldb,operational,objectguid,rdn_name,samba3sam
+");
+               if (!ok) {
+                       message("Error enabling samba3sam module: " + samdb.errstring() + "\n");
+                       ret = ret + 1;
+               }
+
+               ok = samdb.add(sprintf("
+dn: @MAP=samba3sam
+@MAP_URL: %s", ldapurl));
+               assert(ok);
+
+       }
+
        return ret;
 }
+
+function upgrade_verify(subobj, samba3,paths,message)
+{
+       message("Verifying account policies\n");
+       var samldb = ldb_init();
+       var ne = 0;
+
+       var ok = samldb.connect(paths.samdb);
+       assert(ok);
+
+       for (var i in samba3.samaccounts) {
+               var msg = samldb.search("(&(sAMAccountName=" + samba3.samaccounts[i].nt_username + ")(objectclass=user))");
+               assert(msg.length >= 1);
+       }
+       
+       // FIXME
+}