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