2 # -*- coding: utf-8 -*-
3 # This is a port of the original in testprogs/ejs/ldap.js
11 sys.path.append("bin/python")
13 samba.ensure_external_module("subunit", "subunit/python")
14 samba.ensure_external_module("testtools", "testtools")
16 import samba.getopt as options
18 from samba.auth import system_session
19 from ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError
20 from ldb import ERR_NO_SUCH_OBJECT, ERR_ATTRIBUTE_OR_VALUE_EXISTS
21 from ldb import ERR_ENTRY_ALREADY_EXISTS, ERR_UNWILLING_TO_PERFORM
22 from ldb import ERR_NOT_ALLOWED_ON_NON_LEAF, ERR_OTHER, ERR_INVALID_DN_SYNTAX
23 from ldb import ERR_NO_SUCH_ATTRIBUTE
24 from ldb import ERR_OBJECT_CLASS_VIOLATION, ERR_NOT_ALLOWED_ON_RDN
25 from ldb import ERR_NAMING_VIOLATION, ERR_CONSTRAINT_VIOLATION
26 from ldb import ERR_UNDEFINED_ATTRIBUTE_TYPE
27 from ldb import Message, MessageElement, Dn
28 from ldb import FLAG_MOD_ADD, FLAG_MOD_REPLACE, FLAG_MOD_DELETE
30 from samba.dsdb import (UF_NORMAL_ACCOUNT, UF_INTERDOMAIN_TRUST_ACCOUNT,
31 UF_WORKSTATION_TRUST_ACCOUNT, UF_SERVER_TRUST_ACCOUNT,
32 UF_PASSWD_NOTREQD, UF_ACCOUNTDISABLE, ATYPE_NORMAL_ACCOUNT,
33 ATYPE_WORKSTATION_TRUST, SYSTEM_FLAG_DOMAIN_DISALLOW_MOVE)
34 from samba.dcerpc.security import (DOMAIN_RID_USERS, DOMAIN_RID_DOMAIN_MEMBERS,
37 from subunit.run import SubunitTestRunner
40 from samba.ndr import ndr_pack, ndr_unpack
41 from samba.dcerpc import security
43 parser = optparse.OptionParser("ldap [options] <host>")
44 sambaopts = options.SambaOptions(parser)
45 parser.add_option_group(sambaopts)
46 parser.add_option_group(options.VersionOptions(parser))
47 # use command line creds if available
48 credopts = options.CredentialsOptions(parser)
49 parser.add_option_group(credopts)
50 opts, args = parser.parse_args()
58 lp = sambaopts.get_loadparm()
59 creds = credopts.get_credentials(lp)
61 class BasicTests(unittest.TestCase):
63 def delete_force(self, ldb, dn):
66 except LdbError, (num, _):
67 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
69 def find_basedn(self, ldb):
70 res = ldb.search(base="", expression="", scope=SCOPE_BASE,
71 attrs=["defaultNamingContext"])
72 self.assertEquals(len(res), 1)
73 return res[0]["defaultNamingContext"][0]
75 def find_configurationdn(self, ldb):
76 res = ldb.search(base="", expression="", scope=SCOPE_BASE, attrs=["configurationNamingContext"])
77 self.assertEquals(len(res), 1)
78 return res[0]["configurationNamingContext"][0]
80 def find_schemadn(self, ldb):
81 res = ldb.search(base="", expression="", scope=SCOPE_BASE, attrs=["schemaNamingContext"])
82 self.assertEquals(len(res), 1)
83 return res[0]["schemaNamingContext"][0]
85 def find_domain_sid(self):
86 res = self.ldb.search(base=self.base_dn, expression="(objectClass=*)", scope=SCOPE_BASE)
87 return ndr_unpack( security.dom_sid,res[0]["objectSid"][0])
90 super(BasicTests, self).setUp()
93 self.base_dn = self.find_basedn(ldb)
94 self.configuration_dn = self.find_configurationdn(ldb)
95 self.schema_dn = self.find_schemadn(ldb)
96 self.domain_sid = self.find_domain_sid()
98 print "baseDN: %s\n" % self.base_dn
100 self.delete_force(self.ldb, "cn=posixuser,cn=users," + self.base_dn)
101 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
102 self.delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
103 self.delete_force(self.ldb, "cn=ldaptestuser3,cn=users," + self.base_dn)
104 self.delete_force(self.ldb, "cn=ldaptestuser4,cn=ldaptestcontainer," + self.base_dn)
105 self.delete_force(self.ldb, "cn=ldaptestuser4,cn=ldaptestcontainer2," + self.base_dn)
106 self.delete_force(self.ldb, "cn=ldaptestuser5,cn=users," + self.base_dn)
107 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
108 self.delete_force(self.ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
109 self.delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
110 self.delete_force(self.ldb, "cn=ldaptest2computer,cn=computers," + self.base_dn)
111 self.delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
112 self.delete_force(self.ldb, "cn=ldaptestutf8user èùéìòà,cn=users," + self.base_dn)
113 self.delete_force(self.ldb, "cn=ldaptestutf8user2 èùéìòà,cn=users," + self.base_dn)
114 self.delete_force(self.ldb, "cn=entry1,cn=ldaptestcontainer," + self.base_dn)
115 self.delete_force(self.ldb, "cn=entry2,cn=ldaptestcontainer," + self.base_dn)
116 self.delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
117 self.delete_force(self.ldb, "cn=ldaptestcontainer2," + self.base_dn)
118 self.delete_force(self.ldb, "cn=parentguidtest,cn=users," + self.base_dn)
119 self.delete_force(self.ldb, "cn=parentguidtest,cn=testotherusers," + self.base_dn)
120 self.delete_force(self.ldb, "cn=testotherusers," + self.base_dn)
121 self.delete_force(self.ldb, "cn=ldaptestobject," + self.base_dn)
122 self.delete_force(self.ldb, "description=xyz,cn=users," + self.base_dn)
123 self.delete_force(self.ldb, "ou=testou,cn=users," + self.base_dn)
124 self.delete_force(self.ldb, "cn=testsecret,cn=system," + self.base_dn)
126 def test_objectclasses(self):
127 """Test objectClass behaviour"""
128 print "Test objectClass behaviour"""
130 # We cannot create LSA-specific objects (oc "secret" or "trustedDomain")
133 "dn": "cn=testsecret,cn=system," + self.base_dn,
134 "objectClass": "secret" })
136 except LdbError, (num, _):
137 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
139 # Invalid objectclass specified
142 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
143 "objectClass": "X" })
145 except LdbError, (num, _):
146 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
148 # Invalid objectCategory specified
151 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
152 "objectClass": "person",
153 "objectCategory": self.base_dn })
155 except LdbError, (num, _):
156 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
158 # Multi-valued "systemFlags"
161 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
162 "objectClass": "person",
163 "systemFlags": ["0", str(SYSTEM_FLAG_DOMAIN_DISALLOW_MOVE)] })
165 except LdbError, (num, _):
166 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
168 # We cannot instanciate from an abstract objectclass
171 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
172 "objectClass": "connectionPoint" })
174 except LdbError, (num, _):
175 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
178 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
179 "objectClass": "person" })
181 # We can remove derivation classes of the structural objectclass
182 # but they're going to be readded afterwards
184 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
185 m["objectClass"] = MessageElement("top", FLAG_MOD_DELETE,
189 res = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
190 scope=SCOPE_BASE, attrs=["objectClass"])
191 self.assertTrue(len(res) == 1)
192 self.assertTrue("top" in res[0]["objectClass"])
194 # The top-most structural class cannot be deleted since there are
195 # attributes of it in use
197 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
198 m["objectClass"] = MessageElement("person", FLAG_MOD_DELETE,
203 except LdbError, (num, _):
204 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
206 # We cannot delete classes which weren't specified
208 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
209 m["objectClass"] = MessageElement("computer", FLAG_MOD_DELETE,
214 except LdbError, (num, _):
215 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
217 # An invalid class cannot be added
219 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
220 m["objectClass"] = MessageElement("X", FLAG_MOD_ADD,
225 except LdbError, (num, _):
226 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
228 # The top-most structural class cannot be changed by adding another
231 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
232 m["objectClass"] = MessageElement("user", FLAG_MOD_ADD,
237 except LdbError, (num, _):
238 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
240 # An already specified objectclass cannot be added another time
242 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
243 m["objectClass"] = MessageElement("person", FLAG_MOD_ADD,
248 except LdbError, (num, _):
249 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
251 # Auxiliary classes can always be added
253 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
254 m["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_ADD,
258 # It's only possible to replace with the same objectclass combination.
259 # So the replace action on "objectClass" attributes is really useless.
261 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
262 m["objectClass"] = MessageElement(["top", "person", "bootableDevice"],
263 FLAG_MOD_REPLACE, "objectClass")
267 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
268 m["objectClass"] = MessageElement(["person", "bootableDevice"],
269 FLAG_MOD_REPLACE, "objectClass")
273 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
274 m["objectClass"] = MessageElement(["top", "person", "bootableDevice",
275 "connectionPoint"], FLAG_MOD_REPLACE, "objectClass")
279 except LdbError, (num, _):
280 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
283 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
284 m["objectClass"] = MessageElement(["top", "computer"], FLAG_MOD_REPLACE,
289 except LdbError, (num, _):
290 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
292 # Classes can be removed unless attributes of them are used.
294 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
295 m["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_DELETE,
299 res = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
300 scope=SCOPE_BASE, attrs=["objectClass"])
301 self.assertTrue(len(res) == 1)
302 self.assertFalse("bootableDevice" in res[0]["objectClass"])
305 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
306 m["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_ADD,
310 # Add an attribute specific to the "bootableDevice" class
312 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
313 m["bootParameter"] = MessageElement("test", FLAG_MOD_ADD,
317 # Classes can be removed unless attributes of them are used. Now there
318 # exist such attributes on the entry.
320 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
321 m["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_DELETE,
326 except LdbError, (num, _):
327 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
329 # Remove the previously specified attribute
331 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
332 m["bootParameter"] = MessageElement("test", FLAG_MOD_DELETE,
336 # Classes can be removed unless attributes of them are used.
338 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
339 m["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_DELETE,
343 self.delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
345 def test_system_only(self):
346 """Test systemOnly objects"""
347 print "Test systemOnly objects"""
351 "dn": "cn=ldaptestobject," + self.base_dn,
352 "objectclass": "configuration"})
354 except LdbError, (num, _):
355 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
357 self.delete_force(self.ldb, "cn=ldaptestobject," + self.base_dn)
358 self.delete_force(self.ldb, "cn=testsecret,cn=system," + self.base_dn)
360 def test_invalid_parent(self):
361 """Test adding an object with invalid parent"""
362 print "Test adding an object with invalid parent"""
366 "dn": "cn=ldaptestgroup,cn=thisdoesnotexist123,"
368 "objectclass": "group"})
370 except LdbError, (num, _):
371 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
373 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=thisdoesnotexist123,"
378 "dn": "ou=testou,cn=users," + self.base_dn,
379 "objectclass": "organizationalUnit"})
381 except LdbError, (num, _):
382 self.assertEquals(num, ERR_NAMING_VIOLATION)
384 self.delete_force(self.ldb, "ou=testou,cn=users," + self.base_dn)
386 def test_invalid_attribute(self):
387 """Test invalid attributes on schema/objectclasses"""
388 print "Test invalid attributes on schema/objectclasses"""
390 # attributes not in schema test
396 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
397 "objectclass": "group",
398 "thisdoesnotexist": "x"})
400 except LdbError, (num, _):
401 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
404 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
405 "objectclass": "group"})
410 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
411 m["thisdoesnotexist"] = MessageElement("x", FLAG_MOD_REPLACE,
416 except LdbError, (num, _):
417 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
419 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
421 # attributes not in objectclasses and mandatory attributes missing test
422 # Use here a non-SAM entry since it doesn't have special triggers
423 # associated which have an impact on the error results.
427 # mandatory attribute missing
430 "dn": "cn=ldaptestobject," + self.base_dn,
431 "objectclass": "ipProtocol"})
433 except LdbError, (num, _):
434 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
436 # inadequate but schema-valid attribute specified
439 "dn": "cn=ldaptestobject," + self.base_dn,
440 "objectclass": "ipProtocol",
441 "ipProtocolNumber": "1",
444 except LdbError, (num, _):
445 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
448 "dn": "cn=ldaptestobject," + self.base_dn,
449 "objectclass": "ipProtocol",
450 "ipProtocolNumber": "1"})
454 # inadequate but schema-valid attribute add trial
456 m.dn = Dn(ldb, "cn=ldaptestobject," + self.base_dn)
457 m["uid"] = MessageElement("0", FLAG_MOD_ADD, "uid")
461 except LdbError, (num, _):
462 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
464 # mandatory attribute delete trial
466 m.dn = Dn(ldb, "cn=ldaptestobject," + self.base_dn)
467 m["ipProtocolNumber"] = MessageElement([], FLAG_MOD_DELETE,
472 except LdbError, (num, _):
473 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
475 # mandatory attribute delete trial
477 m.dn = Dn(ldb, "cn=ldaptestobject," + self.base_dn)
478 m["ipProtocolNumber"] = MessageElement([], FLAG_MOD_REPLACE,
483 except LdbError, (num, _):
484 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
486 self.delete_force(self.ldb, "cn=ldaptestobject," + self.base_dn)
488 def test_single_valued_attributes(self):
489 """Test single-valued attributes"""
490 print "Test single-valued attributes"""
494 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
495 "objectclass": "group",
496 "sAMAccountName": ["nam1", "nam2"]})
498 except LdbError, (num, _):
499 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
502 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
503 "objectclass": "group"})
506 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
507 m["sAMAccountName"] = MessageElement(["nam1","nam2"], FLAG_MOD_REPLACE,
512 except LdbError, (num, _):
513 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
516 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
517 m["sAMAccountName"] = MessageElement("testgroupXX", FLAG_MOD_REPLACE,
522 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
523 m["sAMAccountName"] = MessageElement("testgroupXX2", FLAG_MOD_ADD,
528 except LdbError, (num, _):
529 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
531 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
533 def test_multi_valued_attributes(self):
534 """Test multi-valued attributes"""
535 print "Test multi-valued attributes"""
537 # TODO: In this test I added some special tests where I got very unusual
538 # results back from a real AD. s4 doesn't match them and I've no idea how to
539 # implement those error cases (maybe there exists a special trigger for
540 # "description" attributes which handle them)
543 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
544 "description": "desc2",
545 "objectclass": "group",
546 "description": "desc1"})
548 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
551 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
552 "objectclass": "group",
553 "description": ["desc1", "desc2"]})
556 # m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
557 # m["description"] = MessageElement(["desc1","desc2"], FLAG_MOD_REPLACE,
562 # except LdbError, (num, _):
563 # self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
566 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
567 m["description"] = MessageElement("desc1", FLAG_MOD_REPLACE,
572 # m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
573 # m["description"] = MessageElement("desc3", FLAG_MOD_ADD,
578 # except LdbError, (num, _):
579 # self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
582 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
583 m["description"] = MessageElement(["desc1","desc2"], FLAG_MOD_DELETE,
588 except LdbError, (num, _):
589 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
592 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
593 m["description"] = MessageElement("desc1", FLAG_MOD_DELETE,
598 # m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
599 # m["description"] = MessageElement(["desc1","desc2"], FLAG_MOD_REPLACE,
604 # except LdbError, (num, _):
605 # self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
608 # m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
609 # m["description"] = MessageElement(["desc3", "desc4"], FLAG_MOD_ADD,
614 # except LdbError, (num, _):
615 # self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
618 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
619 m["description"] = MessageElement("desc3", FLAG_MOD_ADD,
623 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
625 def test_empty_messages(self):
626 """Test empty messages"""
627 print "Test empty messages"""
630 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
635 except LdbError, (num, _):
636 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
641 except LdbError, (num, _):
642 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
644 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
646 def test_empty_attributes(self):
647 """Test empty attributes"""
648 print "Test empty attributes"""
651 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
652 m["objectClass"] = MessageElement("group", FLAG_MOD_ADD, "objectClass")
653 m["description"] = MessageElement([], FLAG_MOD_ADD, "description")
658 except LdbError, (num, _):
659 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
662 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
663 "objectclass": "group"})
666 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
667 m["description"] = MessageElement([], FLAG_MOD_ADD, "description")
672 except LdbError, (num, _):
673 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
676 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
677 m["description"] = MessageElement([], FLAG_MOD_REPLACE, "description")
681 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
682 m["description"] = MessageElement([], FLAG_MOD_DELETE, "description")
686 except LdbError, (num, _):
687 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
689 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
691 def test_instanceType(self):
692 """Tests the 'instanceType' attribute"""
693 print "Tests the 'instanceType' attribute"""
695 # The instance type is single-valued
698 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
699 "objectclass": "group",
700 "instanceType": ["0", "1"]})
702 except LdbError, (num, _):
703 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
705 # The head NC flag cannot be set without the write flag
708 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
709 "objectclass": "group",
710 "instanceType": "1" })
712 except LdbError, (num, _):
713 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
715 # We cannot manipulate NCs without the head NC flag
718 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
719 "objectclass": "group",
720 "instanceType": "32" })
722 except LdbError, (num, _):
723 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
726 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
727 "objectclass": "group"})
730 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
731 m["instanceType"] = MessageElement("0", FLAG_MOD_REPLACE,
736 except LdbError, (num, _):
737 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
740 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
741 m["instanceType"] = MessageElement([], FLAG_MOD_REPLACE,
746 except LdbError, (num, _):
747 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
750 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
751 m["instanceType"] = MessageElement([], FLAG_MOD_DELETE, "instanceType")
755 except LdbError, (num, _):
756 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
758 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
760 def test_distinguished_name(self):
761 """Tests the 'distinguishedName' attribute"""
762 print "Tests the 'distinguishedName' attribute"""
764 # a wrong "distinguishedName" attribute is obviously tolerated
766 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
767 "objectclass": "group",
768 "distinguishedName": "cn=ldaptest,cn=users," + self.base_dn})
770 # proof if the DN has been set correctly
771 res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
772 scope=SCOPE_BASE, attrs=["distinguishedName"])
773 self.assertTrue(len(res) == 1)
774 self.assertTrue("distinguishedName" in res[0])
775 self.assertTrue(Dn(ldb, res[0]["distinguishedName"][0])
776 == Dn(ldb, "cn=ldaptestgroup, cn=users," + self.base_dn))
779 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
780 m["distinguishedName"] = MessageElement(
781 "cn=ldaptestuser,cn=users," + self.base_dn, FLAG_MOD_ADD,
787 except LdbError, (num, _):
788 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
791 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
792 m["distinguishedName"] = MessageElement(
793 "cn=ldaptestuser,cn=users," + self.base_dn, FLAG_MOD_REPLACE,
799 except LdbError, (num, _):
800 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
803 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
804 m["distinguishedName"] = MessageElement(
805 "cn=ldaptestuser,cn=users," + self.base_dn, FLAG_MOD_DELETE,
811 except LdbError, (num, _):
812 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
814 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
816 def test_rdn_name(self):
818 print "Tests the RDN"""
822 "dn": "description=xyz,cn=users," + self.base_dn,
823 "objectclass": "group"})
825 except LdbError, (num, _):
826 self.assertEquals(num, ERR_NAMING_VIOLATION)
828 self.delete_force(self.ldb, "description=xyz,cn=users," + self.base_dn)
830 # a wrong "name" attribute is obviously tolerated
832 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
833 "objectclass": "group",
834 "name": "ldaptestgroupx"})
836 # proof if the name has been set correctly
837 res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
838 scope=SCOPE_BASE, attrs=["name"])
839 self.assertTrue(len(res) == 1)
840 self.assertTrue("name" in res[0])
841 self.assertTrue(res[0]["name"][0] == "ldaptestgroup")
844 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
845 m["name"] = MessageElement("cn=ldaptestuser", FLAG_MOD_REPLACE,
850 except LdbError, (num, _):
851 self.assertEquals(num, ERR_NOT_ALLOWED_ON_RDN)
854 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
855 m["cn"] = MessageElement("ldaptestuser",
856 FLAG_MOD_REPLACE, "cn")
860 except LdbError, (num, _):
861 self.assertEquals(num, ERR_NOT_ALLOWED_ON_RDN)
863 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
866 # this test needs to be disabled until we really understand
867 # what the rDN length constraints are
868 def DISABLED_test_largeRDN(self):
869 """Testing large rDN (limit 64 characters)"""
870 rdn = "CN=a012345678901234567890123456789012345678901234567890123456789012";
871 self.delete_force(self.ldb, "%s,%s" % (rdn, self.base_dn))
873 dn: %s,%s""" % (rdn,self.base_dn) + """
874 objectClass: container
876 self.ldb.add_ldif(ldif)
877 self.delete_force(self.ldb, "%s,%s" % (rdn, self.base_dn))
879 rdn = "CN=a0123456789012345678901234567890123456789012345678901234567890120";
880 self.delete_force(self.ldb, "%s,%s" % (rdn, self.base_dn))
883 dn: %s,%s""" % (rdn,self.base_dn) + """
884 objectClass: container
886 self.ldb.add_ldif(ldif)
888 except LdbError, (num, _):
889 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
890 self.delete_force(self.ldb, "%s,%s" % (rdn, self.base_dn))
892 def test_rename(self):
893 """Tests the rename operation"""
894 print "Tests the rename operations"""
897 # cannot rename to be a child of itself
898 ldb.rename(self.base_dn, "dc=test," + self.base_dn)
900 except LdbError, (num, _):
901 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
905 ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser2,cn=users," + self.base_dn)
907 except LdbError, (num, _):
908 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
911 "dn": "cn=ldaptestuser2,cn=users," + self.base_dn,
912 "objectclass": ["user", "person"] })
914 ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser2,cn=users," + self.base_dn)
915 ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=users," + self.base_dn)
916 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestUSER3,cn=users," + self.base_dn)
919 # containment problem: a user entry cannot contain user entries
920 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser4,cn=ldaptestuser3,cn=users," + self.base_dn)
922 except LdbError, (num, _):
923 self.assertEquals(num, ERR_NAMING_VIOLATION)
927 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=people,cn=users," + self.base_dn)
929 except LdbError, (num, _):
930 self.assertEquals(num, ERR_OTHER)
933 # invalid target DN syntax
934 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, ",cn=users," + self.base_dn)
936 except LdbError, (num, _):
937 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
941 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "ou=ldaptestuser3,cn=users," + self.base_dn)
943 except LdbError, (num, _):
944 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
946 self.delete_force(self.ldb, "cn=ldaptestuser3,cn=users," + self.base_dn)
948 # Performs some "systemFlags" testing
950 # Move failing since no "SYSTEM_FLAG_CONFIG_ALLOW_MOVE"
952 ldb.rename("CN=DisplaySpecifiers," + self.configuration_dn, "CN=DisplaySpecifiers,CN=Services," + self.configuration_dn)
954 except LdbError, (num, _):
955 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
957 # Limited move failing since no "SYSTEM_FLAG_CONFIG_ALLOW_LIMITED_MOVE"
959 ldb.rename("CN=Directory Service,CN=Windows NT,CN=Services," + self.configuration_dn, "CN=Directory Service,CN=RRAS,CN=Services," + self.configuration_dn)
961 except LdbError, (num, _):
962 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
964 # Rename failing since no "SYSTEM_FLAG_CONFIG_ALLOW_RENAME"
966 ldb.rename("CN=DisplaySpecifiers," + self.configuration_dn, "CN=DisplaySpecifiers2," + self.configuration_dn)
968 except LdbError, (num, _):
969 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
971 # It's not really possible to test moves on the schema partition since
972 # there don't exist subcontainers on it.
974 # Rename failing since "SYSTEM_FLAG_SCHEMA_BASE_OBJECT"
976 ldb.rename("CN=Top," + self.schema_dn, "CN=Top2," + self.schema_dn)
978 except LdbError, (num, _):
979 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
981 # Move failing since "SYSTEM_FLAG_DOMAIN_DISALLOW_MOVE"
983 ldb.rename("CN=Users," + self.base_dn, "CN=Users,CN=Computers," + self.base_dn)
985 except LdbError, (num, _):
986 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
988 # Rename failing since "SYSTEM_FLAG_DOMAIN_DISALLOW_RENAME"
990 ldb.rename("CN=Users," + self.base_dn, "CN=Users2," + self.base_dn)
992 except LdbError, (num, _):
993 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
995 # Performs some other constraints testing
998 ldb.rename("CN=Policies,CN=System," + self.base_dn, "CN=Users2," + self.base_dn)
1000 except LdbError, (num, _):
1001 self.assertEquals(num, ERR_OTHER)
1003 def test_rename_twice(self):
1004 """Tests the rename operation twice - this corresponds to a past bug"""
1005 print "Tests the rename twice operation"""
1008 "dn": "cn=ldaptestuser5,cn=users," + self.base_dn,
1009 "objectclass": ["user", "person"] })
1011 ldb.rename("cn=ldaptestuser5,cn=users," + self.base_dn, "cn=ldaptestUSER5,cn=users," + self.base_dn)
1012 self.delete_force(self.ldb, "cn=ldaptestuser5,cn=users," + self.base_dn)
1014 "dn": "cn=ldaptestuser5,cn=users," + self.base_dn,
1015 "objectclass": ["user", "person"] })
1016 ldb.rename("cn=ldaptestuser5,cn=Users," + self.base_dn, "cn=ldaptestUSER5,cn=users," + self.base_dn)
1017 res = ldb.search(expression="cn=ldaptestuser5")
1018 print "Found %u records" % len(res)
1019 self.assertEquals(len(res), 1, "Wrong number of hits for cn=ldaptestuser5")
1020 res = ldb.search(expression="(&(cn=ldaptestuser5)(objectclass=user))")
1021 print "Found %u records" % len(res)
1022 self.assertEquals(len(res), 1, "Wrong number of hits for (&(cn=ldaptestuser5)(objectclass=user))")
1023 self.delete_force(self.ldb, "cn=ldaptestuser5,cn=users," + self.base_dn)
1025 def test_parentGUID(self):
1026 """Test parentGUID behaviour"""
1027 print "Testing parentGUID behaviour\n"
1029 # TODO: This seems to fail on Windows Server. Hidden attribute?
1032 "dn": "cn=parentguidtest,cn=users," + self.base_dn,
1033 "objectclass":"user",
1034 "samaccountname":"parentguidtest"});
1035 res1 = ldb.search(base="cn=parentguidtest,cn=users," + self.base_dn, scope=SCOPE_BASE,
1036 attrs=["parentGUID", "samaccountname"]);
1037 res2 = ldb.search(base="cn=users," + self.base_dn,scope=SCOPE_BASE,
1038 attrs=["objectGUID"]);
1039 res3 = ldb.search(base=self.base_dn, scope=SCOPE_BASE,
1040 attrs=["parentGUID"]);
1041 res4 = ldb.search(base=self.configuration_dn, scope=SCOPE_BASE,
1042 attrs=["parentGUID"]);
1043 res5 = ldb.search(base=self.schema_dn, scope=SCOPE_BASE,
1044 attrs=["parentGUID"]);
1046 """Check if the parentGUID is valid """
1047 self.assertEquals(res1[0]["parentGUID"], res2[0]["objectGUID"]);
1049 """Check if it returns nothing when there is no parent object - default NC"""
1050 has_parentGUID = False
1051 for key in res3[0].keys():
1052 if key == "parentGUID":
1053 has_parentGUID = True
1055 self.assertFalse(has_parentGUID);
1057 """Check if it returns nothing when there is no parent object - configuration NC"""
1058 has_parentGUID = False
1059 for key in res4[0].keys():
1060 if key == "parentGUID":
1061 has_parentGUID = True
1063 self.assertFalse(has_parentGUID);
1065 """Check if it returns nothing when there is no parent object - schema NC"""
1066 has_parentGUID = False
1067 for key in res5[0].keys():
1068 if key == "parentGUID":
1069 has_parentGUID = True
1071 self.assertFalse(has_parentGUID);
1073 """Ensures that if you look for another object attribute after the constructed
1074 parentGUID, it will return correctly"""
1075 has_another_attribute = False
1076 for key in res1[0].keys():
1077 if key == "sAMAccountName":
1078 has_another_attribute = True
1080 self.assertTrue(has_another_attribute)
1081 self.assertTrue(len(res1[0]["samaccountname"]) == 1)
1082 self.assertEquals(res1[0]["samaccountname"][0], "parentguidtest");
1084 print "Testing parentGUID behaviour on rename\n"
1087 "dn": "cn=testotherusers," + self.base_dn,
1088 "objectclass":"container"});
1089 res1 = ldb.search(base="cn=testotherusers," + self.base_dn,scope=SCOPE_BASE,
1090 attrs=["objectGUID"]);
1091 ldb.rename("cn=parentguidtest,cn=users," + self.base_dn,
1092 "cn=parentguidtest,cn=testotherusers," + self.base_dn);
1093 res2 = ldb.search(base="cn=parentguidtest,cn=testotherusers," + self.base_dn,
1095 attrs=["parentGUID"]);
1096 self.assertEquals(res1[0]["objectGUID"], res2[0]["parentGUID"]);
1098 self.delete_force(self.ldb, "cn=parentguidtest,cn=testotherusers," + self.base_dn)
1099 self.delete_force(self.ldb, "cn=testotherusers," + self.base_dn)
1101 def test_groupType_int32(self):
1102 """Test groupType (int32) behaviour (should appear to be casted to a 32 bit signed integer before comparsion)"""
1103 print "Testing groupType (int32) behaviour\n"
1105 res1 = ldb.search(base=self.base_dn, scope=SCOPE_SUBTREE,
1106 attrs=["groupType"], expression="groupType=2147483653");
1108 res2 = ldb.search(base=self.base_dn, scope=SCOPE_SUBTREE,
1109 attrs=["groupType"], expression="groupType=-2147483643");
1111 self.assertEquals(len(res1), len(res2))
1113 self.assertTrue(res1.count > 0)
1115 self.assertEquals(res1[0]["groupType"][0], "-2147483643")
1117 def test_linked_attributes(self):
1118 """This tests the linked attribute behaviour"""
1119 print "Testing linked attribute behaviour\n"
1122 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
1123 "objectclass": "group"})
1125 # This should not work since "memberOf" is linked to "member"
1128 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1129 "objectclass": ["user", "person"],
1130 "memberOf": "cn=ldaptestgroup,cn=users," + self.base_dn})
1131 except LdbError, (num, _):
1132 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1135 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1136 "objectclass": ["user", "person"]})
1139 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1140 m["memberOf"] = MessageElement("cn=ldaptestgroup,cn=users," + self.base_dn,
1141 FLAG_MOD_ADD, "memberOf")
1145 except LdbError, (num, _):
1146 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1149 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1150 m["member"] = MessageElement("cn=ldaptestuser,cn=users," + self.base_dn,
1151 FLAG_MOD_ADD, "member")
1155 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1156 m["memberOf"] = MessageElement("cn=ldaptestgroup,cn=users," + self.base_dn,
1157 FLAG_MOD_REPLACE, "memberOf")
1161 except LdbError, (num, _):
1162 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1165 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1166 m["memberOf"] = MessageElement("cn=ldaptestgroup,cn=users," + self.base_dn,
1167 FLAG_MOD_DELETE, "memberOf")
1171 except LdbError, (num, _):
1172 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1175 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1176 m["member"] = MessageElement("cn=ldaptestuser,cn=users," + self.base_dn,
1177 FLAG_MOD_DELETE, "member")
1180 # This should yield no results since the member attribute for
1181 # "ldaptestuser" should have been deleted
1182 res1 = ldb.search("cn=ldaptestgroup, cn=users," + self.base_dn,
1184 expression="(member=cn=ldaptestuser,cn=users," + self.base_dn + ")",
1186 self.assertTrue(len(res1) == 0)
1188 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1191 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
1192 "objectclass": "group",
1193 "member": "cn=ldaptestuser,cn=users," + self.base_dn})
1195 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1197 # Make sure that the "member" attribute for "ldaptestuser" has been
1199 res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
1200 scope=SCOPE_BASE, attrs=["member"])
1201 self.assertTrue(len(res) == 1)
1202 self.assertFalse("member" in res[0])
1204 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1206 def test_groups(self):
1207 """This tests the group behaviour (setting, changing) of a user account"""
1208 print "Testing group behaviour\n"
1211 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
1212 "objectclass": "group"})
1215 "dn": "cn=ldaptestgroup2,cn=users," + self.base_dn,
1216 "objectclass": "group"})
1218 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
1219 scope=SCOPE_BASE, attrs=["objectSID"])
1220 self.assertTrue(len(res1) == 1)
1221 group_rid_1 = security.dom_sid(ldb.schema_format_value("objectSID",
1222 res1[0]["objectSID"][0])).split()[1]
1224 res1 = ldb.search("cn=ldaptestgroup2,cn=users," + self.base_dn,
1225 scope=SCOPE_BASE, attrs=["objectSID"])
1226 self.assertTrue(len(res1) == 1)
1227 group_rid_2 = security.dom_sid(ldb.schema_format_value("objectSID",
1228 res1[0]["objectSID"][0])).split()[1]
1230 # Try to create a user with an invalid primary group
1233 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1234 "objectclass": ["user", "person"],
1235 "primaryGroupID": "0"})
1237 except LdbError, (num, _):
1238 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1239 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1241 # Try to Create a user with a valid primary group
1242 # TODO Some more investigation needed here
1245 # "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1246 # "objectclass": ["user", "person"],
1247 # "primaryGroupID": str(group_rid_1)})
1249 # except LdbError, (num, _):
1250 # self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1251 # self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1253 # Test to see how we should behave when the user account doesn't
1256 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1257 m["primaryGroupID"] = MessageElement("0", FLAG_MOD_REPLACE,
1262 except LdbError, (num, _):
1263 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
1265 # Test to see how we should behave when the account isn't a user
1267 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1268 m["primaryGroupID"] = MessageElement("0", FLAG_MOD_REPLACE,
1273 except LdbError, (num, _):
1274 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
1276 # Test default primary groups
1279 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1280 "objectclass": ["user", "person"]})
1282 res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
1283 scope=SCOPE_BASE, attrs=["primaryGroupID"])
1284 self.assertTrue(len(res1) == 1)
1285 self.assertEquals(res1[0]["primaryGroupID"][0], str(DOMAIN_RID_USERS))
1287 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1290 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1291 "objectclass": ["user", "person"],
1292 "userAccountControl": str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD) })
1294 res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
1295 scope=SCOPE_BASE, attrs=["primaryGroupID"])
1296 self.assertTrue(len(res1) == 1)
1297 self.assertEquals(res1[0]["primaryGroupID"][0], str(DOMAIN_RID_USERS))
1299 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1301 # unfortunately the INTERDOMAIN_TRUST_ACCOUNT case cannot be tested
1302 # since such accounts aren't directly creatable (ACCESS_DENIED)
1305 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1306 "objectclass": ["computer"],
1307 "userAccountControl": str(UF_SERVER_TRUST_ACCOUNT | UF_PASSWD_NOTREQD) })
1309 res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
1310 scope=SCOPE_BASE, attrs=["primaryGroupID"])
1311 self.assertTrue(len(res1) == 1)
1312 self.assertEquals(res1[0]["primaryGroupID"][0], str(DOMAIN_RID_DCS))
1314 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1316 # Recreate account for further tests
1319 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1320 "objectclass": ["user", "person"]})
1322 # We should be able to reset our actual primary group
1324 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1325 m["primaryGroupID"] = MessageElement(str(DOMAIN_RID_USERS), FLAG_MOD_REPLACE,
1329 # Try to add invalid primary group
1331 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1332 m["primaryGroupID"] = MessageElement("0", FLAG_MOD_REPLACE,
1337 except LdbError, (num, _):
1338 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1340 # Try to make group 1 primary - should be denied since it is not yet
1343 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1344 m["primaryGroupID"] = MessageElement(str(group_rid_1),
1345 FLAG_MOD_REPLACE, "primaryGroupID")
1349 except LdbError, (num, _):
1350 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1352 # Make group 1 secondary
1354 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1355 m["member"] = MessageElement("cn=ldaptestuser,cn=users," + self.base_dn,
1356 FLAG_MOD_REPLACE, "member")
1359 # Make group 1 primary
1361 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1362 m["primaryGroupID"] = MessageElement(str(group_rid_1),
1363 FLAG_MOD_REPLACE, "primaryGroupID")
1366 # Try to delete group 1 - should be denied
1368 ldb.delete("cn=ldaptestgroup,cn=users," + self.base_dn)
1370 except LdbError, (num, _):
1371 self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
1373 # Try to add group 1 also as secondary - should be denied
1375 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1376 m["member"] = MessageElement("cn=ldaptestuser,cn=users," + self.base_dn,
1377 FLAG_MOD_ADD, "member")
1381 except LdbError, (num, _):
1382 self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
1384 # Try to add invalid member to group 1 - should be denied
1386 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1387 m["member"] = MessageElement(
1388 "cn=ldaptestuser3,cn=users," + self.base_dn,
1389 FLAG_MOD_ADD, "member")
1393 except LdbError, (num, _):
1394 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
1396 # Make group 2 secondary
1398 m.dn = Dn(ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
1399 m["member"] = MessageElement("cn=ldaptestuser,cn=users," + self.base_dn,
1400 FLAG_MOD_ADD, "member")
1405 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1406 m["primaryGroupID"] = MessageElement(str(group_rid_2),
1407 FLAG_MOD_REPLACE, "primaryGroupID")
1410 # Old primary group should contain a "member" attribute for the user,
1411 # the new shouldn't contain anymore one
1412 res1 = ldb.search("cn=ldaptestgroup, cn=users," + self.base_dn,
1413 scope=SCOPE_BASE, attrs=["member"])
1414 self.assertTrue(len(res1) == 1)
1415 self.assertTrue(len(res1[0]["member"]) == 1)
1416 self.assertEquals(res1[0]["member"][0].lower(),
1417 ("cn=ldaptestuser,cn=users," + self.base_dn).lower())
1419 res1 = ldb.search("cn=ldaptestgroup2, cn=users," + self.base_dn,
1420 scope=SCOPE_BASE, attrs=["member"])
1421 self.assertTrue(len(res1) == 1)
1422 self.assertFalse("member" in res1[0])
1424 # Also this should be denied
1427 "dn": "cn=ldaptestuser1,cn=users," + self.base_dn,
1428 "objectclass": ["user", "person"],
1429 "primaryGroupID": "0"})
1431 except LdbError, (num, _):
1432 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1434 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1435 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1436 self.delete_force(self.ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
1438 def test_sam_attributes(self):
1439 """Test the behaviour of special attributes of SAM objects"""
1440 print "Testing the behaviour of special attributes of SAM objects\n"""
1443 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1444 "objectclass": ["user", "person"]})
1446 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
1447 "objectclass": "group"})
1450 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1451 m["groupType"] = MessageElement("0", FLAG_MOD_ADD,
1456 except LdbError, (num, _):
1457 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
1460 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1461 m["groupType"] = MessageElement([], FLAG_MOD_DELETE,
1466 except LdbError, (num, _):
1467 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1470 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1471 m["primaryGroupID"] = MessageElement("0", FLAG_MOD_ADD,
1476 except LdbError, (num, _):
1477 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
1480 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1481 m["primaryGroupID"] = MessageElement([], FLAG_MOD_DELETE,
1486 except LdbError, (num, _):
1487 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1490 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1491 m["userAccountControl"] = MessageElement("0", FLAG_MOD_ADD,
1492 "userAccountControl")
1496 except LdbError, (num, _):
1497 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
1500 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1501 m["userAccountControl"] = MessageElement([], FLAG_MOD_DELETE,
1502 "userAccountControl")
1506 except LdbError, (num, _):
1507 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1510 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1511 m["sAMAccountType"] = MessageElement("0", FLAG_MOD_ADD,
1516 except LdbError, (num, _):
1517 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1520 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1521 m["sAMAccountType"] = MessageElement([], FLAG_MOD_REPLACE,
1526 except LdbError, (num, _):
1527 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1530 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1531 m["sAMAccountType"] = MessageElement([], FLAG_MOD_DELETE,
1536 except LdbError, (num, _):
1537 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1539 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1540 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1542 def test_primary_group_token_constructed(self):
1543 """Test the primary group token behaviour (hidden-generated-readonly attribute on groups) and some other constructed attributes"""
1544 print "Testing primary group token behaviour and other constructed attributes\n"
1548 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
1549 "objectclass": "group",
1550 "primaryGroupToken": "100"})
1552 except LdbError, (num, _):
1553 self.assertEquals(num, ERR_UNDEFINED_ATTRIBUTE_TYPE)
1554 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1557 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1558 "objectclass": ["user", "person"]})
1561 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
1562 "objectclass": "group"})
1564 # Testing for one invalid, and one valid operational attribute, but also the things they are built from
1565 res1 = ldb.search(self.base_dn,
1566 scope=SCOPE_BASE, attrs=["primaryGroupToken", "canonicalName", "objectClass", "objectSid"])
1567 self.assertTrue(len(res1) == 1)
1568 self.assertFalse("primaryGroupToken" in res1[0])
1569 self.assertTrue("canonicalName" in res1[0])
1570 self.assertTrue("objectClass" in res1[0])
1571 self.assertTrue("objectSid" in res1[0])
1573 res1 = ldb.search(self.base_dn,
1574 scope=SCOPE_BASE, attrs=["primaryGroupToken", "canonicalName"])
1575 self.assertTrue(len(res1) == 1)
1576 self.assertFalse("primaryGroupToken" in res1[0])
1577 self.assertFalse("objectSid" in res1[0])
1578 self.assertFalse("objectClass" in res1[0])
1579 self.assertTrue("canonicalName" in res1[0])
1581 res1 = ldb.search("cn=users,"+self.base_dn,
1582 scope=SCOPE_BASE, attrs=["primaryGroupToken"])
1583 self.assertTrue(len(res1) == 1)
1584 self.assertFalse("primaryGroupToken" in res1[0])
1586 res1 = ldb.search("cn=ldaptestuser, cn=users," + self.base_dn,
1587 scope=SCOPE_BASE, attrs=["primaryGroupToken"])
1588 self.assertTrue(len(res1) == 1)
1589 self.assertFalse("primaryGroupToken" in res1[0])
1591 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
1593 self.assertTrue(len(res1) == 1)
1594 self.assertFalse("primaryGroupToken" in res1[0])
1596 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
1597 scope=SCOPE_BASE, attrs=["primaryGroupToken", "objectSID"])
1598 self.assertTrue(len(res1) == 1)
1599 primary_group_token = int(res1[0]["primaryGroupToken"][0])
1601 rid = security.dom_sid(ldb.schema_format_value("objectSID", res1[0]["objectSID"][0])).split()[1]
1602 self.assertEquals(primary_group_token, rid)
1605 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1606 m["primaryGroupToken"] = "100"
1610 except LdbError, (num, _):
1611 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
1613 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1614 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1616 def test_tokenGroups(self):
1617 """Test the tokenGroups behaviour (hidden-generated-readonly attribute on SAM objects)"""
1618 print "Testing tokenGroups behaviour\n"
1620 # The domain object shouldn't contain any "tokenGroups" entry
1621 res = ldb.search(self.base_dn, scope=SCOPE_BASE, attrs=["tokenGroups"])
1622 self.assertTrue(len(res) == 1)
1623 self.assertFalse("tokenGroups" in res[0])
1625 # The domain administrator should contain "tokenGroups" entries
1626 # (the exact number depends on the domain/forest function level and the
1627 # DC software versions)
1628 res = ldb.search("cn=Administrator,cn=Users," + self.base_dn,
1629 scope=SCOPE_BASE, attrs=["tokenGroups"])
1630 self.assertTrue(len(res) == 1)
1631 self.assertTrue("tokenGroups" in res[0])
1634 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1635 "objectclass": ["user", "person"]})
1637 # This testuser should contain at least two "tokenGroups" entries
1638 # (exactly two on an unmodified "Domain Users" and "Users" group)
1639 res = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
1640 scope=SCOPE_BASE, attrs=["tokenGroups"])
1641 self.assertTrue(len(res) == 1)
1642 self.assertTrue(len(res[0]["tokenGroups"]) >= 2)
1644 # one entry which we need to find should point to domains "Domain Users"
1645 # group and another entry should point to the builtin "Users"group
1646 domain_users_group_found = False
1647 users_group_found = False
1648 for sid in res[0]["tokenGroups"]:
1649 rid = security.dom_sid(ldb.schema_format_value("objectSID", sid)).split()[1]
1651 domain_users_group_found = True
1653 users_group_found = True
1655 self.assertTrue(domain_users_group_found)
1656 self.assertTrue(users_group_found)
1658 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1660 def test_wkguid(self):
1661 """Test Well known GUID behaviours (including DN+Binary)"""
1662 print "Test Well known GUID behaviours (including DN+Binary)"""
1664 res = self.ldb.search(base=("<WKGUID=ab1d30f3768811d1aded00c04fd8d5cd,%s>" % self.base_dn), scope=SCOPE_BASE, attrs=[])
1665 self.assertEquals(len(res), 1)
1667 res2 = self.ldb.search(scope=SCOPE_BASE, attrs=["wellKnownObjects"], expression=("wellKnownObjects=B:32:ab1d30f3768811d1aded00c04fd8d5cd:%s" % res[0].dn))
1668 self.assertEquals(len(res2), 1)
1670 # Prove that the matching rule is over the whole DN+Binary
1671 res2 = self.ldb.search(scope=SCOPE_BASE, attrs=["wellKnownObjects"], expression=("wellKnownObjects=B:32:ab1d30f3768811d1aded00c04fd8d5cd"))
1672 self.assertEquals(len(res2), 0)
1673 # Prove that the matching rule is over the whole DN+Binary
1674 res2 = self.ldb.search(scope=SCOPE_BASE, attrs=["wellKnownObjects"], expression=("wellKnownObjects=%s") % res[0].dn)
1675 self.assertEquals(len(res2), 0)
1677 def test_subschemasubentry(self):
1678 """Test subSchemaSubEntry appears when requested, but not when not requested"""
1679 print "Test subSchemaSubEntry"""
1681 res = self.ldb.search(base=self.base_dn, scope=SCOPE_BASE, attrs=["subSchemaSubEntry"])
1682 self.assertEquals(len(res), 1)
1683 self.assertEquals(res[0]["subSchemaSubEntry"][0], "CN=Aggregate,"+self.schema_dn)
1685 res = self.ldb.search(base=self.base_dn, scope=SCOPE_BASE, attrs=["*"])
1686 self.assertEquals(len(res), 1)
1687 self.assertTrue("subScheamSubEntry" not in res[0])
1689 def test_delete(self):
1690 """Tests the delete operation"""
1691 print "Tests the delete operations"""
1694 "dn": "cn=ldaptestcontainer," + self.base_dn,
1695 "objectclass": "container"})
1697 "dn": "cn=entry1,cn=ldaptestcontainer," + self.base_dn,
1698 "objectclass": "container"})
1700 "dn": "cn=entry2,cn=ldaptestcontainer," + self.base_dn,
1701 "objectclass": "container"})
1704 ldb.delete("cn=ldaptestcontainer," + self.base_dn)
1706 except LdbError, (num, _):
1707 self.assertEquals(num, ERR_NOT_ALLOWED_ON_NON_LEAF)
1709 ldb.delete("cn=ldaptestcontainer," + self.base_dn, ["tree_delete:0"])
1712 res = ldb.search("cn=ldaptestcontainer," + self.base_dn,
1713 scope=SCOPE_BASE, attrs=[])
1715 except LdbError, (num, _):
1716 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
1718 res = ldb.search("cn=entry1,cn=ldaptestcontainer," + self.base_dn,
1719 scope=SCOPE_BASE, attrs=[])
1721 except LdbError, (num, _):
1722 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
1724 res = ldb.search("cn=entry2,cn=ldaptestcontainer," + self.base_dn,
1725 scope=SCOPE_BASE, attrs=[])
1727 except LdbError, (num, _):
1728 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
1730 self.delete_force(self.ldb, "cn=entry1,cn=ldaptestcontainer," + self.base_dn)
1731 self.delete_force(self.ldb, "cn=entry2,cn=ldaptestcontainer," + self.base_dn)
1732 self.delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
1734 # Performs some protected object delete testing
1736 res = ldb.search(base="", expression="", scope=SCOPE_BASE,
1737 attrs=["dsServiceName", "dNSHostName"])
1738 self.assertEquals(len(res), 1)
1741 ldb.delete(res[0]["dsServiceName"][0])
1743 except LdbError, (num, _):
1744 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1746 res = ldb.search(self.base_dn, scope=SCOPE_SUBTREE,
1747 attrs=["rIDSetReferences"],
1748 expression="(&(objectClass=computer)(dNSHostName=" + res[0]["dNSHostName"][0] + "))")
1749 self.assertEquals(len(res), 1)
1752 ldb.delete(res[0]["rIDSetReferences"][0])
1754 except LdbError, (num, _):
1755 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1758 ldb.delete("cn=Enterprise Schema,cn=Partitions," + self.configuration_dn)
1760 except LdbError, (num, _):
1761 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1763 # TODO: This fails with LDB_ERR_NOT_ALLOWED_ON_NON_LEAF on Windows
1765 # ldb.delete("cn=Enterprise Configuration,cn=Partitions," + self.configuration_dn)
1767 # except LdbError, (num, _):
1768 # self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1770 # Performs some "systemFlags" testing
1772 # Delete failing since "SYSTEM_FLAG_DISALLOW_DELETE"
1774 ldb.delete("CN=Users," + self.base_dn)
1776 except LdbError, (num, _):
1777 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1782 print "Testing user add"
1785 "dn": "cn=ldaptestuser,cn=uSers," + self.base_dn,
1786 "objectclass": ["user", "person"],
1787 "cN": "LDAPtestUSER",
1788 "givenname": "ldap",
1792 "dn": "cn=ldaptestgroup,cn=uSers," + self.base_dn,
1793 "objectclass": "group",
1794 "member": "cn=ldaptestuser,cn=useRs," + self.base_dn})
1797 "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
1798 "objectclass": "computer",
1799 "cN": "LDAPtestCOMPUTER"})
1801 ldb.add({"dn": "cn=ldaptest2computer,cn=computers," + self.base_dn,
1802 "objectClass": "computer",
1803 "cn": "LDAPtest2COMPUTER",
1804 "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT),
1805 "displayname": "ldap testy"})
1808 ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn,
1809 "objectClass": "computer",
1810 "cn": "LDAPtest2COMPUTER"
1813 except LdbError, (num, _):
1814 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1817 ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn,
1818 "objectClass": "computer",
1819 "cn": "ldaptestcomputer3",
1820 "sAMAccountType": str(ATYPE_NORMAL_ACCOUNT)
1823 except LdbError, (num, _):
1824 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1826 ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn,
1827 "objectClass": "computer",
1828 "cn": "LDAPtestCOMPUTER3"
1831 print "Testing ldb.search for (&(cn=ldaptestcomputer3)(objectClass=user))";
1832 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestcomputer3)(objectClass=user))");
1833 self.assertEquals(len(res), 1, "Found only %d for (&(cn=ldaptestcomputer3)(objectClass=user))" % len(res))
1835 self.assertEquals(str(res[0].dn), ("CN=ldaptestcomputer3,CN=Computers," + self.base_dn));
1836 self.assertEquals(res[0]["cn"][0], "ldaptestcomputer3");
1837 self.assertEquals(res[0]["name"][0], "ldaptestcomputer3");
1838 self.assertEquals(res[0]["objectClass"][0], "top");
1839 self.assertEquals(res[0]["objectClass"][1], "person");
1840 self.assertEquals(res[0]["objectClass"][2], "organizationalPerson");
1841 self.assertEquals(res[0]["objectClass"][3], "user");
1842 self.assertEquals(res[0]["objectClass"][4], "computer");
1843 self.assertTrue("objectGUID" in res[0])
1844 self.assertTrue("whenCreated" in res[0])
1845 self.assertEquals(res[0]["objectCategory"][0], ("CN=Computer,CN=Schema,CN=Configuration," + self.base_dn));
1846 self.assertEquals(int(res[0]["primaryGroupID"][0]), 513);
1847 self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_NORMAL_ACCOUNT);
1848 self.assertEquals(int(res[0]["userAccountControl"][0]), UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE);
1850 self.delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
1852 print "Testing attribute or value exists behaviour"
1855 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1857 replace: servicePrincipalName
1858 servicePrincipalName: host/ldaptest2computer
1859 servicePrincipalName: host/ldaptest2computer
1860 servicePrincipalName: cifs/ldaptest2computer
1863 except LdbError, (num, msg):
1864 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
1867 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1869 replace: servicePrincipalName
1870 servicePrincipalName: host/ldaptest2computer
1871 servicePrincipalName: cifs/ldaptest2computer
1875 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1877 add: servicePrincipalName
1878 servicePrincipalName: host/ldaptest2computer
1881 except LdbError, (num, msg):
1882 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
1884 print "Testing ranged results"
1886 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1888 replace: servicePrincipalName
1892 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1894 add: servicePrincipalName
1895 servicePrincipalName: host/ldaptest2computer0
1896 servicePrincipalName: host/ldaptest2computer1
1897 servicePrincipalName: host/ldaptest2computer2
1898 servicePrincipalName: host/ldaptest2computer3
1899 servicePrincipalName: host/ldaptest2computer4
1900 servicePrincipalName: host/ldaptest2computer5
1901 servicePrincipalName: host/ldaptest2computer6
1902 servicePrincipalName: host/ldaptest2computer7
1903 servicePrincipalName: host/ldaptest2computer8
1904 servicePrincipalName: host/ldaptest2computer9
1905 servicePrincipalName: host/ldaptest2computer10
1906 servicePrincipalName: host/ldaptest2computer11
1907 servicePrincipalName: host/ldaptest2computer12
1908 servicePrincipalName: host/ldaptest2computer13
1909 servicePrincipalName: host/ldaptest2computer14
1910 servicePrincipalName: host/ldaptest2computer15
1911 servicePrincipalName: host/ldaptest2computer16
1912 servicePrincipalName: host/ldaptest2computer17
1913 servicePrincipalName: host/ldaptest2computer18
1914 servicePrincipalName: host/ldaptest2computer19
1915 servicePrincipalName: host/ldaptest2computer20
1916 servicePrincipalName: host/ldaptest2computer21
1917 servicePrincipalName: host/ldaptest2computer22
1918 servicePrincipalName: host/ldaptest2computer23
1919 servicePrincipalName: host/ldaptest2computer24
1920 servicePrincipalName: host/ldaptest2computer25
1921 servicePrincipalName: host/ldaptest2computer26
1922 servicePrincipalName: host/ldaptest2computer27
1923 servicePrincipalName: host/ldaptest2computer28
1924 servicePrincipalName: host/ldaptest2computer29
1927 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE,
1928 attrs=["servicePrincipalName;range=0-*"])
1929 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1930 #print len(res[0]["servicePrincipalName;range=0-*"])
1931 self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30)
1933 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-19"])
1934 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1935 # print res[0]["servicePrincipalName;range=0-19"].length
1936 self.assertEquals(len(res[0]["servicePrincipalName;range=0-19"]), 20)
1939 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-30"])
1940 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1941 self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30)
1943 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-40"])
1944 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1945 self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30)
1947 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=30-40"])
1948 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1949 self.assertEquals(len(res[0]["servicePrincipalName;range=30-*"]), 0)
1952 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=10-40"])
1953 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1954 self.assertEquals(len(res[0]["servicePrincipalName;range=10-*"]), 20)
1955 # pos_11 = res[0]["servicePrincipalName;range=10-*"][18]
1957 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=11-40"])
1958 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1959 self.assertEquals(len(res[0]["servicePrincipalName;range=11-*"]), 19)
1960 # print res[0]["servicePrincipalName;range=11-*"][18]
1962 # self.assertEquals((res[0]["servicePrincipalName;range=11-*"][18]), pos_11)
1964 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=11-15"])
1965 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1966 self.assertEquals(len(res[0]["servicePrincipalName;range=11-15"]), 5)
1967 # self.assertEquals(res[0]["servicePrincipalName;range=11-15"][4], pos_11)
1969 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName"])
1970 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1971 # print res[0]["servicePrincipalName"][18]
1973 self.assertEquals(len(res[0]["servicePrincipalName"]), 30)
1974 # self.assertEquals(res[0]["servicePrincipalName"][18], pos_11)
1976 self.delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
1978 "dn": "cn=ldaptestuser2,cn=useRs," + self.base_dn,
1979 "objectClass": ["person", "user"],
1980 "cn": "LDAPtestUSER2",
1981 "givenname": "testy",
1982 "sn": "ldap user2"})
1984 print "Testing Ambigious Name Resolution"
1985 # Testing ldb.search for (&(anr=ldap testy)(objectClass=user))
1986 res = ldb.search(expression="(&(anr=ldap testy)(objectClass=user))")
1987 self.assertEquals(len(res), 3, "Found only %d of 3 for (&(anr=ldap testy)(objectClass=user))" % len(res))
1989 # Testing ldb.search for (&(anr=testy ldap)(objectClass=user))
1990 res = ldb.search(expression="(&(anr=testy ldap)(objectClass=user))")
1991 self.assertEquals(len(res), 2, "Found only %d of 2 for (&(anr=testy ldap)(objectClass=user))" % len(res))
1993 # Testing ldb.search for (&(anr=ldap)(objectClass=user))
1994 res = ldb.search(expression="(&(anr=ldap)(objectClass=user))")
1995 self.assertEquals(len(res), 4, "Found only %d of 4 for (&(anr=ldap)(objectClass=user))" % len(res))
1997 # Testing ldb.search for (&(anr==ldap)(objectClass=user))
1998 res = ldb.search(expression="(&(anr==ldap)(objectClass=user))")
1999 self.assertEquals(len(res), 1, "Could not find (&(anr==ldap)(objectClass=user)). Found only %d for (&(anr=ldap)(objectClass=user))" % len(res))
2001 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
2002 self.assertEquals(res[0]["cn"][0], "ldaptestuser")
2003 self.assertEquals(str(res[0]["name"]), "ldaptestuser")
2005 # Testing ldb.search for (&(anr=testy)(objectClass=user))
2006 res = ldb.search(expression="(&(anr=testy)(objectClass=user))")
2007 self.assertEquals(len(res), 2, "Found only %d for (&(anr=testy)(objectClass=user))" % len(res))
2009 # Testing ldb.search for (&(anr=testy ldap)(objectClass=user))
2010 res = ldb.search(expression="(&(anr=testy ldap)(objectClass=user))")
2011 self.assertEquals(len(res), 2, "Found only %d for (&(anr=testy ldap)(objectClass=user))" % len(res))
2013 # Testing ldb.search for (&(anr==testy ldap)(objectClass=user))
2014 # this test disabled for the moment, as anr with == tests are not understood
2015 # res = ldb.search(expression="(&(anr==testy ldap)(objectClass=user))")
2016 # self.assertEquals(len(res), 1, "Found only %d for (&(anr==testy ldap)(objectClass=user))" % len(res))
2018 # self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
2019 # self.assertEquals(res[0]["cn"][0], "ldaptestuser")
2020 # self.assertEquals(res[0]["name"][0], "ldaptestuser")
2022 # Testing ldb.search for (&(anr==testy ldap)(objectClass=user))
2023 # res = ldb.search(expression="(&(anr==testy ldap)(objectClass=user))")
2024 # self.assertEquals(len(res), 1, "Could not find (&(anr==testy ldap)(objectClass=user))")
2026 # self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
2027 # self.assertEquals(res[0]["cn"][0], "ldaptestuser")
2028 # self.assertEquals(res[0]["name"][0], "ldaptestuser")
2030 # Testing ldb.search for (&(anr=testy ldap user)(objectClass=user))
2031 res = ldb.search(expression="(&(anr=testy ldap user)(objectClass=user))")
2032 self.assertEquals(len(res), 1, "Could not find (&(anr=testy ldap user)(objectClass=user))")
2034 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
2035 self.assertEquals(str(res[0]["cn"]), "ldaptestuser2")
2036 self.assertEquals(str(res[0]["name"]), "ldaptestuser2")
2038 # Testing ldb.search for (&(anr==testy ldap user2)(objectClass=user))
2039 # res = ldb.search(expression="(&(anr==testy ldap user2)(objectClass=user))")
2040 # self.assertEquals(len(res), 1, "Could not find (&(anr==testy ldap user2)(objectClass=user))")
2042 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
2043 self.assertEquals(str(res[0]["cn"]), "ldaptestuser2")
2044 self.assertEquals(str(res[0]["name"]), "ldaptestuser2")
2046 # Testing ldb.search for (&(anr==ldap user2)(objectClass=user))
2047 # res = ldb.search(expression="(&(anr==ldap user2)(objectClass=user))")
2048 # self.assertEquals(len(res), 1, "Could not find (&(anr==ldap user2)(objectClass=user))")
2050 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
2051 self.assertEquals(str(res[0]["cn"]), "ldaptestuser2")
2052 self.assertEquals(str(res[0]["name"]), "ldaptestuser2")
2054 # Testing ldb.search for (&(anr==not ldap user2)(objectClass=user))
2055 # res = ldb.search(expression="(&(anr==not ldap user2)(objectClass=user))")
2056 # self.assertEquals(len(res), 0, "Must not find (&(anr==not ldap user2)(objectClass=user))")
2058 # Testing ldb.search for (&(anr=not ldap user2)(objectClass=user))
2059 res = ldb.search(expression="(&(anr=not ldap user2)(objectClass=user))")
2060 self.assertEquals(len(res), 0, "Must not find (&(anr=not ldap user2)(objectClass=user))")
2062 # Testing ldb.search for (&(anr="testy ldap")(objectClass=user)) (ie, with quotes)
2063 # res = ldb.search(expression="(&(anr==\"testy ldap\")(objectClass=user))")
2064 # self.assertEquals(len(res), 0, "Found (&(anr==\"testy ldap\")(objectClass=user))")
2066 print "Testing Renames"
2068 attrs = ["objectGUID", "objectSid"]
2069 print "Testing ldb.search for (&(cn=ldaptestUSer2)(objectClass=user))"
2070 res_user = ldb.search(self.base_dn, expression="(&(cn=ldaptestUSer2)(objectClass=user))", scope=SCOPE_SUBTREE, attrs=attrs)
2071 self.assertEquals(len(res_user), 1, "Could not find (&(cn=ldaptestUSer2)(objectClass=user))")
2073 # Check rename works with extended/alternate DN forms
2074 ldb.rename("<SID=" + ldb.schema_format_value("objectSID", res_user[0]["objectSID"][0]) + ">" , "cn=ldaptestUSER3,cn=users," + self.base_dn)
2076 print "Testing ldb.search for (&(cn=ldaptestuser3)(objectClass=user))"
2077 res = ldb.search(expression="(&(cn=ldaptestuser3)(objectClass=user))")
2078 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser3)(objectClass=user))")
2080 self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
2081 self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3")
2082 self.assertEquals(str(res[0]["name"]), "ldaptestUSER3")
2084 #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))"
2085 res = ldb.search(expression="(&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))")
2086 self.assertEquals(len(res), 1, "(&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))")
2088 self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
2089 self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3")
2090 self.assertEquals(str(res[0]["name"]), "ldaptestUSER3")
2092 #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))"
2093 res = ldb.search(expression="(&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))")
2094 self.assertEquals(len(res), 1, "(&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))")
2096 self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
2097 self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3")
2098 self.assertEquals(str(res[0]["name"]), "ldaptestUSER3")
2100 #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))"
2101 res = ldb.search(expression="(&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))")
2102 self.assertEquals(len(res), 0, "(&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))")
2104 # This is a Samba special, and does not exist in real AD
2105 # print "Testing ldb.search for (dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")"
2106 # res = ldb.search("(dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")")
2107 # if (res.error != 0 || len(res) != 1) {
2108 # print "Could not find (dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")"
2109 # self.assertEquals(len(res), 1)
2111 # self.assertEquals(res[0].dn, ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
2112 # self.assertEquals(res[0].cn, "ldaptestUSER3")
2113 # self.assertEquals(res[0].name, "ldaptestUSER3")
2115 print "Testing ldb.search for (distinguishedName=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")"
2116 res = ldb.search(expression="(distinguishedName=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")")
2117 self.assertEquals(len(res), 1, "Could not find (dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")")
2118 self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
2119 self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3")
2120 self.assertEquals(str(res[0]["name"]), "ldaptestUSER3")
2122 # ensure we cannot add it again
2124 ldb.add({"dn": "cn=ldaptestuser3,cn=userS," + self.base_dn,
2125 "objectClass": ["person", "user"],
2126 "cn": "LDAPtestUSER3"})
2128 except LdbError, (num, _):
2129 self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
2132 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser2,cn=users," + self.base_dn)
2134 # ensure we cannot rename it twice
2136 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn,
2137 "cn=ldaptestuser2,cn=users," + self.base_dn)
2139 except LdbError, (num, _):
2140 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
2142 # ensure can now use that name
2143 ldb.add({"dn": "cn=ldaptestuser3,cn=users," + self.base_dn,
2144 "objectClass": ["person", "user"],
2145 "cn": "LDAPtestUSER3"})
2147 # ensure we now cannot rename
2149 ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=users," + self.base_dn)
2151 except LdbError, (num, _):
2152 self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
2154 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=configuration," + self.base_dn)
2156 except LdbError, (num, _):
2157 self.assertTrue(num in (71, 64))
2159 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser5,cn=users," + self.base_dn)
2161 ldb.delete("cn=ldaptestuser5,cn=users," + self.base_dn)
2163 self.delete_force(ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
2165 ldb.rename("cn=ldaptestgroup,cn=users," + self.base_dn, "cn=ldaptestgroup2,cn=users," + self.base_dn)
2167 print "Testing subtree renames"
2169 ldb.add({"dn": "cn=ldaptestcontainer," + self.base_dn,
2170 "objectClass": "container"})
2172 ldb.add({"dn": "CN=ldaptestuser4,CN=ldaptestcontainer," + self.base_dn,
2173 "objectClass": ["person", "user"],
2174 "cn": "LDAPtestUSER4"})
2177 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2180 member: cn=ldaptestuser4,cn=ldaptestcontainer,""" + self.base_dn + """
2181 member: cn=ldaptestcomputer,cn=computers,""" + self.base_dn + """
2182 member: cn=ldaptestuser2,cn=users,""" + self.base_dn + """
2185 print "Testing ldb.rename of cn=ldaptestcontainer," + self.base_dn + " to cn=ldaptestcontainer2," + self.base_dn
2186 ldb.rename("CN=ldaptestcontainer," + self.base_dn, "CN=ldaptestcontainer2," + self.base_dn)
2188 print "Testing ldb.search for (&(cn=ldaptestuser4)(objectClass=user))"
2189 res = ldb.search(expression="(&(cn=ldaptestuser4)(objectClass=user))")
2190 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser4)(objectClass=user))")
2192 print "Testing subtree ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in (just renamed from) cn=ldaptestcontainer," + self.base_dn
2194 res = ldb.search("cn=ldaptestcontainer," + self.base_dn,
2195 expression="(&(cn=ldaptestuser4)(objectClass=user))",
2196 scope=SCOPE_SUBTREE)
2198 except LdbError, (num, _):
2199 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
2201 print "Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in (just renamed from) cn=ldaptestcontainer," + self.base_dn
2203 res = ldb.search("cn=ldaptestcontainer," + self.base_dn,
2204 expression="(&(cn=ldaptestuser4)(objectClass=user))", scope=SCOPE_ONELEVEL)
2206 except LdbError, (num, _):
2207 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
2209 print "Testing ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in renamed container"
2210 res = ldb.search("cn=ldaptestcontainer2," + self.base_dn, expression="(&(cn=ldaptestuser4)(objectClass=user))", scope=SCOPE_SUBTREE)
2211 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser4)(objectClass=user)) under cn=ldaptestcontainer2," + self.base_dn)
2213 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn))
2214 self.assertEquals(res[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
2218 print "Testing ldb.search for (&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn + ")(objectclass=group)) to check subtree renames and linked attributes"
2219 res = ldb.search(self.base_dn, expression="(&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn + ")(objectclass=group))", scope=SCOPE_SUBTREE)
2220 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?")
2222 print "Testing ldb.rename (into itself) of cn=ldaptestcontainer2," + self.base_dn + " to cn=ldaptestcontainer,cn=ldaptestcontainer2," + self.base_dn
2224 ldb.rename("cn=ldaptestcontainer2," + self.base_dn, "cn=ldaptestcontainer,cn=ldaptestcontainer2," + self.base_dn)
2226 except LdbError, (num, _):
2227 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
2229 print "Testing ldb.rename (into non-existent container) of cn=ldaptestcontainer2," + self.base_dn + " to cn=ldaptestcontainer,cn=ldaptestcontainer3," + self.base_dn
2231 ldb.rename("cn=ldaptestcontainer2," + self.base_dn, "cn=ldaptestcontainer,cn=ldaptestcontainer3," + self.base_dn)
2233 except LdbError, (num, _):
2234 self.assertTrue(num in (ERR_UNWILLING_TO_PERFORM, ERR_OTHER))
2236 print "Testing delete (should fail, not a leaf node) of renamed cn=ldaptestcontainer2," + self.base_dn
2238 ldb.delete("cn=ldaptestcontainer2," + self.base_dn)
2240 except LdbError, (num, _):
2241 self.assertEquals(num, ERR_NOT_ALLOWED_ON_NON_LEAF)
2243 print "Testing base ldb.search for CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn
2244 res = ldb.search(expression="(objectclass=*)", base=("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn), scope=SCOPE_BASE)
2245 self.assertEquals(len(res), 1)
2246 res = ldb.search(expression="(cn=ldaptestuser40)", base=("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn), scope=SCOPE_BASE)
2247 self.assertEquals(len(res), 0)
2249 print "Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in cn=ldaptestcontainer2," + self.base_dn
2250 res = ldb.search(expression="(&(cn=ldaptestuser4)(objectClass=user))", base=("cn=ldaptestcontainer2," + self.base_dn), scope=SCOPE_ONELEVEL)
2251 # FIXME: self.assertEquals(len(res), 0)
2253 print "Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in cn=ldaptestcontainer2," + self.base_dn
2254 res = ldb.search(expression="(&(cn=ldaptestuser4)(objectClass=user))", base=("cn=ldaptestcontainer2," + self.base_dn), scope=SCOPE_SUBTREE)
2255 # FIXME: self.assertEquals(len(res), 0)
2257 print "Testing delete of subtree renamed "+("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn)
2258 ldb.delete(("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn))
2259 print "Testing delete of renamed cn=ldaptestcontainer2," + self.base_dn
2260 ldb.delete("cn=ldaptestcontainer2," + self.base_dn)
2262 ldb.add({"dn": "cn=ldaptestutf8user èùéìòà,cn=users," + self.base_dn, "objectClass": "user"})
2264 ldb.add({"dn": "cn=ldaptestutf8user2 èùéìòà,cn=users," + self.base_dn, "objectClass": "user"})
2266 print "Testing ldb.search for (&(cn=ldaptestuser)(objectClass=user))"
2267 res = ldb.search(expression="(&(cn=ldaptestuser)(objectClass=user))")
2268 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser)(objectClass=user))")
2270 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
2271 self.assertEquals(str(res[0]["cn"]), "ldaptestuser")
2272 self.assertEquals(str(res[0]["name"]), "ldaptestuser")
2273 self.assertEquals(set(res[0]["objectClass"]), set(["top", "person", "organizationalPerson", "user"]))
2274 self.assertTrue("objectGUID" in res[0])
2275 self.assertTrue("whenCreated" in res[0])
2276 self.assertEquals(str(res[0]["objectCategory"]), ("CN=Person,CN=Schema,CN=Configuration," + self.base_dn))
2277 self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_NORMAL_ACCOUNT)
2278 self.assertEquals(int(res[0]["userAccountControl"][0]), UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE)
2279 self.assertEquals(res[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
2280 self.assertEquals(len(res[0]["memberOf"]), 1)
2282 print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=cn=person,cn=schema,cn=configuration," + self.base_dn + "))"
2283 res2 = ldb.search(expression="(&(cn=ldaptestuser)(objectCategory=cn=person,cn=schema,cn=configuration," + self.base_dn + "))")
2284 self.assertEquals(len(res2), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=cn=person,cn=schema,cn=configuration," + self.base_dn + "))")
2286 self.assertEquals(res[0].dn, res2[0].dn)
2288 print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon))"
2289 res3 = ldb.search(expression="(&(cn=ldaptestuser)(objectCategory=PerSon))")
2290 self.assertEquals(len(res3), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=PerSon)): matched %d" % len(res3))
2292 self.assertEquals(res[0].dn, res3[0].dn)
2294 if gc_ldb is not None:
2295 print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon)) in Global Catalog"
2296 res3gc = gc_ldb.search(expression="(&(cn=ldaptestuser)(objectCategory=PerSon))")
2297 self.assertEquals(len(res3gc), 1)
2299 self.assertEquals(res[0].dn, res3gc[0].dn)
2301 print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon)) in with 'phantom root' control"
2303 if gc_ldb is not None:
2304 res3control = gc_ldb.search(self.base_dn, expression="(&(cn=ldaptestuser)(objectCategory=PerSon))", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["search_options:1:2"])
2305 self.assertEquals(len(res3control), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=PerSon)) in Global Catalog")
2307 self.assertEquals(res[0].dn, res3control[0].dn)
2309 ldb.delete(res[0].dn)
2311 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectClass=user))"
2312 res = ldb.search(expression="(&(cn=ldaptestcomputer)(objectClass=user))")
2313 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser)(objectClass=user))")
2315 self.assertEquals(str(res[0].dn), ("CN=ldaptestcomputer,CN=Computers," + self.base_dn))
2316 self.assertEquals(str(res[0]["cn"]), "ldaptestcomputer")
2317 self.assertEquals(str(res[0]["name"]), "ldaptestcomputer")
2318 self.assertEquals(set(res[0]["objectClass"]), set(["top", "person", "organizationalPerson", "user", "computer"]))
2319 self.assertTrue("objectGUID" in res[0])
2320 self.assertTrue("whenCreated" in res[0])
2321 self.assertEquals(str(res[0]["objectCategory"]), ("CN=Computer,CN=Schema,CN=Configuration," + self.base_dn))
2322 self.assertEquals(int(res[0]["primaryGroupID"][0]), 513)
2323 self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_NORMAL_ACCOUNT)
2324 self.assertEquals(int(res[0]["userAccountControl"][0]), UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE)
2325 self.assertEquals(res[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
2326 self.assertEquals(len(res[0]["memberOf"]), 1)
2328 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + "))"
2329 res2 = ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + "))")
2330 self.assertEquals(len(res2), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + "))")
2332 self.assertEquals(res[0].dn, res2[0].dn)
2334 if gc_ldb is not None:
2335 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + ")) in Global Catlog"
2336 res2gc = gc_ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + "))")
2337 self.assertEquals(len(res2gc), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + ")) in Global Catlog")
2339 self.assertEquals(res[0].dn, res2gc[0].dn)
2341 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=compuTER))"
2342 res3 = ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=compuTER))")
2343 self.assertEquals(len(res3), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=compuTER))")
2345 self.assertEquals(res[0].dn, res3[0].dn)
2347 if gc_ldb is not None:
2348 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=compuTER)) in Global Catalog"
2349 res3gc = gc_ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=compuTER))")
2350 self.assertEquals(len(res3gc), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=compuTER)) in Global Catalog")
2352 self.assertEquals(res[0].dn, res3gc[0].dn)
2354 print "Testing ldb.search for (&(cn=ldaptestcomp*r)(objectCategory=compuTER))"
2355 res4 = ldb.search(expression="(&(cn=ldaptestcomp*r)(objectCategory=compuTER))")
2356 self.assertEquals(len(res4), 1, "Could not find (&(cn=ldaptestcomp*r)(objectCategory=compuTER))")
2358 self.assertEquals(res[0].dn, res4[0].dn)
2360 print "Testing ldb.search for (&(cn=ldaptestcomput*)(objectCategory=compuTER))"
2361 res5 = ldb.search(expression="(&(cn=ldaptestcomput*)(objectCategory=compuTER))")
2362 self.assertEquals(len(res5), 1, "Could not find (&(cn=ldaptestcomput*)(objectCategory=compuTER))")
2364 self.assertEquals(res[0].dn, res5[0].dn)
2366 print "Testing ldb.search for (&(cn=*daptestcomputer)(objectCategory=compuTER))"
2367 res6 = ldb.search(expression="(&(cn=*daptestcomputer)(objectCategory=compuTER))")
2368 self.assertEquals(len(res6), 1, "Could not find (&(cn=*daptestcomputer)(objectCategory=compuTER))")
2370 self.assertEquals(res[0].dn, res6[0].dn)
2372 ldb.delete("<GUID=" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + ">")
2374 print "Testing ldb.search for (&(cn=ldaptest2computer)(objectClass=user))"
2375 res = ldb.search(expression="(&(cn=ldaptest2computer)(objectClass=user))")
2376 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptest2computer)(objectClass=user))")
2378 self.assertEquals(str(res[0].dn), "CN=ldaptest2computer,CN=Computers," + self.base_dn)
2379 self.assertEquals(str(res[0]["cn"]), "ldaptest2computer")
2380 self.assertEquals(str(res[0]["name"]), "ldaptest2computer")
2381 self.assertEquals(list(res[0]["objectClass"]), ["top", "person", "organizationalPerson", "user", "computer"])
2382 self.assertTrue("objectGUID" in res[0])
2383 self.assertTrue("whenCreated" in res[0])
2384 self.assertEquals(res[0]["objectCategory"][0], "CN=Computer,CN=Schema,CN=Configuration," + self.base_dn)
2385 self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_WORKSTATION_TRUST)
2386 self.assertEquals(int(res[0]["userAccountControl"][0]), UF_WORKSTATION_TRUST_ACCOUNT)
2388 ldb.delete("<SID=" + ldb.schema_format_value("objectSID", res[0]["objectSID"][0]) + ">")
2390 attrs = ["cn", "name", "objectClass", "objectGUID", "objectSID", "whenCreated", "nTSecurityDescriptor", "memberOf", "allowedAttributes", "allowedAttributesEffective"]
2391 print "Testing ldb.search for (&(cn=ldaptestUSer2)(objectClass=user))"
2392 res_user = ldb.search(self.base_dn, expression="(&(cn=ldaptestUSer2)(objectClass=user))", scope=SCOPE_SUBTREE, attrs=attrs)
2393 self.assertEquals(len(res_user), 1, "Could not find (&(cn=ldaptestUSer2)(objectClass=user))")
2395 self.assertEquals(str(res_user[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
2396 self.assertEquals(str(res_user[0]["cn"]), "ldaptestuser2")
2397 self.assertEquals(str(res_user[0]["name"]), "ldaptestuser2")
2398 self.assertEquals(list(res_user[0]["objectClass"]), ["top", "person", "organizationalPerson", "user"])
2399 self.assertTrue("objectSid" in res_user[0])
2400 self.assertTrue("objectGUID" in res_user[0])
2401 self.assertTrue("whenCreated" in res_user[0])
2402 self.assertTrue("nTSecurityDescriptor" in res_user[0])
2403 self.assertTrue("allowedAttributes" in res_user[0])
2404 self.assertTrue("allowedAttributesEffective" in res_user[0])
2405 self.assertEquals(res_user[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
2407 ldaptestuser2_sid = res_user[0]["objectSid"][0]
2408 ldaptestuser2_guid = res_user[0]["objectGUID"][0]
2410 attrs = ["cn", "name", "objectClass", "objectGUID", "objectSID", "whenCreated", "nTSecurityDescriptor", "member", "allowedAttributes", "allowedAttributesEffective"]
2411 print "Testing ldb.search for (&(cn=ldaptestgroup2)(objectClass=group))"
2412 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs)
2413 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))")
2415 self.assertEquals(str(res[0].dn), ("CN=ldaptestgroup2,CN=Users," + self.base_dn))
2416 self.assertEquals(str(res[0]["cn"]), "ldaptestgroup2")
2417 self.assertEquals(str(res[0]["name"]), "ldaptestgroup2")
2418 self.assertEquals(list(res[0]["objectClass"]), ["top", "group"])
2419 self.assertTrue("objectGUID" in res[0])
2420 self.assertTrue("objectSid" in res[0])
2421 self.assertTrue("whenCreated" in res[0])
2422 self.assertTrue("nTSecurityDescriptor" in res[0])
2423 self.assertTrue("allowedAttributes" in res[0])
2424 self.assertTrue("allowedAttributesEffective" in res[0])
2426 for m in res[0]["member"]:
2427 memberUP.append(m.upper())
2428 self.assertTrue(("CN=ldaptestuser2,CN=Users," + self.base_dn).upper() in memberUP)
2430 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs, controls=["extended_dn:1:1"])
2431 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))")
2433 print res[0]["member"]
2435 for m in res[0]["member"]:
2436 memberUP.append(m.upper())
2437 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()
2439 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)
2441 print "Quicktest for linked attributes"
2443 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2446 member: CN=ldaptestuser2,CN=Users,""" + self.base_dn + """
2447 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
2451 dn: <GUID=""" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + """>
2454 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
2458 dn: <SID=""" + ldb.schema_format_value("objectSid", res[0]["objectSid"][0]) + """>
2464 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2467 member: <GUID=""" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + """>
2468 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
2472 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2478 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2481 member: <SID=""" + ldb.schema_format_value("objectSid", res_user[0]["objectSid"][0]) + """>
2482 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
2486 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2489 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
2492 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs)
2493 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))")
2495 self.assertEquals(str(res[0].dn), ("CN=ldaptestgroup2,CN=Users," + self.base_dn))
2496 self.assertEquals(res[0]["member"][0], ("CN=ldaptestuser2,CN=Users," + self.base_dn))
2497 self.assertEquals(len(res[0]["member"]), 1)
2499 ldb.delete(("CN=ldaptestuser2,CN=Users," + self.base_dn))
2503 attrs = ["cn", "name", "objectClass", "objectGUID", "whenCreated", "nTSecurityDescriptor", "member"]
2504 print "Testing ldb.search for (&(cn=ldaptestgroup2)(objectClass=group)) to check linked delete"
2505 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs)
2506 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group)) to check linked delete")
2508 self.assertEquals(str(res[0].dn), ("CN=ldaptestgroup2,CN=Users," + self.base_dn))
2509 self.assertTrue("member" not in res[0])
2511 print "Testing ldb.search for (&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))"
2512 # TODO UTF8 users don't seem to work fully anymore
2513 # res = ldb.search(expression="(&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
2514 res = ldb.search(expression="(&(cn=ldaptestutf8user èùéìòà)(objectclass=user))")
2515 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
2517 self.assertEquals(str(res[0].dn), ("CN=ldaptestutf8user èùéìòà,CN=Users," + self.base_dn))
2518 self.assertEquals(str(res[0]["cn"]), "ldaptestutf8user èùéìòà")
2519 self.assertEquals(str(res[0]["name"]), "ldaptestutf8user èùéìòà")
2520 self.assertEquals(list(res[0]["objectClass"]), ["top", "person", "organizationalPerson", "user"])
2521 self.assertTrue("objectGUID" in res[0])
2522 self.assertTrue("whenCreated" in res[0])
2524 ldb.delete(res[0].dn)
2526 print "Testing ldb.search for (&(cn=ldaptestutf8user2*)(objectClass=user))"
2527 res = ldb.search(expression="(&(cn=ldaptestutf8user2*)(objectClass=user))")
2528 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestutf8user2*)(objectClass=user))")
2530 ldb.delete(res[0].dn)
2532 ldb.delete(("CN=ldaptestgroup2,CN=Users," + self.base_dn))
2534 print "Testing ldb.search for (&(cn=ldaptestutf8user2 ÈÙÉÌÒÀ)(objectClass=user))"
2535 # TODO UTF8 users don't seem to work fully anymore
2536 # res = ldb.search(expression="(&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
2537 # self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
2539 print "Testing that we can't get at the configuration DN from the main search base"
2540 res = ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
2541 self.assertEquals(len(res), 0)
2543 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"
2544 res = ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["search_options:1:2"])
2545 self.assertTrue(len(res) > 0)
2547 if gc_ldb is not None:
2548 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"
2550 res = gc_ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["search_options:1:0"])
2551 self.assertTrue(len(res) > 0)
2553 print "Testing that we do find configuration elements in the global catlog"
2554 res = gc_ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
2555 self.assertTrue(len(res) > 0)
2557 print "Testing that we do find configuration elements and user elements at the same time"
2558 res = gc_ldb.search(self.base_dn, expression="(|(objectClass=crossRef)(objectClass=person))", scope=SCOPE_SUBTREE, attrs=["cn"])
2559 self.assertTrue(len(res) > 0)
2561 print "Testing that we do find configuration elements in the global catlog, with the configuration basedn"
2562 res = gc_ldb.search(self.configuration_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
2563 self.assertTrue(len(res) > 0)
2565 print "Testing that we can get at the configuration DN on the main LDAP port"
2566 res = ldb.search(self.configuration_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
2567 self.assertTrue(len(res) > 0)
2569 print "Testing objectCategory canonacolisation"
2570 res = ldb.search(self.configuration_dn, expression="objectCategory=ntDsDSA", scope=SCOPE_SUBTREE, attrs=["cn"])
2571 self.assertTrue(len(res) > 0, "Didn't find any records with objectCategory=ntDsDSA")
2572 self.assertTrue(len(res) != 0)
2574 res = ldb.search(self.configuration_dn, expression="objectCategory=CN=ntDs-DSA," + self.schema_dn, scope=SCOPE_SUBTREE, attrs=["cn"])
2575 self.assertTrue(len(res) > 0, "Didn't find any records with objectCategory=CN=ntDs-DSA," + self.schema_dn)
2576 self.assertTrue(len(res) != 0)
2578 print "Testing objectClass attribute order on "+ self.base_dn
2579 res = ldb.search(expression="objectClass=domain", base=self.base_dn,
2580 scope=SCOPE_BASE, attrs=["objectClass"])
2581 self.assertEquals(len(res), 1)
2583 self.assertEquals(list(res[0]["objectClass"]), ["top", "domain", "domainDNS"])
2587 print "Testing ldb.search for objectCategory=person"
2588 res = ldb.search(self.base_dn, expression="objectCategory=person", scope=SCOPE_SUBTREE, attrs=["cn"])
2589 self.assertTrue(len(res) > 0)
2591 print "Testing ldb.search for objectCategory=person with domain scope control"
2592 res = ldb.search(self.base_dn, expression="objectCategory=person", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["domain_scope:1"])
2593 self.assertTrue(len(res) > 0)
2595 print "Testing ldb.search for objectCategory=user"
2596 res = ldb.search(self.base_dn, expression="objectCategory=user", scope=SCOPE_SUBTREE, attrs=["cn"])
2597 self.assertTrue(len(res) > 0)
2599 print "Testing ldb.search for objectCategory=user with domain scope control"
2600 res = ldb.search(self.base_dn, expression="objectCategory=user", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["domain_scope:1"])
2601 self.assertTrue(len(res) > 0)
2603 print "Testing ldb.search for objectCategory=group"
2604 res = ldb.search(self.base_dn, expression="objectCategory=group", scope=SCOPE_SUBTREE, attrs=["cn"])
2605 self.assertTrue(len(res) > 0)
2607 print "Testing ldb.search for objectCategory=group with domain scope control"
2608 res = ldb.search(self.base_dn, expression="objectCategory=group", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["domain_scope:1"])
2609 self.assertTrue(len(res) > 0)
2611 print "Testing creating a user with the posixAccount objectClass"
2612 self.ldb.add_ldif("""dn: cn=posixuser,CN=Users,%s
2615 objectClass: posixAccount
2617 objectClass: organizationalPerson
2623 homeDirectory: /home/posixuser
2624 loginShell: /bin/bash
2625 gecos: Posix User;;;
2626 description: A POSIX user"""% (self.base_dn))
2628 print "Testing removing the posixAccount objectClass from an existing user"
2629 self.ldb.modify_ldif("""dn: cn=posixuser,CN=Users,%s
2632 objectClass: posixAccount"""% (self.base_dn))
2634 print "Testing adding the posixAccount objectClass to an existing user"
2635 self.ldb.modify_ldif("""dn: cn=posixuser,CN=Users,%s
2638 objectClass: posixAccount"""% (self.base_dn))
2640 self.delete_force(self.ldb, "cn=posixuser,cn=users," + self.base_dn)
2641 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
2642 self.delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
2643 self.delete_force(self.ldb, "cn=ldaptestuser3,cn=users," + self.base_dn)
2644 self.delete_force(self.ldb, "cn=ldaptestuser4,cn=ldaptestcontainer," + self.base_dn)
2645 self.delete_force(self.ldb, "cn=ldaptestuser4,cn=ldaptestcontainer2," + self.base_dn)
2646 self.delete_force(self.ldb, "cn=ldaptestuser5,cn=users," + self.base_dn)
2647 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
2648 self.delete_force(self.ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
2649 self.delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2650 self.delete_force(self.ldb, "cn=ldaptest2computer,cn=computers," + self.base_dn)
2651 self.delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
2652 self.delete_force(self.ldb, "cn=ldaptestutf8user èùéìòà,cn=users," + self.base_dn)
2653 self.delete_force(self.ldb, "cn=ldaptestutf8user2 èùéìòà,cn=users," + self.base_dn)
2654 self.delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
2655 self.delete_force(self.ldb, "cn=ldaptestcontainer2," + self.base_dn)
2657 def test_security_descriptor_add(self):
2658 """ Testing ldb.add_ldif() for nTSecurityDescriptor """
2659 user_name = "testdescriptoruser1"
2660 user_dn = "CN=%s,CN=Users,%s" % (user_name, self.base_dn)
2662 # Test add_ldif() with SDDL security descriptor input
2664 self.delete_force(self.ldb, user_dn)
2666 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2667 self.ldb.add_ldif("""
2668 dn: """ + user_dn + """
2670 sAMAccountName: """ + user_name + """
2671 nTSecurityDescriptor: """ + sddl)
2672 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2673 desc = res[0]["nTSecurityDescriptor"][0]
2674 desc = ndr_unpack( security.descriptor, desc )
2675 desc_sddl = desc.as_sddl( self.domain_sid )
2676 self.assertEqual(desc_sddl, sddl)
2678 self.delete_force(self.ldb, user_dn)
2680 # Test add_ldif() with BASE64 security descriptor
2683 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2684 desc = security.descriptor.from_sddl(sddl, self.domain_sid)
2685 desc_binary = ndr_pack(desc)
2686 desc_base64 = base64.b64encode(desc_binary)
2687 self.ldb.add_ldif("""
2688 dn: """ + user_dn + """
2690 sAMAccountName: """ + user_name + """
2691 nTSecurityDescriptor:: """ + desc_base64)
2692 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2693 desc = res[0]["nTSecurityDescriptor"][0]
2694 desc = ndr_unpack(security.descriptor, desc)
2695 desc_sddl = desc.as_sddl(self.domain_sid)
2696 self.assertEqual(desc_sddl, sddl)
2698 self.delete_force(self.ldb, user_dn)
2700 def test_security_descriptor_add_neg(self):
2701 """Test add_ldif() with BASE64 security descriptor input using WRONG domain SID
2704 user_name = "testdescriptoruser1"
2705 user_dn = "CN=%s,CN=Users,%s" % (user_name, self.base_dn)
2706 self.delete_force(self.ldb, user_dn)
2708 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2709 desc = security.descriptor.from_sddl(sddl, security.dom_sid('S-1-5-21'))
2710 desc_base64 = base64.b64encode( ndr_pack(desc) )
2711 self.ldb.add_ldif("""
2712 dn: """ + user_dn + """
2714 sAMAccountName: """ + user_name + """
2715 nTSecurityDescriptor:: """ + desc_base64)
2716 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2717 self.assertTrue("nTSecurityDescriptor" in res[0])
2719 self.delete_force(self.ldb, user_dn)
2721 def test_security_descriptor_modify(self):
2722 """ Testing ldb.modify_ldif() for nTSecurityDescriptor """
2723 user_name = "testdescriptoruser2"
2724 user_dn = "CN=%s,CN=Users,%s" % (user_name, self.base_dn)
2726 # Delete user object and test modify_ldif() with SDDL security descriptor input
2727 # Add ACE to the original descriptor test
2730 self.delete_force(self.ldb, user_dn)
2731 self.ldb.add_ldif("""
2732 dn: """ + user_dn + """
2734 sAMAccountName: """ + user_name)
2736 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2737 desc = res[0]["nTSecurityDescriptor"][0]
2738 desc = ndr_unpack(security.descriptor, desc)
2739 desc_sddl = desc.as_sddl(self.domain_sid)
2740 sddl = desc_sddl[:desc_sddl.find("(")] + "(A;;RPWP;;;AU)" + desc_sddl[desc_sddl.find("("):]
2742 dn: """ + user_dn + """
2744 replace: nTSecurityDescriptor
2745 nTSecurityDescriptor: """ + sddl
2746 self.ldb.modify_ldif(mod)
2747 # Read modified descriptor
2748 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2749 desc = res[0]["nTSecurityDescriptor"][0]
2750 desc = ndr_unpack(security.descriptor, desc)
2751 desc_sddl = desc.as_sddl(self.domain_sid)
2752 self.assertEqual(desc_sddl, sddl)
2754 self.delete_force(self.ldb, user_dn)
2756 # Test modify_ldif() with SDDL security descriptor input
2757 # New desctiptor test
2760 self.ldb.add_ldif("""
2761 dn: """ + user_dn + """
2763 sAMAccountName: """ + user_name)
2765 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2767 dn: """ + user_dn + """
2769 replace: nTSecurityDescriptor
2770 nTSecurityDescriptor: """ + sddl
2771 self.ldb.modify_ldif(mod)
2772 # Read modified descriptor
2773 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2774 desc = res[0]["nTSecurityDescriptor"][0]
2775 desc = ndr_unpack(security.descriptor, desc)
2776 desc_sddl = desc.as_sddl(self.domain_sid)
2777 self.assertEqual(desc_sddl, sddl)
2779 self.delete_force(self.ldb, user_dn)
2781 # Test modify_ldif() with BASE64 security descriptor input
2782 # Add ACE to the original descriptor test
2785 self.ldb.add_ldif("""
2786 dn: """ + user_dn + """
2788 sAMAccountName: """ + user_name)
2790 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2791 desc = res[0]["nTSecurityDescriptor"][0]
2792 desc = ndr_unpack(security.descriptor, desc)
2793 desc_sddl = desc.as_sddl(self.domain_sid)
2794 sddl = desc_sddl[:desc_sddl.find("(")] + "(A;;RPWP;;;AU)" + desc_sddl[desc_sddl.find("("):]
2795 desc = security.descriptor.from_sddl(sddl, self.domain_sid)
2796 desc_base64 = base64.b64encode(ndr_pack(desc))
2798 dn: """ + user_dn + """
2800 replace: nTSecurityDescriptor
2801 nTSecurityDescriptor:: """ + desc_base64
2802 self.ldb.modify_ldif(mod)
2803 # Read modified descriptor
2804 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2805 desc = res[0]["nTSecurityDescriptor"][0]
2806 desc = ndr_unpack(security.descriptor, desc)
2807 desc_sddl = desc.as_sddl(self.domain_sid)
2808 self.assertEqual(desc_sddl, sddl)
2810 self.delete_force(self.ldb, user_dn)
2812 # Test modify_ldif() with BASE64 security descriptor input
2813 # New descriptor test
2816 self.delete_force(self.ldb, user_dn)
2817 self.ldb.add_ldif("""
2818 dn: """ + user_dn + """
2820 sAMAccountName: """ + user_name)
2822 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2823 desc = security.descriptor.from_sddl(sddl, self.domain_sid)
2824 desc_base64 = base64.b64encode(ndr_pack(desc))
2826 dn: """ + user_dn + """
2828 replace: nTSecurityDescriptor
2829 nTSecurityDescriptor:: """ + desc_base64
2830 self.ldb.modify_ldif(mod)
2831 # Read modified descriptor
2832 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2833 desc = res[0]["nTSecurityDescriptor"][0]
2834 desc = ndr_unpack(security.descriptor, desc)
2835 desc_sddl = desc.as_sddl(self.domain_sid)
2836 self.assertEqual(desc_sddl, sddl)
2838 self.delete_force(self.ldb, user_dn)
2841 class BaseDnTests(unittest.TestCase):
2844 super(BaseDnTests, self).setUp()
2847 def test_rootdse_attrs(self):
2848 """Testing for all rootDSE attributes"""
2849 res = self.ldb.search(scope=SCOPE_BASE, attrs=[])
2850 self.assertEquals(len(res), 1)
2852 def test_highestcommittedusn(self):
2853 """Testing for highestCommittedUSN"""
2854 res = self.ldb.search("", scope=SCOPE_BASE, attrs=["highestCommittedUSN"])
2855 self.assertEquals(len(res), 1)
2856 self.assertTrue(int(res[0]["highestCommittedUSN"][0]) != 0)
2858 def test_netlogon(self):
2859 """Testing for netlogon via LDAP"""
2860 res = self.ldb.search("", scope=SCOPE_BASE, attrs=["netlogon"])
2861 self.assertEquals(len(res), 0)
2863 def test_netlogon_highestcommitted_usn(self):
2864 """Testing for netlogon and highestCommittedUSN via LDAP"""
2865 res = self.ldb.search("", scope=SCOPE_BASE,
2866 attrs=["netlogon", "highestCommittedUSN"])
2867 self.assertEquals(len(res), 0)
2869 def test_namingContexts(self):
2870 """Testing for namingContexts in rootDSE"""
2871 res = self.ldb.search("", scope=SCOPE_BASE,
2872 attrs=["namingContexts", "defaultNamingContext", "schemaNamingContext", "configurationNamingContext"])
2873 self.assertEquals(len(res), 1)
2876 for nc in res[0]["namingContexts"]:
2877 self.assertTrue(nc not in ncs)
2880 self.assertTrue(res[0]["defaultNamingContext"][0] in ncs)
2881 self.assertTrue(res[0]["configurationNamingContext"][0] in ncs)
2882 self.assertTrue(res[0]["schemaNamingContext"][0] in ncs)
2885 if not "://" in host:
2886 if os.path.isfile(host):
2887 host = "tdb://%s" % host
2889 host = "ldap://%s" % host
2891 ldb = Ldb(host, credentials=creds, session_info=system_session(), lp=lp)
2892 if not "tdb://" in host:
2893 gc_ldb = Ldb("%s:3268" % host, credentials=creds,
2894 session_info=system_session(), lp=lp)
2898 runner = SubunitTestRunner()
2900 if not runner.run(unittest.makeSuite(BaseDnTests)).wasSuccessful():
2902 if not runner.run(unittest.makeSuite(BasicTests)).wasSuccessful():