2 # -*- coding: utf-8 -*-
3 # This is a port of the original in testprogs/ejs/ldap.js
11 sys.path.insert(0, "bin/python")
13 samba.ensure_external_module("testtools", "testtools")
14 samba.ensure_external_module("subunit", "subunit/python")
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, ERR_INVALID_ATTRIBUTE_SYNTAX
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 Message, MessageElement, Dn
27 from ldb import FLAG_MOD_ADD, FLAG_MOD_REPLACE, FLAG_MOD_DELETE
28 from ldb import timestring
30 from samba.samdb import SamDB
31 from samba.dsdb import (UF_NORMAL_ACCOUNT,
32 UF_WORKSTATION_TRUST_ACCOUNT,
33 UF_PASSWD_NOTREQD, UF_ACCOUNTDISABLE, ATYPE_NORMAL_ACCOUNT,
34 ATYPE_WORKSTATION_TRUST, SYSTEM_FLAG_DOMAIN_DISALLOW_MOVE,
35 SYSTEM_FLAG_CONFIG_ALLOW_RENAME, SYSTEM_FLAG_CONFIG_ALLOW_MOVE,
36 SYSTEM_FLAG_CONFIG_ALLOW_LIMITED_MOVE)
38 from subunit.run import SubunitTestRunner
41 from samba.ndr import ndr_pack, ndr_unpack
42 from samba.dcerpc import security, lsa
43 from samba.tests import delete_force
45 parser = optparse.OptionParser("ldap.py [options] <host>")
46 sambaopts = options.SambaOptions(parser)
47 parser.add_option_group(sambaopts)
48 parser.add_option_group(options.VersionOptions(parser))
49 # use command line creds if available
50 credopts = options.CredentialsOptions(parser)
51 parser.add_option_group(credopts)
52 opts, args = parser.parse_args()
60 lp = sambaopts.get_loadparm()
61 creds = credopts.get_credentials(lp)
63 class BasicTests(samba.tests.TestCase):
66 super(BasicTests, self).setUp()
69 self.base_dn = ldb.domain_dn()
70 self.configuration_dn = ldb.get_config_basedn().get_linearized()
71 self.schema_dn = ldb.get_schema_basedn().get_linearized()
72 self.domain_sid = security.dom_sid(ldb.get_domain_sid())
74 print "baseDN: %s\n" % self.base_dn
76 delete_force(self.ldb, "cn=posixuser,cn=users," + self.base_dn)
77 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
78 delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
79 delete_force(self.ldb, "cn=ldaptestuser3,cn=users," + self.base_dn)
80 delete_force(self.ldb, "cn=ldaptestuser4,cn=ldaptestcontainer," + self.base_dn)
81 delete_force(self.ldb, "cn=ldaptestuser4,cn=ldaptestcontainer2," + self.base_dn)
82 delete_force(self.ldb, "cn=ldaptestuser5,cn=users," + self.base_dn)
83 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
84 delete_force(self.ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
85 delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
86 delete_force(self.ldb, "cn=ldaptest2computer,cn=computers," + self.base_dn)
87 delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
88 delete_force(self.ldb, "cn=ldaptestutf8user èùéìòà,cn=users," + self.base_dn)
89 delete_force(self.ldb, "cn=ldaptestutf8user2 èùéìòà,cn=users," + self.base_dn)
90 delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
91 delete_force(self.ldb, "cn=ldaptestcontainer2," + self.base_dn)
92 delete_force(self.ldb, "cn=parentguidtest,cn=users," + self.base_dn)
93 delete_force(self.ldb, "cn=parentguidtest,cn=testotherusers," + self.base_dn)
94 delete_force(self.ldb, "cn=testotherusers," + self.base_dn)
95 delete_force(self.ldb, "cn=ldaptestobject," + self.base_dn)
96 delete_force(self.ldb, "description=xyz,cn=users," + self.base_dn)
97 delete_force(self.ldb, "ou=testou,cn=users," + self.base_dn)
98 delete_force(self.ldb, "cn=Test Secret,cn=system," + self.base_dn)
100 def test_objectclasses(self):
101 """Test objectClass behaviour"""
102 print "Test objectClass behaviour"""
104 # Invalid objectclass specified
107 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
110 except LdbError, (num, _):
111 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
113 # Invalid objectclass specified
116 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
117 "objectClass": "X" })
119 except LdbError, (num, _):
120 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
122 # Invalid objectCategory specified
125 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
126 "objectClass": "person",
127 "objectCategory": self.base_dn })
129 except LdbError, (num, _):
130 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
132 # Multi-valued "systemFlags"
135 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
136 "objectClass": "person",
137 "systemFlags": ["0", str(SYSTEM_FLAG_DOMAIN_DISALLOW_MOVE)] })
139 except LdbError, (num, _):
140 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
142 # We cannot instanciate from an abstract object class ("connectionPoint"
143 # or "leaf"). In the first case we use "connectionPoint" (subclass of
144 # "leaf") to prevent a naming violation - this returns us a
145 # "ERR_UNWILLING_TO_PERFORM" since it is not structural. In the second
146 # case however we get "ERR_OBJECT_CLASS_VIOLATION" since an abstract
147 # class is also not allowed to be auxiliary.
150 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
151 "objectClass": "connectionPoint" })
153 except LdbError, (num, _):
154 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
157 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
158 "objectClass": ["person", "leaf"] })
160 except LdbError, (num, _):
161 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
163 # Objects instanciated using "satisfied" abstract classes (concrete
164 # subclasses) are allowed
166 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
167 "objectClass": ["top", "leaf", "connectionPoint", "serviceConnectionPoint"] })
169 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
171 # Two disjoint top-most structural object classes aren't allowed
174 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
175 "objectClass": ["person", "container"] })
177 except LdbError, (num, _):
178 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
180 # Test allowed system flags
182 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
183 "objectClass": "person",
184 "systemFlags": str(~(SYSTEM_FLAG_CONFIG_ALLOW_RENAME | SYSTEM_FLAG_CONFIG_ALLOW_MOVE | SYSTEM_FLAG_CONFIG_ALLOW_LIMITED_MOVE)) })
186 res = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
187 scope=SCOPE_BASE, attrs=["systemFlags"])
188 self.assertTrue(len(res) == 1)
189 self.assertEquals(res[0]["systemFlags"][0], "0")
191 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
194 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
195 "objectClass": "person" })
197 # We can remove derivation classes of the structural objectclass
198 # but they're going to be readded afterwards
200 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
201 m["objectClass"] = MessageElement("top", FLAG_MOD_DELETE,
205 res = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
206 scope=SCOPE_BASE, attrs=["objectClass"])
207 self.assertTrue(len(res) == 1)
208 self.assertTrue("top" in res[0]["objectClass"])
210 # The top-most structural class cannot be deleted since there are
211 # attributes of it in use
213 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
214 m["objectClass"] = MessageElement("person", FLAG_MOD_DELETE,
219 except LdbError, (num, _):
220 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
222 # We cannot delete classes which weren't specified
224 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
225 m["objectClass"] = MessageElement("computer", FLAG_MOD_DELETE,
230 except LdbError, (num, _):
231 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
233 # An invalid class cannot be added
235 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
236 m["objectClass"] = MessageElement("X", FLAG_MOD_ADD,
241 except LdbError, (num, _):
242 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
244 # We cannot add a the new top-most structural class "user" here since
245 # we are missing at least one new mandatory attribute (in this case
248 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
249 m["objectClass"] = MessageElement("user", FLAG_MOD_ADD,
254 except LdbError, (num, _):
255 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
257 # An already specified objectclass cannot be added another time
259 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
260 m["objectClass"] = MessageElement("person", FLAG_MOD_ADD,
265 except LdbError, (num, _):
266 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
268 # Auxiliary classes can always be added
270 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
271 m["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_ADD,
275 # This does not work since object class "leaf" is not auxiliary nor it
276 # stands in direct relation to "person" (and it is abstract too!)
278 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
279 m["objectClass"] = MessageElement("leaf", FLAG_MOD_ADD,
284 except LdbError, (num, _):
285 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
287 # Objectclass replace operations can be performed as well
289 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
290 m["objectClass"] = MessageElement(["top", "person", "bootableDevice"],
291 FLAG_MOD_REPLACE, "objectClass")
295 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
296 m["objectClass"] = MessageElement(["person", "bootableDevice"],
297 FLAG_MOD_REPLACE, "objectClass")
300 # This does not work since object class "leaf" is not auxiliary nor it
301 # stands in direct relation to "person" (and it is abstract too!)
303 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
304 m["objectClass"] = MessageElement(["top", "person", "bootableDevice",
305 "leaf"], FLAG_MOD_REPLACE, "objectClass")
309 except LdbError, (num, _):
310 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
312 # More than one change operation is allowed
314 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
315 m.add(MessageElement("bootableDevice", FLAG_MOD_DELETE, "objectClass"))
316 m.add(MessageElement("bootableDevice", FLAG_MOD_ADD, "objectClass"))
319 # We cannot remove all object classes by an empty replace
321 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
322 m["objectClass"] = MessageElement([], FLAG_MOD_REPLACE, "objectClass")
326 except LdbError, (num, _):
327 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
330 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
331 m["objectClass"] = MessageElement(["top", "computer"], FLAG_MOD_REPLACE,
336 except LdbError, (num, _):
337 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
339 # Classes can be removed unless attributes of them are used.
341 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
342 m["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_DELETE,
346 res = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
347 scope=SCOPE_BASE, attrs=["objectClass"])
348 self.assertTrue(len(res) == 1)
349 self.assertFalse("bootableDevice" in res[0]["objectClass"])
352 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
353 m["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_ADD,
357 # Add an attribute specific to the "bootableDevice" class
359 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
360 m["bootParameter"] = MessageElement("test", FLAG_MOD_ADD,
364 # Classes can be removed unless attributes of them are used. Now there
365 # exist such attributes on the entry.
367 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
368 m["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_DELETE,
373 except LdbError, (num, _):
374 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
376 # Remove the previously specified attribute
378 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
379 m["bootParameter"] = MessageElement("test", FLAG_MOD_DELETE,
383 # Classes can be removed unless attributes of them are used.
385 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
386 m["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_DELETE,
390 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
393 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
394 "objectClass": "user" })
396 # Add a new top-most structural class "container". This does not work
397 # since it stands in no direct relation to the current one.
399 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
400 m["objectClass"] = MessageElement("container", FLAG_MOD_ADD,
405 except LdbError, (num, _):
406 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
408 # Add a new top-most structural class "inetOrgPerson" and remove it
411 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
412 m["objectClass"] = MessageElement("inetOrgPerson", FLAG_MOD_ADD,
417 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
418 m["objectClass"] = MessageElement("inetOrgPerson", FLAG_MOD_DELETE,
422 # Replace top-most structural class to "inetOrgPerson" and reset it
425 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
426 m["objectClass"] = MessageElement("inetOrgPerson", FLAG_MOD_REPLACE,
431 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
432 m["objectClass"] = MessageElement("user", FLAG_MOD_REPLACE,
436 # Add a new auxiliary object class "posixAccount" to "ldaptestuser"
438 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
439 m["objectClass"] = MessageElement("posixAccount", FLAG_MOD_ADD,
443 # Be sure that "top" is the first and the (most) structural object class
444 # the last value of the "objectClass" attribute - MS-ADTS 3.1.1.1.4
445 res = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
446 scope=SCOPE_BASE, attrs=["objectClass"])
447 self.assertTrue(len(res) == 1)
448 self.assertEquals(res[0]["objectClass"][0], "top")
449 self.assertEquals(res[0]["objectClass"][len(res[0]["objectClass"])-1], "user")
451 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
453 def test_system_only(self):
454 """Test systemOnly objects"""
455 print "Test systemOnly objects"""
459 "dn": "cn=ldaptestobject," + self.base_dn,
460 "objectclass": "configuration"})
462 except LdbError, (num, _):
463 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
467 "dn": "cn=Test Secret,cn=system," + self.base_dn,
468 "objectclass": "secret"})
470 except LdbError, (num, _):
471 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
473 delete_force(self.ldb, "cn=ldaptestobject," + self.base_dn)
474 delete_force(self.ldb, "cn=Test Secret,cn=system," + self.base_dn)
476 # Create secret over LSA and try to change it
478 lsa_conn = lsa.lsarpc("ncacn_np:%s" % args[0], lp, creds)
479 lsa_handle = lsa_conn.OpenPolicy2(system_name="\\",
480 attr=lsa.ObjectAttribute(),
481 access_mask=security.SEC_FLAG_MAXIMUM_ALLOWED)
482 secret_name = lsa.String()
483 secret_name.string = "G$Test"
484 sec_handle = lsa_conn.CreateSecret(handle=lsa_handle,
486 access_mask=security.SEC_FLAG_MAXIMUM_ALLOWED)
487 lsa_conn.Close(lsa_handle)
490 m.dn = Dn(ldb, "cn=Test Secret,cn=system," + self.base_dn)
491 m["description"] = MessageElement("desc", FLAG_MOD_REPLACE,
496 except LdbError, (num, _):
497 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
499 delete_force(self.ldb, "cn=Test Secret,cn=system," + self.base_dn)
503 "dn": "cn=ldaptestcontainer," + self.base_dn,
504 "objectclass": "container",
505 "isCriticalSystemObject": "TRUE"})
507 except LdbError, (num, _):
508 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
511 "dn": "cn=ldaptestcontainer," + self.base_dn,
512 "objectclass": "container"})
515 m.dn = Dn(ldb, "cn=ldaptestcontainer," + self.base_dn)
516 m["isCriticalSystemObject"] = MessageElement("TRUE", FLAG_MOD_REPLACE,
517 "isCriticalSystemObject")
521 except LdbError, (num, _):
522 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
524 delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
526 # Proof if DC SAM object has "isCriticalSystemObject" set
527 res = self.ldb.search("", scope=SCOPE_BASE, attrs=["serverName"])
528 self.assertTrue(len(res) == 1)
529 self.assertTrue("serverName" in res[0])
530 res = self.ldb.search(res[0]["serverName"][0], scope=SCOPE_BASE,
531 attrs=["serverReference"])
532 self.assertTrue(len(res) == 1)
533 self.assertTrue("serverReference" in res[0])
534 res = self.ldb.search(res[0]["serverReference"][0], scope=SCOPE_BASE,
535 attrs=["isCriticalSystemObject"])
536 self.assertTrue(len(res) == 1)
537 self.assertTrue("isCriticalSystemObject" in res[0])
538 self.assertEquals(res[0]["isCriticalSystemObject"][0], "TRUE")
540 def test_invalid_parent(self):
541 """Test adding an object with invalid parent"""
542 print "Test adding an object with invalid parent"""
546 "dn": "cn=ldaptestgroup,cn=thisdoesnotexist123,"
548 "objectclass": "group"})
550 except LdbError, (num, _):
551 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
553 delete_force(self.ldb, "cn=ldaptestgroup,cn=thisdoesnotexist123,"
558 "dn": "ou=testou,cn=users," + self.base_dn,
559 "objectclass": "organizationalUnit"})
561 except LdbError, (num, _):
562 self.assertEquals(num, ERR_NAMING_VIOLATION)
564 delete_force(self.ldb, "ou=testou,cn=users," + self.base_dn)
566 def test_invalid_attribute(self):
567 """Test invalid attributes on schema/objectclasses"""
568 print "Test invalid attributes on schema/objectclasses"""
570 # attributes not in schema test
576 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
577 "objectclass": "group",
578 "thisdoesnotexist": "x"})
580 except LdbError, (num, _):
581 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
584 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
585 "objectclass": "group"})
590 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
591 m["thisdoesnotexist"] = MessageElement("x", FLAG_MOD_REPLACE,
596 except LdbError, (num, _):
597 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
599 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
601 # attributes not in objectclasses and mandatory attributes missing test
602 # Use here a non-SAM entry since it doesn't have special triggers
603 # associated which have an impact on the error results.
607 # mandatory attribute missing
610 "dn": "cn=ldaptestobject," + self.base_dn,
611 "objectclass": "ipProtocol"})
613 except LdbError, (num, _):
614 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
616 # inadequate but schema-valid attribute specified
619 "dn": "cn=ldaptestobject," + self.base_dn,
620 "objectclass": "ipProtocol",
621 "ipProtocolNumber": "1",
624 except LdbError, (num, _):
625 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
628 "dn": "cn=ldaptestobject," + self.base_dn,
629 "objectclass": "ipProtocol",
630 "ipProtocolNumber": "1"})
634 # inadequate but schema-valid attribute add trial
636 m.dn = Dn(ldb, "cn=ldaptestobject," + self.base_dn)
637 m["uid"] = MessageElement("0", FLAG_MOD_ADD, "uid")
641 except LdbError, (num, _):
642 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
644 # mandatory attribute delete trial
646 m.dn = Dn(ldb, "cn=ldaptestobject," + self.base_dn)
647 m["ipProtocolNumber"] = MessageElement([], FLAG_MOD_DELETE,
652 except LdbError, (num, _):
653 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
655 # mandatory attribute delete trial
657 m.dn = Dn(ldb, "cn=ldaptestobject," + self.base_dn)
658 m["ipProtocolNumber"] = MessageElement([], FLAG_MOD_REPLACE,
663 except LdbError, (num, _):
664 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
666 delete_force(self.ldb, "cn=ldaptestobject," + self.base_dn)
668 def test_single_valued_attributes(self):
669 """Test single-valued attributes"""
670 print "Test single-valued attributes"""
674 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
675 "objectclass": "group",
676 "sAMAccountName": ["nam1", "nam2"]})
678 except LdbError, (num, _):
679 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
682 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
683 "objectclass": "group"})
686 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
687 m["sAMAccountName"] = MessageElement(["nam1","nam2"], FLAG_MOD_REPLACE,
692 except LdbError, (num, _):
693 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
696 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
697 m["sAMAccountName"] = MessageElement("testgroupXX", FLAG_MOD_REPLACE,
702 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
703 m["sAMAccountName"] = MessageElement("testgroupXX2", FLAG_MOD_ADD,
708 except LdbError, (num, _):
709 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
711 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
713 def test_attribute_ranges(self):
714 """Test attribute ranges"""
715 print "Test attribute ranges"
720 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
721 "objectClass": "person",
724 except LdbError, (num, _):
725 self.assertEquals(num, ERR_INVALID_ATTRIBUTE_SYNTAX)
730 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
731 "objectClass": "person",
732 "sn": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" })
734 except LdbError, (num, _):
735 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
737 # "appliesTo is defined with rangeLower: 36 and rangeUpper: 36
738 # and it's not allowed on objectClass: person
741 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
742 "objectClass": "person",
745 except LdbError, (num, _):
746 self.assertEquals(num, ERR_INVALID_ATTRIBUTE_SYNTAX)
750 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
751 "objectClass": "person",
754 except LdbError, (num, _):
755 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
759 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
760 "objectClass": "person",
761 "appliesTo": "01234567890123456789012345678901345" })
763 except LdbError, (num, _):
764 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
768 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
769 "objectClass": "person",
770 "appliesTo": "012345678901234567890123456789013456" })
772 except LdbError, (num, _):
773 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
777 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
778 "objectClass": "person",
779 "appliesTo": "0123456789012345678901234567890134567" })
781 except LdbError, (num, _):
782 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
785 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
786 "objectClass": "person" })
790 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
791 m["sn"] = MessageElement("", FLAG_MOD_REPLACE, "sn")
795 except LdbError, (num, _):
796 self.assertEquals(num, ERR_INVALID_ATTRIBUTE_SYNTAX)
800 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
801 m["sn"] = MessageElement("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", FLAG_MOD_REPLACE, "sn")
805 except LdbError, (num, _):
806 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
809 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
810 m["appliesTo"] = MessageElement("",
811 FLAG_MOD_ADD, "appliesTo")
815 except LdbError, (num, _):
816 self.assertEquals(num, ERR_INVALID_ATTRIBUTE_SYNTAX)
819 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
820 m["appliesTo"] = MessageElement("",
821 FLAG_MOD_REPLACE, "appliesTo")
825 except LdbError, (num, _):
826 self.assertEquals(num, ERR_INVALID_ATTRIBUTE_SYNTAX)
829 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
830 m["appliesTo"] = MessageElement("",
831 FLAG_MOD_ADD, "appliesTo")
835 except LdbError, (num, _):
836 self.assertEquals(num, ERR_INVALID_ATTRIBUTE_SYNTAX)
839 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
840 m["appliesTo"] = MessageElement("a",
841 FLAG_MOD_REPLACE, "appliesTo")
845 except LdbError, (num, _):
846 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
849 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
850 m["appliesTo"] = MessageElement("01234567890123456789012345678901345",
851 FLAG_MOD_ADD, "appliesTo")
855 except LdbError, (num, _):
856 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
859 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
860 m["appliesTo"] = MessageElement("01234567890123456789012345678901345",
861 FLAG_MOD_REPLACE, "appliesTo")
865 except LdbError, (num, _):
866 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
869 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
870 m["appliesTo"] = MessageElement("012345678901234567890123456789013456",
871 FLAG_MOD_ADD, "appliesTo")
875 except LdbError, (num, _):
876 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
879 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
880 m["appliesTo"] = MessageElement("012345678901234567890123456789013456",
881 FLAG_MOD_REPLACE, "appliesTo")
885 except LdbError, (num, _):
886 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
889 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
890 m["appliesTo"] = MessageElement("0123456789012345678901234567890134567",
891 FLAG_MOD_ADD, "appliesTo")
895 except LdbError, (num, _):
896 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
899 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
900 m["appliesTo"] = MessageElement("0123456789012345678901234567890134567",
901 FLAG_MOD_REPLACE, "appliesTo")
905 except LdbError, (num, _):
906 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
909 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
910 m["sn"] = MessageElement("x", FLAG_MOD_REPLACE, "sn")
913 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
915 def test_empty_messages(self):
916 """Test empty messages"""
917 print "Test empty messages"""
920 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
925 except LdbError, (num, _):
926 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
931 except LdbError, (num, _):
932 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
934 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
936 def test_empty_attributes(self):
937 """Test empty attributes"""
938 print "Test empty attributes"""
941 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
942 m["objectClass"] = MessageElement("group", FLAG_MOD_ADD, "objectClass")
943 m["description"] = MessageElement([], FLAG_MOD_ADD, "description")
948 except LdbError, (num, _):
949 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
952 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
953 "objectclass": "group"})
956 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
957 m["description"] = MessageElement([], FLAG_MOD_ADD, "description")
962 except LdbError, (num, _):
963 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
966 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
967 m["description"] = MessageElement([], FLAG_MOD_REPLACE, "description")
971 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
972 m["description"] = MessageElement([], FLAG_MOD_DELETE, "description")
976 except LdbError, (num, _):
977 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
979 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
981 def test_instanceType(self):
982 """Tests the 'instanceType' attribute"""
983 print "Tests the 'instanceType' attribute"
985 # The instance type is single-valued
988 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
989 "objectclass": "group",
990 "instanceType": ["0", "1"]})
992 except LdbError, (num, _):
993 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
995 # The head NC flag cannot be set without the write flag
998 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
999 "objectclass": "group",
1000 "instanceType": "1" })
1002 except LdbError, (num, _):
1003 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1005 # We cannot manipulate NCs without the head NC flag
1008 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
1009 "objectclass": "group",
1010 "instanceType": "32" })
1012 except LdbError, (num, _):
1013 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1016 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
1017 "objectclass": "group"})
1020 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1021 m["instanceType"] = MessageElement("0", FLAG_MOD_REPLACE,
1026 except LdbError, (num, _):
1027 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
1030 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1031 m["instanceType"] = MessageElement([], FLAG_MOD_REPLACE,
1036 except LdbError, (num, _):
1037 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
1040 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1041 m["instanceType"] = MessageElement([], FLAG_MOD_DELETE, "instanceType")
1045 except LdbError, (num, _):
1046 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
1048 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1050 def test_distinguished_name(self):
1051 """Tests the 'distinguishedName' attribute"""
1052 print "Tests the 'distinguishedName' attribute"
1054 # The "dn" shortcut isn't supported
1056 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1057 m["objectClass"] = MessageElement("group", 0, "objectClass")
1058 m["dn"] = MessageElement("cn=ldaptestgroup,cn=users," + self.base_dn, 0,
1063 except LdbError, (num, _):
1064 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
1066 # a wrong "distinguishedName" attribute is obviously tolerated
1068 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
1069 "objectclass": "group",
1070 "distinguishedName": "cn=ldaptest,cn=users," + self.base_dn})
1072 # proof if the DN has been set correctly
1073 res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
1074 scope=SCOPE_BASE, attrs=["distinguishedName"])
1075 self.assertTrue(len(res) == 1)
1076 self.assertTrue("distinguishedName" in res[0])
1077 self.assertTrue(Dn(ldb, res[0]["distinguishedName"][0])
1078 == Dn(ldb, "cn=ldaptestgroup, cn=users," + self.base_dn))
1080 # The "dn" shortcut isn't supported
1082 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1083 m["dn"] = MessageElement(
1084 "cn=ldaptestgroup,cn=users," + self.base_dn, FLAG_MOD_REPLACE,
1089 except LdbError, (num, _):
1090 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
1093 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1094 m["distinguishedName"] = MessageElement(
1095 "cn=ldaptestuser,cn=users," + self.base_dn, FLAG_MOD_ADD,
1096 "distinguishedName")
1101 except LdbError, (num, _):
1102 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1105 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1106 m["distinguishedName"] = MessageElement(
1107 "cn=ldaptestuser,cn=users," + self.base_dn, FLAG_MOD_REPLACE,
1108 "distinguishedName")
1113 except LdbError, (num, _):
1114 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
1117 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1118 m["distinguishedName"] = MessageElement(
1119 "cn=ldaptestuser,cn=users," + self.base_dn, FLAG_MOD_DELETE,
1120 "distinguishedName")
1125 except LdbError, (num, _):
1126 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1128 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1130 def test_rdn_name(self):
1132 print "Tests the RDN"
1138 self.ldb.search("=,cn=users," + self.base_dn, scope=SCOPE_BASE)
1140 except LdbError, (num, _):
1141 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1145 self.ldb.search("cn=,cn=users," + self.base_dn, scope=SCOPE_BASE)
1147 except LdbError, (num, _):
1148 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1151 self.ldb.search("=ldaptestgroup,cn=users," + self.base_dn, scope=SCOPE_BASE)
1153 except LdbError, (num, _):
1154 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1161 "dn": "=,cn=users," + self.base_dn,
1162 "objectclass": "group"})
1164 except LdbError, (num, _):
1165 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1170 "dn": "=ldaptestgroup,cn=users," + self.base_dn,
1171 "objectclass": "group"})
1173 except LdbError, (num, _):
1174 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1179 "dn": "cn=,cn=users," + self.base_dn,
1180 "objectclass": "group"})
1182 except LdbError, (num, _):
1183 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1185 # a wrong RDN candidate
1188 "dn": "description=xyz,cn=users," + self.base_dn,
1189 "objectclass": "group"})
1191 except LdbError, (num, _):
1192 self.assertEquals(num, ERR_NAMING_VIOLATION)
1194 delete_force(self.ldb, "description=xyz,cn=users," + self.base_dn)
1196 # a wrong "name" attribute is obviously tolerated
1198 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
1199 "objectclass": "group",
1200 "name": "ldaptestgroupx"})
1202 # proof if the name has been set correctly
1203 res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
1204 scope=SCOPE_BASE, attrs=["name"])
1205 self.assertTrue(len(res) == 1)
1206 self.assertTrue("name" in res[0])
1207 self.assertTrue(res[0]["name"][0] == "ldaptestgroup")
1213 m.dn = Dn(ldb, "cn=,cn=users," + self.base_dn)
1214 m["description"] = "test"
1218 except LdbError, (num, _):
1219 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1225 self.ldb.delete("cn=,cn=users," + self.base_dn)
1227 except LdbError, (num, _):
1228 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1234 self.ldb.rename("cn=ldaptestgroup,cn=users," + self.base_dn,
1235 "=,cn=users," + self.base_dn)
1237 except LdbError, (num, _):
1238 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1240 # new empty RDN name
1242 self.ldb.rename("cn=ldaptestgroup,cn=users," + self.base_dn,
1243 "=ldaptestgroup,cn=users," + self.base_dn)
1245 except LdbError, (num, _):
1246 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1248 # new empty RDN value
1250 self.ldb.rename("cn=ldaptestgroup,cn=users," + self.base_dn,
1251 "cn=,cn=users," + self.base_dn)
1253 except LdbError, (num, _):
1254 self.assertEquals(num, ERR_NAMING_VIOLATION)
1256 # new wrong RDN candidate
1258 self.ldb.rename("cn=ldaptestgroup,cn=users," + self.base_dn,
1259 "description=xyz,cn=users," + self.base_dn)
1261 except LdbError, (num, _):
1262 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1264 delete_force(self.ldb, "description=xyz,cn=users," + self.base_dn)
1266 # old empty RDN value
1268 self.ldb.rename("cn=,cn=users," + self.base_dn,
1269 "cn=ldaptestgroup,cn=users," + self.base_dn)
1271 except LdbError, (num, _):
1272 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1277 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1278 m["name"] = MessageElement("cn=ldaptestuser", FLAG_MOD_REPLACE,
1283 except LdbError, (num, _):
1284 self.assertEquals(num, ERR_NOT_ALLOWED_ON_RDN)
1287 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1288 m["cn"] = MessageElement("ldaptestuser",
1289 FLAG_MOD_REPLACE, "cn")
1293 except LdbError, (num, _):
1294 self.assertEquals(num, ERR_NOT_ALLOWED_ON_RDN)
1296 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1299 # this test needs to be disabled until we really understand
1300 # what the rDN length constraints are
1301 def DISABLED_test_largeRDN(self):
1302 """Testing large rDN (limit 64 characters)"""
1303 rdn = "CN=a012345678901234567890123456789012345678901234567890123456789012";
1304 delete_force(self.ldb, "%s,%s" % (rdn, self.base_dn))
1306 dn: %s,%s""" % (rdn,self.base_dn) + """
1307 objectClass: container
1309 self.ldb.add_ldif(ldif)
1310 delete_force(self.ldb, "%s,%s" % (rdn, self.base_dn))
1312 rdn = "CN=a0123456789012345678901234567890123456789012345678901234567890120";
1313 delete_force(self.ldb, "%s,%s" % (rdn, self.base_dn))
1316 dn: %s,%s""" % (rdn,self.base_dn) + """
1317 objectClass: container
1319 self.ldb.add_ldif(ldif)
1321 except LdbError, (num, _):
1322 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
1323 delete_force(self.ldb, "%s,%s" % (rdn, self.base_dn))
1325 def test_rename(self):
1326 """Tests the rename operation"""
1327 print "Tests the rename operations"
1330 # cannot rename to be a child of itself
1331 ldb.rename(self.base_dn, "dc=test," + self.base_dn)
1333 except LdbError, (num, _):
1334 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1338 ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser2,cn=users," + self.base_dn)
1340 except LdbError, (num, _):
1341 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
1344 "dn": "cn=ldaptestuser2,cn=users," + self.base_dn,
1345 "objectclass": "user" })
1347 ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser2,cn=users," + self.base_dn)
1348 ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=users," + self.base_dn)
1349 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestUSER3,cn=users," + self.base_dn)
1352 # containment problem: a user entry cannot contain user entries
1353 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser4,cn=ldaptestuser3,cn=users," + self.base_dn)
1355 except LdbError, (num, _):
1356 self.assertEquals(num, ERR_NAMING_VIOLATION)
1360 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=people,cn=users," + self.base_dn)
1362 except LdbError, (num, _):
1363 self.assertEquals(num, ERR_OTHER)
1366 # invalid target DN syntax
1367 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, ",cn=users," + self.base_dn)
1369 except LdbError, (num, _):
1370 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1374 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "ou=ldaptestuser3,cn=users," + self.base_dn)
1376 except LdbError, (num, _):
1377 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1379 delete_force(self.ldb, "cn=ldaptestuser3,cn=users," + self.base_dn)
1381 # Performs some "systemFlags" testing
1383 # Move failing since no "SYSTEM_FLAG_CONFIG_ALLOW_MOVE"
1385 ldb.rename("CN=DisplaySpecifiers," + self.configuration_dn, "CN=DisplaySpecifiers,CN=Services," + self.configuration_dn)
1387 except LdbError, (num, _):
1388 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1390 # Limited move failing since no "SYSTEM_FLAG_CONFIG_ALLOW_LIMITED_MOVE"
1392 ldb.rename("CN=Directory Service,CN=Windows NT,CN=Services," + self.configuration_dn, "CN=Directory Service,CN=RRAS,CN=Services," + self.configuration_dn)
1394 except LdbError, (num, _):
1395 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1397 # Rename failing since no "SYSTEM_FLAG_CONFIG_ALLOW_RENAME"
1399 ldb.rename("CN=DisplaySpecifiers," + self.configuration_dn, "CN=DisplaySpecifiers2," + self.configuration_dn)
1401 except LdbError, (num, _):
1402 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1404 # It's not really possible to test moves on the schema partition since
1405 # there don't exist subcontainers on it.
1407 # Rename failing since "SYSTEM_FLAG_SCHEMA_BASE_OBJECT"
1409 ldb.rename("CN=Top," + self.schema_dn, "CN=Top2," + self.schema_dn)
1411 except LdbError, (num, _):
1412 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1414 # Move failing since "SYSTEM_FLAG_DOMAIN_DISALLOW_MOVE"
1416 ldb.rename("CN=Users," + self.base_dn, "CN=Users,CN=Computers," + self.base_dn)
1418 except LdbError, (num, _):
1419 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1421 # Rename failing since "SYSTEM_FLAG_DOMAIN_DISALLOW_RENAME"
1423 ldb.rename("CN=Users," + self.base_dn, "CN=Users2," + self.base_dn)
1425 except LdbError, (num, _):
1426 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1428 # Performs some other constraints testing
1431 ldb.rename("CN=Policies,CN=System," + self.base_dn, "CN=Users2," + self.base_dn)
1433 except LdbError, (num, _):
1434 self.assertEquals(num, ERR_OTHER)
1436 def test_rename_twice(self):
1437 """Tests the rename operation twice - this corresponds to a past bug"""
1438 print "Tests the rename twice operation"
1441 "dn": "cn=ldaptestuser5,cn=users," + self.base_dn,
1442 "objectclass": "user" })
1444 ldb.rename("cn=ldaptestuser5,cn=users," + self.base_dn, "cn=ldaptestUSER5,cn=users," + self.base_dn)
1445 delete_force(self.ldb, "cn=ldaptestuser5,cn=users," + self.base_dn)
1447 "dn": "cn=ldaptestuser5,cn=users," + self.base_dn,
1448 "objectclass": "user" })
1449 ldb.rename("cn=ldaptestuser5,cn=Users," + self.base_dn, "cn=ldaptestUSER5,cn=users," + self.base_dn)
1450 res = ldb.search(expression="cn=ldaptestuser5")
1451 print "Found %u records" % len(res)
1452 self.assertEquals(len(res), 1, "Wrong number of hits for cn=ldaptestuser5")
1453 res = ldb.search(expression="(&(cn=ldaptestuser5)(objectclass=user))")
1454 print "Found %u records" % len(res)
1455 self.assertEquals(len(res), 1, "Wrong number of hits for (&(cn=ldaptestuser5)(objectclass=user))")
1456 delete_force(self.ldb, "cn=ldaptestuser5,cn=users," + self.base_dn)
1458 def test_objectGUID(self):
1459 """Test objectGUID behaviour"""
1460 print "Testing objectGUID behaviour\n"
1462 # The objectGUID cannot directly be set
1464 self.ldb.add_ldif("""
1465 dn: cn=ldaptestcontainer,""" + self.base_dn + """
1466 objectClass: container
1467 objectGUID: bd3480c9-58af-4cd8-92df-bc4a18b6e44d
1470 except LdbError, (num, _):
1471 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1474 "dn": "cn=ldaptestcontainer," + self.base_dn,
1475 "objectClass": "container" })
1477 # The objectGUID cannot directly be changed
1479 self.ldb.modify_ldif("""
1480 dn: cn=ldaptestcontainer,""" + self.base_dn + """
1483 objectGUID: bd3480c9-58af-4cd8-92df-bc4a18b6e44d
1486 except LdbError, (num, _):
1487 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
1489 delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
1491 def test_parentGUID(self):
1492 """Test parentGUID behaviour"""
1493 print "Testing parentGUID behaviour\n"
1496 "dn": "cn=parentguidtest,cn=users," + self.base_dn,
1497 "objectclass":"user",
1498 "samaccountname":"parentguidtest"});
1499 res1 = ldb.search(base="cn=parentguidtest,cn=users," + self.base_dn, scope=SCOPE_BASE,
1500 attrs=["parentGUID", "samaccountname"]);
1501 res2 = ldb.search(base="cn=users," + self.base_dn,scope=SCOPE_BASE,
1502 attrs=["objectGUID"]);
1503 res3 = ldb.search(base=self.base_dn, scope=SCOPE_BASE,
1504 attrs=["parentGUID"]);
1505 res4 = ldb.search(base=self.configuration_dn, scope=SCOPE_BASE,
1506 attrs=["parentGUID"]);
1507 res5 = ldb.search(base=self.schema_dn, scope=SCOPE_BASE,
1508 attrs=["parentGUID"]);
1510 """Check if the parentGUID is valid """
1511 self.assertEquals(res1[0]["parentGUID"], res2[0]["objectGUID"]);
1513 """Check if it returns nothing when there is no parent object - default NC"""
1514 has_parentGUID = False
1515 for key in res3[0].keys():
1516 if key == "parentGUID":
1517 has_parentGUID = True
1519 self.assertFalse(has_parentGUID);
1521 """Check if it returns nothing when there is no parent object - configuration NC"""
1522 has_parentGUID = False
1523 for key in res4[0].keys():
1524 if key == "parentGUID":
1525 has_parentGUID = True
1527 self.assertFalse(has_parentGUID);
1529 """Check if it returns nothing when there is no parent object - schema NC"""
1530 has_parentGUID = False
1531 for key in res5[0].keys():
1532 if key == "parentGUID":
1533 has_parentGUID = True
1535 self.assertFalse(has_parentGUID);
1537 """Ensures that if you look for another object attribute after the constructed
1538 parentGUID, it will return correctly"""
1539 has_another_attribute = False
1540 for key in res1[0].keys():
1541 if key == "sAMAccountName":
1542 has_another_attribute = True
1544 self.assertTrue(has_another_attribute)
1545 self.assertTrue(len(res1[0]["samaccountname"]) == 1)
1546 self.assertEquals(res1[0]["samaccountname"][0], "parentguidtest");
1548 print "Testing parentGUID behaviour on rename\n"
1551 "dn": "cn=testotherusers," + self.base_dn,
1552 "objectclass":"container"});
1553 res1 = ldb.search(base="cn=testotherusers," + self.base_dn,scope=SCOPE_BASE,
1554 attrs=["objectGUID"]);
1555 ldb.rename("cn=parentguidtest,cn=users," + self.base_dn,
1556 "cn=parentguidtest,cn=testotherusers," + self.base_dn);
1557 res2 = ldb.search(base="cn=parentguidtest,cn=testotherusers," + self.base_dn,
1559 attrs=["parentGUID"]);
1560 self.assertEquals(res1[0]["objectGUID"], res2[0]["parentGUID"]);
1562 delete_force(self.ldb, "cn=parentguidtest,cn=testotherusers," + self.base_dn)
1563 delete_force(self.ldb, "cn=testotherusers," + self.base_dn)
1565 def test_usnChanged(self):
1566 """Test usnChanged behaviour"""
1567 print "Testing usnChanged behaviour\n"
1570 "dn": "cn=ldaptestcontainer," + self.base_dn,
1571 "objectClass": "container" })
1573 res = ldb.search("cn=ldaptestcontainer," + self.base_dn,
1575 attrs=["objectGUID", "uSNCreated", "uSNChanged", "whenCreated", "whenChanged", "description"])
1576 self.assertTrue(len(res) == 1)
1577 self.assertFalse("description" in res[0])
1578 self.assertTrue("objectGUID" in res[0])
1579 self.assertTrue("uSNCreated" in res[0])
1580 self.assertTrue("uSNChanged" in res[0])
1581 self.assertTrue("whenCreated" in res[0])
1582 self.assertTrue("whenChanged" in res[0])
1584 delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
1586 # All this attributes are specificable on add operations
1588 "dn": "cn=ldaptestcontainer," + self.base_dn,
1589 "objectclass": "container",
1592 "whenCreated": timestring(long(time.time())),
1593 "whenChanged": timestring(long(time.time())) })
1595 res = ldb.search("cn=ldaptestcontainer," + self.base_dn,
1597 attrs=["objectGUID", "uSNCreated", "uSNChanged", "whenCreated", "whenChanged", "description"])
1598 self.assertTrue(len(res) == 1)
1599 self.assertFalse("description" in res[0])
1600 self.assertTrue("objectGUID" in res[0])
1601 self.assertTrue("uSNCreated" in res[0])
1602 self.assertFalse(res[0]["uSNCreated"][0] == "1") # these are corrected
1603 self.assertTrue("uSNChanged" in res[0])
1604 self.assertFalse(res[0]["uSNChanged"][0] == "1") # these are corrected
1605 self.assertTrue("whenCreated" in res[0])
1606 self.assertTrue("whenChanged" in res[0])
1609 dn: cn=ldaptestcontainer,""" + self.base_dn + """
1611 replace: description
1614 res2 = ldb.search("cn=ldaptestcontainer," + self.base_dn,
1616 attrs=["uSNCreated", "uSNChanged", "description"])
1617 self.assertTrue(len(res) == 1)
1618 self.assertFalse("description" in res2[0])
1619 self.assertEqual(res[0]["usnCreated"], res2[0]["usnCreated"])
1620 self.assertEqual(res[0]["usnCreated"], res2[0]["usnChanged"])
1621 self.assertEqual(res[0]["usnChanged"], res2[0]["usnChanged"])
1624 dn: cn=ldaptestcontainer,""" + self.base_dn + """
1626 replace: description
1630 res3 = ldb.search("cn=ldaptestcontainer," + self.base_dn,
1632 attrs=["uSNCreated", "uSNChanged", "description"])
1633 self.assertTrue(len(res) == 1)
1634 self.assertTrue("description" in res3[0])
1635 self.assertEqual("test", str(res3[0]["description"][0]))
1636 self.assertEqual(res[0]["usnCreated"], res3[0]["usnCreated"])
1637 self.assertNotEqual(res[0]["usnCreated"], res3[0]["usnChanged"])
1638 self.assertNotEqual(res[0]["usnChanged"], res3[0]["usnChanged"])
1641 dn: cn=ldaptestcontainer,""" + self.base_dn + """
1643 replace: description
1647 res4 = ldb.search("cn=ldaptestcontainer," + self.base_dn,
1649 attrs=["uSNCreated", "uSNChanged", "description"])
1650 self.assertTrue(len(res) == 1)
1651 self.assertTrue("description" in res4[0])
1652 self.assertEqual("test", str(res4[0]["description"][0]))
1653 self.assertEqual(res[0]["usnCreated"], res4[0]["usnCreated"])
1654 self.assertNotEqual(res3[0]["usnCreated"], res4[0]["usnChanged"])
1655 self.assertEqual(res3[0]["usnChanged"], res4[0]["usnChanged"])
1658 dn: cn=ldaptestcontainer,""" + self.base_dn + """
1660 replace: description
1664 res5 = ldb.search("cn=ldaptestcontainer," + self.base_dn,
1666 attrs=["uSNCreated", "uSNChanged", "description"])
1667 self.assertTrue(len(res) == 1)
1668 self.assertTrue("description" in res5[0])
1669 self.assertEqual("test2", str(res5[0]["description"][0]))
1670 self.assertEqual(res[0]["usnCreated"], res5[0]["usnCreated"])
1671 self.assertNotEqual(res3[0]["usnChanged"], res5[0]["usnChanged"])
1674 dn: cn=ldaptestcontainer,""" + self.base_dn + """
1680 res6 = ldb.search("cn=ldaptestcontainer," + self.base_dn,
1682 attrs=["uSNCreated", "uSNChanged", "description"])
1683 self.assertTrue(len(res) == 1)
1684 self.assertFalse("description" in res6[0])
1685 self.assertEqual(res[0]["usnCreated"], res6[0]["usnCreated"])
1686 self.assertNotEqual(res5[0]["usnChanged"], res6[0]["usnChanged"])
1689 dn: cn=ldaptestcontainer,""" + self.base_dn + """
1695 res7 = ldb.search("cn=ldaptestcontainer," + self.base_dn,
1697 attrs=["uSNCreated", "uSNChanged", "description"])
1698 self.assertTrue(len(res) == 1)
1699 self.assertTrue("description" in res7[0])
1700 self.assertEqual("test3", str(res7[0]["description"][0]))
1701 self.assertEqual(res[0]["usnCreated"], res7[0]["usnCreated"])
1702 self.assertNotEqual(res6[0]["usnChanged"], res7[0]["usnChanged"])
1705 dn: cn=ldaptestcontainer,""" + self.base_dn + """
1710 res8 = ldb.search("cn=ldaptestcontainer," + self.base_dn,
1712 attrs=["uSNCreated", "uSNChanged", "description"])
1713 self.assertTrue(len(res) == 1)
1714 self.assertFalse("description" in res8[0])
1715 self.assertEqual(res[0]["usnCreated"], res8[0]["usnCreated"])
1716 self.assertNotEqual(res7[0]["usnChanged"], res8[0]["usnChanged"])
1718 delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
1720 def test_groupType_int32(self):
1721 """Test groupType (int32) behaviour (should appear to be casted to a 32 bit signed integer before comparsion)"""
1722 print "Testing groupType (int32) behaviour\n"
1724 res1 = ldb.search(base=self.base_dn, scope=SCOPE_SUBTREE,
1725 attrs=["groupType"], expression="groupType=2147483653");
1727 res2 = ldb.search(base=self.base_dn, scope=SCOPE_SUBTREE,
1728 attrs=["groupType"], expression="groupType=-2147483643");
1730 self.assertEquals(len(res1), len(res2))
1732 self.assertTrue(res1.count > 0)
1734 self.assertEquals(res1[0]["groupType"][0], "-2147483643")
1736 def test_linked_attributes(self):
1737 """This tests the linked attribute behaviour"""
1738 print "Testing linked attribute behaviour\n"
1741 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
1742 "objectclass": "group"})
1744 # This should not work since "memberOf" is linked to "member"
1747 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1748 "objectclass": "user",
1749 "memberOf": "cn=ldaptestgroup,cn=users," + self.base_dn})
1750 except LdbError, (num, _):
1751 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1754 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1755 "objectclass": "user"})
1758 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1759 m["memberOf"] = MessageElement("cn=ldaptestgroup,cn=users," + self.base_dn,
1760 FLAG_MOD_ADD, "memberOf")
1764 except LdbError, (num, _):
1765 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1768 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1769 m["member"] = MessageElement("cn=ldaptestuser,cn=users," + self.base_dn,
1770 FLAG_MOD_ADD, "member")
1774 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1775 m["memberOf"] = MessageElement("cn=ldaptestgroup,cn=users," + self.base_dn,
1776 FLAG_MOD_REPLACE, "memberOf")
1780 except LdbError, (num, _):
1781 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1784 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1785 m["memberOf"] = MessageElement("cn=ldaptestgroup,cn=users," + self.base_dn,
1786 FLAG_MOD_DELETE, "memberOf")
1790 except LdbError, (num, _):
1791 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1794 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1795 m["member"] = MessageElement("cn=ldaptestuser,cn=users," + self.base_dn,
1796 FLAG_MOD_DELETE, "member")
1799 # This should yield no results since the member attribute for
1800 # "ldaptestuser" should have been deleted
1801 res1 = ldb.search("cn=ldaptestgroup, cn=users," + self.base_dn,
1803 expression="(member=cn=ldaptestuser,cn=users," + self.base_dn + ")",
1805 self.assertTrue(len(res1) == 0)
1807 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1810 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
1811 "objectclass": "group",
1812 "member": "cn=ldaptestuser,cn=users," + self.base_dn})
1814 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1816 # Make sure that the "member" attribute for "ldaptestuser" has been
1818 res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
1819 scope=SCOPE_BASE, attrs=["member"])
1820 self.assertTrue(len(res) == 1)
1821 self.assertFalse("member" in res[0])
1823 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1825 def test_wkguid(self):
1826 """Test Well known GUID behaviours (including DN+Binary)"""
1827 print "Test Well known GUID behaviours (including DN+Binary)"
1829 res = self.ldb.search(base=("<WKGUID=ab1d30f3768811d1aded00c04fd8d5cd,%s>" % self.base_dn), scope=SCOPE_BASE, attrs=[])
1830 self.assertEquals(len(res), 1)
1832 res2 = self.ldb.search(scope=SCOPE_BASE, attrs=["wellKnownObjects"], expression=("wellKnownObjects=B:32:ab1d30f3768811d1aded00c04fd8d5cd:%s" % res[0].dn))
1833 self.assertEquals(len(res2), 1)
1835 # Prove that the matching rule is over the whole DN+Binary
1836 res2 = self.ldb.search(scope=SCOPE_BASE, attrs=["wellKnownObjects"], expression=("wellKnownObjects=B:32:ab1d30f3768811d1aded00c04fd8d5cd"))
1837 self.assertEquals(len(res2), 0)
1838 # Prove that the matching rule is over the whole DN+Binary
1839 res2 = self.ldb.search(scope=SCOPE_BASE, attrs=["wellKnownObjects"], expression=("wellKnownObjects=%s") % res[0].dn)
1840 self.assertEquals(len(res2), 0)
1842 def test_subschemasubentry(self):
1843 """Test subSchemaSubEntry appears when requested, but not when not requested"""
1844 print "Test subSchemaSubEntry"
1846 res = self.ldb.search(base=self.base_dn, scope=SCOPE_BASE, attrs=["subSchemaSubEntry"])
1847 self.assertEquals(len(res), 1)
1848 self.assertEquals(res[0]["subSchemaSubEntry"][0], "CN=Aggregate,"+self.schema_dn)
1850 res = self.ldb.search(base=self.base_dn, scope=SCOPE_BASE, attrs=["*"])
1851 self.assertEquals(len(res), 1)
1852 self.assertTrue("subScheamSubEntry" not in res[0])
1857 print "Testing user add"
1860 "dn": "cn=ldaptestuser,cn=uSers," + self.base_dn,
1861 "objectclass": "user",
1862 "cN": "LDAPtestUSER",
1863 "givenname": "ldap",
1867 "dn": "cn=ldaptestgroup,cn=uSers," + self.base_dn,
1868 "objectclass": "group",
1869 "member": "cn=ldaptestuser,cn=useRs," + self.base_dn})
1872 "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
1873 "objectclass": "computer",
1874 "cN": "LDAPtestCOMPUTER"})
1876 ldb.add({"dn": "cn=ldaptest2computer,cn=computers," + self.base_dn,
1877 "objectClass": "computer",
1878 "cn": "LDAPtest2COMPUTER",
1879 "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT),
1880 "displayname": "ldap testy"})
1883 ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn,
1884 "objectClass": "computer",
1885 "cn": "LDAPtest2COMPUTER"
1888 except LdbError, (num, _):
1889 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1892 ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn,
1893 "objectClass": "computer",
1894 "cn": "ldaptestcomputer3",
1895 "sAMAccountType": str(ATYPE_NORMAL_ACCOUNT)
1898 except LdbError, (num, _):
1899 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1901 ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn,
1902 "objectClass": "computer",
1903 "cn": "LDAPtestCOMPUTER3"
1906 print "Testing ldb.search for (&(cn=ldaptestcomputer3)(objectClass=user))";
1907 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestcomputer3)(objectClass=user))");
1908 self.assertEquals(len(res), 1, "Found only %d for (&(cn=ldaptestcomputer3)(objectClass=user))" % len(res))
1910 self.assertEquals(str(res[0].dn), ("CN=ldaptestcomputer3,CN=Computers," + self.base_dn));
1911 self.assertEquals(res[0]["cn"][0], "ldaptestcomputer3");
1912 self.assertEquals(res[0]["name"][0], "ldaptestcomputer3");
1913 self.assertEquals(res[0]["objectClass"][0], "top");
1914 self.assertEquals(res[0]["objectClass"][1], "person");
1915 self.assertEquals(res[0]["objectClass"][2], "organizationalPerson");
1916 self.assertEquals(res[0]["objectClass"][3], "user");
1917 self.assertEquals(res[0]["objectClass"][4], "computer");
1918 self.assertTrue("objectGUID" in res[0])
1919 self.assertTrue("whenCreated" in res[0])
1920 self.assertEquals(res[0]["objectCategory"][0], ("CN=Computer,%s" % ldb.get_schema_basedn()))
1921 self.assertEquals(int(res[0]["primaryGroupID"][0]), 513);
1922 self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_NORMAL_ACCOUNT);
1923 self.assertEquals(int(res[0]["userAccountControl"][0]), UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE);
1925 delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
1927 print "Testing attribute or value exists behaviour"
1930 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1932 replace: servicePrincipalName
1933 servicePrincipalName: host/ldaptest2computer
1934 servicePrincipalName: host/ldaptest2computer
1935 servicePrincipalName: cifs/ldaptest2computer
1938 except LdbError, (num, msg):
1939 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
1942 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1944 replace: servicePrincipalName
1945 servicePrincipalName: host/ldaptest2computer
1946 servicePrincipalName: cifs/ldaptest2computer
1950 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1952 add: servicePrincipalName
1953 servicePrincipalName: host/ldaptest2computer
1956 except LdbError, (num, msg):
1957 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
1959 print "Testing ranged results"
1961 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1963 replace: servicePrincipalName
1967 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1969 add: servicePrincipalName
1970 servicePrincipalName: host/ldaptest2computer0
1971 servicePrincipalName: host/ldaptest2computer1
1972 servicePrincipalName: host/ldaptest2computer2
1973 servicePrincipalName: host/ldaptest2computer3
1974 servicePrincipalName: host/ldaptest2computer4
1975 servicePrincipalName: host/ldaptest2computer5
1976 servicePrincipalName: host/ldaptest2computer6
1977 servicePrincipalName: host/ldaptest2computer7
1978 servicePrincipalName: host/ldaptest2computer8
1979 servicePrincipalName: host/ldaptest2computer9
1980 servicePrincipalName: host/ldaptest2computer10
1981 servicePrincipalName: host/ldaptest2computer11
1982 servicePrincipalName: host/ldaptest2computer12
1983 servicePrincipalName: host/ldaptest2computer13
1984 servicePrincipalName: host/ldaptest2computer14
1985 servicePrincipalName: host/ldaptest2computer15
1986 servicePrincipalName: host/ldaptest2computer16
1987 servicePrincipalName: host/ldaptest2computer17
1988 servicePrincipalName: host/ldaptest2computer18
1989 servicePrincipalName: host/ldaptest2computer19
1990 servicePrincipalName: host/ldaptest2computer20
1991 servicePrincipalName: host/ldaptest2computer21
1992 servicePrincipalName: host/ldaptest2computer22
1993 servicePrincipalName: host/ldaptest2computer23
1994 servicePrincipalName: host/ldaptest2computer24
1995 servicePrincipalName: host/ldaptest2computer25
1996 servicePrincipalName: host/ldaptest2computer26
1997 servicePrincipalName: host/ldaptest2computer27
1998 servicePrincipalName: host/ldaptest2computer28
1999 servicePrincipalName: host/ldaptest2computer29
2002 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE,
2003 attrs=["servicePrincipalName;range=0-*"])
2004 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
2005 #print len(res[0]["servicePrincipalName;range=0-*"])
2006 self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30)
2008 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-19"])
2009 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
2010 # print res[0]["servicePrincipalName;range=0-19"].length
2011 self.assertEquals(len(res[0]["servicePrincipalName;range=0-19"]), 20)
2014 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-30"])
2015 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
2016 self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30)
2018 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-40"])
2019 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
2020 self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30)
2022 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=30-40"])
2023 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
2024 self.assertEquals(len(res[0]["servicePrincipalName;range=30-*"]), 0)
2027 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=10-40"])
2028 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
2029 self.assertEquals(len(res[0]["servicePrincipalName;range=10-*"]), 20)
2030 # pos_11 = res[0]["servicePrincipalName;range=10-*"][18]
2032 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=11-40"])
2033 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
2034 self.assertEquals(len(res[0]["servicePrincipalName;range=11-*"]), 19)
2035 # print res[0]["servicePrincipalName;range=11-*"][18]
2037 # self.assertEquals((res[0]["servicePrincipalName;range=11-*"][18]), pos_11)
2039 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=11-15"])
2040 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
2041 self.assertEquals(len(res[0]["servicePrincipalName;range=11-15"]), 5)
2042 # self.assertEquals(res[0]["servicePrincipalName;range=11-15"][4], pos_11)
2044 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName"])
2045 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
2046 # print res[0]["servicePrincipalName"][18]
2048 self.assertEquals(len(res[0]["servicePrincipalName"]), 30)
2049 # self.assertEquals(res[0]["servicePrincipalName"][18], pos_11)
2051 delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
2053 "dn": "cn=ldaptestuser2,cn=useRs," + self.base_dn,
2054 "objectClass": "user",
2055 "cn": "LDAPtestUSER2",
2056 "givenname": "testy",
2057 "sn": "ldap user2"})
2059 print "Testing Ambigious Name Resolution"
2060 # Testing ldb.search for (&(anr=ldap testy)(objectClass=user))
2061 res = ldb.search(expression="(&(anr=ldap testy)(objectClass=user))")
2062 self.assertEquals(len(res), 3, "Found only %d of 3 for (&(anr=ldap testy)(objectClass=user))" % len(res))
2064 # Testing ldb.search for (&(anr=testy ldap)(objectClass=user))
2065 res = ldb.search(expression="(&(anr=testy ldap)(objectClass=user))")
2066 self.assertEquals(len(res), 2, "Found only %d of 2 for (&(anr=testy ldap)(objectClass=user))" % len(res))
2068 # Testing ldb.search for (&(anr=ldap)(objectClass=user))
2069 res = ldb.search(expression="(&(anr=ldap)(objectClass=user))")
2070 self.assertEquals(len(res), 4, "Found only %d of 4 for (&(anr=ldap)(objectClass=user))" % len(res))
2072 # Testing ldb.search for (&(anr==ldap)(objectClass=user))
2073 res = ldb.search(expression="(&(anr==ldap)(objectClass=user))")
2074 self.assertEquals(len(res), 1, "Could not find (&(anr==ldap)(objectClass=user)). Found only %d for (&(anr=ldap)(objectClass=user))" % len(res))
2076 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
2077 self.assertEquals(res[0]["cn"][0], "ldaptestuser")
2078 self.assertEquals(str(res[0]["name"]), "ldaptestuser")
2080 # Testing ldb.search for (&(anr=testy)(objectClass=user))
2081 res = ldb.search(expression="(&(anr=testy)(objectClass=user))")
2082 self.assertEquals(len(res), 2, "Found only %d for (&(anr=testy)(objectClass=user))" % len(res))
2084 # Testing ldb.search for (&(anr=testy ldap)(objectClass=user))
2085 res = ldb.search(expression="(&(anr=testy ldap)(objectClass=user))")
2086 self.assertEquals(len(res), 2, "Found only %d for (&(anr=testy ldap)(objectClass=user))" % len(res))
2088 # Testing ldb.search for (&(anr==testy ldap)(objectClass=user))
2089 # this test disabled for the moment, as anr with == tests are not understood
2090 # res = ldb.search(expression="(&(anr==testy ldap)(objectClass=user))")
2091 # self.assertEquals(len(res), 1, "Found only %d for (&(anr==testy ldap)(objectClass=user))" % len(res))
2093 # self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
2094 # self.assertEquals(res[0]["cn"][0], "ldaptestuser")
2095 # self.assertEquals(res[0]["name"][0], "ldaptestuser")
2097 # Testing ldb.search for (&(anr==testy ldap)(objectClass=user))
2098 # res = ldb.search(expression="(&(anr==testy ldap)(objectClass=user))")
2099 # self.assertEquals(len(res), 1, "Could not find (&(anr==testy ldap)(objectClass=user))")
2101 # self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
2102 # self.assertEquals(res[0]["cn"][0], "ldaptestuser")
2103 # self.assertEquals(res[0]["name"][0], "ldaptestuser")
2105 # Testing ldb.search for (&(anr=testy ldap user)(objectClass=user))
2106 res = ldb.search(expression="(&(anr=testy ldap user)(objectClass=user))")
2107 self.assertEquals(len(res), 1, "Could not find (&(anr=testy ldap user)(objectClass=user))")
2109 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
2110 self.assertEquals(str(res[0]["cn"]), "ldaptestuser2")
2111 self.assertEquals(str(res[0]["name"]), "ldaptestuser2")
2113 # Testing ldb.search for (&(anr==testy ldap user2)(objectClass=user))
2114 # res = ldb.search(expression="(&(anr==testy ldap user2)(objectClass=user))")
2115 # self.assertEquals(len(res), 1, "Could not find (&(anr==testy ldap user2)(objectClass=user))")
2117 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
2118 self.assertEquals(str(res[0]["cn"]), "ldaptestuser2")
2119 self.assertEquals(str(res[0]["name"]), "ldaptestuser2")
2121 # Testing ldb.search for (&(anr==ldap user2)(objectClass=user))
2122 # res = ldb.search(expression="(&(anr==ldap user2)(objectClass=user))")
2123 # self.assertEquals(len(res), 1, "Could not find (&(anr==ldap user2)(objectClass=user))")
2125 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
2126 self.assertEquals(str(res[0]["cn"]), "ldaptestuser2")
2127 self.assertEquals(str(res[0]["name"]), "ldaptestuser2")
2129 # Testing ldb.search for (&(anr==not ldap user2)(objectClass=user))
2130 # res = ldb.search(expression="(&(anr==not ldap user2)(objectClass=user))")
2131 # self.assertEquals(len(res), 0, "Must not find (&(anr==not ldap user2)(objectClass=user))")
2133 # Testing ldb.search for (&(anr=not ldap user2)(objectClass=user))
2134 res = ldb.search(expression="(&(anr=not ldap user2)(objectClass=user))")
2135 self.assertEquals(len(res), 0, "Must not find (&(anr=not ldap user2)(objectClass=user))")
2137 # Testing ldb.search for (&(anr="testy ldap")(objectClass=user)) (ie, with quotes)
2138 # res = ldb.search(expression="(&(anr==\"testy ldap\")(objectClass=user))")
2139 # self.assertEquals(len(res), 0, "Found (&(anr==\"testy ldap\")(objectClass=user))")
2141 print "Testing Renames"
2143 attrs = ["objectGUID", "objectSid"]
2144 print "Testing ldb.search for (&(cn=ldaptestUSer2)(objectClass=user))"
2145 res_user = ldb.search(self.base_dn, expression="(&(cn=ldaptestUSer2)(objectClass=user))", scope=SCOPE_SUBTREE, attrs=attrs)
2146 self.assertEquals(len(res_user), 1, "Could not find (&(cn=ldaptestUSer2)(objectClass=user))")
2148 # Check rename works with extended/alternate DN forms
2149 ldb.rename("<SID=" + ldb.schema_format_value("objectSID", res_user[0]["objectSID"][0]) + ">" , "cn=ldaptestUSER3,cn=users," + self.base_dn)
2151 print "Testing ldb.search for (&(cn=ldaptestuser3)(objectClass=user))"
2152 res = ldb.search(expression="(&(cn=ldaptestuser3)(objectClass=user))")
2153 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser3)(objectClass=user))")
2155 self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
2156 self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3")
2157 self.assertEquals(str(res[0]["name"]), "ldaptestUSER3")
2159 #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))"
2160 res = ldb.search(expression="(&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))")
2161 self.assertEquals(len(res), 1, "(&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))")
2163 self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
2164 self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3")
2165 self.assertEquals(str(res[0]["name"]), "ldaptestUSER3")
2167 #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))"
2168 res = ldb.search(expression="(&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))")
2169 self.assertEquals(len(res), 1, "(&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))")
2171 self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
2172 self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3")
2173 self.assertEquals(str(res[0]["name"]), "ldaptestUSER3")
2175 #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))"
2176 res = ldb.search(expression="(&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))")
2177 self.assertEquals(len(res), 0, "(&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))")
2179 print "Testing ldb.search for (dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ") - should not work"
2180 res = ldb.search(expression="(dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")")
2181 self.assertEquals(len(res), 0, "Could find (dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")")
2183 print "Testing ldb.search for (distinguishedName=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")"
2184 res = ldb.search(expression="(distinguishedName=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")")
2185 self.assertEquals(len(res), 1, "Could not find (distinguishedName=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")")
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 # ensure we cannot add it again
2192 ldb.add({"dn": "cn=ldaptestuser3,cn=userS," + self.base_dn,
2193 "objectClass": "user",
2194 "cn": "LDAPtestUSER3"})
2196 except LdbError, (num, _):
2197 self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
2200 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser2,cn=users," + self.base_dn)
2202 # ensure we cannot rename it twice
2204 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn,
2205 "cn=ldaptestuser2,cn=users," + self.base_dn)
2207 except LdbError, (num, _):
2208 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
2210 # ensure can now use that name
2211 ldb.add({"dn": "cn=ldaptestuser3,cn=users," + self.base_dn,
2212 "objectClass": "user",
2213 "cn": "LDAPtestUSER3"})
2215 # ensure we now cannot rename
2217 ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=users," + self.base_dn)
2219 except LdbError, (num, _):
2220 self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
2222 ldb.rename("cn=ldaptestuser3,cn=users,%s" % self.base_dn, "cn=ldaptestuser3,%s" % ldb.get_config_basedn())
2224 except LdbError, (num, _):
2225 self.assertTrue(num in (71, 64))
2227 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser5,cn=users," + self.base_dn)
2229 ldb.delete("cn=ldaptestuser5,cn=users," + self.base_dn)
2231 delete_force(ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
2233 ldb.rename("cn=ldaptestgroup,cn=users," + self.base_dn, "cn=ldaptestgroup2,cn=users," + self.base_dn)
2235 print "Testing subtree renames"
2237 ldb.add({"dn": "cn=ldaptestcontainer," + self.base_dn,
2238 "objectClass": "container"})
2240 ldb.add({"dn": "CN=ldaptestuser4,CN=ldaptestcontainer," + self.base_dn,
2241 "objectClass": "user",
2242 "cn": "LDAPtestUSER4"})
2244 # Here we don't enforce these hard "description" constraints
2246 dn: cn=ldaptestcontainer,""" + self.base_dn + """
2248 replace: description
2254 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2257 member: cn=ldaptestuser4,cn=ldaptestcontainer,""" + self.base_dn + """
2258 member: cn=ldaptestcomputer,cn=computers,""" + self.base_dn + """
2259 member: cn=ldaptestuser2,cn=users,""" + self.base_dn + """
2262 print "Testing ldb.rename of cn=ldaptestcontainer," + self.base_dn + " to cn=ldaptestcontainer2," + self.base_dn
2263 ldb.rename("CN=ldaptestcontainer," + self.base_dn, "CN=ldaptestcontainer2," + self.base_dn)
2265 print "Testing ldb.search for (&(cn=ldaptestuser4)(objectClass=user))"
2266 res = ldb.search(expression="(&(cn=ldaptestuser4)(objectClass=user))")
2267 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser4)(objectClass=user))")
2269 print "Testing subtree ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in (just renamed from) cn=ldaptestcontainer," + self.base_dn
2271 res = ldb.search("cn=ldaptestcontainer," + self.base_dn,
2272 expression="(&(cn=ldaptestuser4)(objectClass=user))",
2273 scope=SCOPE_SUBTREE)
2275 except LdbError, (num, _):
2276 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
2278 print "Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in (just renamed from) cn=ldaptestcontainer," + self.base_dn
2280 res = ldb.search("cn=ldaptestcontainer," + self.base_dn,
2281 expression="(&(cn=ldaptestuser4)(objectClass=user))", scope=SCOPE_ONELEVEL)
2283 except LdbError, (num, _):
2284 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
2286 print "Testing ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in renamed container"
2287 res = ldb.search("cn=ldaptestcontainer2," + self.base_dn, expression="(&(cn=ldaptestuser4)(objectClass=user))", scope=SCOPE_SUBTREE)
2288 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser4)(objectClass=user)) under cn=ldaptestcontainer2," + self.base_dn)
2290 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn))
2291 self.assertEquals(res[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
2295 print "Testing ldb.search for (&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn + ")(objectclass=group)) to check subtree renames and linked attributes"
2296 res = ldb.search(self.base_dn, expression="(&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn + ")(objectclass=group))", scope=SCOPE_SUBTREE)
2297 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?")
2299 print "Testing ldb.rename (into itself) of cn=ldaptestcontainer2," + self.base_dn + " to cn=ldaptestcontainer,cn=ldaptestcontainer2," + self.base_dn
2301 ldb.rename("cn=ldaptestcontainer2," + self.base_dn, "cn=ldaptestcontainer,cn=ldaptestcontainer2," + self.base_dn)
2303 except LdbError, (num, _):
2304 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
2306 print "Testing ldb.rename (into non-existent container) of cn=ldaptestcontainer2," + self.base_dn + " to cn=ldaptestcontainer,cn=ldaptestcontainer3," + self.base_dn
2308 ldb.rename("cn=ldaptestcontainer2," + self.base_dn, "cn=ldaptestcontainer,cn=ldaptestcontainer3," + self.base_dn)
2310 except LdbError, (num, _):
2311 self.assertTrue(num in (ERR_UNWILLING_TO_PERFORM, ERR_OTHER))
2313 print "Testing delete (should fail, not a leaf node) of renamed cn=ldaptestcontainer2," + self.base_dn
2315 ldb.delete("cn=ldaptestcontainer2," + self.base_dn)
2317 except LdbError, (num, _):
2318 self.assertEquals(num, ERR_NOT_ALLOWED_ON_NON_LEAF)
2320 print "Testing base ldb.search for CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn
2321 res = ldb.search(expression="(objectclass=*)", base=("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn), scope=SCOPE_BASE)
2322 self.assertEquals(len(res), 1)
2323 res = ldb.search(expression="(cn=ldaptestuser40)", base=("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn), scope=SCOPE_BASE)
2324 self.assertEquals(len(res), 0)
2326 print "Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in cn=ldaptestcontainer2," + self.base_dn
2327 res = ldb.search(expression="(&(cn=ldaptestuser4)(objectClass=user))", base=("cn=ldaptestcontainer2," + self.base_dn), scope=SCOPE_ONELEVEL)
2328 self.assertEquals(len(res), 1)
2330 print "Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in cn=ldaptestcontainer2," + self.base_dn
2331 res = ldb.search(expression="(&(cn=ldaptestuser4)(objectClass=user))", base=("cn=ldaptestcontainer2," + self.base_dn), scope=SCOPE_SUBTREE)
2332 self.assertEquals(len(res), 1)
2334 print "Testing delete of subtree renamed "+("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn)
2335 ldb.delete(("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn))
2336 print "Testing delete of renamed cn=ldaptestcontainer2," + self.base_dn
2337 ldb.delete("cn=ldaptestcontainer2," + self.base_dn)
2339 ldb.add({"dn": "cn=ldaptestutf8user èùéìòà,cn=users," + self.base_dn, "objectClass": "user"})
2341 ldb.add({"dn": "cn=ldaptestutf8user2 èùéìòà,cn=users," + self.base_dn, "objectClass": "user"})
2343 print "Testing ldb.search for (&(cn=ldaptestuser)(objectClass=user))"
2344 res = ldb.search(expression="(&(cn=ldaptestuser)(objectClass=user))")
2345 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser)(objectClass=user))")
2347 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
2348 self.assertEquals(str(res[0]["cn"]), "ldaptestuser")
2349 self.assertEquals(str(res[0]["name"]), "ldaptestuser")
2350 self.assertEquals(set(res[0]["objectClass"]), set(["top", "person", "organizationalPerson", "user"]))
2351 self.assertTrue("objectGUID" in res[0])
2352 self.assertTrue("whenCreated" in res[0])
2353 self.assertEquals(str(res[0]["objectCategory"]), ("CN=Person,%s" % ldb.get_schema_basedn()))
2354 self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_NORMAL_ACCOUNT)
2355 self.assertEquals(int(res[0]["userAccountControl"][0]), UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE)
2356 self.assertEquals(res[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
2357 self.assertEquals(len(res[0]["memberOf"]), 1)
2359 print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=cn=person,%s))" % ldb.get_schema_basedn()
2360 res2 = ldb.search(expression="(&(cn=ldaptestuser)(objectCategory=cn=person,%s))" % ldb.get_schema_basedn())
2361 self.assertEquals(len(res2), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=cn=person,%s))" % ldb.get_schema_basedn())
2363 self.assertEquals(res[0].dn, res2[0].dn)
2365 print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon))"
2366 res3 = ldb.search(expression="(&(cn=ldaptestuser)(objectCategory=PerSon))")
2367 self.assertEquals(len(res3), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=PerSon)): matched %d" % len(res3))
2369 self.assertEquals(res[0].dn, res3[0].dn)
2371 if gc_ldb is not None:
2372 print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon)) in Global Catalog"
2373 res3gc = gc_ldb.search(expression="(&(cn=ldaptestuser)(objectCategory=PerSon))")
2374 self.assertEquals(len(res3gc), 1)
2376 self.assertEquals(res[0].dn, res3gc[0].dn)
2378 print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon)) in with 'phantom root' control"
2380 if gc_ldb is not None:
2381 res3control = gc_ldb.search(self.base_dn, expression="(&(cn=ldaptestuser)(objectCategory=PerSon))", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["search_options:1:2"])
2382 self.assertEquals(len(res3control), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=PerSon)) in Global Catalog")
2384 self.assertEquals(res[0].dn, res3control[0].dn)
2386 ldb.delete(res[0].dn)
2388 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectClass=user))"
2389 res = ldb.search(expression="(&(cn=ldaptestcomputer)(objectClass=user))")
2390 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser)(objectClass=user))")
2392 self.assertEquals(str(res[0].dn), ("CN=ldaptestcomputer,CN=Computers," + self.base_dn))
2393 self.assertEquals(str(res[0]["cn"]), "ldaptestcomputer")
2394 self.assertEquals(str(res[0]["name"]), "ldaptestcomputer")
2395 self.assertEquals(set(res[0]["objectClass"]), set(["top", "person", "organizationalPerson", "user", "computer"]))
2396 self.assertTrue("objectGUID" in res[0])
2397 self.assertTrue("whenCreated" in res[0])
2398 self.assertEquals(str(res[0]["objectCategory"]), ("CN=Computer,%s" % ldb.get_schema_basedn()))
2399 self.assertEquals(int(res[0]["primaryGroupID"][0]), 513)
2400 self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_NORMAL_ACCOUNT)
2401 self.assertEquals(int(res[0]["userAccountControl"][0]), UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE)
2402 self.assertEquals(res[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
2403 self.assertEquals(len(res[0]["memberOf"]), 1)
2405 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=cn=computer,%s))" % ldb.get_schema_basedn()
2406 res2 = ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=cn=computer,%s))" % ldb.get_schema_basedn())
2407 self.assertEquals(len(res2), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=cn=computer,%s))" % ldb.get_schema_basedn())
2409 self.assertEquals(res[0].dn, res2[0].dn)
2411 if gc_ldb is not None:
2412 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=cn=computer,%s)) in Global Catalog" % gc_ldb.get_schema_basedn()
2413 res2gc = gc_ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=cn=computer,%s))" % gc_ldb.get_schema_basedn())
2414 self.assertEquals(len(res2gc), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=cn=computer,%s)) In Global Catalog" % gc_ldb.get_schema_basedn())
2416 self.assertEquals(res[0].dn, res2gc[0].dn)
2418 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=compuTER))"
2419 res3 = ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=compuTER))")
2420 self.assertEquals(len(res3), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=compuTER))")
2422 self.assertEquals(res[0].dn, res3[0].dn)
2424 if gc_ldb is not None:
2425 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=compuTER)) in Global Catalog"
2426 res3gc = gc_ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=compuTER))")
2427 self.assertEquals(len(res3gc), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=compuTER)) in Global Catalog")
2429 self.assertEquals(res[0].dn, res3gc[0].dn)
2431 print "Testing ldb.search for (&(cn=ldaptestcomp*r)(objectCategory=compuTER))"
2432 res4 = ldb.search(expression="(&(cn=ldaptestcomp*r)(objectCategory=compuTER))")
2433 self.assertEquals(len(res4), 1, "Could not find (&(cn=ldaptestcomp*r)(objectCategory=compuTER))")
2435 self.assertEquals(res[0].dn, res4[0].dn)
2437 print "Testing ldb.search for (&(cn=ldaptestcomput*)(objectCategory=compuTER))"
2438 res5 = ldb.search(expression="(&(cn=ldaptestcomput*)(objectCategory=compuTER))")
2439 self.assertEquals(len(res5), 1, "Could not find (&(cn=ldaptestcomput*)(objectCategory=compuTER))")
2441 self.assertEquals(res[0].dn, res5[0].dn)
2443 print "Testing ldb.search for (&(cn=*daptestcomputer)(objectCategory=compuTER))"
2444 res6 = ldb.search(expression="(&(cn=*daptestcomputer)(objectCategory=compuTER))")
2445 self.assertEquals(len(res6), 1, "Could not find (&(cn=*daptestcomputer)(objectCategory=compuTER))")
2447 self.assertEquals(res[0].dn, res6[0].dn)
2449 ldb.delete("<GUID=" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + ">")
2451 print "Testing ldb.search for (&(cn=ldaptest2computer)(objectClass=user))"
2452 res = ldb.search(expression="(&(cn=ldaptest2computer)(objectClass=user))")
2453 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptest2computer)(objectClass=user))")
2455 self.assertEquals(str(res[0].dn), "CN=ldaptest2computer,CN=Computers," + self.base_dn)
2456 self.assertEquals(str(res[0]["cn"]), "ldaptest2computer")
2457 self.assertEquals(str(res[0]["name"]), "ldaptest2computer")
2458 self.assertEquals(list(res[0]["objectClass"]), ["top", "person", "organizationalPerson", "user", "computer"])
2459 self.assertTrue("objectGUID" in res[0])
2460 self.assertTrue("whenCreated" in res[0])
2461 self.assertEquals(res[0]["objectCategory"][0], "CN=Computer,%s" % ldb.get_schema_basedn())
2462 self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_WORKSTATION_TRUST)
2463 self.assertEquals(int(res[0]["userAccountControl"][0]), UF_WORKSTATION_TRUST_ACCOUNT)
2465 ldb.delete("<SID=" + ldb.schema_format_value("objectSID", res[0]["objectSID"][0]) + ">")
2467 attrs = ["cn", "name", "objectClass", "objectGUID", "objectSID", "whenCreated", "nTSecurityDescriptor", "memberOf", "allowedAttributes", "allowedAttributesEffective"]
2468 print "Testing ldb.search for (&(cn=ldaptestUSer2)(objectClass=user))"
2469 res_user = ldb.search(self.base_dn, expression="(&(cn=ldaptestUSer2)(objectClass=user))", scope=SCOPE_SUBTREE, attrs=attrs)
2470 self.assertEquals(len(res_user), 1, "Could not find (&(cn=ldaptestUSer2)(objectClass=user))")
2472 self.assertEquals(str(res_user[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
2473 self.assertEquals(str(res_user[0]["cn"]), "ldaptestuser2")
2474 self.assertEquals(str(res_user[0]["name"]), "ldaptestuser2")
2475 self.assertEquals(list(res_user[0]["objectClass"]), ["top", "person", "organizationalPerson", "user"])
2476 self.assertTrue("objectSid" in res_user[0])
2477 self.assertTrue("objectGUID" in res_user[0])
2478 self.assertTrue("whenCreated" in res_user[0])
2479 self.assertTrue("nTSecurityDescriptor" in res_user[0])
2480 self.assertTrue("allowedAttributes" in res_user[0])
2481 self.assertTrue("allowedAttributesEffective" in res_user[0])
2482 self.assertEquals(res_user[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
2484 ldaptestuser2_sid = res_user[0]["objectSid"][0]
2485 ldaptestuser2_guid = res_user[0]["objectGUID"][0]
2487 attrs = ["cn", "name", "objectClass", "objectGUID", "objectSID", "whenCreated", "nTSecurityDescriptor", "member", "allowedAttributes", "allowedAttributesEffective"]
2488 print "Testing ldb.search for (&(cn=ldaptestgroup2)(objectClass=group))"
2489 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs)
2490 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))")
2492 self.assertEquals(str(res[0].dn), ("CN=ldaptestgroup2,CN=Users," + self.base_dn))
2493 self.assertEquals(str(res[0]["cn"]), "ldaptestgroup2")
2494 self.assertEquals(str(res[0]["name"]), "ldaptestgroup2")
2495 self.assertEquals(list(res[0]["objectClass"]), ["top", "group"])
2496 self.assertTrue("objectGUID" in res[0])
2497 self.assertTrue("objectSid" in res[0])
2498 self.assertTrue("whenCreated" in res[0])
2499 self.assertTrue("nTSecurityDescriptor" in res[0])
2500 self.assertTrue("allowedAttributes" in res[0])
2501 self.assertTrue("allowedAttributesEffective" in res[0])
2503 for m in res[0]["member"]:
2504 memberUP.append(m.upper())
2505 self.assertTrue(("CN=ldaptestuser2,CN=Users," + self.base_dn).upper() in memberUP)
2507 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs, controls=["extended_dn:1:1"])
2508 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))")
2510 print res[0]["member"]
2512 for m in res[0]["member"]:
2513 memberUP.append(m.upper())
2514 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()
2516 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)
2518 print "Quicktest for linked attributes"
2520 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2523 member: CN=ldaptestuser2,CN=Users,""" + self.base_dn + """
2524 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
2528 dn: <GUID=""" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + """>
2531 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
2535 dn: <SID=""" + ldb.schema_format_value("objectSid", res[0]["objectSid"][0]) + """>
2541 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2544 member: <GUID=""" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + """>
2545 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
2549 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2555 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2558 member: <SID=""" + ldb.schema_format_value("objectSid", res_user[0]["objectSid"][0]) + """>
2559 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
2563 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2566 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
2569 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs)
2570 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))")
2572 self.assertEquals(str(res[0].dn), ("CN=ldaptestgroup2,CN=Users," + self.base_dn))
2573 self.assertEquals(res[0]["member"][0], ("CN=ldaptestuser2,CN=Users," + self.base_dn))
2574 self.assertEquals(len(res[0]["member"]), 1)
2576 ldb.delete(("CN=ldaptestuser2,CN=Users," + self.base_dn))
2580 attrs = ["cn", "name", "objectClass", "objectGUID", "whenCreated", "nTSecurityDescriptor", "member"]
2581 print "Testing ldb.search for (&(cn=ldaptestgroup2)(objectClass=group)) to check linked delete"
2582 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs)
2583 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group)) to check linked delete")
2585 self.assertEquals(str(res[0].dn), ("CN=ldaptestgroup2,CN=Users," + self.base_dn))
2586 self.assertTrue("member" not in res[0])
2588 print "Testing ldb.search for (&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))"
2589 res = ldb.search(expression="(&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
2590 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
2591 res = ldb.search(expression="(&(cn=ldaptestutf8user èùéìòà)(objectclass=user))")
2592 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
2594 self.assertEquals(str(res[0].dn), ("CN=ldaptestutf8user èùéìòà,CN=Users," + self.base_dn))
2595 self.assertEquals(str(res[0]["cn"]), "ldaptestutf8user èùéìòà")
2596 self.assertEquals(str(res[0]["name"]), "ldaptestutf8user èùéìòà")
2597 self.assertEquals(list(res[0]["objectClass"]), ["top", "person", "organizationalPerson", "user"])
2598 self.assertTrue("objectGUID" in res[0])
2599 self.assertTrue("whenCreated" in res[0])
2601 # delete "ldaptestutf8user"
2602 ldb.delete(res[0].dn)
2604 print "Testing ldb.search for (&(cn=ldaptestutf8user2*)(objectClass=user))"
2605 res = ldb.search(expression="(&(cn=ldaptestutf8user2*)(objectClass=user))")
2606 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestutf8user2*)(objectClass=user))")
2608 print "Testing ldb.search for (&(cn=ldaptestutf8user2 ÈÙÉÌÒÀ)(objectClass=user))"
2609 res = ldb.search(expression="(&(cn=ldaptestutf8user2 ÈÙÉÌÒÀ)(objectClass=user))")
2610 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestutf8user2 ÈÙÉÌÒÀ)(objectClass=user))")
2612 # delete "ldaptestutf8user2 "
2613 ldb.delete(res[0].dn)
2615 ldb.delete(("CN=ldaptestgroup2,CN=Users," + self.base_dn))
2617 print "Testing that we can't get at the configuration DN from the main search base"
2618 res = ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
2619 self.assertEquals(len(res), 0)
2621 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"
2622 res = ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["search_options:1:2"])
2623 self.assertTrue(len(res) > 0)
2625 if gc_ldb is not None:
2626 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"
2628 res = gc_ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["search_options:1:0"])
2629 self.assertTrue(len(res) > 0)
2631 print "Testing that we do find configuration elements in the global catlog"
2632 res = gc_ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
2633 self.assertTrue(len(res) > 0)
2635 print "Testing that we do find configuration elements and user elements at the same time"
2636 res = gc_ldb.search(self.base_dn, expression="(|(objectClass=crossRef)(objectClass=person))", scope=SCOPE_SUBTREE, attrs=["cn"])
2637 self.assertTrue(len(res) > 0)
2639 print "Testing that we do find configuration elements in the global catlog, with the configuration basedn"
2640 res = gc_ldb.search(self.configuration_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
2641 self.assertTrue(len(res) > 0)
2643 print "Testing that we can get at the configuration DN on the main LDAP port"
2644 res = ldb.search(self.configuration_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
2645 self.assertTrue(len(res) > 0)
2647 print "Testing objectCategory canonacolisation"
2648 res = ldb.search(self.configuration_dn, expression="objectCategory=ntDsDSA", scope=SCOPE_SUBTREE, attrs=["cn"])
2649 self.assertTrue(len(res) > 0, "Didn't find any records with objectCategory=ntDsDSA")
2650 self.assertTrue(len(res) != 0)
2652 res = ldb.search(self.configuration_dn, expression="objectCategory=CN=ntDs-DSA," + self.schema_dn, scope=SCOPE_SUBTREE, attrs=["cn"])
2653 self.assertTrue(len(res) > 0, "Didn't find any records with objectCategory=CN=ntDs-DSA," + self.schema_dn)
2654 self.assertTrue(len(res) != 0)
2656 print "Testing objectClass attribute order on "+ self.base_dn
2657 res = ldb.search(expression="objectClass=domain", base=self.base_dn,
2658 scope=SCOPE_BASE, attrs=["objectClass"])
2659 self.assertEquals(len(res), 1)
2661 self.assertEquals(list(res[0]["objectClass"]), ["top", "domain", "domainDNS"])
2665 print "Testing ldb.search for objectCategory=person"
2666 res = ldb.search(self.base_dn, expression="objectCategory=person", scope=SCOPE_SUBTREE, attrs=["cn"])
2667 self.assertTrue(len(res) > 0)
2669 print "Testing ldb.search for objectCategory=person with domain scope control"
2670 res = ldb.search(self.base_dn, expression="objectCategory=person", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["domain_scope:1"])
2671 self.assertTrue(len(res) > 0)
2673 print "Testing ldb.search for objectCategory=user"
2674 res = ldb.search(self.base_dn, expression="objectCategory=user", scope=SCOPE_SUBTREE, attrs=["cn"])
2675 self.assertTrue(len(res) > 0)
2677 print "Testing ldb.search for objectCategory=user with domain scope control"
2678 res = ldb.search(self.base_dn, expression="objectCategory=user", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["domain_scope:1"])
2679 self.assertTrue(len(res) > 0)
2681 print "Testing ldb.search for objectCategory=group"
2682 res = ldb.search(self.base_dn, expression="objectCategory=group", scope=SCOPE_SUBTREE, attrs=["cn"])
2683 self.assertTrue(len(res) > 0)
2685 print "Testing ldb.search for objectCategory=group with domain scope control"
2686 res = ldb.search(self.base_dn, expression="objectCategory=group", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["domain_scope:1"])
2687 self.assertTrue(len(res) > 0)
2689 print "Testing creating a user with the posixAccount objectClass"
2690 self.ldb.add_ldif("""dn: cn=posixuser,CN=Users,%s
2693 objectClass: posixAccount
2695 objectClass: organizationalPerson
2701 homeDirectory: /home/posixuser
2702 loginShell: /bin/bash
2703 gecos: Posix User;;;
2704 description: A POSIX user"""% (self.base_dn))
2706 print "Testing removing the posixAccount objectClass from an existing user"
2707 self.ldb.modify_ldif("""dn: cn=posixuser,CN=Users,%s
2710 objectClass: posixAccount"""% (self.base_dn))
2712 print "Testing adding the posixAccount objectClass to an existing user"
2713 self.ldb.modify_ldif("""dn: cn=posixuser,CN=Users,%s
2716 objectClass: posixAccount"""% (self.base_dn))
2718 delete_force(self.ldb, "cn=posixuser,cn=users," + self.base_dn)
2719 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
2720 delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
2721 delete_force(self.ldb, "cn=ldaptestuser3,cn=users," + self.base_dn)
2722 delete_force(self.ldb, "cn=ldaptestuser4,cn=ldaptestcontainer," + self.base_dn)
2723 delete_force(self.ldb, "cn=ldaptestuser4,cn=ldaptestcontainer2," + self.base_dn)
2724 delete_force(self.ldb, "cn=ldaptestuser5,cn=users," + self.base_dn)
2725 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
2726 delete_force(self.ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
2727 delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2728 delete_force(self.ldb, "cn=ldaptest2computer,cn=computers," + self.base_dn)
2729 delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
2730 delete_force(self.ldb, "cn=ldaptestutf8user èùéìòà,cn=users," + self.base_dn)
2731 delete_force(self.ldb, "cn=ldaptestutf8user2 èùéìòà,cn=users," + self.base_dn)
2732 delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
2733 delete_force(self.ldb, "cn=ldaptestcontainer2," + self.base_dn)
2735 def test_security_descriptor_add(self):
2736 """ Testing ldb.add_ldif() for nTSecurityDescriptor """
2737 user_name = "testdescriptoruser1"
2738 user_dn = "CN=%s,CN=Users,%s" % (user_name, self.base_dn)
2740 # Test an empty security descriptor (naturally this shouldn't work)
2742 delete_force(self.ldb, user_dn)
2744 self.ldb.add({ "dn": user_dn,
2745 "objectClass": "user",
2746 "sAMAccountName": user_name,
2747 "nTSecurityDescriptor": [] })
2749 except LdbError, (num, _):
2750 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
2752 delete_force(self.ldb, user_dn)
2754 # Test add_ldif() with SDDL security descriptor input
2757 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2758 self.ldb.add_ldif("""
2759 dn: """ + user_dn + """
2761 sAMAccountName: """ + user_name + """
2762 nTSecurityDescriptor: """ + sddl)
2763 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2764 desc = res[0]["nTSecurityDescriptor"][0]
2765 desc = ndr_unpack( security.descriptor, desc )
2766 desc_sddl = desc.as_sddl( self.domain_sid )
2767 self.assertEqual(desc_sddl, sddl)
2769 delete_force(self.ldb, user_dn)
2771 # Test add_ldif() with BASE64 security descriptor
2774 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2775 desc = security.descriptor.from_sddl(sddl, self.domain_sid)
2776 desc_binary = ndr_pack(desc)
2777 desc_base64 = base64.b64encode(desc_binary)
2778 self.ldb.add_ldif("""
2779 dn: """ + user_dn + """
2781 sAMAccountName: """ + user_name + """
2782 nTSecurityDescriptor:: """ + desc_base64)
2783 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2784 desc = res[0]["nTSecurityDescriptor"][0]
2785 desc = ndr_unpack(security.descriptor, desc)
2786 desc_sddl = desc.as_sddl(self.domain_sid)
2787 self.assertEqual(desc_sddl, sddl)
2789 delete_force(self.ldb, user_dn)
2791 def test_security_descriptor_add_neg(self):
2792 """Test add_ldif() with BASE64 security descriptor input using WRONG domain SID
2795 user_name = "testdescriptoruser1"
2796 user_dn = "CN=%s,CN=Users,%s" % (user_name, self.base_dn)
2797 delete_force(self.ldb, user_dn)
2799 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2800 desc = security.descriptor.from_sddl(sddl, security.dom_sid('S-1-5-21'))
2801 desc_base64 = base64.b64encode( ndr_pack(desc) )
2802 self.ldb.add_ldif("""
2803 dn: """ + user_dn + """
2805 sAMAccountName: """ + user_name + """
2806 nTSecurityDescriptor:: """ + desc_base64)
2807 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2808 self.assertTrue("nTSecurityDescriptor" in res[0])
2810 delete_force(self.ldb, user_dn)
2812 def test_security_descriptor_modify(self):
2813 """ Testing ldb.modify_ldif() for nTSecurityDescriptor """
2814 user_name = "testdescriptoruser2"
2815 user_dn = "CN=%s,CN=Users,%s" % (user_name, self.base_dn)
2817 # Test an empty security descriptor (naturally this shouldn't work)
2819 delete_force(self.ldb, user_dn)
2820 self.ldb.add({ "dn": user_dn,
2821 "objectClass": "user",
2822 "sAMAccountName": user_name })
2825 m.dn = Dn(ldb, user_dn)
2826 m["nTSecurityDescriptor"] = MessageElement([], FLAG_MOD_ADD,
2827 "nTSecurityDescriptor")
2831 except LdbError, (num, _):
2832 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
2835 m.dn = Dn(ldb, user_dn)
2836 m["nTSecurityDescriptor"] = MessageElement([], FLAG_MOD_REPLACE,
2837 "nTSecurityDescriptor")
2841 except LdbError, (num, _):
2842 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
2845 m.dn = Dn(ldb, user_dn)
2846 m["nTSecurityDescriptor"] = MessageElement([], FLAG_MOD_DELETE,
2847 "nTSecurityDescriptor")
2851 except LdbError, (num, _):
2852 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
2854 delete_force(self.ldb, user_dn)
2856 # Test modify_ldif() with SDDL security descriptor input
2857 # Add ACE to the original descriptor test
2860 self.ldb.add_ldif("""
2861 dn: """ + user_dn + """
2863 sAMAccountName: """ + user_name)
2865 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2866 desc = res[0]["nTSecurityDescriptor"][0]
2867 desc = ndr_unpack(security.descriptor, desc)
2868 desc_sddl = desc.as_sddl(self.domain_sid)
2869 sddl = desc_sddl[:desc_sddl.find("(")] + "(A;;RPWP;;;AU)" + desc_sddl[desc_sddl.find("("):]
2871 dn: """ + user_dn + """
2873 replace: nTSecurityDescriptor
2874 nTSecurityDescriptor: """ + sddl
2875 self.ldb.modify_ldif(mod)
2876 # Read modified descriptor
2877 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2878 desc = res[0]["nTSecurityDescriptor"][0]
2879 desc = ndr_unpack(security.descriptor, desc)
2880 desc_sddl = desc.as_sddl(self.domain_sid)
2881 self.assertEqual(desc_sddl, sddl)
2883 delete_force(self.ldb, user_dn)
2885 # Test modify_ldif() with SDDL security descriptor input
2886 # New desctiptor test
2889 self.ldb.add_ldif("""
2890 dn: """ + user_dn + """
2892 sAMAccountName: """ + user_name)
2894 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2896 dn: """ + user_dn + """
2898 replace: nTSecurityDescriptor
2899 nTSecurityDescriptor: """ + sddl
2900 self.ldb.modify_ldif(mod)
2901 # Read modified descriptor
2902 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2903 desc = res[0]["nTSecurityDescriptor"][0]
2904 desc = ndr_unpack(security.descriptor, desc)
2905 desc_sddl = desc.as_sddl(self.domain_sid)
2906 self.assertEqual(desc_sddl, sddl)
2908 delete_force(self.ldb, user_dn)
2910 # Test modify_ldif() with BASE64 security descriptor input
2911 # Add ACE to the original descriptor test
2914 self.ldb.add_ldif("""
2915 dn: """ + user_dn + """
2917 sAMAccountName: """ + user_name)
2919 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2920 desc = res[0]["nTSecurityDescriptor"][0]
2921 desc = ndr_unpack(security.descriptor, desc)
2922 desc_sddl = desc.as_sddl(self.domain_sid)
2923 sddl = desc_sddl[:desc_sddl.find("(")] + "(A;;RPWP;;;AU)" + desc_sddl[desc_sddl.find("("):]
2924 desc = security.descriptor.from_sddl(sddl, self.domain_sid)
2925 desc_base64 = base64.b64encode(ndr_pack(desc))
2927 dn: """ + user_dn + """
2929 replace: nTSecurityDescriptor
2930 nTSecurityDescriptor:: """ + desc_base64
2931 self.ldb.modify_ldif(mod)
2932 # Read modified descriptor
2933 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2934 desc = res[0]["nTSecurityDescriptor"][0]
2935 desc = ndr_unpack(security.descriptor, desc)
2936 desc_sddl = desc.as_sddl(self.domain_sid)
2937 self.assertEqual(desc_sddl, sddl)
2939 delete_force(self.ldb, user_dn)
2941 # Test modify_ldif() with BASE64 security descriptor input
2942 # New descriptor test
2945 delete_force(self.ldb, user_dn)
2946 self.ldb.add_ldif("""
2947 dn: """ + user_dn + """
2949 sAMAccountName: """ + user_name)
2951 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2952 desc = security.descriptor.from_sddl(sddl, self.domain_sid)
2953 desc_base64 = base64.b64encode(ndr_pack(desc))
2955 dn: """ + user_dn + """
2957 replace: nTSecurityDescriptor
2958 nTSecurityDescriptor:: """ + desc_base64
2959 self.ldb.modify_ldif(mod)
2960 # Read modified descriptor
2961 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2962 desc = res[0]["nTSecurityDescriptor"][0]
2963 desc = ndr_unpack(security.descriptor, desc)
2964 desc_sddl = desc.as_sddl(self.domain_sid)
2965 self.assertEqual(desc_sddl, sddl)
2967 delete_force(self.ldb, user_dn)
2969 def test_dsheuristics(self):
2970 """Tests the 'dSHeuristics' attribute"""
2971 print "Tests the 'dSHeuristics' attribute"
2973 # Get the current value to restore it later
2974 dsheuristics = self.ldb.get_dsheuristics()
2975 # Perform the length checks: for each decade (except the 0th) we need
2976 # the first index to be the number. This goes till the 9th one, beyond
2977 # there does not seem to be another limitation.
2980 for i in range(1,11):
2981 # This is in the range
2982 self.ldb.set_dsheuristics(dshstr + "x")
2983 self.ldb.set_dsheuristics(dshstr + "xxxxx")
2984 dshstr = dshstr + "xxxxxxxxx"
2986 # Not anymore in the range, new decade specifier needed
2988 self.ldb.set_dsheuristics(dshstr + "x")
2990 except LdbError, (num, _):
2991 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
2992 dshstr = dshstr + str(i)
2994 # There does not seem to be an upper limit
2995 self.ldb.set_dsheuristics(dshstr + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
2996 # apart from the above, all char values are accepted
2997 self.ldb.set_dsheuristics("123ABC-+!1asdfg@#^")
2998 self.assertEquals(self.ldb.get_dsheuristics(), "123ABC-+!1asdfg@#^")
3001 self.ldb.set_dsheuristics(dsheuristics)
3003 def test_ldapControlReturn(self):
3004 """Testing that if we request a control that return a control it
3005 really return something"""
3006 res = self.ldb.search(attrs=["cn"],
3007 controls=["paged_results:1:10"])
3008 self.assertEquals(len(res.controls), 1)
3009 self.assertEquals(res.controls[0].oid, "1.2.840.113556.1.4.319")
3010 s = str(res.controls[0])
3012 def test_operational(self):
3013 """Tests operational attributes"""
3014 print "Tests operational attributes"
3016 res = self.ldb.search(self.base_dn, scope=SCOPE_BASE,
3017 attrs=["createTimeStamp", "modifyTimeStamp",
3018 "structuralObjectClass", "whenCreated",
3020 self.assertEquals(len(res), 1)
3021 self.assertTrue("createTimeStamp" in res[0])
3022 self.assertTrue("modifyTimeStamp" in res[0])
3023 self.assertTrue("structuralObjectClass" in res[0])
3024 self.assertTrue("whenCreated" in res[0])
3025 self.assertTrue("whenChanged" in res[0])
3027 class BaseDnTests(samba.tests.TestCase):
3030 super(BaseDnTests, self).setUp()
3033 def test_rootdse_attrs(self):
3034 """Testing for all rootDSE attributes"""
3035 res = self.ldb.search("", scope=SCOPE_BASE, attrs=[])
3036 self.assertEquals(len(res), 1)
3038 def test_highestcommittedusn(self):
3039 """Testing for highestCommittedUSN"""
3040 res = self.ldb.search("", scope=SCOPE_BASE, attrs=["highestCommittedUSN"])
3041 self.assertEquals(len(res), 1)
3042 self.assertTrue(int(res[0]["highestCommittedUSN"][0]) != 0)
3044 def test_netlogon(self):
3045 """Testing for netlogon via LDAP"""
3046 res = self.ldb.search("", scope=SCOPE_BASE, attrs=["netlogon"])
3047 self.assertEquals(len(res), 0)
3049 def test_netlogon_highestcommitted_usn(self):
3050 """Testing for netlogon and highestCommittedUSN via LDAP"""
3051 res = self.ldb.search("", scope=SCOPE_BASE,
3052 attrs=["netlogon", "highestCommittedUSN"])
3053 self.assertEquals(len(res), 0)
3055 def test_namingContexts(self):
3056 """Testing for namingContexts in rootDSE"""
3057 res = self.ldb.search("", scope=SCOPE_BASE,
3058 attrs=["namingContexts", "defaultNamingContext", "schemaNamingContext", "configurationNamingContext"])
3059 self.assertEquals(len(res), 1)
3062 for nc in res[0]["namingContexts"]:
3063 self.assertTrue(nc not in ncs)
3066 self.assertTrue(res[0]["defaultNamingContext"][0] in ncs)
3067 self.assertTrue(res[0]["configurationNamingContext"][0] in ncs)
3068 self.assertTrue(res[0]["schemaNamingContext"][0] in ncs)
3070 def test_serverPath(self):
3071 """Testing the server paths in rootDSE"""
3072 res = self.ldb.search("", scope=SCOPE_BASE,
3073 attrs=["dsServiceName", "serverName"])
3074 self.assertEquals(len(res), 1)
3076 self.assertTrue("CN=Servers" in res[0]["dsServiceName"][0])
3077 self.assertTrue("CN=Sites" in res[0]["dsServiceName"][0])
3078 self.assertTrue("CN=NTDS Settings" in res[0]["dsServiceName"][0])
3079 self.assertTrue("CN=Servers" in res[0]["serverName"][0])
3080 self.assertTrue("CN=Sites" in res[0]["serverName"][0])
3081 self.assertFalse("CN=NTDS Settings" in res[0]["serverName"][0])
3083 def test_functionality(self):
3084 """Testing the server paths in rootDSE"""
3085 res = self.ldb.search("", scope=SCOPE_BASE,
3086 attrs=["forestFunctionality", "domainFunctionality", "domainControllerFunctionality"])
3087 self.assertEquals(len(res), 1)
3088 self.assertEquals(len(res[0]["forestFunctionality"]), 1)
3089 self.assertEquals(len(res[0]["domainFunctionality"]), 1)
3090 self.assertEquals(len(res[0]["domainControllerFunctionality"]), 1)
3092 self.assertTrue(int(res[0]["forestFunctionality"][0]) <= int(res[0]["domainFunctionality"][0]))
3093 self.assertTrue(int(res[0]["domainControllerFunctionality"][0]) >= int(res[0]["domainFunctionality"][0]))
3095 res2 = self.ldb.search("", scope=SCOPE_BASE,
3096 attrs=["dsServiceName", "serverName"])
3097 self.assertEquals(len(res2), 1)
3098 self.assertEquals(len(res2[0]["dsServiceName"]), 1)
3100 res3 = self.ldb.search(res2[0]["dsServiceName"][0], scope=SCOPE_BASE, attrs=["msDS-Behavior-Version"])
3101 self.assertEquals(len(res3), 1)
3102 self.assertEquals(len(res3[0]["msDS-Behavior-Version"]), 1)
3103 self.assertEquals(int(res[0]["domainControllerFunctionality"][0]), int(res3[0]["msDS-Behavior-Version"][0]))
3105 res4 = self.ldb.search(ldb.domain_dn(), scope=SCOPE_BASE, attrs=["msDS-Behavior-Version"])
3106 self.assertEquals(len(res4), 1)
3107 self.assertEquals(len(res4[0]["msDS-Behavior-Version"]), 1)
3108 self.assertEquals(int(res[0]["domainFunctionality"][0]), int(res4[0]["msDS-Behavior-Version"][0]))
3110 res5 = self.ldb.search("cn=partitions,%s" % ldb.get_config_basedn(), scope=SCOPE_BASE, attrs=["msDS-Behavior-Version"])
3111 self.assertEquals(len(res5), 1)
3112 self.assertEquals(len(res5[0]["msDS-Behavior-Version"]), 1)
3113 self.assertEquals(int(res[0]["forestFunctionality"][0]), int(res5[0]["msDS-Behavior-Version"][0]))
3115 def test_dnsHostname(self):
3116 """Testing the DNS hostname in rootDSE"""
3117 res = self.ldb.search("", scope=SCOPE_BASE,
3118 attrs=["dnsHostName", "serverName"])
3119 self.assertEquals(len(res), 1)
3121 res2 = self.ldb.search(res[0]["serverName"][0], scope=SCOPE_BASE,
3122 attrs=["dNSHostName"])
3123 self.assertEquals(len(res2), 1)
3125 self.assertEquals(res[0]["dnsHostName"][0], res2[0]["dNSHostName"][0])
3127 def test_ldapServiceName(self):
3128 """Testing the ldap service name in rootDSE"""
3129 res = self.ldb.search("", scope=SCOPE_BASE,
3130 attrs=["ldapServiceName", "dnsHostName"])
3131 self.assertEquals(len(res), 1)
3132 self.assertTrue("ldapServiceName" in res[0])
3133 self.assertTrue("dnsHostName" in res[0])
3135 (hostname, _, dns_domainname) = res[0]["dnsHostName"][0].partition(".")
3137 given = res[0]["ldapServiceName"][0]
3138 expected = "%s:%s$@%s" % (dns_domainname.lower(), hostname.lower(), dns_domainname.upper())
3139 self.assertEquals(given, expected)
3141 if not "://" in host:
3142 if os.path.isfile(host):
3143 host = "tdb://%s" % host
3145 host = "ldap://%s" % host
3147 ldb = SamDB(host, credentials=creds, session_info=system_session(lp), lp=lp)
3148 if not "tdb://" in host:
3149 gc_ldb = Ldb("%s:3268" % host, credentials=creds,
3150 session_info=system_session(lp), lp=lp)
3154 runner = SubunitTestRunner()
3156 if not runner.run(unittest.makeSuite(BaseDnTests)).wasSuccessful():
3158 if not runner.run(unittest.makeSuite(BasicTests)).wasSuccessful():