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():