r9756: One-way upgrade from Samba3->Samba4 basically works now
[sfrench/samba-autobuild/.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 = randsid();
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         return subobj;
274 }
275
276 var keep = new Array(
277         "dos charset", 
278         "unix charset",
279         "display charset",
280         "comment",
281         "path",
282         "directory",
283         "workgroup",
284         "realm",
285         "netbios name",
286         "netbios aliases",
287         "netbios scope",
288         "server string",
289         "interfaces",
290         "bind interfaces only",
291         "security",
292         "auth methods",
293         "encrypt passwords",
294         "null passwords",
295         "obey pam restrictions",
296         "password server",
297         "smb passwd file",
298         "sam database",
299         "spoolss database",
300         "wins database",
301         "private dir",
302         "passwd chat",
303         "password level",
304         "lanman auth",
305         "ntlm auth",
306         "client NTLMv2 auth",
307         "client lanman auth",
308         "client plaintext auth",
309         "read only",
310         "hosts allow",
311         "hosts deny",
312         "log level",
313         "debuglevel",
314         "log file",
315         "smb ports",
316         "nbt port",
317         "dgram port",
318         "cldap port",
319         "krb5 port",
320         "web port",
321         "tls enabled",
322         "tls keyfile",
323         "tls certfile",
324         "tls cafile",
325         "tls crlfile",
326         "swat directory",
327         "large readwrite",
328         "max protocol",
329         "min protocol",
330         "unicode",
331         "read raw",
332         "write raw",
333         "disable netbios",
334         "nt status support",
335         "announce version",
336         "announce as",
337         "max mux",
338         "max xmit",
339         "name resolve order",
340         "max wins ttl",
341         "min wins ttl",
342         "time server",
343         "unix extensions",
344         "use spnego",
345         "server signing",
346         "client signing",
347         "rpc big endian",
348         "max connections",
349         "paranoid server security",
350         "socket options",
351         "strict sync",
352         "case insensitive filesystem",
353         "max print jobs",
354         "printable",
355         "print ok",
356         "printer name",
357         "printer",
358         "map system",
359         "map hidden",
360         "map archive",
361         "domain logons",
362         "preferred master",
363         "prefered master",
364         "local master",
365         "domain master",
366         "browseable",
367         "browsable",
368         "wins server",
369         "wins support",
370         "csc policy",
371         "strict locking",
372         "config file",
373         "preload",
374         "auto services",
375         "lock dir",
376         "lock directory",
377         "pid directory",
378         "js include",
379         "setup directory",
380         "socket address",
381         "-valid",
382         "copy",
383         "include",
384         "available",
385         "volume",
386         "fstype",
387         "panic action",
388         "msdfs root",
389         "host msdfs",
390         "winbind separator");
391
392 function upgrade_smbconf(samba3)
393 {
394         //FIXME
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         // FIXME: Enable samba3sam module if original passdb backend was ldap
409
410         message("Importing users\n");
411         for (var i in samba3.samaccounts) {
412                 message("... " + samba3.samaccounts[i].username + "\n");
413                 var ldif = upgrade_sam_account(samba3.samaccounts[i],subobj.BASEDN);
414                 ok = samdb.add(ldif);
415                 assert(ok);
416         }
417
418         message("Importing groups\n");
419         for (var i in samba3.groupmappings) {
420                 message("... " + samba3.groupmappings[i].nt_name + "\n");
421                 var ldif = upgrade_sam_group(samba3.groupmappings[i],subobj.BASEDN);
422                 ok = samdb.add(ldif);
423                 assert(ok);
424         }
425
426         message("Importing registry data\n");
427         var hives = new Array("hkcr","hkcu","hklm","hkpd","hku","hkpt"); 
428         for (var i in hives) {
429                 message("... " + hives[i] + "\n");
430                 var regdb = ldb_init();
431                 ok = regdb.connect(hives[i] + ".ldb");
432                 assert(ok);
433                 var ldif = upgrade_registry(samba3.registry, hives[i]);
434                 ok = regdb.add(ldif);
435                 assert(ok);
436         }
437
438         message("Importing WINS data\n");
439         var winsdb = ldb_init();
440         ok = winsdb.connect("wins.ldb");
441         assert(ok);
442
443         var ldif = upgrade_wins(samba3);
444         ok = winsdb.add(ldif);
445         assert(ok);
446
447         return ok;
448 }