44a1f140b1547775d18df2897f18816986923ce1
[nivanova/samba-autobuild/.git] / testprogs / ejs / samba3sam.js
1 #!/usr/bin/env smbscript
2 /*
3   (C) Jelmer Vernooij <jelmer@samba.org> 2005
4   (C) Martin Kuehl <mkhl@samba.org> 2006
5   Published under the GNU GPL
6   Sponsored by Google Summer of Code
7  */
8
9 var sys;
10 var options = GetOptions(ARGV, "POPT_AUTOHELP", "POPT_COMMON_SAMBA");
11 if (options == undefined) {
12         println("Failed to parse options");
13         return -1;
14 }
15
16 libinclude("base.js");
17
18 if (options.ARGV.length != 2) {
19         println("Usage: samba3sam.js <TESTDIR> <DATADIR>");
20         return -1;
21 }
22
23 var prefix = options.ARGV[0];
24 var datadir = options.ARGV[1];
25
26 function setup_data(obj, ldif)
27 {
28         assert(ldif != undefined);
29         ldif = substitute_var(ldif, obj);
30         assert(ldif != undefined);
31         var ok = obj.db.add(ldif);
32         assert(ok.error == 0);
33 }
34
35 function setup_modules(ldb, s3, s4, ldif)
36 {
37         assert(ldif != undefined);
38         ldif = substitute_var(ldif, s4);
39         assert(ldif != undefined);
40         var ok = ldb.add(ldif);
41         assert(ok.error == 0);
42
43         var ldif = "
44 dn: @MAP=samba3sam
45 @FROM: " + s4.BASEDN + "
46 @TO: sambaDomainName=TESTS," + s3.BASEDN + "
47
48 dn: @MODULES
49 @LIST: rootdse,paged_results,server_sort,extended_dn,asq,samldb,password_hash,operational,objectguid,rdn_name,samba3sam,partition
50
51 dn: @PARTITION
52 partition: " + s4.BASEDN + ":" + s4.url + "
53 partition: " + s3.BASEDN + ":" + s3.url + "
54 replicateEntries: @SUBCLASSES
55 replicateEntries: @ATTRIBUTES
56 replicateEntries: @INDEXLIST
57 ";
58         var ok = ldb.add(ldif);
59         assert(ok.error == 0);
60 }
61
62 function test_s3sam_search(ldb)
63 {
64         println("Looking up by non-mapped attribute");
65         var msg = ldb.search("(cn=Administrator)");
66         assert(msg.error == 0);
67         assert(msg.msgs.length == 1);
68         assert(msg.msgs[0].cn == "Administrator");
69
70         println("Looking up by mapped attribute");
71         var msg = ldb.search("(name=Backup Operators)");
72         assert(msg.error == 0);
73         assert(msg.msgs.length == 1);
74         assert(msg.msgs[0].name == "Backup Operators");
75
76         println("Looking up by old name of renamed attribute");
77         var msg = ldb.search("(displayName=Backup Operators)");
78         assert(msg.msgs.length == 0);
79
80         println("Looking up mapped entry containing SID");
81         var msg = ldb.search("(cn=Replicator)");
82         assert(msg.error == 0);
83         assert(msg.msgs.length == 1);
84         println(msg.msgs[0].dn);
85         assert(msg.msgs[0].dn == "cn=Replicator,ou=Groups,dc=vernstok,dc=nl");
86         assert(msg.msgs[0].objectSid == "S-1-5-21-4231626423-2410014848-2360679739-552");
87
88         println("Checking mapping of objectClass");
89         var oc = msg.msgs[0].objectClass;
90         assert(oc != undefined);
91         for (var i in oc) {
92                 assert(oc[i] == "posixGroup" || oc[i] == "group");
93         }
94
95         println("Looking up by objectClass");
96         var msg = ldb.search("(|(objectClass=user)(cn=Administrator))");
97         assert(msg.error == 0);
98         assert(msg.msgs.length == 2);
99         for (var i = 0; i < msg.msgs.length; i++) {
100                 assert((msg.msgs[i].dn == "unixName=Administrator,ou=Users,dc=vernstok,dc=nl") ||
101                        (msg.msgs[i].dn == "unixName=nobody,ou=Users,dc=vernstok,dc=nl"));
102         }
103 }
104
105 function test_s3sam_modify(ldb, s3)
106 {
107         var msg, ok;
108         println("Adding a record that will be fallbacked");
109         ok = ldb.add("
110 dn: cn=Foo
111 foo: bar
112 blah: Blie
113 cn: Foo
114 showInAdvancedViewOnly: TRUE
115 ");
116         if (ok.error != 0) {
117                 println(ok.errstr);
118                 assert(ok.error == 0);
119         }
120
121         println("Checking for existence of record (local)");
122         /* TODO: This record must be searched in the local database, which is currently only supported for base searches
123          * msg = ldb.search("(cn=Foo)", new Array('foo','blah','cn','showInAdvancedViewOnly'));
124          * TODO: Actually, this version should work as well but doesn't...
125          * 
126          */
127         var attrs =  new Array('foo','blah','cn','showInAdvancedViewOnly');
128         msg = ldb.search("(cn=Foo)", "cn=Foo", ldb.LDB_SCOPE_BASE, attrs);
129         assert(msg.error == 0);
130         assert(msg.msgs.length == 1);
131         assert(msg.msgs[0].showInAdvancedViewOnly == "TRUE");
132         assert(msg.msgs[0].foo == "bar");
133         assert(msg.msgs[0].blah == "Blie");
134
135         println("Adding record that will be mapped");
136         ok = ldb.add("
137 dn: cn=Niemand,cn=Users,dc=vernstok,dc=nl
138 objectClass: user
139 unixName: bin
140 sambaUnicodePwd: geheim
141 cn: Niemand
142 ");
143         if (ok.error != 0) {
144                 println(ok.errstr);
145                 assert(ok.error == 0);
146         }
147         assert(ok.error == 0);
148
149         println("Checking for existence of record (remote)");
150         msg = ldb.search("(unixName=bin)", new Array('unixName','cn','dn', 'sambaUnicodePwd'));
151         assert(msg.error == 0);
152         assert(msg.msgs.length == 1);
153         assert(msg.msgs[0].cn == "Niemand"); 
154         assert(msg.msgs[0].sambaUnicodePwd == "geheim");
155
156         println("Checking for existence of record (local && remote)");
157         msg = ldb.search("(&(unixName=bin)(sambaUnicodePwd=geheim))", new Array('unixName','cn','dn', 'sambaUnicodePwd'));
158         assert(msg.error == 0);
159         assert(msg.msgs.length == 1);           // TODO: should check with more records
160         assert(msg.msgs[0].cn == "Niemand");
161         assert(msg.msgs[0].unixName == "bin");
162         assert(msg.msgs[0].sambaUnicodePwd == "geheim");
163
164         println("Checking for existence of record (local || remote)");
165         msg = ldb.search("(|(unixName=bin)(sambaUnicodePwd=geheim))", new Array('unixName','cn','dn', 'sambaUnicodePwd'));
166         println("got " + msg.msgs.length + " replies");
167         assert(msg.error == 0);
168         assert(msg.msgs.length == 1);           // TODO: should check with more records
169         assert(msg.msgs[0].cn == "Niemand");
170         assert(msg.msgs[0].unixName == "bin" || msg.msgs[0].sambaUnicodePwd == "geheim");
171
172         println("Checking for data in destination database");
173         msg = s3.db.search("(cn=Niemand)");
174         assert(msg.error == 0);
175         assert(msg.msgs.length >= 1);
176         assert(msg.msgs[0].sambaSID == "S-1-5-21-4231626423-2410014848-2360679739-2001");
177         assert(msg.msgs[0].displayName == "Niemand");
178
179         println("Adding attribute...");
180         ok = ldb.modify("
181 dn: cn=Niemand,cn=Users,dc=vernstok,dc=nl
182 changetype: modify
183 add: description
184 description: Blah
185 ");
186         if (ok.error != 0) {
187                 println(ok.errstr);
188                 assert(ok.error == 0);
189         }
190         assert(ok.error == 0);
191
192         println("Checking whether changes are still there...");
193         msg = ldb.search("(cn=Niemand)");
194         assert(msg.error == 0);
195         assert(msg.msgs.length >= 1);
196         assert(msg.msgs[0].cn == "Niemand");
197         assert(msg.msgs[0].description == "Blah");
198
199         println("Modifying attribute...");
200         ok = ldb.modify("
201 dn: cn=Niemand,cn=Users,dc=vernstok,dc=nl
202 changetype: modify
203 replace: description
204 description: Blie
205 ");
206                 if (ok.error != 0) {
207                         println(ok.errstr);
208                         assert(ok.error == 0);
209                 }
210         assert(ok.error == 0);
211
212         println("Checking whether changes are still there...");
213         msg = ldb.search("(cn=Niemand)");
214         assert(msg.error == 0);
215         assert(msg.msgs.length >= 1);
216         assert(msg.msgs[0].description == "Blie");
217
218         println("Deleting attribute...");
219         ok = ldb.modify("
220 dn: cn=Niemand,cn=Users,dc=vernstok,dc=nl
221 changetype: modify
222 delete: description
223 ");
224         if (ok.error != 0) {
225                 println(ok.errstr);
226                 assert(ok.error == 0);
227         }
228         assert(ok.error == 0);
229
230         println("Checking whether changes are no longer there...");
231         msg = ldb.search("(cn=Niemand)");
232         assert(msg.error == 0);
233         assert(msg.msgs.length >= 1);
234         assert(msg.msgs[0].description == undefined);
235
236         println("Renaming record...");
237         ok = ldb.rename("cn=Niemand,cn=Users,dc=vernstok,dc=nl", "cn=Niemand2,cn=Users,dc=vernstok,dc=nl");
238         assert(ok.error == 0);
239
240         println("Checking whether DN has changed...");
241         msg = ldb.search("(cn=Niemand2)");
242         assert(msg.error == 0);
243         assert(msg.msgs.length == 1);
244         assert(msg.msgs[0].dn == "cn=Niemand2,cn=Users,dc=vernstok,dc=nl");
245
246         println("Deleting record...");
247         ok = ldb.del("cn=Niemand2,cn=Users,dc=vernstok,dc=nl");
248         if (ok.error != 0) {
249                 println(ok.errstr);
250                 assert(ok.error == 0);
251         }
252
253         println("Checking whether record is gone...");
254         msg = ldb.search("(cn=Niemand2)");
255         assert(msg.error == 0);
256         assert(msg.msgs.length == 0);
257 }
258
259 function test_map_search(ldb, s3, s4)
260 {
261         println("Running search tests on mapped data");
262         var res;
263         var dn;
264         var attrs;
265
266         /* Add a set of split records */
267         var ldif = "
268 dn: " + s4.dn("cn=X") + "
269 objectClass: user
270 cn: X
271 codePage: x
272 revision: x
273 dnsHostName: x
274 nextRid: y
275 lastLogon: x
276 description: x
277 objectSid: S-1-5-21-4231626423-2410014848-2360679739-552
278 primaryGroupID: 1-5-21-4231626423-2410014848-2360679739-512
279
280 dn: " + s4.dn("cn=Y") + "
281 objectClass: top
282 cn: Y
283 codePage: x
284 revision: x
285 dnsHostName: y
286 nextRid: y
287 lastLogon: y
288 description: x
289
290 dn: " + s4.dn("cn=Z") + "
291 objectClass: top
292 cn: Z
293 codePage: x
294 revision: y
295 dnsHostName: z
296 nextRid: y
297 lastLogon: z
298 description: y
299 ";
300         ldif = substitute_var(ldif, s4);
301         assert(ldif != undefined);
302         var ok = ldb.add(ldif);
303         if (ok.error != 0) {
304                 println(ok.errstr);
305                 assert(ok.error == 0);
306         }
307
308         /* Add a set of remote records */
309         var ldif = "
310 dn: " + s3.dn("cn=A") + "
311 objectClass: posixAccount
312 cn: A
313 sambaNextRid: x
314 sambaBadPasswordCount: x
315 sambaLogonTime: x
316 description: x
317 sambaSID: S-1-5-21-4231626423-2410014848-2360679739-552
318 sambaPrimaryGroupSID: S-1-5-21-4231626423-2410014848-2360679739-512
319
320 dn: " + s3.dn("cn=B") + "
321 objectClass: top
322 cn:B
323 sambaNextRid: x
324 sambaBadPasswordCount: x
325 sambaLogonTime: y
326 description: x
327
328 dn: " + s3.dn("cn=C") + "
329 objectClass: top
330 cn: C
331 sambaNextRid: x
332 sambaBadPasswordCount: y
333 sambaLogonTime: z
334 description: y
335 ";
336         ldif = substitute_var(ldif, s3);
337         assert(ldif != undefined);
338         var ok = s3.db.add(ldif);
339         assert(ok.error == 0);
340
341         println("Testing search by DN");
342
343         /* Search remote record by local DN */
344         dn = s4.dn("cn=A");
345         attrs = new Array("dnsHostName", "lastLogon");
346         res = ldb.search("", dn, ldb.SCOPE_BASE, attrs);
347         assert(res.error == 0);
348         assert(res.msgs.length == 1);
349         assert(res.msgs[0].dn == dn);
350         assert(res.msgs[0].dnsHostName == undefined);
351         assert(res.msgs[0].lastLogon == "x");
352
353         /* Search remote record by remote DN */
354         dn = s3.dn("cn=A");
355         attrs = new Array("dnsHostName", "lastLogon", "sambaLogonTime");
356         res = s3.db.search("", dn, ldb.SCOPE_BASE, attrs);
357         assert(res.error == 0);
358         assert(res.msgs.length == 1);
359         assert(res.msgs[0].dn == dn);
360         assert(res.msgs[0].dnsHostName == undefined);
361         assert(res.msgs[0].lastLogon == undefined);
362         assert(res.msgs[0].sambaLogonTime == "x");
363
364         /* Search split record by local DN */
365         dn = s4.dn("cn=X");
366         attrs = new Array("dnsHostName", "lastLogon");
367         res = ldb.search("", dn, ldb.SCOPE_BASE, attrs);
368         assert(res.error == 0);
369         assert(res.msgs.length == 1);
370         assert(res.msgs[0].dn == dn);
371         assert(res.msgs[0].dnsHostName == "x");
372         assert(res.msgs[0].lastLogon == "x");
373
374         /* Search split record by remote DN */
375         dn = s3.dn("cn=X");
376         attrs = new Array("dnsHostName", "lastLogon", "sambaLogonTime");
377         res = s3.db.search("", dn, ldb.SCOPE_BASE, attrs);
378         assert(res.error == 0);
379         assert(res.msgs.length == 1);
380         assert(res.msgs[0].dn == dn);
381         assert(res.msgs[0].dnsHostName == undefined);
382         assert(res.msgs[0].lastLogon == undefined);
383         assert(res.msgs[0].sambaLogonTime == "x");
384
385         println("Testing search by attribute");
386
387         /* Search by ignored attribute */
388         attrs = new Array("dnsHostName", "lastLogon");
389         res = ldb.search("(revision=x)", NULL, ldb. SCOPE_DEFAULT, attrs);
390         assert(res.error == 0);
391         assert(res.msgs.length == 2);
392         assert(res.msgs[0].dn == s4.dn("cn=Y"));
393         assert(res.msgs[0].dnsHostName == "y");
394         assert(res.msgs[0].lastLogon == "y");
395         assert(res.msgs[1].dn == s4.dn("cn=X"));
396         assert(res.msgs[1].dnsHostName == "x");
397         assert(res.msgs[1].lastLogon == "x");
398
399         /* Search by kept attribute */
400         attrs = new Array("dnsHostName", "lastLogon");
401         res = ldb.search("(description=y)", NULL, ldb. SCOPE_DEFAULT, attrs);
402         assert(res.error == 0);
403         assert(res.msgs.length == 2);
404         assert(res.msgs[0].dn == s4.dn("cn=Z"));
405         assert(res.msgs[0].dnsHostName == "z");
406         assert(res.msgs[0].lastLogon == "z");
407         assert(res.msgs[1].dn == s4.dn("cn=C"));
408         assert(res.msgs[1].dnsHostName == undefined);
409         assert(res.msgs[1].lastLogon == "z");
410
411         /* Search by renamed attribute */
412         attrs = new Array("dnsHostName", "lastLogon");
413         res = ldb.search("(badPwdCount=x)", NULL, ldb. SCOPE_DEFAULT, attrs);
414         assert(res.error == 0);
415         assert(res.msgs.length == 2);
416         assert(res.msgs[0].dn == s4.dn("cn=B"));
417         assert(res.msgs[0].dnsHostName == undefined);
418         assert(res.msgs[0].lastLogon == "y");
419         assert(res.msgs[1].dn == s4.dn("cn=A"));
420         assert(res.msgs[1].dnsHostName == undefined);
421         assert(res.msgs[1].lastLogon == "x");
422
423         /* Search by converted attribute */
424         attrs = new Array("dnsHostName", "lastLogon", "objectSid");
425         /* TODO:
426            Using the SID directly in the parse tree leads to conversion
427            errors, letting the search fail with no results.
428         res = ldb.search("(objectSid=S-1-5-21-4231626423-2410014848-2360679739-552)", NULL, ldb. SCOPE_DEFAULT, attrs);
429         */
430         res = ldb.search("(objectSid=*)", NULL, ldb. SCOPE_DEFAULT, attrs);
431         assert(res.error == 0);
432         assert(res.msgs.length == 2);
433         assert(res.msgs[0].dn == s4.dn("cn=X"));
434         assert(res.msgs[0].dnsHostName == "x");
435         assert(res.msgs[0].lastLogon == "x");
436         assert(res.msgs[0].objectSid == "S-1-5-21-4231626423-2410014848-2360679739-552");
437         assert(res.msgs[1].dn == s4.dn("cn=A"));
438         assert(res.msgs[1].dnsHostName == undefined);
439         assert(res.msgs[1].lastLogon == "x");
440         assert(res.msgs[1].objectSid == "S-1-5-21-4231626423-2410014848-2360679739-552");
441
442         /* Search by generated attribute */
443         /* In most cases, this even works when the mapping is missing
444          * a `convert_operator' by enumerating the remote db. */
445         attrs = new Array("dnsHostName", "lastLogon", "primaryGroupID");
446         res = ldb.search("(primaryGroupID=512)", NULL, ldb. SCOPE_DEFAULT, attrs);
447         assert(res.error == 0);
448         assert(res.msgs.length == 1);
449         assert(res.msgs[0].dn == s4.dn("cn=A"));
450         assert(res.msgs[0].dnsHostName == undefined);
451         assert(res.msgs[0].lastLogon == "x");
452         assert(res.msgs[0].primaryGroupID == "512");
453
454         /* TODO: There should actually be two results, A and X.  The
455          * primaryGroupID of X seems to get corrupted somewhere, and the
456          * objectSid isn't available during the generation of remote (!) data,
457          * which can be observed with the following search.  Also note that Xs
458          * objectSid seems to be fine in the previous search for objectSid... */
459         /*
460         res = ldb.search("(primaryGroupID=*)", NULL, ldb. SCOPE_DEFAULT, attrs);
461         println(res.msgs.length + " results found");
462         for (i=0;i<res.msgs.length;i++) {
463                 for (obj in res.msgs[i]) {
464                         println(obj + ": " + res.msgs[i][obj]);
465                 }
466                 println("---");
467         }
468         */
469
470         /* Search by remote name of renamed attribute */
471         attrs = new Array("dnsHostName", "lastLogon");
472         res = ldb.search("(sambaBadPasswordCount=*)", "", ldb. SCOPE_DEFAULT, attrs);
473         assert(res.error == 0);
474         assert(res.msgs.length == 0);
475
476         /* Search by objectClass */
477         attrs = new Array("dnsHostName", "lastLogon", "objectClass");
478         res = ldb.search("(objectClass=user)", NULL, ldb. SCOPE_DEFAULT, attrs);
479         assert(res.error == 0);
480         assert(res.msgs.length == 2);
481         assert(res.msgs[0].dn == s4.dn("cn=X"));
482         assert(res.msgs[0].dnsHostName == "x");
483         assert(res.msgs[0].lastLogon == "x");
484         assert(res.msgs[0].objectClass != undefined);
485         assert(res.msgs[0].objectClass[0] == "user"); 
486         assert(res.msgs[1].dn == s4.dn("cn=A"));
487         assert(res.msgs[1].dnsHostName == undefined);
488         assert(res.msgs[1].lastLogon == "x");
489         assert(res.msgs[1].objectClass != undefined);
490         assert(res.msgs[1].objectClass[0] == "user");
491
492         /* Prove that the objectClass is actually used for the search */
493         res = ldb.search("(|(objectClass=user)(badPwdCount=x))", NULL, ldb. SCOPE_DEFAULT, attrs);
494         assert(res.error == 0);
495         assert(res.msgs.length == 3);
496         assert(res.msgs[0].dn == s4.dn("cn=B"));
497         assert(res.msgs[0].dnsHostName == undefined);
498         assert(res.msgs[0].lastLogon == "y");
499         assert(res.msgs[0].objectClass != undefined);
500         for (i=0;i<res.msgs[0].objectClass.length;i++) {
501                 assert(res.msgs[0].objectClass[i] != "user");
502         }
503         assert(res.msgs[1].dn == s4.dn("cn=X"));
504         assert(res.msgs[1].dnsHostName == "x");
505         assert(res.msgs[1].lastLogon == "x");
506         assert(res.msgs[1].objectClass != undefined);
507         assert(res.msgs[1].objectClass[0] == "user");
508         assert(res.msgs[2].dn == s4.dn("cn=A"));
509         assert(res.msgs[2].dnsHostName == undefined);
510         assert(res.msgs[2].lastLogon == "x");
511         assert(res.msgs[2].objectClass != undefined);
512         assert(res.msgs[2].objectClass[0] == "user");
513
514         println("Testing search by parse tree");
515
516         /* Search by conjunction of local attributes */
517         attrs = new Array("dnsHostName", "lastLogon");
518         res = ldb.search("(&(codePage=x)(revision=x))", NULL, ldb.SCOPE_DEFAULT, attrs);
519         assert(res.error == 0);
520         assert(res.msgs.length == 2);
521         assert(res.msgs[0].dn == s4.dn("cn=Y"));
522         assert(res.msgs[0].dnsHostName == "y");
523         assert(res.msgs[0].lastLogon == "y");
524         assert(res.msgs[1].dn == s4.dn("cn=X"));
525         assert(res.msgs[1].dnsHostName == "x");
526         assert(res.msgs[1].lastLogon == "x");
527
528         /* Search by conjunction of remote attributes */
529         attrs = new Array("dnsHostName", "lastLogon");
530         res = ldb.search("(&(lastLogon=x)(description=x))", NULL, ldb.SCOPE_DEFAULT, attrs);
531         assert(res.error == 0);
532         assert(res.msgs.length == 2);
533         assert(res.msgs[0].dn == s4.dn("cn=X"));
534         assert(res.msgs[0].dnsHostName == "x");
535         assert(res.msgs[0].lastLogon == "x");
536         assert(res.msgs[1].dn == s4.dn("cn=A"));
537         assert(res.msgs[1].dnsHostName == undefined);
538         assert(res.msgs[1].lastLogon == "x");
539         
540         /* Search by conjunction of local and remote attribute */
541         attrs = new Array("dnsHostName", "lastLogon");
542         res = ldb.search("(&(codePage=x)(description=x))", NULL, ldb.SCOPE_DEFAULT, attrs);
543         assert(res.error == 0);
544         assert(res.msgs.length == 2);
545         assert(res.msgs[0].dn == s4.dn("cn=Y"));
546         assert(res.msgs[0].dnsHostName == "y");
547         assert(res.msgs[0].lastLogon == "y");
548         assert(res.msgs[1].dn == s4.dn("cn=X"));
549         assert(res.msgs[1].dnsHostName == "x");
550         assert(res.msgs[1].lastLogon == "x");
551
552         /* Search by conjunction of local and remote attribute w/o match */
553         attrs = new Array("dnsHostName", "lastLogon");
554         res = ldb.search("(&(codePage=x)(nextRid=x))", NULL, ldb.SCOPE_DEFAULT, attrs);
555         assert(res.error == 0);
556         assert(res.msgs.length == 0);
557         res = ldb.search("(&(revision=x)(lastLogon=z))", NULL, ldb.SCOPE_DEFAULT, attrs);
558         assert(res.error == 0);
559         assert(res.msgs.length == 0);
560
561         /* Search by disjunction of local attributes */
562         attrs = new Array("dnsHostName", "lastLogon");
563         res = ldb.search("(|(revision=x)(dnsHostName=x))", NULL, ldb.SCOPE_DEFAULT, attrs);
564         assert(res.error == 0);
565         assert(res.msgs.length == 2);
566         assert(res.msgs[0].dn == s4.dn("cn=Y"));
567         assert(res.msgs[0].dnsHostName == "y");
568         assert(res.msgs[0].lastLogon == "y");
569         assert(res.msgs[1].dn == s4.dn("cn=X"));
570         assert(res.msgs[1].dnsHostName == "x");
571         assert(res.msgs[1].lastLogon == "x");
572
573         /* Search by disjunction of remote attributes */
574         attrs = new Array("dnsHostName", "lastLogon");
575         res = ldb.search("(|(badPwdCount=x)(lastLogon=x))", NULL, ldb.SCOPE_DEFAULT, attrs);
576         assert(res.error == 0);
577         assert(res.msgs.length == 3);
578         assert(res.msgs[0].dn == s4.dn("cn=B"));
579         assert(res.msgs[0].dnsHostName == undefined);
580         assert(res.msgs[0].lastLogon == "y");
581         assert(res.msgs[1].dn == s4.dn("cn=X"));
582         assert(res.msgs[1].dnsHostName == "x");
583         assert(res.msgs[1].lastLogon == "x");
584         assert(res.msgs[2].dn == s4.dn("cn=A"));
585         assert(res.msgs[2].dnsHostName == undefined);
586         assert(res.msgs[2].lastLogon == "x");
587
588         /* Search by disjunction of local and remote attribute */
589         attrs = new Array("dnsHostName", "lastLogon");
590         res = ldb.search("(|(revision=x)(lastLogon=y))", NULL, ldb.SCOPE_DEFAULT, attrs);
591         assert(res.error == 0);
592         assert(res.msgs.length == 3);
593         assert(res.msgs[0].dn == s4.dn("cn=Y"));
594         assert(res.msgs[0].dnsHostName == "y");
595         assert(res.msgs[0].lastLogon == "y");
596         assert(res.msgs[1].dn == s4.dn("cn=B"));
597         assert(res.msgs[1].dnsHostName == undefined);
598         assert(res.msgs[1].lastLogon == "y");
599         assert(res.msgs[2].dn == s4.dn("cn=X"));
600         assert(res.msgs[2].dnsHostName == "x");
601         assert(res.msgs[2].lastLogon == "x");
602
603         /* Search by disjunction of local and remote attribute w/o match */
604         attrs = new Array("dnsHostName", "lastLogon");
605         res = ldb.search("(|(codePage=y)(nextRid=z))", NULL, ldb.SCOPE_DEFAULT, attrs);
606         assert(res.error == 0);
607         assert(res.msgs.length == 0);
608
609         /* Search by negated local attribute */
610         attrs = new Array("dnsHostName", "lastLogon");
611         res = ldb.search("(!(revision=x))", NULL, ldb.SCOPE_DEFAULT, attrs);
612         assert(res.error == 0);
613         assert(res.msgs.length == 4);
614         assert(res.msgs[0].dn == s4.dn("cn=B"));
615         assert(res.msgs[0].dnsHostName == undefined);
616         assert(res.msgs[0].lastLogon == "y");
617         assert(res.msgs[1].dn == s4.dn("cn=A"));
618         assert(res.msgs[1].dnsHostName == undefined);
619         assert(res.msgs[1].lastLogon == "x");
620         assert(res.msgs[2].dn == s4.dn("cn=Z"));
621         assert(res.msgs[2].dnsHostName == "z");
622         assert(res.msgs[2].lastLogon == "z");
623         assert(res.msgs[3].dn == s4.dn("cn=C"));
624         assert(res.msgs[3].dnsHostName == undefined);
625         assert(res.msgs[3].lastLogon == "z");
626
627         /* Search by negated remote attribute */
628         attrs = new Array("dnsHostName", "lastLogon");
629         res = ldb.search("(!(description=x))", NULL, ldb.SCOPE_DEFAULT, attrs);
630         assert(res.error == 0);
631         assert(res.msgs.length == 2);
632         assert(res.msgs[0].dn == s4.dn("cn=Z"));
633         assert(res.msgs[0].dnsHostName == "z");
634         assert(res.msgs[0].lastLogon == "z");
635         assert(res.msgs[1].dn == s4.dn("cn=C"));
636         assert(res.msgs[1].dnsHostName == undefined);
637         assert(res.msgs[1].lastLogon == "z");
638
639         /* Search by negated conjunction of local attributes */
640         attrs = new Array("dnsHostName", "lastLogon");
641         res = ldb.search("(!(&(codePage=x)(revision=x)))", NULL, ldb.SCOPE_DEFAULT, attrs);
642         assert(res.error == 0);
643         assert(res.msgs.length == 4);
644         assert(res.msgs[0].dn == s4.dn("cn=B"));
645         assert(res.msgs[0].dnsHostName == undefined);
646         assert(res.msgs[0].lastLogon == "y");
647         assert(res.msgs[1].dn == s4.dn("cn=A"));
648         assert(res.msgs[1].dnsHostName == undefined);
649         assert(res.msgs[1].lastLogon == "x");
650         assert(res.msgs[2].dn == s4.dn("cn=Z"));
651         assert(res.msgs[2].dnsHostName == "z");
652         assert(res.msgs[2].lastLogon == "z");
653         assert(res.msgs[3].dn == s4.dn("cn=C"));
654         assert(res.msgs[3].dnsHostName == undefined);
655         assert(res.msgs[3].lastLogon == "z");
656
657         /* Search by negated conjunction of remote attributes */
658         attrs = new Array("dnsHostName", "lastLogon");
659         res = ldb.search("(!(&(lastLogon=x)(description=x)))", NULL, ldb.SCOPE_DEFAULT, attrs);
660         assert(res.error == 0);
661         assert(res.msgs.length == 4);
662         assert(res.msgs[0].dn == s4.dn("cn=Y"));
663         assert(res.msgs[0].dnsHostName == "y");
664         assert(res.msgs[0].lastLogon == "y");
665         assert(res.msgs[1].dn == s4.dn("cn=B"));
666         assert(res.msgs[1].dnsHostName == undefined);
667         assert(res.msgs[1].lastLogon == "y");
668         assert(res.msgs[2].dn == s4.dn("cn=Z"));
669         assert(res.msgs[2].dnsHostName == "z");
670         assert(res.msgs[2].lastLogon == "z");
671         assert(res.msgs[3].dn == s4.dn("cn=C"));
672         assert(res.msgs[3].dnsHostName == undefined);
673         assert(res.msgs[3].lastLogon == "z");
674
675         /* Search by negated conjunction of local and remote attribute */
676         attrs = new Array("dnsHostName", "lastLogon");
677         res = ldb.search("(!(&(codePage=x)(description=x)))", NULL, ldb.SCOPE_DEFAULT, attrs);
678         assert(res.error == 0);
679         assert(res.msgs.length == 4);
680         assert(res.msgs[0].dn == s4.dn("cn=B"));
681         assert(res.msgs[0].dnsHostName == undefined);
682         assert(res.msgs[0].lastLogon == "y");
683         assert(res.msgs[1].dn == s4.dn("cn=A"));
684         assert(res.msgs[1].dnsHostName == undefined);
685         assert(res.msgs[1].lastLogon == "x");
686         assert(res.msgs[2].dn == s4.dn("cn=Z"));
687         assert(res.msgs[2].dnsHostName == "z");
688         assert(res.msgs[2].lastLogon == "z");
689         assert(res.msgs[3].dn == s4.dn("cn=C"));
690         assert(res.msgs[3].dnsHostName == undefined);
691         assert(res.msgs[3].lastLogon == "z");
692
693         /* Search by negated disjunction of local attributes */
694         attrs = new Array("dnsHostName", "lastLogon");
695         res = ldb.search("(!(|(revision=x)(dnsHostName=x)))", NULL, ldb.SCOPE_DEFAULT, attrs);
696         assert(res.error == 0);
697         assert(res.msgs[0].dn == s4.dn("cn=B"));
698         assert(res.msgs[0].dnsHostName == undefined);
699         assert(res.msgs[0].lastLogon == "y");
700         assert(res.msgs[1].dn == s4.dn("cn=A"));
701         assert(res.msgs[1].dnsHostName == undefined);
702         assert(res.msgs[1].lastLogon == "x");
703         assert(res.msgs[2].dn == s4.dn("cn=Z"));
704         assert(res.msgs[2].dnsHostName == "z");
705         assert(res.msgs[2].lastLogon == "z");
706         assert(res.msgs[3].dn == s4.dn("cn=C"));
707         assert(res.msgs[3].dnsHostName == undefined);
708         assert(res.msgs[3].lastLogon == "z");
709
710         /* Search by negated disjunction of remote attributes */
711         attrs = new Array("dnsHostName", "lastLogon");
712         res = ldb.search("(!(|(badPwdCount=x)(lastLogon=x)))", NULL, ldb.SCOPE_DEFAULT, attrs);
713         assert(res.error == 0);
714         assert(res.msgs.length == 3);
715         assert(res.msgs[0].dn == s4.dn("cn=Y"));
716         assert(res.msgs[0].dnsHostName == "y");
717         assert(res.msgs[0].lastLogon == "y");
718         assert(res.msgs[1].dn == s4.dn("cn=Z"));
719         assert(res.msgs[1].dnsHostName == "z");
720         assert(res.msgs[1].lastLogon == "z");
721         assert(res.msgs[2].dn == s4.dn("cn=C"));
722         assert(res.msgs[2].dnsHostName == undefined);
723         assert(res.msgs[2].lastLogon == "z");
724
725         /* Search by negated disjunction of local and remote attribute */
726         attrs = new Array("dnsHostName", "lastLogon");
727         res = ldb.search("(!(|(revision=x)(lastLogon=y)))", NULL, ldb.SCOPE_DEFAULT, attrs);
728         assert(res.error == 0);
729         assert(res.msgs.length == 3);
730         assert(res.msgs[0].dn == s4.dn("cn=A"));
731         assert(res.msgs[0].dnsHostName == undefined);
732         assert(res.msgs[0].lastLogon == "x");
733         assert(res.msgs[1].dn == s4.dn("cn=Z"));
734         assert(res.msgs[1].dnsHostName == "z");
735         assert(res.msgs[1].lastLogon == "z");
736         assert(res.msgs[2].dn == s4.dn("cn=C"));
737         assert(res.msgs[2].dnsHostName == undefined);
738         assert(res.msgs[2].lastLogon == "z");
739
740         /* Search by complex parse tree */
741         attrs = new Array("dnsHostName", "lastLogon");
742         res = ldb.search("(|(&(revision=x)(dnsHostName=x))(!(&(description=x)(nextRid=y)))(badPwdCount=y))", NULL, ldb.SCOPE_DEFAULT, attrs);
743         assert(res.error == 0);
744         assert(res.msgs.length == 5);
745         assert(res.msgs[0].dn == s4.dn("cn=B"));
746         assert(res.msgs[0].dnsHostName == undefined);
747         assert(res.msgs[0].lastLogon == "y");
748         assert(res.msgs[1].dn == s4.dn("cn=X"));
749         assert(res.msgs[1].dnsHostName == "x");
750         assert(res.msgs[1].lastLogon == "x");
751         assert(res.msgs[2].dn == s4.dn("cn=A"));
752         assert(res.msgs[2].dnsHostName == undefined);
753         assert(res.msgs[2].lastLogon == "x");
754         assert(res.msgs[3].dn == s4.dn("cn=Z"));
755         assert(res.msgs[3].dnsHostName == "z");
756         assert(res.msgs[3].lastLogon == "z");
757         assert(res.msgs[4].dn == s4.dn("cn=C"));
758         assert(res.msgs[4].dnsHostName == undefined);
759         assert(res.msgs[4].lastLogon == "z");
760
761         /* Clean up */
762         var dns = new Array();
763         dns[0] = s4.dn("cn=A");
764         dns[1] = s4.dn("cn=B");
765         dns[2] = s4.dn("cn=C");
766         dns[3] = s4.dn("cn=X");
767         dns[4] = s4.dn("cn=Y");
768         dns[5] = s4.dn("cn=Z");
769         for (i=0;i<dns.length;i++) {
770                 var ok = ldb.del(dns[i]);
771                 assert(ok.error == 0);
772         }
773 }
774
775 function test_map_modify(ldb, s3, s4)
776 {
777         println("Running modification tests on mapped data");
778
779         var ldif;
780         var attrs;
781         var dn, dn2;
782         var res;
783         var ok;
784
785         println("Testing modification of local records");
786
787         /* Add local record */
788         dn = "cn=test,dc=idealx,dc=org";
789         ldif = "
790 dn: " + dn + "
791 cn: test
792 foo: bar
793 revision: 1
794 description: test
795 ";
796         ok = ldb.add(ldif);
797         assert(ok.error == 0);
798         /* Check it's there */
799         attrs = new Array("foo", "revision", "description");
800         res = ldb.search("", dn, ldb.SCOPE_BASE, attrs);
801         assert(res.error == 0);
802         assert(res.msgs.length == 1);
803         assert(res.msgs[0].dn == dn);
804         assert(res.msgs[0].foo == "bar");
805         assert(res.msgs[0].revision == "1");
806         assert(res.msgs[0].description == "test");
807         /* Check it's not in the local db */
808         res = s4.db.search("(cn=test)", NULL, ldb.SCOPE_DEFAULT, attrs);
809         assert(res.error == 0);
810         assert(res.msgs.length == 0);
811         /* Check it's not in the remote db */
812         res = s3.db.search("(cn=test)", NULL, ldb.SCOPE_DEFAULT, attrs);
813         assert(res.error == 0);
814         assert(res.msgs.length == 0);
815
816         /* Modify local record */
817         ldif = "
818 dn: " + dn + "
819 replace: foo
820 foo: baz
821 replace: description
822 description: foo
823 ";
824         ok = ldb.modify(ldif);
825         assert(ok.error == 0);
826         /* Check in local db */
827         res = ldb.search("", dn, ldb.SCOPE_BASE, attrs);
828         assert(res.error == 0);
829         assert(res.msgs.length == 1);
830         assert(res.msgs[0].dn == dn);
831         assert(res.msgs[0].foo == "baz");
832         assert(res.msgs[0].revision == "1");
833         assert(res.msgs[0].description == "foo");
834
835         /* Rename local record */
836         dn2 = "cn=toast,dc=idealx,dc=org";
837         ok = ldb.rename(dn, dn2);
838         assert(ok.error == 0);
839         /* Check in local db */
840         res = ldb.search("", dn2, ldb.SCOPE_BASE, attrs);
841         assert(res.error == 0);
842         assert(res.msgs.length == 1);
843         assert(res.msgs[0].dn == dn2);
844         assert(res.msgs[0].foo == "baz");
845         assert(res.msgs[0].revision == "1");
846         assert(res.msgs[0].description == "foo");
847
848         /* Delete local record */
849         ok = ldb.del(dn2);
850         assert(ok.error == 0);
851         /* Check it's gone */
852         res = ldb.search("", dn2, ldb.SCOPE_BASE);
853         assert(res.error == 0);
854         assert(res.msgs.length == 0);
855
856         println("Testing modification of remote records");
857
858         /* Add remote record */
859         dn = s4.dn("cn=test");
860         dn2 = s3.dn("cn=test");
861         ldif = "
862 dn: " + dn2 + "
863 cn: test
864 description: foo
865 sambaBadPasswordCount: 3
866 sambaNextRid: 1001
867 ";
868         ok = s3.db.add(ldif);
869         assert(ok.error == 0);
870         /* Check it's there */
871         attrs = new Array("description", "sambaBadPasswordCount", "sambaNextRid");
872         res = s3.db.search("", dn2, ldb.SCOPE_BASE, attrs);
873         assert(res.error == 0);
874         assert(res.msgs.length == 1);
875         assert(res.msgs[0].dn == dn2);
876         assert(res.msgs[0].description == "foo");
877         assert(res.msgs[0].sambaBadPasswordCount == "3");
878         assert(res.msgs[0].sambaNextRid == "1001");
879         /* Check in mapped db */
880         attrs = new Array("description", "badPwdCount", "nextRid");
881         res = ldb.search("", dn, ldb.SCOPE_BASE, attrs);
882         assert(res.error == 0);
883         assert(res.msgs.length == 1);
884         assert(res.msgs[0].dn == dn);
885         assert(res.msgs[0].description == "foo");
886         assert(res.msgs[0].badPwdCount == "3");
887         assert(res.msgs[0].nextRid == "1001");
888         /* Check in local db */
889         res = s4.db.search("", dn, ldb.SCOPE_BASE, attrs);
890         assert(res.error == 0);
891         assert(res.msgs.length == 0);
892
893         /* Modify remote data of remote record */
894         ldif = "
895 dn: " + dn + "
896 replace: description
897 description: test
898 replace: badPwdCount
899 badPwdCount: 4
900 ";
901         ok = ldb.modify(ldif);
902         /* Check in mapped db */
903         attrs = new Array("description", "badPwdCount", "nextRid");
904         res = ldb.search("", dn, ldb.SCOPE_BASE, attrs);
905         assert(res.error == 0);
906         assert(res.msgs.length == 1);
907         assert(res.msgs[0].dn == dn);
908         assert(res.msgs[0].description == "test");
909         assert(res.msgs[0].badPwdCount == "4");
910         assert(res.msgs[0].nextRid == "1001");
911         /* Check in remote db */
912         attrs = new Array("description", "sambaBadPasswordCount", "sambaNextRid");
913         res = s3.db.search("", dn2, ldb.SCOPE_BASE, attrs);
914         assert(res.error == 0);
915         assert(res.msgs.length == 1);
916         assert(res.msgs[0].dn == dn2);
917         assert(res.msgs[0].description == "test");
918         assert(res.msgs[0].sambaBadPasswordCount == "4");
919         assert(res.msgs[0].sambaNextRid == "1001");
920
921         /* Rename remote record */
922         dn2 = s4.dn("cn=toast");
923         ok = ldb.rename(dn, dn2);
924         assert(ok.error == 0);
925         /* Check in mapped db */
926         dn = dn2;
927         attrs = new Array("description", "badPwdCount", "nextRid");
928         res = ldb.search("", dn, ldb.SCOPE_BASE, attrs);
929         assert(res.error == 0);
930         assert(res.msgs.length == 1);
931         assert(res.msgs[0].dn == dn);
932         assert(res.msgs[0].description == "test");
933         assert(res.msgs[0].badPwdCount == "4");
934         assert(res.msgs[0].nextRid == "1001");
935         /* Check in remote db */
936         dn2 = s3.dn("cn=toast");
937         attrs = new Array("description", "sambaBadPasswordCount", "sambaNextRid");
938         res = s3.db.search("", dn2, ldb.SCOPE_BASE, attrs);
939         assert(res.error == 0);
940         assert(res.msgs.length == 1);
941         assert(res.msgs[0].dn == dn2);
942         assert(res.msgs[0].description == "test");
943         assert(res.msgs[0].sambaBadPasswordCount == "4");
944         assert(res.msgs[0].sambaNextRid == "1001");
945
946         /* Delete remote record */
947         ok = ldb.del(dn);
948         assert(ok.error == 0);
949         /* Check in mapped db */
950         res = ldb.search("", dn, ldb.SCOPE_BASE);
951         assert(res.error == 0);
952         assert(res.msgs.length == 0);
953         /* Check in remote db */
954         res = s3.db.search("", dn2, ldb.SCOPE_BASE);
955         assert(res.error == 0);
956         assert(res.msgs.length == 0);
957
958         /* Add remote record (same as before) */
959         dn = s4.dn("cn=test");
960         dn2 = s3.dn("cn=test");
961         ldif = "
962 dn: " + dn2 + "
963 cn: test
964 description: foo
965 sambaBadPasswordCount: 3
966 sambaNextRid: 1001
967 ";
968         ok = s3.db.add(ldif);
969         assert(ok.error == 0);
970
971         /* Modify local data of remote record */
972         ldif = "
973 dn: " + dn + "
974 add: revision
975 revision: 1
976 replace: description
977 description: test
978 ";
979         ok = ldb.modify(ldif);
980         /* Check in mapped db */
981         attrs = new Array("revision", "description");
982         res = ldb.search("", dn, ldb.SCOPE_BASE, attrs);
983         assert(res.error == 0);
984         assert(res.msgs.length == 1);
985         assert(res.msgs[0].dn == dn);
986         assert(res.msgs[0].description == "test");
987         assert(res.msgs[0].revision == "1");
988         /* Check in remote db */
989         res = s3.db.search("", dn2, ldb.SCOPE_BASE, attrs);
990         assert(res.error == 0);
991         assert(res.msgs.length == 1);
992         assert(res.msgs[0].dn == dn2);
993         assert(res.msgs[0].description == "test");
994         assert(res.msgs[0].revision == undefined);
995         /* Check in local db */
996         res = s4.db.search("", dn, ldb.SCOPE_BASE, attrs);
997         assert(res.error == 0);
998         assert(res.msgs.length == 1);
999         assert(res.msgs[0].dn == dn);
1000         assert(res.msgs[0].description == undefined);
1001         assert(res.msgs[0].revision == "1");
1002
1003         /* Delete (newly) split record */
1004         ok = ldb.del(dn);
1005         assert(ok.error == 0);
1006
1007         println("Testing modification of split records");
1008
1009         /* Add split record */
1010         dn = s4.dn("cn=test");
1011         dn2 = s3.dn("cn=test");
1012         ldif = "
1013 dn: " + dn + "
1014 cn: test
1015 description: foo
1016 badPwdCount: 3
1017 nextRid: 1001
1018 revision: 1
1019 ";
1020         ok = ldb.add(ldif);
1021         assert(ok.error == 0);
1022         /* Check it's there */
1023         attrs = new Array("description", "badPwdCount", "nextRid", "revision");
1024         res = ldb.search("", dn, ldb.SCOPE_BASE, attrs);
1025         assert(res.error == 0);
1026         assert(res.msgs.length == 1);
1027         assert(res.msgs[0].dn == dn);
1028         assert(res.msgs[0].description == "foo");
1029         assert(res.msgs[0].badPwdCount == "3");
1030         assert(res.msgs[0].nextRid == "1001");
1031         assert(res.msgs[0].revision == "1");
1032         /* Check in local db */
1033         res = s4.db.search("", dn, ldb.SCOPE_BASE, attrs);
1034         assert(res.error == 0);
1035         assert(res.msgs.length == 1);
1036         assert(res.msgs[0].dn == dn);
1037         assert(res.msgs[0].description == undefined);
1038         assert(res.msgs[0].badPwdCount == undefined);
1039         assert(res.msgs[0].nextRid == undefined);
1040         assert(res.msgs[0].revision == "1");
1041         /* Check in remote db */
1042         attrs = new Array("description", "sambaBadPasswordCount", "sambaNextRid", "revision");
1043         res = s3.db.search("", dn2, ldb.SCOPE_BASE, attrs);
1044         assert(res.error == 0);
1045         assert(res.msgs.length == 1);
1046         assert(res.msgs[0].dn == dn2);
1047         assert(res.msgs[0].description == "foo");
1048         assert(res.msgs[0].sambaBadPasswordCount == "3");
1049         assert(res.msgs[0].sambaNextRid == "1001");
1050         assert(res.msgs[0].revision == undefined);
1051
1052         /* Modify of split record */
1053         ldif = "
1054 dn: " + dn + "
1055 replace: description
1056 description: test
1057 replace: badPwdCount
1058 badPwdCount: 4
1059 replace: revision
1060 revision: 2
1061 ";
1062         ok = ldb.modify(ldif);
1063         assert(ok.error == 0);
1064         /* Check in mapped db */
1065         attrs = new Array("description", "badPwdCount", "nextRid", "revision");
1066         res = ldb.search("", dn, ldb.SCOPE_BASE, attrs);
1067         assert(res.error == 0);
1068         assert(res.msgs.length == 1);
1069         assert(res.msgs[0].dn == dn);
1070         assert(res.msgs[0].description == "test");
1071         assert(res.msgs[0].badPwdCount == "4");
1072         assert(res.msgs[0].nextRid == "1001");
1073         assert(res.msgs[0].revision == "2");
1074         /* Check in local db */
1075         res = s4.db.search("", dn, ldb.SCOPE_BASE, attrs);
1076         assert(res.error == 0);
1077         assert(res.msgs.length == 1);
1078         assert(res.msgs[0].dn == dn);
1079         assert(res.msgs[0].description == undefined);
1080         assert(res.msgs[0].badPwdCount == undefined);
1081         assert(res.msgs[0].nextRid == undefined);
1082         assert(res.msgs[0].revision == "2");
1083         /* Check in remote db */
1084         attrs = new Array("description", "sambaBadPasswordCount", "sambaNextRid", "revision");
1085         res = s3.db.search("", dn2, ldb.SCOPE_BASE, attrs);
1086         assert(res.error == 0);
1087         assert(res.msgs.length == 1);
1088         assert(res.msgs[0].dn == dn2);
1089         assert(res.msgs[0].description == "test");
1090         assert(res.msgs[0].sambaBadPasswordCount == "4");
1091         assert(res.msgs[0].sambaNextRid == "1001");
1092         assert(res.msgs[0].revision == undefined);
1093
1094         /* Rename split record */
1095         dn2 = s4.dn("cn=toast");
1096         ok = ldb.rename(dn, dn2);
1097         assert(ok.error == 0);
1098         /* Check in mapped db */
1099         dn = dn2;
1100         attrs = new Array("description", "badPwdCount", "nextRid", "revision");
1101         res = ldb.search("", dn, ldb.SCOPE_BASE, attrs);
1102         assert(res.error == 0);
1103         assert(res.msgs.length == 1);
1104         assert(res.msgs[0].dn == dn);
1105         assert(res.msgs[0].description == "test");
1106         assert(res.msgs[0].badPwdCount == "4");
1107         assert(res.msgs[0].nextRid == "1001");
1108         assert(res.msgs[0].revision == "2");
1109         /* Check in local db */
1110         res = s4.db.search("", dn, ldb.SCOPE_BASE, attrs);
1111         assert(res.error == 0);
1112         assert(res.msgs.length == 1);
1113         assert(res.msgs[0].dn == dn);
1114         assert(res.msgs[0].description == undefined);
1115         assert(res.msgs[0].badPwdCount == undefined);
1116         assert(res.msgs[0].nextRid == undefined);
1117         assert(res.msgs[0].revision == "2");
1118         /* Check in remote db */
1119         dn2 = s3.dn("cn=toast");
1120         attrs = new Array("description", "sambaBadPasswordCount", "sambaNextRid", "revision");
1121         res = s3.db.search("", dn2, ldb.SCOPE_BASE, attrs);
1122         assert(res.error == 0);
1123         assert(res.msgs.length == 1);
1124         assert(res.msgs[0].dn == dn2);
1125         assert(res.msgs[0].description == "test");
1126         assert(res.msgs[0].sambaBadPasswordCount == "4");
1127         assert(res.msgs[0].sambaNextRid == "1001");
1128         assert(res.msgs[0].revision == undefined);
1129
1130         /* Delete split record */
1131         ok = ldb.del(dn);
1132         assert(ok.error == 0);
1133         /* Check in mapped db */
1134         res = ldb.search("", dn, ldb.SCOPE_BASE);
1135         assert(res.error == 0);
1136         assert(res.msgs.length == 0);
1137         /* Check in local db */
1138         res = s4.db.search("", dn, ldb.SCOPE_BASE);
1139         assert(res.error == 0);
1140         assert(res.msgs.length == 0);
1141         /* Check in remote db */
1142         res = s3.db.search("", dn2, ldb.SCOPE_BASE);
1143         assert(res.error == 0);
1144         assert(res.msgs.length == 0);
1145 }
1146
1147 function make_dn(rdn)
1148 {
1149         return rdn + ",sambaDomainName=TESTS," + this.BASEDN;
1150 }
1151
1152 function make_s4dn(rdn)
1153 {
1154         return rdn + "," + this.BASEDN;
1155 }
1156
1157 var ldb = ldb_init();
1158
1159 sys = sys_init();
1160 var ldbfile = prefix + "/" + "test.ldb";
1161 var ldburl = "tdb://" + ldbfile;
1162
1163 var samba4 = new Object("samba4 partition info");
1164 samba4.file = prefix + "/" + "samba4.ldb";
1165 samba4.url = "tdb://" + samba4.file;
1166 samba4.BASEDN = "dc=vernstok,dc=nl";
1167 samba4.db = ldb_init();
1168 samba4.dn = make_s4dn;
1169
1170 var samba3 = new Object("samba3 partition info");
1171 samba3.file = prefix + "/" + "samba3.ldb";
1172 samba3.url = "tdb://" + samba3.file;
1173 samba3.BASEDN = "cn=Samba3Sam";
1174 samba3.db = ldb_init();
1175 samba3.dn = make_dn;
1176
1177 sys.unlink(ldbfile);
1178 sys.unlink(samba3.file);
1179 sys.unlink(samba4.file);
1180
1181 var ok = ldb.connect(ldburl);
1182 assert(ok);
1183 var ok = samba3.db.connect(samba3.url);
1184 assert(ok);
1185 var ok = samba4.db.connect(samba4.url);
1186 assert(ok);
1187
1188 setup_data(samba3, sys.file_load(datadir + "/" + "samba3.ldif"));
1189 setup_modules(ldb, samba3, samba4, sys.file_load(datadir + "/" + "provision_samba3sam.ldif"));
1190
1191 ldb = ldb_init();
1192 var ok = ldb.connect(ldburl);
1193 assert(ok);
1194
1195 test_s3sam_search(ldb);
1196 test_s3sam_modify(ldb, samba3);
1197
1198 sys.unlink(ldbfile);
1199 sys.unlink(samba3.file);
1200 sys.unlink(samba4.file);
1201
1202 ldb = ldb_init();
1203 var ok = ldb.connect(ldburl);
1204 assert(ok);
1205 samba3.db = ldb_init();
1206 var ok = samba3.db.connect(samba3.url);
1207 assert(ok);
1208 samba4.db = ldb_init();
1209 var ok = samba4.db.connect(samba4.url);
1210 assert(ok);
1211
1212 setup_modules(ldb, samba3, samba4, sys.file_load(datadir + "provision_samba3sam.ldif"));
1213
1214 ldb = ldb_init();
1215 var ok = ldb.connect(ldburl);
1216 assert(ok);
1217
1218 test_map_search(ldb, samba3, samba4);
1219 test_map_modify(ldb, samba3, samba4);
1220
1221 sys.unlink(ldbfile);
1222 sys.unlink(samba3.file);
1223 sys.unlink(samba4.file);
1224
1225 return 0;