def test_dirsync_deleted_items(self): """Check that dirsync returnd deleted objects too""" # Let's create an OU ouname = "OU=testou3,%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=["dirsync:1:0:1"]) guid = None for e in res: if str(e["name"]) == "testou3": guid = str(ndr_unpack(misc.GUID, e.get("objectGUID")[0])) ctl = str(res.controls[0]).split(":") ctl[1] = "1" ctl[2] = "0" ctl[3] = "10000" control1 = str(":".join(ctl)) # So now delete the object and check that # we can see the object but deleted when admin delete_force(self.ldb_admin, ouname) res = self.ldb_admin.search( self.base_dn, expression="(objectClass=organizationalUnit)", controls=[control1]) self.assertEqual(len(res), 1) guid2 = str(ndr_unpack(misc.GUID, res[0].get("objectGUID")[0])) self.assertEqual(guid2, guid) self.assertTrue(res[0].get("isDeleted")) self.assertTrue(res[0].get("name") != None)
def test_dirsync_deleted_items(self): """Check that dirsync returnd deleted objects too""" # Let's create an OU ouname="OU=testou3,%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=["dirsync:1:0:1"]) guid = None for e in res: if str(e["name"]) == "testou3": guid = str(ndr_unpack(misc.GUID,e.get("objectGUID")[0])) ctl = str(res.controls[0]).split(":") ctl[1] = "1" ctl[2] = "0" ctl[3] = "10000" control1 = str(":".join(ctl)) # So now delete the object and check that # we can see the object but deleted when admin delete_force(self.ldb_admin, ouname) res = self.ldb_admin.search(self.base_dn, expression="(objectClass=organizationalUnit)", controls=[control1]) self.assertEqual(len(res), 1) guid2 = str(ndr_unpack(misc.GUID,res[0].get("objectGUID")[0])) self.assertEqual(guid2, guid) self.assertTrue(res[0].get("isDeleted")) self.assertTrue(res[0].get("name") != None)
def create_user_account(self): self.user_pass = samba.generate_random_password(32, 32) self.user_name = USER_NAME self.user_dn = "cn=%s,%s" % (self.user_name, self.ldb.domain_dn()) # remove the account if it exists, this will happen if a previous test # run failed delete_force(self.ldb, self.user_dn) utf16pw = unicode( '"' + self.user_pass.encode('utf-8') + '"', 'utf-8' ).encode('utf-16-le') self.ldb.add({ "dn": self.user_dn, "objectclass": "user", "sAMAccountName": "%s" % self.user_name, "userAccountControl": str(UF_NORMAL_ACCOUNT), "unicodePwd": utf16pw}) self.user_creds = Credentials() self.user_creds.guess(self.get_loadparm()) self.user_creds.set_password(self.user_pass) self.user_creds.set_username(self.user_name) self.user_creds.set_workstation(self.machine_name) pass
def create_machine_account(self): self.machine_pass = samba.generate_random_password(32, 32) self.machine_name = MACHINE_NAME self.machine_dn = "cn=%s,%s" % (self.machine_name, self.ldb.domain_dn()) # remove the account if it exists, this will happen if a previous test # run failed delete_force(self.ldb, self.machine_dn) utf16pw = unicode('"' + self.machine_pass.encode('utf-8') + '"', 'utf-8').encode('utf-16-le') self.ldb.add({ "dn": self.machine_dn, "objectclass": "computer", "sAMAccountName": "%s$" % self.machine_name, "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT | UF_PASSWD_NOTREQD), "unicodePwd": utf16pw }) self.machine_creds = Credentials() self.machine_creds.guess(self.get_loadparm()) self.machine_creds.set_secure_channel_type(SEC_CHAN_WKSTA) self.machine_creds.set_password(self.machine_pass) self.machine_creds.set_username(self.machine_name + "$") self.machine_creds.set_workstation(self.machine_name)
def create_machine_account(self): self.machine_pass = samba.generate_random_password(32, 32) self.machine_name = MACHINE_NAME self.machine_dn = "cn=%s,%s" % (self.machine_name, self.ldb.domain_dn()) # remove the account if it exists, this will happen if a previous test # run failed delete_force(self.ldb, self.machine_dn) utf16pw = unicode( '"' + self.machine_pass.encode('utf-8') + '"', 'utf-8' ).encode('utf-16-le') self.ldb.add({ "dn": self.machine_dn, "objectclass": "computer", "sAMAccountName": "%s$" % self.machine_name, "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT | UF_PASSWD_NOTREQD), "unicodePwd": utf16pw}) self.machine_creds = Credentials() self.machine_creds.guess(self.get_loadparm()) self.machine_creds.set_secure_channel_type(SEC_CHAN_WKSTA) self.machine_creds.set_kerberos_state(DONT_USE_KERBEROS) self.machine_creds.set_password(self.machine_pass) self.machine_creds.set_username(self.machine_name + "$") self.machine_creds.set_workstation(self.machine_name)
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 create_user_account(self): self.user_pass = samba.generate_random_password(32, 32) self.user_name = USER_NAME self.user_dn = "cn=%s,%s" % (self.user_name, self.ldb.domain_dn()) # remove the account if it exists, this will happen if a previous test # run failed delete_force(self.ldb, self.user_dn) utf16pw = unicode('"' + self.user_pass.encode('utf-8') + '"', 'utf-8').encode('utf-16-le') self.ldb.add({ "dn": self.user_dn, "objectclass": "user", "sAMAccountName": "%s" % self.user_name, "userAccountControl": str(UF_NORMAL_ACCOUNT), "unicodePwd": utf16pw }) self.user_creds = Credentials() self.user_creds.guess(self.get_loadparm()) self.user_creds.set_password(self.user_pass) self.user_creds.set_username(self.user_name) self.user_creds.set_workstation(self.machine_name) pass
def create_user_account(cls): cls.user_pass = samba.generate_random_password(32, 32) cls.user_name = USER_NAME cls.user_dn = "cn=%s,%s" % (cls.user_name, cls.ldb.domain_dn()) # remove the account if it exists, this will happen if a previous test # run failed delete_force(cls.ldb, cls.user_dn) utf16pw = ('"%s"' % cls.user_pass).encode('utf-16-le') cls.ldb.add({ "dn": cls.user_dn, "objectclass": "user", "sAMAccountName": "%s" % cls.user_name, "userAccountControl": str(UF_NORMAL_ACCOUNT), "unicodePwd": utf16pw }) cls.user_creds = Credentials() cls.user_creds.guess(cls.lp) cls.user_creds.set_realm(cls.ldb.domain_dns_name().upper()) cls.user_creds.set_domain(cls.ldb.domain_netbios_name().upper()) cls.user_creds.set_password(cls.user_pass) cls.user_creds.set_username(cls.user_name) cls.user_creds.set_workstation(cls.machine_name)
def create_machine_account(cls): cls.machine_pass = samba.generate_random_password(32, 32) cls.machine_name = MACHINE_NAME cls.machine_dn = "cn=%s,%s" % (cls.machine_name, cls.ldb.domain_dn()) # remove the account if it exists, this will happen if a previous test # run failed delete_force(cls.ldb, cls.machine_dn) utf16pw = ('"%s"' % cls.machine_pass).encode('utf-16-le') cls.ldb.add({ "dn": cls.machine_dn, "objectclass": "computer", "sAMAccountName": "%s$" % cls.machine_name, "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT | UF_PASSWD_NOTREQD), "unicodePwd": utf16pw }) cls.machine_creds = Credentials() cls.machine_creds.guess(cls.lp) cls.machine_creds.set_realm(cls.ldb.domain_dns_name().upper()) cls.machine_creds.set_domain(cls.ldb.domain_netbios_name().upper()) cls.machine_creds.set_secure_channel_type(SEC_CHAN_WKSTA) cls.machine_creds.set_kerberos_state(DONT_USE_KERBEROS) cls.machine_creds.set_password(cls.machine_pass) cls.machine_creds.set_username(cls.machine_name + "$") cls.machine_creds.set_workstation(cls.machine_name)
def _test_uac_bits_add_with_args(self, bit, bit_str): computername = self.computernames[0] user_sid = self.sd_utils.get_object_sid(self.unpriv_user_dn) mod = "(OA;;CC;bf967a86-0de6-11d0-a285-00aa003049e2;;%s)" % str( user_sid) old_sd = self.sd_utils.read_sd_on_dn(self.OU) self.sd_utils.dacl_add_ace(self.OU, mod) invalid_bits = set([UF_TEMP_DUPLICATE_ACCOUNT]) # UF_NORMAL_ACCOUNT is invalid alone, needs UF_PASSWD_NOTREQD unwilling_bits = set([UF_NORMAL_ACCOUNT]) # These bits are privileged, but authenticated users have that CAR by default, so this is a pain to test priv_to_auth_users_bits = set([ UF_PASSWD_NOTREQD, UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED, UF_DONT_EXPIRE_PASSWD ]) # These bits really are privileged priv_bits = set([ UF_INTERDOMAIN_TRUST_ACCOUNT, UF_SERVER_TRUST_ACCOUNT, UF_TRUSTED_FOR_DELEGATION, UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION, UF_PARTIAL_SECRETS_ACCOUNT ]) if bit not in account_types and ((bit & UF_NORMAL_ACCOUNT) == 0): bit_add = bit | UF_WORKSTATION_TRUST_ACCOUNT else: bit_add = bit try: self.add_computer_ldap( computername, others={"userAccountControl": [str(bit_add)]}) delete_force(self.admin_samdb, "CN=%s,%s" % (computername, self.OU)) if bit in priv_bits: self.fail( "Unexpectdly able to set userAccountControl bit 0x%08X (%s) on %s" % (bit, bit_str, computername)) except LdbError as e4: (enum, estr) = e4.args if bit in invalid_bits: self.assertEqual( enum, ldb.ERR_OTHER, "Invalid bit 0x%08X (%s) was able to be set on %s" % (bit, bit_str, computername)) elif bit in priv_bits: self.assertEqual(enum, ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS) elif bit in unwilling_bits: self.assertEqual(enum, ldb.ERR_UNWILLING_TO_PERFORM) else: self.fail( "Unable to set userAccountControl bit 0x%08X (%s) on %s: %s" % (bit, bit_str, computername, estr))
def setUp(self): super(AuthLogPassChangeTests, self).setUp() self.remoteAddress = os.environ["CLIENT_IP"] self.server_ip = os.environ["SERVER_IP"] host = "ldap://%s" % os.environ["SERVER"] self.ldb = SamDB(url=host, session_info=system_session(), credentials=self.get_credentials(), lp=self.get_loadparm()) print("ldb %s" % type(self.ldb)) # Gets back the basedn base_dn = self.ldb.domain_dn() print("base_dn %s" % base_dn) # permit password changes during this test PasswordCommon.allow_password_changes(self, self.ldb) self.base_dn = self.ldb.domain_dn() # (Re)adds the test user USER_NAME with password USER_PASS delete_force(self.ldb, "cn=" + USER_NAME + ",cn=users," + self.base_dn) self.ldb.add({ "dn": "cn=" + USER_NAME + ",cn=users," + self.base_dn, "objectclass": "user", "sAMAccountName": USER_NAME, "userPassword": USER_PASS }) # discard any auth log messages for the password setup self.discardMessages()
def test_samr_GetGroupsForUser_nomember(self): # Confirm that we get the correct results against SAMR also if not url.startswith("ldap://"): self.fail( msg= "This test is only valid on ldap (so we an find the hostname and use SAMR)" ) host = url.split("://")[1] test_user = "******" self.admin_ldb.newuser(test_user, self.test_user_pass) res = self.admin_ldb.search(base="cn=%s,cn=users,%s" % (test_user, self.base_dn), attrs=["objectSid"], scope=ldb.SCOPE_BASE) user_sid = ndr_unpack(samba.dcerpc.security.dom_sid, res[0]["objectSid"][0]) (domain_sid, user_rid) = user_sid.split() samr_conn = samba.dcerpc.samr.samr("ncacn_ip_tcp:%s[seal]" % host, lp, creds) samr_handle = samr_conn.Connect2(None, security.SEC_FLAG_MAXIMUM_ALLOWED) samr_domain = samr_conn.OpenDomain(samr_handle, security.SEC_FLAG_MAXIMUM_ALLOWED, domain_sid) user_handle = samr_conn.OpenUser(samr_domain, security.SEC_FLAG_MAXIMUM_ALLOWED, user_rid) rids = samr_conn.GetGroupsForUser(user_handle) user_info = samr_conn.QueryUserInfo(user_handle, 1) delete_force(self.admin_ldb, "CN=%s,%s,%s" % (test_user, "cn=users", self.base_dn)) self.assertEqual(len(rids.rids), 1) self.assertEqual(rids.rids[0].rid, user_info.primary_gid)
def test_computer_account_bind(self): # create a computer acocount for the test delete_force(self.ldb, self.computer_dn) self.ldb.add_ldif(""" dn: """ + self.computer_dn + """ cn: CENTOS53 displayName: CENTOS53$ name: CENTOS53 sAMAccountName: CENTOS53$ countryCode: 0 objectClass: computer objectClass: organizationalPerson objectClass: person objectClass: top objectClass: user codePage: 0 userAccountControl: 4096 dNSHostName: centos53.alabala.test operatingSystemVersion: 5.2 (3790) operatingSystem: Windows Server 2003 """) self.ldb.modify_ldif(""" dn: """ + self.computer_dn + """ changetype: modify replace: unicodePwd unicodePwd:: """ + base64.b64encode("\"P@ssw0rd\"".encode('utf-16-le')) + """ """) # do a simple bind and search with the machine account creds_machine.set_bind_dn(self.computer_dn) creds_machine.set_password(self.password) print "BindTest with: " + creds_machine.get_bind_dn() ldb_machine = samba.tests.connect_samdb(host, credentials=creds_machine, lp=lp, ldap_only=True) res = ldb_machine.search(base="", expression="", scope=SCOPE_BASE, attrs=["*"])
def remove_test_users(self): res = ldb.search(base="cn=Users,%s" % self.base_dn, expression="(objectClass=user)", scope=SCOPE_SUBTREE) dn_list = [item.dn for item in res if "speedtestuser" in str(item.dn)] for dn in dn_list: delete_force(self.ldb_admin, dn)
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_subClassOf(self): """ Testing usage of custom child schamaClass """ class_name = "my-Class" + time.strftime("%s", time.gmtime()) class_ldap_display_name = class_name.replace("-", "") ldif = """ dn: CN=%s,%s""" % (class_name, self.schema_dn) + """ objectClass: top objectClass: classSchema adminDescription: """ + class_name + """ adminDisplayName: """ + class_name + """ cn: """ + class_name + """ governsId: 1.2.840.""" + str(random.randint(1,100000)) + """.1.5.9939 instanceType: 4 objectClassCategory: 1 subClassOf: organizationalUnit systemFlags: 16 systemOnly: FALSE """ self.ldb.add_ldif(ldif) # Search for created objectclass res = [] res = self.ldb.search("cn=%s,%s" % (class_name, self.schema_dn), scope=SCOPE_BASE, attrs=["lDAPDisplayName", "defaultObjectCategory", "schemaIDGUID", "distinguishedName"]) self.assertEquals(len(res), 1) self.assertEquals(res[0]["lDAPDisplayName"][0], class_ldap_display_name) self.assertEquals(res[0]["defaultObjectCategory"][0], res[0]["distinguishedName"][0]) self.assertTrue("schemaIDGUID" in res[0]) ldif = """ dn: changetype: modify add: schemaUpdateNow schemaUpdateNow: 1 """ self.ldb.modify_ldif(ldif) object_name = "org" + time.strftime("%s", time.gmtime()) ldif = """ dn: OU=%s,%s""" % (object_name, self.base_dn) + """ objectClass: """ + class_ldap_display_name + """ ou: """ + object_name + """ instanceType: 4 """ self.ldb.add_ldif(ldif) # Search for created object res = [] res = self.ldb.search("ou=%s,%s" % (object_name, self.base_dn), scope=SCOPE_BASE, attrs=["dn"]) self.assertEquals(len(res), 1) # Delete the object delete_force(self.ldb, "ou=%s,%s" % (object_name, self.base_dn))
def tearDown(self): self.samdb.transaction_start() for site in self.sites: delete_force(self.samdb, site, controls=['tree_delete:1']) for site_link in self.site_links: delete_force(self.samdb, site_link) self.samdb.transaction_commit()
def create_computers(self, ids): dns = [] for i in ids: name = "SAMR_CMP%d" % i dn = "cn=%s,cn=COMPUTERS,%s" % (name, self.samdb.domain_dn()) delete_force(self.samdb, dn) self.samdb.newcomputer(name, description="Description of " + name) dns.append(dn) return dns
def create_groups(self, ids): dns = [] for i in ids: name = "SAMR_GRP%d" % i dn = "cn=%s,cn=Users,%s" % (name, self.samdb.domain_dn()) delete_force(self.samdb, dn) self.samdb.newgroup(name) dns.append(dn) return dns
def add_user(self, options=None, clear_text=False, ldb=None): # set any needed options if options is not None: for (option, value) in options: self.lp.set(option, value) if ldb is None: self.creds = Credentials() self.session = system_session() self.creds.guess(self.lp) self.session = system_session() self.ldb = SamDB(session_info=self.session, credentials=self.creds, lp=self.lp) else: self.ldb = ldb res = self.ldb.search(base=self.ldb.get_config_basedn(), expression="ncName=%s" % self.ldb.get_default_basedn(), attrs=["nETBIOSName"]) self.netbios_domain = res[0]["nETBIOSName"][0] self.dns_domain = self.ldb.domain_dns_name() # Gets back the basedn base_dn = self.ldb.domain_dn() # Gets back the configuration basedn configuration_dn = self.ldb.get_config_basedn().get_linearized() # permit password changes during this test PasswordCommon.allow_password_changes(self, self.ldb) self.base_dn = self.ldb.domain_dn() account_control = 0 if clear_text: # Restore the current domain setting on exit. pwdProperties = self.ldb.get_pwdProperties() self.addCleanup(self.ldb.set_pwdProperties, pwdProperties) # Update the domain setting self.set_store_cleartext(clear_text) account_control |= UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED # (Re)adds the test user USER_NAME with password USER_PASS # and userPrincipalName UPN delete_force(self.ldb, "cn=" + USER_NAME + ",cn=users," + self.base_dn) self.ldb.add({ "dn": "cn=" + USER_NAME + ",cn=users," + self.base_dn, "objectclass": "user", "sAMAccountName": USER_NAME, "userPassword": USER_PASS, "userPrincipalName": UPN, "userAccountControl": str(account_control) })
def setUp(self): super().setUp() strict_checking = samba.tests.env_get_var_value('STRICT_CHECKING', allow_missing=True) if strict_checking is None: strict_checking = '1' self.strict_checking = bool(int(strict_checking)) self.admin_creds = creds self.admin_samdb = SamDB(url=ldaphost, credentials=self.admin_creds, lp=lp) self.domain_sid = security.dom_sid(self.admin_samdb.get_domain_sid()) self.base_dn = self.admin_samdb.domain_dn() self.unpriv_user = "******" self.unpriv_user_pw = "samba123@" self.unpriv_creds = self.get_creds(self.unpriv_user, self.unpriv_user_pw) self.admin_sd_utils = sd_utils.SDUtils(self.admin_samdb) self.test_ou_name = "OU=test_priv_attrs" self.test_ou = self.test_ou_name + "," + self.base_dn delete_force(self.admin_samdb, self.test_ou, controls=["tree_delete:0"]) self.admin_samdb.create_ou(self.test_ou) expected_user_dn = f"CN={self.unpriv_user},{self.test_ou_name},{self.base_dn}" self.admin_samdb.newuser(self.unpriv_user, self.unpriv_user_pw, userou=self.test_ou_name) res = self.admin_samdb.search(expected_user_dn, scope=SCOPE_BASE, attrs=["objectSid"]) self.assertEqual(1, len(res)) self.unpriv_user_dn = res[0].dn self.addCleanup(delete_force, self.admin_samdb, self.unpriv_user_dn, controls=["tree_delete:0"]) self.unpriv_user_sid = self.admin_sd_utils.get_object_sid( self.unpriv_user_dn) self.unpriv_samdb = SamDB(url=ldaphost, credentials=self.unpriv_creds, lp=lp)
def add_user(self, options=None, clear_text=False, ldb=None): # set any needed options if options is not None: for (option, value) in options: self.lp.set(option, value) if ldb is None: self.creds = Credentials() self.session = system_session() self.creds.guess(self.lp) self.session = system_session() self.ldb = SamDB(session_info=self.session, credentials=self.creds, lp=self.lp) else: self.ldb = ldb res = self.ldb.search(base=self.ldb.get_config_basedn(), expression="ncName=%s" % self.ldb.get_default_basedn(), attrs=["nETBIOSName"]) self.netbios_domain = str(res[0]["nETBIOSName"][0]) self.dns_domain = self.ldb.domain_dns_name() # Gets back the basedn base_dn = self.ldb.domain_dn() # Gets back the configuration basedn configuration_dn = self.ldb.get_config_basedn().get_linearized() # permit password changes during this test PasswordCommon.allow_password_changes(self, self.ldb) self.base_dn = self.ldb.domain_dn() account_control = 0 if clear_text: # Restore the current domain setting on exit. pwdProperties = self.ldb.get_pwdProperties() self.addCleanup(self.ldb.set_pwdProperties, pwdProperties) # Update the domain setting self.set_store_cleartext(clear_text) account_control |= UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED # (Re)adds the test user USER_NAME with password USER_PASS # and userPrincipalName UPN delete_force(self.ldb, "cn=" + USER_NAME + ",cn=users," + self.base_dn) self.ldb.add({ "dn": "cn=" + USER_NAME + ",cn=users," + self.base_dn, "objectclass": "user", "sAMAccountName": USER_NAME, "userPassword": USER_PASS, "userPrincipalName": UPN, "userAccountControl": str(account_control) })
def test_uac_bits_add(self): computername = self.computernames[0] user_sid = self.sd_utils.get_object_sid(self.unpriv_user_dn) mod = "(OA;;CC;bf967a86-0de6-11d0-a285-00aa003049e2;;%s)" % str( user_sid) old_sd = self.sd_utils.read_sd_on_dn("OU=test_computer_ou1," + self.base_dn) self.sd_utils.dacl_add_ace("OU=test_computer_ou1," + self.base_dn, mod) invalid_bits = set( [UF_TEMP_DUPLICATE_ACCOUNT, UF_PARTIAL_SECRETS_ACCOUNT]) # These bits are privileged, but authenticated users have that CAR by default, so this is a pain to test priv_to_auth_users_bits = set([ UF_PASSWD_NOTREQD, UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED, UF_DONT_EXPIRE_PASSWD ]) # These bits really are privileged priv_bits = set([ UF_INTERDOMAIN_TRUST_ACCOUNT, UF_SERVER_TRUST_ACCOUNT, UF_TRUSTED_FOR_DELEGATION, UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION ]) for bit in bits: try: self.add_computer_ldap( computername, others={"userAccountControl": [str(bit)]}) delete_force( self.admin_samdb, "CN=%s,OU=test_computer_ou1,%s" % (computername, self.base_dn)) if bit in priv_bits: self.fail( "Unexpectdly able to set userAccountControl bit 0x%08X on %s" % (bit, computername)) except LdbError as e4: (enum, estr) = e4.args if bit in invalid_bits: self.assertEqual( enum, ldb.ERR_OTHER, "Invalid bit 0x%08X was able to be set on %s" % (bit, computername)) # No point going on, try the next bit continue elif bit in priv_bits: self.assertEqual(enum, ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS) continue else: self.fail( "Unable to set userAccountControl bit 0x%08X on %s: %s" % (bit, computername, estr))
def tearDown(self): super(Bug13653Tests, self).tearDown() try: dn = "CN=%s,CN=Users,%s" % (self.user, self.ldb.domain_dn()) delete_force(self.ldb, dn) except Exception as e: # We ignore any exceptions deleting the user in tearDown # this allows the known fail mechanism to work for this test # so the test can be committed before the fix. # otherwise this delete fails with # Error(11) unpacking encrypted secret, data possibly corrupted # or altered pass
def setUp(self): super(AuthLogPassChangeTests, self).setUp() self.remoteAddress = os.environ["CLIENT_IP"] self.server_ip = os.environ["SERVER_IP"] host = "ldap://%s" % os.environ["SERVER"] self.ldb = SamDB(url=host, session_info=system_session(), credentials=self.get_credentials(), lp=self.get_loadparm()) print "ldb %s" % type(self.ldb) # Gets back the basedn base_dn = self.ldb.domain_dn() print "base_dn %s" % base_dn # Gets back the configuration basedn configuration_dn = self.ldb.get_config_basedn().get_linearized() # Get the old "dSHeuristics" if it was set dsheuristics = self.ldb.get_dsheuristics() # Set the "dSHeuristics" to activate the correct "userPassword" # behaviour self.ldb.set_dsheuristics("000000001") # Reset the "dSHeuristics" as they were before self.addCleanup(self.ldb.set_dsheuristics, dsheuristics) # Get the old "minPwdAge" minPwdAge = self.ldb.get_minPwdAge() # Set it temporarily to "0" self.ldb.set_minPwdAge("0") self.base_dn = self.ldb.domain_dn() # Reset the "minPwdAge" as it was before self.addCleanup(self.ldb.set_minPwdAge, minPwdAge) # (Re)adds the test user USER_NAME with password USER_PASS delete_force(self.ldb, "cn=" + USER_NAME + ",cn=users," + self.base_dn) self.ldb.add({ "dn": "cn=" + USER_NAME + ",cn=users," + self.base_dn, "objectclass": "user", "sAMAccountName": USER_NAME, "userPassword": USER_PASS }) # discard any auth log messages for the password setup self.discardMessages()
def tearDown(self): super(UserAccountControlTests, self).tearDown() for computername in self.computernames: delete_force(self.admin_samdb, "CN=%s,OU=test_computer_ou1,%s" % (computername, self.base_dn)) delete_force(self.admin_samdb, "CN=testcomputer-t,OU=test_computer_ou1,%s" % (self.base_dn)) delete_force(self.admin_samdb, "OU=test_computer_ou1,%s" % (self.base_dn)) delete_force(self.admin_samdb, "CN=%s,CN=Users,%s" % (self.unpriv_user, self.base_dn))
def tearDown(self): super(UserAccountControlTests, self).tearDown() for computername in self.computernames: delete_force(self.admin_samdb, "CN={0!s},OU=test_computer_ou1,{1!s}".format(computername, self.base_dn)) delete_force(self.admin_samdb, "CN=testcomputer-t,OU=test_computer_ou1,{0!s}".format((self.base_dn))) delete_force(self.admin_samdb, "OU=test_computer_ou1,{0!s}".format((self.base_dn))) delete_force(self.admin_samdb, "CN={0!s},CN=Users,{1!s}".format(self.unpriv_user, self.base_dn))
def create_account(self, name, machine_account=False, spn=None, upn=None): '''Create an account for testing. The dn of the created account is added to self.accounts, which is used by tearDown to clean up the created accounts. ''' dn = "cn=%s,%s" % (name, self.ldb.domain_dn()) # remove the account if it exists, this will happen if a previous test # run failed delete_force(self.ldb, dn) if machine_account: object_class = "computer" account_name = "%s$" % name account_control = str(UF_WORKSTATION_TRUST_ACCOUNT) else: object_class = "user" account_name = name account_control = str(UF_NORMAL_ACCOUNT) password = generate_random_password(32, 32) utf16pw = ('"%s"' % password).encode('utf-16-le') details = { "dn": dn, "objectclass": object_class, "sAMAccountName": account_name, "userAccountControl": account_control, "unicodePwd": utf16pw } if spn is not None: details["servicePrincipalName"] = spn if upn is not None: details["userPrincipalName"] = upn self.ldb.add(details) creds = Credentials() creds.guess(self.lp) creds.set_realm(self.ldb.domain_dns_name().upper()) creds.set_domain(self.ldb.domain_netbios_name().upper()) creds.set_password(password) creds.set_username(account_name) if machine_account: creds.set_workstation(name) # # Save the account name so it can be deleted in the tearDown self.accounts.append(dn) return (creds, dn)
def setUp(self): self.message_type = MSG_DSDB_LOG self.event_type = DSDB_EVENT_NAME super(AuditLogDsdbTests, self).setUp() self.remoteAddress = os.environ["CLIENT_IP"] self.server_ip = os.environ["SERVER_IP"] host = "ldap://%s" % os.environ["SERVER"] self.ldb = SamDB(url=host, session_info=system_session(), credentials=self.get_credentials(), lp=self.get_loadparm()) self.server = os.environ["SERVER"] # Gets back the basedn self.base_dn = self.ldb.domain_dn() # Get the old "dSHeuristics" if it was set dsheuristics = self.ldb.get_dsheuristics() # Set the "dSHeuristics" to activate the correct "userPassword" # behaviour self.ldb.set_dsheuristics("000000001") # Reset the "dSHeuristics" as they were before self.addCleanup(self.ldb.set_dsheuristics, dsheuristics) # Get the old "minPwdAge" minPwdAge = self.ldb.get_minPwdAge() # Set it temporarily to "0" self.ldb.set_minPwdAge("0") self.base_dn = self.ldb.domain_dn() # Reset the "minPwdAge" as it was before self.addCleanup(self.ldb.set_minPwdAge, minPwdAge) # (Re)adds the test user USER_NAME with password USER_PASS delete_force(self.ldb, "cn=" + USER_NAME + ",cn=users," + self.base_dn) delete_force(self.ldb, "cn=" + SECOND_USER_NAME + ",cn=users," + self.base_dn) self.ldb.add({ "dn": "cn=" + USER_NAME + ",cn=users," + self.base_dn, "objectclass": "user", "sAMAccountName": USER_NAME, "userPassword": USER_PASS })
def create_users(self, ids): dns = [] for i in ids: name = "SAMR_USER%d" % i dn = "cn=%s,CN=USERS,%s" % (name, self.samdb.domain_dn()) delete_force(self.samdb, dn) # We only need the user to exist, we don't need a password self.samdb.newuser(name, password=None, setpassword=False, description="Description for " + name, givenname="given%dname" % i, surname="surname%d" % i) dns.append(dn) return dns
def _readd_user(self, creds, lockOutObservationWindow=0): username = creds.get_username() userpass = creds.get_password() userdn = "cn=%s,cn=users,%s" % (username, self.base_dn) delete_force(self.ldb, userdn) self.ldb.add({ "dn": userdn, "objectclass": "user", "sAMAccountName": username }) self.addCleanup(delete_force, self.ldb, userdn) # Sets the initial user password with a "special" password change # I think that this internally is a password set operation and it can # only be performed by someone which has password set privileges on the # account (at least in s4 we do handle it like that). self.ldb.modify_ldif(""" dn: """ + userdn + """ changetype: modify delete: userPassword add: userPassword userPassword: """ + userpass + """ """) # Enables the user account self.ldb.enable_account("(sAMAccountName=%s)" % username) use_kerberos = creds.get_kerberos_state() fail_creds = self.insta_creds(self.template_creds, username=username, userpass=userpass + "X", kerberos_state=use_kerberos) self._check_account_initial(userdn) # Fail once to get a badPasswordTime try: ldb = SamDB(url=self.host_url, credentials=fail_creds, lp=self.lp) self.fail() except LdbError as e: (num, msg) = e.args self.assertEquals(num, ERR_INVALID_CREDENTIALS) # Succeed to reset everything to 0 ldb = SamDB(url=self.host_url, credentials=creds, lp=self.lp) return ldb
def setUp(self): self.message_type = MSG_DSDB_LOG self.event_type = DSDB_EVENT_NAME super(AuditLogDsdbTests, self).setUp() self.remoteAddress = os.environ["CLIENT_IP"] self.server_ip = os.environ["SERVER_IP"] host = "ldap://%s" % os.environ["SERVER"] self.ldb = SamDB(url=host, session_info=system_session(), credentials=self.get_credentials(), lp=self.get_loadparm()) self.server = os.environ["SERVER"] # Gets back the basedn self.base_dn = self.ldb.domain_dn() # Get the old "dSHeuristics" if it was set dsheuristics = self.ldb.get_dsheuristics() # Set the "dSHeuristics" to activate the correct "userPassword" # behaviour self.ldb.set_dsheuristics("000000001") # Reset the "dSHeuristics" as they were before self.addCleanup(self.ldb.set_dsheuristics, dsheuristics) # Get the old "minPwdAge" minPwdAge = self.ldb.get_minPwdAge() # Set it temporarily to "0" self.ldb.set_minPwdAge("0") self.base_dn = self.ldb.domain_dn() # Reset the "minPwdAge" as it was before self.addCleanup(self.ldb.set_minPwdAge, minPwdAge) # (Re)adds the test user USER_NAME with password USER_PASS delete_force(self.ldb, "cn=" + USER_NAME + ",cn=users," + self.base_dn) self.ldb.add({ "dn": "cn=" + USER_NAME + ",cn=users," + self.base_dn, "objectclass": "user", "sAMAccountName": USER_NAME, "userPassword": USER_PASS })
def _readd_user(self, creds, lockOutObservationWindow=0): username = creds.get_username() userpass = creds.get_password() userdn = "cn=%s,cn=users,%s" % (username, self.base_dn) delete_force(self.ldb, userdn) self.ldb.add({ "dn": userdn, "objectclass": "user", "sAMAccountName": username}) self.addCleanup(delete_force, self.ldb, userdn) # Sets the initial user password with a "special" password change # I think that this internally is a password set operation and it can # only be performed by someone which has password set privileges on the # account (at least in s4 we do handle it like that). self.ldb.modify_ldif(""" dn: """ + userdn + """ changetype: modify delete: userPassword add: userPassword userPassword: """ + userpass + """ """) # Enables the user account self.ldb.enable_account("(sAMAccountName=%s)" % username) use_kerberos = creds.get_kerberos_state() fail_creds = self.insta_creds(self.template_creds, username=username, userpass=userpass+"X", kerberos_state=use_kerberos) self._check_account_initial(userdn) # Fail once to get a badPasswordTime try: ldb = SamDB(url=self.host_url, credentials=fail_creds, lp=self.lp) self.fail() except LdbError as e: (num, msg) = e.args self.assertEquals(num, ERR_INVALID_CREDENTIALS) # Succeed to reset everything to 0 ldb = SamDB(url=self.host_url, credentials=creds, lp=self.lp) return ldb
def tearDown(self): super(DynamicTokenTest, self).tearDown() delete_force(self.admin_ldb, "CN=%s,%s,%s" % (self.test_user, "cn=users", self.base_dn)) delete_force(self.admin_ldb, "CN=%s,%s,%s" % (self.test_group0, "cn=users", self.base_dn)) delete_force(self.admin_ldb, "CN=%s,%s,%s" % (self.test_group1, "cn=users", self.base_dn)) delete_force(self.admin_ldb, "CN=%s,%s,%s" % (self.test_group2, "cn=users", self.base_dn))
def netlogon(self): server = os.environ["SERVER"] host = os.environ["SERVER_IP"] lp = self.get_loadparm() credentials = self.get_credentials() session = system_session() ldb = SamDB(url="ldap://%s" % host, session_info=session, credentials=credentials, lp=lp) machine_pass = samba.generate_random_password(32, 32) machine_name = MACHINE_NAME machine_dn = "cn=%s,%s" % (machine_name, ldb.domain_dn()) delete_force(ldb, machine_dn) utf16pw = ('"%s"' % get_string(machine_pass)).encode('utf-16-le') ldb.add({ "dn": machine_dn, "objectclass": "computer", "sAMAccountName": "%s$" % machine_name, "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT | UF_PASSWD_NOTREQD), "unicodePwd": utf16pw }) machine_creds = Credentials() machine_creds.guess(lp) machine_creds.set_secure_channel_type(SEC_CHAN_WKSTA) machine_creds.set_kerberos_state(DONT_USE_KERBEROS) machine_creds.set_password(machine_pass) machine_creds.set_username(machine_name + "$") machine_creds.set_workstation(machine_name) netlogon.netlogon("ncacn_ip_tcp:%s[schannel,seal]" % server, lp, machine_creds) delete_force(ldb, machine_dn)
def tearDown(self): super(SimpleDirsyncTests, self).tearDown() delete_force(self.ldb_admin, self.get_user_dn(self.dirsync_user)) delete_force(self.ldb_admin, self.get_user_dn(self.simple_user)) delete_force(self.ldb_admin, self.get_user_dn(self.admin_user)) if self.ouname: delete_force(self.ldb_admin, self.ouname) self.sd_utils.modify_sd_on_dn(self.base_dn, self.desc_sddl) try: self.ldb_admin.deletegroup("testgroup") except Exception: pass
def setUp(self): super(UserAccountControlTests, self).setUp() self.admin_creds = creds self.admin_samdb = SamDB(url=ldaphost, session_info=system_session(), credentials=self.admin_creds, lp=lp) self.domain_sid = security.dom_sid(self.admin_samdb.get_domain_sid()) self.base_dn = self.admin_samdb.domain_dn() self.unpriv_user = "******" self.unpriv_user_pw = "samba123@" self.unpriv_creds = self.get_creds(self.unpriv_user, self.unpriv_user_pw) delete_force(self.admin_samdb, "CN=testcomputer-t,OU=test_computer_ou1,%s" % (self.base_dn)) delete_force(self.admin_samdb, "OU=test_computer_ou1,%s" % (self.base_dn)) delete_force(self.admin_samdb, "CN=%s,CN=Users,%s" % (self.unpriv_user, self.base_dn)) self.admin_samdb.newuser(self.unpriv_user, self.unpriv_user_pw) res = self.admin_samdb.search("CN=%s,CN=Users,%s" % (self.unpriv_user, self.admin_samdb.domain_dn()), scope=SCOPE_BASE, attrs=["objectSid"]) self.assertEqual(1, len(res)) self.unpriv_user_sid = ndr_unpack(security.dom_sid, res[0]["objectSid"][0]) self.unpriv_user_dn = res[0].dn self.samdb = SamDB(url=ldaphost, credentials=self.unpriv_creds, lp=lp) self.samr = samr.samr("ncacn_ip_tcp:%s[seal]" % host, lp, self.unpriv_creds) self.samr_handle = self.samr.Connect2(None, security.SEC_FLAG_MAXIMUM_ALLOWED) self.samr_domain = self.samr.OpenDomain(self.samr_handle, security.SEC_FLAG_MAXIMUM_ALLOWED, self.domain_sid) self.sd_utils = sd_utils.SDUtils(self.admin_samdb) self.admin_samdb.create_ou("OU=test_computer_ou1," + self.base_dn) self.unpriv_user_sid = self.sd_utils.get_object_sid(self.unpriv_user_dn) mod = "(OA;;CC;bf967a86-0de6-11d0-a285-00aa003049e2;;%s)" % str(self.unpriv_user_sid) old_sd = self.sd_utils.read_sd_on_dn("OU=test_computer_ou1," + self.base_dn) self.sd_utils.dacl_add_ace("OU=test_computer_ou1," + self.base_dn, mod) self.add_computer_ldap("testcomputer-t") self.sd_utils.modify_sd_on_dn("OU=test_computer_ou1," + self.base_dn, old_sd) self.computernames = ["testcomputer-0"] # Get the SD of the template account, then force it to match # what we expect for SeMachineAccountPrivilege accounts, so we # can confirm we created the accounts correctly self.sd_reference_cc = self.sd_utils.read_sd_on_dn("CN=testcomputer-t,OU=test_computer_ou1,%s" % (self.base_dn)) self.sd_reference_modify = self.sd_utils.read_sd_on_dn("CN=testcomputer-t,OU=test_computer_ou1,%s" % (self.base_dn)) for ace in self.sd_reference_modify.dacl.aces: if ace.type == security.SEC_ACE_TYPE_ACCESS_ALLOWED and ace.trustee == self.unpriv_user_sid: ace.access_mask = ace.access_mask | security.SEC_ADS_SELF_WRITE | security.SEC_ADS_WRITE_PROP # Now reconnect without domain admin rights self.samdb = SamDB(url=ldaphost, credentials=self.unpriv_creds, lp=lp)
def tearDown(self): super(DynamicTokenTest, self).tearDown() delete_force( self.admin_ldb, "CN=%s,%s,%s" % (self.test_user, "cn=users", self.base_dn)) delete_force( self.admin_ldb, "CN=%s,%s,%s" % (self.test_group0, "cn=users", self.base_dn)) delete_force( self.admin_ldb, "CN=%s,%s,%s" % (self.test_group1, "cn=users", self.base_dn)) delete_force( self.admin_ldb, "CN=%s,%s,%s" % (self.test_group2, "cn=users", self.base_dn))
def test_dirsync_deleted_items(self): """Check that dirsync returnd deleted objects too""" # Let's create an OU self.ldb_simple = self.get_ldb_connection(self.simple_user, self.user_pass) ouname = "OU=testou3,%s" % self.base_dn self.ouname = ouname self.ldb_admin.create_ou(ouname) # Specify LDAP_DIRSYNC_OBJECT_SECURITY res = self.ldb_simple.search( self.base_dn, expression="(&(objectClass=organizationalUnit)(!(isDeleted=*)))", controls=["dirsync:1:1:1"]) guid = None for e in res: if str(e["name"]) == "testou3": guid = str(ndr_unpack(misc.GUID, e.get("objectGUID")[0])) self.assertTrue(guid != None) ctl = str(res.controls[0]).split(":") ctl[1] = "1" ctl[2] = "1" ctl[3] = "10000" control1 = str(":".join(ctl)) # So now delete the object and check that # we can see the object but deleted when admin # we just see the objectGUID when simple user delete_force(self.ldb_admin, ouname) res = self.ldb_simple.search( self.base_dn, expression="(objectClass=organizationalUnit)", controls=[control1]) self.assertEqual(len(res), 1) guid2 = str(ndr_unpack(misc.GUID, res[0].get("objectGUID")[0])) self.assertEqual(guid2, guid) self.assertEqual(str(res[0].dn), "")
def test_uac_bits_add(self): computername=self.computernames[0] user_sid = self.sd_utils.get_object_sid(self.unpriv_user_dn) mod = "(OA;;CC;bf967a86-0de6-11d0-a285-00aa003049e2;;%s)" % str(user_sid) old_sd = self.sd_utils.read_sd_on_dn("OU=test_computer_ou1," + self.base_dn) self.sd_utils.dacl_add_ace("OU=test_computer_ou1," + self.base_dn, mod) invalid_bits = set([UF_TEMP_DUPLICATE_ACCOUNT, UF_PARTIAL_SECRETS_ACCOUNT]) # These bits are privileged, but authenticated users have that CAR by default, so this is a pain to test priv_to_auth_users_bits = set([UF_PASSWD_NOTREQD, UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED, UF_DONT_EXPIRE_PASSWD]) # These bits really are privileged priv_bits = set([UF_INTERDOMAIN_TRUST_ACCOUNT, UF_SERVER_TRUST_ACCOUNT, UF_TRUSTED_FOR_DELEGATION, UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION]) for bit in bits: try: self.add_computer_ldap(computername, others={"userAccountControl": [str(bit)]}) delete_force(self.admin_samdb, "CN=%s,OU=test_computer_ou1,%s" % (computername, self.base_dn)) if bit in priv_bits: self.fail("Unexpectdly able to set userAccountControl bit 0x%08X on %s" % (bit, computername)) except LdbError as e4: (enum, estr) = e4.args if bit in invalid_bits: self.assertEqual(enum, ldb.ERR_OTHER, "Invalid bit 0x%08X was able to be set on %s" % (bit, computername)) # No point going on, try the next bit continue elif bit in priv_bits: self.assertEqual(enum, ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS) continue else: self.fail("Unable to set userAccountControl bit 0x%08X on %s: %s" % (bit, computername, estr))
def test_dirsync_deleted_items(self): """Check that dirsync returnd deleted objects too""" # Let's create an OU self.ldb_simple = self.get_ldb_connection(self.simple_user, self.user_pass) ouname="OU=testou3,%s" % self.base_dn self.ouname = ouname self.ldb_admin.create_ou(ouname) # Specify LDAP_DIRSYNC_OBJECT_SECURITY res = self.ldb_simple.search(self.base_dn, expression="(&(objectClass=organizationalUnit)(!(isDeleted=*)))", controls=["dirsync:1:1:1"]) guid = None for e in res: if str(e["name"]) == "testou3": guid = str(ndr_unpack(misc.GUID,e.get("objectGUID")[0])) self.assertTrue(guid != None) ctl = str(res.controls[0]).split(":") ctl[1] = "1" ctl[2] = "1" ctl[3] = "10000" control1 = str(":".join(ctl)) # So now delete the object and check that # we can see the object but deleted when admin # we just see the objectGUID when simple user delete_force(self.ldb_admin, ouname) res = self.ldb_simple.search(self.base_dn, expression="(objectClass=organizationalUnit)", controls=[control1]) self.assertEqual(len(res), 1) guid2 = str(ndr_unpack(misc.GUID,res[0].get("objectGUID")[0])) self.assertEqual(guid2, guid) self.assertEqual(str(res[0].dn), "")
def create_machine_account(self): self.machine_pass = samba.generate_random_password(32, 32) self.machine_name = MACHINE_NAME self.machine_dn = "cn=%s,%s" % (self.machine_name, self.ldb.domain_dn()) # remove the account if it exists, this will happen if a previous test # run failed delete_force(self.ldb, self.machine_dn) # get unicode str for both py2 and py3 pass_unicode = self.machine_pass.encode('utf-8').decode('utf-8') utf16pw = u'"{}"'.format(pass_unicode).encode('utf-16-le') self.ldb.add({ "dn": self.machine_dn, "objectclass": "computer", "sAMAccountName": "%s$" % self.machine_name, "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT | UF_PASSWD_NOTREQD), "unicodePwd": utf16pw}) self.machine_creds = Credentials() self.machine_creds.guess(self.get_loadparm()) self.machine_creds.set_password(self.machine_pass) self.machine_creds.set_username(self.machine_name + "$") self.machine_creds.set_workstation(self.machine_name)
def test_samr_GetGroupsForUser_nomember(self): # Confirm that we get the correct results against SAMR also if not url.startswith("ldap://"): self.fail(msg="This test is only valid on ldap (so we an find the hostname and use SAMR)") host = url.split("://")[1] test_user = "******" self.admin_ldb.newuser(test_user, self.test_user_pass) res = self.admin_ldb.search(base="cn=%s,cn=users,%s" % (test_user, self.base_dn), attrs=["objectSid"], scope=ldb.SCOPE_BASE) user_sid = ndr_unpack(samba.dcerpc.security.dom_sid, res[0]["objectSid"][0]) (domain_sid, user_rid) = user_sid.split() samr_conn = samba.dcerpc.samr.samr("ncacn_ip_tcp:%s[seal]" % host, lp, creds) samr_handle = samr_conn.Connect2(None, security.SEC_FLAG_MAXIMUM_ALLOWED) samr_domain = samr_conn.OpenDomain(samr_handle, security.SEC_FLAG_MAXIMUM_ALLOWED, domain_sid) user_handle = samr_conn.OpenUser(samr_domain, security.SEC_FLAG_MAXIMUM_ALLOWED, user_rid) rids = samr_conn.GetGroupsForUser(user_handle) user_info = samr_conn.QueryUserInfo(user_handle, 1) delete_force(self.admin_ldb, "CN=%s,%s,%s" % (test_user, "cn=users", self.base_dn)) self.assertEqual(len(rids.rids), 1) self.assertEqual(rids.rids[0].rid, user_info.primary_gid)
def test_delete_protection(self): """Delete protection tests""" print self.base_dn delete_force(self.ldb, "cn=entry1,cn=ldaptestcontainer," + self.base_dn) delete_force(self.ldb, "cn=entry2,cn=ldaptestcontainer," + self.base_dn) delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn) self.ldb.add({"dn": "cn=ldaptestcontainer," + self.base_dn, "objectclass": "container"}) self.ldb.add({"dn": "cn=entry1,cn=ldaptestcontainer," + self.base_dn, "objectclass": "container"}) self.ldb.add({"dn": "cn=entry2,cn=ldaptestcontainer," + self.base_dn, "objectclass": "container"}) try: self.ldb.delete("cn=ldaptestcontainer," + self.base_dn) self.fail() except LdbError, (num, _): self.assertEquals(num, ERR_NOT_ALLOWED_ON_NON_LEAF)
def tearDown(self): super(MatchRulesTests, self).tearDown() delete_force(self.ldb, "cn=u4,%s" % self.ou_users) delete_force(self.ldb, "cn=u3,%s" % self.ou_users) delete_force(self.ldb, "cn=u2,%s" % self.ou_users) delete_force(self.ldb, "cn=u1,%s" % self.ou_users) delete_force(self.ldb, "cn=g4,%s" % self.ou_groups) delete_force(self.ldb, "cn=g3,%s" % self.ou_groups) delete_force(self.ldb, "cn=g2,%s" % self.ou_groups) delete_force(self.ldb, "cn=g1,%s" % self.ou_groups) delete_force(self.ldb, "cn=c1,%s" % self.ou_computers) delete_force(self.ldb, "cn=c2,%s" % self.ou_computers) delete_force(self.ldb, "cn=c3,%s" % self.ou_computers) delete_force(self.ldb, self.ou_users) delete_force(self.ldb, self.ou_groups) delete_force(self.ldb, self.ou_computers) delete_force(self.ldb, "OU=o4,OU=o3,OU=o2,OU=o1,%s" % self.ou) delete_force(self.ldb, "OU=o3,OU=o2,OU=o1,%s" % self.ou) delete_force(self.ldb, "OU=o2,OU=o1,%s" % self.ou) delete_force(self.ldb, "OU=o1,%s" % self.ou) delete_force(self.ldb, "CN=e2,%s" % self.ou) delete_force(self.ldb, "CN=e1,%s" % self.ou) delete_force(self.ldb, self.ou)
def tearDown(self): super(GroupAuditTests, self).tearDown() delete_force(self.ldb, "cn=" + USER_NAME + ",cn=users," + self.base_dn) self.ldb.deletegroup(GROUP_NAME_01) self.ldb.deletegroup(GROUP_NAME_02)
def add_user(self, options=None, clear_text=False): self.lp = samba.tests.env_loadparm() # set any needed options if options is not None: for (option,value) in options: self.lp.set(option, value) self.creds = Credentials() self.session = system_session() self.ldb = SamDB( session_info=self.session, credentials=self.creds, lp=self.lp) # Gets back the basedn base_dn = self.ldb.domain_dn() # Gets back the configuration basedn configuration_dn = self.ldb.get_config_basedn().get_linearized() # Get the old "dSHeuristics" if it was set dsheuristics = self.ldb.get_dsheuristics() # Set the "dSHeuristics" to activate the correct "userPassword" # behaviour self.ldb.set_dsheuristics("000000001") # Reset the "dSHeuristics" as they were before self.addCleanup(self.ldb.set_dsheuristics, dsheuristics) # Get the old "minPwdAge" minPwdAge = self.ldb.get_minPwdAge() # Set it temporarily to "0" self.ldb.set_minPwdAge("0") self.base_dn = self.ldb.domain_dn() # Reset the "minPwdAge" as it was before self.addCleanup(self.ldb.set_minPwdAge, minPwdAge) account_control = 0 if clear_text: # get the current pwdProperties pwdProperties = self.ldb.get_pwdProperties() # enable clear text properties props = int(pwdProperties) props |= DOMAIN_PASSWORD_STORE_CLEARTEXT self.ldb.set_pwdProperties(str(props)) # Restore the value on exit. self.addCleanup(self.ldb.set_pwdProperties, pwdProperties) account_control |= UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED # (Re)adds the test user USER_NAME with password USER_PASS # and userPrincipalName UPN delete_force(self.ldb, "cn=" + USER_NAME + ",cn=users," + self.base_dn) self.ldb.add({ "dn": "cn=" + USER_NAME + ",cn=users," + self.base_dn, "objectclass": "user", "sAMAccountName": USER_NAME, "userPassword": USER_PASS, "userPrincipalName": UPN, "userAccountControl": str(account_control) })
def tearDown(self): super(AuthLogTestsNetLogonBadCreds, self).tearDown() delete_force(self.ldb, self.dn)
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)
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="dn=%s" % 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="dn=%s" % 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)
except LdbError, (num, _): self.assertEquals(num, ERR_NO_SUCH_OBJECT) try: res = ldb.search("cn=entry1,cn=ldaptestcontainer," + self.base_dn, scope=SCOPE_BASE, attrs=[]) self.fail() except LdbError, (num, _): self.assertEquals(num, ERR_NO_SUCH_OBJECT) try: res = ldb.search("cn=entry2,cn=ldaptestcontainer," + self.base_dn, scope=SCOPE_BASE, attrs=[]) self.fail() except LdbError, (num, _): self.assertEquals(num, ERR_NO_SUCH_OBJECT) delete_force(self.ldb, "cn=entry1,cn=ldaptestcontainer," + self.base_dn) delete_force(self.ldb, "cn=entry2,cn=ldaptestcontainer," + self.base_dn) delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn) # Performs some protected object delete testing res = ldb.search(base="", expression="", scope=SCOPE_BASE, attrs=["dsServiceName", "dNSHostName"]) self.assertEquals(len(res), 1) # Delete failing since DC's nTDSDSA object is protected try: ldb.delete(res[0]["dsServiceName"][0]) self.fail() except LdbError, (num, _): self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
def test_all(self): """Basic delete tests""" print self.base_dn usr1="cn=testuser,cn=users," + self.base_dn usr2="cn=testuser2,cn=users," + self.base_dn grp1="cn=testdelgroup1,cn=users," + self.base_dn sit1="cn=testsite1,cn=sites," + self.configuration_dn ss1="cn=NTDS Site Settings,cn=testsite1,cn=sites," + self.configuration_dn srv1="cn=Servers,cn=testsite1,cn=sites," + self.configuration_dn srv2="cn=TESTSRV,cn=Servers,cn=testsite1,cn=sites," + self.configuration_dn delete_force(self.ldb, usr1) delete_force(self.ldb, usr2) delete_force(self.ldb, grp1) delete_force(self.ldb, ss1) delete_force(self.ldb, srv2) delete_force(self.ldb, srv1) delete_force(self.ldb, sit1) ldb.add({ "dn": usr1, "objectclass": "user", "description": "test user description", "samaccountname": "testuser"}) ldb.add({ "dn": usr2, "objectclass": "user", "description": "test user 2 description", "samaccountname": "testuser2"}) ldb.add({ "dn": grp1, "objectclass": "group", "description": "test group", "samaccountname": "testdelgroup1", "member": [ usr1, usr2 ], "isDeleted": "FALSE" }) ldb.add({ "dn": sit1, "objectclass": "site" }) ldb.add({ "dn": ss1, "objectclass": ["applicationSiteSettings", "nTDSSiteSettings"] }) ldb.add({ "dn": srv1, "objectclass": "serversContainer" }) ldb.add({ "dn": srv2, "objectClass": "server" }) objLive1 = self.search_dn(usr1) guid1=objLive1["objectGUID"][0] objLive2 = self.search_dn(usr2) guid2=objLive2["objectGUID"][0] objLive3 = self.search_dn(grp1) guid3=objLive3["objectGUID"][0] objLive4 = self.search_dn(sit1) guid4=objLive4["objectGUID"][0] objLive5 = self.search_dn(ss1) guid5=objLive5["objectGUID"][0] objLive6 = self.search_dn(srv1) guid6=objLive6["objectGUID"][0] objLive7 = self.search_dn(srv2) guid7=objLive7["objectGUID"][0] ldb.delete(usr1) ldb.delete(usr2) ldb.delete(grp1) ldb.delete(srv1, ["tree_delete:1"]) ldb.delete(sit1, ["tree_delete:1"]) objDeleted1 = self.search_guid(guid1) objDeleted2 = self.search_guid(guid2) objDeleted3 = self.search_guid(guid3) objDeleted4 = self.search_guid(guid4) objDeleted5 = self.search_guid(guid5) objDeleted6 = self.search_guid(guid6) objDeleted7 = self.search_guid(guid7) self.del_attr_values(objDeleted1) self.del_attr_values(objDeleted2) self.del_attr_values(objDeleted3) self.del_attr_values(objDeleted4) self.del_attr_values(objDeleted5) self.del_attr_values(objDeleted6) self.del_attr_values(objDeleted7) self.preserved_attributes_list(objLive1, objDeleted1) self.preserved_attributes_list(objLive2, objDeleted2) self.preserved_attributes_list(objLive3, objDeleted3) self.preserved_attributes_list(objLive4, objDeleted4) self.preserved_attributes_list(objLive5, objDeleted5) self.preserved_attributes_list(objLive6, objDeleted6) self.preserved_attributes_list(objLive7, objDeleted7) self.check_rdn(objLive1, objDeleted1, "cn") self.check_rdn(objLive2, objDeleted2, "cn") self.check_rdn(objLive3, objDeleted3, "cn") self.check_rdn(objLive4, objDeleted4, "cn") self.check_rdn(objLive5, objDeleted5, "cn") self.check_rdn(objLive6, objDeleted6, "cn") self.check_rdn(objLive7, objDeleted7, "cn") self.delete_deleted(ldb, usr1) self.delete_deleted(ldb, usr2) self.delete_deleted(ldb, grp1) self.delete_deleted(ldb, sit1) self.delete_deleted(ldb, ss1) self.delete_deleted(ldb, srv1) self.delete_deleted(ldb, srv2) self.assertTrue("CN=Deleted Objects" in str(objDeleted1.dn)) self.assertTrue("CN=Deleted Objects" in str(objDeleted2.dn)) self.assertTrue("CN=Deleted Objects" in str(objDeleted3.dn)) self.assertFalse("CN=Deleted Objects" in str(objDeleted4.dn)) self.assertTrue("CN=Deleted Objects" in str(objDeleted5.dn)) self.assertFalse("CN=Deleted Objects" in str(objDeleted6.dn)) self.assertFalse("CN=Deleted Objects" in str(objDeleted7.dn))