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_WORKSTATION_TRUST_ACCOUNT,
31 UF_PASSWD_NOTREQD, UF_ACCOUNTDISABLE, ATYPE_NORMAL_ACCOUNT,
32 ATYPE_WORKSTATION_TRUST)
34 from subunit.run import SubunitTestRunner
37 from samba.ndr import ndr_pack, ndr_unpack
38 from samba.dcerpc import security
40 parser = optparse.OptionParser("ldap [options] <host>")
41 sambaopts = options.SambaOptions(parser)
42 parser.add_option_group(sambaopts)
43 parser.add_option_group(options.VersionOptions(parser))
44 # use command line creds if available
45 credopts = options.CredentialsOptions(parser)
46 parser.add_option_group(credopts)
47 opts, args = parser.parse_args()
55 lp = sambaopts.get_loadparm()
56 creds = credopts.get_credentials(lp)
58 class BasicTests(unittest.TestCase):
60 def delete_force(self, ldb, dn):
63 except LdbError, (num, _):
64 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
66 def find_basedn(self, ldb):
67 res = ldb.search(base="", expression="", scope=SCOPE_BASE,
68 attrs=["defaultNamingContext"])
69 self.assertEquals(len(res), 1)
70 return res[0]["defaultNamingContext"][0]
72 def find_configurationdn(self, ldb):
73 res = ldb.search(base="", expression="", scope=SCOPE_BASE, attrs=["configurationNamingContext"])
74 self.assertEquals(len(res), 1)
75 return res[0]["configurationNamingContext"][0]
77 def find_schemadn(self, ldb):
78 res = ldb.search(base="", expression="", scope=SCOPE_BASE, attrs=["schemaNamingContext"])
79 self.assertEquals(len(res), 1)
80 return res[0]["schemaNamingContext"][0]
82 def find_domain_sid(self):
83 res = self.ldb.search(base=self.base_dn, expression="(objectClass=*)", scope=SCOPE_BASE)
84 return ndr_unpack( security.dom_sid,res[0]["objectSid"][0])
87 super(BasicTests, self).setUp()
90 self.base_dn = self.find_basedn(ldb)
91 self.configuration_dn = self.find_configurationdn(ldb)
92 self.schema_dn = self.find_schemadn(ldb)
93 self.domain_sid = self.find_domain_sid()
95 print "baseDN: %s\n" % self.base_dn
97 self.delete_force(self.ldb, "cn=posixuser,cn=users," + self.base_dn)
98 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
99 self.delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
100 self.delete_force(self.ldb, "cn=ldaptestuser3,cn=users," + self.base_dn)
101 self.delete_force(self.ldb, "cn=ldaptestuser4,cn=ldaptestcontainer," + self.base_dn)
102 self.delete_force(self.ldb, "cn=ldaptestuser4,cn=ldaptestcontainer2," + self.base_dn)
103 self.delete_force(self.ldb, "cn=ldaptestuser5,cn=users," + self.base_dn)
104 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
105 self.delete_force(self.ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
106 self.delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
107 self.delete_force(self.ldb, "cn=ldaptest2computer,cn=computers," + self.base_dn)
108 self.delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
109 self.delete_force(self.ldb, "cn=ldaptestutf8user èùéìòà,cn=users," + self.base_dn)
110 self.delete_force(self.ldb, "cn=ldaptestutf8user2 èùéìòà,cn=users," + self.base_dn)
111 self.delete_force(self.ldb, "cn=entry1,cn=ldaptestcontainer," + self.base_dn)
112 self.delete_force(self.ldb, "cn=entry2,cn=ldaptestcontainer," + self.base_dn)
113 self.delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
114 self.delete_force(self.ldb, "cn=ldaptestcontainer2," + self.base_dn)
115 self.delete_force(self.ldb, "cn=parentguidtest,cn=users," + self.base_dn)
116 self.delete_force(self.ldb, "cn=parentguidtest,cn=testotherusers," + self.base_dn)
117 self.delete_force(self.ldb, "cn=testotherusers," + self.base_dn)
118 self.delete_force(self.ldb, "cn=ldaptestobject," + self.base_dn)
119 self.delete_force(self.ldb, "description=xyz,cn=users," + self.base_dn)
120 self.delete_force(self.ldb, "ou=testou,cn=users," + self.base_dn)
122 def test_objectclasses(self):
123 """Test objectClass behaviour"""
124 print "Test objectClass behaviour"""
126 # Invalid objectclass specified
129 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
130 "objectClass": "X" })
132 except LdbError, (num, _):
133 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
135 # We cannot instanciate from an abstract objectclass
138 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
139 "objectClass": "connectionPoint" })
141 except LdbError, (num, _):
142 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
145 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
146 "objectClass": "person" })
148 # We can remove derivation classes of the structural objectclass
149 # but they're going to be readded afterwards
151 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
152 m["objectClass"] = MessageElement("top", FLAG_MOD_DELETE,
156 res = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
157 scope=SCOPE_BASE, attrs=["objectClass"])
158 self.assertTrue(len(res) == 1)
159 self.assertTrue("top" in res[0]["objectClass"])
161 # The top-most structural class cannot be deleted since there are
162 # attributes of it in use
164 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
165 m["objectClass"] = MessageElement("person", FLAG_MOD_DELETE,
170 except LdbError, (num, _):
171 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
173 # We cannot delete classes which weren't specified
175 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
176 m["objectClass"] = MessageElement("computer", FLAG_MOD_DELETE,
181 except LdbError, (num, _):
182 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
184 # An invalid class cannot be added
186 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
187 m["objectClass"] = MessageElement("X", FLAG_MOD_ADD,
192 except LdbError, (num, _):
193 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
195 # The top-most structural class cannot be changed by adding another
198 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
199 m["objectClass"] = MessageElement("user", FLAG_MOD_ADD,
204 except LdbError, (num, _):
205 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
207 # An already specified objectclass cannot be added another time
209 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
210 m["objectClass"] = MessageElement("person", FLAG_MOD_ADD,
215 except LdbError, (num, _):
216 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
218 # Auxiliary classes can always be added
220 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
221 m["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_ADD,
225 # It's only possible to replace with the same objectclass combination.
226 # So the replace action on "objectClass" attributes is really useless.
228 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
229 m["objectClass"] = MessageElement(["top", "person", "bootableDevice"],
230 FLAG_MOD_REPLACE, "objectClass")
234 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
235 m["objectClass"] = MessageElement(["person", "bootableDevice"],
236 FLAG_MOD_REPLACE, "objectClass")
240 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
241 m["objectClass"] = MessageElement(["top", "person", "bootableDevice",
242 "connectionPoint"], FLAG_MOD_REPLACE, "objectClass")
246 except LdbError, (num, _):
247 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
250 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
251 m["objectClass"] = MessageElement(["top", "computer"], FLAG_MOD_REPLACE,
256 except LdbError, (num, _):
257 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
259 # Classes can be removed unless attributes of them are used.
261 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
262 m["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_DELETE,
266 res = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
267 scope=SCOPE_BASE, attrs=["objectClass"])
268 self.assertTrue(len(res) == 1)
269 self.assertFalse("bootableDevice" in res[0]["objectClass"])
272 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
273 m["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_ADD,
277 # Add an attribute specific to the "bootableDevice" class
279 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
280 m["bootParameter"] = MessageElement("test", FLAG_MOD_ADD,
284 # Classes can be removed unless attributes of them are used. Now there
285 # exist such attributes on the entry.
287 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
288 m["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_DELETE,
293 except LdbError, (num, _):
294 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
296 # Remove the previously specified attribute
298 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
299 m["bootParameter"] = MessageElement("test", FLAG_MOD_DELETE,
303 # Classes can be removed unless attributes of them are used.
305 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
306 m["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_DELETE,
310 self.delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
312 def test_system_only(self):
313 """Test systemOnly objects"""
314 print "Test systemOnly objects"""
318 "dn": "cn=ldaptestobject," + self.base_dn,
319 "objectclass": "configuration"})
321 except LdbError, (num, _):
322 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
324 self.delete_force(self.ldb, "cn=ldaptestobject," + self.base_dn)
326 def test_invalid_parent(self):
327 """Test adding an object with invalid parent"""
328 print "Test adding an object with invalid parent"""
332 "dn": "cn=ldaptestgroup,cn=thisdoesnotexist123,"
334 "objectclass": "group"})
336 except LdbError, (num, _):
337 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
339 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=thisdoesnotexist123,"
344 "dn": "ou=testou,cn=users," + self.base_dn,
345 "objectclass": "organizationalUnit"})
347 except LdbError, (num, _):
348 self.assertEquals(num, ERR_NAMING_VIOLATION)
350 self.delete_force(self.ldb, "ou=testou,cn=users," + self.base_dn)
352 def test_invalid_attribute(self):
353 """Test invalid attributes on schema/objectclasses"""
354 print "Test invalid attributes on schema/objectclasses"""
356 # attributes not in schema test
362 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
363 "objectclass": "group",
364 "thisdoesnotexist": "x"})
366 except LdbError, (num, _):
367 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
370 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
371 "objectclass": "group"})
376 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
377 m["thisdoesnotexist"] = MessageElement("x", FLAG_MOD_REPLACE,
382 except LdbError, (num, _):
383 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
385 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
387 # attributes not in objectclasses and mandatory attributes missing test
388 # Use here a non-SAM entry since it doesn't have special triggers
389 # associated which have an impact on the error results.
393 # mandatory attribute missing
396 "dn": "cn=ldaptestobject," + self.base_dn,
397 "objectclass": "ipProtocol"})
399 except LdbError, (num, _):
400 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
402 # inadequate but schema-valid attribute specified
405 "dn": "cn=ldaptestobject," + self.base_dn,
406 "objectclass": "ipProtocol",
407 "ipProtocolNumber": "1",
410 except LdbError, (num, _):
411 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
414 "dn": "cn=ldaptestobject," + self.base_dn,
415 "objectclass": "ipProtocol",
416 "ipProtocolNumber": "1"})
420 # inadequate but schema-valid attribute add trial
422 m.dn = Dn(ldb, "cn=ldaptestobject," + self.base_dn)
423 m["uid"] = MessageElement("0", FLAG_MOD_ADD, "uid")
427 except LdbError, (num, _):
428 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
430 # mandatory attribute delete trial
432 m.dn = Dn(ldb, "cn=ldaptestobject," + self.base_dn)
433 m["ipProtocolNumber"] = MessageElement([], FLAG_MOD_DELETE,
438 except LdbError, (num, _):
439 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
441 # mandatory attribute delete trial
443 m.dn = Dn(ldb, "cn=ldaptestobject," + self.base_dn)
444 m["ipProtocolNumber"] = MessageElement([], FLAG_MOD_REPLACE,
449 except LdbError, (num, _):
450 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
452 self.delete_force(self.ldb, "cn=ldaptestobject," + self.base_dn)
454 def test_single_valued_attributes(self):
455 """Test single-valued attributes"""
456 print "Test single-valued attributes"""
460 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
461 "objectclass": "group",
462 "sAMAccountName": ["nam1", "nam2"]})
464 except LdbError, (num, _):
465 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
468 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
469 "objectclass": "group"})
472 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
473 m["sAMAccountName"] = MessageElement(["nam1","nam2"], FLAG_MOD_REPLACE,
478 except LdbError, (num, _):
479 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
482 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
483 m["sAMAccountName"] = MessageElement("testgroupXX", FLAG_MOD_REPLACE,
488 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
489 m["sAMAccountName"] = MessageElement("testgroupXX2", FLAG_MOD_ADD,
494 except LdbError, (num, _):
495 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
497 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
499 def test_multi_valued_attributes(self):
500 """Test multi-valued attributes"""
501 print "Test multi-valued attributes"""
503 # TODO: In this test I added some special tests where I got very unusual
504 # results back from a real AD. s4 doesn't match them and I've no idea how to
505 # implement those error cases (maybe there exists a special trigger for
506 # "description" attributes which handle them)
509 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
510 "description": "desc2",
511 "objectclass": "group",
512 "description": "desc1"})
514 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
517 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
518 "objectclass": "group",
519 "description": ["desc1", "desc2"]})
522 # m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
523 # m["description"] = MessageElement(["desc1","desc2"], FLAG_MOD_REPLACE,
528 # except LdbError, (num, _):
529 # self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
532 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
533 m["description"] = MessageElement("desc1", FLAG_MOD_REPLACE,
538 # m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
539 # m["description"] = MessageElement("desc3", FLAG_MOD_ADD,
544 # except LdbError, (num, _):
545 # self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
548 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
549 m["description"] = MessageElement(["desc1","desc2"], FLAG_MOD_DELETE,
554 except LdbError, (num, _):
555 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
558 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
559 m["description"] = MessageElement("desc1", FLAG_MOD_DELETE,
564 # m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
565 # m["description"] = MessageElement(["desc1","desc2"], FLAG_MOD_REPLACE,
570 # except LdbError, (num, _):
571 # self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
574 # m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
575 # m["description"] = MessageElement(["desc3", "desc4"], FLAG_MOD_ADD,
580 # except LdbError, (num, _):
581 # self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
584 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
585 m["description"] = MessageElement("desc3", FLAG_MOD_ADD,
589 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
591 def test_empty_messages(self):
592 """Test empty messages"""
593 print "Test empty messages"""
596 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
601 except LdbError, (num, _):
602 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
607 except LdbError, (num, _):
608 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
610 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
612 def test_empty_attributes(self):
613 """Test empty attributes"""
614 print "Test empty attributes"""
617 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
618 m["objectClass"] = MessageElement("group", FLAG_MOD_ADD, "objectClass")
619 m["description"] = MessageElement([], FLAG_MOD_ADD, "description")
624 except LdbError, (num, _):
625 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
628 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
629 "objectclass": "group"})
632 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
633 m["description"] = MessageElement([], FLAG_MOD_ADD, "description")
638 except LdbError, (num, _):
639 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
642 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
643 m["description"] = MessageElement([], FLAG_MOD_REPLACE, "description")
647 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
648 m["description"] = MessageElement([], FLAG_MOD_DELETE, "description")
652 except LdbError, (num, _):
653 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
655 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
657 def test_instanceType(self):
658 """Tests the 'instanceType' attribute"""
659 print "Tests the 'instanceType' attribute"""
661 # The instance type is single-valued
664 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
665 "objectclass": "group",
666 "instanceType": ["0", "1"]})
668 except LdbError, (num, _):
669 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
671 # The head NC flag cannot be set without the write flag
674 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
675 "objectclass": "group",
676 "instanceType": "1" })
678 except LdbError, (num, _):
679 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
681 # We cannot manipulate NCs without the head NC flag
684 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
685 "objectclass": "group",
686 "instanceType": "32" })
688 except LdbError, (num, _):
689 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
692 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
693 "objectclass": "group"})
696 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
697 m["instanceType"] = MessageElement("0", FLAG_MOD_REPLACE,
702 except LdbError, (num, _):
703 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
706 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
707 m["instanceType"] = MessageElement([], FLAG_MOD_REPLACE,
712 except LdbError, (num, _):
713 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
716 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
717 m["instanceType"] = MessageElement([], FLAG_MOD_DELETE, "instanceType")
721 except LdbError, (num, _):
722 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
724 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
726 def test_distinguished_name(self):
727 """Tests the 'distinguishedName' attribute"""
728 print "Tests the 'distinguishedName' attribute"""
730 # a wrong "distinguishedName" attribute is obviously tolerated
732 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
733 "objectclass": "group",
734 "distinguishedName": "cn=ldaptest,cn=users," + self.base_dn})
736 # proof if the DN has been set correctly
737 res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
738 scope=SCOPE_BASE, attrs=["distinguishedName"])
739 self.assertTrue(len(res) == 1)
740 self.assertTrue("distinguishedName" in res[0])
741 self.assertTrue(Dn(ldb, res[0]["distinguishedName"][0])
742 == Dn(ldb, "cn=ldaptestgroup, cn=users," + self.base_dn))
745 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
746 m["distinguishedName"] = MessageElement(
747 "cn=ldaptestuser,cn=users," + self.base_dn, FLAG_MOD_ADD,
753 except LdbError, (num, _):
754 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
757 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
758 m["distinguishedName"] = MessageElement(
759 "cn=ldaptestuser,cn=users," + self.base_dn, FLAG_MOD_REPLACE,
765 except LdbError, (num, _):
766 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
769 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
770 m["distinguishedName"] = MessageElement(
771 "cn=ldaptestuser,cn=users," + self.base_dn, FLAG_MOD_DELETE,
777 except LdbError, (num, _):
778 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
780 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
782 def test_rdn_name(self):
784 print "Tests the RDN"""
788 "dn": "description=xyz,cn=users," + self.base_dn,
789 "objectclass": "group"})
791 except LdbError, (num, _):
792 self.assertEquals(num, ERR_NAMING_VIOLATION)
794 self.delete_force(self.ldb, "description=xyz,cn=users," + self.base_dn)
796 # a wrong "name" attribute is obviously tolerated
798 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
799 "objectclass": "group",
800 "name": "ldaptestgroupx"})
802 # proof if the name has been set correctly
803 res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
804 scope=SCOPE_BASE, attrs=["name"])
805 self.assertTrue(len(res) == 1)
806 self.assertTrue("name" in res[0])
807 self.assertTrue(res[0]["name"][0] == "ldaptestgroup")
810 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
811 m["name"] = MessageElement("cn=ldaptestuser", FLAG_MOD_REPLACE,
816 except LdbError, (num, _):
817 self.assertEquals(num, ERR_NOT_ALLOWED_ON_RDN)
820 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
821 m["cn"] = MessageElement("ldaptestuser",
822 FLAG_MOD_REPLACE, "cn")
826 except LdbError, (num, _):
827 self.assertEquals(num, ERR_NOT_ALLOWED_ON_RDN)
829 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
832 # this test needs to be disabled until we really understand
833 # what the rDN length constraints are
834 def DISABLED_test_largeRDN(self):
835 """Testing large rDN (limit 64 characters)"""
836 rdn = "CN=a012345678901234567890123456789012345678901234567890123456789012";
837 self.delete_force(self.ldb, "%s,%s" % (rdn, self.base_dn))
839 dn: %s,%s""" % (rdn,self.base_dn) + """
840 objectClass: container
842 self.ldb.add_ldif(ldif)
843 self.delete_force(self.ldb, "%s,%s" % (rdn, self.base_dn))
845 rdn = "CN=a0123456789012345678901234567890123456789012345678901234567890120";
846 self.delete_force(self.ldb, "%s,%s" % (rdn, self.base_dn))
849 dn: %s,%s""" % (rdn,self.base_dn) + """
850 objectClass: container
852 self.ldb.add_ldif(ldif)
854 except LdbError, (num, _):
855 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
856 self.delete_force(self.ldb, "%s,%s" % (rdn, self.base_dn))
858 def test_rename(self):
859 """Tests the rename operation"""
860 print "Tests the rename operations"""
863 # cannot rename to be a child of itself
864 ldb.rename(self.base_dn, "dc=test," + self.base_dn)
866 except LdbError, (num, _):
867 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
871 ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser2,cn=users," + self.base_dn)
873 except LdbError, (num, _):
874 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
877 "dn": "cn=ldaptestuser2,cn=users," + self.base_dn,
878 "objectclass": ["user", "person"] })
880 ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser2,cn=users," + self.base_dn)
881 ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=users," + self.base_dn)
882 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestUSER3,cn=users," + self.base_dn)
885 # containment problem: a user entry cannot contain user entries
886 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser4,cn=ldaptestuser3,cn=users," + self.base_dn)
888 except LdbError, (num, _):
889 self.assertEquals(num, ERR_NAMING_VIOLATION)
893 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=people,cn=users," + self.base_dn)
895 except LdbError, (num, _):
896 self.assertEquals(num, ERR_OTHER)
899 # invalid target DN syntax
900 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, ",cn=users," + self.base_dn)
902 except LdbError, (num, _):
903 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
907 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "ou=ldaptestuser3,cn=users," + self.base_dn)
909 except LdbError, (num, _):
910 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
912 self.delete_force(self.ldb, "cn=ldaptestuser3,cn=users," + self.base_dn)
914 # Performs some "systemFlags" testing
916 # Move failing since no "SYSTEM_FLAG_CONFIG_ALLOW_MOVE"
918 ldb.rename("CN=DisplaySpecifiers," + self.configuration_dn, "CN=DisplaySpecifiers,CN=Services," + self.configuration_dn)
920 except LdbError, (num, _):
921 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
923 # Limited move failing since no "SYSTEM_FLAG_CONFIG_ALLOW_LIMITED_MOVE"
925 ldb.rename("CN=Directory Service,CN=Windows NT,CN=Services," + self.configuration_dn, "CN=Directory Service,CN=RRAS,CN=Services," + self.configuration_dn)
927 except LdbError, (num, _):
928 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
930 # Rename failing since no "SYSTEM_FLAG_CONFIG_ALLOW_RENAME"
932 ldb.rename("CN=DisplaySpecifiers," + self.configuration_dn, "CN=DisplaySpecifiers2," + self.configuration_dn)
934 except LdbError, (num, _):
935 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
937 # It's not really possible to test moves on the schema partition since
938 # there don't exist subcontainers on it.
940 # Rename failing since "SYSTEM_FLAG_SCHEMA_BASE_OBJECT"
942 ldb.rename("CN=Top," + self.schema_dn, "CN=Top2," + self.schema_dn)
944 except LdbError, (num, _):
945 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
947 # Move failing since "SYSTEM_FLAG_DOMAIN_DISALLOW_MOVE"
949 ldb.rename("CN=Users," + self.base_dn, "CN=Users,CN=Computers," + self.base_dn)
951 except LdbError, (num, _):
952 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
954 # Rename failing since "SYSTEM_FLAG_DOMAIN_DISALLOW_RENAME"
956 ldb.rename("CN=Users," + self.base_dn, "CN=Users2," + self.base_dn)
958 except LdbError, (num, _):
959 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
961 # Performs some other constraints testing
964 ldb.rename("CN=Policies,CN=System," + self.base_dn, "CN=Users2," + self.base_dn)
966 except LdbError, (num, _):
967 self.assertEquals(num, ERR_OTHER)
969 def test_rename_twice(self):
970 """Tests the rename operation twice - this corresponds to a past bug"""
971 print "Tests the rename twice operation"""
974 "dn": "cn=ldaptestuser5,cn=users," + self.base_dn,
975 "objectclass": ["user", "person"] })
977 ldb.rename("cn=ldaptestuser5,cn=users," + self.base_dn, "cn=ldaptestUSER5,cn=users," + self.base_dn)
978 self.delete_force(self.ldb, "cn=ldaptestuser5,cn=users," + self.base_dn)
980 "dn": "cn=ldaptestuser5,cn=users," + self.base_dn,
981 "objectclass": ["user", "person"] })
982 ldb.rename("cn=ldaptestuser5,cn=Users," + self.base_dn, "cn=ldaptestUSER5,cn=users," + self.base_dn)
983 res = ldb.search(expression="cn=ldaptestuser5")
984 print "Found %u records" % len(res)
985 self.assertEquals(len(res), 1, "Wrong number of hits for cn=ldaptestuser5")
986 res = ldb.search(expression="(&(cn=ldaptestuser5)(objectclass=user))")
987 print "Found %u records" % len(res)
988 self.assertEquals(len(res), 1, "Wrong number of hits for (&(cn=ldaptestuser5)(objectclass=user))")
989 self.delete_force(self.ldb, "cn=ldaptestuser5,cn=users," + self.base_dn)
991 def test_parentGUID(self):
992 """Test parentGUID behaviour"""
993 print "Testing parentGUID behaviour\n"
995 # TODO: This seems to fail on Windows Server. Hidden attribute?
998 "dn": "cn=parentguidtest,cn=users," + self.base_dn,
999 "objectclass":"user",
1000 "samaccountname":"parentguidtest"});
1001 res1 = ldb.search(base="cn=parentguidtest,cn=users," + self.base_dn, scope=SCOPE_BASE,
1002 attrs=["parentGUID", "samaccountname"]);
1003 res2 = ldb.search(base="cn=users," + self.base_dn,scope=SCOPE_BASE,
1004 attrs=["objectGUID"]);
1005 res3 = ldb.search(base=self.base_dn, scope=SCOPE_BASE,
1006 attrs=["parentGUID"]);
1008 """Check if the parentGUID is valid """
1009 self.assertEquals(res1[0]["parentGUID"], res2[0]["objectGUID"]);
1011 """Check if it returns nothing when there is no parent object"""
1012 has_parentGUID = False
1013 for key in res3[0].keys():
1014 if key == "parentGUID":
1015 has_parentGUID = True
1017 self.assertFalse(has_parentGUID);
1019 """Ensures that if you look for another object attribute after the constructed
1020 parentGUID, it will return correctly"""
1021 has_another_attribute = False
1022 for key in res1[0].keys():
1023 if key == "sAMAccountName":
1024 has_another_attribute = True
1026 self.assertTrue(has_another_attribute)
1027 self.assertTrue(len(res1[0]["samaccountname"]) == 1)
1028 self.assertEquals(res1[0]["samaccountname"][0], "parentguidtest");
1030 print "Testing parentGUID behaviour on rename\n"
1033 "dn": "cn=testotherusers," + self.base_dn,
1034 "objectclass":"container"});
1035 res1 = ldb.search(base="cn=testotherusers," + self.base_dn,scope=SCOPE_BASE,
1036 attrs=["objectGUID"]);
1037 ldb.rename("cn=parentguidtest,cn=users," + self.base_dn,
1038 "cn=parentguidtest,cn=testotherusers," + self.base_dn);
1039 res2 = ldb.search(base="cn=parentguidtest,cn=testotherusers," + self.base_dn,
1041 attrs=["parentGUID"]);
1042 self.assertEquals(res1[0]["objectGUID"], res2[0]["parentGUID"]);
1044 self.delete_force(self.ldb, "cn=parentguidtest,cn=testotherusers," + self.base_dn)
1045 self.delete_force(self.ldb, "cn=testotherusers," + self.base_dn)
1047 def test_groupType_int32(self):
1048 """Test groupType (int32) behaviour (should appear to be casted to a 32 bit signed integer before comparsion)"""
1049 print "Testing groupType (int32) behaviour\n"
1051 res1 = ldb.search(base=self.base_dn, scope=SCOPE_SUBTREE,
1052 attrs=["groupType"], expression="groupType=2147483653");
1054 res2 = ldb.search(base=self.base_dn, scope=SCOPE_SUBTREE,
1055 attrs=["groupType"], expression="groupType=-2147483643");
1057 self.assertEquals(len(res1), len(res2))
1059 self.assertTrue(res1.count > 0)
1061 self.assertEquals(res1[0]["groupType"][0], "-2147483643")
1063 def test_linked_attributes(self):
1064 """This tests the linked attribute behaviour"""
1065 print "Testing linked attribute behaviour\n"
1068 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
1069 "objectclass": "group"})
1071 # This should not work since "memberOf" is linked to "member"
1074 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1075 "objectclass": ["user", "person"],
1076 "memberOf": "cn=ldaptestgroup,cn=users," + self.base_dn})
1077 except LdbError, (num, _):
1078 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1081 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1082 "objectclass": ["user", "person"]})
1085 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1086 m["memberOf"] = MessageElement("cn=ldaptestgroup,cn=users," + self.base_dn,
1087 FLAG_MOD_ADD, "memberOf")
1091 except LdbError, (num, _):
1092 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1095 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1096 m["member"] = MessageElement("cn=ldaptestuser,cn=users," + self.base_dn,
1097 FLAG_MOD_ADD, "member")
1101 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1102 m["memberOf"] = MessageElement("cn=ldaptestgroup,cn=users," + self.base_dn,
1103 FLAG_MOD_REPLACE, "memberOf")
1107 except LdbError, (num, _):
1108 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1111 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1112 m["memberOf"] = MessageElement("cn=ldaptestgroup,cn=users," + self.base_dn,
1113 FLAG_MOD_DELETE, "memberOf")
1117 except LdbError, (num, _):
1118 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1121 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1122 m["member"] = MessageElement("cn=ldaptestuser,cn=users," + self.base_dn,
1123 FLAG_MOD_DELETE, "member")
1126 # This should yield no results since the member attribute for
1127 # "ldaptestuser" should have been deleted
1128 res1 = ldb.search("cn=ldaptestgroup, cn=users," + self.base_dn,
1130 expression="(member=cn=ldaptestuser,cn=users," + self.base_dn + ")",
1132 self.assertTrue(len(res1) == 0)
1134 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1137 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
1138 "objectclass": "group",
1139 "member": "cn=ldaptestuser,cn=users," + self.base_dn})
1141 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1143 # Make sure that the "member" attribute for "ldaptestuser" has been
1145 res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
1146 scope=SCOPE_BASE, attrs=["member"])
1147 self.assertTrue(len(res) == 1)
1148 self.assertFalse("member" in res[0])
1150 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1152 def test_groups(self):
1153 """This tests the group behaviour (setting, changing) of a user account"""
1154 print "Testing group behaviour\n"
1157 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
1158 "objectclass": "group"})
1161 "dn": "cn=ldaptestgroup2,cn=users," + self.base_dn,
1162 "objectclass": "group"})
1164 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
1165 scope=SCOPE_BASE, attrs=["objectSID"])
1166 self.assertTrue(len(res1) == 1)
1167 group_rid_1 = security.dom_sid(ldb.schema_format_value("objectSID",
1168 res1[0]["objectSID"][0])).split()[1]
1170 res1 = ldb.search("cn=ldaptestgroup2,cn=users," + self.base_dn,
1171 scope=SCOPE_BASE, attrs=["objectSID"])
1172 self.assertTrue(len(res1) == 1)
1173 group_rid_2 = security.dom_sid(ldb.schema_format_value("objectSID",
1174 res1[0]["objectSID"][0])).split()[1]
1176 # Try to create a user with an invalid primary group
1179 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1180 "objectclass": ["user", "person"],
1181 "primaryGroupID": "0"})
1183 except LdbError, (num, _):
1184 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1185 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1187 # Try to Create a user with a valid primary group
1188 # TODO Some more investigation needed here
1191 # "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1192 # "objectclass": ["user", "person"],
1193 # "primaryGroupID": str(group_rid_1)})
1195 # except LdbError, (num, _):
1196 # self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1197 # self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1199 # Test to see how we should behave when the user account doesn't
1202 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1203 m["primaryGroupID"] = MessageElement("0", FLAG_MOD_REPLACE,
1208 except LdbError, (num, _):
1209 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
1211 # Test to see how we should behave when the account isn't a user
1213 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1214 m["primaryGroupID"] = MessageElement("0", FLAG_MOD_REPLACE,
1219 except LdbError, (num, _):
1220 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
1223 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1224 "objectclass": ["user", "person"]})
1226 # We should be able to reset our actual primary group
1228 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1229 m["primaryGroupID"] = MessageElement("513", FLAG_MOD_REPLACE,
1233 # Try to add invalid primary group
1235 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1236 m["primaryGroupID"] = MessageElement("0", FLAG_MOD_REPLACE,
1241 except LdbError, (num, _):
1242 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1244 # Try to make group 1 primary - should be denied since it is not yet
1247 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1248 m["primaryGroupID"] = MessageElement(str(group_rid_1),
1249 FLAG_MOD_REPLACE, "primaryGroupID")
1253 except LdbError, (num, _):
1254 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1256 # Make group 1 secondary
1258 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1259 m["member"] = MessageElement("cn=ldaptestuser,cn=users," + self.base_dn,
1260 FLAG_MOD_REPLACE, "member")
1263 # Make group 1 primary
1265 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1266 m["primaryGroupID"] = MessageElement(str(group_rid_1),
1267 FLAG_MOD_REPLACE, "primaryGroupID")
1270 # Try to delete group 1 - should be denied
1272 ldb.delete("cn=ldaptestgroup,cn=users," + self.base_dn)
1274 except LdbError, (num, _):
1275 self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
1277 # Try to add group 1 also as secondary - should be denied
1279 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1280 m["member"] = MessageElement("cn=ldaptestuser,cn=users," + self.base_dn,
1281 FLAG_MOD_ADD, "member")
1285 except LdbError, (num, _):
1286 self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
1288 # Try to add invalid member to group 1 - should be denied
1290 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1291 m["member"] = MessageElement(
1292 "cn=ldaptestuser3,cn=users," + self.base_dn,
1293 FLAG_MOD_ADD, "member")
1297 except LdbError, (num, _):
1298 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
1300 # Make group 2 secondary
1302 m.dn = Dn(ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
1303 m["member"] = MessageElement("cn=ldaptestuser,cn=users," + self.base_dn,
1304 FLAG_MOD_ADD, "member")
1309 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1310 m["primaryGroupID"] = MessageElement(str(group_rid_2),
1311 FLAG_MOD_REPLACE, "primaryGroupID")
1314 # Old primary group should contain a "member" attribute for the user,
1315 # the new shouldn't contain anymore one
1316 res1 = ldb.search("cn=ldaptestgroup, cn=users," + self.base_dn,
1317 scope=SCOPE_BASE, attrs=["member"])
1318 self.assertTrue(len(res1) == 1)
1319 self.assertTrue(len(res1[0]["member"]) == 1)
1320 self.assertEquals(res1[0]["member"][0].lower(),
1321 ("cn=ldaptestuser,cn=users," + self.base_dn).lower())
1323 res1 = ldb.search("cn=ldaptestgroup2, cn=users," + self.base_dn,
1324 scope=SCOPE_BASE, attrs=["member"])
1325 self.assertTrue(len(res1) == 1)
1326 self.assertFalse("member" in res1[0])
1328 # Also this should be denied
1331 "dn": "cn=ldaptestuser1,cn=users," + self.base_dn,
1332 "objectclass": ["user", "person"],
1333 "primaryGroupID": "0"})
1335 except LdbError, (num, _):
1336 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1338 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1339 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1340 self.delete_force(self.ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
1342 def test_sam_attributes(self):
1343 """Test the behaviour of special attributes of SAM objects"""
1344 print "Testing the behaviour of special attributes of SAM objects\n"""
1347 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1348 "objectclass": ["user", "person"]})
1350 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
1351 "objectclass": "group"})
1354 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1355 m["groupType"] = MessageElement("0", FLAG_MOD_ADD,
1360 except LdbError, (num, _):
1361 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
1364 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1365 m["groupType"] = MessageElement([], FLAG_MOD_DELETE,
1370 except LdbError, (num, _):
1371 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1374 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1375 m["primaryGroupID"] = MessageElement("0", FLAG_MOD_ADD,
1380 except LdbError, (num, _):
1381 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
1384 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1385 m["primaryGroupID"] = MessageElement([], FLAG_MOD_DELETE,
1390 except LdbError, (num, _):
1391 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1394 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1395 m["userAccountControl"] = MessageElement("0", FLAG_MOD_ADD,
1396 "userAccountControl")
1400 except LdbError, (num, _):
1401 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
1404 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1405 m["userAccountControl"] = MessageElement([], FLAG_MOD_DELETE,
1406 "userAccountControl")
1410 except LdbError, (num, _):
1411 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1414 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1415 m["sAMAccountType"] = MessageElement("0", FLAG_MOD_ADD,
1420 except LdbError, (num, _):
1421 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1424 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1425 m["sAMAccountType"] = MessageElement([], FLAG_MOD_REPLACE,
1430 except LdbError, (num, _):
1431 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1434 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1435 m["sAMAccountType"] = MessageElement([], FLAG_MOD_DELETE,
1440 except LdbError, (num, _):
1441 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1443 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1444 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1446 def test_primary_group_token_constructed(self):
1447 """Test the primary group token behaviour (hidden-generated-readonly attribute on groups) and some other constructed attributes"""
1448 print "Testing primary group token behaviour and other constructed attributes\n"
1452 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
1453 "objectclass": "group",
1454 "primaryGroupToken": "100"})
1456 except LdbError, (num, _):
1457 self.assertEquals(num, ERR_UNDEFINED_ATTRIBUTE_TYPE)
1458 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1461 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1462 "objectclass": ["user", "person"]})
1465 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
1466 "objectclass": "group"})
1468 # Testing for one invalid, and one valid operational attribute, but also the things they are built from
1469 res1 = ldb.search(self.base_dn,
1470 scope=SCOPE_BASE, attrs=["primaryGroupToken", "canonicalName", "objectClass", "objectSid"])
1471 self.assertTrue(len(res1) == 1)
1472 self.assertFalse("primaryGroupToken" in res1[0])
1473 self.assertTrue("canonicalName" in res1[0])
1474 self.assertTrue("objectClass" in res1[0])
1475 self.assertTrue("objectSid" in res1[0])
1477 res1 = ldb.search(self.base_dn,
1478 scope=SCOPE_BASE, attrs=["primaryGroupToken", "canonicalName"])
1479 self.assertTrue(len(res1) == 1)
1480 self.assertFalse("primaryGroupToken" in res1[0])
1481 self.assertFalse("objectSid" in res1[0])
1482 self.assertFalse("objectClass" in res1[0])
1483 self.assertTrue("canonicalName" in res1[0])
1485 res1 = ldb.search("cn=users,"+self.base_dn,
1486 scope=SCOPE_BASE, attrs=["primaryGroupToken"])
1487 self.assertTrue(len(res1) == 1)
1488 self.assertFalse("primaryGroupToken" in res1[0])
1490 res1 = ldb.search("cn=ldaptestuser, cn=users," + self.base_dn,
1491 scope=SCOPE_BASE, attrs=["primaryGroupToken"])
1492 self.assertTrue(len(res1) == 1)
1493 self.assertFalse("primaryGroupToken" in res1[0])
1495 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
1497 self.assertTrue(len(res1) == 1)
1498 self.assertFalse("primaryGroupToken" in res1[0])
1500 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
1501 scope=SCOPE_BASE, attrs=["primaryGroupToken", "objectSID"])
1502 self.assertTrue(len(res1) == 1)
1503 primary_group_token = int(res1[0]["primaryGroupToken"][0])
1505 rid = security.dom_sid(ldb.schema_format_value("objectSID", res1[0]["objectSID"][0])).split()[1]
1506 self.assertEquals(primary_group_token, rid)
1509 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1510 m["primaryGroupToken"] = "100"
1514 except LdbError, (num, _):
1515 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
1517 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1518 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1520 def test_tokenGroups(self):
1521 """Test the tokenGroups behaviour (hidden-generated-readonly attribute on SAM objects)"""
1522 print "Testing tokenGroups behaviour\n"
1524 # The domain object shouldn't contain any "tokenGroups" entry
1525 res = ldb.search(self.base_dn, scope=SCOPE_BASE, attrs=["tokenGroups"])
1526 self.assertTrue(len(res) == 1)
1527 self.assertFalse("tokenGroups" in res[0])
1529 # The domain administrator should contain "tokenGroups" entries
1530 # (the exact number depends on the domain/forest function level and the
1531 # DC software versions)
1532 res = ldb.search("cn=Administrator,cn=Users," + self.base_dn,
1533 scope=SCOPE_BASE, attrs=["tokenGroups"])
1534 self.assertTrue(len(res) == 1)
1535 self.assertTrue("tokenGroups" in res[0])
1538 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1539 "objectclass": ["user", "person"]})
1541 # This testuser should contain at least two "tokenGroups" entries
1542 # (exactly two on an unmodified "Domain Users" and "Users" group)
1543 res = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
1544 scope=SCOPE_BASE, attrs=["tokenGroups"])
1545 self.assertTrue(len(res) == 1)
1546 self.assertTrue(len(res[0]["tokenGroups"]) >= 2)
1548 # one entry which we need to find should point to domains "Domain Users"
1549 # group and another entry should point to the builtin "Users"group
1550 domain_users_group_found = False
1551 users_group_found = False
1552 for sid in res[0]["tokenGroups"]:
1553 rid = security.dom_sid(ldb.schema_format_value("objectSID", sid)).split()[1]
1555 domain_users_group_found = True
1557 users_group_found = True
1559 self.assertTrue(domain_users_group_found)
1560 self.assertTrue(users_group_found)
1562 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1564 def test_wkguid(self):
1565 """Test Well known GUID behaviours (including DN+Binary)"""
1566 print "Test Well known GUID behaviours (including DN+Binary)"""
1568 res = self.ldb.search(base=("<WKGUID=ab1d30f3768811d1aded00c04fd8d5cd,%s>" % self.base_dn), scope=SCOPE_BASE, attrs=[])
1569 self.assertEquals(len(res), 1)
1571 res2 = self.ldb.search(scope=SCOPE_BASE, attrs=["wellKnownObjects"], expression=("wellKnownObjects=B:32:ab1d30f3768811d1aded00c04fd8d5cd:%s" % res[0].dn))
1572 self.assertEquals(len(res2), 1)
1574 # Prove that the matching rule is over the whole DN+Binary
1575 res2 = self.ldb.search(scope=SCOPE_BASE, attrs=["wellKnownObjects"], expression=("wellKnownObjects=B:32:ab1d30f3768811d1aded00c04fd8d5cd"))
1576 self.assertEquals(len(res2), 0)
1577 # Prove that the matching rule is over the whole DN+Binary
1578 res2 = self.ldb.search(scope=SCOPE_BASE, attrs=["wellKnownObjects"], expression=("wellKnownObjects=%s") % res[0].dn)
1579 self.assertEquals(len(res2), 0)
1581 def test_subschemasubentry(self):
1582 """Test subSchemaSubEntry appears when requested, but not when not requested"""
1583 print "Test subSchemaSubEntry"""
1585 res = self.ldb.search(base=self.base_dn, scope=SCOPE_BASE, attrs=["subSchemaSubEntry"])
1586 self.assertEquals(len(res), 1)
1587 self.assertEquals(res[0]["subSchemaSubEntry"][0], "CN=Aggregate,"+self.schema_dn)
1589 res = self.ldb.search(base=self.base_dn, scope=SCOPE_BASE, attrs=["*"])
1590 self.assertEquals(len(res), 1)
1591 self.assertTrue("subScheamSubEntry" not in res[0])
1593 def test_delete(self):
1594 """Tests the delete operation"""
1595 print "Tests the delete operations"""
1598 "dn": "cn=ldaptestcontainer," + self.base_dn,
1599 "objectclass": "container"})
1601 "dn": "cn=entry1,cn=ldaptestcontainer," + self.base_dn,
1602 "objectclass": "container"})
1604 "dn": "cn=entry2,cn=ldaptestcontainer," + self.base_dn,
1605 "objectclass": "container"})
1608 ldb.delete("cn=ldaptestcontainer," + self.base_dn)
1610 except LdbError, (num, _):
1611 self.assertEquals(num, ERR_NOT_ALLOWED_ON_NON_LEAF)
1613 ldb.delete("cn=ldaptestcontainer," + self.base_dn, ["tree_delete:0"])
1616 res = ldb.search("cn=ldaptestcontainer," + self.base_dn,
1617 scope=SCOPE_BASE, attrs=[])
1619 except LdbError, (num, _):
1620 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
1622 res = ldb.search("cn=entry1,cn=ldaptestcontainer," + self.base_dn,
1623 scope=SCOPE_BASE, attrs=[])
1625 except LdbError, (num, _):
1626 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
1628 res = ldb.search("cn=entry2,cn=ldaptestcontainer," + self.base_dn,
1629 scope=SCOPE_BASE, attrs=[])
1631 except LdbError, (num, _):
1632 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
1634 self.delete_force(self.ldb, "cn=entry1,cn=ldaptestcontainer," + self.base_dn)
1635 self.delete_force(self.ldb, "cn=entry2,cn=ldaptestcontainer," + self.base_dn)
1636 self.delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
1638 # Performs some protected object delete testing
1640 res = ldb.search(base="", expression="", scope=SCOPE_BASE,
1641 attrs=["dsServiceName", "dNSHostName"])
1642 self.assertEquals(len(res), 1)
1645 ldb.delete(res[0]["dsServiceName"][0])
1647 except LdbError, (num, _):
1648 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1650 res = ldb.search(self.base_dn, scope=SCOPE_SUBTREE,
1651 attrs=["rIDSetReferences"],
1652 expression="(&(objectClass=computer)(dNSHostName=" + res[0]["dNSHostName"][0] + "))")
1653 self.assertEquals(len(res), 1)
1656 ldb.delete(res[0]["rIDSetReferences"][0])
1658 except LdbError, (num, _):
1659 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1662 ldb.delete("cn=Enterprise Schema,cn=Partitions," + self.configuration_dn)
1664 except LdbError, (num, _):
1665 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1668 ldb.delete("cn=Enterprise Configuration,cn=Partitions," + self.configuration_dn)
1670 except LdbError, (num, _):
1671 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1673 # Performs some "systemFlags" testing
1675 # Delete failing since "SYSTEM_FLAG_DISALLOW_DELETE"
1677 ldb.delete("CN=Users," + self.base_dn)
1679 except LdbError, (num, _):
1680 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1685 print "Testing user add"
1688 "dn": "cn=ldaptestuser,cn=uSers," + self.base_dn,
1689 "objectclass": ["user", "person"],
1690 "cN": "LDAPtestUSER",
1691 "givenname": "ldap",
1695 "dn": "cn=ldaptestgroup,cn=uSers," + self.base_dn,
1696 "objectclass": "group",
1697 "member": "cn=ldaptestuser,cn=useRs," + self.base_dn})
1700 "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
1701 "objectclass": "computer",
1702 "cN": "LDAPtestCOMPUTER"})
1704 ldb.add({"dn": "cn=ldaptest2computer,cn=computers," + self.base_dn,
1705 "objectClass": "computer",
1706 "cn": "LDAPtest2COMPUTER",
1707 "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT),
1708 "displayname": "ldap testy"})
1711 ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn,
1712 "objectClass": "computer",
1713 "cn": "LDAPtest2COMPUTER"
1716 except LdbError, (num, _):
1717 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1720 ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn,
1721 "objectClass": "computer",
1722 "cn": "ldaptestcomputer3",
1723 "sAMAccountType": str(ATYPE_NORMAL_ACCOUNT)
1726 except LdbError, (num, _):
1727 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1729 ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn,
1730 "objectClass": "computer",
1731 "cn": "LDAPtestCOMPUTER3"
1734 print "Testing ldb.search for (&(cn=ldaptestcomputer3)(objectClass=user))";
1735 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestcomputer3)(objectClass=user))");
1736 self.assertEquals(len(res), 1, "Found only %d for (&(cn=ldaptestcomputer3)(objectClass=user))" % len(res))
1738 self.assertEquals(str(res[0].dn), ("CN=ldaptestcomputer3,CN=Computers," + self.base_dn));
1739 self.assertEquals(res[0]["cn"][0], "ldaptestcomputer3");
1740 self.assertEquals(res[0]["name"][0], "ldaptestcomputer3");
1741 self.assertEquals(res[0]["objectClass"][0], "top");
1742 self.assertEquals(res[0]["objectClass"][1], "person");
1743 self.assertEquals(res[0]["objectClass"][2], "organizationalPerson");
1744 self.assertEquals(res[0]["objectClass"][3], "user");
1745 self.assertEquals(res[0]["objectClass"][4], "computer");
1746 self.assertTrue("objectGUID" in res[0])
1747 self.assertTrue("whenCreated" in res[0])
1748 self.assertEquals(res[0]["objectCategory"][0], ("CN=Computer,CN=Schema,CN=Configuration," + self.base_dn));
1749 self.assertEquals(int(res[0]["primaryGroupID"][0]), 513);
1750 self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_NORMAL_ACCOUNT);
1751 self.assertEquals(int(res[0]["userAccountControl"][0]), UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE);
1753 self.delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
1755 print "Testing attribute or value exists behaviour"
1758 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1760 replace: servicePrincipalName
1761 servicePrincipalName: host/ldaptest2computer
1762 servicePrincipalName: host/ldaptest2computer
1763 servicePrincipalName: cifs/ldaptest2computer
1766 except LdbError, (num, msg):
1767 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
1770 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1772 replace: servicePrincipalName
1773 servicePrincipalName: host/ldaptest2computer
1774 servicePrincipalName: cifs/ldaptest2computer
1778 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1780 add: servicePrincipalName
1781 servicePrincipalName: host/ldaptest2computer
1784 except LdbError, (num, msg):
1785 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
1787 print "Testing ranged results"
1789 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1791 replace: servicePrincipalName
1795 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1797 add: servicePrincipalName
1798 servicePrincipalName: host/ldaptest2computer0
1799 servicePrincipalName: host/ldaptest2computer1
1800 servicePrincipalName: host/ldaptest2computer2
1801 servicePrincipalName: host/ldaptest2computer3
1802 servicePrincipalName: host/ldaptest2computer4
1803 servicePrincipalName: host/ldaptest2computer5
1804 servicePrincipalName: host/ldaptest2computer6
1805 servicePrincipalName: host/ldaptest2computer7
1806 servicePrincipalName: host/ldaptest2computer8
1807 servicePrincipalName: host/ldaptest2computer9
1808 servicePrincipalName: host/ldaptest2computer10
1809 servicePrincipalName: host/ldaptest2computer11
1810 servicePrincipalName: host/ldaptest2computer12
1811 servicePrincipalName: host/ldaptest2computer13
1812 servicePrincipalName: host/ldaptest2computer14
1813 servicePrincipalName: host/ldaptest2computer15
1814 servicePrincipalName: host/ldaptest2computer16
1815 servicePrincipalName: host/ldaptest2computer17
1816 servicePrincipalName: host/ldaptest2computer18
1817 servicePrincipalName: host/ldaptest2computer19
1818 servicePrincipalName: host/ldaptest2computer20
1819 servicePrincipalName: host/ldaptest2computer21
1820 servicePrincipalName: host/ldaptest2computer22
1821 servicePrincipalName: host/ldaptest2computer23
1822 servicePrincipalName: host/ldaptest2computer24
1823 servicePrincipalName: host/ldaptest2computer25
1824 servicePrincipalName: host/ldaptest2computer26
1825 servicePrincipalName: host/ldaptest2computer27
1826 servicePrincipalName: host/ldaptest2computer28
1827 servicePrincipalName: host/ldaptest2computer29
1830 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE,
1831 attrs=["servicePrincipalName;range=0-*"])
1832 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1833 #print len(res[0]["servicePrincipalName;range=0-*"])
1834 self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30)
1836 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-19"])
1837 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1838 # print res[0]["servicePrincipalName;range=0-19"].length
1839 self.assertEquals(len(res[0]["servicePrincipalName;range=0-19"]), 20)
1842 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-30"])
1843 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1844 self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30)
1846 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-40"])
1847 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1848 self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30)
1850 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=30-40"])
1851 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1852 self.assertEquals(len(res[0]["servicePrincipalName;range=30-*"]), 0)
1855 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=10-40"])
1856 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1857 self.assertEquals(len(res[0]["servicePrincipalName;range=10-*"]), 20)
1858 # pos_11 = res[0]["servicePrincipalName;range=10-*"][18]
1860 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=11-40"])
1861 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1862 self.assertEquals(len(res[0]["servicePrincipalName;range=11-*"]), 19)
1863 # print res[0]["servicePrincipalName;range=11-*"][18]
1865 # self.assertEquals((res[0]["servicePrincipalName;range=11-*"][18]), pos_11)
1867 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=11-15"])
1868 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1869 self.assertEquals(len(res[0]["servicePrincipalName;range=11-15"]), 5)
1870 # self.assertEquals(res[0]["servicePrincipalName;range=11-15"][4], pos_11)
1872 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName"])
1873 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1874 # print res[0]["servicePrincipalName"][18]
1876 self.assertEquals(len(res[0]["servicePrincipalName"]), 30)
1877 # self.assertEquals(res[0]["servicePrincipalName"][18], pos_11)
1879 self.delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
1881 "dn": "cn=ldaptestuser2,cn=useRs," + self.base_dn,
1882 "objectClass": ["person", "user"],
1883 "cn": "LDAPtestUSER2",
1884 "givenname": "testy",
1885 "sn": "ldap user2"})
1887 print "Testing Ambigious Name Resolution"
1888 # Testing ldb.search for (&(anr=ldap testy)(objectClass=user))
1889 res = ldb.search(expression="(&(anr=ldap testy)(objectClass=user))")
1890 self.assertEquals(len(res), 3, "Found only %d of 3 for (&(anr=ldap testy)(objectClass=user))" % len(res))
1892 # Testing ldb.search for (&(anr=testy ldap)(objectClass=user))
1893 res = ldb.search(expression="(&(anr=testy ldap)(objectClass=user))")
1894 self.assertEquals(len(res), 2, "Found only %d of 2 for (&(anr=testy ldap)(objectClass=user))" % len(res))
1896 # Testing ldb.search for (&(anr=ldap)(objectClass=user))
1897 res = ldb.search(expression="(&(anr=ldap)(objectClass=user))")
1898 self.assertEquals(len(res), 4, "Found only %d of 4 for (&(anr=ldap)(objectClass=user))" % len(res))
1900 # Testing ldb.search for (&(anr==ldap)(objectClass=user))
1901 res = ldb.search(expression="(&(anr==ldap)(objectClass=user))")
1902 self.assertEquals(len(res), 1, "Could not find (&(anr==ldap)(objectClass=user)). Found only %d for (&(anr=ldap)(objectClass=user))" % len(res))
1904 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
1905 self.assertEquals(res[0]["cn"][0], "ldaptestuser")
1906 self.assertEquals(str(res[0]["name"]), "ldaptestuser")
1908 # Testing ldb.search for (&(anr=testy)(objectClass=user))
1909 res = ldb.search(expression="(&(anr=testy)(objectClass=user))")
1910 self.assertEquals(len(res), 2, "Found only %d for (&(anr=testy)(objectClass=user))" % len(res))
1912 # Testing ldb.search for (&(anr=testy ldap)(objectClass=user))
1913 res = ldb.search(expression="(&(anr=testy ldap)(objectClass=user))")
1914 self.assertEquals(len(res), 2, "Found only %d for (&(anr=testy ldap)(objectClass=user))" % len(res))
1916 # Testing ldb.search for (&(anr==testy ldap)(objectClass=user))
1917 # this test disabled for the moment, as anr with == tests are not understood
1918 # res = ldb.search(expression="(&(anr==testy ldap)(objectClass=user))")
1919 # self.assertEquals(len(res), 1, "Found only %d for (&(anr==testy ldap)(objectClass=user))" % len(res))
1921 # self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
1922 # self.assertEquals(res[0]["cn"][0], "ldaptestuser")
1923 # self.assertEquals(res[0]["name"][0], "ldaptestuser")
1925 # Testing ldb.search for (&(anr==testy ldap)(objectClass=user))
1926 # res = ldb.search(expression="(&(anr==testy ldap)(objectClass=user))")
1927 # self.assertEquals(len(res), 1, "Could not find (&(anr==testy ldap)(objectClass=user))")
1929 # self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
1930 # self.assertEquals(res[0]["cn"][0], "ldaptestuser")
1931 # self.assertEquals(res[0]["name"][0], "ldaptestuser")
1933 # Testing ldb.search for (&(anr=testy ldap user)(objectClass=user))
1934 res = ldb.search(expression="(&(anr=testy ldap user)(objectClass=user))")
1935 self.assertEquals(len(res), 1, "Could not find (&(anr=testy ldap user)(objectClass=user))")
1937 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
1938 self.assertEquals(str(res[0]["cn"]), "ldaptestuser2")
1939 self.assertEquals(str(res[0]["name"]), "ldaptestuser2")
1941 # Testing ldb.search for (&(anr==testy ldap user2)(objectClass=user))
1942 # res = ldb.search(expression="(&(anr==testy ldap user2)(objectClass=user))")
1943 # self.assertEquals(len(res), 1, "Could not find (&(anr==testy ldap user2)(objectClass=user))")
1945 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
1946 self.assertEquals(str(res[0]["cn"]), "ldaptestuser2")
1947 self.assertEquals(str(res[0]["name"]), "ldaptestuser2")
1949 # Testing ldb.search for (&(anr==ldap user2)(objectClass=user))
1950 # res = ldb.search(expression="(&(anr==ldap user2)(objectClass=user))")
1951 # self.assertEquals(len(res), 1, "Could not find (&(anr==ldap user2)(objectClass=user))")
1953 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
1954 self.assertEquals(str(res[0]["cn"]), "ldaptestuser2")
1955 self.assertEquals(str(res[0]["name"]), "ldaptestuser2")
1957 # Testing ldb.search for (&(anr==not ldap user2)(objectClass=user))
1958 # res = ldb.search(expression="(&(anr==not ldap user2)(objectClass=user))")
1959 # self.assertEquals(len(res), 0, "Must not find (&(anr==not ldap user2)(objectClass=user))")
1961 # Testing ldb.search for (&(anr=not ldap user2)(objectClass=user))
1962 res = ldb.search(expression="(&(anr=not ldap user2)(objectClass=user))")
1963 self.assertEquals(len(res), 0, "Must not find (&(anr=not ldap user2)(objectClass=user))")
1965 # Testing ldb.search for (&(anr="testy ldap")(objectClass=user)) (ie, with quotes)
1966 # res = ldb.search(expression="(&(anr==\"testy ldap\")(objectClass=user))")
1967 # self.assertEquals(len(res), 0, "Found (&(anr==\"testy ldap\")(objectClass=user))")
1969 print "Testing Renames"
1971 attrs = ["objectGUID", "objectSid"]
1972 print "Testing ldb.search for (&(cn=ldaptestUSer2)(objectClass=user))"
1973 res_user = ldb.search(self.base_dn, expression="(&(cn=ldaptestUSer2)(objectClass=user))", scope=SCOPE_SUBTREE, attrs=attrs)
1974 self.assertEquals(len(res_user), 1, "Could not find (&(cn=ldaptestUSer2)(objectClass=user))")
1976 # Check rename works with extended/alternate DN forms
1977 ldb.rename("<SID=" + ldb.schema_format_value("objectSID", res_user[0]["objectSID"][0]) + ">" , "cn=ldaptestUSER3,cn=users," + self.base_dn)
1979 print "Testing ldb.search for (&(cn=ldaptestuser3)(objectClass=user))"
1980 res = ldb.search(expression="(&(cn=ldaptestuser3)(objectClass=user))")
1981 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser3)(objectClass=user))")
1983 self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
1984 self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3")
1985 self.assertEquals(str(res[0]["name"]), "ldaptestUSER3")
1987 #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))"
1988 res = ldb.search(expression="(&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))")
1989 self.assertEquals(len(res), 1, "(&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))")
1991 self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
1992 self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3")
1993 self.assertEquals(str(res[0]["name"]), "ldaptestUSER3")
1995 #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))"
1996 res = ldb.search(expression="(&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))")
1997 self.assertEquals(len(res), 1, "(&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))")
1999 self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
2000 self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3")
2001 self.assertEquals(str(res[0]["name"]), "ldaptestUSER3")
2003 #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))"
2004 res = ldb.search(expression="(&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))")
2005 self.assertEquals(len(res), 0, "(&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))")
2007 # This is a Samba special, and does not exist in real AD
2008 # print "Testing ldb.search for (dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")"
2009 # res = ldb.search("(dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")")
2010 # if (res.error != 0 || len(res) != 1) {
2011 # print "Could not find (dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")"
2012 # self.assertEquals(len(res), 1)
2014 # self.assertEquals(res[0].dn, ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
2015 # self.assertEquals(res[0].cn, "ldaptestUSER3")
2016 # self.assertEquals(res[0].name, "ldaptestUSER3")
2018 print "Testing ldb.search for (distinguishedName=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")"
2019 res = ldb.search(expression="(distinguishedName=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")")
2020 self.assertEquals(len(res), 1, "Could not find (dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")")
2021 self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
2022 self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3")
2023 self.assertEquals(str(res[0]["name"]), "ldaptestUSER3")
2025 # ensure we cannot add it again
2027 ldb.add({"dn": "cn=ldaptestuser3,cn=userS," + self.base_dn,
2028 "objectClass": ["person", "user"],
2029 "cn": "LDAPtestUSER3"})
2031 except LdbError, (num, _):
2032 self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
2035 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser2,cn=users," + self.base_dn)
2037 # ensure we cannot rename it twice
2039 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn,
2040 "cn=ldaptestuser2,cn=users," + self.base_dn)
2042 except LdbError, (num, _):
2043 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
2045 # ensure can now use that name
2046 ldb.add({"dn": "cn=ldaptestuser3,cn=users," + self.base_dn,
2047 "objectClass": ["person", "user"],
2048 "cn": "LDAPtestUSER3"})
2050 # ensure we now cannot rename
2052 ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=users," + self.base_dn)
2054 except LdbError, (num, _):
2055 self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
2057 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=configuration," + self.base_dn)
2059 except LdbError, (num, _):
2060 self.assertTrue(num in (71, 64))
2062 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser5,cn=users," + self.base_dn)
2064 ldb.delete("cn=ldaptestuser5,cn=users," + self.base_dn)
2066 self.delete_force(ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
2068 ldb.rename("cn=ldaptestgroup,cn=users," + self.base_dn, "cn=ldaptestgroup2,cn=users," + self.base_dn)
2070 print "Testing subtree renames"
2072 ldb.add({"dn": "cn=ldaptestcontainer," + self.base_dn,
2073 "objectClass": "container"})
2075 ldb.add({"dn": "CN=ldaptestuser4,CN=ldaptestcontainer," + self.base_dn,
2076 "objectClass": ["person", "user"],
2077 "cn": "LDAPtestUSER4"})
2080 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2083 member: cn=ldaptestuser4,cn=ldaptestcontainer,""" + self.base_dn + """
2084 member: cn=ldaptestcomputer,cn=computers,""" + self.base_dn + """
2085 member: cn=ldaptestuser2,cn=users,""" + self.base_dn + """
2088 print "Testing ldb.rename of cn=ldaptestcontainer," + self.base_dn + " to cn=ldaptestcontainer2," + self.base_dn
2089 ldb.rename("CN=ldaptestcontainer," + self.base_dn, "CN=ldaptestcontainer2," + self.base_dn)
2091 print "Testing ldb.search for (&(cn=ldaptestuser4)(objectClass=user))"
2092 res = ldb.search(expression="(&(cn=ldaptestuser4)(objectClass=user))")
2093 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser4)(objectClass=user))")
2095 print "Testing subtree ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in (just renamed from) cn=ldaptestcontainer," + self.base_dn
2097 res = ldb.search("cn=ldaptestcontainer," + self.base_dn,
2098 expression="(&(cn=ldaptestuser4)(objectClass=user))",
2099 scope=SCOPE_SUBTREE)
2101 except LdbError, (num, _):
2102 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
2104 print "Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in (just renamed from) cn=ldaptestcontainer," + self.base_dn
2106 res = ldb.search("cn=ldaptestcontainer," + self.base_dn,
2107 expression="(&(cn=ldaptestuser4)(objectClass=user))", scope=SCOPE_ONELEVEL)
2109 except LdbError, (num, _):
2110 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
2112 print "Testing ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in renamed container"
2113 res = ldb.search("cn=ldaptestcontainer2," + self.base_dn, expression="(&(cn=ldaptestuser4)(objectClass=user))", scope=SCOPE_SUBTREE)
2114 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser4)(objectClass=user)) under cn=ldaptestcontainer2," + self.base_dn)
2116 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn))
2117 self.assertEquals(res[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
2121 print "Testing ldb.search for (&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn + ")(objectclass=group)) to check subtree renames and linked attributes"
2122 res = ldb.search(self.base_dn, expression="(&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn + ")(objectclass=group))", scope=SCOPE_SUBTREE)
2123 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?")
2125 print "Testing ldb.rename (into itself) of cn=ldaptestcontainer2," + self.base_dn + " to cn=ldaptestcontainer,cn=ldaptestcontainer2," + self.base_dn
2127 ldb.rename("cn=ldaptestcontainer2," + self.base_dn, "cn=ldaptestcontainer,cn=ldaptestcontainer2," + self.base_dn)
2129 except LdbError, (num, _):
2130 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
2132 print "Testing ldb.rename (into non-existent container) of cn=ldaptestcontainer2," + self.base_dn + " to cn=ldaptestcontainer,cn=ldaptestcontainer3," + self.base_dn
2134 ldb.rename("cn=ldaptestcontainer2," + self.base_dn, "cn=ldaptestcontainer,cn=ldaptestcontainer3," + self.base_dn)
2136 except LdbError, (num, _):
2137 self.assertTrue(num in (ERR_UNWILLING_TO_PERFORM, ERR_OTHER))
2139 print "Testing delete (should fail, not a leaf node) of renamed cn=ldaptestcontainer2," + self.base_dn
2141 ldb.delete("cn=ldaptestcontainer2," + self.base_dn)
2143 except LdbError, (num, _):
2144 self.assertEquals(num, ERR_NOT_ALLOWED_ON_NON_LEAF)
2146 print "Testing base ldb.search for CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn
2147 res = ldb.search(expression="(objectclass=*)", base=("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn), scope=SCOPE_BASE)
2148 self.assertEquals(len(res), 1)
2149 res = ldb.search(expression="(cn=ldaptestuser40)", base=("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn), scope=SCOPE_BASE)
2150 self.assertEquals(len(res), 0)
2152 print "Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in cn=ldaptestcontainer2," + self.base_dn
2153 res = ldb.search(expression="(&(cn=ldaptestuser4)(objectClass=user))", base=("cn=ldaptestcontainer2," + self.base_dn), scope=SCOPE_ONELEVEL)
2154 # FIXME: self.assertEquals(len(res), 0)
2156 print "Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in cn=ldaptestcontainer2," + self.base_dn
2157 res = ldb.search(expression="(&(cn=ldaptestuser4)(objectClass=user))", base=("cn=ldaptestcontainer2," + self.base_dn), scope=SCOPE_SUBTREE)
2158 # FIXME: self.assertEquals(len(res), 0)
2160 print "Testing delete of subtree renamed "+("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn)
2161 ldb.delete(("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn))
2162 print "Testing delete of renamed cn=ldaptestcontainer2," + self.base_dn
2163 ldb.delete("cn=ldaptestcontainer2," + self.base_dn)
2165 ldb.add({"dn": "cn=ldaptestutf8user èùéìòà,cn=users," + self.base_dn, "objectClass": "user"})
2167 ldb.add({"dn": "cn=ldaptestutf8user2 èùéìòà,cn=users," + self.base_dn, "objectClass": "user"})
2169 print "Testing ldb.search for (&(cn=ldaptestuser)(objectClass=user))"
2170 res = ldb.search(expression="(&(cn=ldaptestuser)(objectClass=user))")
2171 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser)(objectClass=user))")
2173 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
2174 self.assertEquals(str(res[0]["cn"]), "ldaptestuser")
2175 self.assertEquals(str(res[0]["name"]), "ldaptestuser")
2176 self.assertEquals(set(res[0]["objectClass"]), set(["top", "person", "organizationalPerson", "user"]))
2177 self.assertTrue("objectGUID" in res[0])
2178 self.assertTrue("whenCreated" in res[0])
2179 self.assertEquals(str(res[0]["objectCategory"]), ("CN=Person,CN=Schema,CN=Configuration," + self.base_dn))
2180 self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_NORMAL_ACCOUNT)
2181 self.assertEquals(int(res[0]["userAccountControl"][0]), UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE)
2182 self.assertEquals(res[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
2183 self.assertEquals(len(res[0]["memberOf"]), 1)
2185 print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=cn=person,cn=schema,cn=configuration," + self.base_dn + "))"
2186 res2 = ldb.search(expression="(&(cn=ldaptestuser)(objectCategory=cn=person,cn=schema,cn=configuration," + self.base_dn + "))")
2187 self.assertEquals(len(res2), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=cn=person,cn=schema,cn=configuration," + self.base_dn + "))")
2189 self.assertEquals(res[0].dn, res2[0].dn)
2191 print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon))"
2192 res3 = ldb.search(expression="(&(cn=ldaptestuser)(objectCategory=PerSon))")
2193 self.assertEquals(len(res3), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=PerSon)): matched %d" % len(res3))
2195 self.assertEquals(res[0].dn, res3[0].dn)
2197 if gc_ldb is not None:
2198 print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon)) in Global Catalog"
2199 res3gc = gc_ldb.search(expression="(&(cn=ldaptestuser)(objectCategory=PerSon))")
2200 self.assertEquals(len(res3gc), 1)
2202 self.assertEquals(res[0].dn, res3gc[0].dn)
2204 print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon)) in with 'phantom root' control"
2206 if gc_ldb is not None:
2207 res3control = gc_ldb.search(self.base_dn, expression="(&(cn=ldaptestuser)(objectCategory=PerSon))", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["search_options:1:2"])
2208 self.assertEquals(len(res3control), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=PerSon)) in Global Catalog")
2210 self.assertEquals(res[0].dn, res3control[0].dn)
2212 ldb.delete(res[0].dn)
2214 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectClass=user))"
2215 res = ldb.search(expression="(&(cn=ldaptestcomputer)(objectClass=user))")
2216 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser)(objectClass=user))")
2218 self.assertEquals(str(res[0].dn), ("CN=ldaptestcomputer,CN=Computers," + self.base_dn))
2219 self.assertEquals(str(res[0]["cn"]), "ldaptestcomputer")
2220 self.assertEquals(str(res[0]["name"]), "ldaptestcomputer")
2221 self.assertEquals(set(res[0]["objectClass"]), set(["top", "person", "organizationalPerson", "user", "computer"]))
2222 self.assertTrue("objectGUID" in res[0])
2223 self.assertTrue("whenCreated" in res[0])
2224 self.assertEquals(str(res[0]["objectCategory"]), ("CN=Computer,CN=Schema,CN=Configuration," + self.base_dn))
2225 self.assertEquals(int(res[0]["primaryGroupID"][0]), 513)
2226 self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_NORMAL_ACCOUNT)
2227 self.assertEquals(int(res[0]["userAccountControl"][0]), UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE)
2228 self.assertEquals(res[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
2229 self.assertEquals(len(res[0]["memberOf"]), 1)
2231 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + "))"
2232 res2 = ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + "))")
2233 self.assertEquals(len(res2), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + "))")
2235 self.assertEquals(res[0].dn, res2[0].dn)
2237 if gc_ldb is not None:
2238 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + ")) in Global Catlog"
2239 res2gc = gc_ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + "))")
2240 self.assertEquals(len(res2gc), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + ")) in Global Catlog")
2242 self.assertEquals(res[0].dn, res2gc[0].dn)
2244 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=compuTER))"
2245 res3 = ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=compuTER))")
2246 self.assertEquals(len(res3), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=compuTER))")
2248 self.assertEquals(res[0].dn, res3[0].dn)
2250 if gc_ldb is not None:
2251 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=compuTER)) in Global Catalog"
2252 res3gc = gc_ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=compuTER))")
2253 self.assertEquals(len(res3gc), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=compuTER)) in Global Catalog")
2255 self.assertEquals(res[0].dn, res3gc[0].dn)
2257 print "Testing ldb.search for (&(cn=ldaptestcomp*r)(objectCategory=compuTER))"
2258 res4 = ldb.search(expression="(&(cn=ldaptestcomp*r)(objectCategory=compuTER))")
2259 self.assertEquals(len(res4), 1, "Could not find (&(cn=ldaptestcomp*r)(objectCategory=compuTER))")
2261 self.assertEquals(res[0].dn, res4[0].dn)
2263 print "Testing ldb.search for (&(cn=ldaptestcomput*)(objectCategory=compuTER))"
2264 res5 = ldb.search(expression="(&(cn=ldaptestcomput*)(objectCategory=compuTER))")
2265 self.assertEquals(len(res5), 1, "Could not find (&(cn=ldaptestcomput*)(objectCategory=compuTER))")
2267 self.assertEquals(res[0].dn, res5[0].dn)
2269 print "Testing ldb.search for (&(cn=*daptestcomputer)(objectCategory=compuTER))"
2270 res6 = ldb.search(expression="(&(cn=*daptestcomputer)(objectCategory=compuTER))")
2271 self.assertEquals(len(res6), 1, "Could not find (&(cn=*daptestcomputer)(objectCategory=compuTER))")
2273 self.assertEquals(res[0].dn, res6[0].dn)
2275 ldb.delete("<GUID=" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + ">")
2277 print "Testing ldb.search for (&(cn=ldaptest2computer)(objectClass=user))"
2278 res = ldb.search(expression="(&(cn=ldaptest2computer)(objectClass=user))")
2279 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptest2computer)(objectClass=user))")
2281 self.assertEquals(str(res[0].dn), "CN=ldaptest2computer,CN=Computers," + self.base_dn)
2282 self.assertEquals(str(res[0]["cn"]), "ldaptest2computer")
2283 self.assertEquals(str(res[0]["name"]), "ldaptest2computer")
2284 self.assertEquals(list(res[0]["objectClass"]), ["top", "person", "organizationalPerson", "user", "computer"])
2285 self.assertTrue("objectGUID" in res[0])
2286 self.assertTrue("whenCreated" in res[0])
2287 self.assertEquals(res[0]["objectCategory"][0], "CN=Computer,CN=Schema,CN=Configuration," + self.base_dn)
2288 self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_WORKSTATION_TRUST)
2289 self.assertEquals(int(res[0]["userAccountControl"][0]), UF_WORKSTATION_TRUST_ACCOUNT)
2291 ldb.delete("<SID=" + ldb.schema_format_value("objectSID", res[0]["objectSID"][0]) + ">")
2293 attrs = ["cn", "name", "objectClass", "objectGUID", "objectSID", "whenCreated", "nTSecurityDescriptor", "memberOf", "allowedAttributes", "allowedAttributesEffective"]
2294 print "Testing ldb.search for (&(cn=ldaptestUSer2)(objectClass=user))"
2295 res_user = ldb.search(self.base_dn, expression="(&(cn=ldaptestUSer2)(objectClass=user))", scope=SCOPE_SUBTREE, attrs=attrs)
2296 self.assertEquals(len(res_user), 1, "Could not find (&(cn=ldaptestUSer2)(objectClass=user))")
2298 self.assertEquals(str(res_user[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
2299 self.assertEquals(str(res_user[0]["cn"]), "ldaptestuser2")
2300 self.assertEquals(str(res_user[0]["name"]), "ldaptestuser2")
2301 self.assertEquals(list(res_user[0]["objectClass"]), ["top", "person", "organizationalPerson", "user"])
2302 self.assertTrue("objectSid" in res_user[0])
2303 self.assertTrue("objectGUID" in res_user[0])
2304 self.assertTrue("whenCreated" in res_user[0])
2305 self.assertTrue("nTSecurityDescriptor" in res_user[0])
2306 self.assertTrue("allowedAttributes" in res_user[0])
2307 self.assertTrue("allowedAttributesEffective" in res_user[0])
2308 self.assertEquals(res_user[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
2310 ldaptestuser2_sid = res_user[0]["objectSid"][0]
2311 ldaptestuser2_guid = res_user[0]["objectGUID"][0]
2313 attrs = ["cn", "name", "objectClass", "objectGUID", "objectSID", "whenCreated", "nTSecurityDescriptor", "member", "allowedAttributes", "allowedAttributesEffective"]
2314 print "Testing ldb.search for (&(cn=ldaptestgroup2)(objectClass=group))"
2315 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs)
2316 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))")
2318 self.assertEquals(str(res[0].dn), ("CN=ldaptestgroup2,CN=Users," + self.base_dn))
2319 self.assertEquals(str(res[0]["cn"]), "ldaptestgroup2")
2320 self.assertEquals(str(res[0]["name"]), "ldaptestgroup2")
2321 self.assertEquals(list(res[0]["objectClass"]), ["top", "group"])
2322 self.assertTrue("objectGUID" in res[0])
2323 self.assertTrue("objectSid" in res[0])
2324 self.assertTrue("whenCreated" in res[0])
2325 self.assertTrue("nTSecurityDescriptor" in res[0])
2326 self.assertTrue("allowedAttributes" in res[0])
2327 self.assertTrue("allowedAttributesEffective" in res[0])
2329 for m in res[0]["member"]:
2330 memberUP.append(m.upper())
2331 self.assertTrue(("CN=ldaptestuser2,CN=Users," + self.base_dn).upper() in memberUP)
2333 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs, controls=["extended_dn:1:1"])
2334 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))")
2336 print res[0]["member"]
2338 for m in res[0]["member"]:
2339 memberUP.append(m.upper())
2340 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()
2342 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)
2344 print "Quicktest for linked attributes"
2346 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2349 member: CN=ldaptestuser2,CN=Users,""" + self.base_dn + """
2350 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
2354 dn: <GUID=""" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + """>
2357 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
2361 dn: <SID=""" + ldb.schema_format_value("objectSid", res[0]["objectSid"][0]) + """>
2367 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2370 member: <GUID=""" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + """>
2371 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
2375 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2381 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2384 member: <SID=""" + ldb.schema_format_value("objectSid", res_user[0]["objectSid"][0]) + """>
2385 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
2389 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2392 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
2395 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs)
2396 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))")
2398 self.assertEquals(str(res[0].dn), ("CN=ldaptestgroup2,CN=Users," + self.base_dn))
2399 self.assertEquals(res[0]["member"][0], ("CN=ldaptestuser2,CN=Users," + self.base_dn))
2400 self.assertEquals(len(res[0]["member"]), 1)
2402 ldb.delete(("CN=ldaptestuser2,CN=Users," + self.base_dn))
2406 attrs = ["cn", "name", "objectClass", "objectGUID", "whenCreated", "nTSecurityDescriptor", "member"]
2407 print "Testing ldb.search for (&(cn=ldaptestgroup2)(objectClass=group)) to check linked delete"
2408 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs)
2409 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group)) to check linked delete")
2411 self.assertEquals(str(res[0].dn), ("CN=ldaptestgroup2,CN=Users," + self.base_dn))
2412 self.assertTrue("member" not in res[0])
2414 print "Testing ldb.search for (&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))"
2415 # TODO UTF8 users don't seem to work fully anymore
2416 # res = ldb.search(expression="(&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
2417 res = ldb.search(expression="(&(cn=ldaptestutf8user èùéìòà)(objectclass=user))")
2418 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
2420 self.assertEquals(str(res[0].dn), ("CN=ldaptestutf8user èùéìòà,CN=Users," + self.base_dn))
2421 self.assertEquals(str(res[0]["cn"]), "ldaptestutf8user èùéìòà")
2422 self.assertEquals(str(res[0]["name"]), "ldaptestutf8user èùéìòà")
2423 self.assertEquals(list(res[0]["objectClass"]), ["top", "person", "organizationalPerson", "user"])
2424 self.assertTrue("objectGUID" in res[0])
2425 self.assertTrue("whenCreated" in res[0])
2427 ldb.delete(res[0].dn)
2429 print "Testing ldb.search for (&(cn=ldaptestutf8user2*)(objectClass=user))"
2430 res = ldb.search(expression="(&(cn=ldaptestutf8user2*)(objectClass=user))")
2431 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestutf8user2*)(objectClass=user))")
2433 ldb.delete(res[0].dn)
2435 ldb.delete(("CN=ldaptestgroup2,CN=Users," + self.base_dn))
2437 print "Testing ldb.search for (&(cn=ldaptestutf8user2 ÈÙÉÌÒÀ)(objectClass=user))"
2438 # TODO UTF8 users don't seem to work fully anymore
2439 # res = ldb.search(expression="(&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
2440 # self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
2442 print "Testing that we can't get at the configuration DN from the main search base"
2443 res = ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
2444 self.assertEquals(len(res), 0)
2446 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"
2447 res = ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["search_options:1:2"])
2448 self.assertTrue(len(res) > 0)
2450 if gc_ldb is not None:
2451 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"
2453 res = gc_ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["search_options:1:0"])
2454 self.assertTrue(len(res) > 0)
2456 print "Testing that we do find configuration elements in the global catlog"
2457 res = gc_ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
2458 self.assertTrue(len(res) > 0)
2460 print "Testing that we do find configuration elements and user elements at the same time"
2461 res = gc_ldb.search(self.base_dn, expression="(|(objectClass=crossRef)(objectClass=person))", scope=SCOPE_SUBTREE, attrs=["cn"])
2462 self.assertTrue(len(res) > 0)
2464 print "Testing that we do find configuration elements in the global catlog, with the configuration basedn"
2465 res = gc_ldb.search(self.configuration_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
2466 self.assertTrue(len(res) > 0)
2468 print "Testing that we can get at the configuration DN on the main LDAP port"
2469 res = ldb.search(self.configuration_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
2470 self.assertTrue(len(res) > 0)
2472 print "Testing objectCategory canonacolisation"
2473 res = ldb.search(self.configuration_dn, expression="objectCategory=ntDsDSA", scope=SCOPE_SUBTREE, attrs=["cn"])
2474 self.assertTrue(len(res) > 0, "Didn't find any records with objectCategory=ntDsDSA")
2475 self.assertTrue(len(res) != 0)
2477 res = ldb.search(self.configuration_dn, expression="objectCategory=CN=ntDs-DSA," + self.schema_dn, scope=SCOPE_SUBTREE, attrs=["cn"])
2478 self.assertTrue(len(res) > 0, "Didn't find any records with objectCategory=CN=ntDs-DSA," + self.schema_dn)
2479 self.assertTrue(len(res) != 0)
2481 print "Testing objectClass attribute order on "+ self.base_dn
2482 res = ldb.search(expression="objectClass=domain", base=self.base_dn,
2483 scope=SCOPE_BASE, attrs=["objectClass"])
2484 self.assertEquals(len(res), 1)
2486 self.assertEquals(list(res[0]["objectClass"]), ["top", "domain", "domainDNS"])
2490 print "Testing ldb.search for objectCategory=person"
2491 res = ldb.search(self.base_dn, expression="objectCategory=person", scope=SCOPE_SUBTREE, attrs=["cn"])
2492 self.assertTrue(len(res) > 0)
2494 print "Testing ldb.search for objectCategory=person with domain scope control"
2495 res = ldb.search(self.base_dn, expression="objectCategory=person", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["domain_scope:1"])
2496 self.assertTrue(len(res) > 0)
2498 print "Testing ldb.search for objectCategory=user"
2499 res = ldb.search(self.base_dn, expression="objectCategory=user", scope=SCOPE_SUBTREE, attrs=["cn"])
2500 self.assertTrue(len(res) > 0)
2502 print "Testing ldb.search for objectCategory=user with domain scope control"
2503 res = ldb.search(self.base_dn, expression="objectCategory=user", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["domain_scope:1"])
2504 self.assertTrue(len(res) > 0)
2506 print "Testing ldb.search for objectCategory=group"
2507 res = ldb.search(self.base_dn, expression="objectCategory=group", scope=SCOPE_SUBTREE, attrs=["cn"])
2508 self.assertTrue(len(res) > 0)
2510 print "Testing ldb.search for objectCategory=group with domain scope control"
2511 res = ldb.search(self.base_dn, expression="objectCategory=group", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["domain_scope:1"])
2512 self.assertTrue(len(res) > 0)
2514 print "Testing creating a user with the posixAccount objectClass"
2515 self.ldb.add_ldif("""dn: cn=posixuser,CN=Users,%s
2518 objectClass: posixAccount
2520 objectClass: organizationalPerson
2526 homeDirectory: /home/posixuser
2527 loginShell: /bin/bash
2528 gecos: Posix User;;;
2529 description: A POSIX user"""% (self.base_dn))
2531 print "Testing removing the posixAccount objectClass from an existing user"
2532 self.ldb.modify_ldif("""dn: cn=posixuser,CN=Users,%s
2535 objectClass: posixAccount"""% (self.base_dn))
2537 print "Testing adding the posixAccount objectClass to an existing user"
2538 self.ldb.modify_ldif("""dn: cn=posixuser,CN=Users,%s
2541 objectClass: posixAccount"""% (self.base_dn))
2543 self.delete_force(self.ldb, "cn=posixuser,cn=users," + self.base_dn)
2544 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
2545 self.delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
2546 self.delete_force(self.ldb, "cn=ldaptestuser3,cn=users," + self.base_dn)
2547 self.delete_force(self.ldb, "cn=ldaptestuser4,cn=ldaptestcontainer," + self.base_dn)
2548 self.delete_force(self.ldb, "cn=ldaptestuser4,cn=ldaptestcontainer2," + self.base_dn)
2549 self.delete_force(self.ldb, "cn=ldaptestuser5,cn=users," + self.base_dn)
2550 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
2551 self.delete_force(self.ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
2552 self.delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2553 self.delete_force(self.ldb, "cn=ldaptest2computer,cn=computers," + self.base_dn)
2554 self.delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
2555 self.delete_force(self.ldb, "cn=ldaptestutf8user èùéìòà,cn=users," + self.base_dn)
2556 self.delete_force(self.ldb, "cn=ldaptestutf8user2 èùéìòà,cn=users," + self.base_dn)
2557 self.delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
2558 self.delete_force(self.ldb, "cn=ldaptestcontainer2," + self.base_dn)
2560 def test_security_descriptor_add(self):
2561 """ Testing ldb.add_ldif() for nTSecurityDescriptor """
2562 user_name = "testdescriptoruser1"
2563 user_dn = "CN=%s,CN=Users,%s" % (user_name, self.base_dn)
2565 # Test add_ldif() with SDDL security descriptor input
2567 self.delete_force(self.ldb, user_dn)
2569 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2570 self.ldb.add_ldif("""
2571 dn: """ + user_dn + """
2573 sAMAccountName: """ + user_name + """
2574 nTSecurityDescriptor: """ + sddl)
2575 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2576 desc = res[0]["nTSecurityDescriptor"][0]
2577 desc = ndr_unpack( security.descriptor, desc )
2578 desc_sddl = desc.as_sddl( self.domain_sid )
2579 self.assertEqual(desc_sddl, sddl)
2581 self.delete_force(self.ldb, user_dn)
2583 # Test add_ldif() with BASE64 security descriptor
2586 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2587 desc = security.descriptor.from_sddl(sddl, self.domain_sid)
2588 desc_binary = ndr_pack(desc)
2589 desc_base64 = base64.b64encode(desc_binary)
2590 self.ldb.add_ldif("""
2591 dn: """ + user_dn + """
2593 sAMAccountName: """ + user_name + """
2594 nTSecurityDescriptor:: """ + desc_base64)
2595 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2596 desc = res[0]["nTSecurityDescriptor"][0]
2597 desc = ndr_unpack(security.descriptor, desc)
2598 desc_sddl = desc.as_sddl(self.domain_sid)
2599 self.assertEqual(desc_sddl, sddl)
2601 self.delete_force(self.ldb, user_dn)
2603 def test_security_descriptor_add_neg(self):
2604 """Test add_ldif() with BASE64 security descriptor input using WRONG domain SID
2607 user_name = "testdescriptoruser1"
2608 user_dn = "CN=%s,CN=Users,%s" % (user_name, self.base_dn)
2609 self.delete_force(self.ldb, user_dn)
2611 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2612 desc = security.descriptor.from_sddl(sddl, security.dom_sid('S-1-5-21'))
2613 desc_base64 = base64.b64encode( ndr_pack(desc) )
2614 self.ldb.add_ldif("""
2615 dn: """ + user_dn + """
2617 sAMAccountName: """ + user_name + """
2618 nTSecurityDescriptor:: """ + desc_base64)
2619 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2620 self.assertTrue("nTSecurityDescriptor" in res[0])
2622 self.delete_force(self.ldb, user_dn)
2624 def test_security_descriptor_modify(self):
2625 """ Testing ldb.modify_ldif() for nTSecurityDescriptor """
2626 user_name = "testdescriptoruser2"
2627 user_dn = "CN=%s,CN=Users,%s" % (user_name, self.base_dn)
2629 # Delete user object and test modify_ldif() with SDDL security descriptor input
2630 # Add ACE to the original descriptor test
2633 self.delete_force(self.ldb, user_dn)
2634 self.ldb.add_ldif("""
2635 dn: """ + user_dn + """
2637 sAMAccountName: """ + user_name)
2639 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2640 desc = res[0]["nTSecurityDescriptor"][0]
2641 desc = ndr_unpack(security.descriptor, desc)
2642 desc_sddl = desc.as_sddl(self.domain_sid)
2643 sddl = desc_sddl[:desc_sddl.find("(")] + "(A;;RPWP;;;AU)" + desc_sddl[desc_sddl.find("("):]
2645 dn: """ + user_dn + """
2647 replace: nTSecurityDescriptor
2648 nTSecurityDescriptor: """ + sddl
2649 self.ldb.modify_ldif(mod)
2650 # Read modified descriptor
2651 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2652 desc = res[0]["nTSecurityDescriptor"][0]
2653 desc = ndr_unpack(security.descriptor, desc)
2654 desc_sddl = desc.as_sddl(self.domain_sid)
2655 self.assertEqual(desc_sddl, sddl)
2657 self.delete_force(self.ldb, user_dn)
2659 # Test modify_ldif() with SDDL security descriptor input
2660 # New desctiptor test
2663 self.ldb.add_ldif("""
2664 dn: """ + user_dn + """
2666 sAMAccountName: """ + user_name)
2668 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2670 dn: """ + user_dn + """
2672 replace: nTSecurityDescriptor
2673 nTSecurityDescriptor: """ + sddl
2674 self.ldb.modify_ldif(mod)
2675 # Read modified descriptor
2676 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2677 desc = res[0]["nTSecurityDescriptor"][0]
2678 desc = ndr_unpack(security.descriptor, desc)
2679 desc_sddl = desc.as_sddl(self.domain_sid)
2680 self.assertEqual(desc_sddl, sddl)
2682 self.delete_force(self.ldb, user_dn)
2684 # Test modify_ldif() with BASE64 security descriptor input
2685 # Add ACE to the original descriptor test
2688 self.ldb.add_ldif("""
2689 dn: """ + user_dn + """
2691 sAMAccountName: """ + user_name)
2693 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2694 desc = res[0]["nTSecurityDescriptor"][0]
2695 desc = ndr_unpack(security.descriptor, desc)
2696 desc_sddl = desc.as_sddl(self.domain_sid)
2697 sddl = desc_sddl[:desc_sddl.find("(")] + "(A;;RPWP;;;AU)" + desc_sddl[desc_sddl.find("("):]
2698 desc = security.descriptor.from_sddl(sddl, self.domain_sid)
2699 desc_base64 = base64.b64encode(ndr_pack(desc))
2701 dn: """ + user_dn + """
2703 replace: nTSecurityDescriptor
2704 nTSecurityDescriptor:: """ + desc_base64
2705 self.ldb.modify_ldif(mod)
2706 # Read modified descriptor
2707 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2708 desc = res[0]["nTSecurityDescriptor"][0]
2709 desc = ndr_unpack(security.descriptor, desc)
2710 desc_sddl = desc.as_sddl(self.domain_sid)
2711 self.assertEqual(desc_sddl, sddl)
2713 self.delete_force(self.ldb, user_dn)
2715 # Test modify_ldif() with BASE64 security descriptor input
2716 # New descriptor test
2719 self.delete_force(self.ldb, user_dn)
2720 self.ldb.add_ldif("""
2721 dn: """ + user_dn + """
2723 sAMAccountName: """ + user_name)
2725 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2726 desc = security.descriptor.from_sddl(sddl, self.domain_sid)
2727 desc_base64 = base64.b64encode(ndr_pack(desc))
2729 dn: """ + user_dn + """
2731 replace: nTSecurityDescriptor
2732 nTSecurityDescriptor:: """ + desc_base64
2733 self.ldb.modify_ldif(mod)
2734 # Read modified descriptor
2735 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2736 desc = res[0]["nTSecurityDescriptor"][0]
2737 desc = ndr_unpack(security.descriptor, desc)
2738 desc_sddl = desc.as_sddl(self.domain_sid)
2739 self.assertEqual(desc_sddl, sddl)
2741 self.delete_force(self.ldb, user_dn)
2744 class BaseDnTests(unittest.TestCase):
2747 super(BaseDnTests, self).setUp()
2750 def test_rootdse_attrs(self):
2751 """Testing for all rootDSE attributes"""
2752 res = self.ldb.search(scope=SCOPE_BASE, attrs=[])
2753 self.assertEquals(len(res), 1)
2755 def test_highestcommittedusn(self):
2756 """Testing for highestCommittedUSN"""
2757 res = self.ldb.search("", scope=SCOPE_BASE, attrs=["highestCommittedUSN"])
2758 self.assertEquals(len(res), 1)
2759 self.assertTrue(int(res[0]["highestCommittedUSN"][0]) != 0)
2761 def test_netlogon(self):
2762 """Testing for netlogon via LDAP"""
2763 res = self.ldb.search("", scope=SCOPE_BASE, attrs=["netlogon"])
2764 self.assertEquals(len(res), 0)
2766 def test_netlogon_highestcommitted_usn(self):
2767 """Testing for netlogon and highestCommittedUSN via LDAP"""
2768 res = self.ldb.search("", scope=SCOPE_BASE,
2769 attrs=["netlogon", "highestCommittedUSN"])
2770 self.assertEquals(len(res), 0)
2772 def test_namingContexts(self):
2773 """Testing for namingContexts in rootDSE"""
2774 res = self.ldb.search("", scope=SCOPE_BASE,
2775 attrs=["namingContexts", "defaultNamingContext", "schemaNamingContext", "configurationNamingContext"])
2776 self.assertEquals(len(res), 1)
2779 for nc in res[0]["namingContexts"]:
2780 self.assertTrue(nc not in ncs)
2783 self.assertTrue(res[0]["defaultNamingContext"][0] in ncs)
2784 self.assertTrue(res[0]["configurationNamingContext"][0] in ncs)
2785 self.assertTrue(res[0]["schemaNamingContext"][0] in ncs)
2788 if not "://" in host:
2789 if os.path.isfile(host):
2790 host = "tdb://%s" % host
2792 host = "ldap://%s" % host
2794 ldb = Ldb(host, credentials=creds, session_info=system_session(), lp=lp)
2795 if not "tdb://" in host:
2796 gc_ldb = Ldb("%s:3268" % host, credentials=creds,
2797 session_info=system_session(), lp=lp)
2801 runner = SubunitTestRunner()
2803 if not runner.run(unittest.makeSuite(BaseDnTests)).wasSuccessful():
2805 if not runner.run(unittest.makeSuite(BasicTests)).wasSuccessful():