From 0549763600b26fadac443555e1cbec5680f91340 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 29 Aug 2005 12:31:32 +0000 Subject: r9735: More work on generating a valid Samba4 configuration using the Samba3 data (both console and SWAT) (This used to be commit d569465dc4def55c27878028f2fc762960f453d8) --- source4/lib/samba3/PLAN | 6 +- source4/scripting/bin/samba3dump | 3 +- source4/scripting/ejs/smbcalls_samba3.c | 121 +++++++++----- source4/scripting/libjs/upgrade.js | 271 +++++++++++++++++++++++++++++++- source4/setup/upgrade | 85 ++++++++++ 5 files changed, 443 insertions(+), 43 deletions(-) create mode 100644 source4/setup/upgrade (limited to 'source4') diff --git a/source4/lib/samba3/PLAN b/source4/lib/samba3/PLAN index 8bc90da427..dd2f8e0005 100644 --- a/source4/lib/samba3/PLAN +++ b/source4/lib/samba3/PLAN @@ -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 diff --git a/source4/scripting/bin/samba3dump b/source4/scripting/bin/samba3dump index 3960962f8b..6b3d999803 100644 --- a/source4/scripting/bin/samba3dump +++ b/source4/scripting/bin/samba3dump @@ -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); diff --git a/source4/scripting/ejs/smbcalls_samba3.c b/source4/scripting/ejs/smbcalls_samba3.c index bad8a7e58e..66e1299566 100644 --- a/source4/scripting/ejs/smbcalls_samba3.c +++ b/source4/scripting/ejs/smbcalls_samba3.c @@ -26,14 +26,6 @@ #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); diff --git a/source4/scripting/libjs/upgrade.js b/source4/scripting/libjs/upgrade.js index 604bbac2c0..60570935f6 100644 --- a/source4/scripting/libjs/upgrade.js +++ b/source4/scripting/libjs/upgrade.js @@ -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 index 0000000000..447e5ee4f9 --- /dev/null +++ b/source4/setup/upgrade @@ -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] + --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; -- cgit