2 # -*- coding: utf-8 -*-
3 # This is a port of the original in testprogs/ejs/ldap.js
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
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()
66 lp = sambaopts.get_loadparm()
67 creds = credopts.get_credentials(lp)
69 class BasicTests(unittest.TestCase):
70 def delete_force(self, ldb, 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])
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"""
133 "dn": "cn=ldaptestobject," + self.base_dn,
134 "objectclass": "configuration"})
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"""
147 "dn": "cn=ldaptestgroup,cn=thisdoesnotexist123,"
149 "objectclass": "group"})
151 except LdbError, (num, _):
152 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
154 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=thisdoesnotexist123,"
159 "dn": "ou=testou,cn=users," + self.base_dn,
160 "objectclass": "organizationalUnit"})
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)"""
173 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
174 "objectclass": "group",
175 "thisdoesnotexist": "x"})
177 except LdbError, (num, _):
178 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
181 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
182 "objectclass": "group"})
185 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
186 m["thisdoesnotexist"] = MessageElement("x", FLAG_MOD_REPLACE,
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"""
202 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
203 "objectclass": "group",
204 "sAMAccountName": ["nam1", "nam2"]})
206 except LdbError, (num, _):
207 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
210 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
211 "objectclass": "group"})
214 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
215 m["sAMAccountName"] = MessageElement(["nam1","nam2"], FLAG_MOD_REPLACE,
220 except LdbError, (num, _):
221 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
224 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
225 m["sAMAccountName"] = MessageElement("testgroup", FLAG_MOD_REPLACE,
230 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
231 m["sAMAccountName"] = MessageElement("testgroup2", FLAG_MOD_ADD,
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)
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)
259 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
260 "objectclass": "group",
261 "description": ["desc1", "desc2"]})
264 # m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
265 # m["description"] = MessageElement(["desc1","desc2"], FLAG_MOD_REPLACE,
270 # except LdbError, (num, _):
271 # self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
274 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
275 m["description"] = MessageElement("desc1", FLAG_MOD_REPLACE,
280 # m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
281 # m["description"] = MessageElement("desc3", FLAG_MOD_ADD,
286 # except LdbError, (num, _):
287 # self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
290 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
291 m["description"] = MessageElement(["desc1","desc2"], FLAG_MOD_DELETE,
296 except LdbError, (num, _):
297 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
300 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
301 m["description"] = MessageElement("desc1", FLAG_MOD_DELETE,
306 # m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
307 # m["description"] = MessageElement(["desc1","desc2"], FLAG_MOD_REPLACE,
312 # except LdbError, (num, _):
313 # self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
316 # m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
317 # m["description"] = MessageElement(["desc3", "desc4"], FLAG_MOD_ADD,
322 # except LdbError, (num, _):
323 # self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
326 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
327 m["description"] = MessageElement("desc3", FLAG_MOD_ADD,
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"""
338 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
343 except LdbError, (num, _):
344 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
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"""
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")
366 except LdbError, (num, _):
367 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
370 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
371 "objectclass": "group"})
374 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
375 m["description"] = MessageElement([], FLAG_MOD_ADD, "description")
380 except LdbError, (num, _):
381 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
384 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
385 m["description"] = MessageElement([], FLAG_MOD_REPLACE, "description")
389 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
390 m["description"] = MessageElement([], FLAG_MOD_DELETE, "description")
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"""
404 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
405 "objectclass": "group"})
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,
416 except LdbError, (num, _):
417 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
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,
428 except LdbError, (num, _):
429 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
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,
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):
447 print "Tests the RDN"""
451 "dn": "description=xyz,cn=users," + self.base_dn,
452 "objectclass": "group"})
454 except LdbError, (num, _):
455 self.assertEquals(num, ERR_NAMING_VIOLATION)
457 self.delete_force(self.ldb, "description=xyz,cn=users," + self.base_dn)
460 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
461 "objectclass": "group"})
464 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
465 m["name"] = MessageElement("cn=ldaptestuser", FLAG_MOD_REPLACE,
471 except LdbError, (num, _):
472 self.assertEquals(num, ERR_NOT_ALLOWED_ON_RDN)
475 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
476 m["cn"] = MessageElement("ldaptestuser",
477 FLAG_MOD_REPLACE, "cn")
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)
487 def test_rename(self):
488 """Tests the rename operation"""
489 print "Tests the rename operations"""
492 "dn": "cn=ldaptestuser2,cn=users," + self.base_dn,
493 "objectclass": ["user", "person"] })
495 ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser2,cn=users," + self.base_dn)
496 ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=users," + self.base_dn)
497 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestUSER3,cn=users," + self.base_dn)
499 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, ",cn=users," + self.base_dn)
501 except LdbError, (num, _):
502 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
504 self.delete_force(self.ldb, "cn=ldaptestuser3,cn=users," + self.base_dn)
506 def test_parentGUID(self):
507 """Test parentGUID behaviour"""
508 print "Testing parentGUID behaviour\n"
510 # TODO: This seems to fail on Windows Server. Hidden attribute?
513 "dn": "cn=parentguidtest,cn=users," + self.base_dn,
514 "objectclass":"user",
515 "samaccountname":"parentguidtest"});
516 res1 = ldb.search(base="cn=parentguidtest,cn=users," + self.base_dn, scope=SCOPE_BASE,
517 attrs=["parentGUID"]);
518 res2 = ldb.search(base="cn=users," + self.base_dn,scope=SCOPE_BASE,
519 attrs=["objectGUID"]);
520 self.assertEquals(res1[0]["parentGUID"], res2[0]["objectGUID"]);
522 print "Testing parentGUID behaviour on rename\n"
525 "dn": "cn=testotherusers," + self.base_dn,
526 "objectclass":"container"});
527 res1 = ldb.search(base="cn=testotherusers," + self.base_dn,scope=SCOPE_BASE,
528 attrs=["objectGUID"]);
529 ldb.rename("cn=parentguidtest,cn=users," + self.base_dn,
530 "cn=parentguidtest,cn=testotherusers," + self.base_dn);
531 res2 = ldb.search(base="cn=parentguidtest,cn=testotherusers," + self.base_dn,
533 attrs=["parentGUID"]);
534 self.assertEquals(res1[0]["objectGUID"], res2[0]["parentGUID"]);
536 self.delete_force(self.ldb, "cn=parentguidtest,cn=testotherusers," + self.base_dn)
537 self.delete_force(self.ldb, "cn=testotherusers," + self.base_dn)
539 def test_groupType_int32(self):
540 """Test groupType (int32) behaviour (should appear to be casted to a 32 bit signed integer before comparsion)"""
541 print "Testing groupType (int32) behaviour\n"
543 res1 = ldb.search(base=self.base_dn, scope=SCOPE_SUBTREE,
544 attrs=["groupType"], expression="groupType=2147483653");
546 res2 = ldb.search(base=self.base_dn, scope=SCOPE_SUBTREE,
547 attrs=["groupType"], expression="groupType=-2147483643");
549 self.assertEquals(len(res1), len(res2))
551 self.assertTrue(res1.count > 0)
553 self.assertEquals(res1[0]["groupType"][0], "-2147483643")
555 def test_groups(self):
556 """This tests the group behaviour (setting, changing) of a user account"""
557 print "Testing group behaviour\n"
560 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
561 "objectclass": "group"})
564 "dn": "cn=ldaptestgroup2,cn=users," + self.base_dn,
565 "objectclass": "group"})
567 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
568 scope=SCOPE_BASE, attrs=["objectSID"])
569 self.assertTrue(len(res1) == 1)
570 group_rid_1 = dom_sid_to_rid(ldb.schema_format_value("objectSID",
571 res1[0]["objectSID"][0]))
573 res1 = ldb.search("cn=ldaptestgroup2,cn=users," + self.base_dn,
574 scope=SCOPE_BASE, attrs=["objectSID"])
575 self.assertTrue(len(res1) == 1)
576 group_rid_2 = dom_sid_to_rid(ldb.schema_format_value("objectSID",
577 res1[0]["objectSID"][0]))
579 # Try to create a user with an invalid primary group
582 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
583 "objectclass": ["user", "person"],
584 "primaryGroupID": "0"})
586 except LdbError, (num, _):
587 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
588 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
590 # Try to Create a user with a valid primary group
591 # TODO Some more investigation needed here
594 # "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
595 # "objectclass": ["user", "person"],
596 # "primaryGroupID": str(group_rid_1)})
598 # except LdbError, (num, _):
599 # self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
600 # self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
603 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
604 "objectclass": ["user", "person"]})
606 # Try to add invalid primary group
608 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
609 m["primaryGroupID"] = MessageElement("0", FLAG_MOD_REPLACE,
614 except LdbError, (num, _):
615 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
617 # Try to make group 1 primary - should be denied since it is not yet
620 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
621 m["primaryGroupID"] = MessageElement(str(group_rid_1),
622 FLAG_MOD_REPLACE, "primaryGroupID")
626 except LdbError, (num, _):
627 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
629 # Make group 1 secondary
631 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
632 m["member"] = "cn=ldaptestuser,cn=users," + self.base_dn
635 # Make group 1 primary
637 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
638 m["primaryGroupID"] = MessageElement(str(group_rid_1),
639 FLAG_MOD_REPLACE, "primaryGroupID")
642 # Try to delete group 1 - should be denied
644 ldb.delete("cn=ldaptestgroup,cn=users," + self.base_dn)
646 except LdbError, (num, _):
647 self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
649 # Try to add group 1 also as secondary - should be denied
651 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
652 m["member"] = "cn=ldaptestuser,cn=users," + self.base_dn
656 except LdbError, (num, _):
657 self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
659 # Try to add invalid member to group 1 - should be denied
661 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
662 m["member"] = MessageElement(
663 "cn=ldaptestuser3,cn=users," + self.base_dn,
664 FLAG_MOD_ADD, "member")
668 except LdbError, (num, _):
669 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
671 # Make group 2 secondary
673 m.dn = Dn(ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
674 m["member"] = "cn=ldaptestuser,cn=users," + self.base_dn
679 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
680 m["primaryGroupID"] = MessageElement(str(group_rid_2),
681 FLAG_MOD_REPLACE, "primaryGroupID")
684 # Old primary group should contain a "member" attribute for the user,
685 # the new shouldn't contain anymore one
686 res1 = ldb.search("cn=ldaptestgroup, cn=users," + self.base_dn,
687 scope=SCOPE_BASE, attrs=["member"])
688 self.assertTrue(len(res1) == 1)
689 self.assertTrue(len(res1[0]["member"]) == 1)
690 self.assertEquals(res1[0]["member"][0].lower(),
691 ("cn=ldaptestuser,cn=users," + self.base_dn).lower())
693 res1 = ldb.search("cn=ldaptestgroup2, cn=users," + self.base_dn,
694 scope=SCOPE_BASE, attrs=["member"])
695 self.assertTrue(len(res1) == 1)
696 self.assertFalse("member" in res1[0])
698 # Also this should be denied
701 "dn": "cn=ldaptestuser1,cn=users," + self.base_dn,
702 "objectclass": ["user", "person"],
703 "primaryGroupID": "0"})
705 except LdbError, (num, _):
706 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
708 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
709 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
710 self.delete_force(self.ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
712 def test_primary_group_token(self):
713 """Test the primary group token behaviour (hidden-generated-readonly attribute on groups)"""
714 print "Testing primary group token behaviour\n"
717 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
718 "objectclass": ["user", "person"]})
721 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
722 "objectclass": "group"})
724 res1 = ldb.search("cn=ldaptestuser, cn=users," + self.base_dn,
725 scope=SCOPE_BASE, attrs=["primaryGroupToken"])
726 self.assertTrue(len(res1) == 1)
727 self.assertFalse("primaryGroupToken" in res1[0])
729 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
731 self.assertTrue(len(res1) == 1)
732 self.assertFalse("primaryGroupToken" in res1[0])
734 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
735 scope=SCOPE_BASE, attrs=["primaryGroupToken", "objectSID"])
736 self.assertTrue(len(res1) == 1)
737 primary_group_token = int(res1[0]["primaryGroupToken"][0])
739 rid = dom_sid_to_rid(ldb.schema_format_value("objectSID", res1[0]["objectSID"][0]))
740 self.assertEquals(primary_group_token, rid)
742 # TODO Has to wait until we support read-only generated attributes correctly
744 # m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
745 # m["primaryGroupToken"] = "100"
749 # except LdbError, (num, msg):
751 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
752 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
757 print "Testing user add"
760 "dn": "cn=ldaptestuser,cn=uSers," + self.base_dn,
761 "objectclass": ["user", "person"],
762 "cN": "LDAPtestUSER",
767 "dn": "cn=ldaptestgroup,cn=uSers," + self.base_dn,
768 "objectclass": "group",
769 "member": "cn=ldaptestuser,cn=useRs," + self.base_dn})
772 "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
773 "objectclass": "computer",
774 "cN": "LDAPtestCOMPUTER"})
776 ldb.add({"dn": "cn=ldaptest2computer,cn=computers," + self.base_dn,
777 "objectClass": "computer",
778 "cn": "LDAPtest2COMPUTER",
779 "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT),
780 "displayname": "ldap testy"})
783 ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn,
784 "objectClass": "computer",
785 "cn": "LDAPtest2COMPUTER"
788 except LdbError, (num, _):
789 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
792 ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn,
793 "objectClass": "computer",
794 "cn": "ldaptestcomputer3",
795 "sAMAccountType": str(ATYPE_NORMAL_ACCOUNT)
798 except LdbError, (num, _):
799 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
801 ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn,
802 "objectClass": "computer",
803 "cn": "LDAPtestCOMPUTER3"
806 print "Testing ldb.search for (&(cn=ldaptestcomputer3)(objectClass=user))";
807 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestcomputer3)(objectClass=user))");
808 self.assertEquals(len(res), 1, "Found only %d for (&(cn=ldaptestcomputer3)(objectClass=user))" % len(res))
810 self.assertEquals(str(res[0].dn), ("CN=ldaptestcomputer3,CN=Computers," + self.base_dn));
811 self.assertEquals(res[0]["cn"][0], "ldaptestcomputer3");
812 self.assertEquals(res[0]["name"][0], "ldaptestcomputer3");
813 self.assertEquals(res[0]["objectClass"][0], "top");
814 self.assertEquals(res[0]["objectClass"][1], "person");
815 self.assertEquals(res[0]["objectClass"][2], "organizationalPerson");
816 self.assertEquals(res[0]["objectClass"][3], "user");
817 self.assertEquals(res[0]["objectClass"][4], "computer");
818 self.assertTrue("objectGUID" in res[0])
819 self.assertTrue("whenCreated" in res[0])
820 self.assertEquals(res[0]["objectCategory"][0], ("CN=Computer,CN=Schema,CN=Configuration," + self.base_dn));
821 self.assertEquals(int(res[0]["primaryGroupID"][0]), 513);
822 self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_NORMAL_ACCOUNT);
823 self.assertEquals(int(res[0]["userAccountControl"][0]), UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE);
825 self.delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
827 print "Testing attribute or value exists behaviour"
830 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
832 replace: servicePrincipalName
833 servicePrincipalName: host/ldaptest2computer
834 servicePrincipalName: host/ldaptest2computer
835 servicePrincipalName: cifs/ldaptest2computer
838 except LdbError, (num, msg):
839 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
842 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
844 replace: servicePrincipalName
845 servicePrincipalName: host/ldaptest2computer
846 servicePrincipalName: cifs/ldaptest2computer
850 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
852 add: servicePrincipalName
853 servicePrincipalName: host/ldaptest2computer
856 except LdbError, (num, msg):
857 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
859 print "Testing ranged results"
861 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
863 replace: servicePrincipalName
867 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
869 add: servicePrincipalName
870 servicePrincipalName: host/ldaptest2computer0
871 servicePrincipalName: host/ldaptest2computer1
872 servicePrincipalName: host/ldaptest2computer2
873 servicePrincipalName: host/ldaptest2computer3
874 servicePrincipalName: host/ldaptest2computer4
875 servicePrincipalName: host/ldaptest2computer5
876 servicePrincipalName: host/ldaptest2computer6
877 servicePrincipalName: host/ldaptest2computer7
878 servicePrincipalName: host/ldaptest2computer8
879 servicePrincipalName: host/ldaptest2computer9
880 servicePrincipalName: host/ldaptest2computer10
881 servicePrincipalName: host/ldaptest2computer11
882 servicePrincipalName: host/ldaptest2computer12
883 servicePrincipalName: host/ldaptest2computer13
884 servicePrincipalName: host/ldaptest2computer14
885 servicePrincipalName: host/ldaptest2computer15
886 servicePrincipalName: host/ldaptest2computer16
887 servicePrincipalName: host/ldaptest2computer17
888 servicePrincipalName: host/ldaptest2computer18
889 servicePrincipalName: host/ldaptest2computer19
890 servicePrincipalName: host/ldaptest2computer20
891 servicePrincipalName: host/ldaptest2computer21
892 servicePrincipalName: host/ldaptest2computer22
893 servicePrincipalName: host/ldaptest2computer23
894 servicePrincipalName: host/ldaptest2computer24
895 servicePrincipalName: host/ldaptest2computer25
896 servicePrincipalName: host/ldaptest2computer26
897 servicePrincipalName: host/ldaptest2computer27
898 servicePrincipalName: host/ldaptest2computer28
899 servicePrincipalName: host/ldaptest2computer29
902 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE,
903 attrs=["servicePrincipalName;range=0-*"])
904 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
905 #print len(res[0]["servicePrincipalName;range=0-*"])
906 self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30)
908 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-19"])
909 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
910 # print res[0]["servicePrincipalName;range=0-19"].length
911 self.assertEquals(len(res[0]["servicePrincipalName;range=0-19"]), 20)
914 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-30"])
915 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
916 self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30)
918 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-40"])
919 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
920 self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30)
922 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=30-40"])
923 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
924 self.assertEquals(len(res[0]["servicePrincipalName;range=30-*"]), 0)
927 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=10-40"])
928 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
929 self.assertEquals(len(res[0]["servicePrincipalName;range=10-*"]), 20)
930 # pos_11 = res[0]["servicePrincipalName;range=10-*"][18]
932 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=11-40"])
933 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
934 self.assertEquals(len(res[0]["servicePrincipalName;range=11-*"]), 19)
935 # print res[0]["servicePrincipalName;range=11-*"][18]
937 # self.assertEquals((res[0]["servicePrincipalName;range=11-*"][18]), pos_11)
939 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=11-15"])
940 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
941 self.assertEquals(len(res[0]["servicePrincipalName;range=11-15"]), 5)
942 # self.assertEquals(res[0]["servicePrincipalName;range=11-15"][4], pos_11)
944 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName"])
945 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
946 # print res[0]["servicePrincipalName"][18]
948 self.assertEquals(len(res[0]["servicePrincipalName"]), 30)
949 # self.assertEquals(res[0]["servicePrincipalName"][18], pos_11)
951 self.delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
953 "dn": "cn=ldaptestuser2,cn=useRs," + self.base_dn,
954 "objectClass": ["person", "user"],
955 "cn": "LDAPtestUSER2",
956 "givenname": "testy",
959 print "Testing Ambigious Name Resolution"
960 # Testing ldb.search for (&(anr=ldap testy)(objectClass=user))
961 res = ldb.search(expression="(&(anr=ldap testy)(objectClass=user))")
962 self.assertEquals(len(res), 3, "Found only %d of 3 for (&(anr=ldap testy)(objectClass=user))" % len(res))
964 # Testing ldb.search for (&(anr=testy ldap)(objectClass=user))
965 res = ldb.search(expression="(&(anr=testy ldap)(objectClass=user))")
966 self.assertEquals(len(res), 2, "Found only %d of 2 for (&(anr=testy ldap)(objectClass=user))" % len(res))
968 # Testing ldb.search for (&(anr=ldap)(objectClass=user))
969 res = ldb.search(expression="(&(anr=ldap)(objectClass=user))")
970 self.assertEquals(len(res), 4, "Found only %d of 4 for (&(anr=ldap)(objectClass=user))" % len(res))
972 # Testing ldb.search for (&(anr==ldap)(objectClass=user))
973 res = ldb.search(expression="(&(anr==ldap)(objectClass=user))")
974 self.assertEquals(len(res), 1, "Could not find (&(anr==ldap)(objectClass=user)). Found only %d for (&(anr=ldap)(objectClass=user))" % len(res))
976 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
977 self.assertEquals(res[0]["cn"][0], "ldaptestuser")
978 self.assertEquals(str(res[0]["name"]), "ldaptestuser")
980 # Testing ldb.search for (&(anr=testy)(objectClass=user))
981 res = ldb.search(expression="(&(anr=testy)(objectClass=user))")
982 self.assertEquals(len(res), 2, "Found only %d for (&(anr=testy)(objectClass=user))" % len(res))
984 # Testing ldb.search for (&(anr=testy ldap)(objectClass=user))
985 res = ldb.search(expression="(&(anr=testy ldap)(objectClass=user))")
986 self.assertEquals(len(res), 2, "Found only %d for (&(anr=testy ldap)(objectClass=user))" % len(res))
988 # Testing ldb.search for (&(anr==testy ldap)(objectClass=user))
989 # this test disabled for the moment, as anr with == tests are not understood
990 # res = ldb.search(expression="(&(anr==testy ldap)(objectClass=user))")
991 # self.assertEquals(len(res), 1, "Found only %d for (&(anr==testy ldap)(objectClass=user))" % len(res))
993 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
994 self.assertEquals(res[0]["cn"][0], "ldaptestuser")
995 self.assertEquals(res[0]["name"][0], "ldaptestuser")
997 # Testing ldb.search for (&(anr==testy ldap)(objectClass=user))
998 # res = ldb.search(expression="(&(anr==testy ldap)(objectClass=user))")
999 # self.assertEquals(len(res), 1, "Could not find (&(anr==testy ldap)(objectClass=user))")
1001 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
1002 self.assertEquals(res[0]["cn"][0], "ldaptestuser")
1003 self.assertEquals(res[0]["name"][0], "ldaptestuser")
1005 # Testing ldb.search for (&(anr=testy ldap user)(objectClass=user))
1006 res = ldb.search(expression="(&(anr=testy ldap user)(objectClass=user))")
1007 self.assertEquals(len(res), 1, "Could not find (&(anr=testy ldap user)(objectClass=user))")
1009 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
1010 self.assertEquals(str(res[0]["cn"]), "ldaptestuser2")
1011 self.assertEquals(str(res[0]["name"]), "ldaptestuser2")
1013 # Testing ldb.search for (&(anr==testy ldap user2)(objectClass=user))
1014 # res = ldb.search(expression="(&(anr==testy ldap user2)(objectClass=user))")
1015 # self.assertEquals(len(res), 1, "Could not find (&(anr==testy ldap user2)(objectClass=user))")
1017 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
1018 self.assertEquals(str(res[0]["cn"]), "ldaptestuser2")
1019 self.assertEquals(str(res[0]["name"]), "ldaptestuser2")
1021 # Testing ldb.search for (&(anr==ldap user2)(objectClass=user))
1022 # res = ldb.search(expression="(&(anr==ldap user2)(objectClass=user))")
1023 # self.assertEquals(len(res), 1, "Could not find (&(anr==ldap user2)(objectClass=user))")
1025 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
1026 self.assertEquals(str(res[0]["cn"]), "ldaptestuser2")
1027 self.assertEquals(str(res[0]["name"]), "ldaptestuser2")
1029 # Testing ldb.search for (&(anr==not ldap user2)(objectClass=user))
1030 # res = ldb.search(expression="(&(anr==not ldap user2)(objectClass=user))")
1031 # self.assertEquals(len(res), 0, "Must not find (&(anr==not ldap user2)(objectClass=user))")
1033 # Testing ldb.search for (&(anr=not ldap user2)(objectClass=user))
1034 res = ldb.search(expression="(&(anr=not ldap user2)(objectClass=user))")
1035 self.assertEquals(len(res), 0, "Must not find (&(anr=not ldap user2)(objectClass=user))")
1037 # Testing ldb.search for (&(anr="testy ldap")(objectClass=user)) (ie, with quotes)
1038 # res = ldb.search(expression="(&(anr==\"testy ldap\")(objectClass=user))")
1039 # self.assertEquals(len(res), 0, "Found (&(anr==\"testy ldap\")(objectClass=user))")
1041 print "Testing Renames"
1043 attrs = ["objectGUID", "objectSid"]
1044 print "Testing ldb.search for (&(cn=ldaptestUSer2)(objectClass=user))"
1045 res_user = ldb.search(self.base_dn, expression="(&(cn=ldaptestUSer2)(objectClass=user))", scope=SCOPE_SUBTREE, attrs=attrs)
1046 self.assertEquals(len(res_user), 1, "Could not find (&(cn=ldaptestUSer2)(objectClass=user))")
1048 # Check rename works with extended/alternate DN forms
1049 ldb.rename("<SID=" + ldb.schema_format_value("objectSID", res_user[0]["objectSID"][0]) + ">" , "cn=ldaptestUSER3,cn=users," + self.base_dn)
1051 print "Testing ldb.search for (&(cn=ldaptestuser3)(objectClass=user))"
1052 res = ldb.search(expression="(&(cn=ldaptestuser3)(objectClass=user))")
1053 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser3)(objectClass=user))")
1055 self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
1056 self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3")
1057 self.assertEquals(str(res[0]["name"]), "ldaptestUSER3")
1059 #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))"
1060 res = ldb.search(expression="(&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))")
1061 self.assertEquals(len(res), 1, "(&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))")
1063 self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
1064 self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3")
1065 self.assertEquals(str(res[0]["name"]), "ldaptestUSER3")
1067 #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))"
1068 res = ldb.search(expression="(&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))")
1069 self.assertEquals(len(res), 1, "(&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))")
1071 self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
1072 self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3")
1073 self.assertEquals(str(res[0]["name"]), "ldaptestUSER3")
1075 #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))"
1076 res = ldb.search(expression="(&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))")
1077 self.assertEquals(len(res), 0, "(&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))")
1079 # This is a Samba special, and does not exist in real AD
1080 # print "Testing ldb.search for (dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")"
1081 # res = ldb.search("(dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")")
1082 # if (res.error != 0 || len(res) != 1) {
1083 # print "Could not find (dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")"
1084 # self.assertEquals(len(res), 1)
1086 # self.assertEquals(res[0].dn, ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
1087 # self.assertEquals(res[0].cn, "ldaptestUSER3")
1088 # self.assertEquals(res[0].name, "ldaptestUSER3")
1090 print "Testing ldb.search for (distinguishedName=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")"
1091 res = ldb.search(expression="(distinguishedName=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")")
1092 self.assertEquals(len(res), 1, "Could not find (dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")")
1093 self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
1094 self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3")
1095 self.assertEquals(str(res[0]["name"]), "ldaptestUSER3")
1097 # ensure we cannot add it again
1099 ldb.add({"dn": "cn=ldaptestuser3,cn=userS," + self.base_dn,
1100 "objectClass": ["person", "user"],
1101 "cn": "LDAPtestUSER3"})
1103 except LdbError, (num, _):
1104 self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
1107 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser2,cn=users," + self.base_dn)
1109 # ensure we cannot rename it twice
1111 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn,
1112 "cn=ldaptestuser2,cn=users," + self.base_dn)
1114 except LdbError, (num, _):
1115 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
1117 # ensure can now use that name
1118 ldb.add({"dn": "cn=ldaptestuser3,cn=users," + self.base_dn,
1119 "objectClass": ["person", "user"],
1120 "cn": "LDAPtestUSER3"})
1122 # ensure we now cannot rename
1124 ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=users," + self.base_dn)
1126 except LdbError, (num, _):
1127 self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
1129 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=configuration," + self.base_dn)
1131 except LdbError, (num, _):
1132 self.assertTrue(num in (71, 64))
1134 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser5,cn=users," + self.base_dn)
1136 ldb.delete("cn=ldaptestuser5,cn=users," + self.base_dn)
1138 self.delete_force(ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
1140 ldb.rename("cn=ldaptestgroup,cn=users," + self.base_dn, "cn=ldaptestgroup2,cn=users," + self.base_dn)
1142 print "Testing subtree renames"
1144 ldb.add({"dn": "cn=ldaptestcontainer," + self.base_dn,
1145 "objectClass": "container"})
1147 ldb.add({"dn": "CN=ldaptestuser4,CN=ldaptestcontainer," + self.base_dn,
1148 "objectClass": ["person", "user"],
1149 "cn": "LDAPtestUSER4"})
1152 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
1155 member: cn=ldaptestuser4,cn=ldaptestcontainer,""" + self.base_dn + """
1156 member: cn=ldaptestcomputer,cn=computers,""" + self.base_dn + """
1157 member: cn=ldaptestuser2,cn=users,""" + self.base_dn + """
1160 print "Testing ldb.rename of cn=ldaptestcontainer," + self.base_dn + " to cn=ldaptestcontainer2," + self.base_dn
1161 ldb.rename("CN=ldaptestcontainer," + self.base_dn, "CN=ldaptestcontainer2," + self.base_dn)
1163 print "Testing ldb.search for (&(cn=ldaptestuser4)(objectClass=user))"
1164 res = ldb.search(expression="(&(cn=ldaptestuser4)(objectClass=user))")
1165 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser4)(objectClass=user))")
1167 print "Testing subtree ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in (just renamed from) cn=ldaptestcontainer," + self.base_dn
1169 res = ldb.search("cn=ldaptestcontainer," + self.base_dn,
1170 expression="(&(cn=ldaptestuser4)(objectClass=user))",
1171 scope=SCOPE_SUBTREE)
1173 except LdbError, (num, _):
1174 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
1176 print "Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in (just renamed from) cn=ldaptestcontainer," + self.base_dn
1178 res = ldb.search("cn=ldaptestcontainer," + self.base_dn,
1179 expression="(&(cn=ldaptestuser4)(objectClass=user))", scope=SCOPE_ONELEVEL)
1181 except LdbError, (num, _):
1182 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
1184 print "Testing ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in renamed container"
1185 res = ldb.search("cn=ldaptestcontainer2," + self.base_dn, expression="(&(cn=ldaptestuser4)(objectClass=user))", scope=SCOPE_SUBTREE)
1186 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser4)(objectClass=user)) under cn=ldaptestcontainer2," + self.base_dn)
1188 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn))
1189 self.assertEquals(res[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
1193 print "Testing ldb.search for (&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn + ")(objectclass=group)) to check subtree renames and linked attributes"
1194 res = ldb.search(self.base_dn, expression="(&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn + ")(objectclass=group))", scope=SCOPE_SUBTREE)
1195 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?")
1197 print "Testing ldb.rename (into itself) of cn=ldaptestcontainer2," + self.base_dn + " to cn=ldaptestcontainer,cn=ldaptestcontainer2," + self.base_dn
1199 ldb.rename("cn=ldaptestcontainer2," + self.base_dn, "cn=ldaptestcontainer,cn=ldaptestcontainer2," + self.base_dn)
1201 except LdbError, (num, _):
1202 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1204 print "Testing ldb.rename (into non-existent container) of cn=ldaptestcontainer2," + self.base_dn + " to cn=ldaptestcontainer,cn=ldaptestcontainer3," + self.base_dn
1206 ldb.rename("cn=ldaptestcontainer2," + self.base_dn, "cn=ldaptestcontainer,cn=ldaptestcontainer3," + self.base_dn)
1208 except LdbError, (num, _):
1209 self.assertTrue(num in (ERR_UNWILLING_TO_PERFORM, ERR_OTHER))
1211 print "Testing delete (should fail, not a leaf node) of renamed cn=ldaptestcontainer2," + self.base_dn
1213 ldb.delete("cn=ldaptestcontainer2," + self.base_dn)
1215 except LdbError, (num, _):
1216 self.assertEquals(num, ERR_NOT_ALLOWED_ON_NON_LEAF)
1218 print "Testing base ldb.search for CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn
1219 res = ldb.search(expression="(objectclass=*)", base=("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn), scope=SCOPE_BASE)
1220 self.assertEquals(len(res), 1)
1221 res = ldb.search(expression="(cn=ldaptestuser40)", base=("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn), scope=SCOPE_BASE)
1222 self.assertEquals(len(res), 0)
1224 print "Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in cn=ldaptestcontainer2," + self.base_dn
1225 res = ldb.search(expression="(&(cn=ldaptestuser4)(objectClass=user))", base=("cn=ldaptestcontainer2," + self.base_dn), scope=SCOPE_ONELEVEL)
1226 # FIXME: self.assertEquals(len(res), 0)
1228 print "Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in cn=ldaptestcontainer2," + self.base_dn
1229 res = ldb.search(expression="(&(cn=ldaptestuser4)(objectClass=user))", base=("cn=ldaptestcontainer2," + self.base_dn), scope=SCOPE_SUBTREE)
1230 # FIXME: self.assertEquals(len(res), 0)
1232 print "Testing delete of subtree renamed "+("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn)
1233 ldb.delete(("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn))
1234 print "Testing delete of renamed cn=ldaptestcontainer2," + self.base_dn
1235 ldb.delete("cn=ldaptestcontainer2," + self.base_dn)
1237 ldb.add({"dn": "cn=ldaptestutf8user èùéìòà,cn=users," + self.base_dn, "objectClass": "user"})
1239 ldb.add({"dn": "cn=ldaptestutf8user2 èùéìòà,cn=users," + self.base_dn, "objectClass": "user"})
1241 print "Testing ldb.search for (&(cn=ldaptestuser)(objectClass=user))"
1242 res = ldb.search(expression="(&(cn=ldaptestuser)(objectClass=user))")
1243 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser)(objectClass=user))")
1245 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
1246 self.assertEquals(str(res[0]["cn"]), "ldaptestuser")
1247 self.assertEquals(str(res[0]["name"]), "ldaptestuser")
1248 self.assertEquals(set(res[0]["objectClass"]), set(["top", "person", "organizationalPerson", "user"]))
1249 self.assertTrue("objectGUID" in res[0])
1250 self.assertTrue("whenCreated" in res[0])
1251 self.assertEquals(str(res[0]["objectCategory"]), ("CN=Person,CN=Schema,CN=Configuration," + self.base_dn))
1252 self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_NORMAL_ACCOUNT)
1253 self.assertEquals(int(res[0]["userAccountControl"][0]), UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE)
1254 self.assertEquals(res[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
1255 self.assertEquals(len(res[0]["memberOf"]), 1)
1257 print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=cn=person,cn=schema,cn=configuration," + self.base_dn + "))"
1258 res2 = ldb.search(expression="(&(cn=ldaptestuser)(objectCategory=cn=person,cn=schema,cn=configuration," + self.base_dn + "))")
1259 self.assertEquals(len(res2), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=cn=person,cn=schema,cn=configuration," + self.base_dn + "))")
1261 self.assertEquals(res[0].dn, res2[0].dn)
1263 print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon))"
1264 res3 = ldb.search(expression="(&(cn=ldaptestuser)(objectCategory=PerSon))")
1265 self.assertEquals(len(res3), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=PerSon)): matched %d" % len(res3))
1267 self.assertEquals(res[0].dn, res3[0].dn)
1269 if gc_ldb is not None:
1270 print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon)) in Global Catalog"
1271 res3gc = gc_ldb.search(expression="(&(cn=ldaptestuser)(objectCategory=PerSon))")
1272 self.assertEquals(len(res3gc), 1)
1274 self.assertEquals(res[0].dn, res3gc[0].dn)
1276 print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon)) in with 'phantom root' control"
1278 res3control = gc_ldb.search(self.base_dn, expression="(&(cn=ldaptestuser)(objectCategory=PerSon))", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["search_options:1:2"])
1279 self.assertEquals(len(res3control), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=PerSon)) in Global Catalog")
1281 self.assertEquals(res[0].dn, res3control[0].dn)
1283 ldb.delete(res[0].dn)
1285 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectClass=user))"
1286 res = ldb.search(expression="(&(cn=ldaptestcomputer)(objectClass=user))")
1287 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser)(objectClass=user))")
1289 self.assertEquals(str(res[0].dn), ("CN=ldaptestcomputer,CN=Computers," + self.base_dn))
1290 self.assertEquals(str(res[0]["cn"]), "ldaptestcomputer")
1291 self.assertEquals(str(res[0]["name"]), "ldaptestcomputer")
1292 self.assertEquals(set(res[0]["objectClass"]), set(["top", "person", "organizationalPerson", "user", "computer"]))
1293 self.assertTrue("objectGUID" in res[0])
1294 self.assertTrue("whenCreated" in res[0])
1295 self.assertEquals(str(res[0]["objectCategory"]), ("CN=Computer,CN=Schema,CN=Configuration," + self.base_dn))
1296 self.assertEquals(int(res[0]["primaryGroupID"][0]), 513)
1297 self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_NORMAL_ACCOUNT)
1298 self.assertEquals(int(res[0]["userAccountControl"][0]), UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE)
1299 self.assertEquals(res[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
1300 self.assertEquals(len(res[0]["memberOf"]), 1)
1302 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + "))"
1303 res2 = ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + "))")
1304 self.assertEquals(len(res2), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + "))")
1306 self.assertEquals(res[0].dn, res2[0].dn)
1308 if gc_ldb is not None:
1309 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + ")) in Global Catlog"
1310 res2gc = gc_ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + "))")
1311 self.assertEquals(len(res2gc), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + ")) in Global Catlog")
1313 self.assertEquals(res[0].dn, res2gc[0].dn)
1315 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=compuTER))"
1316 res3 = ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=compuTER))")
1317 self.assertEquals(len(res3), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=compuTER))")
1319 self.assertEquals(res[0].dn, res3[0].dn)
1321 if gc_ldb is not None:
1322 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=compuTER)) in Global Catalog"
1323 res3gc = gc_ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=compuTER))")
1324 self.assertEquals(len(res3gc), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=compuTER)) in Global Catalog")
1326 self.assertEquals(res[0].dn, res3gc[0].dn)
1328 print "Testing ldb.search for (&(cn=ldaptestcomp*r)(objectCategory=compuTER))"
1329 res4 = ldb.search(expression="(&(cn=ldaptestcomp*r)(objectCategory=compuTER))")
1330 self.assertEquals(len(res4), 1, "Could not find (&(cn=ldaptestcomp*r)(objectCategory=compuTER))")
1332 self.assertEquals(res[0].dn, res4[0].dn)
1334 print "Testing ldb.search for (&(cn=ldaptestcomput*)(objectCategory=compuTER))"
1335 res5 = ldb.search(expression="(&(cn=ldaptestcomput*)(objectCategory=compuTER))")
1336 self.assertEquals(len(res5), 1, "Could not find (&(cn=ldaptestcomput*)(objectCategory=compuTER))")
1338 self.assertEquals(res[0].dn, res5[0].dn)
1340 print "Testing ldb.search for (&(cn=*daptestcomputer)(objectCategory=compuTER))"
1341 res6 = ldb.search(expression="(&(cn=*daptestcomputer)(objectCategory=compuTER))")
1342 self.assertEquals(len(res6), 1, "Could not find (&(cn=*daptestcomputer)(objectCategory=compuTER))")
1344 self.assertEquals(res[0].dn, res6[0].dn)
1346 ldb.delete("<GUID=" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + ">")
1348 print "Testing ldb.search for (&(cn=ldaptest2computer)(objectClass=user))"
1349 res = ldb.search(expression="(&(cn=ldaptest2computer)(objectClass=user))")
1350 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptest2computer)(objectClass=user))")
1352 self.assertEquals(str(res[0].dn), "CN=ldaptest2computer,CN=Computers," + self.base_dn)
1353 self.assertEquals(str(res[0]["cn"]), "ldaptest2computer")
1354 self.assertEquals(str(res[0]["name"]), "ldaptest2computer")
1355 self.assertEquals(list(res[0]["objectClass"]), ["top", "person", "organizationalPerson", "user", "computer"])
1356 self.assertTrue("objectGUID" in res[0])
1357 self.assertTrue("whenCreated" in res[0])
1358 self.assertEquals(res[0]["objectCategory"][0], "CN=Computer,CN=Schema,CN=Configuration," + self.base_dn)
1359 self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_WORKSTATION_TRUST)
1360 self.assertEquals(int(res[0]["userAccountControl"][0]), UF_WORKSTATION_TRUST_ACCOUNT)
1362 ldb.delete("<SID=" + ldb.schema_format_value("objectSID", res[0]["objectSID"][0]) + ">")
1364 attrs = ["cn", "name", "objectClass", "objectGUID", "objectSID", "whenCreated", "nTSecurityDescriptor", "memberOf", "allowedAttributes", "allowedAttributesEffective"]
1365 print "Testing ldb.search for (&(cn=ldaptestUSer2)(objectClass=user))"
1366 res_user = ldb.search(self.base_dn, expression="(&(cn=ldaptestUSer2)(objectClass=user))", scope=SCOPE_SUBTREE, attrs=attrs)
1367 self.assertEquals(len(res_user), 1, "Could not find (&(cn=ldaptestUSer2)(objectClass=user))")
1369 self.assertEquals(str(res_user[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
1370 self.assertEquals(str(res_user[0]["cn"]), "ldaptestuser2")
1371 self.assertEquals(str(res_user[0]["name"]), "ldaptestuser2")
1372 self.assertEquals(list(res_user[0]["objectClass"]), ["top", "person", "organizationalPerson", "user"])
1373 self.assertTrue("objectSid" in res_user[0])
1374 self.assertTrue("objectGUID" in res_user[0])
1375 self.assertTrue("whenCreated" in res_user[0])
1376 self.assertTrue("nTSecurityDescriptor" in res_user[0])
1377 self.assertTrue("allowedAttributes" in res_user[0])
1378 self.assertTrue("allowedAttributesEffective" in res_user[0])
1379 self.assertEquals(res_user[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
1381 ldaptestuser2_sid = res_user[0]["objectSid"][0]
1382 ldaptestuser2_guid = res_user[0]["objectGUID"][0]
1384 attrs = ["cn", "name", "objectClass", "objectGUID", "objectSID", "whenCreated", "nTSecurityDescriptor", "member", "allowedAttributes", "allowedAttributesEffective"]
1385 print "Testing ldb.search for (&(cn=ldaptestgroup2)(objectClass=group))"
1386 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs)
1387 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))")
1389 self.assertEquals(str(res[0].dn), ("CN=ldaptestgroup2,CN=Users," + self.base_dn))
1390 self.assertEquals(str(res[0]["cn"]), "ldaptestgroup2")
1391 self.assertEquals(str(res[0]["name"]), "ldaptestgroup2")
1392 self.assertEquals(list(res[0]["objectClass"]), ["top", "group"])
1393 self.assertTrue("objectGUID" in res[0])
1394 self.assertTrue("objectSid" in res[0])
1395 self.assertTrue("whenCreated" in res[0])
1396 self.assertTrue("nTSecurityDescriptor" in res[0])
1397 self.assertTrue("allowedAttributes" in res[0])
1398 self.assertTrue("allowedAttributesEffective" in res[0])
1400 for m in res[0]["member"]:
1401 memberUP.append(m.upper())
1402 self.assertTrue(("CN=ldaptestuser2,CN=Users," + self.base_dn).upper() in memberUP)
1404 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs, controls=["extended_dn:1:1"])
1405 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))")
1407 print res[0]["member"]
1409 for m in res[0]["member"]:
1410 memberUP.append(m.upper())
1411 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()
1413 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)
1415 print "Testing Linked attribute behaviours"
1417 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
1420 member: CN=ldaptestuser2,CN=Users,""" + self.base_dn + """
1421 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
1425 dn: <GUID=""" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + """>
1428 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
1432 dn: <SID=""" + ldb.schema_format_value("objectSid", res[0]["objectSid"][0]) + """>
1438 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
1441 member: <GUID=""" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + """>
1442 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
1446 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
1452 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
1455 member: <SID=""" + ldb.schema_format_value("objectSid", res_user[0]["objectSid"][0]) + """>
1456 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
1460 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
1463 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
1466 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs)
1467 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))")
1469 self.assertEquals(str(res[0].dn), ("CN=ldaptestgroup2,CN=Users," + self.base_dn))
1470 self.assertEquals(res[0]["member"][0], ("CN=ldaptestuser2,CN=Users," + self.base_dn))
1471 self.assertEquals(len(res[0]["member"]), 1)
1473 ldb.delete(("CN=ldaptestuser2,CN=Users," + self.base_dn))
1477 attrs = ["cn", "name", "objectClass", "objectGUID", "whenCreated", "nTSecurityDescriptor", "member"]
1478 print "Testing ldb.search for (&(cn=ldaptestgroup2)(objectClass=group)) to check linked delete"
1479 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs)
1480 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group)) to check linked delete")
1482 self.assertEquals(str(res[0].dn), ("CN=ldaptestgroup2,CN=Users," + self.base_dn))
1483 self.assertTrue("member" not in res[0])
1485 print "Testing ldb.search for (&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))"
1486 # TODO UTF8 users don't seem to work fully anymore
1487 # res = ldb.search(expression="(&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
1488 res = ldb.search(expression="(&(cn=ldaptestutf8user èùéìòà)(objectclass=user))")
1489 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
1491 self.assertEquals(str(res[0].dn), ("CN=ldaptestutf8user èùéìòà,CN=Users," + self.base_dn))
1492 self.assertEquals(str(res[0]["cn"]), "ldaptestutf8user èùéìòà")
1493 self.assertEquals(str(res[0]["name"]), "ldaptestutf8user èùéìòà")
1494 self.assertEquals(list(res[0]["objectClass"]), ["top", "person", "organizationalPerson", "user"])
1495 self.assertTrue("objectGUID" in res[0])
1496 self.assertTrue("whenCreated" in res[0])
1498 ldb.delete(res[0].dn)
1500 print "Testing ldb.search for (&(cn=ldaptestutf8user2*)(objectClass=user))"
1501 res = ldb.search(expression="(&(cn=ldaptestutf8user2*)(objectClass=user))")
1502 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestutf8user2*)(objectClass=user))")
1504 ldb.delete(res[0].dn)
1506 ldb.delete(("CN=ldaptestgroup2,CN=Users," + self.base_dn))
1508 print "Testing ldb.search for (&(cn=ldaptestutf8user2 ÈÙÉÌÒÀ)(objectClass=user))"
1509 # TODO UTF8 users don't seem to work fully anymore
1510 # res = ldb.search(expression="(&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
1511 # self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
1513 print "Testing that we can't get at the configuration DN from the main search base"
1514 res = ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
1515 self.assertEquals(len(res), 0)
1517 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"
1518 res = ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["search_options:1:2"])
1519 self.assertTrue(len(res) > 0)
1521 if gc_ldb is not None:
1522 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"
1524 res = gc_ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["search_options:1:0"])
1525 self.assertTrue(len(res) > 0)
1527 print "Testing that we do find configuration elements in the global catlog"
1528 res = gc_ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
1529 self.assertTrue(len(res) > 0)
1531 print "Testing that we do find configuration elements and user elements at the same time"
1532 res = gc_ldb.search(self.base_dn, expression="(|(objectClass=crossRef)(objectClass=person))", scope=SCOPE_SUBTREE, attrs=["cn"])
1533 self.assertTrue(len(res) > 0)
1535 print "Testing that we do find configuration elements in the global catlog, with the configuration basedn"
1536 res = gc_ldb.search(self.configuration_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
1537 self.assertTrue(len(res) > 0)
1539 print "Testing that we can get at the configuration DN on the main LDAP port"
1540 res = ldb.search(self.configuration_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
1541 self.assertTrue(len(res) > 0)
1543 print "Testing objectCategory canonacolisation"
1544 res = ldb.search(self.configuration_dn, expression="objectCategory=ntDsDSA", scope=SCOPE_SUBTREE, attrs=["cn"])
1545 self.assertTrue(len(res) > 0, "Didn't find any records with objectCategory=ntDsDSA")
1546 self.assertTrue(len(res) != 0)
1548 res = ldb.search(self.configuration_dn, expression="objectCategory=CN=ntDs-DSA," + self.schema_dn, scope=SCOPE_SUBTREE, attrs=["cn"])
1549 self.assertTrue(len(res) > 0, "Didn't find any records with objectCategory=CN=ntDs-DSA," + self.schema_dn)
1550 self.assertTrue(len(res) != 0)
1552 print "Testing objectClass attribute order on "+ self.base_dn
1553 res = ldb.search(expression="objectClass=domain", base=self.base_dn,
1554 scope=SCOPE_BASE, attrs=["objectClass"])
1555 self.assertEquals(len(res), 1)
1557 self.assertEquals(list(res[0]["objectClass"]), ["top", "domain", "domainDNS"])
1561 print "Testing ldb.search for objectCategory=person"
1562 res = ldb.search(self.base_dn, expression="objectCategory=person", scope=SCOPE_SUBTREE, attrs=["cn"])
1563 self.assertTrue(len(res) > 0)
1565 print "Testing ldb.search for objectCategory=person with domain scope control"
1566 res = ldb.search(self.base_dn, expression="objectCategory=person", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["domain_scope:1"])
1567 self.assertTrue(len(res) > 0)
1569 print "Testing ldb.search for objectCategory=user"
1570 res = ldb.search(self.base_dn, expression="objectCategory=user", scope=SCOPE_SUBTREE, attrs=["cn"])
1571 self.assertTrue(len(res) > 0)
1573 print "Testing ldb.search for objectCategory=user with domain scope control"
1574 res = ldb.search(self.base_dn, expression="objectCategory=user", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["domain_scope:1"])
1575 self.assertTrue(len(res) > 0)
1577 print "Testing ldb.search for objectCategory=group"
1578 res = ldb.search(self.base_dn, expression="objectCategory=group", scope=SCOPE_SUBTREE, attrs=["cn"])
1579 self.assertTrue(len(res) > 0)
1581 print "Testing ldb.search for objectCategory=group with domain scope control"
1582 res = ldb.search(self.base_dn, expression="objectCategory=group", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["domain_scope:1"])
1583 self.assertTrue(len(res) > 0)
1585 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1586 self.delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
1587 self.delete_force(self.ldb, "cn=ldaptestuser3,cn=users," + self.base_dn)
1588 self.delete_force(self.ldb, "cn=ldaptestuser4,cn=ldaptestcontainer," + self.base_dn)
1589 self.delete_force(self.ldb, "cn=ldaptestuser4,cn=ldaptestcontainer2," + self.base_dn)
1590 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1591 self.delete_force(self.ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
1592 self.delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
1593 self.delete_force(self.ldb, "cn=ldaptest2computer,cn=computers," + self.base_dn)
1594 self.delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
1595 self.delete_force(self.ldb, "cn=ldaptestutf8user èùéìòà,cn=users," + self.base_dn)
1596 self.delete_force(self.ldb, "cn=ldaptestutf8user2 èùéìòà,cn=users," + self.base_dn)
1597 self.delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
1598 self.delete_force(self.ldb, "cn=ldaptestcontainer2," + self.base_dn)
1600 def test_security_descriptor_add(self):
1601 """ Testing ldb.add_ldif() for nTSecurityDescriptor """
1602 user_name = "testdescriptoruser1"
1603 user_dn = "CN=%s,CN=Users,%s" % (user_name, self.base_dn)
1605 # Test add_ldif() with SDDL security descriptor input
1607 self.delete_force(self.ldb, user_dn)
1609 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
1610 self.ldb.add_ldif("""
1611 dn: """ + user_dn + """
1613 sAMAccountName: """ + user_name + """
1614 nTSecurityDescriptor: """ + sddl)
1615 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
1616 desc = res[0]["nTSecurityDescriptor"][0]
1617 desc = ndr_unpack( security.descriptor, desc )
1618 desc_sddl = desc.as_sddl( self.domain_sid )
1619 self.assertEqual(desc_sddl, sddl)
1621 self.delete_force(self.ldb, user_dn)
1623 # Test add_ldif() with BASE64 security descriptor
1626 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
1627 desc = security.descriptor.from_sddl(sddl, self.domain_sid)
1628 desc_binary = ndr_pack(desc)
1629 desc_base64 = base64.b64encode(desc_binary)
1630 self.ldb.add_ldif("""
1631 dn: """ + user_dn + """
1633 sAMAccountName: """ + user_name + """
1634 nTSecurityDescriptor:: """ + desc_base64)
1635 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
1636 desc = res[0]["nTSecurityDescriptor"][0]
1637 desc = ndr_unpack(security.descriptor, desc)
1638 desc_sddl = desc.as_sddl(self.domain_sid)
1639 self.assertEqual(desc_sddl, sddl)
1641 self.delete_force(self.ldb, user_dn)
1643 def test_security_descriptor_add_neg(self):
1644 """Test add_ldif() with BASE64 security descriptor input using WRONG domain SID
1647 user_name = "testdescriptoruser1"
1648 user_dn = "CN=%s,CN=Users,%s" % (user_name, self.base_dn)
1649 self.delete_force(self.ldb, user_dn)
1651 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
1652 desc = security.descriptor.from_sddl(sddl, security.dom_sid('S-1-5-21'))
1653 desc_base64 = base64.b64encode( ndr_pack(desc) )
1654 self.ldb.add_ldif("""
1655 dn: """ + user_dn + """
1657 sAMAccountName: """ + user_name + """
1658 nTSecurityDescriptor:: """ + desc_base64)
1659 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
1661 self.assertRaises(KeyError, lambda: res[0]["nTSecurityDescriptor"])
1663 self.delete_force(self.ldb, user_dn)
1665 def test_security_descriptor_modify(self):
1666 """ Testing ldb.modify_ldif() for nTSecurityDescriptor """
1667 user_name = "testdescriptoruser2"
1668 user_dn = "CN=%s,CN=Users,%s" % (user_name, self.base_dn)
1670 # Delete user object and test modify_ldif() with SDDL security descriptor input
1671 # Add ACE to the original descriptor test
1674 self.delete_force(self.ldb, user_dn)
1675 self.ldb.add_ldif("""
1676 dn: """ + user_dn + """
1678 sAMAccountName: """ + user_name)
1680 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
1681 desc = res[0]["nTSecurityDescriptor"][0]
1682 desc = ndr_unpack(security.descriptor, desc)
1683 desc_sddl = desc.as_sddl(self.domain_sid)
1684 sddl = desc_sddl[:desc_sddl.find("(")] + "(A;;RPWP;;;AU)" + desc_sddl[desc_sddl.find("("):]
1686 dn: """ + user_dn + """
1688 replace: nTSecurityDescriptor
1689 nTSecurityDescriptor: """ + sddl
1690 self.ldb.modify_ldif(mod)
1691 # Read modified descriptor
1692 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
1693 desc = res[0]["nTSecurityDescriptor"][0]
1694 desc = ndr_unpack(security.descriptor, desc)
1695 desc_sddl = desc.as_sddl(self.domain_sid)
1696 self.assertEqual(desc_sddl, sddl)
1698 self.delete_force(self.ldb, user_dn)
1700 # Test modify_ldif() with SDDL security descriptor input
1701 # New desctiptor test
1704 self.ldb.add_ldif("""
1705 dn: """ + user_dn + """
1707 sAMAccountName: """ + user_name)
1709 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
1711 dn: """ + user_dn + """
1713 replace: nTSecurityDescriptor
1714 nTSecurityDescriptor: """ + sddl
1715 self.ldb.modify_ldif(mod)
1716 # Read modified descriptor
1717 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
1718 desc = res[0]["nTSecurityDescriptor"][0]
1719 desc = ndr_unpack(security.descriptor, desc)
1720 desc_sddl = desc.as_sddl(self.domain_sid)
1721 self.assertEqual(desc_sddl, sddl)
1723 self.delete_force(self.ldb, user_dn)
1725 # Test modify_ldif() with BASE64 security descriptor input
1726 # Add ACE to the original descriptor test
1729 self.ldb.add_ldif("""
1730 dn: """ + user_dn + """
1732 sAMAccountName: """ + user_name)
1734 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
1735 desc = res[0]["nTSecurityDescriptor"][0]
1736 desc = ndr_unpack(security.descriptor, desc)
1737 desc_sddl = desc.as_sddl(self.domain_sid)
1738 sddl = desc_sddl[:desc_sddl.find("(")] + "(A;;RPWP;;;AU)" + desc_sddl[desc_sddl.find("("):]
1739 desc = security.descriptor.from_sddl(sddl, self.domain_sid)
1740 desc_base64 = base64.b64encode(ndr_pack(desc))
1742 dn: """ + user_dn + """
1744 replace: nTSecurityDescriptor
1745 nTSecurityDescriptor:: """ + desc_base64
1746 self.ldb.modify_ldif(mod)
1747 # Read modified descriptor
1748 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
1749 desc = res[0]["nTSecurityDescriptor"][0]
1750 desc = ndr_unpack(security.descriptor, desc)
1751 desc_sddl = desc.as_sddl(self.domain_sid)
1752 self.assertEqual(desc_sddl, sddl)
1754 self.delete_force(self.ldb, user_dn)
1756 # Test modify_ldif() with BASE64 security descriptor input
1757 # New descriptor test
1760 self.delete_force(self.ldb, user_dn)
1761 self.ldb.add_ldif("""
1762 dn: """ + user_dn + """
1764 sAMAccountName: """ + user_name)
1766 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
1767 desc = security.descriptor.from_sddl(sddl, self.domain_sid)
1768 desc_base64 = base64.b64encode(ndr_pack(desc))
1770 dn: """ + user_dn + """
1772 replace: nTSecurityDescriptor
1773 nTSecurityDescriptor:: """ + desc_base64
1774 self.ldb.modify_ldif(mod)
1775 # Read modified descriptor
1776 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
1777 desc = res[0]["nTSecurityDescriptor"][0]
1778 desc = ndr_unpack(security.descriptor, desc)
1779 desc_sddl = desc.as_sddl(self.domain_sid)
1780 self.assertEqual(desc_sddl, sddl)
1782 self.delete_force(self.ldb, user_dn)
1784 class BaseDnTests(unittest.TestCase):
1788 def test_rootdse_attrs(self):
1789 """Testing for all rootDSE attributes"""
1790 res = self.ldb.search(scope=SCOPE_BASE, attrs=[])
1791 self.assertEquals(len(res), 1)
1793 def test_highestcommittedusn(self):
1794 """Testing for highestCommittedUSN"""
1795 res = self.ldb.search("", scope=SCOPE_BASE, attrs=["highestCommittedUSN"])
1796 self.assertEquals(len(res), 1)
1797 self.assertTrue(int(res[0]["highestCommittedUSN"][0]) != 0)
1799 def test_netlogon(self):
1800 """Testing for netlogon via LDAP"""
1801 res = self.ldb.search("", scope=SCOPE_BASE, attrs=["netlogon"])
1802 self.assertEquals(len(res), 0)
1804 def test_netlogon_highestcommitted_usn(self):
1805 """Testing for netlogon and highestCommittedUSN via LDAP"""
1806 res = self.ldb.search("", scope=SCOPE_BASE,
1807 attrs=["netlogon", "highestCommittedUSN"])
1808 self.assertEquals(len(res), 0)
1810 class SchemaTests(unittest.TestCase):
1811 def delete_force(self, ldb, dn):
1814 except LdbError, (num, _):
1815 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
1817 def find_schemadn(self, ldb):
1818 res = ldb.search(base="", expression="", scope=SCOPE_BASE, attrs=["schemaNamingContext"])
1819 self.assertEquals(len(res), 1)
1820 return res[0]["schemaNamingContext"][0]
1822 def find_basedn(self, ldb):
1823 res = ldb.search(base="", expression="", scope=SCOPE_BASE,
1824 attrs=["defaultNamingContext"])
1825 self.assertEquals(len(res), 1)
1826 return res[0]["defaultNamingContext"][0]
1830 self.schema_dn = self.find_schemadn(ldb)
1831 self.base_dn = self.find_basedn(ldb)
1833 def test_generated_schema(self):
1834 """Testing we can read the generated schema via LDAP"""
1835 res = self.ldb.search("cn=aggregate,"+self.schema_dn, scope=SCOPE_BASE,
1836 attrs=["objectClasses", "attributeTypes", "dITContentRules"])
1837 self.assertEquals(len(res), 1)
1838 self.assertTrue("dITContentRules" in res[0])
1839 self.assertTrue("objectClasses" in res[0])
1840 self.assertTrue("attributeTypes" in res[0])
1842 def test_generated_schema_is_operational(self):
1843 """Testing we don't get the generated schema via LDAP by default"""
1844 res = self.ldb.search("cn=aggregate,"+self.schema_dn, scope=SCOPE_BASE,
1846 self.assertEquals(len(res), 1)
1847 self.assertFalse("dITContentRules" in res[0])
1848 self.assertFalse("objectClasses" in res[0])
1849 self.assertFalse("attributeTypes" in res[0])
1851 def test_schemaUpdateNow(self):
1852 """Testing schemaUpdateNow"""
1853 class_name = "test-class" + time.strftime("%s", time.gmtime())
1854 class_ldap_display_name = class_name.replace("-", "")
1855 object_name = "obj" + time.strftime("%s", time.gmtime())
1858 dn: CN=%s,%s""" % (class_name, self.schema_dn) + """
1859 lDAPDisplayName: """ + class_ldap_display_name + """
1861 objectClass: classSchema
1862 adminDescription: """ + class_name + """
1863 adminDisplayName: """ + class_name + """
1864 cn: """ + class_name + """
1865 objectCategory: CN=Class-Schema,""" + self.schema_dn + """
1866 defaultObjectCategory: CN=%s,%s""" % (class_name, self.schema_dn) + """
1867 distinguishedName: CN=%s,%s""" % (class_name, self.schema_dn) + """
1868 governsID: 1.2.840.""" + str(random.randint(1,100000)) + """.1.5.9939
1870 name: """ + class_name + """
1871 objectClassCategory: 1
1872 subClassOf: organizationalPerson
1875 systemMustContain: cn
1878 self.ldb.add_ldif(ldif)
1882 add: schemaUpdateNow
1885 self.ldb.modify_ldif(ldif)
1887 dn: CN=%s,CN=Users,%s"""% (object_name, self.base_dn) + """
1888 objectClass: organizationalPerson
1890 objectClass: """ + class_ldap_display_name + """
1892 cn: """ + object_name + """
1894 objectCategory: CN=%s,%s"""% (class_name, self.schema_dn) + """
1895 distinguishedName: CN=%s,CN=Users,%s"""% (object_name, self.base_dn) + """
1896 name: """ + object_name + """
1898 self.ldb.add_ldif(ldif)
1899 # Search for created objectClass
1901 res = self.ldb.search("cn=%s,%s" % (class_name, self.schema_dn), scope=SCOPE_BASE, attrs=["*"])
1902 self.assertNotEqual(res, [])
1905 res = self.ldb.search("cn=%s,cn=Users,%s" % (object_name, self.base_dn), scope=SCOPE_BASE, attrs=["*"])
1906 self.assertNotEqual(res, [])
1908 self.delete_force(self.ldb, "cn=%s,cn=Users,%s" % (object_name, self.base_dn))
1910 if not "://" in host:
1911 host = "ldap://%s" % host
1913 ldb = Ldb(host, credentials=creds, session_info=system_session(), lp=lp)
1914 gc_ldb = Ldb("%s:3268" % host, credentials=creds,
1915 session_info=system_session(), lp=lp)
1917 runner = SubunitTestRunner()
1919 if not runner.run(unittest.makeSuite(BaseDnTests)).wasSuccessful():
1921 if not runner.run(unittest.makeSuite(BasicTests)).wasSuccessful():
1923 if not runner.run(unittest.makeSuite(SchemaTests)).wasSuccessful():