s4:ldb Add Well Known GUID (WKGUID) tests to ldap.py
[Samba/ekacnet.git] / source4 / lib / ldb / tests / python / ldap.py
blob59bea8b3b06334afbe4862c5c46c886629ade45c
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3 # This is a port of the original in testprogs/ejs/ldap.js
5 import getopt
6 import optparse
7 import sys
8 import time
9 import random
10 import base64
12 sys.path.append("bin/python")
13 sys.path.append("../lib/subunit/python")
15 import samba.getopt as options
17 from samba.auth import system_session
18 from ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError
19 from ldb import ERR_NO_SUCH_OBJECT, ERR_ATTRIBUTE_OR_VALUE_EXISTS
20 from ldb import ERR_ENTRY_ALREADY_EXISTS, ERR_UNWILLING_TO_PERFORM
21 from ldb import ERR_NOT_ALLOWED_ON_NON_LEAF, ERR_OTHER, ERR_INVALID_DN_SYNTAX
22 from ldb import ERR_NO_SUCH_ATTRIBUTE, ERR_INSUFFICIENT_ACCESS_RIGHTS
23 from ldb import ERR_OBJECT_CLASS_VIOLATION, ERR_NOT_ALLOWED_ON_RDN
24 from ldb import ERR_NAMING_VIOLATION, ERR_CONSTRAINT_VIOLATION
25 from ldb import Message, MessageElement, Dn
26 from ldb import FLAG_MOD_ADD, FLAG_MOD_REPLACE, FLAG_MOD_DELETE
27 from samba import Ldb, param, dom_sid_to_rid
28 from samba import UF_NORMAL_ACCOUNT, UF_TEMP_DUPLICATE_ACCOUNT
29 from samba import UF_SERVER_TRUST_ACCOUNT, UF_WORKSTATION_TRUST_ACCOUNT
30 from samba import UF_INTERDOMAIN_TRUST_ACCOUNT
31 from samba import UF_PASSWD_NOTREQD, UF_ACCOUNTDISABLE
32 from samba import GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
33 from samba import GTYPE_SECURITY_GLOBAL_GROUP, GTYPE_SECURITY_DOMAIN_LOCAL_GROUP
34 from samba import GTYPE_SECURITY_UNIVERSAL_GROUP
35 from samba import GTYPE_DISTRIBUTION_GLOBAL_GROUP
36 from samba import GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP
37 from samba import GTYPE_DISTRIBUTION_UNIVERSAL_GROUP
38 from samba import ATYPE_NORMAL_ACCOUNT, ATYPE_WORKSTATION_TRUST
39 from samba import ATYPE_SECURITY_GLOBAL_GROUP, ATYPE_SECURITY_LOCAL_GROUP
40 from samba import ATYPE_SECURITY_UNIVERSAL_GROUP
41 from samba import ATYPE_DISTRIBUTION_GLOBAL_GROUP
42 from samba import ATYPE_DISTRIBUTION_LOCAL_GROUP
43 from samba import ATYPE_DISTRIBUTION_UNIVERSAL_GROUP
45 from subunit import SubunitTestRunner
46 import unittest
48 from samba.ndr import ndr_pack, ndr_unpack
49 from samba.dcerpc import security
51 parser = optparse.OptionParser("ldap [options] <host>")
52 sambaopts = options.SambaOptions(parser)
53 parser.add_option_group(sambaopts)
54 parser.add_option_group(options.VersionOptions(parser))
55 # use command line creds if available
56 credopts = options.CredentialsOptions(parser)
57 parser.add_option_group(credopts)
58 opts, args = parser.parse_args()
60 if len(args) < 1:
61 parser.print_usage()
62 sys.exit(1)
64 host = args[0]
66 lp = sambaopts.get_loadparm()
67 creds = credopts.get_credentials(lp)
69 class BasicTests(unittest.TestCase):
70 def delete_force(self, ldb, dn):
71 try:
72 ldb.delete(dn)
73 except LdbError, (num, _):
74 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
76 def find_basedn(self, ldb):
77 res = ldb.search(base="", expression="", scope=SCOPE_BASE,
78 attrs=["defaultNamingContext"])
79 self.assertEquals(len(res), 1)
80 return res[0]["defaultNamingContext"][0]
82 def find_configurationdn(self, ldb):
83 res = ldb.search(base="", expression="", scope=SCOPE_BASE, attrs=["configurationNamingContext"])
84 self.assertEquals(len(res), 1)
85 return res[0]["configurationNamingContext"][0]
87 def find_schemadn(self, ldb):
88 res = ldb.search(base="", expression="", scope=SCOPE_BASE, attrs=["schemaNamingContext"])
89 self.assertEquals(len(res), 1)
90 return res[0]["schemaNamingContext"][0]
92 def find_domain_sid(self):
93 res = self.ldb.search(base=self.base_dn, expression="(objectClass=*)", scope=SCOPE_BASE)
94 return ndr_unpack( security.dom_sid,res[0]["objectSid"][0])
96 def setUp(self):
97 self.ldb = ldb
98 self.gc_ldb = gc_ldb
99 self.base_dn = self.find_basedn(ldb)
100 self.configuration_dn = self.find_configurationdn(ldb)
101 self.schema_dn = self.find_schemadn(ldb)
102 self.domain_sid = self.find_domain_sid()
104 print "baseDN: %s\n" % self.base_dn
106 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
107 self.delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
108 self.delete_force(self.ldb, "cn=ldaptestuser3,cn=users," + self.base_dn)
109 self.delete_force(self.ldb, "cn=ldaptestuser4,cn=ldaptestcontainer," + self.base_dn)
110 self.delete_force(self.ldb, "cn=ldaptestuser4,cn=ldaptestcontainer2," + self.base_dn)
111 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
112 self.delete_force(self.ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
113 self.delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
114 self.delete_force(self.ldb, "cn=ldaptest2computer,cn=computers," + self.base_dn)
115 self.delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
116 self.delete_force(self.ldb, "cn=ldaptestutf8user èùéìòà,cn=users," + self.base_dn)
117 self.delete_force(self.ldb, "cn=ldaptestutf8user2 èùéìòà,cn=users," + self.base_dn)
118 self.delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
119 self.delete_force(self.ldb, "cn=ldaptestcontainer2," + self.base_dn)
120 self.delete_force(self.ldb, "cn=parentguidtest,cn=users," + self.base_dn)
121 self.delete_force(self.ldb, "cn=parentguidtest,cn=testotherusers," + self.base_dn)
122 self.delete_force(self.ldb, "cn=testotherusers," + self.base_dn)
123 self.delete_force(self.ldb, "cn=ldaptestobject," + self.base_dn)
124 self.delete_force(self.ldb, "description=xyz,cn=users," + self.base_dn)
125 self.delete_force(self.ldb, "ou=testou,cn=users," + self.base_dn)
127 def test_system_only(self):
128 """Test systemOnly objects"""
129 print "Test systemOnly objects"""
131 try:
132 self.ldb.add({
133 "dn": "cn=ldaptestobject," + self.base_dn,
134 "objectclass": "configuration"})
135 self.fail()
136 except LdbError, (num, _):
137 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
139 self.delete_force(self.ldb, "cn=ldaptestobject," + self.base_dn)
141 def test_invalid_parent(self):
142 """Test adding an object with invalid parent"""
143 print "Test adding an object with invalid parent"""
145 try:
146 self.ldb.add({
147 "dn": "cn=ldaptestgroup,cn=thisdoesnotexist123,"
148 + self.base_dn,
149 "objectclass": "group"})
150 self.fail()
151 except LdbError, (num, _):
152 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
154 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=thisdoesnotexist123,"
155 + self.base_dn)
157 try:
158 self.ldb.add({
159 "dn": "ou=testou,cn=users," + self.base_dn,
160 "objectclass": "organizationalUnit"})
161 self.fail()
162 except LdbError, (num, _):
163 self.assertEquals(num, ERR_NAMING_VIOLATION)
165 self.delete_force(self.ldb, "ou=testou,cn=users," + self.base_dn)
167 def test_invalid_attribute(self):
168 """Test adding invalid attributes (not in schema)"""
169 print "Test adding invalid attributes (not in schema)"""
171 try:
172 self.ldb.add({
173 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
174 "objectclass": "group",
175 "thisdoesnotexist": "x"})
176 self.fail()
177 except LdbError, (num, _):
178 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
180 self.ldb.add({
181 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
182 "objectclass": "group"})
184 m = Message()
185 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
186 m["thisdoesnotexist"] = MessageElement("x", FLAG_MOD_REPLACE,
187 "thisdoesnotexist")
188 try:
189 ldb.modify(m)
190 self.fail()
191 except LdbError, (num, _):
192 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
194 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
196 def test_single_valued_attributes(self):
197 """Test single-valued attributes"""
198 print "Test single-valued attributes"""
200 try:
201 self.ldb.add({
202 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
203 "objectclass": "group",
204 "sAMAccountName": ["nam1", "nam2"]})
205 self.fail()
206 except LdbError, (num, _):
207 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
209 self.ldb.add({
210 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
211 "objectclass": "group"})
213 m = Message()
214 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
215 m["sAMAccountName"] = MessageElement(["nam1","nam2"], FLAG_MOD_REPLACE,
216 "sAMAccountName")
217 try:
218 ldb.modify(m)
219 self.fail()
220 except LdbError, (num, _):
221 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
223 m = Message()
224 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
225 m["sAMAccountName"] = MessageElement("testgroupXX", FLAG_MOD_REPLACE,
226 "sAMAccountName")
227 ldb.modify(m)
229 m = Message()
230 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
231 m["sAMAccountName"] = MessageElement("testgroupXX2", FLAG_MOD_ADD,
232 "sAMAccountName")
233 try:
234 ldb.modify(m)
235 self.fail()
236 except LdbError, (num, _):
237 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
239 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
241 def test_multi_valued_attributes(self):
242 """Test multi-valued attributes"""
243 print "Test multi-valued attributes"""
245 # TODO: In this test I added some special tests where I got very unusual
246 # results back from a real AD. s4 doesn't match them and I've no idea how to
247 # implement those error cases (maybe there exists a special trigger for
248 # "description" attributes which handle them)
250 self.ldb.add({
251 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
252 "description": "desc2",
253 "objectclass": "group",
254 "description": "desc1"})
256 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
258 self.ldb.add({
259 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
260 "objectclass": "group",
261 "description": ["desc1", "desc2"]})
263 # m = Message()
264 # m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
265 # m["description"] = MessageElement(["desc1","desc2"], FLAG_MOD_REPLACE,
266 # "description")
267 # try:
268 # ldb.modify(m)
269 # self.fail()
270 # except LdbError, (num, _):
271 # self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
273 m = Message()
274 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
275 m["description"] = MessageElement("desc1", FLAG_MOD_REPLACE,
276 "description")
277 ldb.modify(m)
279 # m = Message()
280 # m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
281 # m["description"] = MessageElement("desc3", FLAG_MOD_ADD,
282 # "description")
283 # try:
284 # ldb.modify(m)
285 # self.fail()
286 # except LdbError, (num, _):
287 # self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
289 m = Message()
290 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
291 m["description"] = MessageElement(["desc1","desc2"], FLAG_MOD_DELETE,
292 "description")
293 try:
294 ldb.modify(m)
295 self.fail()
296 except LdbError, (num, _):
297 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
299 m = Message()
300 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
301 m["description"] = MessageElement("desc1", FLAG_MOD_DELETE,
302 "description")
303 ldb.modify(m)
305 # m = Message()
306 # m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
307 # m["description"] = MessageElement(["desc1","desc2"], FLAG_MOD_REPLACE,
308 # "description")
309 # try:
310 # ldb.modify(m)
311 # self.fail()
312 # except LdbError, (num, _):
313 # self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
315 # m = Message()
316 # m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
317 # m["description"] = MessageElement(["desc3", "desc4"], FLAG_MOD_ADD,
318 # "description")
319 # try:
320 # ldb.modify(m)
321 # self.fail()
322 # except LdbError, (num, _):
323 # self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
325 m = Message()
326 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
327 m["description"] = MessageElement("desc3", FLAG_MOD_ADD,
328 "description")
329 ldb.modify(m)
331 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
333 def test_empty_messages(self):
334 """Test empty messages"""
335 print "Test empty messages"""
337 m = Message()
338 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
340 try:
341 ldb.add(m)
342 self.fail()
343 except LdbError, (num, _):
344 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
346 try:
347 ldb.modify(m)
348 self.fail()
349 except LdbError, (num, _):
350 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
352 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
354 def test_empty_attributes(self):
355 """Test empty attributes"""
356 print "Test empty attributes"""
358 m = Message()
359 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
360 m["objectClass"] = MessageElement("group", FLAG_MOD_ADD, "objectClass")
361 m["description"] = MessageElement([], FLAG_MOD_ADD, "description")
363 try:
364 ldb.add(m)
365 self.fail()
366 except LdbError, (num, _):
367 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
369 self.ldb.add({
370 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
371 "objectclass": "group"})
373 m = Message()
374 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
375 m["description"] = MessageElement([], FLAG_MOD_ADD, "description")
377 try:
378 ldb.modify(m)
379 self.fail()
380 except LdbError, (num, _):
381 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
383 m = Message()
384 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
385 m["description"] = MessageElement([], FLAG_MOD_REPLACE, "description")
386 ldb.modify(m)
388 m = Message()
389 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
390 m["description"] = MessageElement([], FLAG_MOD_DELETE, "description")
391 try:
392 ldb.modify(m)
393 self.fail()
394 except LdbError, (num, _):
395 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
397 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
399 def test_distinguished_name(self):
400 """Tests the 'distinguishedName' attribute"""
401 print "Tests the 'distinguishedName' attribute"""
403 self.ldb.add({
404 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
405 "objectclass": "group"})
407 m = Message()
408 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
409 m["distinguishedName"] = MessageElement(
410 "cn=ldaptestuser,cn=users," + self.base_dn, FLAG_MOD_ADD,
411 "distinguishedName")
413 try:
414 ldb.modify(m)
415 self.fail()
416 except LdbError, (num, _):
417 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
419 m = Message()
420 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
421 m["distinguishedName"] = MessageElement(
422 "cn=ldaptestuser,cn=users," + self.base_dn, FLAG_MOD_REPLACE,
423 "distinguishedName")
425 try:
426 ldb.modify(m)
427 self.fail()
428 except LdbError, (num, _):
429 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
431 m = Message()
432 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
433 m["distinguishedName"] = MessageElement(
434 "cn=ldaptestuser,cn=users," + self.base_dn, FLAG_MOD_DELETE,
435 "distinguishedName")
437 try:
438 ldb.modify(m)
439 self.fail()
440 except LdbError, (num, _):
441 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
443 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
445 def test_rdn_name(self):
446 """Tests the RDN"""
447 print "Tests the RDN"""
449 try:
450 self.ldb.add({
451 "dn": "description=xyz,cn=users," + self.base_dn,
452 "objectclass": "group"})
453 self.fail()
454 except LdbError, (num, _):
455 self.assertEquals(num, ERR_NAMING_VIOLATION)
457 self.delete_force(self.ldb, "description=xyz,cn=users," + self.base_dn)
459 self.ldb.add({
460 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
461 "objectclass": "group"})
463 m = Message()
464 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
465 m["name"] = MessageElement("cn=ldaptestuser", FLAG_MOD_REPLACE,
466 "name")
468 try:
469 ldb.modify(m)
470 self.fail()
471 except LdbError, (num, _):
472 self.assertEquals(num, ERR_NOT_ALLOWED_ON_RDN)
474 m = Message()
475 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
476 m["cn"] = MessageElement("ldaptestuser",
477 FLAG_MOD_REPLACE, "cn")
479 try:
480 ldb.modify(m)
481 self.fail()
482 except LdbError, (num, _):
483 self.assertEquals(num, ERR_NOT_ALLOWED_ON_RDN)
485 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
488 # this test needs to be disabled until we really understand
489 # what the rDN length constraints are
490 def DISABLED_test_largeRDN(self):
491 """Testing large rDN (limit 64 characters)"""
492 rdn = "CN=a012345678901234567890123456789012345678901234567890123456789012";
493 self.delete_force(self.ldb, "%s,%s" % (rdn, self.base_dn))
494 ldif = """
495 dn: %s,%s""" % (rdn,self.base_dn) + """
496 objectClass: container
498 self.ldb.add_ldif(ldif)
499 self.delete_force(self.ldb, "%s,%s" % (rdn, self.base_dn))
501 rdn = "CN=a0123456789012345678901234567890123456789012345678901234567890120";
502 self.delete_force(self.ldb, "%s,%s" % (rdn, self.base_dn))
503 try:
504 ldif = """
505 dn: %s,%s""" % (rdn,self.base_dn) + """
506 objectClass: container
508 self.ldb.add_ldif(ldif)
509 self.fail()
510 except LdbError, (num, _):
511 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
512 self.delete_force(self.ldb, "%s,%s" % (rdn, self.base_dn))
514 def test_rename(self):
515 """Tests the rename operation"""
516 print "Tests the rename operations"""
518 self.ldb.add({
519 "dn": "cn=ldaptestuser2,cn=users," + self.base_dn,
520 "objectclass": ["user", "person"] })
522 ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser2,cn=users," + self.base_dn)
523 ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=users," + self.base_dn)
524 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestUSER3,cn=users," + self.base_dn)
525 try:
526 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, ",cn=users," + self.base_dn)
527 self.fail()
528 except LdbError, (num, _):
529 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
531 self.delete_force(self.ldb, "cn=ldaptestuser3,cn=users," + self.base_dn)
533 def test_parentGUID(self):
534 """Test parentGUID behaviour"""
535 print "Testing parentGUID behaviour\n"
537 # TODO: This seems to fail on Windows Server. Hidden attribute?
539 self.ldb.add({
540 "dn": "cn=parentguidtest,cn=users," + self.base_dn,
541 "objectclass":"user",
542 "samaccountname":"parentguidtest"});
543 res1 = ldb.search(base="cn=parentguidtest,cn=users," + self.base_dn, scope=SCOPE_BASE,
544 attrs=["parentGUID"]);
545 res2 = ldb.search(base="cn=users," + self.base_dn,scope=SCOPE_BASE,
546 attrs=["objectGUID"]);
547 self.assertEquals(res1[0]["parentGUID"], res2[0]["objectGUID"]);
549 print "Testing parentGUID behaviour on rename\n"
551 self.ldb.add({
552 "dn": "cn=testotherusers," + self.base_dn,
553 "objectclass":"container"});
554 res1 = ldb.search(base="cn=testotherusers," + self.base_dn,scope=SCOPE_BASE,
555 attrs=["objectGUID"]);
556 ldb.rename("cn=parentguidtest,cn=users," + self.base_dn,
557 "cn=parentguidtest,cn=testotherusers," + self.base_dn);
558 res2 = ldb.search(base="cn=parentguidtest,cn=testotherusers," + self.base_dn,
559 scope=SCOPE_BASE,
560 attrs=["parentGUID"]);
561 self.assertEquals(res1[0]["objectGUID"], res2[0]["parentGUID"]);
563 self.delete_force(self.ldb, "cn=parentguidtest,cn=testotherusers," + self.base_dn)
564 self.delete_force(self.ldb, "cn=testotherusers," + self.base_dn)
566 def test_groupType_int32(self):
567 """Test groupType (int32) behaviour (should appear to be casted to a 32 bit signed integer before comparsion)"""
568 print "Testing groupType (int32) behaviour\n"
570 res1 = ldb.search(base=self.base_dn, scope=SCOPE_SUBTREE,
571 attrs=["groupType"], expression="groupType=2147483653");
573 res2 = ldb.search(base=self.base_dn, scope=SCOPE_SUBTREE,
574 attrs=["groupType"], expression="groupType=-2147483643");
576 self.assertEquals(len(res1), len(res2))
578 self.assertTrue(res1.count > 0)
580 self.assertEquals(res1[0]["groupType"][0], "-2147483643")
582 def test_groups(self):
583 """This tests the group behaviour (setting, changing) of a user account"""
584 print "Testing group behaviour\n"
586 ldb.add({
587 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
588 "objectclass": "group"})
590 ldb.add({
591 "dn": "cn=ldaptestgroup2,cn=users," + self.base_dn,
592 "objectclass": "group"})
594 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
595 scope=SCOPE_BASE, attrs=["objectSID"])
596 self.assertTrue(len(res1) == 1)
597 group_rid_1 = dom_sid_to_rid(ldb.schema_format_value("objectSID",
598 res1[0]["objectSID"][0]))
600 res1 = ldb.search("cn=ldaptestgroup2,cn=users," + self.base_dn,
601 scope=SCOPE_BASE, attrs=["objectSID"])
602 self.assertTrue(len(res1) == 1)
603 group_rid_2 = dom_sid_to_rid(ldb.schema_format_value("objectSID",
604 res1[0]["objectSID"][0]))
606 # Try to create a user with an invalid primary group
607 try:
608 ldb.add({
609 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
610 "objectclass": ["user", "person"],
611 "primaryGroupID": "0"})
612 self.fail()
613 except LdbError, (num, _):
614 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
615 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
617 # Try to Create a user with a valid primary group
618 # TODO Some more investigation needed here
619 # try:
620 # ldb.add({
621 # "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
622 # "objectclass": ["user", "person"],
623 # "primaryGroupID": str(group_rid_1)})
624 # self.fail()
625 # except LdbError, (num, _):
626 # self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
627 # self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
629 ldb.add({
630 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
631 "objectclass": ["user", "person"]})
633 # Try to add invalid primary group
634 m = Message()
635 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
636 m["primaryGroupID"] = MessageElement("0", FLAG_MOD_REPLACE,
637 "primaryGroupID")
638 try:
639 ldb.modify(m)
640 self.fail()
641 except LdbError, (num, _):
642 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
644 # Try to make group 1 primary - should be denied since it is not yet
645 # secondary
646 m = Message()
647 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
648 m["primaryGroupID"] = MessageElement(str(group_rid_1),
649 FLAG_MOD_REPLACE, "primaryGroupID")
650 try:
651 ldb.modify(m)
652 self.fail()
653 except LdbError, (num, _):
654 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
656 # Make group 1 secondary
657 m = Message()
658 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
659 m["member"] = "cn=ldaptestuser,cn=users," + self.base_dn
660 ldb.modify(m)
662 # Make group 1 primary
663 m = Message()
664 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
665 m["primaryGroupID"] = MessageElement(str(group_rid_1),
666 FLAG_MOD_REPLACE, "primaryGroupID")
667 ldb.modify(m)
669 # Try to delete group 1 - should be denied
670 try:
671 ldb.delete("cn=ldaptestgroup,cn=users," + self.base_dn)
672 self.fail()
673 except LdbError, (num, _):
674 self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
676 # Try to add group 1 also as secondary - should be denied
677 m = Message()
678 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
679 m["member"] = "cn=ldaptestuser,cn=users," + self.base_dn
680 try:
681 ldb.modify(m)
682 self.fail()
683 except LdbError, (num, _):
684 self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
686 # Try to add invalid member to group 1 - should be denied
687 m = Message()
688 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
689 m["member"] = MessageElement(
690 "cn=ldaptestuser3,cn=users," + self.base_dn,
691 FLAG_MOD_ADD, "member")
692 try:
693 ldb.modify(m)
694 self.fail()
695 except LdbError, (num, _):
696 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
698 # Make group 2 secondary
699 m = Message()
700 m.dn = Dn(ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
701 m["member"] = "cn=ldaptestuser,cn=users," + self.base_dn
702 ldb.modify(m)
704 # Swap the groups
705 m = Message()
706 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
707 m["primaryGroupID"] = MessageElement(str(group_rid_2),
708 FLAG_MOD_REPLACE, "primaryGroupID")
709 ldb.modify(m)
711 # Old primary group should contain a "member" attribute for the user,
712 # the new shouldn't contain anymore one
713 res1 = ldb.search("cn=ldaptestgroup, cn=users," + self.base_dn,
714 scope=SCOPE_BASE, attrs=["member"])
715 self.assertTrue(len(res1) == 1)
716 self.assertTrue(len(res1[0]["member"]) == 1)
717 self.assertEquals(res1[0]["member"][0].lower(),
718 ("cn=ldaptestuser,cn=users," + self.base_dn).lower())
720 res1 = ldb.search("cn=ldaptestgroup2, cn=users," + self.base_dn,
721 scope=SCOPE_BASE, attrs=["member"])
722 self.assertTrue(len(res1) == 1)
723 self.assertFalse("member" in res1[0])
725 # Also this should be denied
726 try:
727 ldb.add({
728 "dn": "cn=ldaptestuser1,cn=users," + self.base_dn,
729 "objectclass": ["user", "person"],
730 "primaryGroupID": "0"})
731 self.fail()
732 except LdbError, (num, _):
733 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
735 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
736 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
737 self.delete_force(self.ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
739 def test_primary_group_token(self):
740 """Test the primary group token behaviour (hidden-generated-readonly attribute on groups)"""
741 print "Testing primary group token behaviour\n"
743 ldb.add({
744 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
745 "objectclass": ["user", "person"]})
747 ldb.add({
748 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
749 "objectclass": "group"})
751 res1 = ldb.search("cn=ldaptestuser, cn=users," + self.base_dn,
752 scope=SCOPE_BASE, attrs=["primaryGroupToken"])
753 self.assertTrue(len(res1) == 1)
754 self.assertFalse("primaryGroupToken" in res1[0])
756 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
757 scope=SCOPE_BASE)
758 self.assertTrue(len(res1) == 1)
759 self.assertFalse("primaryGroupToken" in res1[0])
761 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
762 scope=SCOPE_BASE, attrs=["primaryGroupToken", "objectSID"])
763 self.assertTrue(len(res1) == 1)
764 primary_group_token = int(res1[0]["primaryGroupToken"][0])
766 rid = dom_sid_to_rid(ldb.schema_format_value("objectSID", res1[0]["objectSID"][0]))
767 self.assertEquals(primary_group_token, rid)
769 # TODO Has to wait until we support read-only generated attributes correctly
770 # m = Message()
771 # m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
772 # m["primaryGroupToken"] = "100"
773 # try:
774 # ldb.modify(m)
775 # self.fail()
776 # except LdbError, (num, msg):
778 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
779 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
781 def test_wkguid(self):
782 """Test Well known GUID behaviours (including DN+Binary)"""
783 print "Test Well known GUID behaviours (including DN+Binary)"""
785 res = self.ldb.search(base=("<WKGUID=ab1d30f3768811d1aded00c04fd8d5cd,%s>" % self.base_dn), scope=SCOPE_BASE, attrs=[])
786 self.assertEquals(len(res), 1)
788 res2 = self.ldb.search(scope=SCOPE_BASE, attrs=["wellKnownObjects"], expression=("wellKnownObjects=B:32:ab1d30f3768811d1aded00c04fd8d5cd:%s" % res[0].dn))
789 self.assertEquals(len(res2), 1)
791 # Prove that the matching rule is over the whole DN+Binary
792 res2 = self.ldb.search(scope=SCOPE_BASE, attrs=["wellKnownObjects"], expression=("wellKnownObjects=B:32:ab1d30f3768811d1aded00c04fd8d5cd"))
793 self.assertEquals(len(res2), 0)
794 # Prove that the matching rule is over the whole DN+Binary
795 res2 = self.ldb.search(scope=SCOPE_BASE, attrs=["wellKnownObjects"], expression=("wellKnownObjects=%s") % res[0].dn)
796 self.assertEquals(len(res2), 0)
798 def test_all(self):
799 """Basic tests"""
801 print "Testing user add"
803 ldb.add({
804 "dn": "cn=ldaptestuser,cn=uSers," + self.base_dn,
805 "objectclass": ["user", "person"],
806 "cN": "LDAPtestUSER",
807 "givenname": "ldap",
808 "sn": "testy"})
810 ldb.add({
811 "dn": "cn=ldaptestgroup,cn=uSers," + self.base_dn,
812 "objectclass": "group",
813 "member": "cn=ldaptestuser,cn=useRs," + self.base_dn})
815 ldb.add({
816 "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
817 "objectclass": "computer",
818 "cN": "LDAPtestCOMPUTER"})
820 ldb.add({"dn": "cn=ldaptest2computer,cn=computers," + self.base_dn,
821 "objectClass": "computer",
822 "cn": "LDAPtest2COMPUTER",
823 "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT),
824 "displayname": "ldap testy"})
826 try:
827 ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn,
828 "objectClass": "computer",
829 "cn": "LDAPtest2COMPUTER"
831 self.fail()
832 except LdbError, (num, _):
833 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
835 try:
836 ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn,
837 "objectClass": "computer",
838 "cn": "ldaptestcomputer3",
839 "sAMAccountType": str(ATYPE_NORMAL_ACCOUNT)
841 self.fail()
842 except LdbError, (num, _):
843 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
845 ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn,
846 "objectClass": "computer",
847 "cn": "LDAPtestCOMPUTER3"
850 print "Testing ldb.search for (&(cn=ldaptestcomputer3)(objectClass=user))";
851 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestcomputer3)(objectClass=user))");
852 self.assertEquals(len(res), 1, "Found only %d for (&(cn=ldaptestcomputer3)(objectClass=user))" % len(res))
854 self.assertEquals(str(res[0].dn), ("CN=ldaptestcomputer3,CN=Computers," + self.base_dn));
855 self.assertEquals(res[0]["cn"][0], "ldaptestcomputer3");
856 self.assertEquals(res[0]["name"][0], "ldaptestcomputer3");
857 self.assertEquals(res[0]["objectClass"][0], "top");
858 self.assertEquals(res[0]["objectClass"][1], "person");
859 self.assertEquals(res[0]["objectClass"][2], "organizationalPerson");
860 self.assertEquals(res[0]["objectClass"][3], "user");
861 self.assertEquals(res[0]["objectClass"][4], "computer");
862 self.assertTrue("objectGUID" in res[0])
863 self.assertTrue("whenCreated" in res[0])
864 self.assertEquals(res[0]["objectCategory"][0], ("CN=Computer,CN=Schema,CN=Configuration," + self.base_dn));
865 self.assertEquals(int(res[0]["primaryGroupID"][0]), 513);
866 self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_NORMAL_ACCOUNT);
867 self.assertEquals(int(res[0]["userAccountControl"][0]), UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE);
869 self.delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
871 print "Testing attribute or value exists behaviour"
872 try:
873 ldb.modify_ldif("""
874 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
875 changetype: modify
876 replace: servicePrincipalName
877 servicePrincipalName: host/ldaptest2computer
878 servicePrincipalName: host/ldaptest2computer
879 servicePrincipalName: cifs/ldaptest2computer
880 """)
881 self.fail()
882 except LdbError, (num, msg):
883 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
885 ldb.modify_ldif("""
886 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
887 changetype: modify
888 replace: servicePrincipalName
889 servicePrincipalName: host/ldaptest2computer
890 servicePrincipalName: cifs/ldaptest2computer
891 """)
892 try:
893 ldb.modify_ldif("""
894 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
895 changetype: modify
896 add: servicePrincipalName
897 servicePrincipalName: host/ldaptest2computer
898 """)
899 self.fail()
900 except LdbError, (num, msg):
901 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
903 print "Testing ranged results"
904 ldb.modify_ldif("""
905 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
906 changetype: modify
907 replace: servicePrincipalName
908 """)
910 ldb.modify_ldif("""
911 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
912 changetype: modify
913 add: servicePrincipalName
914 servicePrincipalName: host/ldaptest2computer0
915 servicePrincipalName: host/ldaptest2computer1
916 servicePrincipalName: host/ldaptest2computer2
917 servicePrincipalName: host/ldaptest2computer3
918 servicePrincipalName: host/ldaptest2computer4
919 servicePrincipalName: host/ldaptest2computer5
920 servicePrincipalName: host/ldaptest2computer6
921 servicePrincipalName: host/ldaptest2computer7
922 servicePrincipalName: host/ldaptest2computer8
923 servicePrincipalName: host/ldaptest2computer9
924 servicePrincipalName: host/ldaptest2computer10
925 servicePrincipalName: host/ldaptest2computer11
926 servicePrincipalName: host/ldaptest2computer12
927 servicePrincipalName: host/ldaptest2computer13
928 servicePrincipalName: host/ldaptest2computer14
929 servicePrincipalName: host/ldaptest2computer15
930 servicePrincipalName: host/ldaptest2computer16
931 servicePrincipalName: host/ldaptest2computer17
932 servicePrincipalName: host/ldaptest2computer18
933 servicePrincipalName: host/ldaptest2computer19
934 servicePrincipalName: host/ldaptest2computer20
935 servicePrincipalName: host/ldaptest2computer21
936 servicePrincipalName: host/ldaptest2computer22
937 servicePrincipalName: host/ldaptest2computer23
938 servicePrincipalName: host/ldaptest2computer24
939 servicePrincipalName: host/ldaptest2computer25
940 servicePrincipalName: host/ldaptest2computer26
941 servicePrincipalName: host/ldaptest2computer27
942 servicePrincipalName: host/ldaptest2computer28
943 servicePrincipalName: host/ldaptest2computer29
944 """)
946 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE,
947 attrs=["servicePrincipalName;range=0-*"])
948 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
949 #print len(res[0]["servicePrincipalName;range=0-*"])
950 self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30)
952 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-19"])
953 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
954 # print res[0]["servicePrincipalName;range=0-19"].length
955 self.assertEquals(len(res[0]["servicePrincipalName;range=0-19"]), 20)
958 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-30"])
959 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
960 self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30)
962 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-40"])
963 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
964 self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30)
966 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=30-40"])
967 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
968 self.assertEquals(len(res[0]["servicePrincipalName;range=30-*"]), 0)
971 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=10-40"])
972 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
973 self.assertEquals(len(res[0]["servicePrincipalName;range=10-*"]), 20)
974 # pos_11 = res[0]["servicePrincipalName;range=10-*"][18]
976 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=11-40"])
977 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
978 self.assertEquals(len(res[0]["servicePrincipalName;range=11-*"]), 19)
979 # print res[0]["servicePrincipalName;range=11-*"][18]
980 # print pos_11
981 # self.assertEquals((res[0]["servicePrincipalName;range=11-*"][18]), pos_11)
983 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=11-15"])
984 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
985 self.assertEquals(len(res[0]["servicePrincipalName;range=11-15"]), 5)
986 # self.assertEquals(res[0]["servicePrincipalName;range=11-15"][4], pos_11)
988 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName"])
989 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
990 # print res[0]["servicePrincipalName"][18]
991 # print pos_11
992 self.assertEquals(len(res[0]["servicePrincipalName"]), 30)
993 # self.assertEquals(res[0]["servicePrincipalName"][18], pos_11)
995 self.delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
996 ldb.add({
997 "dn": "cn=ldaptestuser2,cn=useRs," + self.base_dn,
998 "objectClass": ["person", "user"],
999 "cn": "LDAPtestUSER2",
1000 "givenname": "testy",
1001 "sn": "ldap user2"})
1003 print "Testing Ambigious Name Resolution"
1004 # Testing ldb.search for (&(anr=ldap testy)(objectClass=user))
1005 res = ldb.search(expression="(&(anr=ldap testy)(objectClass=user))")
1006 self.assertEquals(len(res), 3, "Found only %d of 3 for (&(anr=ldap testy)(objectClass=user))" % len(res))
1008 # Testing ldb.search for (&(anr=testy ldap)(objectClass=user))
1009 res = ldb.search(expression="(&(anr=testy ldap)(objectClass=user))")
1010 self.assertEquals(len(res), 2, "Found only %d of 2 for (&(anr=testy ldap)(objectClass=user))" % len(res))
1012 # Testing ldb.search for (&(anr=ldap)(objectClass=user))
1013 res = ldb.search(expression="(&(anr=ldap)(objectClass=user))")
1014 self.assertEquals(len(res), 4, "Found only %d of 4 for (&(anr=ldap)(objectClass=user))" % len(res))
1016 # Testing ldb.search for (&(anr==ldap)(objectClass=user))
1017 res = ldb.search(expression="(&(anr==ldap)(objectClass=user))")
1018 self.assertEquals(len(res), 1, "Could not find (&(anr==ldap)(objectClass=user)). Found only %d for (&(anr=ldap)(objectClass=user))" % len(res))
1020 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
1021 self.assertEquals(res[0]["cn"][0], "ldaptestuser")
1022 self.assertEquals(str(res[0]["name"]), "ldaptestuser")
1024 # Testing ldb.search for (&(anr=testy)(objectClass=user))
1025 res = ldb.search(expression="(&(anr=testy)(objectClass=user))")
1026 self.assertEquals(len(res), 2, "Found only %d for (&(anr=testy)(objectClass=user))" % len(res))
1028 # Testing ldb.search for (&(anr=testy ldap)(objectClass=user))
1029 res = ldb.search(expression="(&(anr=testy ldap)(objectClass=user))")
1030 self.assertEquals(len(res), 2, "Found only %d for (&(anr=testy ldap)(objectClass=user))" % len(res))
1032 # Testing ldb.search for (&(anr==testy ldap)(objectClass=user))
1033 # this test disabled for the moment, as anr with == tests are not understood
1034 # res = ldb.search(expression="(&(anr==testy ldap)(objectClass=user))")
1035 # self.assertEquals(len(res), 1, "Found only %d for (&(anr==testy ldap)(objectClass=user))" % len(res))
1037 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
1038 self.assertEquals(res[0]["cn"][0], "ldaptestuser")
1039 self.assertEquals(res[0]["name"][0], "ldaptestuser")
1041 # Testing ldb.search for (&(anr==testy ldap)(objectClass=user))
1042 # res = ldb.search(expression="(&(anr==testy ldap)(objectClass=user))")
1043 # self.assertEquals(len(res), 1, "Could not find (&(anr==testy ldap)(objectClass=user))")
1045 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
1046 self.assertEquals(res[0]["cn"][0], "ldaptestuser")
1047 self.assertEquals(res[0]["name"][0], "ldaptestuser")
1049 # Testing ldb.search for (&(anr=testy ldap user)(objectClass=user))
1050 res = ldb.search(expression="(&(anr=testy ldap user)(objectClass=user))")
1051 self.assertEquals(len(res), 1, "Could not find (&(anr=testy ldap user)(objectClass=user))")
1053 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
1054 self.assertEquals(str(res[0]["cn"]), "ldaptestuser2")
1055 self.assertEquals(str(res[0]["name"]), "ldaptestuser2")
1057 # Testing ldb.search for (&(anr==testy ldap user2)(objectClass=user))
1058 # res = ldb.search(expression="(&(anr==testy ldap user2)(objectClass=user))")
1059 # self.assertEquals(len(res), 1, "Could not find (&(anr==testy ldap user2)(objectClass=user))")
1061 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
1062 self.assertEquals(str(res[0]["cn"]), "ldaptestuser2")
1063 self.assertEquals(str(res[0]["name"]), "ldaptestuser2")
1065 # Testing ldb.search for (&(anr==ldap user2)(objectClass=user))
1066 # res = ldb.search(expression="(&(anr==ldap user2)(objectClass=user))")
1067 # self.assertEquals(len(res), 1, "Could not find (&(anr==ldap user2)(objectClass=user))")
1069 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
1070 self.assertEquals(str(res[0]["cn"]), "ldaptestuser2")
1071 self.assertEquals(str(res[0]["name"]), "ldaptestuser2")
1073 # Testing ldb.search for (&(anr==not ldap user2)(objectClass=user))
1074 # res = ldb.search(expression="(&(anr==not ldap user2)(objectClass=user))")
1075 # self.assertEquals(len(res), 0, "Must not find (&(anr==not ldap user2)(objectClass=user))")
1077 # Testing ldb.search for (&(anr=not ldap user2)(objectClass=user))
1078 res = ldb.search(expression="(&(anr=not ldap user2)(objectClass=user))")
1079 self.assertEquals(len(res), 0, "Must not find (&(anr=not ldap user2)(objectClass=user))")
1081 # Testing ldb.search for (&(anr="testy ldap")(objectClass=user)) (ie, with quotes)
1082 # res = ldb.search(expression="(&(anr==\"testy ldap\")(objectClass=user))")
1083 # self.assertEquals(len(res), 0, "Found (&(anr==\"testy ldap\")(objectClass=user))")
1085 print "Testing Renames"
1087 attrs = ["objectGUID", "objectSid"]
1088 print "Testing ldb.search for (&(cn=ldaptestUSer2)(objectClass=user))"
1089 res_user = ldb.search(self.base_dn, expression="(&(cn=ldaptestUSer2)(objectClass=user))", scope=SCOPE_SUBTREE, attrs=attrs)
1090 self.assertEquals(len(res_user), 1, "Could not find (&(cn=ldaptestUSer2)(objectClass=user))")
1092 # Check rename works with extended/alternate DN forms
1093 ldb.rename("<SID=" + ldb.schema_format_value("objectSID", res_user[0]["objectSID"][0]) + ">" , "cn=ldaptestUSER3,cn=users," + self.base_dn)
1095 print "Testing ldb.search for (&(cn=ldaptestuser3)(objectClass=user))"
1096 res = ldb.search(expression="(&(cn=ldaptestuser3)(objectClass=user))")
1097 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser3)(objectClass=user))")
1099 self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
1100 self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3")
1101 self.assertEquals(str(res[0]["name"]), "ldaptestUSER3")
1103 #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))"
1104 res = ldb.search(expression="(&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))")
1105 self.assertEquals(len(res), 1, "(&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))")
1107 self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
1108 self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3")
1109 self.assertEquals(str(res[0]["name"]), "ldaptestUSER3")
1111 #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))"
1112 res = ldb.search(expression="(&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))")
1113 self.assertEquals(len(res), 1, "(&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))")
1115 self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
1116 self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3")
1117 self.assertEquals(str(res[0]["name"]), "ldaptestUSER3")
1119 #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))"
1120 res = ldb.search(expression="(&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))")
1121 self.assertEquals(len(res), 0, "(&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))")
1123 # This is a Samba special, and does not exist in real AD
1124 # print "Testing ldb.search for (dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")"
1125 # res = ldb.search("(dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")")
1126 # if (res.error != 0 || len(res) != 1) {
1127 # print "Could not find (dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")"
1128 # self.assertEquals(len(res), 1)
1130 # self.assertEquals(res[0].dn, ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
1131 # self.assertEquals(res[0].cn, "ldaptestUSER3")
1132 # self.assertEquals(res[0].name, "ldaptestUSER3")
1134 print "Testing ldb.search for (distinguishedName=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")"
1135 res = ldb.search(expression="(distinguishedName=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")")
1136 self.assertEquals(len(res), 1, "Could not find (dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")")
1137 self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
1138 self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3")
1139 self.assertEquals(str(res[0]["name"]), "ldaptestUSER3")
1141 # ensure we cannot add it again
1142 try:
1143 ldb.add({"dn": "cn=ldaptestuser3,cn=userS," + self.base_dn,
1144 "objectClass": ["person", "user"],
1145 "cn": "LDAPtestUSER3"})
1146 self.fail()
1147 except LdbError, (num, _):
1148 self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
1150 # rename back
1151 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser2,cn=users," + self.base_dn)
1153 # ensure we cannot rename it twice
1154 try:
1155 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn,
1156 "cn=ldaptestuser2,cn=users," + self.base_dn)
1157 self.fail()
1158 except LdbError, (num, _):
1159 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
1161 # ensure can now use that name
1162 ldb.add({"dn": "cn=ldaptestuser3,cn=users," + self.base_dn,
1163 "objectClass": ["person", "user"],
1164 "cn": "LDAPtestUSER3"})
1166 # ensure we now cannot rename
1167 try:
1168 ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=users," + self.base_dn)
1169 self.fail()
1170 except LdbError, (num, _):
1171 self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
1172 try:
1173 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=configuration," + self.base_dn)
1174 self.fail()
1175 except LdbError, (num, _):
1176 self.assertTrue(num in (71, 64))
1178 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser5,cn=users," + self.base_dn)
1180 ldb.delete("cn=ldaptestuser5,cn=users," + self.base_dn)
1182 self.delete_force(ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
1184 ldb.rename("cn=ldaptestgroup,cn=users," + self.base_dn, "cn=ldaptestgroup2,cn=users," + self.base_dn)
1186 print "Testing subtree renames"
1188 ldb.add({"dn": "cn=ldaptestcontainer," + self.base_dn,
1189 "objectClass": "container"})
1191 ldb.add({"dn": "CN=ldaptestuser4,CN=ldaptestcontainer," + self.base_dn,
1192 "objectClass": ["person", "user"],
1193 "cn": "LDAPtestUSER4"})
1195 ldb.modify_ldif("""
1196 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
1197 changetype: modify
1198 add: member
1199 member: cn=ldaptestuser4,cn=ldaptestcontainer,""" + self.base_dn + """
1200 member: cn=ldaptestcomputer,cn=computers,""" + self.base_dn + """
1201 member: cn=ldaptestuser2,cn=users,""" + self.base_dn + """
1202 """)
1204 print "Testing ldb.rename of cn=ldaptestcontainer," + self.base_dn + " to cn=ldaptestcontainer2," + self.base_dn
1205 ldb.rename("CN=ldaptestcontainer," + self.base_dn, "CN=ldaptestcontainer2," + self.base_dn)
1207 print "Testing ldb.search for (&(cn=ldaptestuser4)(objectClass=user))"
1208 res = ldb.search(expression="(&(cn=ldaptestuser4)(objectClass=user))")
1209 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser4)(objectClass=user))")
1211 print "Testing subtree ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in (just renamed from) cn=ldaptestcontainer," + self.base_dn
1212 try:
1213 res = ldb.search("cn=ldaptestcontainer," + self.base_dn,
1214 expression="(&(cn=ldaptestuser4)(objectClass=user))",
1215 scope=SCOPE_SUBTREE)
1216 self.fail(res)
1217 except LdbError, (num, _):
1218 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
1220 print "Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in (just renamed from) cn=ldaptestcontainer," + self.base_dn
1221 try:
1222 res = ldb.search("cn=ldaptestcontainer," + self.base_dn,
1223 expression="(&(cn=ldaptestuser4)(objectClass=user))", scope=SCOPE_ONELEVEL)
1224 self.fail()
1225 except LdbError, (num, _):
1226 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
1228 print "Testing ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in renamed container"
1229 res = ldb.search("cn=ldaptestcontainer2," + self.base_dn, expression="(&(cn=ldaptestuser4)(objectClass=user))", scope=SCOPE_SUBTREE)
1230 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser4)(objectClass=user)) under cn=ldaptestcontainer2," + self.base_dn)
1232 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn))
1233 self.assertEquals(res[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
1235 time.sleep(4)
1237 print "Testing ldb.search for (&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn + ")(objectclass=group)) to check subtree renames and linked attributes"
1238 res = ldb.search(self.base_dn, expression="(&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn + ")(objectclass=group))", scope=SCOPE_SUBTREE)
1239 self.assertEquals(len(res), 1, "Could not find (&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn + ")(objectclass=group)), perhaps linked attributes are not consistant with subtree renames?")
1241 print "Testing ldb.rename (into itself) of cn=ldaptestcontainer2," + self.base_dn + " to cn=ldaptestcontainer,cn=ldaptestcontainer2," + self.base_dn
1242 try:
1243 ldb.rename("cn=ldaptestcontainer2," + self.base_dn, "cn=ldaptestcontainer,cn=ldaptestcontainer2," + self.base_dn)
1244 self.fail()
1245 except LdbError, (num, _):
1246 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1248 print "Testing ldb.rename (into non-existent container) of cn=ldaptestcontainer2," + self.base_dn + " to cn=ldaptestcontainer,cn=ldaptestcontainer3," + self.base_dn
1249 try:
1250 ldb.rename("cn=ldaptestcontainer2," + self.base_dn, "cn=ldaptestcontainer,cn=ldaptestcontainer3," + self.base_dn)
1251 self.fail()
1252 except LdbError, (num, _):
1253 self.assertTrue(num in (ERR_UNWILLING_TO_PERFORM, ERR_OTHER))
1255 print "Testing delete (should fail, not a leaf node) of renamed cn=ldaptestcontainer2," + self.base_dn
1256 try:
1257 ldb.delete("cn=ldaptestcontainer2," + self.base_dn)
1258 self.fail()
1259 except LdbError, (num, _):
1260 self.assertEquals(num, ERR_NOT_ALLOWED_ON_NON_LEAF)
1262 print "Testing base ldb.search for CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn
1263 res = ldb.search(expression="(objectclass=*)", base=("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn), scope=SCOPE_BASE)
1264 self.assertEquals(len(res), 1)
1265 res = ldb.search(expression="(cn=ldaptestuser40)", base=("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn), scope=SCOPE_BASE)
1266 self.assertEquals(len(res), 0)
1268 print "Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in cn=ldaptestcontainer2," + self.base_dn
1269 res = ldb.search(expression="(&(cn=ldaptestuser4)(objectClass=user))", base=("cn=ldaptestcontainer2," + self.base_dn), scope=SCOPE_ONELEVEL)
1270 # FIXME: self.assertEquals(len(res), 0)
1272 print "Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in cn=ldaptestcontainer2," + self.base_dn
1273 res = ldb.search(expression="(&(cn=ldaptestuser4)(objectClass=user))", base=("cn=ldaptestcontainer2," + self.base_dn), scope=SCOPE_SUBTREE)
1274 # FIXME: self.assertEquals(len(res), 0)
1276 print "Testing delete of subtree renamed "+("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn)
1277 ldb.delete(("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn))
1278 print "Testing delete of renamed cn=ldaptestcontainer2," + self.base_dn
1279 ldb.delete("cn=ldaptestcontainer2," + self.base_dn)
1281 ldb.add({"dn": "cn=ldaptestutf8user èùéìòà,cn=users," + self.base_dn, "objectClass": "user"})
1283 ldb.add({"dn": "cn=ldaptestutf8user2 èùéìòà,cn=users," + self.base_dn, "objectClass": "user"})
1285 print "Testing ldb.search for (&(cn=ldaptestuser)(objectClass=user))"
1286 res = ldb.search(expression="(&(cn=ldaptestuser)(objectClass=user))")
1287 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser)(objectClass=user))")
1289 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
1290 self.assertEquals(str(res[0]["cn"]), "ldaptestuser")
1291 self.assertEquals(str(res[0]["name"]), "ldaptestuser")
1292 self.assertEquals(set(res[0]["objectClass"]), set(["top", "person", "organizationalPerson", "user"]))
1293 self.assertTrue("objectGUID" in res[0])
1294 self.assertTrue("whenCreated" in res[0])
1295 self.assertEquals(str(res[0]["objectCategory"]), ("CN=Person,CN=Schema,CN=Configuration," + self.base_dn))
1296 self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_NORMAL_ACCOUNT)
1297 self.assertEquals(int(res[0]["userAccountControl"][0]), UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE)
1298 self.assertEquals(res[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
1299 self.assertEquals(len(res[0]["memberOf"]), 1)
1301 print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=cn=person,cn=schema,cn=configuration," + self.base_dn + "))"
1302 res2 = ldb.search(expression="(&(cn=ldaptestuser)(objectCategory=cn=person,cn=schema,cn=configuration," + self.base_dn + "))")
1303 self.assertEquals(len(res2), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=cn=person,cn=schema,cn=configuration," + self.base_dn + "))")
1305 self.assertEquals(res[0].dn, res2[0].dn)
1307 print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon))"
1308 res3 = ldb.search(expression="(&(cn=ldaptestuser)(objectCategory=PerSon))")
1309 self.assertEquals(len(res3), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=PerSon)): matched %d" % len(res3))
1311 self.assertEquals(res[0].dn, res3[0].dn)
1313 if gc_ldb is not None:
1314 print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon)) in Global Catalog"
1315 res3gc = gc_ldb.search(expression="(&(cn=ldaptestuser)(objectCategory=PerSon))")
1316 self.assertEquals(len(res3gc), 1)
1318 self.assertEquals(res[0].dn, res3gc[0].dn)
1320 print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon)) in with 'phantom root' control"
1322 res3control = gc_ldb.search(self.base_dn, expression="(&(cn=ldaptestuser)(objectCategory=PerSon))", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["search_options:1:2"])
1323 self.assertEquals(len(res3control), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=PerSon)) in Global Catalog")
1325 self.assertEquals(res[0].dn, res3control[0].dn)
1327 ldb.delete(res[0].dn)
1329 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectClass=user))"
1330 res = ldb.search(expression="(&(cn=ldaptestcomputer)(objectClass=user))")
1331 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser)(objectClass=user))")
1333 self.assertEquals(str(res[0].dn), ("CN=ldaptestcomputer,CN=Computers," + self.base_dn))
1334 self.assertEquals(str(res[0]["cn"]), "ldaptestcomputer")
1335 self.assertEquals(str(res[0]["name"]), "ldaptestcomputer")
1336 self.assertEquals(set(res[0]["objectClass"]), set(["top", "person", "organizationalPerson", "user", "computer"]))
1337 self.assertTrue("objectGUID" in res[0])
1338 self.assertTrue("whenCreated" in res[0])
1339 self.assertEquals(str(res[0]["objectCategory"]), ("CN=Computer,CN=Schema,CN=Configuration," + self.base_dn))
1340 self.assertEquals(int(res[0]["primaryGroupID"][0]), 513)
1341 self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_NORMAL_ACCOUNT)
1342 self.assertEquals(int(res[0]["userAccountControl"][0]), UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE)
1343 self.assertEquals(res[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
1344 self.assertEquals(len(res[0]["memberOf"]), 1)
1346 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + "))"
1347 res2 = ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + "))")
1348 self.assertEquals(len(res2), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + "))")
1350 self.assertEquals(res[0].dn, res2[0].dn)
1352 if gc_ldb is not None:
1353 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + ")) in Global Catlog"
1354 res2gc = gc_ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + "))")
1355 self.assertEquals(len(res2gc), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + ")) in Global Catlog")
1357 self.assertEquals(res[0].dn, res2gc[0].dn)
1359 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=compuTER))"
1360 res3 = ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=compuTER))")
1361 self.assertEquals(len(res3), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=compuTER))")
1363 self.assertEquals(res[0].dn, res3[0].dn)
1365 if gc_ldb is not None:
1366 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=compuTER)) in Global Catalog"
1367 res3gc = gc_ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=compuTER))")
1368 self.assertEquals(len(res3gc), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=compuTER)) in Global Catalog")
1370 self.assertEquals(res[0].dn, res3gc[0].dn)
1372 print "Testing ldb.search for (&(cn=ldaptestcomp*r)(objectCategory=compuTER))"
1373 res4 = ldb.search(expression="(&(cn=ldaptestcomp*r)(objectCategory=compuTER))")
1374 self.assertEquals(len(res4), 1, "Could not find (&(cn=ldaptestcomp*r)(objectCategory=compuTER))")
1376 self.assertEquals(res[0].dn, res4[0].dn)
1378 print "Testing ldb.search for (&(cn=ldaptestcomput*)(objectCategory=compuTER))"
1379 res5 = ldb.search(expression="(&(cn=ldaptestcomput*)(objectCategory=compuTER))")
1380 self.assertEquals(len(res5), 1, "Could not find (&(cn=ldaptestcomput*)(objectCategory=compuTER))")
1382 self.assertEquals(res[0].dn, res5[0].dn)
1384 print "Testing ldb.search for (&(cn=*daptestcomputer)(objectCategory=compuTER))"
1385 res6 = ldb.search(expression="(&(cn=*daptestcomputer)(objectCategory=compuTER))")
1386 self.assertEquals(len(res6), 1, "Could not find (&(cn=*daptestcomputer)(objectCategory=compuTER))")
1388 self.assertEquals(res[0].dn, res6[0].dn)
1390 ldb.delete("<GUID=" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + ">")
1392 print "Testing ldb.search for (&(cn=ldaptest2computer)(objectClass=user))"
1393 res = ldb.search(expression="(&(cn=ldaptest2computer)(objectClass=user))")
1394 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptest2computer)(objectClass=user))")
1396 self.assertEquals(str(res[0].dn), "CN=ldaptest2computer,CN=Computers," + self.base_dn)
1397 self.assertEquals(str(res[0]["cn"]), "ldaptest2computer")
1398 self.assertEquals(str(res[0]["name"]), "ldaptest2computer")
1399 self.assertEquals(list(res[0]["objectClass"]), ["top", "person", "organizationalPerson", "user", "computer"])
1400 self.assertTrue("objectGUID" in res[0])
1401 self.assertTrue("whenCreated" in res[0])
1402 self.assertEquals(res[0]["objectCategory"][0], "CN=Computer,CN=Schema,CN=Configuration," + self.base_dn)
1403 self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_WORKSTATION_TRUST)
1404 self.assertEquals(int(res[0]["userAccountControl"][0]), UF_WORKSTATION_TRUST_ACCOUNT)
1406 ldb.delete("<SID=" + ldb.schema_format_value("objectSID", res[0]["objectSID"][0]) + ">")
1408 attrs = ["cn", "name", "objectClass", "objectGUID", "objectSID", "whenCreated", "nTSecurityDescriptor", "memberOf", "allowedAttributes", "allowedAttributesEffective"]
1409 print "Testing ldb.search for (&(cn=ldaptestUSer2)(objectClass=user))"
1410 res_user = ldb.search(self.base_dn, expression="(&(cn=ldaptestUSer2)(objectClass=user))", scope=SCOPE_SUBTREE, attrs=attrs)
1411 self.assertEquals(len(res_user), 1, "Could not find (&(cn=ldaptestUSer2)(objectClass=user))")
1413 self.assertEquals(str(res_user[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
1414 self.assertEquals(str(res_user[0]["cn"]), "ldaptestuser2")
1415 self.assertEquals(str(res_user[0]["name"]), "ldaptestuser2")
1416 self.assertEquals(list(res_user[0]["objectClass"]), ["top", "person", "organizationalPerson", "user"])
1417 self.assertTrue("objectSid" in res_user[0])
1418 self.assertTrue("objectGUID" in res_user[0])
1419 self.assertTrue("whenCreated" in res_user[0])
1420 self.assertTrue("nTSecurityDescriptor" in res_user[0])
1421 self.assertTrue("allowedAttributes" in res_user[0])
1422 self.assertTrue("allowedAttributesEffective" in res_user[0])
1423 self.assertEquals(res_user[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
1425 ldaptestuser2_sid = res_user[0]["objectSid"][0]
1426 ldaptestuser2_guid = res_user[0]["objectGUID"][0]
1428 attrs = ["cn", "name", "objectClass", "objectGUID", "objectSID", "whenCreated", "nTSecurityDescriptor", "member", "allowedAttributes", "allowedAttributesEffective"]
1429 print "Testing ldb.search for (&(cn=ldaptestgroup2)(objectClass=group))"
1430 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs)
1431 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))")
1433 self.assertEquals(str(res[0].dn), ("CN=ldaptestgroup2,CN=Users," + self.base_dn))
1434 self.assertEquals(str(res[0]["cn"]), "ldaptestgroup2")
1435 self.assertEquals(str(res[0]["name"]), "ldaptestgroup2")
1436 self.assertEquals(list(res[0]["objectClass"]), ["top", "group"])
1437 self.assertTrue("objectGUID" in res[0])
1438 self.assertTrue("objectSid" in res[0])
1439 self.assertTrue("whenCreated" in res[0])
1440 self.assertTrue("nTSecurityDescriptor" in res[0])
1441 self.assertTrue("allowedAttributes" in res[0])
1442 self.assertTrue("allowedAttributesEffective" in res[0])
1443 memberUP = []
1444 for m in res[0]["member"]:
1445 memberUP.append(m.upper())
1446 self.assertTrue(("CN=ldaptestuser2,CN=Users," + self.base_dn).upper() in memberUP)
1448 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs, controls=["extended_dn:1:1"])
1449 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))")
1451 print res[0]["member"]
1452 memberUP = []
1453 for m in res[0]["member"]:
1454 memberUP.append(m.upper())
1455 print ("<GUID=" + ldb.schema_format_value("objectGUID", ldaptestuser2_guid) + ">;<SID=" + ldb.schema_format_value("objectSid", ldaptestuser2_sid) + ">;CN=ldaptestuser2,CN=Users," + self.base_dn).upper()
1457 self.assertTrue(("<GUID=" + ldb.schema_format_value("objectGUID", ldaptestuser2_guid) + ">;<SID=" + ldb.schema_format_value("objectSid", ldaptestuser2_sid) + ">;CN=ldaptestuser2,CN=Users," + self.base_dn).upper() in memberUP)
1459 print "Testing Linked attribute behaviours"
1460 ldb.modify_ldif("""
1461 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
1462 changetype: modify
1463 replace: member
1464 member: CN=ldaptestuser2,CN=Users,""" + self.base_dn + """
1465 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
1466 """)
1468 ldb.modify_ldif("""
1469 dn: <GUID=""" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + """>
1470 changetype: modify
1471 replace: member
1472 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
1473 """)
1475 ldb.modify_ldif("""
1476 dn: <SID=""" + ldb.schema_format_value("objectSid", res[0]["objectSid"][0]) + """>
1477 changetype: modify
1478 delete: member
1479 """)
1481 ldb.modify_ldif("""
1482 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
1483 changetype: modify
1484 add: member
1485 member: <GUID=""" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + """>
1486 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
1487 """)
1489 ldb.modify_ldif("""
1490 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
1491 changetype: modify
1492 replace: member
1493 """)
1495 ldb.modify_ldif("""
1496 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
1497 changetype: modify
1498 add: member
1499 member: <SID=""" + ldb.schema_format_value("objectSid", res_user[0]["objectSid"][0]) + """>
1500 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
1501 """)
1503 ldb.modify_ldif("""
1504 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
1505 changetype: modify
1506 delete: member
1507 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
1508 """)
1510 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs)
1511 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))")
1513 self.assertEquals(str(res[0].dn), ("CN=ldaptestgroup2,CN=Users," + self.base_dn))
1514 self.assertEquals(res[0]["member"][0], ("CN=ldaptestuser2,CN=Users," + self.base_dn))
1515 self.assertEquals(len(res[0]["member"]), 1)
1517 ldb.delete(("CN=ldaptestuser2,CN=Users," + self.base_dn))
1519 time.sleep(4)
1521 attrs = ["cn", "name", "objectClass", "objectGUID", "whenCreated", "nTSecurityDescriptor", "member"]
1522 print "Testing ldb.search for (&(cn=ldaptestgroup2)(objectClass=group)) to check linked delete"
1523 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs)
1524 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group)) to check linked delete")
1526 self.assertEquals(str(res[0].dn), ("CN=ldaptestgroup2,CN=Users," + self.base_dn))
1527 self.assertTrue("member" not in res[0])
1529 print "Testing ldb.search for (&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))"
1530 # TODO UTF8 users don't seem to work fully anymore
1531 # res = ldb.search(expression="(&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
1532 res = ldb.search(expression="(&(cn=ldaptestutf8user èùéìòà)(objectclass=user))")
1533 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
1535 self.assertEquals(str(res[0].dn), ("CN=ldaptestutf8user èùéìòà,CN=Users," + self.base_dn))
1536 self.assertEquals(str(res[0]["cn"]), "ldaptestutf8user èùéìòà")
1537 self.assertEquals(str(res[0]["name"]), "ldaptestutf8user èùéìòà")
1538 self.assertEquals(list(res[0]["objectClass"]), ["top", "person", "organizationalPerson", "user"])
1539 self.assertTrue("objectGUID" in res[0])
1540 self.assertTrue("whenCreated" in res[0])
1542 ldb.delete(res[0].dn)
1544 print "Testing ldb.search for (&(cn=ldaptestutf8user2*)(objectClass=user))"
1545 res = ldb.search(expression="(&(cn=ldaptestutf8user2*)(objectClass=user))")
1546 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestutf8user2*)(objectClass=user))")
1548 ldb.delete(res[0].dn)
1550 ldb.delete(("CN=ldaptestgroup2,CN=Users," + self.base_dn))
1552 print "Testing ldb.search for (&(cn=ldaptestutf8user2 ÈÙÉÌÒÀ)(objectClass=user))"
1553 # TODO UTF8 users don't seem to work fully anymore
1554 # res = ldb.search(expression="(&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
1555 # self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
1557 print "Testing that we can't get at the configuration DN from the main search base"
1558 res = ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
1559 self.assertEquals(len(res), 0)
1561 print "Testing that we can get at the configuration DN from the main search base on the LDAP port with the 'phantom root' search_options control"
1562 res = ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["search_options:1:2"])
1563 self.assertTrue(len(res) > 0)
1565 if gc_ldb is not None:
1566 print "Testing that we can get at the configuration DN from the main search base on the GC port with the search_options control == 0"
1568 res = gc_ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["search_options:1:0"])
1569 self.assertTrue(len(res) > 0)
1571 print "Testing that we do find configuration elements in the global catlog"
1572 res = gc_ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
1573 self.assertTrue(len(res) > 0)
1575 print "Testing that we do find configuration elements and user elements at the same time"
1576 res = gc_ldb.search(self.base_dn, expression="(|(objectClass=crossRef)(objectClass=person))", scope=SCOPE_SUBTREE, attrs=["cn"])
1577 self.assertTrue(len(res) > 0)
1579 print "Testing that we do find configuration elements in the global catlog, with the configuration basedn"
1580 res = gc_ldb.search(self.configuration_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
1581 self.assertTrue(len(res) > 0)
1583 print "Testing that we can get at the configuration DN on the main LDAP port"
1584 res = ldb.search(self.configuration_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
1585 self.assertTrue(len(res) > 0)
1587 print "Testing objectCategory canonacolisation"
1588 res = ldb.search(self.configuration_dn, expression="objectCategory=ntDsDSA", scope=SCOPE_SUBTREE, attrs=["cn"])
1589 self.assertTrue(len(res) > 0, "Didn't find any records with objectCategory=ntDsDSA")
1590 self.assertTrue(len(res) != 0)
1592 res = ldb.search(self.configuration_dn, expression="objectCategory=CN=ntDs-DSA," + self.schema_dn, scope=SCOPE_SUBTREE, attrs=["cn"])
1593 self.assertTrue(len(res) > 0, "Didn't find any records with objectCategory=CN=ntDs-DSA," + self.schema_dn)
1594 self.assertTrue(len(res) != 0)
1596 print "Testing objectClass attribute order on "+ self.base_dn
1597 res = ldb.search(expression="objectClass=domain", base=self.base_dn,
1598 scope=SCOPE_BASE, attrs=["objectClass"])
1599 self.assertEquals(len(res), 1)
1601 self.assertEquals(list(res[0]["objectClass"]), ["top", "domain", "domainDNS"])
1603 # check enumeration
1605 print "Testing ldb.search for objectCategory=person"
1606 res = ldb.search(self.base_dn, expression="objectCategory=person", scope=SCOPE_SUBTREE, attrs=["cn"])
1607 self.assertTrue(len(res) > 0)
1609 print "Testing ldb.search for objectCategory=person with domain scope control"
1610 res = ldb.search(self.base_dn, expression="objectCategory=person", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["domain_scope:1"])
1611 self.assertTrue(len(res) > 0)
1613 print "Testing ldb.search for objectCategory=user"
1614 res = ldb.search(self.base_dn, expression="objectCategory=user", scope=SCOPE_SUBTREE, attrs=["cn"])
1615 self.assertTrue(len(res) > 0)
1617 print "Testing ldb.search for objectCategory=user with domain scope control"
1618 res = ldb.search(self.base_dn, expression="objectCategory=user", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["domain_scope:1"])
1619 self.assertTrue(len(res) > 0)
1621 print "Testing ldb.search for objectCategory=group"
1622 res = ldb.search(self.base_dn, expression="objectCategory=group", scope=SCOPE_SUBTREE, attrs=["cn"])
1623 self.assertTrue(len(res) > 0)
1625 print "Testing ldb.search for objectCategory=group with domain scope control"
1626 res = ldb.search(self.base_dn, expression="objectCategory=group", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["domain_scope:1"])
1627 self.assertTrue(len(res) > 0)
1629 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1630 self.delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
1631 self.delete_force(self.ldb, "cn=ldaptestuser3,cn=users," + self.base_dn)
1632 self.delete_force(self.ldb, "cn=ldaptestuser4,cn=ldaptestcontainer," + self.base_dn)
1633 self.delete_force(self.ldb, "cn=ldaptestuser4,cn=ldaptestcontainer2," + self.base_dn)
1634 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1635 self.delete_force(self.ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
1636 self.delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
1637 self.delete_force(self.ldb, "cn=ldaptest2computer,cn=computers," + self.base_dn)
1638 self.delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
1639 self.delete_force(self.ldb, "cn=ldaptestutf8user èùéìòà,cn=users," + self.base_dn)
1640 self.delete_force(self.ldb, "cn=ldaptestutf8user2 èùéìòà,cn=users," + self.base_dn)
1641 self.delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
1642 self.delete_force(self.ldb, "cn=ldaptestcontainer2," + self.base_dn)
1644 def test_security_descriptor_add(self):
1645 """ Testing ldb.add_ldif() for nTSecurityDescriptor """
1646 user_name = "testdescriptoruser1"
1647 user_dn = "CN=%s,CN=Users,%s" % (user_name, self.base_dn)
1649 # Test add_ldif() with SDDL security descriptor input
1651 self.delete_force(self.ldb, user_dn)
1652 try:
1653 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
1654 self.ldb.add_ldif("""
1655 dn: """ + user_dn + """
1656 objectclass: user
1657 sAMAccountName: """ + user_name + """
1658 nTSecurityDescriptor: """ + sddl)
1659 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
1660 desc = res[0]["nTSecurityDescriptor"][0]
1661 desc = ndr_unpack( security.descriptor, desc )
1662 desc_sddl = desc.as_sddl( self.domain_sid )
1663 self.assertEqual(desc_sddl, sddl)
1664 finally:
1665 self.delete_force(self.ldb, user_dn)
1667 # Test add_ldif() with BASE64 security descriptor
1669 try:
1670 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
1671 desc = security.descriptor.from_sddl(sddl, self.domain_sid)
1672 desc_binary = ndr_pack(desc)
1673 desc_base64 = base64.b64encode(desc_binary)
1674 self.ldb.add_ldif("""
1675 dn: """ + user_dn + """
1676 objectclass: user
1677 sAMAccountName: """ + user_name + """
1678 nTSecurityDescriptor:: """ + desc_base64)
1679 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
1680 desc = res[0]["nTSecurityDescriptor"][0]
1681 desc = ndr_unpack(security.descriptor, desc)
1682 desc_sddl = desc.as_sddl(self.domain_sid)
1683 self.assertEqual(desc_sddl, sddl)
1684 finally:
1685 self.delete_force(self.ldb, user_dn)
1687 def test_security_descriptor_add_neg(self):
1688 """Test add_ldif() with BASE64 security descriptor input using WRONG domain SID
1689 Negative test
1691 user_name = "testdescriptoruser1"
1692 user_dn = "CN=%s,CN=Users,%s" % (user_name, self.base_dn)
1693 self.delete_force(self.ldb, user_dn)
1694 try:
1695 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
1696 desc = security.descriptor.from_sddl(sddl, security.dom_sid('S-1-5-21'))
1697 desc_base64 = base64.b64encode( ndr_pack(desc) )
1698 self.ldb.add_ldif("""
1699 dn: """ + user_dn + """
1700 objectclass: user
1701 sAMAccountName: """ + user_name + """
1702 nTSecurityDescriptor:: """ + desc_base64)
1703 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
1704 print res
1705 self.assertRaises(KeyError, lambda: res[0]["nTSecurityDescriptor"])
1706 finally:
1707 self.delete_force(self.ldb, user_dn)
1709 def test_security_descriptor_modify(self):
1710 """ Testing ldb.modify_ldif() for nTSecurityDescriptor """
1711 user_name = "testdescriptoruser2"
1712 user_dn = "CN=%s,CN=Users,%s" % (user_name, self.base_dn)
1714 # Delete user object and test modify_ldif() with SDDL security descriptor input
1715 # Add ACE to the original descriptor test
1717 try:
1718 self.delete_force(self.ldb, user_dn)
1719 self.ldb.add_ldif("""
1720 dn: """ + user_dn + """
1721 objectclass: user
1722 sAMAccountName: """ + user_name)
1723 # Modify descriptor
1724 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
1725 desc = res[0]["nTSecurityDescriptor"][0]
1726 desc = ndr_unpack(security.descriptor, desc)
1727 desc_sddl = desc.as_sddl(self.domain_sid)
1728 sddl = desc_sddl[:desc_sddl.find("(")] + "(A;;RPWP;;;AU)" + desc_sddl[desc_sddl.find("("):]
1729 mod = """
1730 dn: """ + user_dn + """
1731 changetype: modify
1732 replace: nTSecurityDescriptor
1733 nTSecurityDescriptor: """ + sddl
1734 self.ldb.modify_ldif(mod)
1735 # Read modified descriptor
1736 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
1737 desc = res[0]["nTSecurityDescriptor"][0]
1738 desc = ndr_unpack(security.descriptor, desc)
1739 desc_sddl = desc.as_sddl(self.domain_sid)
1740 self.assertEqual(desc_sddl, sddl)
1741 finally:
1742 self.delete_force(self.ldb, user_dn)
1744 # Test modify_ldif() with SDDL security descriptor input
1745 # New desctiptor test
1747 try:
1748 self.ldb.add_ldif("""
1749 dn: """ + user_dn + """
1750 objectclass: user
1751 sAMAccountName: """ + user_name)
1752 # Modify descriptor
1753 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
1754 mod = """
1755 dn: """ + user_dn + """
1756 changetype: modify
1757 replace: nTSecurityDescriptor
1758 nTSecurityDescriptor: """ + sddl
1759 self.ldb.modify_ldif(mod)
1760 # Read modified descriptor
1761 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
1762 desc = res[0]["nTSecurityDescriptor"][0]
1763 desc = ndr_unpack(security.descriptor, desc)
1764 desc_sddl = desc.as_sddl(self.domain_sid)
1765 self.assertEqual(desc_sddl, sddl)
1766 finally:
1767 self.delete_force(self.ldb, user_dn)
1769 # Test modify_ldif() with BASE64 security descriptor input
1770 # Add ACE to the original descriptor test
1772 try:
1773 self.ldb.add_ldif("""
1774 dn: """ + user_dn + """
1775 objectclass: user
1776 sAMAccountName: """ + user_name)
1777 # Modify descriptor
1778 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
1779 desc = res[0]["nTSecurityDescriptor"][0]
1780 desc = ndr_unpack(security.descriptor, desc)
1781 desc_sddl = desc.as_sddl(self.domain_sid)
1782 sddl = desc_sddl[:desc_sddl.find("(")] + "(A;;RPWP;;;AU)" + desc_sddl[desc_sddl.find("("):]
1783 desc = security.descriptor.from_sddl(sddl, self.domain_sid)
1784 desc_base64 = base64.b64encode(ndr_pack(desc))
1785 mod = """
1786 dn: """ + user_dn + """
1787 changetype: modify
1788 replace: nTSecurityDescriptor
1789 nTSecurityDescriptor:: """ + desc_base64
1790 self.ldb.modify_ldif(mod)
1791 # Read modified descriptor
1792 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
1793 desc = res[0]["nTSecurityDescriptor"][0]
1794 desc = ndr_unpack(security.descriptor, desc)
1795 desc_sddl = desc.as_sddl(self.domain_sid)
1796 self.assertEqual(desc_sddl, sddl)
1797 finally:
1798 self.delete_force(self.ldb, user_dn)
1800 # Test modify_ldif() with BASE64 security descriptor input
1801 # New descriptor test
1803 try:
1804 self.delete_force(self.ldb, user_dn)
1805 self.ldb.add_ldif("""
1806 dn: """ + user_dn + """
1807 objectclass: user
1808 sAMAccountName: """ + user_name)
1809 # Modify descriptor
1810 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
1811 desc = security.descriptor.from_sddl(sddl, self.domain_sid)
1812 desc_base64 = base64.b64encode(ndr_pack(desc))
1813 mod = """
1814 dn: """ + user_dn + """
1815 changetype: modify
1816 replace: nTSecurityDescriptor
1817 nTSecurityDescriptor:: """ + desc_base64
1818 self.ldb.modify_ldif(mod)
1819 # Read modified descriptor
1820 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
1821 desc = res[0]["nTSecurityDescriptor"][0]
1822 desc = ndr_unpack(security.descriptor, desc)
1823 desc_sddl = desc.as_sddl(self.domain_sid)
1824 self.assertEqual(desc_sddl, sddl)
1825 finally:
1826 self.delete_force(self.ldb, user_dn)
1828 class BaseDnTests(unittest.TestCase):
1829 def setUp(self):
1830 self.ldb = ldb
1832 def test_rootdse_attrs(self):
1833 """Testing for all rootDSE attributes"""
1834 res = self.ldb.search(scope=SCOPE_BASE, attrs=[])
1835 self.assertEquals(len(res), 1)
1837 def test_highestcommittedusn(self):
1838 """Testing for highestCommittedUSN"""
1839 res = self.ldb.search("", scope=SCOPE_BASE, attrs=["highestCommittedUSN"])
1840 self.assertEquals(len(res), 1)
1841 self.assertTrue(int(res[0]["highestCommittedUSN"][0]) != 0)
1843 def test_netlogon(self):
1844 """Testing for netlogon via LDAP"""
1845 res = self.ldb.search("", scope=SCOPE_BASE, attrs=["netlogon"])
1846 self.assertEquals(len(res), 0)
1848 def test_netlogon_highestcommitted_usn(self):
1849 """Testing for netlogon and highestCommittedUSN via LDAP"""
1850 res = self.ldb.search("", scope=SCOPE_BASE,
1851 attrs=["netlogon", "highestCommittedUSN"])
1852 self.assertEquals(len(res), 0)
1854 class SchemaTests(unittest.TestCase):
1855 def delete_force(self, ldb, dn):
1856 try:
1857 ldb.delete(dn)
1858 except LdbError, (num, _):
1859 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
1861 def find_schemadn(self, ldb):
1862 res = ldb.search(base="", expression="", scope=SCOPE_BASE, attrs=["schemaNamingContext"])
1863 self.assertEquals(len(res), 1)
1864 return res[0]["schemaNamingContext"][0]
1866 def find_basedn(self, ldb):
1867 res = ldb.search(base="", expression="", scope=SCOPE_BASE,
1868 attrs=["defaultNamingContext"])
1869 self.assertEquals(len(res), 1)
1870 return res[0]["defaultNamingContext"][0]
1872 def setUp(self):
1873 self.ldb = ldb
1874 self.schema_dn = self.find_schemadn(ldb)
1875 self.base_dn = self.find_basedn(ldb)
1877 def test_generated_schema(self):
1878 """Testing we can read the generated schema via LDAP"""
1879 res = self.ldb.search("cn=aggregate,"+self.schema_dn, scope=SCOPE_BASE,
1880 attrs=["objectClasses", "attributeTypes", "dITContentRules"])
1881 self.assertEquals(len(res), 1)
1882 self.assertTrue("dITContentRules" in res[0])
1883 self.assertTrue("objectClasses" in res[0])
1884 self.assertTrue("attributeTypes" in res[0])
1886 def test_generated_schema_is_operational(self):
1887 """Testing we don't get the generated schema via LDAP by default"""
1888 res = self.ldb.search("cn=aggregate,"+self.schema_dn, scope=SCOPE_BASE,
1889 attrs=["*"])
1890 self.assertEquals(len(res), 1)
1891 self.assertFalse("dITContentRules" in res[0])
1892 self.assertFalse("objectClasses" in res[0])
1893 self.assertFalse("attributeTypes" in res[0])
1896 def test_schemaUpdateNow(self):
1897 """Testing schemaUpdateNow"""
1898 class_name = "test-class" + time.strftime("%s", time.gmtime())
1899 class_ldap_display_name = class_name.replace("-", "")
1900 object_name = "obj" + time.strftime("%s", time.gmtime())
1902 ldif = """
1903 dn: CN=%s,%s""" % (class_name, self.schema_dn) + """
1904 lDAPDisplayName: """ + class_ldap_display_name + """
1905 objectClass: top
1906 objectClass: classSchema
1907 adminDescription: """ + class_name + """
1908 adminDisplayName: """ + class_name + """
1909 cn: """ + class_name + """
1910 objectCategory: CN=Class-Schema,""" + self.schema_dn + """
1911 defaultObjectCategory: CN=%s,%s""" % (class_name, self.schema_dn) + """
1912 distinguishedName: CN=%s,%s""" % (class_name, self.schema_dn) + """
1913 governsID: 1.2.840.""" + str(random.randint(1,100000)) + """.1.5.9939
1914 instanceType: 4
1915 name: """ + class_name + """
1916 objectClassCategory: 1
1917 subClassOf: organizationalPerson
1918 systemFlags: 16
1919 rDNAttID: cn
1920 systemMustContain: cn
1921 systemOnly: FALSE
1923 self.ldb.add_ldif(ldif)
1924 ldif = """
1926 changetype: modify
1927 add: schemaUpdateNow
1928 schemaUpdateNow: 1
1930 self.ldb.modify_ldif(ldif)
1931 ldif = """
1932 dn: CN=%s,CN=Users,%s"""% (object_name, self.base_dn) + """
1933 objectClass: organizationalPerson
1934 objectClass: person
1935 objectClass: """ + class_ldap_display_name + """
1936 objectClass: top
1937 cn: """ + object_name + """
1938 instanceType: 4
1939 objectCategory: CN=%s,%s"""% (class_name, self.schema_dn) + """
1940 distinguishedName: CN=%s,CN=Users,%s"""% (object_name, self.base_dn) + """
1941 name: """ + object_name + """
1943 self.ldb.add_ldif(ldif)
1944 # Search for created objectClass
1945 res = []
1946 res = self.ldb.search("cn=%s,%s" % (class_name, self.schema_dn), scope=SCOPE_BASE, attrs=["*"])
1947 self.assertNotEqual(res, [])
1949 res = []
1950 res = self.ldb.search("cn=%s,cn=Users,%s" % (object_name, self.base_dn), scope=SCOPE_BASE, attrs=["*"])
1951 self.assertNotEqual(res, [])
1952 # Delete the object
1953 self.delete_force(self.ldb, "cn=%s,cn=Users,%s" % (object_name, self.base_dn))
1955 if not "://" in host:
1956 host = "ldap://%s" % host
1958 ldb = Ldb(host, credentials=creds, session_info=system_session(), lp=lp)
1959 gc_ldb = Ldb("%s:3268" % host, credentials=creds,
1960 session_info=system_session(), lp=lp)
1962 runner = SubunitTestRunner()
1963 rc = 0
1964 if not runner.run(unittest.makeSuite(BaseDnTests)).wasSuccessful():
1965 rc = 1
1966 if not runner.run(unittest.makeSuite(BasicTests)).wasSuccessful():
1967 rc = 1
1968 if not runner.run(unittest.makeSuite(SchemaTests)).wasSuccessful():
1969 rc = 1
1970 sys.exit(rc)