1 #!/usr/bin/env smbscript
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
11 var options = GetOptions(ARGV, "POPT_AUTOHELP", "POPT_COMMON_SAMBA");
12 if (options == undefined) {
13 println("Failed to parse options");
17 libinclude("base.js");
19 if (options.ARGV.length != 2) {
20 println("Usage: samba3sam.js <TESTDIR> <DATADIR>");
24 var prefix = options.ARGV[0];
25 var datadir = options.ARGV[1];
27 function setup_data(obj, ldif)
29 assert(ldif != undefined);
30 ldif = substitute_var(ldif, obj);
31 assert(ldif != undefined);
32 var ok = obj.db.add(ldif);
36 function setup_modules(ldb, s3, s4, ldif)
38 assert(ldif != undefined);
39 ldif = substitute_var(ldif, s4);
40 assert(ldif != undefined);
41 var ok = ldb.add(ldif);
46 @FROM: " + s4.BASEDN + "
47 @TO: " + s3.BASEDN + "
50 @LIST: rootdse,paged_results,server_sort,extended_dn,asq,samldb,objectclass,password_hash,operational,objectguid,rdn_name,samba3sam,partition
53 partition: " + s4.BASEDN + ":" + s4.url + "
54 partition: " + s3.BASEDN + ":" + s3.url + "
55 replicateEntries: @SUBCLASSES
56 replicateEntries: @ATTRIBUTES
57 replicateEntries: @INDEXLIST
59 var ok = ldb.add(ldif);
63 function test_s3sam_search(ldb)
65 println("Looking up by non-mapped attribute");
66 var msg = ldb.search("(cn=Administrator)");
67 assert(msg.length == 1);
68 assert(msg[0].cn == "Administrator");
70 println("Looking up by mapped attribute");
71 var msg = ldb.search("(name=Backup Operators)");
72 assert(msg.length == 1);
73 assert(msg[0].name == "Backup Operators");
75 println("Looking up by old name of renamed attribute");
76 var msg = ldb.search("(displayName=Backup Operators)");
77 assert(msg.length == 0);
79 println("Looking up mapped entry containing SID");
80 var msg = ldb.search("(cn=Replicator)");
81 assert(msg.length == 1);
83 assert(msg[0].dn == "cn=Replicator,ou=Groups,sambaDomainName=TESTS,dc=vernstok,dc=nl");
84 assert(msg[0].objectSid == "S-1-5-21-4231626423-2410014848-2360679739-552");
86 println("Checking mapping of objectClass");
87 var oc = msg[0].objectClass;
88 assert(oc != undefined);
90 assert(oc[i] == "posixGroup" || oc[i] == "group");
93 println("Looking up by objectClass");
94 var msg = ldb.search("(|(objectClass=user)(cn=Administrator))");
95 assert(msg != undefined);
96 assert(msg.length == 2);
97 for (var i = 0; i < msg.length; i++) {
98 assert((msg[i].dn == "unixName=Administrator,ou=Users,sambaDomainName=TESTS,dc=vernstok,dc=nl") ||
99 (msg[i].dn == "unixName=nobody,ou=Users,sambaDomainName=TESTS,dc=vernstok,dc=nl"));
103 function test_s3sam_modify(ldb, s3)
105 println("Adding a record that will be fallbacked");
107 dn: cn=Foo,dc=idealx,dc=org
111 showInAdvancedViewOnly: TRUE
115 println("Checking for existence of record (local)");
116 /* TODO: This record must be searched in the local database, which is currently only supported for base searches
117 * msg = ldb.search("(cn=Foo)", new Array('foo','blah','cn','showInAdvancedViewOnly'));
118 * TODO: Actually, this version should work as well but doesn't...
119 * msg = ldb.search("(cn=Foo)", "dc=idealx,dc=org", ldb.LDB_SCOPE_SUBTREE new Array('foo','blah','cn','showInAdvancedViewOnly'));
121 msg = ldb.search("", "cn=Foo,dc=idealx,dc=org", ldb.LDB_SCOPE_BASE new Array('foo','blah','cn','showInAdvancedViewOnly'));
122 assert(msg.length == 1);
123 assert(msg[0].showInAdvancedViewOnly == "TRUE");
124 assert(msg[0].foo == "bar");
125 assert(msg[0].blah == "Blie");
127 println("Adding record that will be mapped");
129 dn: cn=Niemand,sambaDomainName=TESTS,dc=vernstok,dc=nl
137 println("Checking for existence of record (remote)");
138 msg = ldb.search("(unixName=bin)", new Array('unixName','cn','dn', 'unicodePwd'));
139 assert(msg.length == 1);
140 assert(msg[0].cn == "Niemand");
141 assert(msg[0].unicodePwd == "geheim");
143 println("Checking for existence of record (local && remote)");
144 msg = ldb.search("(&(unixName=bin)(unicodePwd=geheim))", new Array('unixName','cn','dn', 'unicodePwd'));
145 assert(msg.length == 1); // TODO: should check with more records
146 assert(msg[0].cn == "Niemand");
147 assert(msg[0].unixName == "bin");
148 assert(msg[0].unicodePwd == "geheim");
150 println("Checking for existence of record (local || remote)");
151 msg = ldb.search("(|(unixName=bin)(unicodePwd=geheim))", new Array('unixName','cn','dn', 'unicodePwd'));
152 assert(msg.length == 1); // TODO: should check with more records
153 assert(msg[0].cn == "Niemand");
154 assert(msg[0].unixName == "bin" || msg[0].unicodePwd == "geheim");
156 println("Checking for data in destination database");
157 msg = s3.db.search("(cn=Niemand)");
158 assert(msg.length >= 1);
159 assert(msg[0].sambaSID == "S-1-5-21-4231626423-2410014848-2360679739-2001");
160 assert(msg[0].displayName == "Niemand");
162 println("Adding attribute...");
164 dn: cn=Niemand,sambaDomainName=TESTS,dc=vernstok,dc=nl
171 println("Checking whether changes are still there...");
172 msg = ldb.search("(cn=Niemand)");
173 assert(msg.length >= 1);
174 assert(msg[0].cn == "Niemand");
175 assert(msg[0].description == "Blah");
177 println("Modifying attribute...");
179 dn: cn=Niemand,sambaDomainName=TESTS,dc=vernstok,dc=nl
186 println("Checking whether changes are still there...");
187 msg = ldb.search("(cn=Niemand)");
188 assert(msg.length >= 1);
189 assert(msg[0].description == "Blie");
191 println("Deleting attribute...");
193 dn: cn=Niemand,sambaDomainName=TESTS,dc=vernstok,dc=nl
199 println("Checking whether changes are no longer there...");
200 msg = ldb.search("(cn=Niemand)");
201 assert(msg.length >= 1);
202 assert(msg[0].description == undefined);
204 println("Renaming record...");
205 ok = ldb.rename("cn=Niemand,sambaDomainName=TESTS,dc=vernstok,dc=nl", "cn=Niemand,dc=vernstok,dc=nl");
207 println("Checking whether DN has changed...");
208 msg = ldb.search("(cn=Niemand)");
209 assert(msg.length == 1);
210 assert(msg[0].dn == "cn=Niemand,dc=vernstok,dc=nl");
212 println("Deleting record...");
213 ok = ldb.del("cn=Niemand,dc=vernstok,dc=nl");
216 println("Checking whether record is gone...");
217 msg = ldb.search("(cn=Niemand)");
218 assert(msg.length == 0);
221 function test_map_search(ldb, s3, s4)
223 println("Running search tests on mapped data");
228 /* Add a set of split records */
230 dn: cn=X,sambaDomainName=TESTS,${BASEDN}
239 objectSid: S-1-5-21-4231626423-2410014848-2360679739-552
240 primaryGroupID: 1-5-21-4231626423-2410014848-2360679739-512
242 dn: cn=Y,sambaDomainName=TESTS,${BASEDN}
252 dn: cn=Z,sambaDomainName=TESTS,${BASEDN}
262 ldif = substitute_var(ldif, s4);
263 assert(ldif != undefined);
264 var ok = ldb.add(ldif);
267 /* Add a set of remote records */
269 dn: cn=A,sambaDomainName=TESTS,${BASEDN}
270 objectClass: posixAccount
273 sambaBadPasswordCount: x
276 sambaSID: S-1-5-21-4231626423-2410014848-2360679739-552
277 sambaPrimaryGroupSID: S-1-5-21-4231626423-2410014848-2360679739-512
279 dn: cn=B,sambaDomainName=TESTS,${BASEDN}
283 sambaBadPasswordCount: x
287 dn: cn=C,sambaDomainName=TESTS,${BASEDN}
291 sambaBadPasswordCount: y
295 ldif = substitute_var(ldif, s3);
296 assert(ldif != undefined);
297 var ok = s3.db.add(ldif);
300 println("Testing search by DN");
302 /* Search remote record by local DN */
303 dn = "cn=A,sambaDomainName=TESTS," + s4.BASEDN;
304 attrs = new Array("objectCategory", "lastLogon");
305 res = ldb.search("", dn, ldb.SCOPE_BASE, attrs);
306 assert(res != undefined);
307 assert(res.length == 1);
308 assert(res[0].dn == dn);
309 assert(res[0].objectCategory == undefined);
310 assert(res[0].lastLogon == "x");
312 /* Search remote record by remote DN */
313 dn = "cn=A,sambaDomainName=TESTS," + s3.BASEDN;
314 attrs = new Array("objectCategory", "lastLogon", "sambaLogonTime");
315 res = s3.db.search("", dn, ldb.SCOPE_BASE, attrs);
316 assert(res != undefined);
317 assert(res.length == 1);
318 assert(res[0].dn == dn);
319 assert(res[0].objectCategory == undefined);
320 assert(res[0].lastLogon == undefined);
321 assert(res[0].sambaLogonTime == "x");
323 /* Search split record by local DN */
324 dn = "cn=X,sambaDomainName=TESTS," + s4.BASEDN;
325 attrs = new Array("objectCategory", "lastLogon");
326 res = ldb.search("", dn, ldb.SCOPE_BASE, attrs);
327 assert(res != undefined);
328 assert(res.length == 1);
329 assert(res[0].dn == dn);
330 assert(res[0].objectCategory == "x");
331 assert(res[0].lastLogon == "x");
333 /* Search split record by remote DN */
334 dn = "cn=X,sambaDomainName=TESTS," + s3.BASEDN;
335 attrs = new Array("objectCategory", "lastLogon", "sambaLogonTime");
336 res = s3.db.search("", dn, ldb.SCOPE_BASE, attrs);
337 assert(res != undefined);
338 assert(res.length == 1);
339 assert(res[0].dn == dn);
340 assert(res[0].objectCategory == undefined);
341 assert(res[0].lastLogon == undefined);
342 assert(res[0].sambaLogonTime == "x");
344 println("Testing search by attribute");
346 /* Search by ignored attribute */
347 attrs = new Array("objectCategory", "lastLogon");
348 res = ldb.search("(revision=x)", NULL, ldb. SCOPE_DEFAULT, attrs);
349 assert(res != undefined);
350 assert(res.length == 2);
351 assert(res[0].dn == ("cn=Y,sambaDomainName=TESTS," + s4.BASEDN));
352 assert(res[0].objectCategory == "y");
353 assert(res[0].lastLogon == "y");
354 assert(res[1].dn == ("cn=X,sambaDomainName=TESTS," + s4.BASEDN));
355 assert(res[1].objectCategory == "x");
356 assert(res[1].lastLogon == "x");
358 /* Search by kept attribute */
359 attrs = new Array("objectCategory", "lastLogon");
360 res = ldb.search("(description=y)", NULL, ldb. SCOPE_DEFAULT, attrs);
361 assert(res != undefined);
362 assert(res.length == 2);
363 assert(res[0].dn == ("cn=Z,sambaDomainName=TESTS," + s4.BASEDN));
364 assert(res[0].objectCategory == "z");
365 assert(res[0].lastLogon == "z");
366 assert(res[1].dn == ("cn=C,sambaDomainName=TESTS," + s4.BASEDN));
367 assert(res[1].objectCategory == undefined);
368 assert(res[1].lastLogon == "z");
370 /* Search by renamed attribute */
371 attrs = new Array("objectCategory", "lastLogon");
372 res = ldb.search("(badPwdCount=x)", NULL, ldb. SCOPE_DEFAULT, attrs);
373 assert(res != undefined);
374 assert(res.length == 2);
375 assert(res[0].dn == ("cn=B,sambaDomainName=TESTS," + s4.BASEDN));
376 assert(res[0].objectCategory == undefined);
377 assert(res[0].lastLogon == "y");
378 assert(res[1].dn == ("cn=A,sambaDomainName=TESTS," + s4.BASEDN));
379 assert(res[1].objectCategory == undefined);
380 assert(res[1].lastLogon == "x");
382 /* Search by converted attribute */
383 attrs = new Array("objectCategory", "lastLogon", "objectSid");
385 Using the SID directly in the parse tree leads to conversion
386 errors, letting the search fail with no results.
387 res = ldb.search("(objectSid=S-1-5-21-4231626423-2410014848-2360679739-552)", NULL, ldb. SCOPE_DEFAULT, attrs);
389 res = ldb.search("(objectSid=*)", NULL, ldb. SCOPE_DEFAULT, attrs);
390 assert(res != undefined);
391 assert(res.length == 2);
392 assert(res[0].dn == ("cn=X,sambaDomainName=TESTS," + s4.BASEDN));
393 assert(res[0].objectCategory == "x");
394 assert(res[0].lastLogon == "x");
395 assert(res[0].objectSid == "S-1-5-21-4231626423-2410014848-2360679739-552");
396 assert(res[1].dn == ("cn=A,sambaDomainName=TESTS," + s4.BASEDN));
397 assert(res[1].objectCategory == undefined);
398 assert(res[1].lastLogon == "x");
399 assert(res[1].objectSid == "S-1-5-21-4231626423-2410014848-2360679739-552");
401 /* Search by generated attribute */
402 /* In most cases, this even works when the mapping is missing
403 * a `convert_operator' by enumerating the remote db. */
404 attrs = new Array("objectCategory", "lastLogon", "primaryGroupID");
405 res = ldb.search("(primaryGroupID=1-5-21-4231626423-2410014848-2360679739-512)", NULL, ldb. SCOPE_DEFAULT, attrs);
406 assert(res != undefined);
407 assert(res.length == 1);
408 assert(res[0].dn == ("cn=A,sambaDomainName=TESTS," + s4.BASEDN));
409 assert(res[0].objectCategory == undefined);
410 assert(res[0].lastLogon == "x");
411 assert(res[0].primaryGroupID == "1-5-21-4231626423-2410014848-2360679739-512");
413 /* TODO: There should actually be two results, A and X. The
414 * primaryGroupID of X seems to get corrupted somewhere, and the
415 * objectSid isn't available during the generation of remote (!) data,
416 * which can be observed with the following search. Also note that Xs
417 * objectSid seems to be fine in the previous search for objectSid... */
419 res = ldb.search("(primaryGroupID=*)", NULL, ldb. SCOPE_DEFAULT, attrs);
420 println(res.length + " results found");
421 for (i=0;i<res.length;i++) {
422 for (obj in res[i]) {
423 println(obj + ": " + res[i][obj]);
429 /* Search by remote name of renamed attribute */
430 attrs = new Array("objectCategory", "lastLogon");
431 res = ldb.search("(sambaBadPasswordCount=*)", "", ldb. SCOPE_DEFAULT, attrs);
432 assert(res != undefined);
433 assert(res.length == 0);
435 /* Search by objectClass */
436 attrs = new Array("objectCategory", "lastLogon", "objectClass");
437 res = ldb.search("(objectClass=user)", NULL, ldb. SCOPE_DEFAULT, attrs);
438 assert(res != undefined);
439 assert(res.length == 2);
440 assert(res[0].dn == ("cn=X,sambaDomainName=TESTS," + s4.BASEDN));
441 assert(res[0].objectCategory == "x");
442 assert(res[0].lastLogon == "x");
443 assert(res[0].objectClass != undefined);
444 assert(res[0].objectClass[3] == "user");
445 assert(res[1].dn == ("cn=A,sambaDomainName=TESTS," + s4.BASEDN));
446 assert(res[1].objectCategory == undefined);
447 assert(res[1].lastLogon == "x");
448 assert(res[1].objectClass != undefined);
449 assert(res[1].objectClass[0] == "user");
451 /* Prove that the objectClass is actually used for the search */
452 res = ldb.search("(|(objectClass=user)(badPwdCount=x))", NULL, ldb. SCOPE_DEFAULT, attrs);
453 assert(res != undefined);
454 assert(res.length == 3);
455 assert(res[0].dn == ("cn=B,sambaDomainName=TESTS," + s4.BASEDN));
456 assert(res[0].objectCategory == undefined);
457 assert(res[0].lastLogon == "y");
458 assert(res[0].objectClass != undefined);
459 for (i=0;i<res[0].objectClass.length;i++) {
460 assert(res[0].objectClass[i] != "user");
462 assert(res[1].dn == ("cn=X,sambaDomainName=TESTS," + s4.BASEDN));
463 assert(res[1].objectCategory == "x");
464 assert(res[1].lastLogon == "x");
465 assert(res[1].objectClass != undefined);
466 assert(res[1].objectClass[3] == "user");
467 assert(res[2].dn == ("cn=A,sambaDomainName=TESTS," + s4.BASEDN));
468 assert(res[2].objectCategory == undefined);
469 assert(res[2].lastLogon == "x");
470 assert(res[2].objectClass != undefined);
471 assert(res[2].objectClass[0] == "user");
473 println("Testing search by parse tree");
475 /* Search by conjunction of local attributes */
476 attrs = new Array("objectCategory", "lastLogon");
477 res = ldb.search("(&(codePage=x)(revision=x))", NULL, ldb.SCOPE_DEFAULT, attrs);
478 assert(res != undefined);
479 assert(res.length == 2);
480 assert(res[0].dn == ("cn=Y,sambaDomainName=TESTS," + s4.BASEDN));
481 assert(res[0].objectCategory == "y");
482 assert(res[0].lastLogon == "y");
483 assert(res[1].dn == ("cn=X,sambaDomainName=TESTS," + s4.BASEDN));
484 assert(res[1].objectCategory == "x");
485 assert(res[1].lastLogon == "x");
487 /* Search by conjunction of remote attributes */
488 attrs = new Array("objectCategory", "lastLogon");
489 res = ldb.search("(&(lastLogon=x)(description=x))", NULL, ldb.SCOPE_DEFAULT, attrs);
490 assert(res != undefined);
491 assert(res.length == 2);
492 assert(res[0].dn == ("cn=X,sambaDomainName=TESTS," + s4.BASEDN));
493 assert(res[0].objectCategory == "x");
494 assert(res[0].lastLogon == "x");
495 assert(res[1].dn == ("cn=A,sambaDomainName=TESTS," + s4.BASEDN));
496 assert(res[1].objectCategory == undefined);
497 assert(res[1].lastLogon == "x");
499 /* Search by conjunction of local and remote attribute */
500 attrs = new Array("objectCategory", "lastLogon");
501 res = ldb.search("(&(codePage=x)(description=x))", NULL, ldb.SCOPE_DEFAULT, attrs);
502 assert(res != undefined);
503 assert(res.length == 2);
504 assert(res[0].dn == ("cn=Y,sambaDomainName=TESTS," + s4.BASEDN));
505 assert(res[0].objectCategory == "y");
506 assert(res[0].lastLogon == "y");
507 assert(res[1].dn == ("cn=X,sambaDomainName=TESTS," + s4.BASEDN));
508 assert(res[1].objectCategory == "x");
509 assert(res[1].lastLogon == "x");
511 /* Search by conjunction of local and remote attribute w/o match */
512 attrs = new Array("objectCategory", "lastLogon");
513 res = ldb.search("(&(codePage=x)(nextRid=x))", NULL, ldb.SCOPE_DEFAULT, attrs);
514 assert(res != undefined);
515 assert(res.length == 0);
516 res = ldb.search("(&(revision=x)(lastLogon=z))", NULL, ldb.SCOPE_DEFAULT, attrs);
517 assert(res != undefined);
518 assert(res.length == 0);
520 /* Search by disjunction of local attributes */
521 attrs = new Array("objectCategory", "lastLogon");
522 res = ldb.search("(|(revision=x)(objectCategory=x))", NULL, ldb.SCOPE_DEFAULT, attrs);
523 assert(res != undefined);
524 assert(res.length == 2);
525 assert(res[0].dn == ("cn=Y,sambaDomainName=TESTS," + s4.BASEDN));
526 assert(res[0].objectCategory == "y");
527 assert(res[0].lastLogon == "y");
528 assert(res[1].dn == ("cn=X,sambaDomainName=TESTS," + s4.BASEDN));
529 assert(res[1].objectCategory == "x");
530 assert(res[1].lastLogon == "x");
532 /* Search by disjunction of remote attributes */
533 attrs = new Array("objectCategory", "lastLogon");
534 res = ldb.search("(|(badPwdCount=x)(lastLogon=x))", NULL, ldb.SCOPE_DEFAULT, attrs);
535 assert(res != undefined);
536 assert(res.length == 3);
537 assert(res[0].dn == ("cn=B,sambaDomainName=TESTS," + s4.BASEDN));
538 assert(res[0].objectCategory == undefined);
539 assert(res[0].lastLogon == "y");
540 assert(res[1].dn == ("cn=X,sambaDomainName=TESTS," + s4.BASEDN));
541 assert(res[1].objectCategory == "x");
542 assert(res[1].lastLogon == "x");
543 assert(res[2].dn == ("cn=A,sambaDomainName=TESTS," + s4.BASEDN));
544 assert(res[2].objectCategory == undefined);
545 assert(res[2].lastLogon == "x");
547 /* Search by disjunction of local and remote attribute */
548 attrs = new Array("objectCategory", "lastLogon");
549 res = ldb.search("(|(revision=x)(lastLogon=y))", NULL, ldb.SCOPE_DEFAULT, attrs);
550 assert(res != undefined);
551 assert(res.length == 3);
552 assert(res[0].dn == ("cn=Y,sambaDomainName=TESTS," + s4.BASEDN));
553 assert(res[0].objectCategory == "y");
554 assert(res[0].lastLogon == "y");
555 assert(res[1].dn == ("cn=B,sambaDomainName=TESTS," + s4.BASEDN));
556 assert(res[1].objectCategory == undefined);
557 assert(res[1].lastLogon == "y");
558 assert(res[2].dn == ("cn=X,sambaDomainName=TESTS," + s4.BASEDN));
559 assert(res[2].objectCategory == "x");
560 assert(res[2].lastLogon == "x");
562 /* Search by disjunction of local and remote attribute w/o match */
563 attrs = new Array("objectCategory", "lastLogon");
564 res = ldb.search("(|(codePage=y)(nextRid=z))", NULL, ldb.SCOPE_DEFAULT, attrs);
565 assert(res != undefined);
566 assert(res.length == 0);
568 /* Search by negated local attribute */
569 attrs = new Array("objectCategory", "lastLogon");
570 res = ldb.search("(!(revision=x))", NULL, ldb.SCOPE_DEFAULT, attrs);
571 assert(res != undefined);
572 assert(res.length == 4);
573 assert(res[0].dn == ("cn=B,sambaDomainName=TESTS," + s4.BASEDN));
574 assert(res[0].objectCategory == undefined);
575 assert(res[0].lastLogon == "y");
576 assert(res[1].dn == ("cn=A,sambaDomainName=TESTS," + s4.BASEDN));
577 assert(res[1].objectCategory == undefined);
578 assert(res[1].lastLogon == "x");
579 assert(res[2].dn == ("cn=Z,sambaDomainName=TESTS," + s4.BASEDN));
580 assert(res[2].objectCategory == "z");
581 assert(res[2].lastLogon == "z");
582 assert(res[3].dn == ("cn=C,sambaDomainName=TESTS," + s4.BASEDN));
583 assert(res[3].objectCategory == undefined);
584 assert(res[3].lastLogon == "z");
586 /* Search by negated remote attribute */
587 attrs = new Array("objectCategory", "lastLogon");
588 res = ldb.search("(!(description=x))", NULL, ldb.SCOPE_DEFAULT, attrs);
589 assert(res != undefined);
590 assert(res.length == 2);
591 assert(res[0].dn == ("cn=Z,sambaDomainName=TESTS," + s4.BASEDN));
592 assert(res[0].objectCategory == "z");
593 assert(res[0].lastLogon == "z");
594 assert(res[1].dn == ("cn=C,sambaDomainName=TESTS," + s4.BASEDN));
595 assert(res[1].objectCategory == undefined);
596 assert(res[1].lastLogon == "z");
598 /* Search by negated conjunction of local attributes */
599 attrs = new Array("objectCategory", "lastLogon");
600 res = ldb.search("(!(&(codePage=x)(revision=x)))", NULL, ldb.SCOPE_DEFAULT, attrs);
601 assert(res != undefined);
602 assert(res.length == 4);
603 assert(res[0].dn == ("cn=B,sambaDomainName=TESTS," + s4.BASEDN));
604 assert(res[0].objectCategory == undefined);
605 assert(res[0].lastLogon == "y");
606 assert(res[1].dn == ("cn=A,sambaDomainName=TESTS," + s4.BASEDN));
607 assert(res[1].objectCategory == undefined);
608 assert(res[1].lastLogon == "x");
609 assert(res[2].dn == ("cn=Z,sambaDomainName=TESTS," + s4.BASEDN));
610 assert(res[2].objectCategory == "z");
611 assert(res[2].lastLogon == "z");
612 assert(res[3].dn == ("cn=C,sambaDomainName=TESTS," + s4.BASEDN));
613 assert(res[3].objectCategory == undefined);
614 assert(res[3].lastLogon == "z");
616 /* Search by negated conjunction of remote attributes */
617 attrs = new Array("objectCategory", "lastLogon");
618 res = ldb.search("(!(&(lastLogon=x)(description=x)))", NULL, ldb.SCOPE_DEFAULT, attrs);
619 assert(res != undefined);
620 assert(res.length == 4);
621 assert(res[0].dn == ("cn=Y,sambaDomainName=TESTS," + s4.BASEDN));
622 assert(res[0].objectCategory == "y");
623 assert(res[0].lastLogon == "y");
624 assert(res[1].dn == ("cn=B,sambaDomainName=TESTS," + s4.BASEDN));
625 assert(res[1].objectCategory == undefined);
626 assert(res[1].lastLogon == "y");
627 assert(res[2].dn == ("cn=Z,sambaDomainName=TESTS," + s4.BASEDN));
628 assert(res[2].objectCategory == "z");
629 assert(res[2].lastLogon == "z");
630 assert(res[3].dn == ("cn=C,sambaDomainName=TESTS," + s4.BASEDN));
631 assert(res[3].objectCategory == undefined);
632 assert(res[3].lastLogon == "z");
634 /* Search by negated conjunction of local and remote attribute */
635 attrs = new Array("objectCategory", "lastLogon");
636 res = ldb.search("(!(&(codePage=x)(description=x)))", NULL, ldb.SCOPE_DEFAULT, attrs);
637 assert(res != undefined);
638 assert(res.length == 4);
639 assert(res[0].dn == ("cn=B,sambaDomainName=TESTS," + s4.BASEDN));
640 assert(res[0].objectCategory == undefined);
641 assert(res[0].lastLogon == "y");
642 assert(res[1].dn == ("cn=A,sambaDomainName=TESTS," + s4.BASEDN));
643 assert(res[1].objectCategory == undefined);
644 assert(res[1].lastLogon == "x");
645 assert(res[2].dn == ("cn=Z,sambaDomainName=TESTS," + s4.BASEDN));
646 assert(res[2].objectCategory == "z");
647 assert(res[2].lastLogon == "z");
648 assert(res[3].dn == ("cn=C,sambaDomainName=TESTS," + s4.BASEDN));
649 assert(res[3].objectCategory == undefined);
650 assert(res[3].lastLogon == "z");
652 /* Search by negated disjunction of local attributes */
653 attrs = new Array("objectCategory", "lastLogon");
654 res = ldb.search("(!(|(revision=x)(objectCategory=x)))", NULL, ldb.SCOPE_DEFAULT, attrs);
655 assert(res != undefined);
656 assert(res[0].dn == ("cn=B,sambaDomainName=TESTS," + s4.BASEDN));
657 assert(res[0].objectCategory == undefined);
658 assert(res[0].lastLogon == "y");
659 assert(res[1].dn == ("cn=A,sambaDomainName=TESTS," + s4.BASEDN));
660 assert(res[1].objectCategory == undefined);
661 assert(res[1].lastLogon == "x");
662 assert(res[2].dn == ("cn=Z,sambaDomainName=TESTS," + s4.BASEDN));
663 assert(res[2].objectCategory == "z");
664 assert(res[2].lastLogon == "z");
665 assert(res[3].dn == ("cn=C,sambaDomainName=TESTS," + s4.BASEDN));
666 assert(res[3].objectCategory == undefined);
667 assert(res[3].lastLogon == "z");
669 /* Search by negated disjunction of remote attributes */
670 attrs = new Array("objectCategory", "lastLogon");
671 res = ldb.search("(!(|(badPwdCount=x)(lastLogon=x)))", NULL, ldb.SCOPE_DEFAULT, attrs);
672 assert(res != undefined);
673 assert(res.length == 3);
674 assert(res[0].dn == ("cn=Y,sambaDomainName=TESTS," + s4.BASEDN));
675 assert(res[0].objectCategory == "y");
676 assert(res[0].lastLogon == "y");
677 assert(res[1].dn == ("cn=Z,sambaDomainName=TESTS," + s4.BASEDN));
678 assert(res[1].objectCategory == "z");
679 assert(res[1].lastLogon == "z");
680 assert(res[2].dn == ("cn=C,sambaDomainName=TESTS," + s4.BASEDN));
681 assert(res[2].objectCategory == undefined);
682 assert(res[2].lastLogon == "z");
684 /* Search by negated disjunction of local and remote attribute */
685 attrs = new Array("objectCategory", "lastLogon");
686 res = ldb.search("(!(|(revision=x)(lastLogon=y)))", NULL, ldb.SCOPE_DEFAULT, attrs);
687 assert(res != undefined);
688 assert(res.length == 3);
689 assert(res[0].dn == ("cn=A,sambaDomainName=TESTS," + s4.BASEDN));
690 assert(res[0].objectCategory == undefined);
691 assert(res[0].lastLogon == "x");
692 assert(res[1].dn == ("cn=Z,sambaDomainName=TESTS," + s4.BASEDN));
693 assert(res[1].objectCategory == "z");
694 assert(res[1].lastLogon == "z");
695 assert(res[2].dn == ("cn=C,sambaDomainName=TESTS," + s4.BASEDN));
696 assert(res[2].objectCategory == undefined);
697 assert(res[2].lastLogon == "z");
699 /* Search by complex parse tree */
700 attrs = new Array("objectCategory", "lastLogon");
701 res = ldb.search("(|(&(revision=x)(objectCategory=x))(!(&(description=x)(nextRid=y)))(badPwdCount=y))", NULL, ldb.SCOPE_DEFAULT, attrs);
702 assert(res != undefined);
703 assert(res.length == 5);
704 assert(res[0].dn == ("cn=B,sambaDomainName=TESTS," + s4.BASEDN));
705 assert(res[0].objectCategory == undefined);
706 assert(res[0].lastLogon == "y");
707 assert(res[1].dn == ("cn=X,sambaDomainName=TESTS," + s4.BASEDN));
708 assert(res[1].objectCategory == "x");
709 assert(res[1].lastLogon == "x");
710 assert(res[2].dn == ("cn=A,sambaDomainName=TESTS," + s4.BASEDN));
711 assert(res[2].objectCategory == undefined);
712 assert(res[2].lastLogon == "x");
713 assert(res[3].dn == ("cn=Z,sambaDomainName=TESTS," + s4.BASEDN));
714 assert(res[3].objectCategory == "z");
715 assert(res[3].lastLogon == "z");
716 assert(res[4].dn == ("cn=C,sambaDomainName=TESTS," + s4.BASEDN));
717 assert(res[4].objectCategory == undefined);
718 assert(res[4].lastLogon == "z");
722 var ldbfile = prefix + "/" + "test.ldb";
723 var ldburl = "tdb://" + ldbfile;
725 var samba4 = new Object("samba4 partition info");
726 samba4.file = prefix + "/" + "samba4.ldb";
727 samba4.url = "tdb://" + samba4.file;
728 samba4.BASEDN = "dc=vernstok,dc=nl";
729 samba4.db = ldb_init();
731 var samba3 = new Object("samba3 partition info");
732 samba3.file = prefix + "/" + "samba3.ldb";
733 samba3.url = "tdb://" + samba3.file;
734 samba3.BASEDN = "cn=Samba3Sam," + samba4.BASEDN;
735 samba3.db = ldb_init();
738 sys.unlink(samba3.file);
739 sys.unlink(samba4.file);
741 var ok = ldb.connect(ldburl);
743 var ok = samba3.db.connect(samba3.url);
745 var ok = samba4.db.connect(samba4.url);
748 setup_data(samba3, sys.file_load(datadir + "/" + "samba3.ldif"));
749 setup_modules(ldb, samba3, samba4, sys.file_load(datadir + "/" + "provision_samba3sam.ldif"));
752 var ok = ldb.connect(ldburl);
755 test_s3sam_search(ldb);
756 test_s3sam_modify(ldb, samba3);
759 sys.unlink(samba3.file);
760 sys.unlink(samba4.file);
763 var ok = ldb.connect(ldburl);
765 samba3.db = ldb_init();
766 var ok = samba3.db.connect(samba3.url);
768 samba4.db = ldb_init();
769 var ok = samba4.db.connect(samba4.url);
772 setup_modules(ldb, samba3, samba4, sys.file_load(datadir + "provision_samba3sam.ldif"));
775 var ok = ldb.connect(ldburl);
778 test_map_search(ldb, samba3, samba4);
781 sys.unlink(samba3.file);
782 sys.unlink(samba4.file);