2 # -*- coding: utf-8 -*-
9 sys.path.append("bin/python")
10 sys.path.append("../lib/subunit/python")
12 import samba.getopt as options
14 from samba.auth import system_session
15 from ldb import SCOPE_BASE, LdbError
16 from ldb import ERR_NO_SUCH_OBJECT
19 from subunit.run import SubunitTestRunner
22 parser = optparse.OptionParser("deletetest.py [options] <host|file>")
23 sambaopts = options.SambaOptions(parser)
24 parser.add_option_group(sambaopts)
25 parser.add_option_group(options.VersionOptions(parser))
26 # use command line creds if available
27 credopts = options.CredentialsOptions(parser)
28 parser.add_option_group(credopts)
29 opts, args = parser.parse_args()
37 lp = sambaopts.get_loadparm()
38 creds = credopts.get_credentials(lp)
40 class BasicDeleteTests(unittest.TestCase):
42 def delete_force(self, ldb, dn):
45 except LdbError, (num, _):
46 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
48 def GUID_string(self, guid):
49 return self.ldb.schema_format_value("objectGUID", guid)
51 def find_basedn(self, ldb):
52 res = ldb.search(base="", expression="", scope=SCOPE_BASE,
53 attrs=["defaultNamingContext"])
54 self.assertEquals(len(res), 1)
55 return res[0]["defaultNamingContext"][0]
59 self.base_dn = self.find_basedn(ldb)
61 def search_guid(self,guid):
62 print "SEARCH by GUID %s" % self.GUID_string(guid)
64 expression = "(objectGUID=%s)" % self.GUID_string(guid)
65 res = ldb.search(expression=expression,
66 controls=["show_deleted:1"])
67 self.assertEquals(len(res), 1)
70 def search_dn(self,dn):
71 print "SEARCH by DN %s" % dn
73 res = ldb.search(expression="(objectClass=*)",
76 controls=["show_deleted:1"])
77 self.assertEquals(len(res), 1)
80 def del_attr_values(self, delObj):
81 print "Checking attributes for %s" % delObj["dn"]
83 self.assertEquals(delObj["isDeleted"][0],"TRUE")
84 self.assertTrue(not("objectCategory" in delObj))
85 self.assertTrue(not("sAMAccountType" in delObj))
87 def preserved_attributes_list(self, liveObj, delObj):
88 print "Checking for preserved attributes list"
90 preserved_list = ["nTSecurityDescriptor", "attributeID", "attributeSyntax", "dNReferenceUpdate", "dNSHostName",
91 "flatName", "governsID", "groupType", "instanceType", "lDAPDisplayName", "legacyExchangeDN",
92 "isDeleted", "isRecycled", "lastKnownParent", "msDS-LastKnownRDN", "mS-DS-CreatorSID",
93 "mSMQOwnerID", "nCName", "objectClass", "distinguishedName", "objectGUID", "objectSid",
94 "oMSyntax", "proxiedObjectName", "name", "replPropertyMetaData", "sAMAccountName",
95 "securityIdentifier", "sIDHistory", "subClassOf", "systemFlags", "trustPartner", "trustDirection",
96 "trustType", "trustAttributes", "userAccountControl", "uSNChanged", "uSNCreated", "whenCreated"]
99 if a in preserved_list:
100 self.assertTrue(a in delObj)
102 def check_rdn(self, liveObj, delObj, rdnName):
103 print "Checking for correct rDN"
104 rdn=liveObj[rdnName][0]
105 rdn2=delObj[rdnName][0]
106 name2=delObj[rdnName][0]
107 guid=liveObj["objectGUID"][0]
108 self.assertEquals(rdn2, rdn + "\nDEL:" + self.GUID_string(guid))
109 self.assertEquals(name2, rdn + "\nDEL:" + self.GUID_string(guid))
111 def delete_deleted(self, ldb, dn):
112 print "Testing the deletion of the already deleted dn %s" % dn
117 except LdbError, (num, _):
118 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
121 """Basic delete tests"""
125 dn1="cn=testuser,cn=users," + self.base_dn
126 dn2="cn=testuser2,cn=users," + self.base_dn
127 grp1="cn=testdelgroup1,cn=users," + self.base_dn
129 self.delete_force(self.ldb, dn1)
130 self.delete_force(self.ldb, dn2)
131 self.delete_force(self.ldb, grp1)
135 "objectclass": "user",
137 "description": "test user description",
138 "samaccountname": "testuser"})
142 "objectclass": "user",
144 "description": "test user 2 description",
145 "samaccountname": "testuser2"})
149 "objectclass": "group",
150 "cn": "testdelgroup1",
151 "description": "test group",
152 "samaccountname": "testdelgroup1",
153 "member": [ dn1, dn2 ] })
155 objLive1 = self.search_dn(dn1)
156 guid1=objLive1["objectGUID"][0]
158 objLive2 = self.search_dn(dn2)
159 guid2=objLive2["objectGUID"][0]
161 objLive3 = self.search_dn(grp1)
162 guid3=objLive3["objectGUID"][0]
168 objDeleted1 = self.search_guid(guid1)
169 objDeleted2 = self.search_guid(guid2)
170 objDeleted3 = self.search_guid(guid3)
172 self.del_attr_values(objDeleted1)
173 self.del_attr_values(objDeleted2)
174 self.del_attr_values(objDeleted3)
176 self.preserved_attributes_list(objLive1, objDeleted1)
177 self.preserved_attributes_list(objLive2, objDeleted2)
179 self.check_rdn(objLive1, objDeleted1, "cn")
180 self.check_rdn(objLive2, objDeleted2, "cn")
181 self.check_rdn(objLive3, objDeleted3, "cn")
183 self.delete_deleted(ldb, dn1)
184 self.delete_deleted(ldb, dn2)
185 self.delete_deleted(ldb, grp1)
187 if not "://" in host:
188 if os.path.isfile(host):
189 host = "tdb://%s" % host
191 host = "ldap://%s" % host
193 ldb = Ldb(host, credentials=creds, session_info=system_session(), lp=lp)
195 runner = SubunitTestRunner()
197 if not runner.run(unittest.makeSuite(BasicDeleteTests)).wasSuccessful():