r9754: Upgrading with the command line utility now works, at least partially (-:
[kai/samba.git] / source4 / 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 ldif = sprintf(
105 "dn: cn=%s,%s
106 objectClass: top
107 objectClass: person
108 objectClass: user
109 lastLogon: %d
110 lastLogoff: %d
111 unixName: %s
112 name: %s
113 cn: %s
114 description: %s
115 primaryGroupID: %d
116 badPwdcount: %d
117 logonCount: %d
118 samba3Domain: %s
119 samba3DirDrive: %s
120 samba3MungedDial: %s
121 samba3Homedir: %s
122 samba3LogonScript: %s
123 samba3ProfilePath: %s
124 samba3Workstations: %s
125 samba3KickOffTime: %d
126 samba3BadPwdTime: %d
127 samba3PassLastSetTime: %d
128 samba3PassCanChangeTime: %d
129 samba3PassMustChangeTime: %d
130 samba3Rid: %d
131
132 ", acc.fullname, domaindn, acc.logon_time, acc.logoff_time, acc.username, acc.nt_username, 
133 acc.fullname, acc.acct_desc, acc.group_rid, acc.bad_password_count, acc.logon_count,
134 acc.domain, acc.dir_drive, acc.munged_dial, acc.homedir, acc.logon_script, 
135 acc.profile_path, acc.workstations, acc.kickoff_time, acc.bad_password_time, 
136 acc.pass_last_set_time, acc.pass_can_change_time, acc.pass_must_change_time, acc.user_rid); 
137
138                 /* FIXME: Passwords */
139
140         return ldif;
141 }
142
143 function upgrade_sam_group(grp,domaindn)
144 {
145         var ldif = sprintf(
146 "dn: cn=%s,%s
147 objectClass: top
148 objectClass: group
149 description: %s
150 cn: %s
151 objectSid: %s
152 unixName: FIXME
153 samba3SidNameUse: %d
154 ", grp.nt_name, domaindn, 
155 grp.comment, grp.nt_name, grp.sid, grp.sid_name_use);
156
157         return ldif;
158 }
159
160 function upgrade_winbind(samba3,domaindn)
161 {
162         var ldif = sprintf("
163                 
164 dn: dc=none
165 userHwm: %d
166 groupHwm: %d
167
168 ", samba3.idmap.user_hwm, samba3.idmap.group_hwm);
169
170         for (var i in samba3.idmap.mappings) {
171                 var m = samba3.idmap.mappings[i];
172                 ldif = ldif + sprintf("
173 dn: SID=%s,%s
174 SID: %s
175 type: %d
176 unixID: %d", m.sid, domaindn, m.sid, m.type, m.unix_id);
177         }
178         
179         return ldif;
180 }
181 */
182
183 function upgrade_wins(samba3)
184 {
185         var ldif = "";
186         for (i in samba3.winsentries) {
187                 var e = samba3.winsentries[i];
188                 
189                 ldif = ldif + sprintf("
190 dn: type=%d,name=%s
191 name: %s
192 objectClass: wins
193 nbFlags: %x
194 expires: %s
195 ", e.type, e.name, e.name, e.type, e.nb_flags, sys.ldaptime(e.ttl));
196
197                 for (var i in e.ips) {
198                         ldif = ldif + sprintf("address: %s\n", e.ips[i]);
199                 }
200         }
201
202         return ldif;
203 }
204
205 function upgrade_provision(samba3)
206 {
207         var subobj = new Object();
208         var nss = nss_init();
209         var lp = loadparm_init();
210         var rdn_list;
211
212         var domainname = samba3.get_param("global", "workgroup");
213
214         if (domainname == undefined) {
215                 domainname = samba3.secrets.domains[0].name;
216                 println("No domain specified in smb.conf file, assuming '" + domainname + "'");
217         }
218         
219         var domsec = samba3.find_domainsecrets(domainname);
220         var hostsec = samba3.find_domainsecrets(hostname());
221         var realm = samba3.get_param("global", "realm");
222
223         if (realm == undefined) {
224                 realm = domainname;
225                 println("No realm specified in smb.conf file, assuming '" + realm + "'");
226         }
227         random_init(local);
228
229         subobj.REALM        = realm;
230         subobj.DOMAIN       = domainname;
231         subobj.HOSTNAME     = hostname();
232
233         assert(subobj.REALM);
234         assert(subobj.DOMAIN);
235         assert(subobj.HOSTNAME);
236
237         subobj.HOSTIP       = hostip();
238         if (domsec != undefined) {
239                 subobj.DOMAINGUID   = domsec.guid;
240                 subobj.DOMAINSID    = domsec.sid;
241         } else {
242                 println("Can't find domain secrets for '" + domainname + "'; using random SID and GUID");
243                 subobj.DOMAINGUID = randguid();
244                 subobj.DOMAINSID = randguid();
245         }
246         
247         if (hostsec) {
248                 subobj.HOSTGUID     = hostsec.guid;
249         } else {
250                 subobj.HOSTGUID = randguid();
251         }
252         subobj.INVOCATIONID = randguid();
253         subobj.KRBTGTPASS   = randpass(12);
254         subobj.MACHINEPASS  = randpass(12);
255         subobj.ADMINPASS    = randpass(12);
256         subobj.DEFAULTSITE  = "Default-First-Site-Name";
257         subobj.NEWGUID      = randguid;
258         subobj.NTTIME       = nttime;
259         subobj.LDAPTIME     = ldaptime;
260         subobj.DATESTRING   = datestring;
261         subobj.USN          = nextusn;
262         subobj.ROOT         = findnss(nss.getpwnam, "root");
263         subobj.NOBODY       = findnss(nss.getpwnam, "nobody");
264         subobj.NOGROUP      = findnss(nss.getgrnam, "nogroup", "nobody");
265         subobj.WHEEL        = findnss(nss.getgrnam, "wheel", "root");
266         subobj.USERS        = findnss(nss.getgrnam, "users", "guest", "other");
267         subobj.DNSDOMAIN    = strlower(subobj.REALM);
268         subobj.DNSNAME      = sprintf("%s.%s", 
269                                       strlower(subobj.HOSTNAME), 
270                                       subobj.DNSDOMAIN);
271         subobj.BASEDN       = "DC=" + join(",DC=", split(".", subobj.REALM));
272         rdn_list = split(".", subobj.REALM);
273         subobj.RDN_DC       = rdn_list[0];
274         return subobj;
275 }
276
277 var keep = new Array(
278         "dos charset", 
279         "unix charset",
280         "display charset",
281         "comment",
282         "path",
283         "directory",
284         "workgroup",
285         "realm",
286         "netbios name",
287         "netbios aliases",
288         "netbios scope",
289         "server string",
290         "interfaces",
291         "bind interfaces only",
292         "security",
293         "auth methods",
294         "encrypt passwords",
295         "null passwords",
296         "obey pam restrictions",
297         "password server",
298         "smb passwd file",
299         "sam database",
300         "spoolss database",
301         "wins database",
302         "private dir",
303         "passwd chat",
304         "password level",
305         "lanman auth",
306         "ntlm auth",
307         "client NTLMv2 auth",
308         "client lanman auth",
309         "client plaintext auth",
310         "read only",
311         "hosts allow",
312         "hosts deny",
313         "log level",
314         "debuglevel",
315         "log file",
316         "smb ports",
317         "nbt port",
318         "dgram port",
319         "cldap port",
320         "krb5 port",
321         "web port",
322         "tls enabled",
323         "tls keyfile",
324         "tls certfile",
325         "tls cafile",
326         "tls crlfile",
327         "swat directory",
328         "large readwrite",
329         "max protocol",
330         "min protocol",
331         "unicode",
332         "read raw",
333         "write raw",
334         "disable netbios",
335         "nt status support",
336         "announce version",
337         "announce as",
338         "max mux",
339         "max xmit",
340         "name resolve order",
341         "max wins ttl",
342         "min wins ttl",
343         "time server",
344         "unix extensions",
345         "use spnego",
346         "server signing",
347         "client signing",
348         "rpc big endian",
349         "max connections",
350         "paranoid server security",
351         "socket options",
352         "strict sync",
353         "case insensitive filesystem",
354         "max print jobs",
355         "printable",
356         "print ok",
357         "printer name",
358         "printer",
359         "map system",
360         "map hidden",
361         "map archive",
362         "domain logons",
363         "preferred master",
364         "prefered master",
365         "local master",
366         "domain master",
367         "browseable",
368         "browsable",
369         "wins server",
370         "wins support",
371         "csc policy",
372         "strict locking",
373         "config file",
374         "preload",
375         "auto services",
376         "lock dir",
377         "lock directory",
378         "pid directory",
379         "js include",
380         "setup directory",
381         "socket address",
382         "-valid",
383         "copy",
384         "include",
385         "available",
386         "volume",
387         "fstype",
388         "panic action",
389         "msdfs root",
390         "host msdfs",
391         "winbind separator");
392
393 function upgrade_smbconf(samba3)
394 {
395         //FIXME
396 }
397
398 function upgrade(subobj, samba3, message)
399 {
400         var samdb = ldb_init();
401         var ok = samdb.connect("sam.ldb");
402         assert(ok);
403
404         message("Importing account policies\n");
405         var ldif = upgrade_sam_policy(samba3,subobj.BASEDN);
406         ldifprint(ldif);
407         ok = samdb.modify(ldif);
408         assert(ok);
409
410         // FIXME: Enable samba3sam module if original passdb backend was ldap
411
412         message("Importing users\n");
413         for (var i in samba3.samaccounts) {
414                 message("Importing user '" + samba3.samaccounts[i].username + "'\n");
415                 var ldif = upgrade_sam_account(samba3.samaccounts[i],subobj.BASEDN);
416                 ldifprint(ldif);
417                 ok = samdb.add(ldif);
418                 assert(ok);
419         }
420
421         message("Importing groups\n");
422         for (var i in samba3.groupmappings) {
423                 message("Importing group '" + samba3.groupmappings[i].username + "'\n");
424                 var ldif = upgrade_sam_group(samba3.groupmappings[i],subobj.BASEDN);
425                 ldifprint(ldif);
426                 ok = samdb.add(ldif);
427                 assert(ok);
428         }
429
430         message("Importing registry data\n");
431         var hives = new Array("hkcr","hkcu","hklm","hkpd"); 
432         for (var i in hives) {
433                 println("... " + hives[i]);
434                 var regdb = ldb_init();
435                 ok = regdb.connect(hives[i] + ".ldb");
436                 assert(ok);
437                 var ldif = upgrade_registry(samba3.registry, hives[i]);
438                 ldifprint(ldif);
439                 ok = regdb.add(ldif);
440                 assert(ok);
441         }
442
443         message("Importing WINS data\n");
444         var winsdb = ldb_init();
445         ok = winsdb.connect("wins.ldb");
446         assert(ok);
447
448         var ldif = upgrade_wins(samba3);
449         ldifprint(ldif);
450         ok = winsdb.add(ldif);
451         assert(ok);
452
453         return ok;
454 }