r8338: - added a substitute_var() js library function for doing hash driven
[ira/wip.git] / source4 / setup / provision
1 #!/usr/bin/env smbscript
2 /*
3         provision a Samba4 server
4         Copyright Andrew Tridgell 2005
5         Released under the GNU GPL v2 or later
6 */
7
8 var options = new Object();
9 ok = GetOptions(ARGV, options, 
10                 "POPT_AUTOHELP",
11                 "POPT_COMMON_SAMBA",
12                 "POPT_COMMON_VERSION",
13                 'realm=s',
14                 'domain=s',
15                 'domain-guid=s',
16                 'domain-sid=s',
17                 'host-name=s',
18                 'host-ip=s',
19                 'host-guid=s',
20                 'invocationid=s',
21                 'adminpass=s',
22                 'krbtgtpass=s',
23                 'machinepass=s',
24                 'root=s',
25                 'nobody=s',
26                 'nogroup=s',
27                 'wheel=s',
28                 'users=s',
29                 'outputdir=s',
30                 'quiet');
31 if (ok == false) {
32    println("Failed to parse options: " + options.ERROR);
33    return -1;
34 }
35
36 libinclude("base.js");
37
38 /* used to generate sequence numbers for records */
39 next_usn = 1;
40
41 /*
42   print a message if quiet is not set
43 */
44 function message(s) 
45 {
46         if (options["quiet"] == undefined) {
47                 println(s);
48         }
49 }
50
51 /*
52   find a user or group from a list of possibilities
53 */
54 function findnss()
55 {
56         var i;
57         assert(arguments.length >= 2);
58         var nssfn = arguments[0];
59         var name = arguments[1];
60         if (options[name] != undefined) {
61                 return options[name];
62         }
63         for (i=2;i<arguments.length;i++) {
64                 if (nssfn(arguments[i]) != undefined) {
65                         return arguments[i];
66                 }
67         }
68         println("Unable to find user/group for " + name);
69         exit(1);
70 }
71
72 /*
73    add a foreign security principle
74  */
75 function add_foreign(str, sid, desc, unixname)
76 {
77         var add = "
78 dn: CN=${SID},CN=ForeignSecurityPrincipals,${BASEDN}
79 objectClass: top
80 objectClass: foreignSecurityPrincipal
81 cn: ${SID}
82 description: ${DESC}
83 instanceType: 4
84 whenCreated: ${LDAPTIME}
85 whenChanged: ${LDAPTIME}
86 uSNCreated: 1
87 uSNChanged: 1
88 showInAdvancedViewOnly: TRUE
89 name: ${SID}
90 objectGUID: ${NEWGUID}
91 objectSid: ${SID}
92 objectCategory: CN=Foreign-Security-Principal,CN=Schema,CN=Configuration,${BASEDN}
93 unixName: ${UNIXNAME}
94 ";
95         var sub = new Object();
96         sub.SID = sid;
97         sub.DESC = desc;
98         sub.UNIXNAME = unixname;
99         return str + substitute_var(add, sub);
100 }
101
102 /*
103   return current time as a nt time string
104 */
105 function nttime()
106 {
107         return "" + sys_nttime();
108 }
109
110 /*
111   return current time as a ldap time string
112 */
113 function ldaptime()
114 {
115         return sys_ldaptime(sys_nttime());
116 }
117
118 /*
119   return current time as a ldap time string
120 */
121 function nextusn()
122 {
123         next_usn = next_usn+1;
124         return next_usn;
125 }
126
127 /*
128   return first part of hostname
129 */
130 function hostname()
131 {
132         var s = split(".", sys_hostname());
133         return s[0];
134 }
135
136 /*
137  show some help
138 */
139 function ShowHelp()
140 {
141         print("
142 Samba4 provisioning
143
144 provision.pl [options]
145  --realm        REALM           set realm
146  --domain       DOMAIN          set domain
147  --domain-guid  GUID            set domainguid (otherwise random)
148  --domain-sid   SID             set domainsid (otherwise random)
149  --host-name    HOSTNAME        set hostname
150  --host-ip      IPADDRESS       set ipaddress
151  --host-guid    GUID            set hostguid (otherwise random)
152  --invocationid GUID            set invocationid (otherwise random)
153  --outputdir    OUTPUTDIR       set output directory
154  --adminpass    PASSWORD        choose admin password (otherwise random)
155  --krbtgtpass   PASSWORD        choose krbtgt password (otherwise random)
156  --machinepass  PASSWORD        choose machine password (otherwise random)
157  --root         USERNAME        choose 'root' unix username
158  --nobody       USERNAME        choose 'nobody' user
159  --nogroup      GROUPNAME       choose 'nogroup' group
160  --wheel        GROUPNAME       choose 'wheel' privileged group
161  --users        GROUPNAME       choose 'users' group
162  --quiet                        Be quiet
163
164 You must provide at least a realm and domain
165
166 ");
167         exit(1);
168 }
169
170 if (options['host-name'] == undefined) {
171         options['host-name'] = hostname();
172 }
173
174 /*
175    main program
176 */
177 if (options["realm"] == undefined ||
178     options["domain"] == undefined ||
179     options["host-name"] == undefined) {
180         ShowHelp();
181 }
182
183 options.realm        = strlower(options.realm);
184 options['host-name'] = strlower(options['host-name']);
185 options.domain       = strupper(options.domain);
186 options.netbiosname  = strupper(options['host-name']);
187
188 if (options.hostip == undefined) {
189         var list = sys_interfaces();
190         options.hostip = list[0];
191 }
192
193 message("Provisioning for " + options.domain + " in realm " + options.realm);
194
195 options.root    = findnss(getpwnam, "root", "root");
196 options.nobody  = findnss(getpwnam, "nobody", "nobody");
197 options.nogroup = findnss(getgrnam, "nogroup", "nogroup", "nobody");
198 options.wheel   = findnss(getgrnam, "wheel", "wheel", "root");
199 options.users   = findnss(getgrnam, "users", "users", "guest", "other");
200
201
202 options.dnsdomain = strlower(options.realm);
203 options.dnsname   = strlower(options['host-name']) + "." + options.dnsdomain;
204 options.basedn    = "DC=" + join(",DC=", split(".", options.realm));
205
206 var data = FileLoad("setup/provision.ldif");
207 if (data == undefined) {
208         println("Unable to load provision.ldif");
209         exit(1);
210 }
211
212 /*
213   setup the substitution object
214 */
215 var subobj = new Object();
216 subobj.DOMAINGUID   = randguid();
217 subobj.DOMAINSID    = randsid();
218 subobj.HOSTGUID     = randguid();
219 subobj.INVOCATIONID = randguid();
220 subobj.KRBTGTPASS   = randpass(12);
221 subobj.MACHINEPASS  = randpass(12);
222 subobj.ADMINPASS    = randpass(12);
223 subobj.DEFAULTSITE  = "Default-First-Site-Name";
224 subobj.NEWGUID      = randguid;
225 subobj.NTTIME       = nttime;
226 subobj.LDAPTIME     = ldaptime;
227 subobj.USN          = nextusn;
228 for (r in options) {
229         var key = strupper(join("", split("-", r)));
230         subobj[key] = options[r];
231 }
232
233
234 data = add_foreign(data, "S-1-5-7",  "Anonymous",           "${NOBODY}");
235 data = add_foreign(data, "S-1-1-0",  "World",               "${NOGROUP}");
236 data = add_foreign(data, "S-1-5-2",  "Network",             "${NOGROUP}");
237 data = add_foreign(data, "S-1-5-18", "System",              "${ROOT}");
238 data = add_foreign(data, "S-1-5-11", "Authenticated Users", "${USERS}");
239
240 newdata = substitute_var(data, subobj);
241
242 println(newdata);
243 return 0;