1 #!/usr/bin/env smbscript
3 provision a Samba4 server
4 Copyright Andrew Tridgell 2005
5 Released under the GNU GPL v2 or later
8 options = new Object();
9 ok = GetOptions(ARGV, options,
12 "POPT_COMMON_VERSION",
31 println("Failed to parse options: " + options.ERROR);
35 libinclude("base.js");
37 /* used to generate sequence numbers for records */
41 print a message if quiet is not set
45 if (options["quiet"] == undefined) {
51 find a user or group from a list of possibilities
56 assert(arguments.length >= 2);
57 var nssfn = arguments[0];
58 var name = arguments[1];
59 if (options[name] != undefined) {
62 for (i=2;i<arguments.length;i++) {
63 if (nssfn(arguments[i]) != undefined) {
67 println("Unable to find user/group for " + name);
72 add a foreign security principle
74 function add_foreign(str, sid, desc, unixname)
77 dn: CN=${SID},CN=ForeignSecurityPrincipals,${BASEDN}
79 objectClass: foreignSecurityPrincipal
83 whenCreated: ${LDAPTIME}
84 whenChanged: ${LDAPTIME}
87 showInAdvancedViewOnly: TRUE
89 objectGUID: ${NEWGUID}
91 objectCategory: CN=Foreign-Security-Principal,CN=Schema,CN=Configuration,${BASEDN}
94 var sub = new Object();
97 sub.UNIXNAME = unixname;
98 return str + substitute_var(add, sub);
102 return current time as a nt time string
106 return "" + sys_nttime();
110 return current time as a ldap time string
114 return sys_ldaptime(sys_nttime());
117 function datestring()
119 var t = sys_gmtime(sys_nttime());
120 return sprintf("%04u%02u%02u%02u",
121 t.tm_year+1900, t.tm_mon+1, t.tm_mday, t.tm_hour);
125 return current time as a ldap time string
129 next_usn = next_usn+1;
134 return first part of hostname
138 var s = split(".", sys_hostname());
144 setup a ldb in the private dir
146 function setup_ldb(ldif, dbname, subobj)
149 if (arguments.length == 4) {
150 extra = arguments[3];
153 var db = lpGet("private dir") + "/" + dbname;
154 var src = lpGet("setup directory") + "/" + ldif;
158 var data = sys_file_load(src);
160 data = substitute_var(data, subobj);
162 message("Creating " + db + "\n from " + src);
163 ok = ldbAdd(db, data);
168 setup a file in the private dir
170 function setup_file(template, fname, subobj)
172 var f = lpGet("private dir") + "/" + fname;
173 var src = lpGet("setup directory") + "/" + template;
177 var data = sys_file_load(src);
178 data = substitute_var(data, subobj);
180 message("Creating " + f + "\n from " + src);
181 ok = sys_file_save(f, data);
193 provision.pl [options]
194 --realm REALM set realm
195 --domain DOMAIN set domain
196 --domain-guid GUID set domainguid (otherwise random)
197 --domain-sid SID set domainsid (otherwise random)
198 --host-name HOSTNAME set hostname
199 --host-ip IPADDRESS set ipaddress
200 --host-guid GUID set hostguid (otherwise random)
201 --invocationid GUID set invocationid (otherwise random)
202 --adminpass PASSWORD choose admin password (otherwise random)
203 --krbtgtpass PASSWORD choose krbtgt password (otherwise random)
204 --machinepass PASSWORD choose machine password (otherwise random)
205 --root USERNAME choose 'root' unix username
206 --nobody USERNAME choose 'nobody' user
207 --nogroup GROUPNAME choose 'nogroup' group
208 --wheel GROUPNAME choose 'wheel' privileged group
209 --users GROUPNAME choose 'users' group
212 You must provide at least a realm and domain
218 if (options['host-name'] == undefined) {
219 options['host-name'] = hostname();
225 if (options["realm"] == undefined ||
226 options["domain"] == undefined ||
227 options["host-name"] == undefined) {
231 options.realm = strlower(options.realm);
232 options['host-name'] = strlower(options['host-name']);
233 options.domain = strupper(options.domain);
234 options.netbiosname = strupper(options['host-name']);
236 if (options.hostip == undefined) {
237 var list = sys_interfaces();
238 options.hostip = list[0];
241 message("Provisioning for " + options.domain + " in realm " + options.realm);
243 options.root = findnss(getpwnam, "root", "root");
244 options.nobody = findnss(getpwnam, "nobody", "nobody");
245 options.nogroup = findnss(getgrnam, "nogroup", "nogroup", "nobody");
246 options.wheel = findnss(getgrnam, "wheel", "wheel", "root");
247 options.users = findnss(getgrnam, "users", "users", "guest", "other");
250 options.dnsdomain = strlower(options.realm);
251 options.dnsname = strlower(options['host-name']) + "." + options.dnsdomain;
252 options.basedn = "DC=" + join(",DC=", split(".", options.realm));
255 setup the substitution object
257 var subobj = new Object();
258 subobj.DOMAINGUID = randguid();
259 subobj.DOMAINSID = randsid();
260 subobj.HOSTGUID = randguid();
261 subobj.INVOCATIONID = randguid();
262 subobj.KRBTGTPASS = randpass(12);
263 subobj.MACHINEPASS = randpass(12);
264 subobj.ADMINPASS = randpass(12);
265 subobj.DEFAULTSITE = "Default-First-Site-Name";
266 subobj.NEWGUID = randguid;
267 subobj.NTTIME = nttime;
268 subobj.LDAPTIME = ldaptime;
269 subobj.DATESTRING = datestring;
270 subobj.USN = nextusn;
272 var key = strupper(join("", split("-", r)));
273 subobj[key] = options[r];
278 extradata = add_foreign(extradata, "S-1-5-7", "Anonymous", "${NOBODY}");
279 extradata = add_foreign(extradata, "S-1-1-0", "World", "${NOGROUP}");
280 extradata = add_foreign(extradata, "S-1-5-2", "Network", "${NOGROUP}");
281 extradata = add_foreign(extradata, "S-1-5-18", "System", "${ROOT}");
282 extradata = add_foreign(extradata, "S-1-5-11", "Authenticated Users", "${USERS}");
284 message("Using administrator password: " + subobj.ADMINPASS);
286 setup_ldb("hklm.ldif", "hklm.ldb", subobj);
287 setup_ldb("provision.ldif", "sam.ldb", subobj, extradata);
288 setup_ldb("rootdse.ldif", "rootdse.ldb", subobj);
289 setup_ldb("secrets.ldif", "secrets.ldb", subobj);
290 setup_file("provision.zone", subobj.DNSDOMAIN + ".zone", subobj);