#!/bin/sh exec smbscript "$0" ${1+"$@"} /* demonstrate access to ldb databases from ejs */ var ldb = ldb_init(); var sys; var options = GetOptions(ARGV, "POPT_AUTOHELP", "POPT_COMMON_SAMBA"); if (options == undefined) { println("Failed to parse options"); return -1; } libinclude("base.js"); if (options.ARGV.length != 1) { println("Usage: ldb.js <prefix>"); return -1; } prefix = options.ARGV[0]; function basic_tests(ldb) { println("Running basic tests"); ok = ldb.add(" dn: cn=x,cn=test objectClass: foo x: 3 "); assert(ok.error == 0); println("Testing ldb.search"); var res = ldb.search("(objectClass=*)"); assert(res.msgs[0].objectClass[0] == "foo"); assert(res.msgs[0].dn == "cn=x,cn=test"); assert(res.msgs[0].x == 3); ok = ldb.add(" dn: cn=x2,cn=test objectClass: foo x: 4 "); assert(ok.error == 0); var attrs = new Array("x"); res = ldb.search("x=4", NULL, ldb.SCOPE_DEFAULT, attrs); assert(res.msgs[0].x == 4); assert(res.msgs[0].objectClass == undefined); assert(res.msgs[0].dn == "cn=x2,cn=test"); ok = ldb.del("cn=x,cn=test"); assert(ok.error == 0); ok = ldb.rename("cn=x2,cn=test", "cn=x3,cn=test"); assert(ok.error == 0); res = ldb.search("x=4", NULL, ldb.SCOPE_DEFAULT, attrs); assert(res.msgs[0].dn == "cn=x3,cn=test"); ok = ldb.rename("cn=x3,cn=test", "cn=X3,cn=test"); assert(ok.error == 0); res = ldb.search("x=4", NULL, ldb.SCOPE_DEFAULT, attrs); assert(res.msgs[0].dn == "cn=X3,cn=test"); ok = ldb.modify(" dn: cn=x3,cn=test changetype: modify add: x x: 7 "); res = ldb.search("x=7"); assert(res.msgs.length == 1); assert(res.msgs[0].x.length == 2); /* Check a few things before we add modules */ assert(res.msgs[0].objectGUID == undefined); assert(res.msgs[0].createTimestamp == undefined); assert(res.msgs[0].whenCreated == undefined); } function setup_modules(ldb) { ok = ldb.add(" dn: @MODULES @LIST: rootdse,operational,rdn_name,partition dn: @ROOTDSE defaultNamingContext: cn=Test dn: @PARTITION partition: cn=SideTest:" + prefix + "/" + "testside.ldb partition: cn=Sub,cn=PartTest:" + prefix + "/" + "testsub.ldb partition: cn=PartTest:" + prefix + "/" + "testpartition.ldb partition: cn=Sub,cn=Sub,cn=PartTest:" + prefix + "/" + "testsubsub.ldb replicateEntries: @ATTRIBUTES replicateEntries: @INDEXLIST modules: cn=PartTest:objectguid "); } /* Test the basic operation of the timestamps,objectguid and name_rdn modules */ function modules_test(ldb, parttestldb) { println("Running modules tests"); ok = ldb.add(" dn: @ATTRIBUTES cn: CASE_INSENSITIVE caseattr: CASE_INSENSITIVE "); if (ok.error != 0) { println("Failed to add: " + ok.errstr); assert(ok.error == 0); } /* Confirm that the attributes were replicated */ var res_attrs = parttestldb.search("cn=*", "@ATTRIBUTES", parttestldb.SCOPE_BASE); assert(res_attrs.msgs[0].cn == "CASE_INSENSITIVE"); ok = ldb.add(" dn: cn=x8,cn=PartTest objectClass: foo x: 8 "); if (ok.error != 0) { println("Failed to add: " + ok.errstr); assert(ok.error == 0); } ok = ldb.add(" dn: cn=x9,cn=PartTest objectClass: foo x: 9 cn: X9 "); if (ok.error != 0) { println("Failed to add: " + ok.errstr); assert(ok.error == 0); } ok = ldb.add(" dn: cn=X9,cn=PartTest objectClass: foo x: 9 cn: X9 "); if (ok.error == 0) { println("Should have failed to add cn=X9,cn=PartTest"); assert(ok.error != 0); } var res = ldb.search("x=8", "cn=PartTest", ldb.SCOPE_DEFAULT); assert(res.msgs[0].objectGUID != undefined); assert(res.msgs[0].uSNCreated != undefined); assert(res.msgs[0].uSNChanged != undefined); assert(res.msgs[0].createTimestamp == undefined); assert(res.msgs[0].whenCreated != undefined); assert(res.msgs[0].name == "x8"); assert(res.msgs[0].cn == "x8"); /* Confirm that this ended up in the correct LDB */ var res_otherldb = parttestldb.search("x=8", "cn=PartTest", parttestldb.SCOPE_DEFAULT); assert(res_otherldb.msgs[0].objectGUID != undefined); assert(res_otherldb.msgs[0].createTimestamp == undefined); assert(res_otherldb.msgs[0].whenCreated != undefined); assert(res_otherldb.msgs[0].name == "x8"); assert(res_otherldb.msgs[0].cn == "x8"); var attrs = new Array("*", "createTimestamp"); var res2 = ldb.search("x=9", "cn=PartTest", ldb.SCOPE_DEFAULT, attrs); assert(res2.msgs[0].objectGUID != undefined); assert(res2.msgs[0].createTimestamp != undefined); assert(res2.msgs[0].whenCreated != undefined); assert(res2.msgs[0].name == "x9"); assert(res2.msgs[0].cn == "x9"); assert(res.msgs[0].objectGUID != res2.msgs[0].objectGUID); var attrs = new Array("*"); var res3 = ldb.search("", "", ldb.SCOPE_BASE, attrs); assert(res3.msgs[0].cn == undefined); assert(res3.msgs[0].distinguishedName == undefined); assert(res3.msgs[0].name == undefined); assert(res3.msgs[0].currentTime != undefined); assert(res3.msgs[0].highestCommittedUSN != undefined); assert(res3.msgs[0].namingContexts[0] == "cn=Sub,cn=Sub,cn=PartTest"); assert(res3.msgs[0].namingContexts[1] == "cn=Sub,cn=PartTest"); assert(res3.msgs[0].namingContexts[2] == "cn=PartTest"); assert(res3.msgs[0].namingContexts[3] == "cn=SideTest"); var usn = res3.msgs[0].highestCommittedUSN; /* Start a transaction. We are going to abort it later, to * show we clean up all partitions */ ok = ldb.transaction_start() if (!ok) { println("Failed to start a transaction: " + ok.errstr); assert(ok.error == 0); } ok = ldb.add(" dn: cn=x10,cn=parttest objectClass: foo x: 10 "); if (ok.error != 0) { println("Failed to add: " + ok.errstr); assert(ok.error == 0); } var attrs = new Array("highestCommittedUSN"); var res4 = ldb.search("", "", ldb.SCOPE_BASE, attrs); var usn2 = res4.msgs[0].highestCommittedUSN; assert(usn < res4.msgs[0].highestCommittedUSN); ok = ldb.add(" dn: cn=x11,cn=sub,cn=parttest objectClass: foo x: 11 "); if (ok.error != 0) { println("Failed to add: " + ok.errstr); assert(ok.error == 0); } var attrs = new Array("highestCommittedUSN"); var res5 = ldb.search("", "", ldb.SCOPE_BASE, attrs); assert(usn2 < res5.msgs[0].highestCommittedUSN); var attrs = new Array("*", "createTimestamp"); var res6 = ldb.search("x=11", "cn=parttest", ldb.SCOPE_SUB, attrs); assert(res6.msgs.length == 0); var attrs = new Array("*", "createTimestamp"); var res7 = ldb.search("x=10", "cn=sub,cn=parttest", ldb.SCOPE_DEFAULT, attrs); assert(res7.msgs.length == 0); var res8 = ldb.search("x=11", "cn=sub,cn=parttest", ldb.SCOPE_DEFAULT, attrs); assert(res8.msgs[0].objectGUID == undefined); /* The objectGUID module is not loaded here */ assert(res8.msgs[0].uSNCreated == undefined); /* The objectGUID module is not loaded here */ assert(res8.msgs[0].name == "x11"); assert(res8.msgs[0].cn == "x11"); ok = ldb.add(" dn: caseattr=XY,cn=PartTest objectClass: foo x: Y "); if (ok.error != 0) { println("Failed to add: " + ok.errstr); assert(ok.error == 0); } ok = ldb.add(" dn: caseattr=XZ,cn=PartTest objectClass: foo x: Z caseattr: XZ "); if (ok.error != 0) { println("Failed to add: " + ok.errstr); assert(ok.error == 0); } ok = ldb.add(" dn: caseattr=xz,cn=PartTest objectClass: foo x: Z caseattr: xz "); if (ok.error == 0) { println("Should have failed to add caseattr=xz,cn=PartTest"); assert(ok.error != 0); } ok = ldb.add(" dn: caseattr2=XZ,cn=PartTest objectClass: foo x: Z caseattr2: XZ "); if (ok.error != 0) { println("Failed to add: " + ok.errstr); assert(ok.error == 0); } ok = ldb.add(" dn: caseattr2=Xz,cn=PartTest objectClass: foo x: Z caseattr2: Xz "); if (ok.error != 0) { println("Failed to add: " + ok.errstr); assert(ok.error == 0); } var resX = ldb.search("caseattr=xz", "cn=parttest", ldb.SCOPE_DEFAULT, attrs); assert(resX.msgs.length == 1); assert(resX.msgs[0].objectGUID != undefined); assert(resX.msgs[0].createTimestamp != undefined); assert(resX.msgs[0].whenCreated != undefined); assert(resX.msgs[0].name == "XZ"); var rescount = ldb.search("(|(caseattr=*)(cn=*))", "cn=parttest", ldb.SCOPE_DEFAULT, attrs); assert(rescount.msgs.length == 5); /* Check this attribute is *not* case sensitive */ var resXcount = ldb.search("caseattr=x*", "cn=parttest", ldb.SCOPE_DEFAULT, attrs); assert(resXcount.msgs.length == 2); /* Check that this attribute *is* case sensitive */ var resXcount2 = ldb.search("caseattr2=xz", "cn=parttest", ldb.SCOPE_DEFAULT, attrs); assert(resXcount2.msgs.length == 0); /* Now abort the transaction to show that even with * partitions, it is aborted everywhere */ ok = ldb.transaction_cancel(); if (!ok) { println("Failed to cancel a transaction: " + ok.errstr); assert(ok); } /* now check it all went away */ var attrs = new Array("highestCommittedUSN"); var res9 = ldb.search("", "", ldb.SCOPE_BASE, attrs); assert(usn == res9.msgs[0].highestCommittedUSN); var attrs = new Array("*"); var res10 = ldb.search("x=11", "cn=sub,cn=parttest", ldb.SCOPE_DEFAULT, attrs); assert(res10.msgs.length == 0); var attrs = new Array("*"); var res11 = ldb.search("x=10", "cn=parttest", ldb.SCOPE_DEFAULT, attrs); assert(res11.msgs.length == 0); var attrs = new Array("*"); var res12 = ldb.search("caseattr=*", "cn=parttest", ldb.SCOPE_DEFAULT, attrs); assert(res12.msgs.length == 0); } sys = sys_init(); var dbfile = "test.ldb"; sys.unlink(prefix + "/" + dbfile); sys.unlink(prefix + "/" + "testpartition.ldb"); sys.unlink(prefix + "/" + "testsub.ldb"); sys.unlink(prefix + "/" + "testsubsub.ldb"); sys.unlink(prefix + "/" + "testside.ldb"); var ok = ldb.connect("tdb://" + prefix + "/" + dbfile); assert(ok); basic_tests(ldb); setup_modules(ldb); ldb = ldb_init(); var ok = ldb.connect("tdb://" + prefix + "/" + dbfile); assert(ok); parttestldb = ldb_init(); var ok = parttestldb.connect("tdb://" + prefix + "/" + "testpartition.ldb"); assert(ok); modules_test(ldb, parttestldb); sys.unlink(prefix + "/" + dbfile); sys.unlink(prefix + "/" + "testpartition.ldb"); sys.unlink(prefix + "/" + "testsub.ldb"); sys.unlink(prefix + "/" + "testsubsub.ldb"); sys.unlink(prefix + "/" + "testside.ldb"); return 0;