diff options
author | Andrew Tridgell <tridge@samba.org> | 2005-07-12 11:46:34 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:20:13 -0500 |
commit | adb7fd18e5e58bc466bdd31d68423e5f958a1d5d (patch) | |
tree | 1af5f5d9ca3223bc70eb6293f715e4ab3db329b6 | |
parent | a4c614b01279e7f89ceea4b2dffccee6cefe37dc (diff) | |
download | samba-adb7fd18e5e58bc466bdd31d68423e5f958a1d5d.tar.gz samba-adb7fd18e5e58bc466bdd31d68423e5f958a1d5d.tar.bz2 samba-adb7fd18e5e58bc466bdd31d68423e5f958a1d5d.zip |
r8372: - split out provisioning logic into a separate ejs library
- added a provisioning web page
(This used to be commit 7476cb94132cf2849ec19360468904ca6fe8de2c)
-rw-r--r-- | source4/scripting/ejs/smbcalls_string.c | 15 | ||||
-rw-r--r-- | source4/scripting/libjs/provision.js | 222 | ||||
-rwxr-xr-x | source4/setup/provision | 205 | ||||
-rw-r--r-- | swat/esptest/menu.js | 1 | ||||
-rw-r--r-- | swat/esptest/provision.esp | 55 | ||||
-rw-r--r-- | swat/scripting/common.js | 31 |
6 files changed, 330 insertions, 199 deletions
diff --git a/source4/scripting/ejs/smbcalls_string.c b/source4/scripting/ejs/smbcalls_string.c index ad998701f6..6597f3b27b 100644 --- a/source4/scripting/ejs/smbcalls_string.c +++ b/source4/scripting/ejs/smbcalls_string.c @@ -27,6 +27,20 @@ /* usage: + var len = strlen(str); +*/ +static int ejs_strlen(MprVarHandle eid, int argc, char **argv) +{ + if (argc != 1) { + ejsSetErrorMsg(eid, "strlen invalid arguments"); + return -1; + } + mpr_Return(eid, mprCreateIntegerVar(strlen_m(argv[0]))); + return 0; +} + +/* + usage: var s = strlower("UPPER"); */ static int ejs_strlower(MprVarHandle eid, int argc, char **argv) @@ -311,6 +325,7 @@ static int ejs_vsprintf(MprVarHandle eid, int argc, struct MprVar **argv) */ void smb_setup_ejs_string(void) { + ejsDefineStringCFunction(-1, "strlen", ejs_strlen, NULL, MPR_VAR_SCRIPT_HANDLE); ejsDefineStringCFunction(-1, "strlower", ejs_strlower, NULL, MPR_VAR_SCRIPT_HANDLE); ejsDefineStringCFunction(-1, "strupper", ejs_strupper, NULL, MPR_VAR_SCRIPT_HANDLE); ejsDefineStringCFunction(-1, "split", ejs_split, NULL, MPR_VAR_SCRIPT_HANDLE); diff --git a/source4/scripting/libjs/provision.js b/source4/scripting/libjs/provision.js new file mode 100644 index 0000000000..ba6807ce44 --- /dev/null +++ b/source4/scripting/libjs/provision.js @@ -0,0 +1,222 @@ +/* + backend code for provisioning a Samba4 server + Copyright Andrew Tridgell 2005 + Released under the GNU GPL v2 or later +*/ + +/* used to generate sequence numbers for records */ +provision_next_usn = 1; + +/* + find a user or group from a list of possibilities +*/ +function findnss() +{ + var i; + assert(arguments.length >= 2); + var nssfn = arguments[0]; + for (i=1;i<arguments.length;i++) { + if (nssfn(arguments[i]) != undefined) { + return arguments[i]; + } + } + printf("Unable to find user/group for %s\n", arguments[1]); + assert(i<arguments.length); +} + +/* + add a foreign security principle + */ +function add_foreign(str, sid, desc, unixname) +{ + var add = " +dn: CN=${SID},CN=ForeignSecurityPrincipals,${BASEDN} +objectClass: top +objectClass: foreignSecurityPrincipal +cn: ${SID} +description: ${DESC} +instanceType: 4 +whenCreated: ${LDAPTIME} +whenChanged: ${LDAPTIME} +uSNCreated: 1 +uSNChanged: 1 +showInAdvancedViewOnly: TRUE +name: ${SID} +objectGUID: ${NEWGUID} +objectSid: ${SID} +objectCategory: CN=Foreign-Security-Principal,CN=Schema,CN=Configuration,${BASEDN} +unixName: ${UNIXNAME} +"; + var sub = new Object(); + sub.SID = sid; + sub.DESC = desc; + sub.UNIXNAME = unixname; + return str + substitute_var(add, sub); +} + +/* + return current time as a nt time string +*/ +function nttime() +{ + return "" + sys_nttime(); +} + +/* + return current time as a ldap time string +*/ +function ldaptime() +{ + return sys_ldaptime(sys_nttime()); +} + +/* + return a date string suitable for a dns zone serial number +*/ +function datestring() +{ + var t = sys_gmtime(sys_nttime()); + return sprintf("%04u%02u%02u%02u", + t.tm_year+1900, t.tm_mon+1, t.tm_mday, t.tm_hour); +} + +/* + return first host IP +*/ +function hostip() +{ + var list = sys_interfaces(); + return list[0]; +} + +/* + return current time as a ldap time string +*/ +function nextusn() +{ + provision_next_usn = provision_next_usn+1; + return provision_next_usn; +} + +/* + return first part of hostname +*/ +function hostname() +{ + var s = split(".", sys_hostname()); + return s[0]; +} + + +/* + setup a ldb in the private dir + */ +function setup_ldb(ldif, dbname, subobj) +{ + var extra = ""; + if (arguments.length == 4) { + extra = arguments[3]; + } + + var db = lpGet("private dir") + "/" + dbname; + var src = lpGet("setup directory") + "/" + ldif; + + sys_unlink(db); + + var data = sys_file_load(src); + data = data + extra; + data = substitute_var(data, subobj); + + ok = ldbAdd(db, data); + assert(ok); +} + +/* + setup a file in the private dir + */ +function setup_file(template, fname, subobj) +{ + var f = lpGet("private dir") + "/" + fname; + var src = lpGet("setup directory") + "/" + template; + + sys_unlink(f); + + var data = sys_file_load(src); + data = substitute_var(data, subobj); + + ok = sys_file_save(f, data); + assert(ok); +} + +/* + provision samba4 - caution, this wipes all existing data! +*/ +function provision(subobj, message) +{ + var data = ""; + + /* + some options need to be upper/lower case + */ + subobj.REALM = strlower(subobj.REALM); + subobj.HOSTNAME = strlower(subobj.HOSTNAME); + subobj.DOMAIN = strupper(subobj.DOMAIN); + subobj.NETBIOSNAME = strupper(subobj.HOSTNAME); + + data = add_foreign(data, "S-1-5-7", "Anonymous", "${NOBODY}"); + data = add_foreign(data, "S-1-1-0", "World", "${NOGROUP}"); + data = add_foreign(data, "S-1-5-2", "Network", "${NOGROUP}"); + data = add_foreign(data, "S-1-5-18", "System", "${ROOT}"); + data = add_foreign(data, "S-1-5-11", "Authenticated Users", "${USERS}"); + + provision_next_usn = 1; + + message("Setting up hklm.ldb\n"); + setup_ldb("hklm.ldif", "hklm.ldb", subobj); + message("Setting up sam.ldb\n"); + setup_ldb("provision.ldif", "sam.ldb", subobj, data); + message("Setting up rootdse.ldb\n"); + setup_ldb("rootdse.ldif", "rootdse.ldb", subobj); + message("Setting up secrets.ldb\n"); + setup_ldb("secrets.ldif", "secrets.ldb", subobj); + message("Setting up DNS zone file\n"); + setup_file("provision.zone", subobj.DNSDOMAIN + ".zone", subobj); +} + +/* + guess reasonably default options for provisioning +*/ +function provision_guess() +{ + var subobj = new Object(); + subobj.REALM = lpGet("realm"); + subobj.DOMAIN = lpGet("workgroup"); + subobj.HOSTNAME = hostname(); + subobj.HOSTIP = hostip(); + subobj.DOMAINGUID = randguid(); + subobj.DOMAINSID = randsid(); + subobj.HOSTGUID = randguid(); + 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(getpwnam, "root"); + subobj.NOBODY = findnss(getpwnam, "nobody"); + subobj.NOGROUP = findnss(getgrnam, "nogroup"); + subobj.WHEEL = findnss(getgrnam, "wheel", "root"); + subobj.USERS = findnss(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)); + return subobj; +} + +return 0; diff --git a/source4/setup/provision b/source4/setup/provision index f37907241e..56c526541d 100755 --- a/source4/setup/provision +++ b/source4/setup/provision @@ -33,153 +33,16 @@ if (ok == false) { } libinclude("base.js"); - -/* used to generate sequence numbers for records */ -next_usn = 1; +libinclude("provision.js"); /* print a message if quiet is not set */ -function message(s) +function message() { if (options["quiet"] == undefined) { - println(s); - } -} - -/* - find a user or group from a list of possibilities -*/ -function findnss() -{ - var i; - assert(arguments.length >= 2); - var nssfn = arguments[0]; - var name = arguments[1]; - if (options[name] != undefined) { - return options[name]; - } - for (i=2;i<arguments.length;i++) { - if (nssfn(arguments[i]) != undefined) { - return arguments[i]; - } - } - println("Unable to find user/group for " + name); - exit(1); -} - -/* - add a foreign security principle - */ -function add_foreign(str, sid, desc, unixname) -{ - var add = " -dn: CN=${SID},CN=ForeignSecurityPrincipals,${BASEDN} -objectClass: top -objectClass: foreignSecurityPrincipal -cn: ${SID} -description: ${DESC} -instanceType: 4 -whenCreated: ${LDAPTIME} -whenChanged: ${LDAPTIME} -uSNCreated: 1 -uSNChanged: 1 -showInAdvancedViewOnly: TRUE -name: ${SID} -objectGUID: ${NEWGUID} -objectSid: ${SID} -objectCategory: CN=Foreign-Security-Principal,CN=Schema,CN=Configuration,${BASEDN} -unixName: ${UNIXNAME} -"; - var sub = new Object(); - sub.SID = sid; - sub.DESC = desc; - sub.UNIXNAME = unixname; - return str + substitute_var(add, sub); -} - -/* - return current time as a nt time string -*/ -function nttime() -{ - return "" + sys_nttime(); -} - -/* - return current time as a ldap time string -*/ -function ldaptime() -{ - return sys_ldaptime(sys_nttime()); -} - -function datestring() -{ - var t = sys_gmtime(sys_nttime()); - return sprintf("%04u%02u%02u%02u", - t.tm_year+1900, t.tm_mon+1, t.tm_mday, t.tm_hour); -} - -/* - return current time as a ldap time string -*/ -function nextusn() -{ - next_usn = next_usn+1; - return next_usn; -} - -/* - return first part of hostname -*/ -function hostname() -{ - var s = split(".", sys_hostname()); - return s[0]; -} - - -/* - setup a ldb in the private dir - */ -function setup_ldb(ldif, dbname, subobj) -{ - var extra = ""; - if (arguments.length == 4) { - extra = arguments[3]; + print(vsprintf(arguments)); } - - var db = lpGet("private dir") + "/" + dbname; - var src = lpGet("setup directory") + "/" + ldif; - - sys_unlink(db); - - var data = sys_file_load(src); - data = data + extra; - data = substitute_var(data, subobj); - - message("Creating " + db + "\n from " + src); - ok = ldbAdd(db, data); - assert(ok); -} - -/* - setup a file in the private dir - */ -function setup_file(template, fname, subobj) -{ - var f = lpGet("private dir") + "/" + fname; - var src = lpGet("setup directory") + "/" + template; - - sys_unlink(f); - - var data = sys_file_load(src); - data = substitute_var(data, subobj); - - message("Creating " + f + "\n from " + src); - ok = sys_file_save(f, data); - assert(ok); } /* @@ -228,66 +91,14 @@ if (options["realm"] == undefined || ShowHelp(); } -options.realm = strlower(options.realm); -options['host-name'] = strlower(options['host-name']); -options.domain = strupper(options.domain); -options.netbiosname = strupper(options['host-name']); - -if (options.hostip == undefined) { - var list = sys_interfaces(); - options.hostip = list[0]; -} - -message("Provisioning for " + options.domain + " in realm " + options.realm); - -options.root = findnss(getpwnam, "root", "root"); -options.nobody = findnss(getpwnam, "nobody", "nobody"); -options.nogroup = findnss(getgrnam, "nogroup", "nogroup", "nobody"); -options.wheel = findnss(getgrnam, "wheel", "wheel", "root"); -options.users = findnss(getgrnam, "users", "users", "guest", "other"); - - -options.dnsdomain = strlower(options.realm); -options.dnsname = strlower(options['host-name']) + "." + options.dnsdomain; -options.basedn = "DC=" + join(",DC=", split(".", options.realm)); - -/* - setup the substitution object -*/ -var subobj = new Object(); -subobj.DOMAINGUID = randguid(); -subobj.DOMAINSID = randsid(); -subobj.HOSTGUID = randguid(); -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; +var subobj = provision_guess(); for (r in options) { var key = strupper(join("", split("-", r))); subobj[key] = options[r]; } - -var extradata = ""; -extradata = add_foreign(extradata, "S-1-5-7", "Anonymous", "${NOBODY}"); -extradata = add_foreign(extradata, "S-1-1-0", "World", "${NOGROUP}"); -extradata = add_foreign(extradata, "S-1-5-2", "Network", "${NOGROUP}"); -extradata = add_foreign(extradata, "S-1-5-18", "System", "${ROOT}"); -extradata = add_foreign(extradata, "S-1-5-11", "Authenticated Users", "${USERS}"); - -message("Using administrator password: " + subobj.ADMINPASS); - -setup_ldb("hklm.ldif", "hklm.ldb", subobj); -setup_ldb("provision.ldif", "sam.ldb", subobj, extradata); -setup_ldb("rootdse.ldif", "rootdse.ldb", subobj); -setup_ldb("secrets.ldif", "secrets.ldb", subobj); -setup_file("provision.zone", subobj.DNSDOMAIN + ".zone", subobj); - -message("All OK"); +message("Provisioning for %s in realm %s\n", subobj.DOMAIN, subobj.REALM); +message("Using administrator password: %s\n", subobj.ADMINPASS); +provision(subobj, message); +message("All OK\n"); return 0; diff --git a/swat/esptest/menu.js b/swat/esptest/menu.js index d46561f311..d2a145cc5c 100644 --- a/swat/esptest/menu.js +++ b/swat/esptest/menu.js @@ -1,6 +1,7 @@ /* show a menu for the esp test pages */ simple_menu( "ESP Tests", + "Provisioning", session_uri("/esptest/provision.esp"), "ldb database", session_uri("/esptest/ldb.esp"), "samr calls", session_uri("/esptest/samr.esp"), "html forms", session_uri("/esptest/formtest.esp"), diff --git a/swat/esptest/provision.esp b/swat/esptest/provision.esp new file mode 100644 index 0000000000..b2f5fbf618 --- /dev/null +++ b/swat/esptest/provision.esp @@ -0,0 +1,55 @@ +<% page_header("columns", "Server provisioning"); + + libinclude("base.js"); + libinclude("provision.js"); +%> + +<h1>Samba4 provisioning</h1> + +<% +var f = FormObj("Provisioning", 9, 2); +var i, subobj = provision_guess(); + +f.element[0].label = "Realm"; +f.element[0].name = "REALM"; +f.element[1].label = "Domain Name"; +f.element[1].name = "DOMAIN"; +f.element[2].label = "Host Name"; +f.element[2].name = "HOSTNAME"; +f.element[3].label = "Administrator Password"; +f.element[3].name = "ADMINPASS"; +f.element[4].label = "Domain SID"; +f.element[4].name = "DOMAINSID"; +f.element[5].label = "Host GUID"; +f.element[5].name = "HOSTGUID"; +f.element[6].label = "Base DN"; +f.element[6].name = "BASEDN"; +f.element[7].label = "Host IP"; +f.element[7].name = "HOSTIP"; +f.element[8].label = "Default Site"; +f.element[8].name = "DEFAULTSITE"; +f.submit[0] = "Provision"; +f.submit[1] = "Cancel"; + +if (form['submit'] == "Cancel") { + redirect("/"); +} + +if (form['submit'] == "Provision") { + for (r in form) { + subobj[r] = form[r]; + } +} + +for (i=0;i<f.element.length;i++) { + f.element[i].value = subobj[f.element[i].name]; +} +if (form['submit'] == "Provision") { + provision(subobj, writefln); +} else { + display_form(f); +} +%> + + +<% page_footer(); %> diff --git a/swat/scripting/common.js b/swat/scripting/common.js index 2e90c1b469..0e297d7d99 100644 --- a/swat/scripting/common.js +++ b/swat/scripting/common.js @@ -23,6 +23,22 @@ function session_uri(uri) { return uri + global.SESSIONURI; } +/* + like printf, but to the web page +*/ +function writef() +{ + write(vsprintf(arguments)); +} + +/* + like writef with a <br> +*/ +function writefln() +{ + write(vsprintf(arguments)); + write("<br/>\n"); +} /* if the browser was too dumb to set the HOST header, then @@ -196,6 +212,7 @@ function FormObj(name, num_elements, num_submits) f.element[i].value = current value (optional, defaults to "") */ function display_form(f) { + var i, size = 20; write('<form name="' + f.name + '" method="post" action="' + f.action + '" class="' + f.class + '">\n'); @@ -210,6 +227,12 @@ function display_form(f) { if (e.value == undefined) { e.value = ""; } + if (strlen(e.value) > size) { + size = strlen(e.value) + 4; + } + } + for (i in f.element) { + var e = f.element[i]; write("<tr>"); write("<td>" + e.label + "</td>"); if (e.type == "select") { @@ -223,8 +246,12 @@ function display_form(f) { } write('</select></td>\n'); } else { - write('<td><input name="' + e.name + '" type="' + - e.type + '" value="' + e.value + '" /></td>\n'); + var sizestr = ""; + if (e.type == "text" || e.type == "password") { + sizestr = sprintf('size="%d"', size); + } + writef('<td><input name="%s" type="%s" value="%s" %s /></td>\n', + e.name, e.type, e.value, sizestr); } write("</tr>"); } |