def test_delete_w_unhandled_ctrl(self): l = ldb.Ldb(filename()) m = ldb.Message() m.dn = ldb.Dn(l, "dc=foo1") m["b"] = [b"a"] l.add(m) self.assertRaises(ldb.LdbError, lambda: l.delete(m.dn, ["search_options:1:2"])) l.delete(m.dn)
def test_add_dict_string_dn(self): l = ldb.Ldb(filename()) m = {"dn": "dc=foo6", "bla": "bla"} self.assertEquals(len(l.search()), 1) l.add(m) try: self.assertEquals(len(l.search()), 2) finally: l.delete(ldb.Dn(l, "dc=foo6"))
def test_add_dict(self): l = ldb.Ldb(filename()) m = {"dn": ldb.Dn(l, "dc=foo5"), "bla": "bla"} self.assertEquals(len(l.search()), 0) l.add(m) try: self.assertEquals(len(l.search()), 1) finally: l.delete(ldb.Dn(l, "dc=foo5"))
def test_add_dict_bytes_dn(self): l = ldb.Ldb(filename()) m = {"dn": b"dc=foo6", "bla": b"bla"} self.assertEqual(len(l.search()), 0) l.add(m) try: self.assertEqual(len(l.search()), 1) finally: l.delete(ldb.Dn(l, "dc=foo6"))
def test_add_text(self): l = ldb.Ldb(filename()) m = ldb.Message() m.dn = ldb.Dn(l, "dc=foo4") m["bla"] = "bla" self.assertEqual(len(l.search()), 0) l.add(m) try: self.assertEqual(len(l.search()), 1) finally: l.delete(ldb.Dn(l, "dc=foo4"))
def test_msg_diff(self): l = ldb.Ldb() msgs = l.parse_ldif( "dn: foo=bar\nfoo: bar\nbaz: do\n\ndn: foo=bar\nfoo: bar\nbaz: dont\n" ) msg1 = next(msgs)[1] msg2 = next(msgs)[1] msgdiff = l.msg_diff(msg1, msg2) self.assertEqual("foo=bar", msgdiff.get("dn").__str__()) self.assertRaises(KeyError, lambda: msgdiff["foo"]) self.assertEqual(1, len(msgdiff))
def test_use_module(self): ops = [] class ExampleModule: name = "bla" def __init__(self, ldb, next): ops.append("init") self.next = next def search(self, *args, **kwargs): return self.next.search(*args, **kwargs) ldb.register_module(ExampleModule) if os.path.exists("usemodule.ldb"): os.unlink("usemodule.ldb") l = ldb.Ldb("usemodule.ldb") l.add({"dn": "@MODULES", "@LIST": "bla"}) self.assertEquals([], ops) l = ldb.Ldb("usemodule.ldb") self.assertEquals(["init"], ops)
def test_rename(self): l = ldb.Ldb(filename()) m = ldb.Message() m.dn = ldb.Dn(l, "dc=foo7") m["bla"] = b"bla" self.assertEqual(len(l.search()), 0) l.add(m) try: l.rename(ldb.Dn(l, "dc=foo7"), ldb.Dn(l, "dc=bar")) self.assertEqual(len(l.search()), 1) finally: l.delete(ldb.Dn(l, "dc=bar"))
def test_zero_byte_string(self): """Testing we do not get trapped in the \0 byte in a property string.""" l = ldb.Ldb(filename()) l.add({ "dn": b"dc=somedn", "objectclass": b"user", "cN": b"LDAPtestUSER", "givenname": b"ldap", "displayname": b"foo\0bar", }) res = l.search(expression="(dn=dc=somedn)") self.assertEqual(b"foo\0bar", res[0]["displayname"][0])
def setup_premade_v1_db(self): db_name = "guidindexpackv1.ldb" this_file_dir = os.path.dirname(os.path.abspath(__file__)) db_path = os.path.join(this_file_dir, "../", db_name) self.testdir = tempdir() self.filename = os.path.join(self.testdir, db_name) shutil.copy(db_path, self.filename) url = self.prefix + self.filename self.l = ldb.Ldb(url, options=["modules:"]) self.num_recs_added = 10
def test_rename_string_dns(self): l = ldb.Ldb(filename()) m = ldb.Message() m.dn = ldb.Dn(l, "dc=foo8") m["bla"] = "bla" self.assertEquals(len(l.search()), 1) l.add(m) self.assertEquals(len(l.search()), 2) try: l.rename("dc=foo8", "dc=bar") self.assertEquals(len(l.search()), 2) finally: l.delete(ldb.Dn(l, "dc=bar"))
def _create_dbconn(self, cache_type, domain_name): if cache_type == CacheType.sysdb: db_path = os.path.join(config.DB_PATH, "cache_%s.ldb" % domain_name) elif cache_type == CacheType.timestamps: db_path = os.path.join(config.DB_PATH, "timestamps_%s.ldb" % domain_name) else: raise ValueError("Unknown cache type\n") pyldb = ldb.Ldb() pyldb.connect(db_path) return pyldb
def test_equal_simplel(self): db = ldb.Ldb(filename()) msg1 = ldb.Message() msg1.dn = ldb.Dn(db, "foo=bar") msg2 = ldb.Message() msg2.dn = ldb.Dn(db, "foo=bar") self.assertEqual(msg1, msg2) msg1['foo'] = b'bar' msg2['foo'] = b'bar' self.assertEqual(msg1, msg2) msg2['foo'] = b'blie' self.assertNotEqual(msg1, msg2) msg2['foo'] = b'blie'
def test_empty_dn(self): l = ldb.Ldb(filename()) self.assertEqual(0, len(l.search())) m = ldb.Message() m.dn = ldb.Dn(l, "dc=empty") l.add(m) rm = l.search() self.assertEqual(1, len(rm)) self.assertEqual(set(["dn", "distinguishedName"]), set(rm[0].keys())) rm = l.search(m.dn) self.assertEqual(1, len(rm)) self.assertEqual(set(["dn", "distinguishedName"]), set(rm[0].keys())) rm = l.search(m.dn, attrs=["blah"]) self.assertEqual(1, len(rm)) self.assertEqual(0, len(rm[0]))
def setUp(self): super(MaxIndexKeyLengthTests, self).setUp() self.testdir = tempdir() self.filename = os.path.join(self.testdir, "key_len_test.ldb") # Note that the maximum key length is set to 50 self.l = ldb.Ldb(self.url(), options=[ "modules:rdn_name", "max_key_len_for_self_test:50"]) self.l.add({"dn": "@ATTRIBUTES", "uniqueThing": "UNIQUE_INDEX"}) self.l.add({"dn": "@INDEXLIST", "@IDXATTR": [b"uniqueThing", b"notUnique"], "@IDXONE": [b"1"], "@IDXGUID": [b"objectUUID"], "@IDX_DN_GUID": [b"GUID"]})
def _test_full_db_lock1(self, backend_path): (r1, w1) = os.pipe() pid = os.fork() if pid == 0: # In the child, close the main DB, re-open just one DB del(self.samdb) gc.collect() backenddb = ldb.Ldb(backend_path) backenddb.transaction_start() backenddb.add({"dn":"@DSDB_LOCK_TEST"}) backenddb.delete("@DSDB_LOCK_TEST") # Obtain a write lock backenddb.transaction_prepare_commit() os.write(w1, b"prepared") time.sleep(2) # Drop the write lock backenddb.transaction_cancel() os._exit(0) self.assertEqual(os.read(r1, 8), b"prepared") start = time.time() # We need to hold this iterator open to hold the all-record lock. res = self.samdb.search_iterator() # This should take at least 2 seconds because the transaction # has a write lock on one backend db open end = time.time() self.assertGreater(end - start, 1.9) # Release the locks for l in res: pass (got_pid, status) = os.waitpid(pid, 0) self.assertEqual(got_pid, pid) self.assertTrue(os.WIFEXITED(status)) self.assertEqual(os.WEXITSTATUS(status), 0)
def test_modify_add_text(self): l = ldb.Ldb(filename()) m = ldb.Message() m.dn = ldb.Dn(l, "dc=add") m.text["bla"] = ["1234"] l.add(m) try: m = ldb.Message() m.dn = ldb.Dn(l, "dc=add") m["bla"] = ldb.MessageElement(["456"], ldb.FLAG_MOD_ADD, "bla") self.assertEqual(ldb.FLAG_MOD_ADD, m["bla"].flags()) l.modify(m) rm = l.search(m.dn)[0] self.assertEqual(2, len(rm)) self.assertEqual(["1234", "456"], list(rm.text["bla"])) finally: l.delete(ldb.Dn(l, "dc=add"))
def sysdb_sed_domainid(domain_name, domain_id): sssd_cache = "{0}/cache_{1}.ldb".format(config.DB_PATH, domain_name) domain_ldb = ldb.Ldb(sssd_cache) msg = ldb.Message() msg.dn = ldb.Dn(domain_ldb, "cn=sysdb") msg["cn"] = "sysdb" msg["description"] = "base object" msg["version"] = "0.17" domain_ldb.add(msg) # Set domainID for fake AD domain msg = ldb.Message() msg.dn = ldb.Dn(domain_ldb, "cn={0},cn=sysdb".format(domain_name)) msg["cn"] = domain_name msg["domainID"] = domain_id msg["distinguishedName"] = "cn={0},cn=sysdb".format(domain_name) domain_ldb.add(msg) msg = ldb.Message() msg.dn = ldb.Dn(domain_ldb, "@ATTRIBUTES") msg["distinguishedName"] = "@ATTRIBUTES" for attr in [ 'cn', 'dc', 'dn', 'objectclass', 'originalDN', 'userPrincipalName' ]: msg[attr] = "CASE_INSENSITIVE" domain_ldb.add(msg) msg = ldb.Message() msg.dn = ldb.Dn(domain_ldb, "@INDEXLIST") msg["distinguishedName"] = "@INDEXLIST" msg["@IDXONE"] = "1" for attr in [ 'cn', 'objectclass', 'member', 'memberof', 'name', 'uidNumber', 'gidNumber', 'lastUpdate', 'dataExpireTimestamp', 'originalDN', 'nameAlias', 'servicePort', 'serviceProtocol', 'sudoUser', 'sshKnownHostsExpire', 'objectSIDString' ]: msg["@IDXATTR"] = attr domain_ldb.add(msg) msg = ldb.Message() msg.dn = ldb.Dn(domain_ldb, "@MODULES") msg["distinguishedName"] = "@MODULES" msg["@LIST"] = "asq,memberof" domain_ldb.add(msg)
def setUp(self): name = filename() self.name = name if os.path.exists(name): os.unlink(name) self.l = ldb.Ldb(name) self.l.add({"dn": "DC=SAMBA,DC=ORG", "name": "samba.org"}) self.l.add({"dn": "OU=ADMIN,DC=SAMBA,DC=ORG", "name": "Admins"}) self.l.add({"dn": "OU=USERS,DC=SAMBA,DC=ORG", "name": "Users"}) self.l.add({"dn": "OU=OU1,DC=SAMBA,DC=ORG", "name": "OU #1"}) self.l.add({"dn": "OU=OU2,DC=SAMBA,DC=ORG", "name": "OU #2"}) self.l.add({"dn": "OU=OU3,DC=SAMBA,DC=ORG", "name": "OU #3"}) self.l.add({"dn": "OU=OU4,DC=SAMBA,DC=ORG", "name": "OU #4"}) self.l.add({"dn": "OU=OU5,DC=SAMBA,DC=ORG", "name": "OU #5"}) self.l.add({"dn": "OU=OU6,DC=SAMBA,DC=ORG", "name": "OU #6"}) self.l.add({"dn": "OU=OU7,DC=SAMBA,DC=ORG", "name": "OU #7"}) self.l.add({"dn": "OU=OU8,DC=SAMBA,DC=ORG", "name": "OU #8"}) self.l.add({"dn": "OU=OU9,DC=SAMBA,DC=ORG", "name": "OU #9"}) self.l.add({"dn": "OU=OU10,DC=SAMBA,DC=ORG", "name": "OU #10"})
def test_modify_replace_text(self): l = ldb.Ldb(filename()) m = ldb.Message() m.dn = ldb.Dn(l, "dc=modify2") m.text["bla"] = ["1234", "456"] l.add(m) try: m = ldb.Message() m.dn = ldb.Dn(l, "dc=modify2") m["bla"] = ldb.MessageElement(["789"], ldb.FLAG_MOD_REPLACE, "bla") self.assertEqual(ldb.FLAG_MOD_REPLACE, m["bla"].flags()) l.modify(m) rm = l.search(m.dn)[0] self.assertEqual(2, len(rm)) self.assertEqual(["789"], list(rm.text["bla"])) rm = l.search(m.dn, attrs=["bla"])[0] self.assertEqual(1, len(rm)) finally: l.delete(ldb.Dn(l, "dc=modify2"))
def test_modify_delete(self): l = ldb.Ldb(filename()) m = ldb.Message() m.dn = ldb.Dn(l, "dc=modifydelete") m["bla"] = ["1234"] l.add(m) rm = l.search(m.dn)[0] self.assertEquals(["1234"], list(rm["bla"])) try: m = ldb.Message() m.dn = ldb.Dn(l, "dc=modifydelete") m["bla"] = ldb.MessageElement([], ldb.FLAG_MOD_DELETE, "bla") self.assertEquals(ldb.FLAG_MOD_DELETE, m["bla"].flags()) l.modify(m) rm = l.search(m.dn)[0] self.assertEquals(1, len(rm)) rm = l.search(m.dn, attrs=["bla"])[0] self.assertEquals(0, len(rm)) finally: l.delete(ldb.Dn(l, "dc=modifydelete"))
def test_from_dict_text(self): rec = {"dn": "dc=fromdict", "a1": ["a1-val1", "a1-val1"]} l = ldb.Ldb() # check different types of input Flags for flags in [ ldb.FLAG_MOD_ADD, ldb.FLAG_MOD_REPLACE, ldb.FLAG_MOD_DELETE ]: m = ldb.Message.from_dict(l, rec, flags) self.assertEqual(rec["a1"], list(m.text["a1"])) self.assertEqual(flags, m.text["a1"].flags()) # check input params self.assertRaises(TypeError, ldb.Message.from_dict, dict(), rec, ldb.FLAG_MOD_REPLACE) self.assertRaises(TypeError, ldb.Message.from_dict, l, list(), ldb.FLAG_MOD_REPLACE) self.assertRaises(ValueError, ldb.Message.from_dict, l, rec, 0) # Message.from_dict expects dictionary with 'dn' err_rec = {"a1": ["a1-val1", "a1-val1"]} self.assertRaises(TypeError, ldb.Message.from_dict, l, err_rec, ldb.FLAG_MOD_REPLACE)
def test_encrypted_secrets(self): """Test that secret attributes are stored encrypted on disk""" basedn = self.ldb.domain_dn() backend_filename = "%s.ldb" % basedn.upper() backend_subpath = os.path.join("sam.ldb.d", backend_filename) backend_path = self.lp.private_path(backend_subpath) backenddb = ldb.Ldb(backend_path) dn = "CN=Administrator,CN=Users,%s" % basedn res = backenddb.search(scope=ldb.SCOPE_BASE, base=dn, attrs=["unicodePwd"]) self.assertIs(True, len(res) > 0) obj = res[0] blob = obj["unicodePwd"][0] self.assertTrue(len(blob) > 30) # Now verify that the header contains the correct magic value. encrypted = ndr_unpack(drsblobs.EncryptedSecret, blob) magic = 0xca5caded self.assertEquals(magic, encrypted.header.magic)
def test_repr(self): self.msg.dn = ldb.Dn(ldb.Ldb(filename()), "dc=foo29") self.msg["dc"] = b"foo" if PY3: self.assertIn(repr(self.msg), [ "Message({'dn': Dn('dc=foo29'), 'dc': MessageElement([b'foo'])})", "Message({'dc': MessageElement([b'foo']), 'dn': Dn('dc=foo29')})", ]) self.assertIn(repr(self.msg.text), [ "Message({'dn': Dn('dc=foo29'), 'dc': MessageElement([b'foo'])}).text", "Message({'dc': MessageElement([b'foo']), 'dn': Dn('dc=foo29')}).text", ]) else: self.assertEquals( repr(self.msg), "Message({'dn': Dn('dc=foo29'), 'dc': MessageElement(['foo'])})" ) self.assertEquals( repr(self.msg.text), "Message({'dn': Dn('dc=foo29'), 'dc': MessageElement(['foo'])}).text" )
def test_modify_delete_text(self): l = ldb.Ldb(filename()) m = ldb.Message() m.dn = ldb.Dn(l, "dc=modifydelete") m.text["bla"] = ["1234"] l.add(m) rm = l.search(m.dn)[0] self.assertEqual(["1234"], list(rm.text["bla"])) try: m = ldb.Message() m.dn = ldb.Dn(l, "dc=modifydelete") m["bla"] = ldb.MessageElement([], ldb.FLAG_MOD_DELETE, "bla") self.assertEqual(ldb.FLAG_MOD_DELETE, m["bla"].flags()) l.modify(m) rm = l.search(m.dn) self.assertEqual(1, len(rm)) self.assertEqual(set(["dn", "distinguishedName"]), set(rm[0].keys())) rm = l.search(m.dn, attrs=["bla"]) self.assertEqual(1, len(rm)) self.assertEqual(0, len(rm[0])) finally: l.delete(ldb.Dn(l, "dc=modifydelete"))
def _test_full_db_lock2(self, backend_path): (r1, w1) = os.pipe() (r2, w2) = os.pipe() pid = os.fork() if pid == 0: # In the child, close the main DB, re-open del (self.samdb) gc.collect() self.samdb = SamDB(session_info=self.session, credentials=self.creds, lp=self.lp) # We need to hold this iterator open to hold the all-record lock. res = self.samdb.search_iterator() os.write(w2, b"start") if (os.read(r1, 7) != b"started"): os._exit(1) os.write(w2, b"add") if (os.read(r1, 5) != b"added"): os._exit(2) # Wait 2 seconds to block prepare_commit() in the child. os.write(w2, b"prepare") time.sleep(2) # Release the locks for l in res: pass if (os.read(r1, 8) != b"prepared"): os._exit(3) os._exit(0) # In the parent, close the main DB, re-open just one DB del (self.samdb) gc.collect() backenddb = ldb.Ldb(backend_path) # We can start the transaction during the search # because both just grab the all-record read lock. self.assertEqual(os.read(r2, 5), b"start") backenddb.transaction_start() os.write(w1, b"started") self.assertEqual(os.read(r2, 3), b"add") backenddb.add({"dn": "@DSDB_LOCK_TEST"}) backenddb.delete("@DSDB_LOCK_TEST") os.write(w1, b"added") # Obtain a write lock, this will block until # the child releases the read lock. self.assertEqual(os.read(r2, 7), b"prepare") start = time.time() backenddb.transaction_prepare_commit() end = time.time() try: self.assertGreater(end - start, 1.9) except: raise finally: os.write(w1, b"prepared") # Drop the write lock backenddb.transaction_cancel() (got_pid, status) = os.waitpid(pid, 0) self.assertEqual(got_pid, pid) self.assertTrue(os.WIFEXITED(status)) self.assertEqual(os.WEXITSTATUS(status), 0)
def test_ldb_dn_explode_crash(self): for i in range(106, 150): dn = ldb.Dn(ldb.Ldb(), "a=b%s,c= " % (' ' * i)) dn.validate()
def test_search_attr_string(self): l = ldb.Ldb(filename()) self.assertRaises(TypeError, l.search, attrs="dc") self.assertRaises(TypeError, l.search, attrs=b"dc")
def test_search_string_dn(self): l = ldb.Ldb(filename()) self.assertEqual( len(l.search("", ldb.SCOPE_SUBTREE, "(dc=*)", ["dc"])), 0)
def test_search_attrs(self): l = ldb.Ldb(filename()) self.assertEqual( len(l.search(ldb.Dn(l, ""), ldb.SCOPE_SUBTREE, "(dc=*)", ["dc"])), 0)