2 # -*- coding: utf-8 -*-
3 # This is a port of the original in testprogs/ejs/ldap.js
11 sys.path.append("bin/python")
13 samba.ensure_external_module("subunit", "subunit/python")
14 samba.ensure_external_module("testtools", "testtools")
16 import samba.getopt as options
18 from samba.auth import system_session
19 from ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError
20 from ldb import ERR_NO_SUCH_OBJECT, ERR_ATTRIBUTE_OR_VALUE_EXISTS
21 from ldb import ERR_ENTRY_ALREADY_EXISTS, ERR_UNWILLING_TO_PERFORM
22 from ldb import ERR_NOT_ALLOWED_ON_NON_LEAF, ERR_OTHER, ERR_INVALID_DN_SYNTAX
23 from ldb import ERR_NO_SUCH_ATTRIBUTE
24 from ldb import ERR_OBJECT_CLASS_VIOLATION, ERR_NOT_ALLOWED_ON_RDN
25 from ldb import ERR_NAMING_VIOLATION, ERR_CONSTRAINT_VIOLATION
26 from ldb import ERR_UNDEFINED_ATTRIBUTE_TYPE
27 from ldb import Message, MessageElement, Dn
28 from ldb import FLAG_MOD_ADD, FLAG_MOD_REPLACE, FLAG_MOD_DELETE
30 from samba.dsdb import (UF_NORMAL_ACCOUNT, UF_INTERDOMAIN_TRUST_ACCOUNT,
31 UF_WORKSTATION_TRUST_ACCOUNT, UF_SERVER_TRUST_ACCOUNT,
32 UF_PARTIAL_SECRETS_ACCOUNT,
33 UF_PASSWD_NOTREQD, UF_ACCOUNTDISABLE, ATYPE_NORMAL_ACCOUNT,
34 ATYPE_WORKSTATION_TRUST, SYSTEM_FLAG_DOMAIN_DISALLOW_MOVE)
35 from samba.dcerpc.security import (DOMAIN_RID_USERS, DOMAIN_RID_DOMAIN_MEMBERS,
36 DOMAIN_RID_DCS, DOMAIN_RID_READONLY_DCS)
38 from subunit.run import SubunitTestRunner
41 from samba.ndr import ndr_pack, ndr_unpack
42 from samba.dcerpc import security
44 parser = optparse.OptionParser("ldap [options] <host>")
45 sambaopts = options.SambaOptions(parser)
46 parser.add_option_group(sambaopts)
47 parser.add_option_group(options.VersionOptions(parser))
48 # use command line creds if available
49 credopts = options.CredentialsOptions(parser)
50 parser.add_option_group(credopts)
51 opts, args = parser.parse_args()
59 lp = sambaopts.get_loadparm()
60 creds = credopts.get_credentials(lp)
62 class BasicTests(unittest.TestCase):
64 def delete_force(self, ldb, dn):
67 except LdbError, (num, _):
68 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
70 def find_basedn(self, ldb):
71 res = ldb.search(base="", expression="", scope=SCOPE_BASE,
72 attrs=["defaultNamingContext"])
73 self.assertEquals(len(res), 1)
74 return res[0]["defaultNamingContext"][0]
76 def find_configurationdn(self, ldb):
77 res = ldb.search(base="", expression="", scope=SCOPE_BASE, attrs=["configurationNamingContext"])
78 self.assertEquals(len(res), 1)
79 return res[0]["configurationNamingContext"][0]
81 def find_schemadn(self, ldb):
82 res = ldb.search(base="", expression="", scope=SCOPE_BASE, attrs=["schemaNamingContext"])
83 self.assertEquals(len(res), 1)
84 return res[0]["schemaNamingContext"][0]
86 def find_domain_sid(self):
87 res = self.ldb.search(base=self.base_dn, expression="(objectClass=*)", scope=SCOPE_BASE)
88 return ndr_unpack( security.dom_sid,res[0]["objectSid"][0])
91 super(BasicTests, self).setUp()
94 self.base_dn = self.find_basedn(ldb)
95 self.configuration_dn = self.find_configurationdn(ldb)
96 self.schema_dn = self.find_schemadn(ldb)
97 self.domain_sid = self.find_domain_sid()
99 print "baseDN: %s\n" % self.base_dn
101 self.delete_force(self.ldb, "cn=posixuser,cn=users," + self.base_dn)
102 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
103 self.delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
104 self.delete_force(self.ldb, "cn=ldaptestuser3,cn=users," + self.base_dn)
105 self.delete_force(self.ldb, "cn=ldaptestuser4,cn=ldaptestcontainer," + self.base_dn)
106 self.delete_force(self.ldb, "cn=ldaptestuser4,cn=ldaptestcontainer2," + self.base_dn)
107 self.delete_force(self.ldb, "cn=ldaptestuser5,cn=users," + self.base_dn)
108 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
109 self.delete_force(self.ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
110 self.delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
111 self.delete_force(self.ldb, "cn=ldaptest2computer,cn=computers," + self.base_dn)
112 self.delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
113 self.delete_force(self.ldb, "cn=ldaptestutf8user èùéìòà,cn=users," + self.base_dn)
114 self.delete_force(self.ldb, "cn=ldaptestutf8user2 èùéìòà,cn=users," + self.base_dn)
115 self.delete_force(self.ldb, "cn=entry1,cn=ldaptestcontainer," + self.base_dn)
116 self.delete_force(self.ldb, "cn=entry2,cn=ldaptestcontainer," + self.base_dn)
117 self.delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
118 self.delete_force(self.ldb, "cn=ldaptestcontainer2," + self.base_dn)
119 self.delete_force(self.ldb, "cn=parentguidtest,cn=users," + self.base_dn)
120 self.delete_force(self.ldb, "cn=parentguidtest,cn=testotherusers," + self.base_dn)
121 self.delete_force(self.ldb, "cn=testotherusers," + self.base_dn)
122 self.delete_force(self.ldb, "cn=ldaptestobject," + self.base_dn)
123 self.delete_force(self.ldb, "description=xyz,cn=users," + self.base_dn)
124 self.delete_force(self.ldb, "ou=testou,cn=users," + self.base_dn)
125 self.delete_force(self.ldb, "cn=testsecret,cn=system," + self.base_dn)
127 def test_objectclasses(self):
128 """Test objectClass behaviour"""
129 print "Test objectClass behaviour"""
131 # We cannot create LSA-specific objects (oc "secret" or "trustedDomain")
134 "dn": "cn=testsecret,cn=system," + self.base_dn,
135 "objectClass": "secret" })
137 except LdbError, (num, _):
138 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
140 # Invalid objectclass specified
143 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
144 "objectClass": "X" })
146 except LdbError, (num, _):
147 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
149 # Invalid objectCategory specified
152 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
153 "objectClass": "person",
154 "objectCategory": self.base_dn })
156 except LdbError, (num, _):
157 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
159 # Multi-valued "systemFlags"
162 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
163 "objectClass": "person",
164 "systemFlags": ["0", str(SYSTEM_FLAG_DOMAIN_DISALLOW_MOVE)] })
166 except LdbError, (num, _):
167 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
169 # We cannot instanciate from an abstract objectclass
172 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
173 "objectClass": "connectionPoint" })
175 except LdbError, (num, _):
176 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
179 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
180 "objectClass": "person" })
182 # We can remove derivation classes of the structural objectclass
183 # but they're going to be readded afterwards
185 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
186 m["objectClass"] = MessageElement("top", FLAG_MOD_DELETE,
190 res = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
191 scope=SCOPE_BASE, attrs=["objectClass"])
192 self.assertTrue(len(res) == 1)
193 self.assertTrue("top" in res[0]["objectClass"])
195 # The top-most structural class cannot be deleted since there are
196 # attributes of it in use
198 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
199 m["objectClass"] = MessageElement("person", FLAG_MOD_DELETE,
204 except LdbError, (num, _):
205 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
207 # We cannot delete classes which weren't specified
209 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
210 m["objectClass"] = MessageElement("computer", FLAG_MOD_DELETE,
215 except LdbError, (num, _):
216 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
218 # An invalid class cannot be added
220 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
221 m["objectClass"] = MessageElement("X", FLAG_MOD_ADD,
226 except LdbError, (num, _):
227 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
229 # The top-most structural class cannot be changed by adding another
232 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
233 m["objectClass"] = MessageElement("user", FLAG_MOD_ADD,
238 except LdbError, (num, _):
239 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
241 # An already specified objectclass cannot be added another time
243 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
244 m["objectClass"] = MessageElement("person", FLAG_MOD_ADD,
249 except LdbError, (num, _):
250 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
252 # Auxiliary classes can always be added
254 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
255 m["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_ADD,
259 # It's only possible to replace with the same objectclass combination.
260 # So the replace action on "objectClass" attributes is really useless.
262 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
263 m["objectClass"] = MessageElement(["top", "person", "bootableDevice"],
264 FLAG_MOD_REPLACE, "objectClass")
268 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
269 m["objectClass"] = MessageElement(["person", "bootableDevice"],
270 FLAG_MOD_REPLACE, "objectClass")
274 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
275 m["objectClass"] = MessageElement(["top", "person", "bootableDevice",
276 "connectionPoint"], FLAG_MOD_REPLACE, "objectClass")
280 except LdbError, (num, _):
281 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
284 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
285 m["objectClass"] = MessageElement(["top", "computer"], FLAG_MOD_REPLACE,
290 except LdbError, (num, _):
291 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
293 # Classes can be removed unless attributes of them are used.
295 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
296 m["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_DELETE,
300 res = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
301 scope=SCOPE_BASE, attrs=["objectClass"])
302 self.assertTrue(len(res) == 1)
303 self.assertFalse("bootableDevice" in res[0]["objectClass"])
306 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
307 m["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_ADD,
311 # Add an attribute specific to the "bootableDevice" class
313 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
314 m["bootParameter"] = MessageElement("test", FLAG_MOD_ADD,
318 # Classes can be removed unless attributes of them are used. Now there
319 # exist such attributes on the entry.
321 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
322 m["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_DELETE,
327 except LdbError, (num, _):
328 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
330 # Remove the previously specified attribute
332 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
333 m["bootParameter"] = MessageElement("test", FLAG_MOD_DELETE,
337 # Classes can be removed unless attributes of them are used.
339 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
340 m["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_DELETE,
344 self.delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
346 def test_system_only(self):
347 """Test systemOnly objects"""
348 print "Test systemOnly objects"""
352 "dn": "cn=ldaptestobject," + self.base_dn,
353 "objectclass": "configuration"})
355 except LdbError, (num, _):
356 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
360 "dn": "cn=testsecret,cn=system," + self.base_dn,
361 "objectclass": "secret"})
363 except LdbError, (num, _):
364 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
366 self.delete_force(self.ldb, "cn=ldaptestobject," + self.base_dn)
367 self.delete_force(self.ldb, "cn=testsecret,cn=system," + self.base_dn)
369 def test_invalid_parent(self):
370 """Test adding an object with invalid parent"""
371 print "Test adding an object with invalid parent"""
375 "dn": "cn=ldaptestgroup,cn=thisdoesnotexist123,"
377 "objectclass": "group"})
379 except LdbError, (num, _):
380 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
382 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=thisdoesnotexist123,"
387 "dn": "ou=testou,cn=users," + self.base_dn,
388 "objectclass": "organizationalUnit"})
390 except LdbError, (num, _):
391 self.assertEquals(num, ERR_NAMING_VIOLATION)
393 self.delete_force(self.ldb, "ou=testou,cn=users," + self.base_dn)
395 def test_invalid_attribute(self):
396 """Test invalid attributes on schema/objectclasses"""
397 print "Test invalid attributes on schema/objectclasses"""
399 # attributes not in schema test
405 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
406 "objectclass": "group",
407 "thisdoesnotexist": "x"})
409 except LdbError, (num, _):
410 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
413 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
414 "objectclass": "group"})
419 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
420 m["thisdoesnotexist"] = MessageElement("x", FLAG_MOD_REPLACE,
425 except LdbError, (num, _):
426 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
428 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
430 # attributes not in objectclasses and mandatory attributes missing test
431 # Use here a non-SAM entry since it doesn't have special triggers
432 # associated which have an impact on the error results.
436 # mandatory attribute missing
439 "dn": "cn=ldaptestobject," + self.base_dn,
440 "objectclass": "ipProtocol"})
442 except LdbError, (num, _):
443 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
445 # inadequate but schema-valid attribute specified
448 "dn": "cn=ldaptestobject," + self.base_dn,
449 "objectclass": "ipProtocol",
450 "ipProtocolNumber": "1",
453 except LdbError, (num, _):
454 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
457 "dn": "cn=ldaptestobject," + self.base_dn,
458 "objectclass": "ipProtocol",
459 "ipProtocolNumber": "1"})
463 # inadequate but schema-valid attribute add trial
465 m.dn = Dn(ldb, "cn=ldaptestobject," + self.base_dn)
466 m["uid"] = MessageElement("0", FLAG_MOD_ADD, "uid")
470 except LdbError, (num, _):
471 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
473 # mandatory attribute delete trial
475 m.dn = Dn(ldb, "cn=ldaptestobject," + self.base_dn)
476 m["ipProtocolNumber"] = MessageElement([], FLAG_MOD_DELETE,
481 except LdbError, (num, _):
482 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
484 # mandatory attribute delete trial
486 m.dn = Dn(ldb, "cn=ldaptestobject," + self.base_dn)
487 m["ipProtocolNumber"] = MessageElement([], FLAG_MOD_REPLACE,
492 except LdbError, (num, _):
493 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
495 self.delete_force(self.ldb, "cn=ldaptestobject," + self.base_dn)
497 def test_single_valued_attributes(self):
498 """Test single-valued attributes"""
499 print "Test single-valued attributes"""
503 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
504 "objectclass": "group",
505 "sAMAccountName": ["nam1", "nam2"]})
507 except LdbError, (num, _):
508 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
511 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
512 "objectclass": "group"})
515 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
516 m["sAMAccountName"] = MessageElement(["nam1","nam2"], FLAG_MOD_REPLACE,
521 except LdbError, (num, _):
522 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
525 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
526 m["sAMAccountName"] = MessageElement("testgroupXX", FLAG_MOD_REPLACE,
531 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
532 m["sAMAccountName"] = MessageElement("testgroupXX2", FLAG_MOD_ADD,
537 except LdbError, (num, _):
538 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
540 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
542 def test_multi_valued_attributes(self):
543 """Test multi-valued attributes"""
544 print "Test multi-valued attributes"""
546 # TODO: In this test I added some special tests where I got very unusual
547 # results back from a real AD. s4 doesn't match them and I've no idea how to
548 # implement those error cases (maybe there exists a special trigger for
549 # "description" attributes which handle them)
552 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
553 "description": "desc2",
554 "objectclass": "group",
555 "description": "desc1"})
557 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
560 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
561 "objectclass": "group",
562 "description": ["desc1", "desc2"]})
565 # m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
566 # m["description"] = MessageElement(["desc1","desc2"], FLAG_MOD_REPLACE,
571 # except LdbError, (num, _):
572 # self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
575 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
576 m["description"] = MessageElement("desc1", FLAG_MOD_REPLACE,
581 # m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
582 # m["description"] = MessageElement("desc3", FLAG_MOD_ADD,
587 # except LdbError, (num, _):
588 # self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
591 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
592 m["description"] = MessageElement(["desc1","desc2"], FLAG_MOD_DELETE,
597 except LdbError, (num, _):
598 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
601 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
602 m["description"] = MessageElement("desc1", FLAG_MOD_DELETE,
607 # m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
608 # m["description"] = MessageElement(["desc1","desc2"], FLAG_MOD_REPLACE,
613 # except LdbError, (num, _):
614 # self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
617 # m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
618 # m["description"] = MessageElement(["desc3", "desc4"], FLAG_MOD_ADD,
623 # except LdbError, (num, _):
624 # self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
627 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
628 m["description"] = MessageElement("desc3", FLAG_MOD_ADD,
632 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
634 def test_empty_messages(self):
635 """Test empty messages"""
636 print "Test empty messages"""
639 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
644 except LdbError, (num, _):
645 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
650 except LdbError, (num, _):
651 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
653 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
655 def test_empty_attributes(self):
656 """Test empty attributes"""
657 print "Test empty attributes"""
660 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
661 m["objectClass"] = MessageElement("group", FLAG_MOD_ADD, "objectClass")
662 m["description"] = MessageElement([], FLAG_MOD_ADD, "description")
667 except LdbError, (num, _):
668 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
671 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
672 "objectclass": "group"})
675 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
676 m["description"] = MessageElement([], FLAG_MOD_ADD, "description")
681 except LdbError, (num, _):
682 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
685 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
686 m["description"] = MessageElement([], FLAG_MOD_REPLACE, "description")
690 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
691 m["description"] = MessageElement([], FLAG_MOD_DELETE, "description")
695 except LdbError, (num, _):
696 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
698 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
700 def test_instanceType(self):
701 """Tests the 'instanceType' attribute"""
702 print "Tests the 'instanceType' attribute"""
704 # The instance type is single-valued
707 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
708 "objectclass": "group",
709 "instanceType": ["0", "1"]})
711 except LdbError, (num, _):
712 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
714 # The head NC flag cannot be set without the write flag
717 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
718 "objectclass": "group",
719 "instanceType": "1" })
721 except LdbError, (num, _):
722 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
724 # We cannot manipulate NCs without the head NC flag
727 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
728 "objectclass": "group",
729 "instanceType": "32" })
731 except LdbError, (num, _):
732 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
735 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
736 "objectclass": "group"})
739 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
740 m["instanceType"] = MessageElement("0", FLAG_MOD_REPLACE,
745 except LdbError, (num, _):
746 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
749 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
750 m["instanceType"] = MessageElement([], FLAG_MOD_REPLACE,
755 except LdbError, (num, _):
756 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
759 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
760 m["instanceType"] = MessageElement([], FLAG_MOD_DELETE, "instanceType")
764 except LdbError, (num, _):
765 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
767 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
769 def test_distinguished_name(self):
770 """Tests the 'distinguishedName' attribute"""
771 print "Tests the 'distinguishedName' attribute"""
773 # a wrong "distinguishedName" attribute is obviously tolerated
775 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
776 "objectclass": "group",
777 "distinguishedName": "cn=ldaptest,cn=users," + self.base_dn})
779 # proof if the DN has been set correctly
780 res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
781 scope=SCOPE_BASE, attrs=["distinguishedName"])
782 self.assertTrue(len(res) == 1)
783 self.assertTrue("distinguishedName" in res[0])
784 self.assertTrue(Dn(ldb, res[0]["distinguishedName"][0])
785 == Dn(ldb, "cn=ldaptestgroup, cn=users," + self.base_dn))
788 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
789 m["distinguishedName"] = MessageElement(
790 "cn=ldaptestuser,cn=users," + self.base_dn, FLAG_MOD_ADD,
796 except LdbError, (num, _):
797 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
800 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
801 m["distinguishedName"] = MessageElement(
802 "cn=ldaptestuser,cn=users," + self.base_dn, FLAG_MOD_REPLACE,
808 except LdbError, (num, _):
809 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
812 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
813 m["distinguishedName"] = MessageElement(
814 "cn=ldaptestuser,cn=users," + self.base_dn, FLAG_MOD_DELETE,
820 except LdbError, (num, _):
821 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
823 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
825 def test_rdn_name(self):
827 print "Tests the RDN"""
831 "dn": "description=xyz,cn=users," + self.base_dn,
832 "objectclass": "group"})
834 except LdbError, (num, _):
835 self.assertEquals(num, ERR_NAMING_VIOLATION)
837 self.delete_force(self.ldb, "description=xyz,cn=users," + self.base_dn)
839 # a wrong "name" attribute is obviously tolerated
841 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
842 "objectclass": "group",
843 "name": "ldaptestgroupx"})
845 # proof if the name has been set correctly
846 res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
847 scope=SCOPE_BASE, attrs=["name"])
848 self.assertTrue(len(res) == 1)
849 self.assertTrue("name" in res[0])
850 self.assertTrue(res[0]["name"][0] == "ldaptestgroup")
853 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
854 m["name"] = MessageElement("cn=ldaptestuser", FLAG_MOD_REPLACE,
859 except LdbError, (num, _):
860 self.assertEquals(num, ERR_NOT_ALLOWED_ON_RDN)
863 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
864 m["cn"] = MessageElement("ldaptestuser",
865 FLAG_MOD_REPLACE, "cn")
869 except LdbError, (num, _):
870 self.assertEquals(num, ERR_NOT_ALLOWED_ON_RDN)
872 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
875 # this test needs to be disabled until we really understand
876 # what the rDN length constraints are
877 def DISABLED_test_largeRDN(self):
878 """Testing large rDN (limit 64 characters)"""
879 rdn = "CN=a012345678901234567890123456789012345678901234567890123456789012";
880 self.delete_force(self.ldb, "%s,%s" % (rdn, self.base_dn))
882 dn: %s,%s""" % (rdn,self.base_dn) + """
883 objectClass: container
885 self.ldb.add_ldif(ldif)
886 self.delete_force(self.ldb, "%s,%s" % (rdn, self.base_dn))
888 rdn = "CN=a0123456789012345678901234567890123456789012345678901234567890120";
889 self.delete_force(self.ldb, "%s,%s" % (rdn, self.base_dn))
892 dn: %s,%s""" % (rdn,self.base_dn) + """
893 objectClass: container
895 self.ldb.add_ldif(ldif)
897 except LdbError, (num, _):
898 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
899 self.delete_force(self.ldb, "%s,%s" % (rdn, self.base_dn))
901 def test_rename(self):
902 """Tests the rename operation"""
903 print "Tests the rename operations"""
906 # cannot rename to be a child of itself
907 ldb.rename(self.base_dn, "dc=test," + self.base_dn)
909 except LdbError, (num, _):
910 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
914 ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser2,cn=users," + self.base_dn)
916 except LdbError, (num, _):
917 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
920 "dn": "cn=ldaptestuser2,cn=users," + self.base_dn,
921 "objectclass": ["user", "person"] })
923 ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser2,cn=users," + self.base_dn)
924 ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=users," + self.base_dn)
925 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestUSER3,cn=users," + self.base_dn)
928 # containment problem: a user entry cannot contain user entries
929 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser4,cn=ldaptestuser3,cn=users," + self.base_dn)
931 except LdbError, (num, _):
932 self.assertEquals(num, ERR_NAMING_VIOLATION)
936 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=people,cn=users," + self.base_dn)
938 except LdbError, (num, _):
939 self.assertEquals(num, ERR_OTHER)
942 # invalid target DN syntax
943 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, ",cn=users," + self.base_dn)
945 except LdbError, (num, _):
946 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
950 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "ou=ldaptestuser3,cn=users," + self.base_dn)
952 except LdbError, (num, _):
953 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
955 self.delete_force(self.ldb, "cn=ldaptestuser3,cn=users," + self.base_dn)
957 # Performs some "systemFlags" testing
959 # Move failing since no "SYSTEM_FLAG_CONFIG_ALLOW_MOVE"
961 ldb.rename("CN=DisplaySpecifiers," + self.configuration_dn, "CN=DisplaySpecifiers,CN=Services," + self.configuration_dn)
963 except LdbError, (num, _):
964 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
966 # Limited move failing since no "SYSTEM_FLAG_CONFIG_ALLOW_LIMITED_MOVE"
968 ldb.rename("CN=Directory Service,CN=Windows NT,CN=Services," + self.configuration_dn, "CN=Directory Service,CN=RRAS,CN=Services," + self.configuration_dn)
970 except LdbError, (num, _):
971 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
973 # Rename failing since no "SYSTEM_FLAG_CONFIG_ALLOW_RENAME"
975 ldb.rename("CN=DisplaySpecifiers," + self.configuration_dn, "CN=DisplaySpecifiers2," + self.configuration_dn)
977 except LdbError, (num, _):
978 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
980 # It's not really possible to test moves on the schema partition since
981 # there don't exist subcontainers on it.
983 # Rename failing since "SYSTEM_FLAG_SCHEMA_BASE_OBJECT"
985 ldb.rename("CN=Top," + self.schema_dn, "CN=Top2," + self.schema_dn)
987 except LdbError, (num, _):
988 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
990 # Move failing since "SYSTEM_FLAG_DOMAIN_DISALLOW_MOVE"
992 ldb.rename("CN=Users," + self.base_dn, "CN=Users,CN=Computers," + self.base_dn)
994 except LdbError, (num, _):
995 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
997 # Rename failing since "SYSTEM_FLAG_DOMAIN_DISALLOW_RENAME"
999 ldb.rename("CN=Users," + self.base_dn, "CN=Users2," + self.base_dn)
1001 except LdbError, (num, _):
1002 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1004 # Performs some other constraints testing
1007 ldb.rename("CN=Policies,CN=System," + self.base_dn, "CN=Users2," + self.base_dn)
1009 except LdbError, (num, _):
1010 self.assertEquals(num, ERR_OTHER)
1012 def test_rename_twice(self):
1013 """Tests the rename operation twice - this corresponds to a past bug"""
1014 print "Tests the rename twice operation"""
1017 "dn": "cn=ldaptestuser5,cn=users," + self.base_dn,
1018 "objectclass": ["user", "person"] })
1020 ldb.rename("cn=ldaptestuser5,cn=users," + self.base_dn, "cn=ldaptestUSER5,cn=users," + self.base_dn)
1021 self.delete_force(self.ldb, "cn=ldaptestuser5,cn=users," + self.base_dn)
1023 "dn": "cn=ldaptestuser5,cn=users," + self.base_dn,
1024 "objectclass": ["user", "person"] })
1025 ldb.rename("cn=ldaptestuser5,cn=Users," + self.base_dn, "cn=ldaptestUSER5,cn=users," + self.base_dn)
1026 res = ldb.search(expression="cn=ldaptestuser5")
1027 print "Found %u records" % len(res)
1028 self.assertEquals(len(res), 1, "Wrong number of hits for cn=ldaptestuser5")
1029 res = ldb.search(expression="(&(cn=ldaptestuser5)(objectclass=user))")
1030 print "Found %u records" % len(res)
1031 self.assertEquals(len(res), 1, "Wrong number of hits for (&(cn=ldaptestuser5)(objectclass=user))")
1032 self.delete_force(self.ldb, "cn=ldaptestuser5,cn=users," + self.base_dn)
1034 def test_parentGUID(self):
1035 """Test parentGUID behaviour"""
1036 print "Testing parentGUID behaviour\n"
1038 # TODO: This seems to fail on Windows Server. Hidden attribute?
1041 "dn": "cn=parentguidtest,cn=users," + self.base_dn,
1042 "objectclass":"user",
1043 "samaccountname":"parentguidtest"});
1044 res1 = ldb.search(base="cn=parentguidtest,cn=users," + self.base_dn, scope=SCOPE_BASE,
1045 attrs=["parentGUID", "samaccountname"]);
1046 res2 = ldb.search(base="cn=users," + self.base_dn,scope=SCOPE_BASE,
1047 attrs=["objectGUID"]);
1048 res3 = ldb.search(base=self.base_dn, scope=SCOPE_BASE,
1049 attrs=["parentGUID"]);
1050 res4 = ldb.search(base=self.configuration_dn, scope=SCOPE_BASE,
1051 attrs=["parentGUID"]);
1052 res5 = ldb.search(base=self.schema_dn, scope=SCOPE_BASE,
1053 attrs=["parentGUID"]);
1055 """Check if the parentGUID is valid """
1056 self.assertEquals(res1[0]["parentGUID"], res2[0]["objectGUID"]);
1058 """Check if it returns nothing when there is no parent object - default NC"""
1059 has_parentGUID = False
1060 for key in res3[0].keys():
1061 if key == "parentGUID":
1062 has_parentGUID = True
1064 self.assertFalse(has_parentGUID);
1066 """Check if it returns nothing when there is no parent object - configuration NC"""
1067 has_parentGUID = False
1068 for key in res4[0].keys():
1069 if key == "parentGUID":
1070 has_parentGUID = True
1072 self.assertFalse(has_parentGUID);
1074 """Check if it returns nothing when there is no parent object - schema NC"""
1075 has_parentGUID = False
1076 for key in res5[0].keys():
1077 if key == "parentGUID":
1078 has_parentGUID = True
1080 self.assertFalse(has_parentGUID);
1082 """Ensures that if you look for another object attribute after the constructed
1083 parentGUID, it will return correctly"""
1084 has_another_attribute = False
1085 for key in res1[0].keys():
1086 if key == "sAMAccountName":
1087 has_another_attribute = True
1089 self.assertTrue(has_another_attribute)
1090 self.assertTrue(len(res1[0]["samaccountname"]) == 1)
1091 self.assertEquals(res1[0]["samaccountname"][0], "parentguidtest");
1093 print "Testing parentGUID behaviour on rename\n"
1096 "dn": "cn=testotherusers," + self.base_dn,
1097 "objectclass":"container"});
1098 res1 = ldb.search(base="cn=testotherusers," + self.base_dn,scope=SCOPE_BASE,
1099 attrs=["objectGUID"]);
1100 ldb.rename("cn=parentguidtest,cn=users," + self.base_dn,
1101 "cn=parentguidtest,cn=testotherusers," + self.base_dn);
1102 res2 = ldb.search(base="cn=parentguidtest,cn=testotherusers," + self.base_dn,
1104 attrs=["parentGUID"]);
1105 self.assertEquals(res1[0]["objectGUID"], res2[0]["parentGUID"]);
1107 self.delete_force(self.ldb, "cn=parentguidtest,cn=testotherusers," + self.base_dn)
1108 self.delete_force(self.ldb, "cn=testotherusers," + self.base_dn)
1110 def test_groupType_int32(self):
1111 """Test groupType (int32) behaviour (should appear to be casted to a 32 bit signed integer before comparsion)"""
1112 print "Testing groupType (int32) behaviour\n"
1114 res1 = ldb.search(base=self.base_dn, scope=SCOPE_SUBTREE,
1115 attrs=["groupType"], expression="groupType=2147483653");
1117 res2 = ldb.search(base=self.base_dn, scope=SCOPE_SUBTREE,
1118 attrs=["groupType"], expression="groupType=-2147483643");
1120 self.assertEquals(len(res1), len(res2))
1122 self.assertTrue(res1.count > 0)
1124 self.assertEquals(res1[0]["groupType"][0], "-2147483643")
1126 def test_linked_attributes(self):
1127 """This tests the linked attribute behaviour"""
1128 print "Testing linked attribute behaviour\n"
1131 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
1132 "objectclass": "group"})
1134 # This should not work since "memberOf" is linked to "member"
1137 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1138 "objectclass": ["user", "person"],
1139 "memberOf": "cn=ldaptestgroup,cn=users," + self.base_dn})
1140 except LdbError, (num, _):
1141 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1144 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1145 "objectclass": ["user", "person"]})
1148 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1149 m["memberOf"] = MessageElement("cn=ldaptestgroup,cn=users," + self.base_dn,
1150 FLAG_MOD_ADD, "memberOf")
1154 except LdbError, (num, _):
1155 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1158 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1159 m["member"] = MessageElement("cn=ldaptestuser,cn=users," + self.base_dn,
1160 FLAG_MOD_ADD, "member")
1164 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1165 m["memberOf"] = MessageElement("cn=ldaptestgroup,cn=users," + self.base_dn,
1166 FLAG_MOD_REPLACE, "memberOf")
1170 except LdbError, (num, _):
1171 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1174 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1175 m["memberOf"] = MessageElement("cn=ldaptestgroup,cn=users," + self.base_dn,
1176 FLAG_MOD_DELETE, "memberOf")
1180 except LdbError, (num, _):
1181 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1184 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1185 m["member"] = MessageElement("cn=ldaptestuser,cn=users," + self.base_dn,
1186 FLAG_MOD_DELETE, "member")
1189 # This should yield no results since the member attribute for
1190 # "ldaptestuser" should have been deleted
1191 res1 = ldb.search("cn=ldaptestgroup, cn=users," + self.base_dn,
1193 expression="(member=cn=ldaptestuser,cn=users," + self.base_dn + ")",
1195 self.assertTrue(len(res1) == 0)
1197 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1200 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
1201 "objectclass": "group",
1202 "member": "cn=ldaptestuser,cn=users," + self.base_dn})
1204 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1206 # Make sure that the "member" attribute for "ldaptestuser" has been
1208 res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
1209 scope=SCOPE_BASE, attrs=["member"])
1210 self.assertTrue(len(res) == 1)
1211 self.assertFalse("member" in res[0])
1213 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1215 def test_users_groups(self):
1216 """This tests the SAM users and groups behaviour"""
1217 print "Testing users and groups behaviour\n"
1220 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
1221 "objectclass": "group"})
1224 "dn": "cn=ldaptestgroup2,cn=users," + self.base_dn,
1225 "objectclass": "group"})
1227 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
1228 scope=SCOPE_BASE, attrs=["objectSID"])
1229 self.assertTrue(len(res1) == 1)
1230 group_rid_1 = security.dom_sid(ldb.schema_format_value("objectSID",
1231 res1[0]["objectSID"][0])).split()[1]
1233 res1 = ldb.search("cn=ldaptestgroup2,cn=users," + self.base_dn,
1234 scope=SCOPE_BASE, attrs=["objectSID"])
1235 self.assertTrue(len(res1) == 1)
1236 group_rid_2 = security.dom_sid(ldb.schema_format_value("objectSID",
1237 res1[0]["objectSID"][0])).split()[1]
1239 # Try to create a user with an invalid primary group
1242 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1243 "objectclass": ["user", "person"],
1244 "primaryGroupID": "0"})
1246 except LdbError, (num, _):
1247 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1248 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1250 # Try to Create a user with a valid primary group
1253 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1254 "objectclass": ["user", "person"],
1255 "primaryGroupID": str(group_rid_1)})
1257 except LdbError, (num, _):
1258 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1259 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1261 # Test to see how we should behave when the user account doesn't
1264 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1265 m["primaryGroupID"] = MessageElement("0", FLAG_MOD_REPLACE,
1270 except LdbError, (num, _):
1271 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
1273 # Test to see how we should behave when the account isn't a user
1275 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1276 m["primaryGroupID"] = MessageElement("0", FLAG_MOD_REPLACE,
1281 except LdbError, (num, _):
1282 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
1284 # Test default primary groups on add operations
1287 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1288 "objectclass": ["user", "person"]})
1290 res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
1291 scope=SCOPE_BASE, attrs=["primaryGroupID"])
1292 self.assertTrue(len(res1) == 1)
1293 self.assertEquals(res1[0]["primaryGroupID"][0], str(DOMAIN_RID_USERS))
1295 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1298 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1299 "objectclass": ["user", "person"],
1300 "userAccountControl": str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD) })
1302 res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
1303 scope=SCOPE_BASE, attrs=["primaryGroupID"])
1304 self.assertTrue(len(res1) == 1)
1305 self.assertEquals(res1[0]["primaryGroupID"][0], str(DOMAIN_RID_USERS))
1307 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1309 # unfortunately the INTERDOMAIN_TRUST_ACCOUNT case cannot be tested
1310 # since such accounts aren't directly creatable (ACCESS_DENIED)
1313 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1314 "objectclass": ["computer"],
1315 "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT | UF_PASSWD_NOTREQD) })
1317 res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
1318 scope=SCOPE_BASE, attrs=["primaryGroupID"])
1319 self.assertTrue(len(res1) == 1)
1320 self.assertEquals(res1[0]["primaryGroupID"][0], str(DOMAIN_RID_DOMAIN_MEMBERS))
1322 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1325 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1326 "objectclass": ["computer"],
1327 "userAccountControl": str(UF_SERVER_TRUST_ACCOUNT | UF_PASSWD_NOTREQD) })
1329 res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
1330 scope=SCOPE_BASE, attrs=["primaryGroupID"])
1331 self.assertTrue(len(res1) == 1)
1332 self.assertEquals(res1[0]["primaryGroupID"][0], str(DOMAIN_RID_DCS))
1334 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1336 # Read-only DC accounts are only creatable by
1337 # UF_WORKSTATION_TRUST_ACCOUNT and work only on DCs >= 2008 (therefore
1338 # we have a fallback in the assertion)
1340 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1341 "objectclass": ["computer"],
1342 "userAccountControl": str(UF_PARTIAL_SECRETS_ACCOUNT | UF_WORKSTATION_TRUST_ACCOUNT | UF_PASSWD_NOTREQD) })
1344 res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
1345 scope=SCOPE_BASE, attrs=["primaryGroupID"])
1346 self.assertTrue(len(res1) == 1)
1347 self.assertTrue(res1[0]["primaryGroupID"][0] == str(DOMAIN_RID_READONLY_DCS) or
1348 res1[0]["primaryGroupID"][0] == str(DOMAIN_RID_DOMAIN_MEMBERS))
1350 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1352 # Test default primary groups on modify operations
1355 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1356 "objectclass": ["user", "person"]})
1359 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1360 m["userAccountControl"] = MessageElement(str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD), FLAG_MOD_REPLACE,
1361 "userAccountControl")
1364 res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
1365 scope=SCOPE_BASE, attrs=["primaryGroupID"])
1366 self.assertTrue(len(res1) == 1)
1367 self.assertEquals(res1[0]["primaryGroupID"][0], str(DOMAIN_RID_USERS))
1369 # unfortunately the INTERDOMAIN_TRUST_ACCOUNT case cannot be tested
1370 # since such accounts aren't directly creatable (ACCESS_DENIED)
1372 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1375 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1376 "objectclass": ["computer"]})
1378 res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
1379 scope=SCOPE_BASE, attrs=["primaryGroupID"])
1380 self.assertTrue(len(res1) == 1)
1381 self.assertEquals(res1[0]["primaryGroupID"][0], str(DOMAIN_RID_USERS))
1384 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1385 m["userAccountControl"] = MessageElement(str(UF_WORKSTATION_TRUST_ACCOUNT | UF_PASSWD_NOTREQD), FLAG_MOD_REPLACE,
1386 "userAccountControl")
1389 res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
1390 scope=SCOPE_BASE, attrs=["primaryGroupID"])
1391 self.assertTrue(len(res1) == 1)
1392 self.assertEquals(res1[0]["primaryGroupID"][0], str(DOMAIN_RID_DOMAIN_MEMBERS))
1395 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1396 m["userAccountControl"] = MessageElement(str(UF_SERVER_TRUST_ACCOUNT | UF_PASSWD_NOTREQD), FLAG_MOD_REPLACE,
1397 "userAccountControl")
1400 res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
1401 scope=SCOPE_BASE, attrs=["primaryGroupID"])
1402 self.assertTrue(len(res1) == 1)
1403 self.assertEquals(res1[0]["primaryGroupID"][0], str(DOMAIN_RID_DCS))
1405 # Read-only DC accounts are only creatable by
1406 # UF_WORKSTATION_TRUST_ACCOUNT and work only on DCs >= 2008 (therefore
1407 # we have a fallback in the assertion)
1409 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1410 m["userAccountControl"] = MessageElement(str(UF_PARTIAL_SECRETS_ACCOUNT | UF_WORKSTATION_TRUST_ACCOUNT | UF_PASSWD_NOTREQD), FLAG_MOD_REPLACE,
1411 "userAccountControl")
1414 res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
1415 scope=SCOPE_BASE, attrs=["primaryGroupID"])
1416 self.assertTrue(len(res1) == 1)
1417 self.assertTrue(res1[0]["primaryGroupID"][0] == str(DOMAIN_RID_READONLY_DCS) or
1418 res1[0]["primaryGroupID"][0] == str(DOMAIN_RID_DOMAIN_MEMBERS))
1420 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1422 # Recreate account for further tests
1425 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1426 "objectclass": ["user", "person"]})
1428 # We should be able to reset our actual primary group
1430 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1431 m["primaryGroupID"] = MessageElement(str(DOMAIN_RID_USERS), FLAG_MOD_REPLACE,
1435 # Try to add invalid primary group
1437 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1438 m["primaryGroupID"] = MessageElement("0", FLAG_MOD_REPLACE,
1443 except LdbError, (num, _):
1444 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1446 # Try to make group 1 primary - should be denied since it is not yet
1449 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1450 m["primaryGroupID"] = MessageElement(str(group_rid_1),
1451 FLAG_MOD_REPLACE, "primaryGroupID")
1455 except LdbError, (num, _):
1456 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1458 # Make group 1 secondary
1460 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1461 m["member"] = MessageElement("cn=ldaptestuser,cn=users," + self.base_dn,
1462 FLAG_MOD_REPLACE, "member")
1465 # Make group 1 primary
1467 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1468 m["primaryGroupID"] = MessageElement(str(group_rid_1),
1469 FLAG_MOD_REPLACE, "primaryGroupID")
1472 # Try to delete group 1 - should be denied
1474 ldb.delete("cn=ldaptestgroup,cn=users," + self.base_dn)
1476 except LdbError, (num, _):
1477 self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
1479 # Try to add group 1 also as secondary - should be denied
1481 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1482 m["member"] = MessageElement("cn=ldaptestuser,cn=users," + self.base_dn,
1483 FLAG_MOD_ADD, "member")
1487 except LdbError, (num, _):
1488 self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
1490 # Try to add invalid member to group 1 - should be denied
1492 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1493 m["member"] = MessageElement(
1494 "cn=ldaptestuser3,cn=users," + self.base_dn,
1495 FLAG_MOD_ADD, "member")
1499 except LdbError, (num, _):
1500 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
1502 # Make group 2 secondary
1504 m.dn = Dn(ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
1505 m["member"] = MessageElement("cn=ldaptestuser,cn=users," + self.base_dn,
1506 FLAG_MOD_ADD, "member")
1511 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1512 m["primaryGroupID"] = MessageElement(str(group_rid_2),
1513 FLAG_MOD_REPLACE, "primaryGroupID")
1516 # Old primary group should contain a "member" attribute for the user,
1517 # the new shouldn't contain anymore one
1518 res1 = ldb.search("cn=ldaptestgroup, cn=users," + self.base_dn,
1519 scope=SCOPE_BASE, attrs=["member"])
1520 self.assertTrue(len(res1) == 1)
1521 self.assertTrue(len(res1[0]["member"]) == 1)
1522 self.assertEquals(res1[0]["member"][0].lower(),
1523 ("cn=ldaptestuser,cn=users," + self.base_dn).lower())
1525 res1 = ldb.search("cn=ldaptestgroup2, cn=users," + self.base_dn,
1526 scope=SCOPE_BASE, attrs=["member"])
1527 self.assertTrue(len(res1) == 1)
1528 self.assertFalse("member" in res1[0])
1530 # Also this should be denied
1533 "dn": "cn=ldaptestuser1,cn=users," + self.base_dn,
1534 "objectclass": ["user", "person"],
1535 "primaryGroupID": "0"})
1537 except LdbError, (num, _):
1538 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1540 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1541 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1542 self.delete_force(self.ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
1544 def test_sam_attributes(self):
1545 """Test the behaviour of special attributes of SAM objects"""
1546 print "Testing the behaviour of special attributes of SAM objects\n"""
1549 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1550 "objectclass": ["user", "person"]})
1552 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
1553 "objectclass": "group"})
1556 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1557 m["groupType"] = MessageElement("0", FLAG_MOD_ADD,
1562 except LdbError, (num, _):
1563 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
1566 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1567 m["groupType"] = MessageElement([], FLAG_MOD_DELETE,
1572 except LdbError, (num, _):
1573 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1576 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1577 m["primaryGroupID"] = MessageElement("0", FLAG_MOD_ADD,
1582 except LdbError, (num, _):
1583 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
1586 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1587 m["primaryGroupID"] = MessageElement([], FLAG_MOD_DELETE,
1592 except LdbError, (num, _):
1593 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1596 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1597 m["userAccountControl"] = MessageElement("0", FLAG_MOD_ADD,
1598 "userAccountControl")
1602 except LdbError, (num, _):
1603 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
1606 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1607 m["userAccountControl"] = MessageElement([], FLAG_MOD_DELETE,
1608 "userAccountControl")
1612 except LdbError, (num, _):
1613 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1616 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1617 m["sAMAccountType"] = MessageElement("0", FLAG_MOD_ADD,
1622 except LdbError, (num, _):
1623 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1626 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1627 m["sAMAccountType"] = MessageElement([], FLAG_MOD_REPLACE,
1632 except LdbError, (num, _):
1633 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1636 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1637 m["sAMAccountType"] = MessageElement([], FLAG_MOD_DELETE,
1642 except LdbError, (num, _):
1643 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1645 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1646 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1648 def test_primary_group_token_constructed(self):
1649 """Test the primary group token behaviour (hidden-generated-readonly attribute on groups) and some other constructed attributes"""
1650 print "Testing primary group token behaviour and other constructed attributes\n"
1654 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
1655 "objectclass": "group",
1656 "primaryGroupToken": "100"})
1658 except LdbError, (num, _):
1659 self.assertEquals(num, ERR_UNDEFINED_ATTRIBUTE_TYPE)
1660 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1663 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1664 "objectclass": ["user", "person"]})
1667 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
1668 "objectclass": "group"})
1670 # Testing for one invalid, and one valid operational attribute, but also the things they are built from
1671 res1 = ldb.search(self.base_dn,
1672 scope=SCOPE_BASE, attrs=["primaryGroupToken", "canonicalName", "objectClass", "objectSid"])
1673 self.assertTrue(len(res1) == 1)
1674 self.assertFalse("primaryGroupToken" in res1[0])
1675 self.assertTrue("canonicalName" in res1[0])
1676 self.assertTrue("objectClass" in res1[0])
1677 self.assertTrue("objectSid" in res1[0])
1679 res1 = ldb.search(self.base_dn,
1680 scope=SCOPE_BASE, attrs=["primaryGroupToken", "canonicalName"])
1681 self.assertTrue(len(res1) == 1)
1682 self.assertFalse("primaryGroupToken" in res1[0])
1683 self.assertFalse("objectSid" in res1[0])
1684 self.assertFalse("objectClass" in res1[0])
1685 self.assertTrue("canonicalName" in res1[0])
1687 res1 = ldb.search("cn=users,"+self.base_dn,
1688 scope=SCOPE_BASE, attrs=["primaryGroupToken"])
1689 self.assertTrue(len(res1) == 1)
1690 self.assertFalse("primaryGroupToken" in res1[0])
1692 res1 = ldb.search("cn=ldaptestuser, cn=users," + self.base_dn,
1693 scope=SCOPE_BASE, attrs=["primaryGroupToken"])
1694 self.assertTrue(len(res1) == 1)
1695 self.assertFalse("primaryGroupToken" in res1[0])
1697 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
1699 self.assertTrue(len(res1) == 1)
1700 self.assertFalse("primaryGroupToken" in res1[0])
1702 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
1703 scope=SCOPE_BASE, attrs=["primaryGroupToken", "objectSID"])
1704 self.assertTrue(len(res1) == 1)
1705 primary_group_token = int(res1[0]["primaryGroupToken"][0])
1707 rid = security.dom_sid(ldb.schema_format_value("objectSID", res1[0]["objectSID"][0])).split()[1]
1708 self.assertEquals(primary_group_token, rid)
1711 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1712 m["primaryGroupToken"] = "100"
1716 except LdbError, (num, _):
1717 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
1719 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1720 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1722 def test_tokenGroups(self):
1723 """Test the tokenGroups behaviour (hidden-generated-readonly attribute on SAM objects)"""
1724 print "Testing tokenGroups behaviour\n"
1726 # The domain object shouldn't contain any "tokenGroups" entry
1727 res = ldb.search(self.base_dn, scope=SCOPE_BASE, attrs=["tokenGroups"])
1728 self.assertTrue(len(res) == 1)
1729 self.assertFalse("tokenGroups" in res[0])
1731 # The domain administrator should contain "tokenGroups" entries
1732 # (the exact number depends on the domain/forest function level and the
1733 # DC software versions)
1734 res = ldb.search("cn=Administrator,cn=Users," + self.base_dn,
1735 scope=SCOPE_BASE, attrs=["tokenGroups"])
1736 self.assertTrue(len(res) == 1)
1737 self.assertTrue("tokenGroups" in res[0])
1740 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1741 "objectclass": ["user", "person"]})
1743 # This testuser should contain at least two "tokenGroups" entries
1744 # (exactly two on an unmodified "Domain Users" and "Users" group)
1745 res = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
1746 scope=SCOPE_BASE, attrs=["tokenGroups"])
1747 self.assertTrue(len(res) == 1)
1748 self.assertTrue(len(res[0]["tokenGroups"]) >= 2)
1750 # one entry which we need to find should point to domains "Domain Users"
1751 # group and another entry should point to the builtin "Users"group
1752 domain_users_group_found = False
1753 users_group_found = False
1754 for sid in res[0]["tokenGroups"]:
1755 rid = security.dom_sid(ldb.schema_format_value("objectSID", sid)).split()[1]
1757 domain_users_group_found = True
1759 users_group_found = True
1761 self.assertTrue(domain_users_group_found)
1762 self.assertTrue(users_group_found)
1764 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1766 def test_wkguid(self):
1767 """Test Well known GUID behaviours (including DN+Binary)"""
1768 print "Test Well known GUID behaviours (including DN+Binary)"""
1770 res = self.ldb.search(base=("<WKGUID=ab1d30f3768811d1aded00c04fd8d5cd,%s>" % self.base_dn), scope=SCOPE_BASE, attrs=[])
1771 self.assertEquals(len(res), 1)
1773 res2 = self.ldb.search(scope=SCOPE_BASE, attrs=["wellKnownObjects"], expression=("wellKnownObjects=B:32:ab1d30f3768811d1aded00c04fd8d5cd:%s" % res[0].dn))
1774 self.assertEquals(len(res2), 1)
1776 # Prove that the matching rule is over the whole DN+Binary
1777 res2 = self.ldb.search(scope=SCOPE_BASE, attrs=["wellKnownObjects"], expression=("wellKnownObjects=B:32:ab1d30f3768811d1aded00c04fd8d5cd"))
1778 self.assertEquals(len(res2), 0)
1779 # Prove that the matching rule is over the whole DN+Binary
1780 res2 = self.ldb.search(scope=SCOPE_BASE, attrs=["wellKnownObjects"], expression=("wellKnownObjects=%s") % res[0].dn)
1781 self.assertEquals(len(res2), 0)
1783 def test_subschemasubentry(self):
1784 """Test subSchemaSubEntry appears when requested, but not when not requested"""
1785 print "Test subSchemaSubEntry"""
1787 res = self.ldb.search(base=self.base_dn, scope=SCOPE_BASE, attrs=["subSchemaSubEntry"])
1788 self.assertEquals(len(res), 1)
1789 self.assertEquals(res[0]["subSchemaSubEntry"][0], "CN=Aggregate,"+self.schema_dn)
1791 res = self.ldb.search(base=self.base_dn, scope=SCOPE_BASE, attrs=["*"])
1792 self.assertEquals(len(res), 1)
1793 self.assertTrue("subScheamSubEntry" not in res[0])
1795 def test_delete(self):
1796 """Tests the delete operation"""
1797 print "Tests the delete operations"""
1800 "dn": "cn=ldaptestcontainer," + self.base_dn,
1801 "objectclass": "container"})
1803 "dn": "cn=entry1,cn=ldaptestcontainer," + self.base_dn,
1804 "objectclass": "container"})
1806 "dn": "cn=entry2,cn=ldaptestcontainer," + self.base_dn,
1807 "objectclass": "container"})
1810 ldb.delete("cn=ldaptestcontainer," + self.base_dn)
1812 except LdbError, (num, _):
1813 self.assertEquals(num, ERR_NOT_ALLOWED_ON_NON_LEAF)
1815 ldb.delete("cn=ldaptestcontainer," + self.base_dn, ["tree_delete:0"])
1818 res = ldb.search("cn=ldaptestcontainer," + self.base_dn,
1819 scope=SCOPE_BASE, attrs=[])
1821 except LdbError, (num, _):
1822 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
1824 res = ldb.search("cn=entry1,cn=ldaptestcontainer," + self.base_dn,
1825 scope=SCOPE_BASE, attrs=[])
1827 except LdbError, (num, _):
1828 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
1830 res = ldb.search("cn=entry2,cn=ldaptestcontainer," + self.base_dn,
1831 scope=SCOPE_BASE, attrs=[])
1833 except LdbError, (num, _):
1834 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
1836 self.delete_force(self.ldb, "cn=entry1,cn=ldaptestcontainer," + self.base_dn)
1837 self.delete_force(self.ldb, "cn=entry2,cn=ldaptestcontainer," + self.base_dn)
1838 self.delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
1840 # Performs some protected object delete testing
1842 res = ldb.search(base="", expression="", scope=SCOPE_BASE,
1843 attrs=["dsServiceName", "dNSHostName"])
1844 self.assertEquals(len(res), 1)
1847 ldb.delete(res[0]["dsServiceName"][0])
1849 except LdbError, (num, _):
1850 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1852 res = ldb.search(self.base_dn, scope=SCOPE_SUBTREE,
1853 attrs=["rIDSetReferences"],
1854 expression="(&(objectClass=computer)(dNSHostName=" + res[0]["dNSHostName"][0] + "))")
1855 self.assertEquals(len(res), 1)
1858 ldb.delete(res[0]["rIDSetReferences"][0])
1860 except LdbError, (num, _):
1861 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1864 ldb.delete("cn=Enterprise Schema,cn=Partitions," + self.configuration_dn)
1866 except LdbError, (num, _):
1867 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1869 # TODO: This fails with LDB_ERR_NOT_ALLOWED_ON_NON_LEAF on Windows
1871 # ldb.delete("cn=Enterprise Configuration,cn=Partitions," + self.configuration_dn)
1873 # except LdbError, (num, _):
1874 # self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1876 # Performs some "systemFlags" testing
1878 # Delete failing since "SYSTEM_FLAG_DISALLOW_DELETE"
1880 ldb.delete("CN=Users," + self.base_dn)
1882 except LdbError, (num, _):
1883 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1888 print "Testing user add"
1891 "dn": "cn=ldaptestuser,cn=uSers," + self.base_dn,
1892 "objectclass": ["user", "person"],
1893 "cN": "LDAPtestUSER",
1894 "givenname": "ldap",
1898 "dn": "cn=ldaptestgroup,cn=uSers," + self.base_dn,
1899 "objectclass": "group",
1900 "member": "cn=ldaptestuser,cn=useRs," + self.base_dn})
1903 "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
1904 "objectclass": "computer",
1905 "cN": "LDAPtestCOMPUTER"})
1907 ldb.add({"dn": "cn=ldaptest2computer,cn=computers," + self.base_dn,
1908 "objectClass": "computer",
1909 "cn": "LDAPtest2COMPUTER",
1910 "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT),
1911 "displayname": "ldap testy"})
1914 ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn,
1915 "objectClass": "computer",
1916 "cn": "LDAPtest2COMPUTER"
1919 except LdbError, (num, _):
1920 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1923 ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn,
1924 "objectClass": "computer",
1925 "cn": "ldaptestcomputer3",
1926 "sAMAccountType": str(ATYPE_NORMAL_ACCOUNT)
1929 except LdbError, (num, _):
1930 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1932 ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn,
1933 "objectClass": "computer",
1934 "cn": "LDAPtestCOMPUTER3"
1937 print "Testing ldb.search for (&(cn=ldaptestcomputer3)(objectClass=user))";
1938 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestcomputer3)(objectClass=user))");
1939 self.assertEquals(len(res), 1, "Found only %d for (&(cn=ldaptestcomputer3)(objectClass=user))" % len(res))
1941 self.assertEquals(str(res[0].dn), ("CN=ldaptestcomputer3,CN=Computers," + self.base_dn));
1942 self.assertEquals(res[0]["cn"][0], "ldaptestcomputer3");
1943 self.assertEquals(res[0]["name"][0], "ldaptestcomputer3");
1944 self.assertEquals(res[0]["objectClass"][0], "top");
1945 self.assertEquals(res[0]["objectClass"][1], "person");
1946 self.assertEquals(res[0]["objectClass"][2], "organizationalPerson");
1947 self.assertEquals(res[0]["objectClass"][3], "user");
1948 self.assertEquals(res[0]["objectClass"][4], "computer");
1949 self.assertTrue("objectGUID" in res[0])
1950 self.assertTrue("whenCreated" in res[0])
1951 self.assertEquals(res[0]["objectCategory"][0], ("CN=Computer,CN=Schema,CN=Configuration," + self.base_dn));
1952 self.assertEquals(int(res[0]["primaryGroupID"][0]), 513);
1953 self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_NORMAL_ACCOUNT);
1954 self.assertEquals(int(res[0]["userAccountControl"][0]), UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE);
1956 self.delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
1958 print "Testing attribute or value exists behaviour"
1961 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1963 replace: servicePrincipalName
1964 servicePrincipalName: host/ldaptest2computer
1965 servicePrincipalName: host/ldaptest2computer
1966 servicePrincipalName: cifs/ldaptest2computer
1969 except LdbError, (num, msg):
1970 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
1973 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1975 replace: servicePrincipalName
1976 servicePrincipalName: host/ldaptest2computer
1977 servicePrincipalName: cifs/ldaptest2computer
1981 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1983 add: servicePrincipalName
1984 servicePrincipalName: host/ldaptest2computer
1987 except LdbError, (num, msg):
1988 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
1990 print "Testing ranged results"
1992 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1994 replace: servicePrincipalName
1998 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
2000 add: servicePrincipalName
2001 servicePrincipalName: host/ldaptest2computer0
2002 servicePrincipalName: host/ldaptest2computer1
2003 servicePrincipalName: host/ldaptest2computer2
2004 servicePrincipalName: host/ldaptest2computer3
2005 servicePrincipalName: host/ldaptest2computer4
2006 servicePrincipalName: host/ldaptest2computer5
2007 servicePrincipalName: host/ldaptest2computer6
2008 servicePrincipalName: host/ldaptest2computer7
2009 servicePrincipalName: host/ldaptest2computer8
2010 servicePrincipalName: host/ldaptest2computer9
2011 servicePrincipalName: host/ldaptest2computer10
2012 servicePrincipalName: host/ldaptest2computer11
2013 servicePrincipalName: host/ldaptest2computer12
2014 servicePrincipalName: host/ldaptest2computer13
2015 servicePrincipalName: host/ldaptest2computer14
2016 servicePrincipalName: host/ldaptest2computer15
2017 servicePrincipalName: host/ldaptest2computer16
2018 servicePrincipalName: host/ldaptest2computer17
2019 servicePrincipalName: host/ldaptest2computer18
2020 servicePrincipalName: host/ldaptest2computer19
2021 servicePrincipalName: host/ldaptest2computer20
2022 servicePrincipalName: host/ldaptest2computer21
2023 servicePrincipalName: host/ldaptest2computer22
2024 servicePrincipalName: host/ldaptest2computer23
2025 servicePrincipalName: host/ldaptest2computer24
2026 servicePrincipalName: host/ldaptest2computer25
2027 servicePrincipalName: host/ldaptest2computer26
2028 servicePrincipalName: host/ldaptest2computer27
2029 servicePrincipalName: host/ldaptest2computer28
2030 servicePrincipalName: host/ldaptest2computer29
2033 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE,
2034 attrs=["servicePrincipalName;range=0-*"])
2035 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
2036 #print len(res[0]["servicePrincipalName;range=0-*"])
2037 self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30)
2039 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-19"])
2040 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
2041 # print res[0]["servicePrincipalName;range=0-19"].length
2042 self.assertEquals(len(res[0]["servicePrincipalName;range=0-19"]), 20)
2045 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-30"])
2046 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
2047 self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30)
2049 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-40"])
2050 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
2051 self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30)
2053 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=30-40"])
2054 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
2055 self.assertEquals(len(res[0]["servicePrincipalName;range=30-*"]), 0)
2058 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=10-40"])
2059 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
2060 self.assertEquals(len(res[0]["servicePrincipalName;range=10-*"]), 20)
2061 # pos_11 = res[0]["servicePrincipalName;range=10-*"][18]
2063 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=11-40"])
2064 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
2065 self.assertEquals(len(res[0]["servicePrincipalName;range=11-*"]), 19)
2066 # print res[0]["servicePrincipalName;range=11-*"][18]
2068 # self.assertEquals((res[0]["servicePrincipalName;range=11-*"][18]), pos_11)
2070 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=11-15"])
2071 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
2072 self.assertEquals(len(res[0]["servicePrincipalName;range=11-15"]), 5)
2073 # self.assertEquals(res[0]["servicePrincipalName;range=11-15"][4], pos_11)
2075 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName"])
2076 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
2077 # print res[0]["servicePrincipalName"][18]
2079 self.assertEquals(len(res[0]["servicePrincipalName"]), 30)
2080 # self.assertEquals(res[0]["servicePrincipalName"][18], pos_11)
2082 self.delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
2084 "dn": "cn=ldaptestuser2,cn=useRs," + self.base_dn,
2085 "objectClass": ["person", "user"],
2086 "cn": "LDAPtestUSER2",
2087 "givenname": "testy",
2088 "sn": "ldap user2"})
2090 print "Testing Ambigious Name Resolution"
2091 # Testing ldb.search for (&(anr=ldap testy)(objectClass=user))
2092 res = ldb.search(expression="(&(anr=ldap testy)(objectClass=user))")
2093 self.assertEquals(len(res), 3, "Found only %d of 3 for (&(anr=ldap testy)(objectClass=user))" % len(res))
2095 # Testing ldb.search for (&(anr=testy ldap)(objectClass=user))
2096 res = ldb.search(expression="(&(anr=testy ldap)(objectClass=user))")
2097 self.assertEquals(len(res), 2, "Found only %d of 2 for (&(anr=testy ldap)(objectClass=user))" % len(res))
2099 # Testing ldb.search for (&(anr=ldap)(objectClass=user))
2100 res = ldb.search(expression="(&(anr=ldap)(objectClass=user))")
2101 self.assertEquals(len(res), 4, "Found only %d of 4 for (&(anr=ldap)(objectClass=user))" % len(res))
2103 # Testing ldb.search for (&(anr==ldap)(objectClass=user))
2104 res = ldb.search(expression="(&(anr==ldap)(objectClass=user))")
2105 self.assertEquals(len(res), 1, "Could not find (&(anr==ldap)(objectClass=user)). Found only %d for (&(anr=ldap)(objectClass=user))" % len(res))
2107 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
2108 self.assertEquals(res[0]["cn"][0], "ldaptestuser")
2109 self.assertEquals(str(res[0]["name"]), "ldaptestuser")
2111 # Testing ldb.search for (&(anr=testy)(objectClass=user))
2112 res = ldb.search(expression="(&(anr=testy)(objectClass=user))")
2113 self.assertEquals(len(res), 2, "Found only %d for (&(anr=testy)(objectClass=user))" % len(res))
2115 # Testing ldb.search for (&(anr=testy ldap)(objectClass=user))
2116 res = ldb.search(expression="(&(anr=testy ldap)(objectClass=user))")
2117 self.assertEquals(len(res), 2, "Found only %d for (&(anr=testy ldap)(objectClass=user))" % len(res))
2119 # Testing ldb.search for (&(anr==testy ldap)(objectClass=user))
2120 # this test disabled for the moment, as anr with == tests are not understood
2121 # res = ldb.search(expression="(&(anr==testy ldap)(objectClass=user))")
2122 # self.assertEquals(len(res), 1, "Found only %d for (&(anr==testy ldap)(objectClass=user))" % len(res))
2124 # self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
2125 # self.assertEquals(res[0]["cn"][0], "ldaptestuser")
2126 # self.assertEquals(res[0]["name"][0], "ldaptestuser")
2128 # Testing ldb.search for (&(anr==testy ldap)(objectClass=user))
2129 # res = ldb.search(expression="(&(anr==testy ldap)(objectClass=user))")
2130 # self.assertEquals(len(res), 1, "Could not find (&(anr==testy ldap)(objectClass=user))")
2132 # self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
2133 # self.assertEquals(res[0]["cn"][0], "ldaptestuser")
2134 # self.assertEquals(res[0]["name"][0], "ldaptestuser")
2136 # Testing ldb.search for (&(anr=testy ldap user)(objectClass=user))
2137 res = ldb.search(expression="(&(anr=testy ldap user)(objectClass=user))")
2138 self.assertEquals(len(res), 1, "Could not find (&(anr=testy ldap user)(objectClass=user))")
2140 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
2141 self.assertEquals(str(res[0]["cn"]), "ldaptestuser2")
2142 self.assertEquals(str(res[0]["name"]), "ldaptestuser2")
2144 # Testing ldb.search for (&(anr==testy ldap user2)(objectClass=user))
2145 # res = ldb.search(expression="(&(anr==testy ldap user2)(objectClass=user))")
2146 # self.assertEquals(len(res), 1, "Could not find (&(anr==testy ldap user2)(objectClass=user))")
2148 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
2149 self.assertEquals(str(res[0]["cn"]), "ldaptestuser2")
2150 self.assertEquals(str(res[0]["name"]), "ldaptestuser2")
2152 # Testing ldb.search for (&(anr==ldap user2)(objectClass=user))
2153 # res = ldb.search(expression="(&(anr==ldap user2)(objectClass=user))")
2154 # self.assertEquals(len(res), 1, "Could not find (&(anr==ldap user2)(objectClass=user))")
2156 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
2157 self.assertEquals(str(res[0]["cn"]), "ldaptestuser2")
2158 self.assertEquals(str(res[0]["name"]), "ldaptestuser2")
2160 # Testing ldb.search for (&(anr==not ldap user2)(objectClass=user))
2161 # res = ldb.search(expression="(&(anr==not ldap user2)(objectClass=user))")
2162 # self.assertEquals(len(res), 0, "Must not find (&(anr==not ldap user2)(objectClass=user))")
2164 # Testing ldb.search for (&(anr=not ldap user2)(objectClass=user))
2165 res = ldb.search(expression="(&(anr=not ldap user2)(objectClass=user))")
2166 self.assertEquals(len(res), 0, "Must not find (&(anr=not ldap user2)(objectClass=user))")
2168 # Testing ldb.search for (&(anr="testy ldap")(objectClass=user)) (ie, with quotes)
2169 # res = ldb.search(expression="(&(anr==\"testy ldap\")(objectClass=user))")
2170 # self.assertEquals(len(res), 0, "Found (&(anr==\"testy ldap\")(objectClass=user))")
2172 print "Testing Renames"
2174 attrs = ["objectGUID", "objectSid"]
2175 print "Testing ldb.search for (&(cn=ldaptestUSer2)(objectClass=user))"
2176 res_user = ldb.search(self.base_dn, expression="(&(cn=ldaptestUSer2)(objectClass=user))", scope=SCOPE_SUBTREE, attrs=attrs)
2177 self.assertEquals(len(res_user), 1, "Could not find (&(cn=ldaptestUSer2)(objectClass=user))")
2179 # Check rename works with extended/alternate DN forms
2180 ldb.rename("<SID=" + ldb.schema_format_value("objectSID", res_user[0]["objectSID"][0]) + ">" , "cn=ldaptestUSER3,cn=users," + self.base_dn)
2182 print "Testing ldb.search for (&(cn=ldaptestuser3)(objectClass=user))"
2183 res = ldb.search(expression="(&(cn=ldaptestuser3)(objectClass=user))")
2184 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser3)(objectClass=user))")
2186 self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
2187 self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3")
2188 self.assertEquals(str(res[0]["name"]), "ldaptestUSER3")
2190 #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))"
2191 res = ldb.search(expression="(&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))")
2192 self.assertEquals(len(res), 1, "(&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))")
2194 self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
2195 self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3")
2196 self.assertEquals(str(res[0]["name"]), "ldaptestUSER3")
2198 #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))"
2199 res = ldb.search(expression="(&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))")
2200 self.assertEquals(len(res), 1, "(&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))")
2202 self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
2203 self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3")
2204 self.assertEquals(str(res[0]["name"]), "ldaptestUSER3")
2206 #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))"
2207 res = ldb.search(expression="(&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))")
2208 self.assertEquals(len(res), 0, "(&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))")
2210 # This is a Samba special, and does not exist in real AD
2211 # print "Testing ldb.search for (dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")"
2212 # res = ldb.search("(dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")")
2213 # if (res.error != 0 || len(res) != 1) {
2214 # print "Could not find (dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")"
2215 # self.assertEquals(len(res), 1)
2217 # self.assertEquals(res[0].dn, ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
2218 # self.assertEquals(res[0].cn, "ldaptestUSER3")
2219 # self.assertEquals(res[0].name, "ldaptestUSER3")
2221 print "Testing ldb.search for (distinguishedName=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")"
2222 res = ldb.search(expression="(distinguishedName=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")")
2223 self.assertEquals(len(res), 1, "Could not find (dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")")
2224 self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
2225 self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3")
2226 self.assertEquals(str(res[0]["name"]), "ldaptestUSER3")
2228 # ensure we cannot add it again
2230 ldb.add({"dn": "cn=ldaptestuser3,cn=userS," + self.base_dn,
2231 "objectClass": ["person", "user"],
2232 "cn": "LDAPtestUSER3"})
2234 except LdbError, (num, _):
2235 self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
2238 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser2,cn=users," + self.base_dn)
2240 # ensure we cannot rename it twice
2242 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn,
2243 "cn=ldaptestuser2,cn=users," + self.base_dn)
2245 except LdbError, (num, _):
2246 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
2248 # ensure can now use that name
2249 ldb.add({"dn": "cn=ldaptestuser3,cn=users," + self.base_dn,
2250 "objectClass": ["person", "user"],
2251 "cn": "LDAPtestUSER3"})
2253 # ensure we now cannot rename
2255 ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=users," + self.base_dn)
2257 except LdbError, (num, _):
2258 self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
2260 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=configuration," + self.base_dn)
2262 except LdbError, (num, _):
2263 self.assertTrue(num in (71, 64))
2265 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser5,cn=users," + self.base_dn)
2267 ldb.delete("cn=ldaptestuser5,cn=users," + self.base_dn)
2269 self.delete_force(ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
2271 ldb.rename("cn=ldaptestgroup,cn=users," + self.base_dn, "cn=ldaptestgroup2,cn=users," + self.base_dn)
2273 print "Testing subtree renames"
2275 ldb.add({"dn": "cn=ldaptestcontainer," + self.base_dn,
2276 "objectClass": "container"})
2278 ldb.add({"dn": "CN=ldaptestuser4,CN=ldaptestcontainer," + self.base_dn,
2279 "objectClass": ["person", "user"],
2280 "cn": "LDAPtestUSER4"})
2283 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2286 member: cn=ldaptestuser4,cn=ldaptestcontainer,""" + self.base_dn + """
2287 member: cn=ldaptestcomputer,cn=computers,""" + self.base_dn + """
2288 member: cn=ldaptestuser2,cn=users,""" + self.base_dn + """
2291 print "Testing ldb.rename of cn=ldaptestcontainer," + self.base_dn + " to cn=ldaptestcontainer2," + self.base_dn
2292 ldb.rename("CN=ldaptestcontainer," + self.base_dn, "CN=ldaptestcontainer2," + self.base_dn)
2294 print "Testing ldb.search for (&(cn=ldaptestuser4)(objectClass=user))"
2295 res = ldb.search(expression="(&(cn=ldaptestuser4)(objectClass=user))")
2296 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser4)(objectClass=user))")
2298 print "Testing subtree ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in (just renamed from) cn=ldaptestcontainer," + self.base_dn
2300 res = ldb.search("cn=ldaptestcontainer," + self.base_dn,
2301 expression="(&(cn=ldaptestuser4)(objectClass=user))",
2302 scope=SCOPE_SUBTREE)
2304 except LdbError, (num, _):
2305 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
2307 print "Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in (just renamed from) cn=ldaptestcontainer," + self.base_dn
2309 res = ldb.search("cn=ldaptestcontainer," + self.base_dn,
2310 expression="(&(cn=ldaptestuser4)(objectClass=user))", scope=SCOPE_ONELEVEL)
2312 except LdbError, (num, _):
2313 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
2315 print "Testing ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in renamed container"
2316 res = ldb.search("cn=ldaptestcontainer2," + self.base_dn, expression="(&(cn=ldaptestuser4)(objectClass=user))", scope=SCOPE_SUBTREE)
2317 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser4)(objectClass=user)) under cn=ldaptestcontainer2," + self.base_dn)
2319 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn))
2320 self.assertEquals(res[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
2324 print "Testing ldb.search for (&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn + ")(objectclass=group)) to check subtree renames and linked attributes"
2325 res = ldb.search(self.base_dn, expression="(&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn + ")(objectclass=group))", scope=SCOPE_SUBTREE)
2326 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?")
2328 print "Testing ldb.rename (into itself) of cn=ldaptestcontainer2," + self.base_dn + " to cn=ldaptestcontainer,cn=ldaptestcontainer2," + self.base_dn
2330 ldb.rename("cn=ldaptestcontainer2," + self.base_dn, "cn=ldaptestcontainer,cn=ldaptestcontainer2," + self.base_dn)
2332 except LdbError, (num, _):
2333 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
2335 print "Testing ldb.rename (into non-existent container) of cn=ldaptestcontainer2," + self.base_dn + " to cn=ldaptestcontainer,cn=ldaptestcontainer3," + self.base_dn
2337 ldb.rename("cn=ldaptestcontainer2," + self.base_dn, "cn=ldaptestcontainer,cn=ldaptestcontainer3," + self.base_dn)
2339 except LdbError, (num, _):
2340 self.assertTrue(num in (ERR_UNWILLING_TO_PERFORM, ERR_OTHER))
2342 print "Testing delete (should fail, not a leaf node) of renamed cn=ldaptestcontainer2," + self.base_dn
2344 ldb.delete("cn=ldaptestcontainer2," + self.base_dn)
2346 except LdbError, (num, _):
2347 self.assertEquals(num, ERR_NOT_ALLOWED_ON_NON_LEAF)
2349 print "Testing base ldb.search for CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn
2350 res = ldb.search(expression="(objectclass=*)", base=("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn), scope=SCOPE_BASE)
2351 self.assertEquals(len(res), 1)
2352 res = ldb.search(expression="(cn=ldaptestuser40)", base=("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn), scope=SCOPE_BASE)
2353 self.assertEquals(len(res), 0)
2355 print "Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in cn=ldaptestcontainer2," + self.base_dn
2356 res = ldb.search(expression="(&(cn=ldaptestuser4)(objectClass=user))", base=("cn=ldaptestcontainer2," + self.base_dn), scope=SCOPE_ONELEVEL)
2357 # FIXME: self.assertEquals(len(res), 0)
2359 print "Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in cn=ldaptestcontainer2," + self.base_dn
2360 res = ldb.search(expression="(&(cn=ldaptestuser4)(objectClass=user))", base=("cn=ldaptestcontainer2," + self.base_dn), scope=SCOPE_SUBTREE)
2361 # FIXME: self.assertEquals(len(res), 0)
2363 print "Testing delete of subtree renamed "+("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn)
2364 ldb.delete(("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn))
2365 print "Testing delete of renamed cn=ldaptestcontainer2," + self.base_dn
2366 ldb.delete("cn=ldaptestcontainer2," + self.base_dn)
2368 ldb.add({"dn": "cn=ldaptestutf8user èùéìòà,cn=users," + self.base_dn, "objectClass": "user"})
2370 ldb.add({"dn": "cn=ldaptestutf8user2 èùéìòà,cn=users," + self.base_dn, "objectClass": "user"})
2372 print "Testing ldb.search for (&(cn=ldaptestuser)(objectClass=user))"
2373 res = ldb.search(expression="(&(cn=ldaptestuser)(objectClass=user))")
2374 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser)(objectClass=user))")
2376 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
2377 self.assertEquals(str(res[0]["cn"]), "ldaptestuser")
2378 self.assertEquals(str(res[0]["name"]), "ldaptestuser")
2379 self.assertEquals(set(res[0]["objectClass"]), set(["top", "person", "organizationalPerson", "user"]))
2380 self.assertTrue("objectGUID" in res[0])
2381 self.assertTrue("whenCreated" in res[0])
2382 self.assertEquals(str(res[0]["objectCategory"]), ("CN=Person,CN=Schema,CN=Configuration," + self.base_dn))
2383 self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_NORMAL_ACCOUNT)
2384 self.assertEquals(int(res[0]["userAccountControl"][0]), UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE)
2385 self.assertEquals(res[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
2386 self.assertEquals(len(res[0]["memberOf"]), 1)
2388 print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=cn=person,cn=schema,cn=configuration," + self.base_dn + "))"
2389 res2 = ldb.search(expression="(&(cn=ldaptestuser)(objectCategory=cn=person,cn=schema,cn=configuration," + self.base_dn + "))")
2390 self.assertEquals(len(res2), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=cn=person,cn=schema,cn=configuration," + self.base_dn + "))")
2392 self.assertEquals(res[0].dn, res2[0].dn)
2394 print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon))"
2395 res3 = ldb.search(expression="(&(cn=ldaptestuser)(objectCategory=PerSon))")
2396 self.assertEquals(len(res3), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=PerSon)): matched %d" % len(res3))
2398 self.assertEquals(res[0].dn, res3[0].dn)
2400 if gc_ldb is not None:
2401 print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon)) in Global Catalog"
2402 res3gc = gc_ldb.search(expression="(&(cn=ldaptestuser)(objectCategory=PerSon))")
2403 self.assertEquals(len(res3gc), 1)
2405 self.assertEquals(res[0].dn, res3gc[0].dn)
2407 print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon)) in with 'phantom root' control"
2409 if gc_ldb is not None:
2410 res3control = gc_ldb.search(self.base_dn, expression="(&(cn=ldaptestuser)(objectCategory=PerSon))", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["search_options:1:2"])
2411 self.assertEquals(len(res3control), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=PerSon)) in Global Catalog")
2413 self.assertEquals(res[0].dn, res3control[0].dn)
2415 ldb.delete(res[0].dn)
2417 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectClass=user))"
2418 res = ldb.search(expression="(&(cn=ldaptestcomputer)(objectClass=user))")
2419 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser)(objectClass=user))")
2421 self.assertEquals(str(res[0].dn), ("CN=ldaptestcomputer,CN=Computers," + self.base_dn))
2422 self.assertEquals(str(res[0]["cn"]), "ldaptestcomputer")
2423 self.assertEquals(str(res[0]["name"]), "ldaptestcomputer")
2424 self.assertEquals(set(res[0]["objectClass"]), set(["top", "person", "organizationalPerson", "user", "computer"]))
2425 self.assertTrue("objectGUID" in res[0])
2426 self.assertTrue("whenCreated" in res[0])
2427 self.assertEquals(str(res[0]["objectCategory"]), ("CN=Computer,CN=Schema,CN=Configuration," + self.base_dn))
2428 self.assertEquals(int(res[0]["primaryGroupID"][0]), 513)
2429 self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_NORMAL_ACCOUNT)
2430 self.assertEquals(int(res[0]["userAccountControl"][0]), UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE)
2431 self.assertEquals(res[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
2432 self.assertEquals(len(res[0]["memberOf"]), 1)
2434 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + "))"
2435 res2 = ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + "))")
2436 self.assertEquals(len(res2), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + "))")
2438 self.assertEquals(res[0].dn, res2[0].dn)
2440 if gc_ldb is not None:
2441 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + ")) in Global Catlog"
2442 res2gc = gc_ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + "))")
2443 self.assertEquals(len(res2gc), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + ")) in Global Catlog")
2445 self.assertEquals(res[0].dn, res2gc[0].dn)
2447 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=compuTER))"
2448 res3 = ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=compuTER))")
2449 self.assertEquals(len(res3), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=compuTER))")
2451 self.assertEquals(res[0].dn, res3[0].dn)
2453 if gc_ldb is not None:
2454 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=compuTER)) in Global Catalog"
2455 res3gc = gc_ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=compuTER))")
2456 self.assertEquals(len(res3gc), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=compuTER)) in Global Catalog")
2458 self.assertEquals(res[0].dn, res3gc[0].dn)
2460 print "Testing ldb.search for (&(cn=ldaptestcomp*r)(objectCategory=compuTER))"
2461 res4 = ldb.search(expression="(&(cn=ldaptestcomp*r)(objectCategory=compuTER))")
2462 self.assertEquals(len(res4), 1, "Could not find (&(cn=ldaptestcomp*r)(objectCategory=compuTER))")
2464 self.assertEquals(res[0].dn, res4[0].dn)
2466 print "Testing ldb.search for (&(cn=ldaptestcomput*)(objectCategory=compuTER))"
2467 res5 = ldb.search(expression="(&(cn=ldaptestcomput*)(objectCategory=compuTER))")
2468 self.assertEquals(len(res5), 1, "Could not find (&(cn=ldaptestcomput*)(objectCategory=compuTER))")
2470 self.assertEquals(res[0].dn, res5[0].dn)
2472 print "Testing ldb.search for (&(cn=*daptestcomputer)(objectCategory=compuTER))"
2473 res6 = ldb.search(expression="(&(cn=*daptestcomputer)(objectCategory=compuTER))")
2474 self.assertEquals(len(res6), 1, "Could not find (&(cn=*daptestcomputer)(objectCategory=compuTER))")
2476 self.assertEquals(res[0].dn, res6[0].dn)
2478 ldb.delete("<GUID=" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + ">")
2480 print "Testing ldb.search for (&(cn=ldaptest2computer)(objectClass=user))"
2481 res = ldb.search(expression="(&(cn=ldaptest2computer)(objectClass=user))")
2482 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptest2computer)(objectClass=user))")
2484 self.assertEquals(str(res[0].dn), "CN=ldaptest2computer,CN=Computers," + self.base_dn)
2485 self.assertEquals(str(res[0]["cn"]), "ldaptest2computer")
2486 self.assertEquals(str(res[0]["name"]), "ldaptest2computer")
2487 self.assertEquals(list(res[0]["objectClass"]), ["top", "person", "organizationalPerson", "user", "computer"])
2488 self.assertTrue("objectGUID" in res[0])
2489 self.assertTrue("whenCreated" in res[0])
2490 self.assertEquals(res[0]["objectCategory"][0], "CN=Computer,CN=Schema,CN=Configuration," + self.base_dn)
2491 self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_WORKSTATION_TRUST)
2492 self.assertEquals(int(res[0]["userAccountControl"][0]), UF_WORKSTATION_TRUST_ACCOUNT)
2494 ldb.delete("<SID=" + ldb.schema_format_value("objectSID", res[0]["objectSID"][0]) + ">")
2496 attrs = ["cn", "name", "objectClass", "objectGUID", "objectSID", "whenCreated", "nTSecurityDescriptor", "memberOf", "allowedAttributes", "allowedAttributesEffective"]
2497 print "Testing ldb.search for (&(cn=ldaptestUSer2)(objectClass=user))"
2498 res_user = ldb.search(self.base_dn, expression="(&(cn=ldaptestUSer2)(objectClass=user))", scope=SCOPE_SUBTREE, attrs=attrs)
2499 self.assertEquals(len(res_user), 1, "Could not find (&(cn=ldaptestUSer2)(objectClass=user))")
2501 self.assertEquals(str(res_user[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
2502 self.assertEquals(str(res_user[0]["cn"]), "ldaptestuser2")
2503 self.assertEquals(str(res_user[0]["name"]), "ldaptestuser2")
2504 self.assertEquals(list(res_user[0]["objectClass"]), ["top", "person", "organizationalPerson", "user"])
2505 self.assertTrue("objectSid" in res_user[0])
2506 self.assertTrue("objectGUID" in res_user[0])
2507 self.assertTrue("whenCreated" in res_user[0])
2508 self.assertTrue("nTSecurityDescriptor" in res_user[0])
2509 self.assertTrue("allowedAttributes" in res_user[0])
2510 self.assertTrue("allowedAttributesEffective" in res_user[0])
2511 self.assertEquals(res_user[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
2513 ldaptestuser2_sid = res_user[0]["objectSid"][0]
2514 ldaptestuser2_guid = res_user[0]["objectGUID"][0]
2516 attrs = ["cn", "name", "objectClass", "objectGUID", "objectSID", "whenCreated", "nTSecurityDescriptor", "member", "allowedAttributes", "allowedAttributesEffective"]
2517 print "Testing ldb.search for (&(cn=ldaptestgroup2)(objectClass=group))"
2518 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs)
2519 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))")
2521 self.assertEquals(str(res[0].dn), ("CN=ldaptestgroup2,CN=Users," + self.base_dn))
2522 self.assertEquals(str(res[0]["cn"]), "ldaptestgroup2")
2523 self.assertEquals(str(res[0]["name"]), "ldaptestgroup2")
2524 self.assertEquals(list(res[0]["objectClass"]), ["top", "group"])
2525 self.assertTrue("objectGUID" in res[0])
2526 self.assertTrue("objectSid" in res[0])
2527 self.assertTrue("whenCreated" in res[0])
2528 self.assertTrue("nTSecurityDescriptor" in res[0])
2529 self.assertTrue("allowedAttributes" in res[0])
2530 self.assertTrue("allowedAttributesEffective" in res[0])
2532 for m in res[0]["member"]:
2533 memberUP.append(m.upper())
2534 self.assertTrue(("CN=ldaptestuser2,CN=Users," + self.base_dn).upper() in memberUP)
2536 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs, controls=["extended_dn:1:1"])
2537 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))")
2539 print res[0]["member"]
2541 for m in res[0]["member"]:
2542 memberUP.append(m.upper())
2543 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()
2545 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)
2547 print "Quicktest for linked attributes"
2549 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2552 member: CN=ldaptestuser2,CN=Users,""" + self.base_dn + """
2553 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
2557 dn: <GUID=""" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + """>
2560 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
2564 dn: <SID=""" + ldb.schema_format_value("objectSid", res[0]["objectSid"][0]) + """>
2570 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2573 member: <GUID=""" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + """>
2574 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
2578 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2584 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2587 member: <SID=""" + ldb.schema_format_value("objectSid", res_user[0]["objectSid"][0]) + """>
2588 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
2592 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2595 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
2598 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs)
2599 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))")
2601 self.assertEquals(str(res[0].dn), ("CN=ldaptestgroup2,CN=Users," + self.base_dn))
2602 self.assertEquals(res[0]["member"][0], ("CN=ldaptestuser2,CN=Users," + self.base_dn))
2603 self.assertEquals(len(res[0]["member"]), 1)
2605 ldb.delete(("CN=ldaptestuser2,CN=Users," + self.base_dn))
2609 attrs = ["cn", "name", "objectClass", "objectGUID", "whenCreated", "nTSecurityDescriptor", "member"]
2610 print "Testing ldb.search for (&(cn=ldaptestgroup2)(objectClass=group)) to check linked delete"
2611 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs)
2612 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group)) to check linked delete")
2614 self.assertEquals(str(res[0].dn), ("CN=ldaptestgroup2,CN=Users," + self.base_dn))
2615 self.assertTrue("member" not in res[0])
2617 print "Testing ldb.search for (&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))"
2618 # TODO UTF8 users don't seem to work fully anymore
2619 # res = ldb.search(expression="(&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
2620 res = ldb.search(expression="(&(cn=ldaptestutf8user èùéìòà)(objectclass=user))")
2621 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
2623 self.assertEquals(str(res[0].dn), ("CN=ldaptestutf8user èùéìòà,CN=Users," + self.base_dn))
2624 self.assertEquals(str(res[0]["cn"]), "ldaptestutf8user èùéìòà")
2625 self.assertEquals(str(res[0]["name"]), "ldaptestutf8user èùéìòà")
2626 self.assertEquals(list(res[0]["objectClass"]), ["top", "person", "organizationalPerson", "user"])
2627 self.assertTrue("objectGUID" in res[0])
2628 self.assertTrue("whenCreated" in res[0])
2630 ldb.delete(res[0].dn)
2632 print "Testing ldb.search for (&(cn=ldaptestutf8user2*)(objectClass=user))"
2633 res = ldb.search(expression="(&(cn=ldaptestutf8user2*)(objectClass=user))")
2634 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestutf8user2*)(objectClass=user))")
2636 ldb.delete(res[0].dn)
2638 ldb.delete(("CN=ldaptestgroup2,CN=Users," + self.base_dn))
2640 print "Testing ldb.search for (&(cn=ldaptestutf8user2 ÈÙÉÌÒÀ)(objectClass=user))"
2641 # TODO UTF8 users don't seem to work fully anymore
2642 # res = ldb.search(expression="(&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
2643 # self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
2645 print "Testing that we can't get at the configuration DN from the main search base"
2646 res = ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
2647 self.assertEquals(len(res), 0)
2649 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"
2650 res = ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["search_options:1:2"])
2651 self.assertTrue(len(res) > 0)
2653 if gc_ldb is not None:
2654 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"
2656 res = gc_ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["search_options:1:0"])
2657 self.assertTrue(len(res) > 0)
2659 print "Testing that we do find configuration elements in the global catlog"
2660 res = gc_ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
2661 self.assertTrue(len(res) > 0)
2663 print "Testing that we do find configuration elements and user elements at the same time"
2664 res = gc_ldb.search(self.base_dn, expression="(|(objectClass=crossRef)(objectClass=person))", scope=SCOPE_SUBTREE, attrs=["cn"])
2665 self.assertTrue(len(res) > 0)
2667 print "Testing that we do find configuration elements in the global catlog, with the configuration basedn"
2668 res = gc_ldb.search(self.configuration_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
2669 self.assertTrue(len(res) > 0)
2671 print "Testing that we can get at the configuration DN on the main LDAP port"
2672 res = ldb.search(self.configuration_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
2673 self.assertTrue(len(res) > 0)
2675 print "Testing objectCategory canonacolisation"
2676 res = ldb.search(self.configuration_dn, expression="objectCategory=ntDsDSA", scope=SCOPE_SUBTREE, attrs=["cn"])
2677 self.assertTrue(len(res) > 0, "Didn't find any records with objectCategory=ntDsDSA")
2678 self.assertTrue(len(res) != 0)
2680 res = ldb.search(self.configuration_dn, expression="objectCategory=CN=ntDs-DSA," + self.schema_dn, scope=SCOPE_SUBTREE, attrs=["cn"])
2681 self.assertTrue(len(res) > 0, "Didn't find any records with objectCategory=CN=ntDs-DSA," + self.schema_dn)
2682 self.assertTrue(len(res) != 0)
2684 print "Testing objectClass attribute order on "+ self.base_dn
2685 res = ldb.search(expression="objectClass=domain", base=self.base_dn,
2686 scope=SCOPE_BASE, attrs=["objectClass"])
2687 self.assertEquals(len(res), 1)
2689 self.assertEquals(list(res[0]["objectClass"]), ["top", "domain", "domainDNS"])
2693 print "Testing ldb.search for objectCategory=person"
2694 res = ldb.search(self.base_dn, expression="objectCategory=person", scope=SCOPE_SUBTREE, attrs=["cn"])
2695 self.assertTrue(len(res) > 0)
2697 print "Testing ldb.search for objectCategory=person with domain scope control"
2698 res = ldb.search(self.base_dn, expression="objectCategory=person", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["domain_scope:1"])
2699 self.assertTrue(len(res) > 0)
2701 print "Testing ldb.search for objectCategory=user"
2702 res = ldb.search(self.base_dn, expression="objectCategory=user", scope=SCOPE_SUBTREE, attrs=["cn"])
2703 self.assertTrue(len(res) > 0)
2705 print "Testing ldb.search for objectCategory=user with domain scope control"
2706 res = ldb.search(self.base_dn, expression="objectCategory=user", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["domain_scope:1"])
2707 self.assertTrue(len(res) > 0)
2709 print "Testing ldb.search for objectCategory=group"
2710 res = ldb.search(self.base_dn, expression="objectCategory=group", scope=SCOPE_SUBTREE, attrs=["cn"])
2711 self.assertTrue(len(res) > 0)
2713 print "Testing ldb.search for objectCategory=group with domain scope control"
2714 res = ldb.search(self.base_dn, expression="objectCategory=group", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["domain_scope:1"])
2715 self.assertTrue(len(res) > 0)
2717 print "Testing creating a user with the posixAccount objectClass"
2718 self.ldb.add_ldif("""dn: cn=posixuser,CN=Users,%s
2721 objectClass: posixAccount
2723 objectClass: organizationalPerson
2729 homeDirectory: /home/posixuser
2730 loginShell: /bin/bash
2731 gecos: Posix User;;;
2732 description: A POSIX user"""% (self.base_dn))
2734 print "Testing removing the posixAccount objectClass from an existing user"
2735 self.ldb.modify_ldif("""dn: cn=posixuser,CN=Users,%s
2738 objectClass: posixAccount"""% (self.base_dn))
2740 print "Testing adding the posixAccount objectClass to an existing user"
2741 self.ldb.modify_ldif("""dn: cn=posixuser,CN=Users,%s
2744 objectClass: posixAccount"""% (self.base_dn))
2746 self.delete_force(self.ldb, "cn=posixuser,cn=users," + self.base_dn)
2747 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
2748 self.delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
2749 self.delete_force(self.ldb, "cn=ldaptestuser3,cn=users," + self.base_dn)
2750 self.delete_force(self.ldb, "cn=ldaptestuser4,cn=ldaptestcontainer," + self.base_dn)
2751 self.delete_force(self.ldb, "cn=ldaptestuser4,cn=ldaptestcontainer2," + self.base_dn)
2752 self.delete_force(self.ldb, "cn=ldaptestuser5,cn=users," + self.base_dn)
2753 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
2754 self.delete_force(self.ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
2755 self.delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2756 self.delete_force(self.ldb, "cn=ldaptest2computer,cn=computers," + self.base_dn)
2757 self.delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
2758 self.delete_force(self.ldb, "cn=ldaptestutf8user èùéìòà,cn=users," + self.base_dn)
2759 self.delete_force(self.ldb, "cn=ldaptestutf8user2 èùéìòà,cn=users," + self.base_dn)
2760 self.delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
2761 self.delete_force(self.ldb, "cn=ldaptestcontainer2," + self.base_dn)
2763 def test_security_descriptor_add(self):
2764 """ Testing ldb.add_ldif() for nTSecurityDescriptor """
2765 user_name = "testdescriptoruser1"
2766 user_dn = "CN=%s,CN=Users,%s" % (user_name, self.base_dn)
2768 # Test add_ldif() with SDDL security descriptor input
2770 self.delete_force(self.ldb, user_dn)
2772 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2773 self.ldb.add_ldif("""
2774 dn: """ + user_dn + """
2776 sAMAccountName: """ + user_name + """
2777 nTSecurityDescriptor: """ + sddl)
2778 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2779 desc = res[0]["nTSecurityDescriptor"][0]
2780 desc = ndr_unpack( security.descriptor, desc )
2781 desc_sddl = desc.as_sddl( self.domain_sid )
2782 self.assertEqual(desc_sddl, sddl)
2784 self.delete_force(self.ldb, user_dn)
2786 # Test add_ldif() with BASE64 security descriptor
2789 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2790 desc = security.descriptor.from_sddl(sddl, self.domain_sid)
2791 desc_binary = ndr_pack(desc)
2792 desc_base64 = base64.b64encode(desc_binary)
2793 self.ldb.add_ldif("""
2794 dn: """ + user_dn + """
2796 sAMAccountName: """ + user_name + """
2797 nTSecurityDescriptor:: """ + desc_base64)
2798 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2799 desc = res[0]["nTSecurityDescriptor"][0]
2800 desc = ndr_unpack(security.descriptor, desc)
2801 desc_sddl = desc.as_sddl(self.domain_sid)
2802 self.assertEqual(desc_sddl, sddl)
2804 self.delete_force(self.ldb, user_dn)
2806 def test_security_descriptor_add_neg(self):
2807 """Test add_ldif() with BASE64 security descriptor input using WRONG domain SID
2810 user_name = "testdescriptoruser1"
2811 user_dn = "CN=%s,CN=Users,%s" % (user_name, self.base_dn)
2812 self.delete_force(self.ldb, user_dn)
2814 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2815 desc = security.descriptor.from_sddl(sddl, security.dom_sid('S-1-5-21'))
2816 desc_base64 = base64.b64encode( ndr_pack(desc) )
2817 self.ldb.add_ldif("""
2818 dn: """ + user_dn + """
2820 sAMAccountName: """ + user_name + """
2821 nTSecurityDescriptor:: """ + desc_base64)
2822 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2823 self.assertTrue("nTSecurityDescriptor" in res[0])
2825 self.delete_force(self.ldb, user_dn)
2827 def test_security_descriptor_modify(self):
2828 """ Testing ldb.modify_ldif() for nTSecurityDescriptor """
2829 user_name = "testdescriptoruser2"
2830 user_dn = "CN=%s,CN=Users,%s" % (user_name, self.base_dn)
2832 # Delete user object and test modify_ldif() with SDDL security descriptor input
2833 # Add ACE to the original descriptor test
2836 self.delete_force(self.ldb, user_dn)
2837 self.ldb.add_ldif("""
2838 dn: """ + user_dn + """
2840 sAMAccountName: """ + user_name)
2842 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2843 desc = res[0]["nTSecurityDescriptor"][0]
2844 desc = ndr_unpack(security.descriptor, desc)
2845 desc_sddl = desc.as_sddl(self.domain_sid)
2846 sddl = desc_sddl[:desc_sddl.find("(")] + "(A;;RPWP;;;AU)" + desc_sddl[desc_sddl.find("("):]
2848 dn: """ + user_dn + """
2850 replace: nTSecurityDescriptor
2851 nTSecurityDescriptor: """ + sddl
2852 self.ldb.modify_ldif(mod)
2853 # Read modified descriptor
2854 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2855 desc = res[0]["nTSecurityDescriptor"][0]
2856 desc = ndr_unpack(security.descriptor, desc)
2857 desc_sddl = desc.as_sddl(self.domain_sid)
2858 self.assertEqual(desc_sddl, sddl)
2860 self.delete_force(self.ldb, user_dn)
2862 # Test modify_ldif() with SDDL security descriptor input
2863 # New desctiptor test
2866 self.ldb.add_ldif("""
2867 dn: """ + user_dn + """
2869 sAMAccountName: """ + user_name)
2871 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2873 dn: """ + user_dn + """
2875 replace: nTSecurityDescriptor
2876 nTSecurityDescriptor: """ + sddl
2877 self.ldb.modify_ldif(mod)
2878 # Read modified descriptor
2879 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2880 desc = res[0]["nTSecurityDescriptor"][0]
2881 desc = ndr_unpack(security.descriptor, desc)
2882 desc_sddl = desc.as_sddl(self.domain_sid)
2883 self.assertEqual(desc_sddl, sddl)
2885 self.delete_force(self.ldb, user_dn)
2887 # Test modify_ldif() with BASE64 security descriptor input
2888 # Add ACE to the original descriptor test
2891 self.ldb.add_ldif("""
2892 dn: """ + user_dn + """
2894 sAMAccountName: """ + user_name)
2896 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2897 desc = res[0]["nTSecurityDescriptor"][0]
2898 desc = ndr_unpack(security.descriptor, desc)
2899 desc_sddl = desc.as_sddl(self.domain_sid)
2900 sddl = desc_sddl[:desc_sddl.find("(")] + "(A;;RPWP;;;AU)" + desc_sddl[desc_sddl.find("("):]
2901 desc = security.descriptor.from_sddl(sddl, self.domain_sid)
2902 desc_base64 = base64.b64encode(ndr_pack(desc))
2904 dn: """ + user_dn + """
2906 replace: nTSecurityDescriptor
2907 nTSecurityDescriptor:: """ + desc_base64
2908 self.ldb.modify_ldif(mod)
2909 # Read modified descriptor
2910 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2911 desc = res[0]["nTSecurityDescriptor"][0]
2912 desc = ndr_unpack(security.descriptor, desc)
2913 desc_sddl = desc.as_sddl(self.domain_sid)
2914 self.assertEqual(desc_sddl, sddl)
2916 self.delete_force(self.ldb, user_dn)
2918 # Test modify_ldif() with BASE64 security descriptor input
2919 # New descriptor test
2922 self.delete_force(self.ldb, user_dn)
2923 self.ldb.add_ldif("""
2924 dn: """ + user_dn + """
2926 sAMAccountName: """ + user_name)
2928 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2929 desc = security.descriptor.from_sddl(sddl, self.domain_sid)
2930 desc_base64 = base64.b64encode(ndr_pack(desc))
2932 dn: """ + user_dn + """
2934 replace: nTSecurityDescriptor
2935 nTSecurityDescriptor:: """ + desc_base64
2936 self.ldb.modify_ldif(mod)
2937 # Read modified descriptor
2938 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2939 desc = res[0]["nTSecurityDescriptor"][0]
2940 desc = ndr_unpack(security.descriptor, desc)
2941 desc_sddl = desc.as_sddl(self.domain_sid)
2942 self.assertEqual(desc_sddl, sddl)
2944 self.delete_force(self.ldb, user_dn)
2947 class BaseDnTests(unittest.TestCase):
2950 super(BaseDnTests, self).setUp()
2953 def test_rootdse_attrs(self):
2954 """Testing for all rootDSE attributes"""
2955 res = self.ldb.search(scope=SCOPE_BASE, attrs=[])
2956 self.assertEquals(len(res), 1)
2958 def test_highestcommittedusn(self):
2959 """Testing for highestCommittedUSN"""
2960 res = self.ldb.search("", scope=SCOPE_BASE, attrs=["highestCommittedUSN"])
2961 self.assertEquals(len(res), 1)
2962 self.assertTrue(int(res[0]["highestCommittedUSN"][0]) != 0)
2964 def test_netlogon(self):
2965 """Testing for netlogon via LDAP"""
2966 res = self.ldb.search("", scope=SCOPE_BASE, attrs=["netlogon"])
2967 self.assertEquals(len(res), 0)
2969 def test_netlogon_highestcommitted_usn(self):
2970 """Testing for netlogon and highestCommittedUSN via LDAP"""
2971 res = self.ldb.search("", scope=SCOPE_BASE,
2972 attrs=["netlogon", "highestCommittedUSN"])
2973 self.assertEquals(len(res), 0)
2975 def test_namingContexts(self):
2976 """Testing for namingContexts in rootDSE"""
2977 res = self.ldb.search("", scope=SCOPE_BASE,
2978 attrs=["namingContexts", "defaultNamingContext", "schemaNamingContext", "configurationNamingContext"])
2979 self.assertEquals(len(res), 1)
2982 for nc in res[0]["namingContexts"]:
2983 self.assertTrue(nc not in ncs)
2986 self.assertTrue(res[0]["defaultNamingContext"][0] in ncs)
2987 self.assertTrue(res[0]["configurationNamingContext"][0] in ncs)
2988 self.assertTrue(res[0]["schemaNamingContext"][0] in ncs)
2990 def test_serverPath(self):
2991 """Testing the server paths in rootDSE"""
2992 res = self.ldb.search("", scope=SCOPE_BASE,
2993 attrs=["dsServiceName", "serverName"])
2994 self.assertEquals(len(res), 1)
2996 self.assertTrue("CN=Servers" in res[0]["dsServiceName"][0])
2997 self.assertTrue("CN=Sites" in res[0]["dsServiceName"][0])
2998 self.assertTrue("CN=NTDS Settings" in res[0]["dsServiceName"][0])
2999 self.assertTrue("CN=Servers" in res[0]["serverName"][0])
3000 self.assertTrue("CN=Sites" in res[0]["serverName"][0])
3001 self.assertFalse("CN=NTDS Settings" in res[0]["serverName"][0])
3003 def test_dnsHostname(self):
3004 """Testing the DNS hostname in rootDSE"""
3005 res = self.ldb.search("", scope=SCOPE_BASE,
3006 attrs=["dnsHostName", "serverName"])
3007 self.assertEquals(len(res), 1)
3009 res2 = self.ldb.search(res[0]["serverName"][0], scope=SCOPE_BASE,
3010 attrs=["dNSHostName"])
3011 self.assertEquals(len(res2), 1)
3013 self.assertEquals(res[0]["dnsHostName"][0], res2[0]["dNSHostName"][0])
3015 def test_ldapServiceName(self):
3016 """Testing the ldap service name in rootDSE"""
3017 res = self.ldb.search("", scope=SCOPE_BASE,
3018 attrs=["ldapServiceName", "dNSHostName"])
3019 self.assertEquals(len(res), 1)
3021 (hostname, _, dns_domainname) = res[0]["dNSHostName"][0].partition(".")
3022 self.assertTrue(":%s$@%s" % (hostname, dns_domainname.upper())
3023 in res[0]["ldapServiceName"][0])
3025 if not "://" in host:
3026 if os.path.isfile(host):
3027 host = "tdb://%s" % host
3029 host = "ldap://%s" % host
3031 ldb = Ldb(host, credentials=creds, session_info=system_session(), lp=lp)
3032 if not "tdb://" in host:
3033 gc_ldb = Ldb("%s:3268" % host, credentials=creds,
3034 session_info=system_session(), lp=lp)
3038 runner = SubunitTestRunner()
3040 if not runner.run(unittest.makeSuite(BaseDnTests)).wasSuccessful():
3042 if not runner.run(unittest.makeSuite(BasicTests)).wasSuccessful():