def test_urgent_attributes(self): '''Test if the urgent replication is activated when handling urgent attributes of an object''' self.ldb.add({ "dn": "cn=user UrgAttr test,cn=users," + self.base_dn, "objectclass": "user", "samaccountname": "user UrgAttr test", "userAccountControl": str(dsdb.UF_NORMAL_ACCOUNT), "lockoutTime": "0", "pwdLastSet": "0", "description": "urgent attributes test description" }) # urgent replication should NOT be enabled when creating res = self.ldb.load_partition_usn(self.base_dn) self.assertNotEquals(res["uSNHighest"], res["uSNUrgent"]) # urgent replication should be enabled when modifying userAccountControl m = Message() m.dn = Dn(ldb, "cn=user UrgAttr test,cn=users," + self.base_dn) m["userAccountControl"] = MessageElement( str(dsdb.UF_NORMAL_ACCOUNT + dsdb.UF_SMARTCARD_REQUIRED), FLAG_MOD_REPLACE, "userAccountControl") ldb.modify(m) res = self.ldb.load_partition_usn(self.base_dn) self.assertEquals(res["uSNHighest"], res["uSNUrgent"]) # urgent replication should be enabled when modifying lockoutTime m = Message() m.dn = Dn(ldb, "cn=user UrgAttr test,cn=users," + self.base_dn) m["lockoutTime"] = MessageElement("1", FLAG_MOD_REPLACE, "lockoutTime") ldb.modify(m) res = self.ldb.load_partition_usn(self.base_dn) self.assertEquals(res["uSNHighest"], res["uSNUrgent"]) # urgent replication should be enabled when modifying pwdLastSet m = Message() m.dn = Dn(ldb, "cn=user UrgAttr test,cn=users," + self.base_dn) m["pwdLastSet"] = MessageElement("1", FLAG_MOD_REPLACE, "pwdLastSet") ldb.modify(m) res = self.ldb.load_partition_usn(self.base_dn) self.assertEquals(res["uSNHighest"], res["uSNUrgent"]) # urgent replication should NOT be enabled when modifying a not-urgent # attribute m = Message() m.dn = Dn(ldb, "cn=user UrgAttr test,cn=users," + self.base_dn) m["description"] = MessageElement( "updated urgent attributes test description", FLAG_MOD_REPLACE, "description") ldb.modify(m) res = self.ldb.load_partition_usn(self.base_dn) self.assertNotEquals(res["uSNHighest"], res["uSNUrgent"]) # urgent replication should NOT be enabled when deleting self.delete_force(self.ldb, "cn=user UrgAttr test,cn=users," + self.base_dn) res = self.ldb.load_partition_usn(self.base_dn) self.assertNotEquals(res["uSNHighest"], res["uSNUrgent"])
def test_secret_object(self): '''Test if the urgent replication is activated when handling a secret object''' self.ldb.add({ "dn": "cn=test secret,cn=System," + self.base_dn, "objectClass": "secret", "cn": "test secret", "name": "test secret", "currentValue": "xxxxxxx" }) # urgent replication should be enabled when creating res = self.ldb.load_partition_usn(self.base_dn) self.assertEquals(res["uSNHighest"], res["uSNUrgent"]) # urgent replication should be enabled when modifying m = Message() m.dn = Dn(ldb, "cn=test secret,cn=System," + self.base_dn) m["currentValue"] = MessageElement("yyyyyyyy", FLAG_MOD_REPLACE, "currentValue") ldb.modify(m) res = self.ldb.load_partition_usn(self.base_dn) self.assertEquals(res["uSNHighest"], res["uSNUrgent"]) # urgent replication should NOT be enabled when deleting self.delete_force(self.ldb, "cn=test secret,cn=System," + self.base_dn) res = self.ldb.load_partition_usn(self.base_dn) self.assertNotEquals(res["uSNHighest"], res["uSNUrgent"])
def test_nonurgent_object(self): """Test if the urgent replication is not activated when handling a non urgent object""" self.ldb.add({ "dn": "cn=nonurgenttest,cn=users," + self.base_dn, "objectclass": "user", "samaccountname": "nonurgenttest", "description": "nonurgenttest description" }) # urgent replication should not be enabled when creating res = self.ldb.load_partition_usn(self.base_dn) self.assertNotEquals(res["uSNHighest"], res["uSNUrgent"]) # urgent replication should not be enabled when modifying m = Message() m.dn = Dn(ldb, "cn=nonurgenttest,cn=users," + self.base_dn) m["description"] = MessageElement("new description", FLAG_MOD_REPLACE, "description") ldb.modify(m) res = self.ldb.load_partition_usn(self.base_dn) self.assertNotEquals(res["uSNHighest"], res["uSNUrgent"]) # urgent replication should not be enabled when deleting self.delete_force(self.ldb, "cn=nonurgenttest,cn=users," + self.base_dn) res = self.ldb.load_partition_usn(self.base_dn) self.assertNotEquals(res["uSNHighest"], res["uSNUrgent"])
def _unlink_user_and_group(self, u, g): user = "******" % (u, self.ou_users) group = "CN=g%d,%s" % (g, self.ou_groups) m = Message() m.dn = Dn(self.ldb, group) m["member"] = MessageElement(user, FLAG_MOD_DELETE, "member") self.ldb.modify(m)
def test_crossRef_object(self): """Test if the urgent replication is activated when handling a crossRef object.""" self.ldb.add({ "dn": "CN=test crossRef,CN=Partitions,CN=Configuration," + self.base_dn, "objectClass": "crossRef", "cn": "test crossRef", "dnsRoot": self.get_loadparm().get("realm").lower(), "instanceType": "4", "nCName": self.base_dn, "showInAdvancedViewOnly": "TRUE", "name": "test crossRef", "systemFlags": "1"}, ["relax:0"]) # urgent replication should be enabled when creating res = self.ldb.load_partition_usn("cn=Configuration," + self.base_dn) self.assertEqual(res["uSNHighest"], res["uSNUrgent"]) # urgent replication should NOT be enabled when modifying m = Message() m.dn = Dn(self.ldb, "cn=test crossRef,CN=Partitions,CN=Configuration," + self.base_dn) m["systemFlags"] = MessageElement("0", FLAG_MOD_REPLACE, "systemFlags") self.ldb.modify(m) res = self.ldb.load_partition_usn("cn=Configuration," + self.base_dn) self.assertNotEquals(res["uSNHighest"], res["uSNUrgent"]) # urgent replication should be enabled when deleting self.delete_force(self.ldb, "cn=test crossRef,CN=Partitions,CN=Configuration," + self.base_dn) res = self.ldb.load_partition_usn("cn=Configuration," + self.base_dn) self.assertEqual(res["uSNHighest"], res["uSNUrgent"])
def _test_link_many_users_batch(self, n=(LINK_BATCH_SIZE * 10)): # this links unevenly, putting more users in the first group # and fewer in the last. ng = self.state.n_groups nu = self.state.next_user_id messages = [] for g in range(ng): m = Message() m.dn = Dn(self.ldb, "CN=g%d,%s" % (g, self.ou_groups)) messages.append(m) while n: u = random.randrange(nu) g = random.randrange(random.randrange(ng) + 1) link = (u, g) if link in self.state.active_links: continue m = messages[g] m["member%s" % u] = MessageElement( "cn=u%d,%s" % (u, self.ou_users), FLAG_MOD_ADD, "member") self.state.active_links.add(link) n -= 1 for m in messages: try: self.ldb.modify(m) except LdbError as e: print(e) print(m)
def test_u1_member_of_g4(self): i = 0 import time print "KEYS: total add modify delete" while True: group = i % self.n_groups + 1 start = time.time() self.ldb.add({ "dn": "cn=u%d,%s" % (group, self.ou_users), "objectclass": "user" }) end_add = time.time() start_mod = time.time() m = Message() m.dn = Dn(self.ldb, "CN=g%d,%s" % (group, self.ou_groups)) m["member"] = MessageElement("cn=u%d,%s" % (group, self.ou_users), FLAG_MOD_ADD, "member") self.ldb.modify(m) end_mod = time.time() delete_force(self.ldb, "cn=u%d,%s" % (group, self.ou_users)) end = time.time() print end - start, end_add - start, end_mod - start_mod, end - end_mod i += 1
def test_attributeSchema_object(self): """Test if the urgent replication is activated when handling an attributeSchema object""" self.ldb.add_ldif( """dn: CN=test attributeSchema,cn=Schema,CN=Configuration,%s""" % self.base_dn + """ objectClass: attributeSchema cn: test attributeSchema instanceType: 4 isSingleValued: FALSE showInAdvancedViewOnly: FALSE attributeID: 1.3.6.1.4.1.7165.4.6.1.4.""" + str(random.randint(1, 100000)) + """ attributeSyntax: 2.5.5.12 adminDisplayName: test attributeSchema adminDescription: test attributeSchema oMSyntax: 64 systemOnly: FALSE searchFlags: 8 lDAPDisplayName: testAttributeSchema name: test attributeSchema""") # urgent replication should be enabled when creating res = self.ldb.load_partition_usn("cn=Schema,cn=Configuration," + self.base_dn) self.assertEqual(res["uSNHighest"], res["uSNUrgent"]) # urgent replication should be enabled when modifying m = Message() m.dn = Dn(self.ldb, "CN=test attributeSchema,CN=Schema,CN=Configuration," + self.base_dn) m["lDAPDisplayName"] = MessageElement("updatedTestAttributeSchema", FLAG_MOD_REPLACE, "lDAPDisplayName") self.ldb.modify(m) res = self.ldb.load_partition_usn("cn=Schema,cn=Configuration," + self.base_dn) self.assertEqual(res["uSNHighest"], res["uSNUrgent"])
def test_rIDManager_object(self): '''Test if the urgent replication is activated when handling a rIDManager object''' self.ldb.add_ldif( """dn: CN=RID Manager test,CN=System,%s""" % self.base_dn + """ objectClass: rIDManager cn: RID Manager test instanceType: 4 showInAdvancedViewOnly: TRUE name: RID Manager test systemFlags: -1946157056 isCriticalSystemObject: TRUE rIDAvailablePool: 133001-1073741823""", ["relax:0"]) # urgent replication should be enabled when creating res = self.ldb.load_partition_usn(self.base_dn) self.assertEquals(res["uSNHighest"], res["uSNUrgent"]) # urgent replication should be enabled when modifying m = Message() m.dn = Dn(ldb, "CN=RID Manager test,CN=System," + self.base_dn) m["systemFlags"] = MessageElement("0", FLAG_MOD_REPLACE, "systemFlags") ldb.modify(m) res = self.ldb.load_partition_usn(self.base_dn) self.assertEquals(res["uSNHighest"], res["uSNUrgent"]) # urgent replication should NOT be enabled when deleting self.delete_force(self.ldb, "CN=RID Manager test,CN=System," + self.base_dn) res = self.ldb.load_partition_usn(self.base_dn) self.assertNotEquals(res["uSNHighest"], res["uSNUrgent"])
def test_unicodePwd_clear_set(self): """Performs a password cleartext set operation on 'unicodePwd'""" m = Message() m.dn = Dn(self.ldb, "cn=testuser,cn=users," + self.base_dn) m["unicodePwd"] = MessageElement("\"thatsAcomplPASS2\"".encode('utf-16-le'), FLAG_MOD_REPLACE, "unicodePwd") self.ldb.modify(m)
def test_userPassword_clear_set(self): """Performs a password cleartext set operation on 'userPassword'""" # Notice: This works only against Windows if "dSHeuristics" has been set # properly m = Message() m.dn = Dn(self.ldb, "cn=testuser,cn=users," + self.base_dn) m["userPassword"] = MessageElement("thatsAcomplPASS2", FLAG_MOD_REPLACE, "userPassword") self.ldb.modify(m)
def test_nTDSDSA_object(self): '''Test if the urgent replication is activated when handling a nTDSDSA object''' self.ldb.add( { "dn": "cn=test server,cn=Servers,cn=Default-First-Site-Name,cn=Sites,%s" % self.ldb.get_config_basedn(), "objectclass": "server", "cn": "test server", "name": "test server", "systemFlags": "50000000" }, ["relax:0"]) self.ldb.add_ldif( """dn: cn=NTDS Settings test,cn=test server,cn=Servers,cn=Default-First-Site-Name,cn=Sites,cn=Configuration,%s""" % (self.base_dn) + """ objectclass: nTDSDSA cn: NTDS Settings test options: 1 instanceType: 4 systemFlags: 33554432""", ["relax:0"]) # urgent replication should be enabled when creation res = self.ldb.load_partition_usn("cn=Configuration," + self.base_dn) self.assertEquals(res["uSNHighest"], res["uSNUrgent"]) # urgent replication should NOT be enabled when modifying m = Message() m.dn = Dn( ldb, "cn=NTDS Settings test,cn=test server,cn=Servers,cn=Default-First-Site-Name,cn=Sites,cn=Configuration," + self.base_dn) m["options"] = MessageElement("0", FLAG_MOD_REPLACE, "options") ldb.modify(m) res = self.ldb.load_partition_usn("cn=Configuration," + self.base_dn) self.assertNotEquals(res["uSNHighest"], res["uSNUrgent"]) # urgent replication should be enabled when deleting self.delete_force( self.ldb, "cn=NTDS Settings test,cn=test server,cn=Servers,cn=Default-First-Site-Name,cn=Sites,cn=Configuration," + self.base_dn) res = self.ldb.load_partition_usn("cn=Configuration," + self.base_dn) self.assertEquals(res["uSNHighest"], res["uSNUrgent"]) self.delete_force( self.ldb, "cn=test server,cn=Servers,cn=Default-First-Site-Name,cn=Sites,cn=Configuration," + self.base_dn)
def enable_recycle_bin(self): msg = Message() msg.dn = Dn(self.samdb, "") msg["enableOptionalFeature"] = MessageElement( "CN=Partitions," + self.configuration_dn + ":766ddcd8-acd0-445e-f3b9-a7f9b6744f2a", FLAG_MOD_ADD, "enableOptionalFeature") try: self.samdb.modify(msg) except LdbError as e: (num, _) = e.args self.assertEqual(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
def set_attr_search_flags(self, attr_dn, flags): """Modifies the searchFlags for an object in the schema""" m = Message() m.dn = Dn(self.ldb_admin, attr_dn) m['searchFlags'] = MessageElement(flags, FLAG_MOD_REPLACE, 'searchFlags') self.ldb_admin.modify(m) # note we have to update the schema for this change to take effect (on # Windows, at least) self.ldb_admin.set_schema_update_now()
def _link_user_and_group(self, u, g): link = (u, g) if link in self.state.active_links: return False m = Message() m.dn = Dn(self.ldb, "CN=g%d,%s" % (g, self.ou_groups)) m["member"] = MessageElement("cn=u%d,%s" % (u, self.ou_users), FLAG_MOD_ADD, "member") self.ldb.modify(m) self.state.active_links.add(link) return True
def _unlink_user_and_group(self, u, g): link = (u, g) if link not in self.state.active_links: return False user = "******" % (u, self.ou_users) group = "CN=g%d,%s" % (g, self.ou_groups) m = Message() m.dn = Dn(self.ldb, group) m["member"] = MessageElement(user, FLAG_MOD_DELETE, "member") self.ldb.modify(m) self.state.active_links.remove(link) return True
def test_dBCSPwd_hash_set(self): """Performs a password hash set operation on 'dBCSPwd' which should be prevented""" # Notice: Direct hash password sets should never work m = Message() m.dn = Dn(self.ldb, "cn=testuser,cn=users," + self.base_dn) m["dBCSPwd"] = MessageElement("XXXXXXXXXXXXXXXX", FLAG_MOD_REPLACE, "dBCSPwd") try: self.ldb.modify(m) self.fail() except LdbError as e6: (num, _) = e6.args self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
def test_classSchema_object(self): """Test if the urgent replication is activated when handling a classSchema object.""" try: self.ldb.add_ldif( """dn: CN=test classSchema,CN=Schema,CN=Configuration,%s""" % self.base_dn + """ objectClass: classSchema cn: test classSchema instanceType: 4 subClassOf: top governsId: 1.3.6.1.4.1.7165.4.6.2.4.""" + str(random.randint(1, 100000)) + """ rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: test classSchema adminDescription: test classSchema objectClassCategory: 1 lDAPDisplayName: testClassSchema name: test classSchema systemOnly: FALSE systemPossSuperiors: dfsConfiguration systemMustContain: msDFS-SchemaMajorVersion defaultSecurityDescriptor: D:(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;DA)(A;;RPWPCRCCD CLCLORCWOWDSDDTSW;;;SY)(A;;RPLCLORC;;;AU)(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;CO) systemFlags: 16 defaultHidingValue: TRUE""") # urgent replication should be enabled when creating res = self.ldb.load_partition_usn("cn=Schema,cn=Configuration," + self.base_dn) self.assertEqual(res["uSNHighest"], res["uSNUrgent"]) except LdbError: print( "Not testing urgent replication when creating classSchema object ...\n" ) # urgent replication should be enabled when modifying m = Message() m.dn = Dn( self.ldb, "CN=test classSchema,CN=Schema,CN=Configuration," + self.base_dn) m["lDAPDisplayName"] = MessageElement("updatedTestClassSchema", FLAG_MOD_REPLACE, "lDAPDisplayName") self.ldb.modify(m) res = self.ldb.load_partition_usn("cn=Schema,cn=Configuration," + self.base_dn) self.assertEqual(res["uSNHighest"], res["uSNUrgent"])
def restore_deleted_object(samdb, del_dn, new_dn, new_attrs=None): """Restores a deleted object :param samdb: SamDB connection to SAM :param del_dn: str Deleted object DN :param new_dn: str Where to restore the object :param new_attrs: dict Additional attributes to set """ msg = Message() msg.dn = Dn(samdb, str(del_dn)) msg["isDeleted"] = MessageElement([], FLAG_MOD_DELETE, "isDeleted") msg["distinguishedName"] = MessageElement([str(new_dn)], FLAG_MOD_REPLACE, "distinguishedName") if new_attrs is not None: assert isinstance(new_attrs, dict) for attr in new_attrs: msg[attr] = MessageElement(new_attrs[attr], FLAG_MOD_REPLACE, attr) samdb.modify(msg, ["show_deleted:1"])
def test_clearTextPassword_clear_set(self): """Performs a password cleartext set operation on 'clearTextPassword'""" # Notice: This never works against Windows - only supported by us try: m = Message() m.dn = Dn(self.ldb, "cn=testuser,cn=users," + self.base_dn) m["clearTextPassword"] = MessageElement("thatsAcomplPASS2".encode('utf-16-le'), FLAG_MOD_REPLACE, "clearTextPassword") self.ldb.modify(m) # this passes against s4 except LdbError as e10: (num, msg) = e10.args # "NO_SUCH_ATTRIBUTE" is returned by Windows -> ignore it if num != ERR_NO_SUCH_ATTRIBUTE: raise LdbError(num, msg)
def update_lockout_settings(self, threshold, duration, observation_window): """Updates the global user lockout settings""" m = Message() m.dn = Dn(self.ldb, self.base_dn) account_lockout_duration_ticks = -int(duration * (1e7)) m["lockoutDuration"] = MessageElement( str(account_lockout_duration_ticks), FLAG_MOD_REPLACE, "lockoutDuration") m["lockoutThreshold"] = MessageElement(str(threshold), FLAG_MOD_REPLACE, "lockoutThreshold") lockout_observation_window_ticks = -int(observation_window * (1e7)) m["lockOutObservationWindow"] = MessageElement( str(lockout_observation_window_ticks), FLAG_MOD_REPLACE, "lockOutObservationWindow") self.ldb.modify(m)
def modify_sd_on_dn(self, object_dn, sd, controls=None): """Modify security descriptor using either SDDL string or security.descriptor object """ m = Message() m.dn = Dn(self.ldb, object_dn) assert (isinstance(sd, str) or isinstance(sd, security.descriptor)) if isinstance(sd, str): tmp_desc = security.descriptor.from_sddl(sd, self.domain_sid) elif isinstance(sd, security.descriptor): tmp_desc = sd m["nTSecurityDescriptor"] = MessageElement(ndr_pack(tmp_desc), FLAG_MOD_REPLACE, "nTSecurityDescriptor") self.ldb.modify(m, controls)
def test_modify_order_member(self): name = "modify_order_member_other_group" dn2 = "cn=%s,%s" % (name, self.base_dn) m = Message() m.dn = Dn(self.admin_dsdb, dn2) self.admin_dsdb.add({"dn": dn2, "objectclass": "group"}) self.addCleanup(self.delete_object, dn2) start_attrs = [("objectclass", "group"), ("member", dn2)] mod_attrs = [ ("member", None, FLAG_MOD_DELETE), ("member", None, FLAG_MOD_REPLACE), ("member", dn2, FLAG_MOD_DELETE), ("member", None, FLAG_MOD_ADD), ] self._test_modify_order(start_attrs, mod_attrs, ["memberOf"])
def test_msDS_IntId_on_class(self): """Testing msDs-IntId creation for Class Reference: MS-ADTS - 3.1.1.2.4.8 Class classSchema""" # 1. Create Class without systemFlags # msDS-IntId should be created if forest functional # level is >= DS_DOMAIN_FUNCTION_2003 # and missing otherwise (class_name, class_ldap_name, class_dn) = self._make_obj_names("msDS-IntId-Class-1-") ldif = self._make_class_ldif(class_dn, class_name) # try to add msDS-IntId during Class creation ldif_add = ldif + "msDS-IntId: -1993108831\n" self.ldb.add_ldif(ldif_add) self._ldap_schemaUpdateNow() res = self.ldb.search(class_dn, scope=SCOPE_BASE, attrs=["*"]) self.assertEquals(len(res), 1) self.assertEquals(res[0]["msDS-IntId"][0], "-1993108831") # add a new Class and update schema (class_name, class_ldap_name, class_dn) = self._make_obj_names("msDS-IntId-Class-2-") ldif = self._make_class_ldif(class_dn, class_name) self.ldb.add_ldif(ldif) self._ldap_schemaUpdateNow() # Search for created Class res = self.ldb.search(class_dn, scope=SCOPE_BASE, attrs=["*"]) self.assertEquals(len(res), 1) self.assertFalse("msDS-IntId" in res[0]) msg = Message() msg.dn = Dn(self.ldb, class_dn) msg["msDS-IntId"] = MessageElement("-1993108831", FLAG_MOD_REPLACE, "msDS-IntId") try: self.ldb.modify(msg) self.fail("Modifying msDS-IntId should return error") except LdbError, (num, _): self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
def test_attributeSchema_object(self): '''Test if the urgent replication is activated when handling an attributeSchema object''' try: self.ldb.add_ldif( """dn: CN=test attributeSchema,cn=Schema,CN=Configuration,%s""" % self.base_dn + """ objectClass: attributeSchema cn: test attributeSchema instanceType: 4 isSingleValued: FALSE showInAdvancedViewOnly: FALSE attributeID: 0.9.2342.19200300.100.1.1 attributeSyntax: 2.5.5.12 adminDisplayName: test attributeSchema adminDescription: test attributeSchema oMSyntax: 64 systemOnly: FALSE searchFlags: 8 lDAPDisplayName: test attributeSchema name: test attributeSchema""") # urgent replication should be enabled when creating res = self.ldb.load_partition_usn("cn=Schema,cn=Configuration," + self.base_dn) self.assertEquals(res["uSNHighest"], res["uSNUrgent"]) except LdbError: print "Not testing urgent replication when creating attributeSchema object ...\n" # urgent replication should be enabled when modifying m = Message() m.dn = Dn( ldb, "CN=test attributeSchema,CN=Schema,CN=Configuration," + self.base_dn) m["lDAPDisplayName"] = MessageElement("updated test attributeSchema", FLAG_MOD_REPLACE, "lDAPDisplayName") ldb.modify(m) res = self.ldb.load_partition_usn("cn=Schema,cn=Configuration," + self.base_dn) self.assertEquals(res["uSNHighest"], res["uSNUrgent"])
def add_attr(self, dn, attr, value): m = Message() m.dn = Dn(self.ldb_admin, dn) m[attr] = MessageElement(value, FLAG_MOD_ADD, attr) self.ldb_admin.modify(m)
# Search for created attribute res = [] res = self.ldb.search(attr_dn, scope=SCOPE_BASE, attrs=["lDAPDisplayName", "msDS-IntId"]) self.assertEquals(len(res), 1) self.assertEquals(res[0]["lDAPDisplayName"][0], attr_ldap_name) if self.forest_level >= DS_DOMAIN_FUNCTION_2003: if self._is_schema_base_object(res[0]): self.assertTrue("msDS-IntId" not in res[0]) else: self.assertTrue("msDS-IntId" in res[0]) else: self.assertTrue("msDS-IntId" not in res[0]) msg = Message() msg.dn = Dn(self.ldb, attr_dn) msg["msDS-IntId"] = MessageElement("-1993108831", FLAG_MOD_REPLACE, "msDS-IntId") try: self.ldb.modify(msg) self.fail("Modifying msDS-IntId should return error") except LdbError, (num, _): self.assertEquals(num, ERR_CONSTRAINT_VIOLATION) def _make_class_ldif(self, class_dn, class_name): ldif = """ dn: """ + class_dn + """ objectClass: top objectClass: classSchema adminDescription: """ + class_name + """ adminDisplayName: """ + class_name + """
def test_dirsync_attributes(self): """Check behavior with some attributes """ res = self.ldb_admin.search(self.base_dn, expression="samaccountname=*", controls=["dirsync:1:0:1"]) # Check that nTSecurityDescriptor is returned as it's the case when doing dirsync self.assertTrue(res.msgs[0].get("ntsecuritydescriptor") != None) # Check that non replicated attributes are not returned self.assertTrue(res.msgs[0].get("badPwdCount") == None) # Check that non forward link are not returned self.assertTrue(res.msgs[0].get("memberof") == None) # Asking for instanceType will return also objectGUID res = self.ldb_admin.search(self.base_dn, expression="samaccountname=Administrator", attrs=["instanceType"], controls=["dirsync:1:0:1"]) self.assertTrue(res.msgs[0].get("objectGUID") != None) self.assertTrue(res.msgs[0].get("instanceType") != None) # We don't return an entry if asked for objectGUID res = self.ldb_admin.search(self.base_dn, expression="(distinguishedName=%s)" % str(self.base_dn), attrs=["objectGUID"], controls=["dirsync:1:0:1"]) self.assertEquals(len(res.msgs), 0) # a request on the root of a NC didn't return parentGUID res = self.ldb_admin.search(self.base_dn, expression="(distinguishedName=%s)" % str(self.base_dn), attrs=["name"], controls=["dirsync:1:0:1"]) self.assertTrue(res.msgs[0].get("objectGUID") != None) self.assertTrue(res.msgs[0].get("name") != None) self.assertTrue(res.msgs[0].get("parentGUID") == None) self.assertTrue(res.msgs[0].get("instanceType") != None) # Asking for name will return also objectGUID and parentGUID # and instanceType and of course name res = self.ldb_admin.search(self.base_dn, expression="samaccountname=Administrator", attrs=["name"], controls=["dirsync:1:0:1"]) self.assertTrue(res.msgs[0].get("objectGUID") != None) self.assertTrue(res.msgs[0].get("name") != None) self.assertTrue(res.msgs[0].get("parentGUID") != None) self.assertTrue(res.msgs[0].get("instanceType") != None) # Asking for dn will not return not only DN but more like if attrs=* # parentGUID should be returned res = self.ldb_admin.search(self.base_dn, expression="samaccountname=Administrator", attrs=["dn"], controls=["dirsync:1:0:1"]) count = len(res.msgs[0]) res2 = self.ldb_admin.search(self.base_dn, expression="samaccountname=Administrator", controls=["dirsync:1:0:1"]) count2 = len(res2.msgs[0]) self.assertEqual(count, count2) # Asking for cn will return nothing on objects that have CN as RDN res = self.ldb_admin.search(self.base_dn, expression="samaccountname=Administrator", attrs=["cn"], controls=["dirsync:1:0:1"]) self.assertEqual(len(res.msgs), 0) # Asking for parentGUID will return nothing too res = self.ldb_admin.search(self.base_dn, expression="samaccountname=Administrator", attrs=["parentGUID"], controls=["dirsync:1:0:1"]) self.assertEqual(len(res.msgs), 0) ouname = "OU=testou,%s" % self.base_dn self.ouname = ouname self.ldb_admin.create_ou(ouname) delta = Message() delta.dn = Dn(self.ldb_admin, str(ouname)) delta["cn"] = MessageElement("test ou", FLAG_MOD_ADD, "cn") self.ldb_admin.modify(delta) res = self.ldb_admin.search(self.base_dn, expression="name=testou", attrs=["cn"], controls=["dirsync:1:0:1"]) self.assertEqual(len(res.msgs), 1) self.assertEqual(len(res.msgs[0]), 3) delete_force(self.ldb_admin, ouname)
def test_dirsync_send_delta(self): """Check that dirsync return correct delta when sending the last cookie""" res = self.ldb_admin.search( self.base_dn, expression="(&(samaccountname=test*)(!(isDeleted=*)))", controls=["dirsync:1:0:10000"]) ctl = str(res.controls[0]).split(":") ctl[1] = "1" ctl[2] = "0" ctl[3] = "10000" control = str(":".join(ctl)) res = self.ldb_admin.search( self.base_dn, expression="(&(samaccountname=test*)(!(isDeleted=*)))", controls=[control]) self.assertEqual(len(res), 0) res = self.ldb_admin.search( self.base_dn, expression="(&(objectClass=organizationalUnit)(!(isDeleted=*)))", controls=["dirsync:1:0:100000"]) ctl = str(res.controls[0]).split(":") ctl[1] = "1" ctl[2] = "0" ctl[3] = "10000" control2 = str(":".join(ctl)) # Let's create an OU ouname = "OU=testou2,%s" % self.base_dn self.ouname = ouname self.ldb_admin.create_ou(ouname) res = self.ldb_admin.search( self.base_dn, expression="(&(objectClass=organizationalUnit)(!(isDeleted=*)))", controls=[control2]) self.assertEqual(len(res), 1) ctl = str(res.controls[0]).split(":") ctl[1] = "1" ctl[2] = "0" ctl[3] = "10000" control3 = str(":".join(ctl)) delta = Message() delta.dn = Dn(self.ldb_admin, str(ouname)) delta["cn"] = MessageElement("test ou", FLAG_MOD_ADD, "cn") self.ldb_admin.modify(delta) res = self.ldb_admin.search( self.base_dn, expression="(&(objectClass=organizationalUnit)(!(isDeleted=*)))", controls=[control3]) self.assertEqual(len(res.msgs), 1) # 3 attributes: instanceType, cn and objectGUID self.assertEqual(len(res.msgs[0]), 3) delta = Message() delta.dn = Dn(self.ldb_admin, str(ouname)) delta["cn"] = MessageElement([], FLAG_MOD_DELETE, "cn") self.ldb_admin.modify(delta) res = self.ldb_admin.search( self.base_dn, expression="(&(objectClass=organizationalUnit)(!(isDeleted=*)))", controls=[control3]) self.assertEqual(len(res.msgs), 1) # So we won't have much attribute returned but instanceType and GUID # are. # 3 attributes: instanceType and objectGUID and cn but empty self.assertEqual(len(res.msgs[0]), 3) ouname = "OU=newouname,%s" % self.base_dn self.ldb_admin.rename(str(res[0].dn), str(Dn(self.ldb_admin, ouname))) self.ouname = ouname ctl = str(res.controls[0]).split(":") ctl[1] = "1" ctl[2] = "0" ctl[3] = "10000" control4 = str(":".join(ctl)) res = self.ldb_admin.search( self.base_dn, expression="(&(objectClass=organizationalUnit)(!(isDeleted=*)))", controls=[control3]) self.assertTrue(res[0].get("parentGUID") != None) self.assertTrue(res[0].get("name") != None) delete_force(self.ldb_admin, ouname)
class SchemaTests_msDS_IntId(samba.tests.TestCase): def setUp(self): super(SchemaTests_msDS_IntId, self).setUp() self.ldb = SamDB(host, credentials=creds, session_info=system_session(lp), lp=lp, options=ldb_options) res = self.ldb.search(base="", expression="", scope=SCOPE_BASE, attrs=["schemaNamingContext", "defaultNamingContext", "forestFunctionality"]) self.assertEquals(len(res), 1) self.schema_dn = res[0]["schemaNamingContext"][0] self.base_dn = res[0]["defaultNamingContext"][0] self.forest_level = int(res[0]["forestFunctionality"][0]) def _ldap_schemaUpdateNow(self): ldif = """ dn: changetype: modify add: schemaUpdateNow schemaUpdateNow: 1 """ self.ldb.modify_ldif(ldif) def _make_obj_names(self, prefix): class_name = prefix + time.strftime("%s", time.gmtime()) class_ldap_name = class_name.replace("-", "") class_dn = "CN=%s,%s" % (class_name, self.schema_dn) return (class_name, class_ldap_name, class_dn) def _is_schema_base_object(self, ldb_msg): """Test systemFlags for SYSTEM_FLAG_SCHEMA_BASE_OBJECT (16)""" systemFlags = 0 if "systemFlags" in ldb_msg: systemFlags = int(ldb_msg["systemFlags"][0]) return (systemFlags & 16) != 0 def _make_attr_ldif(self, attr_name, attr_dn): ldif = """ dn: """ + attr_dn + """ objectClass: top objectClass: attributeSchema adminDescription: """ + attr_name + """ adminDisplayName: """ + attr_name + """ cn: """ + attr_name + """ attributeId: 1.2.840.""" + str(random.randint(1,100000)) + """.1.5.9940 attributeSyntax: 2.5.5.12 omSyntax: 64 instanceType: 4 isSingleValued: TRUE systemOnly: FALSE """ return ldif def test_msDS_IntId_on_attr(self): """Testing msDs-IntId creation for Attributes. See MS-ADTS - 3.1.1.Attributes This test should verify that: - Creating attribute with 'msDS-IntId' fails with ERR_UNWILLING_TO_PERFORM - Adding 'msDS-IntId' on existing attribute fails with ERR_CONSTRAINT_VIOLATION - Creating attribute with 'msDS-IntId' set and FLAG_SCHEMA_BASE_OBJECT flag set fails with ERR_UNWILLING_TO_PERFORM - Attributes created with FLAG_SCHEMA_BASE_OBJECT not set have 'msDS-IntId' attribute added internally """ # 1. Create attribute without systemFlags # msDS-IntId should be created if forest functional # level is >= DS_DOMAIN_FUNCTION_2003 # and missing otherwise (attr_name, attr_ldap_name, attr_dn) = self._make_obj_names("msDS-IntId-Attr-1-") ldif = self._make_attr_ldif(attr_name, attr_dn) # try to add msDS-IntId during Attribute creation ldif_fail = ldif + "msDS-IntId: -1993108831\n" try: self.ldb.add_ldif(ldif_fail) self.fail("Adding attribute with preset msDS-IntId should fail") except LdbError, (num, _): self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) # add the new attribute and update schema self.ldb.add_ldif(ldif) self._ldap_schemaUpdateNow() # Search for created attribute res = [] res = self.ldb.search(attr_dn, scope=SCOPE_BASE, attrs=["lDAPDisplayName", "msDS-IntId", "systemFlags"]) self.assertEquals(len(res), 1) self.assertEquals(res[0]["lDAPDisplayName"][0], attr_ldap_name) if self.forest_level >= DS_DOMAIN_FUNCTION_2003: if self._is_schema_base_object(res[0]): self.assertTrue("msDS-IntId" not in res[0]) else: self.assertTrue("msDS-IntId" in res[0]) else: self.assertTrue("msDS-IntId" not in res[0]) msg = Message() msg.dn = Dn(self.ldb, attr_dn) msg["msDS-IntId"] = MessageElement("-1993108831", FLAG_MOD_REPLACE, "msDS-IntId") try: self.ldb.modify(msg) self.fail("Modifying msDS-IntId should return error") except LdbError, (num, _): self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)