r9735: More work on generating a valid Samba4 configuration using the
authorJelmer Vernooij <jelmer@samba.org>
Mon, 29 Aug 2005 12:31:32 +0000 (12:31 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:34:55 +0000 (13:34 -0500)
Samba3 data (both console and SWAT)
(This used to be commit d569465dc4def55c27878028f2fc762960f453d8)

source4/lib/samba3/PLAN
source4/scripting/bin/samba3dump
source4/scripting/ejs/smbcalls_samba3.c
source4/scripting/libjs/upgrade.js
source4/setup/upgrade [new file with mode: 0644]
swat/install/samba3.esp

index 8bc90da..dd2f8e0 100644 (file)
@@ -31,11 +31,11 @@ Three possible viable approaches:
 (going with a combination of 1 and 2)
 
 ldb mapping backend:
- - do search in new and old (mapped) backend and merge results?
+ - do search in new and old (mapped) backend and merge results
 
 Upgrade process:
  - take libdir & smb.conf
  - read various tdb files / old smb.conf 
- - write new smb.conf (ejs?)
+ - write new smb.conf (ejs)
   - list of parameters to keep.. generate some of the others
- - add generated LDIF (ejs?)
+ - add generated LDIF (ejs). Call out to current provisioning
index 3960962..6b3d999 100644 (file)
@@ -155,10 +155,9 @@ function print_samba3_winsdb(samba3)
 
 function print_samba3_groupmappings(groupdb)
 {
-       var i;
        print_header("Group Mappings");
        
-       for (i in groupdb.groupmappings) {
+       for (var i in groupdb.groupmappings) {
                var g = groupdb.groupmappings[i];
                printf("\t--- Group: %s ---\n", g.nt_name);
                printf("\tComment: %s\n", g.comment);
index bad8a7e..66e1299 100644 (file)
 #include "lib/samba3/samba3.h"
 
 
-#if 0
-
-struct samba3_secrets
-{
-};
-
-#endif 
-
 static struct MprVar mprRegistry(struct samba3_regdb *reg)
 {
        struct MprVar mpv = mprObject("registry"), ks, vs, k, v;
@@ -169,6 +161,37 @@ static struct MprVar mprAliases(struct samba3_groupdb *db)
        return mpv;
 }
 
+static struct MprVar mprDomainSecrets(struct samba3_domainsecrets *ds)
+{
+       struct MprVar v, e = mprObject("domainsecrets");
+       char *tmp;
+
+       mprSetVar(&e, "name", mprString(ds->name));
+
+       tmp = dom_sid_string(NULL, &ds->sid);
+       mprSetVar(&e, "sid", mprString(tmp));
+       talloc_free(tmp);
+
+       tmp = GUID_string(NULL, &ds->guid);
+       mprSetVar(&e, "guid", mprString(tmp));
+       talloc_free(tmp);
+
+       mprSetVar(&e, "plaintext_pw", mprString(ds->plaintext_pw));
+
+       mprSetVar(&e, "last_change_time", mprCreateIntegerVar(ds->last_change_time));
+       mprSetVar(&e, "sec_channel_type", mprCreateIntegerVar(ds->sec_channel_type));
+
+       v = mprObject("hash_pw");
+
+       mprSetVar(&v, "hash", mprData(ds->hash_pw.hash, 16));
+
+       mprSetVar(&v, "mod_time", mprCreateIntegerVar(ds->hash_pw.mod_time));
+
+       mprSetVar(&e, "hash_pw", v);
+
+       return e;
+}
+
 static struct MprVar mprSecrets(struct samba3_secrets *sec)
 {
        struct MprVar mpv = mprObject("samba3_secrets"), es, e;
@@ -188,34 +211,7 @@ static struct MprVar mprSecrets(struct samba3_secrets *sec)
        mprSetVar(&mpv, "ldappws", es);
 
        for (i = 0; i < sec->domain_count; i++) {
-               char *tmp;
-               struct MprVar v;
-               e = mprObject("domainsecrets");
-
-               mprSetVar(&e, "name", mprString(sec->domains[i].name));
-               
-               tmp = dom_sid_string(NULL, &sec->domains[i].sid);
-               mprSetVar(&e, "sid", mprString(tmp));
-               talloc_free(tmp);
-
-               tmp = GUID_string(NULL, &sec->domains[i].guid);
-               mprSetVar(&e, "guid", mprString(tmp));
-               talloc_free(tmp);
-
-               mprSetVar(&e, "plaintext_pw", mprString(sec->domains[i].plaintext_pw));
-
-               mprSetVar(&e, "last_change_time", mprCreateIntegerVar(sec->domains[i].last_change_time));
-               mprSetVar(&e, "sec_channel_type", mprCreateIntegerVar(sec->domains[i].sec_channel_type));
-
-               v = mprObject("hash_pw");
-
-               mprSetVar(&v, "hash", mprData(sec->domains[i].hash_pw.hash, 16));
-
-               mprSetVar(&v, "mod_time", mprCreateIntegerVar(sec->domains[i].hash_pw.mod_time));
-
-               mprSetVar(&e, "hash_pw", v);
-
-               mprAddArray(&es, i, e);
+               mprAddArray(&es, i, mprDomainSecrets(&sec->domains[i]));
        }
 
        mprSetVar(&mpv, "domains", es);
@@ -381,6 +377,54 @@ static struct MprVar mprWinsEntries(struct samba3 *samba3)
        return mpv;
 }
 
+static int ejs_get_param(MprVarHandle eid, int argc, struct MprVar **argv)
+{
+       struct samba3 *samba3;
+       const char *tmp;
+
+       if (argc < 2) {
+               ejsSetErrorMsg(eid, "get_param invalid arguments");
+               return -1;
+       }
+
+       samba3 = mprGetThisPtr(eid, "samba3");
+       mprAssert(samba3);
+       tmp = samba3_get_param(samba3, mprToString(argv[0]), mprToString(argv[1]));
+
+       if (tmp == NULL) {
+               mpr_Return(eid, mprCreateUndefinedVar());
+       } else {
+               mpr_Return(eid, mprString(tmp));
+       }
+
+       return 0;
+}
+
+static int ejs_find_domainsecrets(MprVarHandle eid, int argc, struct MprVar **argv)
+{
+       struct samba3 *samba3 = NULL;
+       struct samba3_domainsecrets *sec;
+
+       if (argc < 1) {
+               ejsSetErrorMsg(eid, "find_domainsecrets invalid arguments");
+               return -1;
+       }
+
+       samba3 = mprGetThisPtr(eid, "samba3");
+       mprAssert(samba3);
+       sec = samba3_find_domainsecrets(samba3, mprToString(argv[0]));
+
+       if (sec == NULL) {
+               mpr_Return(eid, mprCreateUndefinedVar());
+       } else {
+               mpr_Return(eid, mprDomainSecrets(sec));
+       }
+
+       return 0;
+}
+
+
+
 /*
   initialise samba3 ejs subsystem
 */
@@ -402,6 +446,9 @@ static int ejs_samba3_read(MprVarHandle eid, int argc, struct MprVar **argv)
                return -1;
        }
 
+       mprAssert(samba3);
+       
+       mprSetThisPtr(eid, "samba3", samba3);
        mprSetVar(&mpv, "winsentries", mprWinsEntries(samba3));
        mprSetVar(&mpv, "samaccounts", mprSamAccounts(samba3));
        mprSetVar(&mpv, "shares", mprShares(samba3));
@@ -411,6 +458,8 @@ static int ejs_samba3_read(MprVarHandle eid, int argc, struct MprVar **argv)
        mprSetVar(&mpv, "idmapdb", mprIdmapDb(&samba3->idmap));
        mprSetVar(&mpv, "policy", mprPolicy(&samba3->policy));
        mprSetVar(&mpv, "registry", mprRegistry(&samba3->registry));
+       mprSetCFunction(&mpv, "get_param", ejs_get_param);
+       mprSetCFunction(&mpv, "find_domainsecrets", ejs_find_domainsecrets);
 
        mpr_Return(eid, mpv);
        
index 604bbac..6057093 100644 (file)
@@ -6,8 +6,275 @@
 
 libinclude("base.js");
 
-function foo() 
+function regkey_to_dn(name)
 {
+       var dn = "hive=NONE";
+       var i = 0;
 
-       return 0;
+       var as = split("/", name);
+
+       for (i in as) {
+               if (i > 0) {
+                       dn = sprintf("key=%s,", as[i]) + dn;
+               }
+       }
+
+       return dn;
+}
+
+/* Where prefix is any of:
+ * - HKLM
+ *   HKU
+ *   HKCR
+ *   HKPD
+ *   HKPT
+ */
+
+function upgrade_registry(regdb,prefix)
+{
+       var prefix_up = strupper(prefix);
+
+       var ldif = "";
+
+       for (var i in regdb.keys) {
+               var rk = regdb.keys[i];
+               /* Only handle selected hive */
+               if (strncmp(prefix_up, rk.name, strlen(prefix_up)) != 0) {
+                       continue;
+               }
+
+               var keydn = regkey_to_dn(rk.name);
+
+               var pts = split("/", rk.name);
+
+               /* Convert key name to dn */
+               ldif = ldif + sprintf("
+dn: %s
+name: %s
+
+", keydn, pts[0]);
+               
+               for (var j in rk.values) {
+                       var rv = rk.values[j];
+
+                       ldif = ldif + sprintf("
+dn: %s,value=%s
+value: %s
+type: %d
+data:: %s", keydn, rv.value, rv.type, base64(rv.data));
+               }
+       }
+
+       return ldif;
+}
+
+function upgrade_sam_domain(samba3)
+{
+       var ldif = sprintf("
+dn: %s
+dc: FIXME
+objectClass: top
+objectClass: domain
+objectSid: %s
+objectGUID: %s
+name: %s
+oEMInformation: Provisioned by Samba4 (upgraded from Samba3)
+minPwdLength: %d
+pwdHistoryLength: %d
+minPwdAge: %d
+maxPwdAge: %d
+lockoutDuration: %d
+samba3ResetCountMinutes: %d
+samba3UserMustLogonToChangePassword: %d
+samba3BadLockoutMinutes: %d
+samba3DisconnectTime: %d
+samba3RefuseMachinePwdChange: %d
+
+", domaindn, domsec.sid, domsec.guid, domainname, 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
+);
+
+       return ldif;
+}
+
+function upgrade_sam_account(acc,domaindn)
+{
+       var ldif = sprintf(
+"dn: cn=%s,%s
+objectClass: top
+objectClass: person
+objectClass: user
+lastLogon: %d
+lastLogoff: %d
+unixName: %s
+name: %s
+cn: %s
+description: %s
+primaryGroupID: %d
+badPwdcount: %d
+logonCount: %d
+samba3Domain: %s
+samba3DirDrive: %s
+samba3MungedDial: %s
+samba3Homedir: %s
+samba3LogonScript: %s
+samba3ProfilePath: %s
+samba3Workstations: %s
+samba3KickOffTime: %d
+samba3BadPwdTime: %d
+samba3PassLastSetTime: %d
+samba3PassCanChangeTime: %d
+samba3PassMustChangeTime: %d
+samba3Rid: %d
+
+", acc.fullname, domaindn, sam.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.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); 
+
+               /* FIXME: Passwords */
+
+       return ldif;
+}
+
+function upgrade_sam_group(grp,domaindn)
+{
+       var ldif = sprintf(
+"dn: cn=%s,%s
+objectClass: top
+objectClass: group
+description: %s
+cn: %s
+objectSid: %s
+unixName: FIXME
+samba3SidNameUse: %d", grp.nt_name, domaindn, 
+grp.comment, grp.nt_name, grp.sid, grp.sid_name_use);
+
+       return ldif;
+}
+
+function upgrade_sam(samba3,domaindn)
+{
+       domainname = samba3.get_param("global", "workgroup");
+
+       if (domainname == undefined) {
+               DEBUG(0, ("No domain name specified in smb.conf!\n"));
+               return -1;
+       }
+
+       domsec = samba3.find_domainsecrets(domainname);
+
+       var ldif = upgrade_sam_domain(samba3,domaindn);
+
+       /* Users */
+       for (var i in samba3.samaccounts) {
+               ldif = ldif + upgrade_sam_account(samba3.samaccounts[i],domaindn);
+       }
+
+       /* Groups */
+       for (var i in samba3.group.groupmappings) {
+               ldif = ldif + upgrade_sam_group(samba3.group.groupmappings[i],domaindn);
+
+       }
+
+       return count;
+}
+
+function upgrade_winbind(samba3,domaindn)
+{
+       var ldif = sprintf("
+               
+dn: dc=none
+userHwm: %d
+groupHwm: %d
+
+", samba3.idmap.user_hwm, samba3.idmap.group_hwm);
+
+       for (var i in samba3.idmap.mappings) {
+               var m = samba3.idmap.mappings[i];
+               ldif = ldif + sprintf("
+dn: SID=%s,%s
+SID: %s
+type: %d
+unixID: %d", m.sid, domaindn, m.sid, m.type, m.unix_id);
+       }
+       
+       return ldif;
+}
+*/
+
+function upgrade_wins(samba3)
+{
+       var ldif = "";
+       for (i in samba3.winsentries) {
+               var e = samba3.winsentries[i];
+               
+               ldif = ldif + sprintf("
+dn: type=%d,name=%s
+name: %s
+objectClass: wins
+nbFlags: %x
+expires: %s", e.type, e.name, e.name, e.type, e.nb_flags, sys.ldap_time(e.ttl));
+
+               for (var i in e.ips) {
+                       ldif = ldif + sprintf("address: %s\n", e.ips[i]);
+               }
+       }
+
+       return ldif;
+}
+
+function upgrade_provision(samba3)
+{
+       var subobj = new Object();
+       var nss = nss_init();
+       var lp = loadparm_init();
+       var rdn_list;
+
+       var domainname = samba3.get_param("global", "workgroup");
+       var domsec = samba3.find_domainsecrets(domainname);
+       var hostsec = samba3.find_domainsecrets(hostname());
+       var realm = samba3.get_param("global", "realm");
+       random_init(local);
+
+       subobj.REALM        = realm;
+       subobj.DOMAIN       = domainname;
+       subobj.HOSTNAME     = hostname();
+
+       assert(subobj.REALM);
+       assert(subobj.DOMAIN);
+       assert(subobj.HOSTNAME);
+
+       subobj.HOSTIP       = hostip();
+       subobj.DOMAINGUID   = domsec.guid;
+       subobj.DOMAINSID    = domsec.sid;
+       subobj.HOSTGUID     = hostsec.guid;
+       subobj.INVOCATIONID = randguid();
+       subobj.KRBTGTPASS   = randpass(12);
+       subobj.MACHINEPASS  = randpass(12);
+       subobj.ADMINPASS    = randpass(12);
+       subobj.DEFAULTSITE  = "Default-First-Site-Name";
+       subobj.NEWGUID      = randguid;
+       subobj.NTTIME       = nttime;
+       subobj.LDAPTIME     = ldaptime;
+       subobj.DATESTRING   = datestring;
+       subobj.USN          = nextusn;
+       subobj.ROOT         = findnss(nss.getpwnam, split(samba3.get_param("global", "admin users")));
+       subobj.NOBODY       = findnss(nss.getpwnam, "nobody");
+       subobj.NOGROUP      = findnss(nss.getgrnam, "nogroup", "nobody");
+       subobj.WHEEL        = findnss(nss.getgrnam, "wheel", "root");
+       subobj.USERS        = findnss(nss.getgrnam, "users", "guest", "other");
+       subobj.DNSDOMAIN    = strlower(subobj.REALM);
+       subobj.DNSNAME      = sprintf("%s.%s", 
+                                     strlower(subobj.HOSTNAME), 
+                                     subobj.DNSDOMAIN);
+       subobj.BASEDN       = "DC=" + join(",DC=", split(".", subobj.REALM));
+       rdn_list = split(".", subobj.REALM);
+       subobj.RDN_DC       = rdn_list[0];
+       return subobj;
 }
diff --git a/source4/setup/upgrade b/source4/setup/upgrade
new file mode 100644 (file)
index 0000000..447e5ee
--- /dev/null
@@ -0,0 +1,85 @@
+#!/bin/sh
+exec smbscript "$0" ${1+"$@"}
+/*
+       Upgrade from Samba3
+       Copyright Jelmer Vernooij 2005
+       Released under the GNU GPL v2 or later
+*/
+
+options = GetOptions(ARGV,
+               "POPT_AUTOHELP",
+               "POPT_COMMON_SAMBA",
+               "POPT_COMMON_VERSION",
+               'quiet', 'blank');
+
+if (options == undefined) {
+   println("Failed to parse options");
+   return -1;
+}
+
+libinclude("base.js");
+libinclude("provision.js");
+libinclude("upgrade.js");
+
+/*
+  print a message if quiet is not set
+*/
+function message() 
+{
+       if (options["quiet"] == undefined) {
+               print(vsprintf(arguments));
+       }
+}
+
+/*
+ show some help
+*/
+function ShowHelp()
+{
+       print("
+Samba4 import tool
+
+provision [options] <libdir> <smbconf>
+ --quiet                       Be quiet
+ --blank                       do not add users or groups, just the structure
+
+You must provide at least a realm and domain
+
+");
+       exit(1);
+}
+
+if (options.ARGV.length != 2) {
+       ShowHelp();
+       exit(1);
+}
+
+message("Reading Samba3 databases and smb.conf\n");
+var samba3 = samba3_read(options.ARGV[0], options.ARGV[1]);
+
+if (samba3 == undefined) {
+       println("Error reading Samba3 data");
+       exit(1);
+}
+
+message("Writing smb.conf\n");
+// FIXME
+
+message("Provisioning\n");
+var subobj = upgrade_provision(samba3);
+provision(subobj, message, blank);
+
+message("Importing account policies\n");
+// FIXME
+
+message("Importing users\n");
+// FIXME
+
+message("Importing groups\n");
+// FIXME
+
+message("Importing WINS data\n");
+// FIXME
+
+message("All OK\n");
+return 0;
index ead694a..6fa246b 100644 (file)
@@ -9,30 +9,40 @@
 <h1>Import from Samba3</h1>
 
 <%
-var f = FormObj("Import from Samba3", 0, 2);
-var i;
-
-f.add("SMBCONF", "smb.conf file");
-f.add("LIBDIR", "Lib directory");
-f.submit[0] = "Import";
-f.submit[1] = "Cancel";
-
 if (form['submit'] == "Cancel") {
        redirect("/");
 }
 
 if (form['submit'] == "Import") {
-       for (r in form) {
-               subobj[r] = form[r];
-       }
-}
+       write("LIBDIR: " + form['LIBDIR'] + "\n" + "SMBCONF: " + form['SMBCONF']);
+       var samba3 = samba3_read(form['SMBCONF'], form['LIBDIR']);
+
+       domainname = samba3.get_param("global", "workgroup");
+       var sec = samba3.find_domainsecrets(domainname);
+       write("<p>Import data from Samba3 installation.</p>\n");
+       write("<table>\n");
+       write("<tr><td>Domain name</td><td>" + domainname + "</td></tr>\n");
+       write("<tr><td>Domain SID</td><td>" + sec.sid + "</td></tr>\n");
+       write("<tr><td>Domain GUID</td><td>" + sec.guid + "</td></tr>\n");
+       write("</table>");
+
+       var f = FormObj("Import from Samba3", 0, 2);
+       f.submit[0] = "Continue";
+       f.submit[1] = "Cancel";
+       f.display();    
+} else if (form['submit'] == "Continue") {
+       // FIXME                  
+} else {
+       var f = FormObj("Import from Samba3", 0, 2);
 
-f.element[0].value = "/etc/samba/smb.conf";
-f.element[1].value = "/var/lib/samba";
+       f.add("SMBCONF", "smb.conf file");
+       f.add("LIBDIR", "Lib directory");
+       f.submit[0] = "Import";
+       f.submit[1] = "Cancel";
+
+       f.element[0].value = "/etc/samba/smb.conf";
+       f.element[1].value = "/var/lib/samba";
 
-if (form['submit'] == "import") {
-       //              provision(subobj, writefln, false);
-} else {
        f.display();
 }
 %>