r8372: - split out provisioning logic into a separate ejs library
authorAndrew Tridgell <tridge@samba.org>
Tue, 12 Jul 2005 11:46:34 +0000 (11:46 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:20:13 +0000 (13:20 -0500)
- added a provisioning web page
(This used to be commit 7476cb94132cf2849ec19360468904ca6fe8de2c)

source4/scripting/ejs/smbcalls_string.c
source4/scripting/libjs/provision.js [new file with mode: 0644]
source4/setup/provision
swat/esptest/menu.js
swat/esptest/provision.esp [new file with mode: 0644]
swat/scripting/common.js

index ad99870..6597f3b 100644 (file)
 #include "lib/ejs/ejs.h"
 #include "system/passwd.h"
 
+/*
+  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");
@@ -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 (file)
index 0000000..ba6807c
--- /dev/null
@@ -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;
index f379072..56c5265 100755 (executable)
@@ -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;
index d46561f..d2a145c 100644 (file)
@@ -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 (file)
index 0000000..b2f5fbf
--- /dev/null
@@ -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(); %>
index 2e90c1b..0e297d7 100644 (file)
@@ -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>");
        }