dbf1c0f2c32a11537782e464f8ddf4ed3227f143
[samba.git] / source / scripting / libjs / upgrade.js
1 /*
2         backend code for upgrading from Samba3
3         Copyright Jelmer Vernooij 2005
4         Released under the GNU GPL v2 or later
5 */
6
7 libinclude("base.js");
8
9 function regkey_to_dn(name)
10 {
11         var dn = "hive=NONE";
12         var i = 0;
13
14         var as = split("/", name);
15
16         for (i in as) {
17                 if (i > 0) {
18                         dn = sprintf("key=%s,", as[i]) + dn;
19                 }
20         }
21
22         return dn;
23 }
24
25 /* Where prefix is any of:
26  * - HKLM
27  *   HKU
28  *   HKCR
29  *   HKPD
30  *   HKPT
31  */
32
33 function upgrade_registry(regdb,prefix)
34 {
35         assert(regdb != undefined);
36         var prefix_up = strupper(prefix);
37
38         var ldif = "";
39
40         for (var i in regdb.keys) {
41                 var rk = regdb.keys[i];
42                 var pts = split("/", rk.name);
43
44                 /* Only handle selected hive */
45                 if (strupper(pts[0]) != prefix_up) {
46                         continue;
47                 }
48
49                 var keydn = regkey_to_dn(rk.name);
50
51                 var pts = split("/", rk.name);
52
53                 /* Convert key name to dn */
54                 ldif = ldif + sprintf("
55 dn: %s
56 name: %s
57
58 ", keydn, pts[0]);
59                 
60                 for (var j in rk.values) {
61                         var rv = rk.values[j];
62
63                         ldif = ldif + sprintf("
64 dn: %s,value=%s
65 value: %s
66 type: %d
67 data:: %s", keydn, rv.value, rv.type, base64(rv.data));
68                 }
69         }
70
71         return ldif;
72 }
73
74 function upgrade_sam_policy(samba3,dn)
75 {
76         var ldif = sprintf("
77 dn: %s
78 changetype: modify
79 replace: minPwdLength
80 minPwdLength: %d
81 pwdHistoryLength: %d
82 minPwdAge: %d
83 maxPwdAge: %d
84 lockoutDuration: %d
85 samba3ResetCountMinutes: %d
86 samba3UserMustLogonToChangePassword: %d
87 samba3BadLockoutMinutes: %d
88 samba3DisconnectTime: %d
89 samba3RefuseMachinePwdChange: %d
90
91 ", dn, samba3.policy.min_password_length, 
92         samba3.policy.password_history, samba3.policy.minimum_password_age,
93         samba3.policy.maximum_password_age, samba3.policy.lockout_duration,
94         samba3.policy.reset_count_minutes, samba3.policy.user_must_logon_to_change_password,
95         samba3.policy.bad_lockout_minutes, samba3.policy.disconnect_time, 
96         samba3.policy.refuse_machine_password_change
97 );
98
99         return ldif;
100 }
101
102 function upgrade_sam_account(acc,domaindn)
103 {
104         var ldb = ldb_init();
105         var ldif = sprintf(
106 "dn: cn=%s,%s
107 objectClass: top
108 objectClass: person
109 objectClass: user
110 lastLogon: %d
111 lastLogoff: %d
112 unixName: %s
113 name: %s
114 cn: %s
115 description: %s
116 primaryGroupID: %d
117 badPwdcount: %d
118 logonCount: %d
119 ntPwdHash:: %s
120 lmPwdHash:: %s
121 samba3Domain: %s
122 samba3DirDrive: %s
123 samba3MungedDial: %s
124 samba3Homedir: %s
125 samba3LogonScript: %s
126 samba3ProfilePath: %s
127 samba3Workstations: %s
128 samba3KickOffTime: %d
129 samba3BadPwdTime: %d
130 samba3PassLastSetTime: %d
131 samba3PassCanChangeTime: %d
132 samba3PassMustChangeTime: %d
133 samba3Rid: %d
134
135 ", acc.fullname, domaindn, acc.logon_time, acc.logoff_time, acc.username, acc.nt_username, 
136 acc.fullname, acc.acct_desc, acc.group_rid, acc.bad_password_count, acc.logon_count,
137 acc.domain, acc.dir_drive, acc.munged_dial, acc.homedir, acc.logon_script, 
138 acc.profile_path, acc.workstations, acc.kickoff_time, acc.bad_password_time, 
139 acc.pass_last_set_time, acc.pass_can_change_time, acc.pass_must_change_time, acc.user_rid,
140         ldb.encode(acc.lm_pw), ldb.encode(acc.nt_pw)); 
141
142         return ldif;
143 }
144
145 function upgrade_sam_group(grp,domaindn)
146 {
147         var ldif = sprintf(
148 "dn: cn=%s,%s
149 objectClass: top
150 objectClass: group
151 description: %s
152 cn: %s
153 objectSid: %s
154 unixName: FIXME
155 samba3SidNameUse: %d
156 ", grp.nt_name, domaindn, 
157 grp.comment, grp.nt_name, grp.sid, grp.sid_name_use);
158
159         return ldif;
160 }
161
162 function upgrade_winbind(samba3,domaindn)
163 {
164         var ldif = sprintf("
165                 
166 dn: dc=none
167 userHwm: %d
168 groupHwm: %d
169
170 ", samba3.idmap.user_hwm, samba3.idmap.group_hwm);
171
172         for (var i in samba3.idmap.mappings) {
173                 var m = samba3.idmap.mappings[i];
174                 ldif = ldif + sprintf("
175 dn: SID=%s,%s
176 SID: %s
177 type: %d
178 unixID: %d", m.sid, domaindn, m.sid, m.type, m.unix_id);
179         }
180         
181         return ldif;
182 }
183 */
184
185 function upgrade_wins(samba3)
186 {
187         var ldif = "";
188         for (i in samba3.winsentries) {
189                 var e = samba3.winsentries[i];
190                 
191                 ldif = ldif + sprintf("
192 dn: type=%d,name=%s
193 name: %s
194 objectClass: wins
195 nbFlags: %x
196 expires: %s
197 ", e.type, e.name, e.name, e.type, e.nb_flags, sys.ldaptime(e.ttl));
198
199                 for (var i in e.ips) {
200                         ldif = ldif + sprintf("address: %s\n", e.ips[i]);
201                 }
202         }
203
204         return ldif;
205 }
206
207 function upgrade_provision(samba3)
208 {
209         var subobj = new Object();
210         var nss = nss_init();
211         var lp = loadparm_init();
212         var rdn_list;
213
214         var domainname = samba3.get_param("global", "workgroup");
215
216         if (domainname == undefined) {
217                 domainname = samba3.secrets.domains[0].name;
218                 println("No domain specified in smb.conf file, assuming '" + domainname + "'");
219         }
220         
221         var domsec = samba3.find_domainsecrets(domainname);
222         var hostsec = samba3.find_domainsecrets(hostname());
223         var realm = samba3.get_param("global", "realm");
224
225         if (realm == undefined) {
226                 realm = domainname;
227                 println("No realm specified in smb.conf file, assuming '" + realm + "'");
228         }
229         random_init(local);
230
231         subobj.REALM        = realm;
232         subobj.DOMAIN       = domainname;
233         subobj.HOSTNAME     = hostname();
234
235         assert(subobj.REALM);
236         assert(subobj.DOMAIN);
237         assert(subobj.HOSTNAME);
238
239         subobj.HOSTIP       = hostip();
240         if (domsec != undefined) {
241                 subobj.DOMAINGUID   = domsec.guid;
242                 subobj.DOMAINSID    = domsec.sid;
243         } else {
244                 println("Can't find domain secrets for '" + domainname + "'; using random SID and GUID");
245                 subobj.DOMAINGUID = randguid();
246                 subobj.DOMAINSID = randsid();
247         }
248         
249         if (hostsec) {
250                 subobj.HOSTGUID     = hostsec.guid;
251         } else {
252                 subobj.HOSTGUID = randguid();
253         }
254         subobj.INVOCATIONID = randguid();
255         subobj.KRBTGTPASS   = randpass(12);
256         subobj.MACHINEPASS  = randpass(12);
257         subobj.ADMINPASS    = randpass(12);
258         subobj.DEFAULTSITE  = "Default-First-Site-Name";
259         subobj.NEWGUID      = randguid;
260         subobj.NTTIME       = nttime;
261         subobj.LDAPTIME     = ldaptime;
262         subobj.DATESTRING   = datestring;
263         subobj.USN          = nextusn;
264         subobj.ROOT         = findnss(nss.getpwnam, "root");
265         subobj.NOBODY       = findnss(nss.getpwnam, "nobody");
266         subobj.NOGROUP      = findnss(nss.getgrnam, "nogroup", "nobody");
267         subobj.WHEEL        = findnss(nss.getgrnam, "wheel", "root");
268         subobj.USERS        = findnss(nss.getgrnam, "users", "guest", "other");
269         subobj.DNSDOMAIN    = strlower(subobj.REALM);
270         subobj.DNSNAME      = sprintf("%s.%s", 
271                                       strlower(subobj.HOSTNAME), 
272                                       subobj.DNSDOMAIN);
273         subobj.BASEDN       = "DC=" + join(",DC=", split(".", subobj.REALM));
274         rdn_list = split(".", subobj.REALM);
275         return subobj;
276 }
277
278 var keep = new Array(
279         "dos charset", 
280         "unix charset",
281         "display charset",
282         "comment",
283         "path",
284         "directory",
285         "workgroup",
286         "realm",
287         "netbios name",
288         "netbios aliases",
289         "netbios scope",
290         "server string",
291         "interfaces",
292         "bind interfaces only",
293         "security",
294         "auth methods",
295         "encrypt passwords",
296         "null passwords",
297         "obey pam restrictions",
298         "password server",
299         "smb passwd file",
300         "private dir",
301         "passwd chat",
302         "password level",
303         "lanman auth",
304         "ntlm auth",
305         "client NTLMv2 auth",
306         "client lanman auth",
307         "client plaintext auth",
308         "read only",
309         "hosts allow",
310         "hosts deny",
311         "log level",
312         "debuglevel",
313         "log file",
314         "smb ports",
315         "large readwrite",
316         "max protocol",
317         "min protocol",
318         "unicode",
319         "read raw",
320         "write raw",
321         "disable netbios",
322         "nt status support",
323         "announce version",
324         "announce as",
325         "max mux",
326         "max xmit",
327         "name resolve order",
328         "max wins ttl",
329         "min wins ttl",
330         "time server",
331         "unix extensions",
332         "use spnego",
333         "server signing",
334         "client signing",
335         "max connections",
336         "paranoid server security",
337         "socket options",
338         "strict sync",
339         "max print jobs",
340         "printable",
341         "print ok",
342         "printer name",
343         "printer",
344         "map system",
345         "map hidden",
346         "map archive",
347         "domain logons",
348         "preferred master",
349         "prefered master",
350         "local master",
351         "domain master",
352         "browseable",
353         "browsable",
354         "wins server",
355         "wins support",
356         "csc policy",
357         "strict locking",
358         "config file",
359         "preload",
360         "auto services",
361         "lock dir",
362         "lock directory",
363         "pid directory",
364         "socket address",
365         "copy",
366         "include",
367         "available",
368         "volume",
369         "fstype",
370         "panic action",
371         "msdfs root",
372         "host msdfs",
373         "winbind separator");
374
375 function upgrade_smbconf(samba3)
376 {
377         //FIXME
378 }
379
380 function save_smbconf(path,smbconf)
381 {
382         var data = "
383 # Generated by upgrade.js";
384
385         for (var i in smbconf.shares) {
386                 var s = smbconf.shares[i];
387                 data = data + "\n[" + s.name + "]\n";
388                 for (var j in s.parameters) {
389                         var p = s.parameters[j];
390                         data = data + "\t" + p.name + " = " + p + "\n";
391                 }
392         }
393         
394         sys.file_save(path,data);
395 }
396
397 function upgrade(subobj, samba3, message)
398 {
399         var samdb = ldb_init();
400         var ok = samdb.connect("sam.ldb");
401         assert(ok);
402
403         message("Importing account policies\n");
404         var ldif = upgrade_sam_policy(samba3,subobj.BASEDN);
405         ok = samdb.modify(ldif);
406         assert(ok);
407
408         var ldapurl = undefined;
409
410         // FIXME: figure out ldapurl
411
412         // Enable samba3sam module if original passdb backend was ldap
413         if (ldapurl != undefined) {
414                 var ldif = sprintf("
415 dn: @MAP=samba3sam
416 @MAP_URL: %s", ldapurl);
417                 samdb.add(ldif);
418
419                 samdb.modify("dn: @MODULES
420 @LIST: samldb,timestamps,objectguid,rdn_name");
421         }
422
423         message("Importing users\n");
424         for (var i in samba3.samaccounts) {
425                 message("... " + samba3.samaccounts[i].username + "\n");
426                 var ldif = upgrade_sam_account(samba3.samaccounts[i],subobj.BASEDN);
427                 ok = samdb.add(ldif);
428                 assert(ok);
429         }
430
431         message("Importing groups\n");
432         for (var i in samba3.groupmappings) {
433                 message("... " + samba3.groupmappings[i].nt_name + "\n");
434                 var ldif = upgrade_sam_group(samba3.groupmappings[i],subobj.BASEDN);
435                 ok = samdb.add(ldif);
436                 assert(ok);
437         }
438
439         message("Importing registry data\n");
440         var hives = new Array("hkcr","hkcu","hklm","hkpd","hku","hkpt"); 
441         for (var i in hives) {
442                 message("... " + hives[i] + "\n");
443                 var regdb = ldb_init();
444                 ok = regdb.connect(hives[i] + ".ldb");
445                 assert(ok);
446                 var ldif = upgrade_registry(samba3.registry, hives[i]);
447                 ok = regdb.add(ldif);
448                 assert(ok);
449         }
450
451         message("Importing WINS data\n");
452         var winsdb = ldb_init();
453         ok = winsdb.connect("wins.ldb");
454         assert(ok);
455
456         var ldif = upgrade_wins(samba3);
457         ok = winsdb.add(ldif);
458         assert(ok);
459
460         return ok;
461 }