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)
738 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
739 "objectClass": "person" })
743 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
744 m["sn"] = MessageElement("", FLAG_MOD_REPLACE, "sn")
748 except LdbError, (num, _):
749 self.assertEquals(num, ERR_INVALID_ATTRIBUTE_SYNTAX)
753 # m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
754 # m["sn"] = MessageElement("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", FLAG_MOD_REPLACE, "sn")
758 # except LdbError, (num, _):
759 # self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
762 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
763 m["sn"] = MessageElement("x", FLAG_MOD_REPLACE, "sn")
766 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
768 def test_empty_messages(self):
769 """Test empty messages"""
770 print "Test empty messages"""
773 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
778 except LdbError, (num, _):
779 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
784 except LdbError, (num, _):
785 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
787 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
789 def test_empty_attributes(self):
790 """Test empty attributes"""
791 print "Test empty attributes"""
794 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
795 m["objectClass"] = MessageElement("group", FLAG_MOD_ADD, "objectClass")
796 m["description"] = MessageElement([], FLAG_MOD_ADD, "description")
801 except LdbError, (num, _):
802 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
805 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
806 "objectclass": "group"})
809 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
810 m["description"] = MessageElement([], FLAG_MOD_ADD, "description")
815 except LdbError, (num, _):
816 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
819 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
820 m["description"] = MessageElement([], FLAG_MOD_REPLACE, "description")
824 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
825 m["description"] = MessageElement([], FLAG_MOD_DELETE, "description")
829 except LdbError, (num, _):
830 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
832 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
834 def test_instanceType(self):
835 """Tests the 'instanceType' attribute"""
836 print "Tests the 'instanceType' attribute"
838 # The instance type is single-valued
841 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
842 "objectclass": "group",
843 "instanceType": ["0", "1"]})
845 except LdbError, (num, _):
846 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
848 # The head NC flag cannot be set without the write flag
851 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
852 "objectclass": "group",
853 "instanceType": "1" })
855 except LdbError, (num, _):
856 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
858 # We cannot manipulate NCs without the head NC flag
861 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
862 "objectclass": "group",
863 "instanceType": "32" })
865 except LdbError, (num, _):
866 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
869 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
870 "objectclass": "group"})
873 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
874 m["instanceType"] = MessageElement("0", FLAG_MOD_REPLACE,
879 except LdbError, (num, _):
880 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
883 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
884 m["instanceType"] = MessageElement([], FLAG_MOD_REPLACE,
889 except LdbError, (num, _):
890 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
893 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
894 m["instanceType"] = MessageElement([], FLAG_MOD_DELETE, "instanceType")
898 except LdbError, (num, _):
899 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
901 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
903 def test_distinguished_name(self):
904 """Tests the 'distinguishedName' attribute"""
905 print "Tests the 'distinguishedName' attribute"
907 # The "dn" shortcut isn't supported
909 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
910 m["objectClass"] = MessageElement("group", 0, "objectClass")
911 m["dn"] = MessageElement("cn=ldaptestgroup,cn=users," + self.base_dn, 0,
916 except LdbError, (num, _):
917 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
919 # a wrong "distinguishedName" attribute is obviously tolerated
921 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
922 "objectclass": "group",
923 "distinguishedName": "cn=ldaptest,cn=users," + self.base_dn})
925 # proof if the DN has been set correctly
926 res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
927 scope=SCOPE_BASE, attrs=["distinguishedName"])
928 self.assertTrue(len(res) == 1)
929 self.assertTrue("distinguishedName" in res[0])
930 self.assertTrue(Dn(ldb, res[0]["distinguishedName"][0])
931 == Dn(ldb, "cn=ldaptestgroup, cn=users," + self.base_dn))
933 # The "dn" shortcut isn't supported
935 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
936 m["dn"] = MessageElement(
937 "cn=ldaptestgroup,cn=users," + self.base_dn, FLAG_MOD_REPLACE,
942 except LdbError, (num, _):
943 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
946 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
947 m["distinguishedName"] = MessageElement(
948 "cn=ldaptestuser,cn=users," + self.base_dn, FLAG_MOD_ADD,
954 except LdbError, (num, _):
955 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
958 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
959 m["distinguishedName"] = MessageElement(
960 "cn=ldaptestuser,cn=users," + self.base_dn, FLAG_MOD_REPLACE,
966 except LdbError, (num, _):
967 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
970 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
971 m["distinguishedName"] = MessageElement(
972 "cn=ldaptestuser,cn=users," + self.base_dn, FLAG_MOD_DELETE,
978 except LdbError, (num, _):
979 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
981 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
983 def test_rdn_name(self):
985 print "Tests the RDN"
991 self.ldb.search("=,cn=users," + self.base_dn, scope=SCOPE_BASE)
993 except LdbError, (num, _):
994 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
998 self.ldb.search("cn=,cn=users," + self.base_dn, scope=SCOPE_BASE)
1000 except LdbError, (num, _):
1001 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1004 self.ldb.search("=ldaptestgroup,cn=users," + self.base_dn, scope=SCOPE_BASE)
1006 except LdbError, (num, _):
1007 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1014 "dn": "=,cn=users," + self.base_dn,
1015 "objectclass": "group"})
1017 except LdbError, (num, _):
1018 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1023 "dn": "=ldaptestgroup,cn=users," + self.base_dn,
1024 "objectclass": "group"})
1026 except LdbError, (num, _):
1027 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1032 "dn": "cn=,cn=users," + self.base_dn,
1033 "objectclass": "group"})
1035 except LdbError, (num, _):
1036 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1038 # a wrong RDN candidate
1041 "dn": "description=xyz,cn=users," + self.base_dn,
1042 "objectclass": "group"})
1044 except LdbError, (num, _):
1045 self.assertEquals(num, ERR_NAMING_VIOLATION)
1047 delete_force(self.ldb, "description=xyz,cn=users," + self.base_dn)
1049 # a wrong "name" attribute is obviously tolerated
1051 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
1052 "objectclass": "group",
1053 "name": "ldaptestgroupx"})
1055 # proof if the name has been set correctly
1056 res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
1057 scope=SCOPE_BASE, attrs=["name"])
1058 self.assertTrue(len(res) == 1)
1059 self.assertTrue("name" in res[0])
1060 self.assertTrue(res[0]["name"][0] == "ldaptestgroup")
1066 m.dn = Dn(ldb, "cn=,cn=users," + self.base_dn)
1067 m["description"] = "test"
1071 except LdbError, (num, _):
1072 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1078 self.ldb.delete("cn=,cn=users," + self.base_dn)
1080 except LdbError, (num, _):
1081 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1087 self.ldb.rename("cn=ldaptestgroup,cn=users," + self.base_dn,
1088 "=,cn=users," + self.base_dn)
1090 except LdbError, (num, _):
1091 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1093 # new empty RDN name
1095 self.ldb.rename("cn=ldaptestgroup,cn=users," + self.base_dn,
1096 "=ldaptestgroup,cn=users," + self.base_dn)
1098 except LdbError, (num, _):
1099 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1101 # new empty RDN value
1103 self.ldb.rename("cn=ldaptestgroup,cn=users," + self.base_dn,
1104 "cn=,cn=users," + self.base_dn)
1106 except LdbError, (num, _):
1107 self.assertEquals(num, ERR_NAMING_VIOLATION)
1109 # new wrong RDN candidate
1111 self.ldb.rename("cn=ldaptestgroup,cn=users," + self.base_dn,
1112 "description=xyz,cn=users," + self.base_dn)
1114 except LdbError, (num, _):
1115 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1117 delete_force(self.ldb, "description=xyz,cn=users," + self.base_dn)
1119 # old empty RDN value
1121 self.ldb.rename("cn=,cn=users," + self.base_dn,
1122 "cn=ldaptestgroup,cn=users," + self.base_dn)
1124 except LdbError, (num, _):
1125 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1130 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1131 m["name"] = MessageElement("cn=ldaptestuser", FLAG_MOD_REPLACE,
1136 except LdbError, (num, _):
1137 self.assertEquals(num, ERR_NOT_ALLOWED_ON_RDN)
1140 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1141 m["cn"] = MessageElement("ldaptestuser",
1142 FLAG_MOD_REPLACE, "cn")
1146 except LdbError, (num, _):
1147 self.assertEquals(num, ERR_NOT_ALLOWED_ON_RDN)
1149 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1152 # this test needs to be disabled until we really understand
1153 # what the rDN length constraints are
1154 def DISABLED_test_largeRDN(self):
1155 """Testing large rDN (limit 64 characters)"""
1156 rdn = "CN=a012345678901234567890123456789012345678901234567890123456789012";
1157 delete_force(self.ldb, "%s,%s" % (rdn, self.base_dn))
1159 dn: %s,%s""" % (rdn,self.base_dn) + """
1160 objectClass: container
1162 self.ldb.add_ldif(ldif)
1163 delete_force(self.ldb, "%s,%s" % (rdn, self.base_dn))
1165 rdn = "CN=a0123456789012345678901234567890123456789012345678901234567890120";
1166 delete_force(self.ldb, "%s,%s" % (rdn, self.base_dn))
1169 dn: %s,%s""" % (rdn,self.base_dn) + """
1170 objectClass: container
1172 self.ldb.add_ldif(ldif)
1174 except LdbError, (num, _):
1175 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
1176 delete_force(self.ldb, "%s,%s" % (rdn, self.base_dn))
1178 def test_rename(self):
1179 """Tests the rename operation"""
1180 print "Tests the rename operations"
1183 # cannot rename to be a child of itself
1184 ldb.rename(self.base_dn, "dc=test," + self.base_dn)
1186 except LdbError, (num, _):
1187 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1191 ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser2,cn=users," + self.base_dn)
1193 except LdbError, (num, _):
1194 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
1197 "dn": "cn=ldaptestuser2,cn=users," + self.base_dn,
1198 "objectclass": "user" })
1200 ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser2,cn=users," + self.base_dn)
1201 ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=users," + self.base_dn)
1202 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestUSER3,cn=users," + self.base_dn)
1205 # containment problem: a user entry cannot contain user entries
1206 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser4,cn=ldaptestuser3,cn=users," + self.base_dn)
1208 except LdbError, (num, _):
1209 self.assertEquals(num, ERR_NAMING_VIOLATION)
1213 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=people,cn=users," + self.base_dn)
1215 except LdbError, (num, _):
1216 self.assertEquals(num, ERR_OTHER)
1219 # invalid target DN syntax
1220 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, ",cn=users," + self.base_dn)
1222 except LdbError, (num, _):
1223 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1227 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "ou=ldaptestuser3,cn=users," + self.base_dn)
1229 except LdbError, (num, _):
1230 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1232 delete_force(self.ldb, "cn=ldaptestuser3,cn=users," + self.base_dn)
1234 # Performs some "systemFlags" testing
1236 # Move failing since no "SYSTEM_FLAG_CONFIG_ALLOW_MOVE"
1238 ldb.rename("CN=DisplaySpecifiers," + self.configuration_dn, "CN=DisplaySpecifiers,CN=Services," + self.configuration_dn)
1240 except LdbError, (num, _):
1241 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1243 # Limited move failing since no "SYSTEM_FLAG_CONFIG_ALLOW_LIMITED_MOVE"
1245 ldb.rename("CN=Directory Service,CN=Windows NT,CN=Services," + self.configuration_dn, "CN=Directory Service,CN=RRAS,CN=Services," + self.configuration_dn)
1247 except LdbError, (num, _):
1248 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1250 # Rename failing since no "SYSTEM_FLAG_CONFIG_ALLOW_RENAME"
1252 ldb.rename("CN=DisplaySpecifiers," + self.configuration_dn, "CN=DisplaySpecifiers2," + self.configuration_dn)
1254 except LdbError, (num, _):
1255 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1257 # It's not really possible to test moves on the schema partition since
1258 # there don't exist subcontainers on it.
1260 # Rename failing since "SYSTEM_FLAG_SCHEMA_BASE_OBJECT"
1262 ldb.rename("CN=Top," + self.schema_dn, "CN=Top2," + self.schema_dn)
1264 except LdbError, (num, _):
1265 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1267 # Move failing since "SYSTEM_FLAG_DOMAIN_DISALLOW_MOVE"
1269 ldb.rename("CN=Users," + self.base_dn, "CN=Users,CN=Computers," + self.base_dn)
1271 except LdbError, (num, _):
1272 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1274 # Rename failing since "SYSTEM_FLAG_DOMAIN_DISALLOW_RENAME"
1276 ldb.rename("CN=Users," + self.base_dn, "CN=Users2," + self.base_dn)
1278 except LdbError, (num, _):
1279 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1281 # Performs some other constraints testing
1284 ldb.rename("CN=Policies,CN=System," + self.base_dn, "CN=Users2," + self.base_dn)
1286 except LdbError, (num, _):
1287 self.assertEquals(num, ERR_OTHER)
1289 def test_rename_twice(self):
1290 """Tests the rename operation twice - this corresponds to a past bug"""
1291 print "Tests the rename twice operation"
1294 "dn": "cn=ldaptestuser5,cn=users," + self.base_dn,
1295 "objectclass": "user" })
1297 ldb.rename("cn=ldaptestuser5,cn=users," + self.base_dn, "cn=ldaptestUSER5,cn=users," + self.base_dn)
1298 delete_force(self.ldb, "cn=ldaptestuser5,cn=users," + self.base_dn)
1300 "dn": "cn=ldaptestuser5,cn=users," + self.base_dn,
1301 "objectclass": "user" })
1302 ldb.rename("cn=ldaptestuser5,cn=Users," + self.base_dn, "cn=ldaptestUSER5,cn=users," + self.base_dn)
1303 res = ldb.search(expression="cn=ldaptestuser5")
1304 print "Found %u records" % len(res)
1305 self.assertEquals(len(res), 1, "Wrong number of hits for cn=ldaptestuser5")
1306 res = ldb.search(expression="(&(cn=ldaptestuser5)(objectclass=user))")
1307 print "Found %u records" % len(res)
1308 self.assertEquals(len(res), 1, "Wrong number of hits for (&(cn=ldaptestuser5)(objectclass=user))")
1309 delete_force(self.ldb, "cn=ldaptestuser5,cn=users," + self.base_dn)
1311 def test_objectGUID(self):
1312 """Test objectGUID behaviour"""
1313 print "Testing objectGUID behaviour\n"
1315 # The objectGUID cannot directly be set
1317 self.ldb.add_ldif("""
1318 dn: cn=ldaptestcontainer,""" + self.base_dn + """
1319 objectClass: container
1320 objectGUID: bd3480c9-58af-4cd8-92df-bc4a18b6e44d
1323 except LdbError, (num, _):
1324 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1327 "dn": "cn=ldaptestcontainer," + self.base_dn,
1328 "objectClass": "container" })
1330 # The objectGUID cannot directly be changed
1332 self.ldb.modify_ldif("""
1333 dn: cn=ldaptestcontainer,""" + self.base_dn + """
1336 objectGUID: bd3480c9-58af-4cd8-92df-bc4a18b6e44d
1339 except LdbError, (num, _):
1340 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
1342 delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
1344 def test_parentGUID(self):
1345 """Test parentGUID behaviour"""
1346 print "Testing parentGUID behaviour\n"
1349 "dn": "cn=parentguidtest,cn=users," + self.base_dn,
1350 "objectclass":"user",
1351 "samaccountname":"parentguidtest"});
1352 res1 = ldb.search(base="cn=parentguidtest,cn=users," + self.base_dn, scope=SCOPE_BASE,
1353 attrs=["parentGUID", "samaccountname"]);
1354 res2 = ldb.search(base="cn=users," + self.base_dn,scope=SCOPE_BASE,
1355 attrs=["objectGUID"]);
1356 res3 = ldb.search(base=self.base_dn, scope=SCOPE_BASE,
1357 attrs=["parentGUID"]);
1358 res4 = ldb.search(base=self.configuration_dn, scope=SCOPE_BASE,
1359 attrs=["parentGUID"]);
1360 res5 = ldb.search(base=self.schema_dn, scope=SCOPE_BASE,
1361 attrs=["parentGUID"]);
1363 """Check if the parentGUID is valid """
1364 self.assertEquals(res1[0]["parentGUID"], res2[0]["objectGUID"]);
1366 """Check if it returns nothing when there is no parent object - default NC"""
1367 has_parentGUID = False
1368 for key in res3[0].keys():
1369 if key == "parentGUID":
1370 has_parentGUID = True
1372 self.assertFalse(has_parentGUID);
1374 """Check if it returns nothing when there is no parent object - configuration NC"""
1375 has_parentGUID = False
1376 for key in res4[0].keys():
1377 if key == "parentGUID":
1378 has_parentGUID = True
1380 self.assertFalse(has_parentGUID);
1382 """Check if it returns nothing when there is no parent object - schema NC"""
1383 has_parentGUID = False
1384 for key in res5[0].keys():
1385 if key == "parentGUID":
1386 has_parentGUID = True
1388 self.assertFalse(has_parentGUID);
1390 """Ensures that if you look for another object attribute after the constructed
1391 parentGUID, it will return correctly"""
1392 has_another_attribute = False
1393 for key in res1[0].keys():
1394 if key == "sAMAccountName":
1395 has_another_attribute = True
1397 self.assertTrue(has_another_attribute)
1398 self.assertTrue(len(res1[0]["samaccountname"]) == 1)
1399 self.assertEquals(res1[0]["samaccountname"][0], "parentguidtest");
1401 print "Testing parentGUID behaviour on rename\n"
1404 "dn": "cn=testotherusers," + self.base_dn,
1405 "objectclass":"container"});
1406 res1 = ldb.search(base="cn=testotherusers," + self.base_dn,scope=SCOPE_BASE,
1407 attrs=["objectGUID"]);
1408 ldb.rename("cn=parentguidtest,cn=users," + self.base_dn,
1409 "cn=parentguidtest,cn=testotherusers," + self.base_dn);
1410 res2 = ldb.search(base="cn=parentguidtest,cn=testotherusers," + self.base_dn,
1412 attrs=["parentGUID"]);
1413 self.assertEquals(res1[0]["objectGUID"], res2[0]["parentGUID"]);
1415 delete_force(self.ldb, "cn=parentguidtest,cn=testotherusers," + self.base_dn)
1416 delete_force(self.ldb, "cn=testotherusers," + self.base_dn)
1418 def test_usnChanged(self):
1419 """Test usnChanged behaviour"""
1420 print "Testing usnChanged behaviour\n"
1423 "dn": "cn=ldaptestcontainer," + self.base_dn,
1424 "objectClass": "container" })
1426 res = ldb.search("cn=ldaptestcontainer," + self.base_dn,
1428 attrs=["objectGUID", "uSNCreated", "uSNChanged", "whenCreated", "whenChanged", "description"])
1429 self.assertTrue(len(res) == 1)
1430 self.assertFalse("description" in res[0])
1431 self.assertTrue("objectGUID" in res[0])
1432 self.assertTrue("uSNCreated" in res[0])
1433 self.assertTrue("uSNChanged" in res[0])
1434 self.assertTrue("whenCreated" in res[0])
1435 self.assertTrue("whenChanged" in res[0])
1437 delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
1439 # All this attributes are specificable on add operations
1441 "dn": "cn=ldaptestcontainer," + self.base_dn,
1442 "objectclass": "container",
1445 "whenCreated": timestring(long(time.time())),
1446 "whenChanged": timestring(long(time.time())) })
1448 res = ldb.search("cn=ldaptestcontainer," + self.base_dn,
1450 attrs=["objectGUID", "uSNCreated", "uSNChanged", "whenCreated", "whenChanged", "description"])
1451 self.assertTrue(len(res) == 1)
1452 self.assertFalse("description" in res[0])
1453 self.assertTrue("objectGUID" in res[0])
1454 self.assertTrue("uSNCreated" in res[0])
1455 self.assertFalse(res[0]["uSNCreated"][0] == "1") # these are corrected
1456 self.assertTrue("uSNChanged" in res[0])
1457 self.assertFalse(res[0]["uSNChanged"][0] == "1") # these are corrected
1458 self.assertTrue("whenCreated" in res[0])
1459 self.assertTrue("whenChanged" in res[0])
1462 dn: cn=ldaptestcontainer,""" + self.base_dn + """
1464 replace: description
1467 res2 = ldb.search("cn=ldaptestcontainer," + self.base_dn,
1469 attrs=["uSNCreated", "uSNChanged", "description"])
1470 self.assertTrue(len(res) == 1)
1471 self.assertFalse("description" in res2[0])
1472 self.assertEqual(res[0]["usnCreated"], res2[0]["usnCreated"])
1473 self.assertEqual(res[0]["usnCreated"], res2[0]["usnChanged"])
1474 self.assertEqual(res[0]["usnChanged"], res2[0]["usnChanged"])
1477 dn: cn=ldaptestcontainer,""" + self.base_dn + """
1479 replace: description
1483 res3 = ldb.search("cn=ldaptestcontainer," + self.base_dn,
1485 attrs=["uSNCreated", "uSNChanged", "description"])
1486 self.assertTrue(len(res) == 1)
1487 self.assertTrue("description" in res3[0])
1488 self.assertEqual("test", str(res3[0]["description"][0]))
1489 self.assertEqual(res[0]["usnCreated"], res3[0]["usnCreated"])
1490 self.assertNotEqual(res[0]["usnCreated"], res3[0]["usnChanged"])
1491 self.assertNotEqual(res[0]["usnChanged"], res3[0]["usnChanged"])
1494 dn: cn=ldaptestcontainer,""" + self.base_dn + """
1496 replace: description
1500 res4 = ldb.search("cn=ldaptestcontainer," + self.base_dn,
1502 attrs=["uSNCreated", "uSNChanged", "description"])
1503 self.assertTrue(len(res) == 1)
1504 self.assertTrue("description" in res4[0])
1505 self.assertEqual("test", str(res4[0]["description"][0]))
1506 self.assertEqual(res[0]["usnCreated"], res4[0]["usnCreated"])
1507 self.assertNotEqual(res3[0]["usnCreated"], res4[0]["usnChanged"])
1508 self.assertEqual(res3[0]["usnChanged"], res4[0]["usnChanged"])
1511 dn: cn=ldaptestcontainer,""" + self.base_dn + """
1513 replace: description
1517 res5 = ldb.search("cn=ldaptestcontainer," + self.base_dn,
1519 attrs=["uSNCreated", "uSNChanged", "description"])
1520 self.assertTrue(len(res) == 1)
1521 self.assertTrue("description" in res5[0])
1522 self.assertEqual("test2", str(res5[0]["description"][0]))
1523 self.assertEqual(res[0]["usnCreated"], res5[0]["usnCreated"])
1524 self.assertNotEqual(res3[0]["usnChanged"], res5[0]["usnChanged"])
1527 dn: cn=ldaptestcontainer,""" + self.base_dn + """
1533 res6 = ldb.search("cn=ldaptestcontainer," + self.base_dn,
1535 attrs=["uSNCreated", "uSNChanged", "description"])
1536 self.assertTrue(len(res) == 1)
1537 self.assertFalse("description" in res6[0])
1538 self.assertEqual(res[0]["usnCreated"], res6[0]["usnCreated"])
1539 self.assertNotEqual(res5[0]["usnChanged"], res6[0]["usnChanged"])
1542 dn: cn=ldaptestcontainer,""" + self.base_dn + """
1548 res7 = ldb.search("cn=ldaptestcontainer," + self.base_dn,
1550 attrs=["uSNCreated", "uSNChanged", "description"])
1551 self.assertTrue(len(res) == 1)
1552 self.assertTrue("description" in res7[0])
1553 self.assertEqual("test3", str(res7[0]["description"][0]))
1554 self.assertEqual(res[0]["usnCreated"], res7[0]["usnCreated"])
1555 self.assertNotEqual(res6[0]["usnChanged"], res7[0]["usnChanged"])
1558 dn: cn=ldaptestcontainer,""" + self.base_dn + """
1563 res8 = ldb.search("cn=ldaptestcontainer," + self.base_dn,
1565 attrs=["uSNCreated", "uSNChanged", "description"])
1566 self.assertTrue(len(res) == 1)
1567 self.assertFalse("description" in res8[0])
1568 self.assertEqual(res[0]["usnCreated"], res8[0]["usnCreated"])
1569 self.assertNotEqual(res7[0]["usnChanged"], res8[0]["usnChanged"])
1571 delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
1573 def test_groupType_int32(self):
1574 """Test groupType (int32) behaviour (should appear to be casted to a 32 bit signed integer before comparsion)"""
1575 print "Testing groupType (int32) behaviour\n"
1577 res1 = ldb.search(base=self.base_dn, scope=SCOPE_SUBTREE,
1578 attrs=["groupType"], expression="groupType=2147483653");
1580 res2 = ldb.search(base=self.base_dn, scope=SCOPE_SUBTREE,
1581 attrs=["groupType"], expression="groupType=-2147483643");
1583 self.assertEquals(len(res1), len(res2))
1585 self.assertTrue(res1.count > 0)
1587 self.assertEquals(res1[0]["groupType"][0], "-2147483643")
1589 def test_linked_attributes(self):
1590 """This tests the linked attribute behaviour"""
1591 print "Testing linked attribute behaviour\n"
1594 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
1595 "objectclass": "group"})
1597 # This should not work since "memberOf" is linked to "member"
1600 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1601 "objectclass": "user",
1602 "memberOf": "cn=ldaptestgroup,cn=users," + self.base_dn})
1603 except LdbError, (num, _):
1604 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1607 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1608 "objectclass": "user"})
1611 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1612 m["memberOf"] = MessageElement("cn=ldaptestgroup,cn=users," + self.base_dn,
1613 FLAG_MOD_ADD, "memberOf")
1617 except LdbError, (num, _):
1618 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1621 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1622 m["member"] = MessageElement("cn=ldaptestuser,cn=users," + self.base_dn,
1623 FLAG_MOD_ADD, "member")
1627 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1628 m["memberOf"] = MessageElement("cn=ldaptestgroup,cn=users," + self.base_dn,
1629 FLAG_MOD_REPLACE, "memberOf")
1633 except LdbError, (num, _):
1634 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1637 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1638 m["memberOf"] = MessageElement("cn=ldaptestgroup,cn=users," + self.base_dn,
1639 FLAG_MOD_DELETE, "memberOf")
1643 except LdbError, (num, _):
1644 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1647 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1648 m["member"] = MessageElement("cn=ldaptestuser,cn=users," + self.base_dn,
1649 FLAG_MOD_DELETE, "member")
1652 # This should yield no results since the member attribute for
1653 # "ldaptestuser" should have been deleted
1654 res1 = ldb.search("cn=ldaptestgroup, cn=users," + self.base_dn,
1656 expression="(member=cn=ldaptestuser,cn=users," + self.base_dn + ")",
1658 self.assertTrue(len(res1) == 0)
1660 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1663 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
1664 "objectclass": "group",
1665 "member": "cn=ldaptestuser,cn=users," + self.base_dn})
1667 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1669 # Make sure that the "member" attribute for "ldaptestuser" has been
1671 res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
1672 scope=SCOPE_BASE, attrs=["member"])
1673 self.assertTrue(len(res) == 1)
1674 self.assertFalse("member" in res[0])
1676 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1678 def test_wkguid(self):
1679 """Test Well known GUID behaviours (including DN+Binary)"""
1680 print "Test Well known GUID behaviours (including DN+Binary)"
1682 res = self.ldb.search(base=("<WKGUID=ab1d30f3768811d1aded00c04fd8d5cd,%s>" % self.base_dn), scope=SCOPE_BASE, attrs=[])
1683 self.assertEquals(len(res), 1)
1685 res2 = self.ldb.search(scope=SCOPE_BASE, attrs=["wellKnownObjects"], expression=("wellKnownObjects=B:32:ab1d30f3768811d1aded00c04fd8d5cd:%s" % res[0].dn))
1686 self.assertEquals(len(res2), 1)
1688 # Prove that the matching rule is over the whole DN+Binary
1689 res2 = self.ldb.search(scope=SCOPE_BASE, attrs=["wellKnownObjects"], expression=("wellKnownObjects=B:32:ab1d30f3768811d1aded00c04fd8d5cd"))
1690 self.assertEquals(len(res2), 0)
1691 # Prove that the matching rule is over the whole DN+Binary
1692 res2 = self.ldb.search(scope=SCOPE_BASE, attrs=["wellKnownObjects"], expression=("wellKnownObjects=%s") % res[0].dn)
1693 self.assertEquals(len(res2), 0)
1695 def test_subschemasubentry(self):
1696 """Test subSchemaSubEntry appears when requested, but not when not requested"""
1697 print "Test subSchemaSubEntry"
1699 res = self.ldb.search(base=self.base_dn, scope=SCOPE_BASE, attrs=["subSchemaSubEntry"])
1700 self.assertEquals(len(res), 1)
1701 self.assertEquals(res[0]["subSchemaSubEntry"][0], "CN=Aggregate,"+self.schema_dn)
1703 res = self.ldb.search(base=self.base_dn, scope=SCOPE_BASE, attrs=["*"])
1704 self.assertEquals(len(res), 1)
1705 self.assertTrue("subScheamSubEntry" not in res[0])
1710 print "Testing user add"
1713 "dn": "cn=ldaptestuser,cn=uSers," + self.base_dn,
1714 "objectclass": "user",
1715 "cN": "LDAPtestUSER",
1716 "givenname": "ldap",
1720 "dn": "cn=ldaptestgroup,cn=uSers," + self.base_dn,
1721 "objectclass": "group",
1722 "member": "cn=ldaptestuser,cn=useRs," + self.base_dn})
1725 "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
1726 "objectclass": "computer",
1727 "cN": "LDAPtestCOMPUTER"})
1729 ldb.add({"dn": "cn=ldaptest2computer,cn=computers," + self.base_dn,
1730 "objectClass": "computer",
1731 "cn": "LDAPtest2COMPUTER",
1732 "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT),
1733 "displayname": "ldap testy"})
1736 ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn,
1737 "objectClass": "computer",
1738 "cn": "LDAPtest2COMPUTER"
1741 except LdbError, (num, _):
1742 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1745 ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn,
1746 "objectClass": "computer",
1747 "cn": "ldaptestcomputer3",
1748 "sAMAccountType": str(ATYPE_NORMAL_ACCOUNT)
1751 except LdbError, (num, _):
1752 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1754 ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn,
1755 "objectClass": "computer",
1756 "cn": "LDAPtestCOMPUTER3"
1759 print "Testing ldb.search for (&(cn=ldaptestcomputer3)(objectClass=user))";
1760 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestcomputer3)(objectClass=user))");
1761 self.assertEquals(len(res), 1, "Found only %d for (&(cn=ldaptestcomputer3)(objectClass=user))" % len(res))
1763 self.assertEquals(str(res[0].dn), ("CN=ldaptestcomputer3,CN=Computers," + self.base_dn));
1764 self.assertEquals(res[0]["cn"][0], "ldaptestcomputer3");
1765 self.assertEquals(res[0]["name"][0], "ldaptestcomputer3");
1766 self.assertEquals(res[0]["objectClass"][0], "top");
1767 self.assertEquals(res[0]["objectClass"][1], "person");
1768 self.assertEquals(res[0]["objectClass"][2], "organizationalPerson");
1769 self.assertEquals(res[0]["objectClass"][3], "user");
1770 self.assertEquals(res[0]["objectClass"][4], "computer");
1771 self.assertTrue("objectGUID" in res[0])
1772 self.assertTrue("whenCreated" in res[0])
1773 self.assertEquals(res[0]["objectCategory"][0], ("CN=Computer,%s" % ldb.get_schema_basedn()))
1774 self.assertEquals(int(res[0]["primaryGroupID"][0]), 513);
1775 self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_NORMAL_ACCOUNT);
1776 self.assertEquals(int(res[0]["userAccountControl"][0]), UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE);
1778 delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
1780 print "Testing attribute or value exists behaviour"
1783 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1785 replace: servicePrincipalName
1786 servicePrincipalName: host/ldaptest2computer
1787 servicePrincipalName: host/ldaptest2computer
1788 servicePrincipalName: cifs/ldaptest2computer
1791 except LdbError, (num, msg):
1792 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
1795 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1797 replace: servicePrincipalName
1798 servicePrincipalName: host/ldaptest2computer
1799 servicePrincipalName: cifs/ldaptest2computer
1803 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1805 add: servicePrincipalName
1806 servicePrincipalName: host/ldaptest2computer
1809 except LdbError, (num, msg):
1810 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
1812 print "Testing ranged results"
1814 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1816 replace: servicePrincipalName
1820 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1822 add: servicePrincipalName
1823 servicePrincipalName: host/ldaptest2computer0
1824 servicePrincipalName: host/ldaptest2computer1
1825 servicePrincipalName: host/ldaptest2computer2
1826 servicePrincipalName: host/ldaptest2computer3
1827 servicePrincipalName: host/ldaptest2computer4
1828 servicePrincipalName: host/ldaptest2computer5
1829 servicePrincipalName: host/ldaptest2computer6
1830 servicePrincipalName: host/ldaptest2computer7
1831 servicePrincipalName: host/ldaptest2computer8
1832 servicePrincipalName: host/ldaptest2computer9
1833 servicePrincipalName: host/ldaptest2computer10
1834 servicePrincipalName: host/ldaptest2computer11
1835 servicePrincipalName: host/ldaptest2computer12
1836 servicePrincipalName: host/ldaptest2computer13
1837 servicePrincipalName: host/ldaptest2computer14
1838 servicePrincipalName: host/ldaptest2computer15
1839 servicePrincipalName: host/ldaptest2computer16
1840 servicePrincipalName: host/ldaptest2computer17
1841 servicePrincipalName: host/ldaptest2computer18
1842 servicePrincipalName: host/ldaptest2computer19
1843 servicePrincipalName: host/ldaptest2computer20
1844 servicePrincipalName: host/ldaptest2computer21
1845 servicePrincipalName: host/ldaptest2computer22
1846 servicePrincipalName: host/ldaptest2computer23
1847 servicePrincipalName: host/ldaptest2computer24
1848 servicePrincipalName: host/ldaptest2computer25
1849 servicePrincipalName: host/ldaptest2computer26
1850 servicePrincipalName: host/ldaptest2computer27
1851 servicePrincipalName: host/ldaptest2computer28
1852 servicePrincipalName: host/ldaptest2computer29
1855 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE,
1856 attrs=["servicePrincipalName;range=0-*"])
1857 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1858 #print len(res[0]["servicePrincipalName;range=0-*"])
1859 self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30)
1861 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-19"])
1862 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1863 # print res[0]["servicePrincipalName;range=0-19"].length
1864 self.assertEquals(len(res[0]["servicePrincipalName;range=0-19"]), 20)
1867 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-30"])
1868 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1869 self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30)
1871 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-40"])
1872 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1873 self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30)
1875 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=30-40"])
1876 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1877 self.assertEquals(len(res[0]["servicePrincipalName;range=30-*"]), 0)
1880 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=10-40"])
1881 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1882 self.assertEquals(len(res[0]["servicePrincipalName;range=10-*"]), 20)
1883 # pos_11 = res[0]["servicePrincipalName;range=10-*"][18]
1885 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=11-40"])
1886 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1887 self.assertEquals(len(res[0]["servicePrincipalName;range=11-*"]), 19)
1888 # print res[0]["servicePrincipalName;range=11-*"][18]
1890 # self.assertEquals((res[0]["servicePrincipalName;range=11-*"][18]), pos_11)
1892 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=11-15"])
1893 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1894 self.assertEquals(len(res[0]["servicePrincipalName;range=11-15"]), 5)
1895 # self.assertEquals(res[0]["servicePrincipalName;range=11-15"][4], pos_11)
1897 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName"])
1898 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1899 # print res[0]["servicePrincipalName"][18]
1901 self.assertEquals(len(res[0]["servicePrincipalName"]), 30)
1902 # self.assertEquals(res[0]["servicePrincipalName"][18], pos_11)
1904 delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
1906 "dn": "cn=ldaptestuser2,cn=useRs," + self.base_dn,
1907 "objectClass": "user",
1908 "cn": "LDAPtestUSER2",
1909 "givenname": "testy",
1910 "sn": "ldap user2"})
1912 print "Testing Ambigious Name Resolution"
1913 # Testing ldb.search for (&(anr=ldap testy)(objectClass=user))
1914 res = ldb.search(expression="(&(anr=ldap testy)(objectClass=user))")
1915 self.assertEquals(len(res), 3, "Found only %d of 3 for (&(anr=ldap testy)(objectClass=user))" % len(res))
1917 # Testing ldb.search for (&(anr=testy ldap)(objectClass=user))
1918 res = ldb.search(expression="(&(anr=testy ldap)(objectClass=user))")
1919 self.assertEquals(len(res), 2, "Found only %d of 2 for (&(anr=testy ldap)(objectClass=user))" % len(res))
1921 # Testing ldb.search for (&(anr=ldap)(objectClass=user))
1922 res = ldb.search(expression="(&(anr=ldap)(objectClass=user))")
1923 self.assertEquals(len(res), 4, "Found only %d of 4 for (&(anr=ldap)(objectClass=user))" % len(res))
1925 # Testing ldb.search for (&(anr==ldap)(objectClass=user))
1926 res = ldb.search(expression="(&(anr==ldap)(objectClass=user))")
1927 self.assertEquals(len(res), 1, "Could not find (&(anr==ldap)(objectClass=user)). Found only %d for (&(anr=ldap)(objectClass=user))" % len(res))
1929 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
1930 self.assertEquals(res[0]["cn"][0], "ldaptestuser")
1931 self.assertEquals(str(res[0]["name"]), "ldaptestuser")
1933 # Testing ldb.search for (&(anr=testy)(objectClass=user))
1934 res = ldb.search(expression="(&(anr=testy)(objectClass=user))")
1935 self.assertEquals(len(res), 2, "Found only %d for (&(anr=testy)(objectClass=user))" % len(res))
1937 # Testing ldb.search for (&(anr=testy ldap)(objectClass=user))
1938 res = ldb.search(expression="(&(anr=testy ldap)(objectClass=user))")
1939 self.assertEquals(len(res), 2, "Found only %d for (&(anr=testy ldap)(objectClass=user))" % len(res))
1941 # Testing ldb.search for (&(anr==testy ldap)(objectClass=user))
1942 # this test disabled for the moment, as anr with == tests are not understood
1943 # res = ldb.search(expression="(&(anr==testy ldap)(objectClass=user))")
1944 # self.assertEquals(len(res), 1, "Found only %d for (&(anr==testy ldap)(objectClass=user))" % len(res))
1946 # self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
1947 # self.assertEquals(res[0]["cn"][0], "ldaptestuser")
1948 # self.assertEquals(res[0]["name"][0], "ldaptestuser")
1950 # Testing ldb.search for (&(anr==testy ldap)(objectClass=user))
1951 # res = ldb.search(expression="(&(anr==testy ldap)(objectClass=user))")
1952 # self.assertEquals(len(res), 1, "Could not find (&(anr==testy ldap)(objectClass=user))")
1954 # self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
1955 # self.assertEquals(res[0]["cn"][0], "ldaptestuser")
1956 # self.assertEquals(res[0]["name"][0], "ldaptestuser")
1958 # Testing ldb.search for (&(anr=testy ldap user)(objectClass=user))
1959 res = ldb.search(expression="(&(anr=testy ldap user)(objectClass=user))")
1960 self.assertEquals(len(res), 1, "Could not find (&(anr=testy ldap user)(objectClass=user))")
1962 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
1963 self.assertEquals(str(res[0]["cn"]), "ldaptestuser2")
1964 self.assertEquals(str(res[0]["name"]), "ldaptestuser2")
1966 # Testing ldb.search for (&(anr==testy ldap user2)(objectClass=user))
1967 # res = ldb.search(expression="(&(anr==testy ldap user2)(objectClass=user))")
1968 # self.assertEquals(len(res), 1, "Could not find (&(anr==testy ldap user2)(objectClass=user))")
1970 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
1971 self.assertEquals(str(res[0]["cn"]), "ldaptestuser2")
1972 self.assertEquals(str(res[0]["name"]), "ldaptestuser2")
1974 # Testing ldb.search for (&(anr==ldap user2)(objectClass=user))
1975 # res = ldb.search(expression="(&(anr==ldap user2)(objectClass=user))")
1976 # self.assertEquals(len(res), 1, "Could not find (&(anr==ldap user2)(objectClass=user))")
1978 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
1979 self.assertEquals(str(res[0]["cn"]), "ldaptestuser2")
1980 self.assertEquals(str(res[0]["name"]), "ldaptestuser2")
1982 # Testing ldb.search for (&(anr==not ldap user2)(objectClass=user))
1983 # res = ldb.search(expression="(&(anr==not ldap user2)(objectClass=user))")
1984 # self.assertEquals(len(res), 0, "Must not find (&(anr==not ldap user2)(objectClass=user))")
1986 # Testing ldb.search for (&(anr=not ldap user2)(objectClass=user))
1987 res = ldb.search(expression="(&(anr=not ldap user2)(objectClass=user))")
1988 self.assertEquals(len(res), 0, "Must not find (&(anr=not ldap user2)(objectClass=user))")
1990 # Testing ldb.search for (&(anr="testy ldap")(objectClass=user)) (ie, with quotes)
1991 # res = ldb.search(expression="(&(anr==\"testy ldap\")(objectClass=user))")
1992 # self.assertEquals(len(res), 0, "Found (&(anr==\"testy ldap\")(objectClass=user))")
1994 print "Testing Renames"
1996 attrs = ["objectGUID", "objectSid"]
1997 print "Testing ldb.search for (&(cn=ldaptestUSer2)(objectClass=user))"
1998 res_user = ldb.search(self.base_dn, expression="(&(cn=ldaptestUSer2)(objectClass=user))", scope=SCOPE_SUBTREE, attrs=attrs)
1999 self.assertEquals(len(res_user), 1, "Could not find (&(cn=ldaptestUSer2)(objectClass=user))")
2001 # Check rename works with extended/alternate DN forms
2002 ldb.rename("<SID=" + ldb.schema_format_value("objectSID", res_user[0]["objectSID"][0]) + ">" , "cn=ldaptestUSER3,cn=users," + self.base_dn)
2004 print "Testing ldb.search for (&(cn=ldaptestuser3)(objectClass=user))"
2005 res = ldb.search(expression="(&(cn=ldaptestuser3)(objectClass=user))")
2006 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser3)(objectClass=user))")
2008 self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
2009 self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3")
2010 self.assertEquals(str(res[0]["name"]), "ldaptestUSER3")
2012 #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))"
2013 res = ldb.search(expression="(&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))")
2014 self.assertEquals(len(res), 1, "(&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))")
2016 self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
2017 self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3")
2018 self.assertEquals(str(res[0]["name"]), "ldaptestUSER3")
2020 #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))"
2021 res = ldb.search(expression="(&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))")
2022 self.assertEquals(len(res), 1, "(&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))")
2024 self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
2025 self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3")
2026 self.assertEquals(str(res[0]["name"]), "ldaptestUSER3")
2028 #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))"
2029 res = ldb.search(expression="(&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))")
2030 self.assertEquals(len(res), 0, "(&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))")
2032 print "Testing ldb.search for (dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ") - should not work"
2033 res = ldb.search(expression="(dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")")
2034 self.assertEquals(len(res), 0, "Could find (dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")")
2036 print "Testing ldb.search for (distinguishedName=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")"
2037 res = ldb.search(expression="(distinguishedName=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")")
2038 self.assertEquals(len(res), 1, "Could not find (distinguishedName=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")")
2039 self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
2040 self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3")
2041 self.assertEquals(str(res[0]["name"]), "ldaptestUSER3")
2043 # ensure we cannot add it again
2045 ldb.add({"dn": "cn=ldaptestuser3,cn=userS," + self.base_dn,
2046 "objectClass": "user",
2047 "cn": "LDAPtestUSER3"})
2049 except LdbError, (num, _):
2050 self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
2053 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser2,cn=users," + self.base_dn)
2055 # ensure we cannot rename it twice
2057 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn,
2058 "cn=ldaptestuser2,cn=users," + self.base_dn)
2060 except LdbError, (num, _):
2061 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
2063 # ensure can now use that name
2064 ldb.add({"dn": "cn=ldaptestuser3,cn=users," + self.base_dn,
2065 "objectClass": "user",
2066 "cn": "LDAPtestUSER3"})
2068 # ensure we now cannot rename
2070 ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=users," + self.base_dn)
2072 except LdbError, (num, _):
2073 self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
2075 ldb.rename("cn=ldaptestuser3,cn=users,%s" % self.base_dn, "cn=ldaptestuser3,%s" % ldb.get_config_basedn())
2077 except LdbError, (num, _):
2078 self.assertTrue(num in (71, 64))
2080 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser5,cn=users," + self.base_dn)
2082 ldb.delete("cn=ldaptestuser5,cn=users," + self.base_dn)
2084 delete_force(ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
2086 ldb.rename("cn=ldaptestgroup,cn=users," + self.base_dn, "cn=ldaptestgroup2,cn=users," + self.base_dn)
2088 print "Testing subtree renames"
2090 ldb.add({"dn": "cn=ldaptestcontainer," + self.base_dn,
2091 "objectClass": "container"})
2093 ldb.add({"dn": "CN=ldaptestuser4,CN=ldaptestcontainer," + self.base_dn,
2094 "objectClass": "user",
2095 "cn": "LDAPtestUSER4"})
2097 # Here we don't enforce these hard "description" constraints
2099 dn: cn=ldaptestcontainer,""" + self.base_dn + """
2101 replace: description
2107 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2110 member: cn=ldaptestuser4,cn=ldaptestcontainer,""" + self.base_dn + """
2111 member: cn=ldaptestcomputer,cn=computers,""" + self.base_dn + """
2112 member: cn=ldaptestuser2,cn=users,""" + self.base_dn + """
2115 print "Testing ldb.rename of cn=ldaptestcontainer," + self.base_dn + " to cn=ldaptestcontainer2," + self.base_dn
2116 ldb.rename("CN=ldaptestcontainer," + self.base_dn, "CN=ldaptestcontainer2," + self.base_dn)
2118 print "Testing ldb.search for (&(cn=ldaptestuser4)(objectClass=user))"
2119 res = ldb.search(expression="(&(cn=ldaptestuser4)(objectClass=user))")
2120 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser4)(objectClass=user))")
2122 print "Testing subtree ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in (just renamed from) cn=ldaptestcontainer," + self.base_dn
2124 res = ldb.search("cn=ldaptestcontainer," + self.base_dn,
2125 expression="(&(cn=ldaptestuser4)(objectClass=user))",
2126 scope=SCOPE_SUBTREE)
2128 except LdbError, (num, _):
2129 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
2131 print "Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in (just renamed from) cn=ldaptestcontainer," + self.base_dn
2133 res = ldb.search("cn=ldaptestcontainer," + self.base_dn,
2134 expression="(&(cn=ldaptestuser4)(objectClass=user))", scope=SCOPE_ONELEVEL)
2136 except LdbError, (num, _):
2137 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
2139 print "Testing ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in renamed container"
2140 res = ldb.search("cn=ldaptestcontainer2," + self.base_dn, expression="(&(cn=ldaptestuser4)(objectClass=user))", scope=SCOPE_SUBTREE)
2141 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser4)(objectClass=user)) under cn=ldaptestcontainer2," + self.base_dn)
2143 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn))
2144 self.assertEquals(res[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
2148 print "Testing ldb.search for (&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn + ")(objectclass=group)) to check subtree renames and linked attributes"
2149 res = ldb.search(self.base_dn, expression="(&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn + ")(objectclass=group))", scope=SCOPE_SUBTREE)
2150 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?")
2152 print "Testing ldb.rename (into itself) of cn=ldaptestcontainer2," + self.base_dn + " to cn=ldaptestcontainer,cn=ldaptestcontainer2," + self.base_dn
2154 ldb.rename("cn=ldaptestcontainer2," + self.base_dn, "cn=ldaptestcontainer,cn=ldaptestcontainer2," + self.base_dn)
2156 except LdbError, (num, _):
2157 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
2159 print "Testing ldb.rename (into non-existent container) of cn=ldaptestcontainer2," + self.base_dn + " to cn=ldaptestcontainer,cn=ldaptestcontainer3," + self.base_dn
2161 ldb.rename("cn=ldaptestcontainer2," + self.base_dn, "cn=ldaptestcontainer,cn=ldaptestcontainer3," + self.base_dn)
2163 except LdbError, (num, _):
2164 self.assertTrue(num in (ERR_UNWILLING_TO_PERFORM, ERR_OTHER))
2166 print "Testing delete (should fail, not a leaf node) of renamed cn=ldaptestcontainer2," + self.base_dn
2168 ldb.delete("cn=ldaptestcontainer2," + self.base_dn)
2170 except LdbError, (num, _):
2171 self.assertEquals(num, ERR_NOT_ALLOWED_ON_NON_LEAF)
2173 print "Testing base ldb.search for CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn
2174 res = ldb.search(expression="(objectclass=*)", base=("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn), scope=SCOPE_BASE)
2175 self.assertEquals(len(res), 1)
2176 res = ldb.search(expression="(cn=ldaptestuser40)", base=("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn), scope=SCOPE_BASE)
2177 self.assertEquals(len(res), 0)
2179 print "Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in cn=ldaptestcontainer2," + self.base_dn
2180 res = ldb.search(expression="(&(cn=ldaptestuser4)(objectClass=user))", base=("cn=ldaptestcontainer2," + self.base_dn), scope=SCOPE_ONELEVEL)
2181 self.assertEquals(len(res), 1)
2183 print "Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in cn=ldaptestcontainer2," + self.base_dn
2184 res = ldb.search(expression="(&(cn=ldaptestuser4)(objectClass=user))", base=("cn=ldaptestcontainer2," + self.base_dn), scope=SCOPE_SUBTREE)
2185 self.assertEquals(len(res), 1)
2187 print "Testing delete of subtree renamed "+("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn)
2188 ldb.delete(("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn))
2189 print "Testing delete of renamed cn=ldaptestcontainer2," + self.base_dn
2190 ldb.delete("cn=ldaptestcontainer2," + self.base_dn)
2192 ldb.add({"dn": "cn=ldaptestutf8user èùéìòà,cn=users," + self.base_dn, "objectClass": "user"})
2194 ldb.add({"dn": "cn=ldaptestutf8user2 èùéìòà,cn=users," + self.base_dn, "objectClass": "user"})
2196 print "Testing ldb.search for (&(cn=ldaptestuser)(objectClass=user))"
2197 res = ldb.search(expression="(&(cn=ldaptestuser)(objectClass=user))")
2198 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser)(objectClass=user))")
2200 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
2201 self.assertEquals(str(res[0]["cn"]), "ldaptestuser")
2202 self.assertEquals(str(res[0]["name"]), "ldaptestuser")
2203 self.assertEquals(set(res[0]["objectClass"]), set(["top", "person", "organizationalPerson", "user"]))
2204 self.assertTrue("objectGUID" in res[0])
2205 self.assertTrue("whenCreated" in res[0])
2206 self.assertEquals(str(res[0]["objectCategory"]), ("CN=Person,%s" % ldb.get_schema_basedn()))
2207 self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_NORMAL_ACCOUNT)
2208 self.assertEquals(int(res[0]["userAccountControl"][0]), UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE)
2209 self.assertEquals(res[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
2210 self.assertEquals(len(res[0]["memberOf"]), 1)
2212 print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=cn=person,%s))" % ldb.get_schema_basedn()
2213 res2 = ldb.search(expression="(&(cn=ldaptestuser)(objectCategory=cn=person,%s))" % ldb.get_schema_basedn())
2214 self.assertEquals(len(res2), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=cn=person,%s))" % ldb.get_schema_basedn())
2216 self.assertEquals(res[0].dn, res2[0].dn)
2218 print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon))"
2219 res3 = ldb.search(expression="(&(cn=ldaptestuser)(objectCategory=PerSon))")
2220 self.assertEquals(len(res3), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=PerSon)): matched %d" % len(res3))
2222 self.assertEquals(res[0].dn, res3[0].dn)
2224 if gc_ldb is not None:
2225 print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon)) in Global Catalog"
2226 res3gc = gc_ldb.search(expression="(&(cn=ldaptestuser)(objectCategory=PerSon))")
2227 self.assertEquals(len(res3gc), 1)
2229 self.assertEquals(res[0].dn, res3gc[0].dn)
2231 print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon)) in with 'phantom root' control"
2233 if gc_ldb is not None:
2234 res3control = gc_ldb.search(self.base_dn, expression="(&(cn=ldaptestuser)(objectCategory=PerSon))", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["search_options:1:2"])
2235 self.assertEquals(len(res3control), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=PerSon)) in Global Catalog")
2237 self.assertEquals(res[0].dn, res3control[0].dn)
2239 ldb.delete(res[0].dn)
2241 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectClass=user))"
2242 res = ldb.search(expression="(&(cn=ldaptestcomputer)(objectClass=user))")
2243 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser)(objectClass=user))")
2245 self.assertEquals(str(res[0].dn), ("CN=ldaptestcomputer,CN=Computers," + self.base_dn))
2246 self.assertEquals(str(res[0]["cn"]), "ldaptestcomputer")
2247 self.assertEquals(str(res[0]["name"]), "ldaptestcomputer")
2248 self.assertEquals(set(res[0]["objectClass"]), set(["top", "person", "organizationalPerson", "user", "computer"]))
2249 self.assertTrue("objectGUID" in res[0])
2250 self.assertTrue("whenCreated" in res[0])
2251 self.assertEquals(str(res[0]["objectCategory"]), ("CN=Computer,%s" % ldb.get_schema_basedn()))
2252 self.assertEquals(int(res[0]["primaryGroupID"][0]), 513)
2253 self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_NORMAL_ACCOUNT)
2254 self.assertEquals(int(res[0]["userAccountControl"][0]), UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE)
2255 self.assertEquals(res[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
2256 self.assertEquals(len(res[0]["memberOf"]), 1)
2258 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=cn=computer,%s))" % ldb.get_schema_basedn()
2259 res2 = ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=cn=computer,%s))" % ldb.get_schema_basedn())
2260 self.assertEquals(len(res2), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=cn=computer,%s))" % ldb.get_schema_basedn())
2262 self.assertEquals(res[0].dn, res2[0].dn)
2264 if gc_ldb is not None:
2265 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=cn=computer,%s)) in Global Catalog" % gc_ldb.get_schema_basedn()
2266 res2gc = gc_ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=cn=computer,%s))" % gc_ldb.get_schema_basedn())
2267 self.assertEquals(len(res2gc), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=cn=computer,%s)) In Global Catalog" % gc_ldb.get_schema_basedn())
2269 self.assertEquals(res[0].dn, res2gc[0].dn)
2271 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=compuTER))"
2272 res3 = ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=compuTER))")
2273 self.assertEquals(len(res3), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=compuTER))")
2275 self.assertEquals(res[0].dn, res3[0].dn)
2277 if gc_ldb is not None:
2278 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=compuTER)) in Global Catalog"
2279 res3gc = gc_ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=compuTER))")
2280 self.assertEquals(len(res3gc), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=compuTER)) in Global Catalog")
2282 self.assertEquals(res[0].dn, res3gc[0].dn)
2284 print "Testing ldb.search for (&(cn=ldaptestcomp*r)(objectCategory=compuTER))"
2285 res4 = ldb.search(expression="(&(cn=ldaptestcomp*r)(objectCategory=compuTER))")
2286 self.assertEquals(len(res4), 1, "Could not find (&(cn=ldaptestcomp*r)(objectCategory=compuTER))")
2288 self.assertEquals(res[0].dn, res4[0].dn)
2290 print "Testing ldb.search for (&(cn=ldaptestcomput*)(objectCategory=compuTER))"
2291 res5 = ldb.search(expression="(&(cn=ldaptestcomput*)(objectCategory=compuTER))")
2292 self.assertEquals(len(res5), 1, "Could not find (&(cn=ldaptestcomput*)(objectCategory=compuTER))")
2294 self.assertEquals(res[0].dn, res5[0].dn)
2296 print "Testing ldb.search for (&(cn=*daptestcomputer)(objectCategory=compuTER))"
2297 res6 = ldb.search(expression="(&(cn=*daptestcomputer)(objectCategory=compuTER))")
2298 self.assertEquals(len(res6), 1, "Could not find (&(cn=*daptestcomputer)(objectCategory=compuTER))")
2300 self.assertEquals(res[0].dn, res6[0].dn)
2302 ldb.delete("<GUID=" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + ">")
2304 print "Testing ldb.search for (&(cn=ldaptest2computer)(objectClass=user))"
2305 res = ldb.search(expression="(&(cn=ldaptest2computer)(objectClass=user))")
2306 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptest2computer)(objectClass=user))")
2308 self.assertEquals(str(res[0].dn), "CN=ldaptest2computer,CN=Computers," + self.base_dn)
2309 self.assertEquals(str(res[0]["cn"]), "ldaptest2computer")
2310 self.assertEquals(str(res[0]["name"]), "ldaptest2computer")
2311 self.assertEquals(list(res[0]["objectClass"]), ["top", "person", "organizationalPerson", "user", "computer"])
2312 self.assertTrue("objectGUID" in res[0])
2313 self.assertTrue("whenCreated" in res[0])
2314 self.assertEquals(res[0]["objectCategory"][0], "CN=Computer,%s" % ldb.get_schema_basedn())
2315 self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_WORKSTATION_TRUST)
2316 self.assertEquals(int(res[0]["userAccountControl"][0]), UF_WORKSTATION_TRUST_ACCOUNT)
2318 ldb.delete("<SID=" + ldb.schema_format_value("objectSID", res[0]["objectSID"][0]) + ">")
2320 attrs = ["cn", "name", "objectClass", "objectGUID", "objectSID", "whenCreated", "nTSecurityDescriptor", "memberOf", "allowedAttributes", "allowedAttributesEffective"]
2321 print "Testing ldb.search for (&(cn=ldaptestUSer2)(objectClass=user))"
2322 res_user = ldb.search(self.base_dn, expression="(&(cn=ldaptestUSer2)(objectClass=user))", scope=SCOPE_SUBTREE, attrs=attrs)
2323 self.assertEquals(len(res_user), 1, "Could not find (&(cn=ldaptestUSer2)(objectClass=user))")
2325 self.assertEquals(str(res_user[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
2326 self.assertEquals(str(res_user[0]["cn"]), "ldaptestuser2")
2327 self.assertEquals(str(res_user[0]["name"]), "ldaptestuser2")
2328 self.assertEquals(list(res_user[0]["objectClass"]), ["top", "person", "organizationalPerson", "user"])
2329 self.assertTrue("objectSid" in res_user[0])
2330 self.assertTrue("objectGUID" in res_user[0])
2331 self.assertTrue("whenCreated" in res_user[0])
2332 self.assertTrue("nTSecurityDescriptor" in res_user[0])
2333 self.assertTrue("allowedAttributes" in res_user[0])
2334 self.assertTrue("allowedAttributesEffective" in res_user[0])
2335 self.assertEquals(res_user[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
2337 ldaptestuser2_sid = res_user[0]["objectSid"][0]
2338 ldaptestuser2_guid = res_user[0]["objectGUID"][0]
2340 attrs = ["cn", "name", "objectClass", "objectGUID", "objectSID", "whenCreated", "nTSecurityDescriptor", "member", "allowedAttributes", "allowedAttributesEffective"]
2341 print "Testing ldb.search for (&(cn=ldaptestgroup2)(objectClass=group))"
2342 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs)
2343 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))")
2345 self.assertEquals(str(res[0].dn), ("CN=ldaptestgroup2,CN=Users," + self.base_dn))
2346 self.assertEquals(str(res[0]["cn"]), "ldaptestgroup2")
2347 self.assertEquals(str(res[0]["name"]), "ldaptestgroup2")
2348 self.assertEquals(list(res[0]["objectClass"]), ["top", "group"])
2349 self.assertTrue("objectGUID" in res[0])
2350 self.assertTrue("objectSid" in res[0])
2351 self.assertTrue("whenCreated" in res[0])
2352 self.assertTrue("nTSecurityDescriptor" in res[0])
2353 self.assertTrue("allowedAttributes" in res[0])
2354 self.assertTrue("allowedAttributesEffective" in res[0])
2356 for m in res[0]["member"]:
2357 memberUP.append(m.upper())
2358 self.assertTrue(("CN=ldaptestuser2,CN=Users," + self.base_dn).upper() in memberUP)
2360 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs, controls=["extended_dn:1:1"])
2361 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))")
2363 print res[0]["member"]
2365 for m in res[0]["member"]:
2366 memberUP.append(m.upper())
2367 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()
2369 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)
2371 print "Quicktest for linked attributes"
2373 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2376 member: CN=ldaptestuser2,CN=Users,""" + self.base_dn + """
2377 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
2381 dn: <GUID=""" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + """>
2384 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
2388 dn: <SID=""" + ldb.schema_format_value("objectSid", res[0]["objectSid"][0]) + """>
2394 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2397 member: <GUID=""" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + """>
2398 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
2402 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2408 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2411 member: <SID=""" + ldb.schema_format_value("objectSid", res_user[0]["objectSid"][0]) + """>
2412 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
2416 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2419 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
2422 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs)
2423 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))")
2425 self.assertEquals(str(res[0].dn), ("CN=ldaptestgroup2,CN=Users," + self.base_dn))
2426 self.assertEquals(res[0]["member"][0], ("CN=ldaptestuser2,CN=Users," + self.base_dn))
2427 self.assertEquals(len(res[0]["member"]), 1)
2429 ldb.delete(("CN=ldaptestuser2,CN=Users," + self.base_dn))
2433 attrs = ["cn", "name", "objectClass", "objectGUID", "whenCreated", "nTSecurityDescriptor", "member"]
2434 print "Testing ldb.search for (&(cn=ldaptestgroup2)(objectClass=group)) to check linked delete"
2435 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs)
2436 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group)) to check linked delete")
2438 self.assertEquals(str(res[0].dn), ("CN=ldaptestgroup2,CN=Users," + self.base_dn))
2439 self.assertTrue("member" not in res[0])
2441 print "Testing ldb.search for (&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))"
2442 res = ldb.search(expression="(&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
2443 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
2444 res = ldb.search(expression="(&(cn=ldaptestutf8user èùéìòà)(objectclass=user))")
2445 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
2447 self.assertEquals(str(res[0].dn), ("CN=ldaptestutf8user èùéìòà,CN=Users," + self.base_dn))
2448 self.assertEquals(str(res[0]["cn"]), "ldaptestutf8user èùéìòà")
2449 self.assertEquals(str(res[0]["name"]), "ldaptestutf8user èùéìòà")
2450 self.assertEquals(list(res[0]["objectClass"]), ["top", "person", "organizationalPerson", "user"])
2451 self.assertTrue("objectGUID" in res[0])
2452 self.assertTrue("whenCreated" in res[0])
2454 # delete "ldaptestutf8user"
2455 ldb.delete(res[0].dn)
2457 print "Testing ldb.search for (&(cn=ldaptestutf8user2*)(objectClass=user))"
2458 res = ldb.search(expression="(&(cn=ldaptestutf8user2*)(objectClass=user))")
2459 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestutf8user2*)(objectClass=user))")
2461 print "Testing ldb.search for (&(cn=ldaptestutf8user2 ÈÙÉÌÒÀ)(objectClass=user))"
2462 res = ldb.search(expression="(&(cn=ldaptestutf8user2 ÈÙÉÌÒÀ)(objectClass=user))")
2463 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestutf8user2 ÈÙÉÌÒÀ)(objectClass=user))")
2465 # delete "ldaptestutf8user2 "
2466 ldb.delete(res[0].dn)
2468 ldb.delete(("CN=ldaptestgroup2,CN=Users," + self.base_dn))
2470 print "Testing that we can't get at the configuration DN from the main search base"
2471 res = ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
2472 self.assertEquals(len(res), 0)
2474 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"
2475 res = ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["search_options:1:2"])
2476 self.assertTrue(len(res) > 0)
2478 if gc_ldb is not None:
2479 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"
2481 res = gc_ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["search_options:1:0"])
2482 self.assertTrue(len(res) > 0)
2484 print "Testing that we do find configuration elements in the global catlog"
2485 res = gc_ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
2486 self.assertTrue(len(res) > 0)
2488 print "Testing that we do find configuration elements and user elements at the same time"
2489 res = gc_ldb.search(self.base_dn, expression="(|(objectClass=crossRef)(objectClass=person))", scope=SCOPE_SUBTREE, attrs=["cn"])
2490 self.assertTrue(len(res) > 0)
2492 print "Testing that we do find configuration elements in the global catlog, with the configuration basedn"
2493 res = gc_ldb.search(self.configuration_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
2494 self.assertTrue(len(res) > 0)
2496 print "Testing that we can get at the configuration DN on the main LDAP port"
2497 res = ldb.search(self.configuration_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
2498 self.assertTrue(len(res) > 0)
2500 print "Testing objectCategory canonacolisation"
2501 res = ldb.search(self.configuration_dn, expression="objectCategory=ntDsDSA", scope=SCOPE_SUBTREE, attrs=["cn"])
2502 self.assertTrue(len(res) > 0, "Didn't find any records with objectCategory=ntDsDSA")
2503 self.assertTrue(len(res) != 0)
2505 res = ldb.search(self.configuration_dn, expression="objectCategory=CN=ntDs-DSA," + self.schema_dn, scope=SCOPE_SUBTREE, attrs=["cn"])
2506 self.assertTrue(len(res) > 0, "Didn't find any records with objectCategory=CN=ntDs-DSA," + self.schema_dn)
2507 self.assertTrue(len(res) != 0)
2509 print "Testing objectClass attribute order on "+ self.base_dn
2510 res = ldb.search(expression="objectClass=domain", base=self.base_dn,
2511 scope=SCOPE_BASE, attrs=["objectClass"])
2512 self.assertEquals(len(res), 1)
2514 self.assertEquals(list(res[0]["objectClass"]), ["top", "domain", "domainDNS"])
2518 print "Testing ldb.search for objectCategory=person"
2519 res = ldb.search(self.base_dn, expression="objectCategory=person", scope=SCOPE_SUBTREE, attrs=["cn"])
2520 self.assertTrue(len(res) > 0)
2522 print "Testing ldb.search for objectCategory=person with domain scope control"
2523 res = ldb.search(self.base_dn, expression="objectCategory=person", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["domain_scope:1"])
2524 self.assertTrue(len(res) > 0)
2526 print "Testing ldb.search for objectCategory=user"
2527 res = ldb.search(self.base_dn, expression="objectCategory=user", scope=SCOPE_SUBTREE, attrs=["cn"])
2528 self.assertTrue(len(res) > 0)
2530 print "Testing ldb.search for objectCategory=user with domain scope control"
2531 res = ldb.search(self.base_dn, expression="objectCategory=user", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["domain_scope:1"])
2532 self.assertTrue(len(res) > 0)
2534 print "Testing ldb.search for objectCategory=group"
2535 res = ldb.search(self.base_dn, expression="objectCategory=group", scope=SCOPE_SUBTREE, attrs=["cn"])
2536 self.assertTrue(len(res) > 0)
2538 print "Testing ldb.search for objectCategory=group with domain scope control"
2539 res = ldb.search(self.base_dn, expression="objectCategory=group", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["domain_scope:1"])
2540 self.assertTrue(len(res) > 0)
2542 print "Testing creating a user with the posixAccount objectClass"
2543 self.ldb.add_ldif("""dn: cn=posixuser,CN=Users,%s
2546 objectClass: posixAccount
2548 objectClass: organizationalPerson
2554 homeDirectory: /home/posixuser
2555 loginShell: /bin/bash
2556 gecos: Posix User;;;
2557 description: A POSIX user"""% (self.base_dn))
2559 print "Testing removing the posixAccount objectClass from an existing user"
2560 self.ldb.modify_ldif("""dn: cn=posixuser,CN=Users,%s
2563 objectClass: posixAccount"""% (self.base_dn))
2565 print "Testing adding the posixAccount objectClass to an existing user"
2566 self.ldb.modify_ldif("""dn: cn=posixuser,CN=Users,%s
2569 objectClass: posixAccount"""% (self.base_dn))
2571 delete_force(self.ldb, "cn=posixuser,cn=users," + self.base_dn)
2572 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
2573 delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
2574 delete_force(self.ldb, "cn=ldaptestuser3,cn=users," + self.base_dn)
2575 delete_force(self.ldb, "cn=ldaptestuser4,cn=ldaptestcontainer," + self.base_dn)
2576 delete_force(self.ldb, "cn=ldaptestuser4,cn=ldaptestcontainer2," + self.base_dn)
2577 delete_force(self.ldb, "cn=ldaptestuser5,cn=users," + self.base_dn)
2578 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
2579 delete_force(self.ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
2580 delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2581 delete_force(self.ldb, "cn=ldaptest2computer,cn=computers," + self.base_dn)
2582 delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
2583 delete_force(self.ldb, "cn=ldaptestutf8user èùéìòà,cn=users," + self.base_dn)
2584 delete_force(self.ldb, "cn=ldaptestutf8user2 èùéìòà,cn=users," + self.base_dn)
2585 delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
2586 delete_force(self.ldb, "cn=ldaptestcontainer2," + self.base_dn)
2588 def test_security_descriptor_add(self):
2589 """ Testing ldb.add_ldif() for nTSecurityDescriptor """
2590 user_name = "testdescriptoruser1"
2591 user_dn = "CN=%s,CN=Users,%s" % (user_name, self.base_dn)
2593 # Test an empty security descriptor (naturally this shouldn't work)
2595 delete_force(self.ldb, user_dn)
2597 self.ldb.add({ "dn": user_dn,
2598 "objectClass": "user",
2599 "sAMAccountName": user_name,
2600 "nTSecurityDescriptor": [] })
2602 except LdbError, (num, _):
2603 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
2605 delete_force(self.ldb, user_dn)
2607 # Test add_ldif() with SDDL security descriptor input
2610 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2611 self.ldb.add_ldif("""
2612 dn: """ + user_dn + """
2614 sAMAccountName: """ + user_name + """
2615 nTSecurityDescriptor: """ + sddl)
2616 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2617 desc = res[0]["nTSecurityDescriptor"][0]
2618 desc = ndr_unpack( security.descriptor, desc )
2619 desc_sddl = desc.as_sddl( self.domain_sid )
2620 self.assertEqual(desc_sddl, sddl)
2622 delete_force(self.ldb, user_dn)
2624 # Test add_ldif() with BASE64 security descriptor
2627 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2628 desc = security.descriptor.from_sddl(sddl, self.domain_sid)
2629 desc_binary = ndr_pack(desc)
2630 desc_base64 = base64.b64encode(desc_binary)
2631 self.ldb.add_ldif("""
2632 dn: """ + user_dn + """
2634 sAMAccountName: """ + user_name + """
2635 nTSecurityDescriptor:: """ + desc_base64)
2636 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2637 desc = res[0]["nTSecurityDescriptor"][0]
2638 desc = ndr_unpack(security.descriptor, desc)
2639 desc_sddl = desc.as_sddl(self.domain_sid)
2640 self.assertEqual(desc_sddl, sddl)
2642 delete_force(self.ldb, user_dn)
2644 def test_security_descriptor_add_neg(self):
2645 """Test add_ldif() with BASE64 security descriptor input using WRONG domain SID
2648 user_name = "testdescriptoruser1"
2649 user_dn = "CN=%s,CN=Users,%s" % (user_name, self.base_dn)
2650 delete_force(self.ldb, user_dn)
2652 sddl = "O:DUG:DUD:AI(A;;RPWP;;;AU)S:PAI"
2653 desc = security.descriptor.from_sddl(sddl, security.dom_sid('S-1-5-21'))
2654 desc_base64 = base64.b64encode( ndr_pack(desc) )
2655 self.ldb.add_ldif("""
2656 dn: """ + user_dn + """
2658 sAMAccountName: """ + user_name + """
2659 nTSecurityDescriptor:: """ + desc_base64)
2660 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2661 self.assertTrue("nTSecurityDescriptor" in res[0])
2662 desc = res[0]["nTSecurityDescriptor"][0]
2663 desc = ndr_unpack(security.descriptor, desc)
2664 desc_sddl = desc.as_sddl(self.domain_sid)
2665 self.assertTrue("O:S-1-5-21-513G:S-1-5-21-513D:AI(A;;RPWP;;;AU)" in desc_sddl)
2667 delete_force(self.ldb, user_dn)
2669 def test_security_descriptor_modify(self):
2670 """ Testing ldb.modify_ldif() for nTSecurityDescriptor """
2671 user_name = "testdescriptoruser2"
2672 user_dn = "CN=%s,CN=Users,%s" % (user_name, self.base_dn)
2674 # Test an empty security descriptor (naturally this shouldn't work)
2676 delete_force(self.ldb, user_dn)
2677 self.ldb.add({ "dn": user_dn,
2678 "objectClass": "user",
2679 "sAMAccountName": user_name })
2682 m.dn = Dn(ldb, user_dn)
2683 m["nTSecurityDescriptor"] = MessageElement([], FLAG_MOD_ADD,
2684 "nTSecurityDescriptor")
2688 except LdbError, (num, _):
2689 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
2692 m.dn = Dn(ldb, user_dn)
2693 m["nTSecurityDescriptor"] = MessageElement([], FLAG_MOD_REPLACE,
2694 "nTSecurityDescriptor")
2698 except LdbError, (num, _):
2699 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
2702 m.dn = Dn(ldb, user_dn)
2703 m["nTSecurityDescriptor"] = MessageElement([], FLAG_MOD_DELETE,
2704 "nTSecurityDescriptor")
2708 except LdbError, (num, _):
2709 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
2711 delete_force(self.ldb, user_dn)
2713 # Test modify_ldif() with SDDL security descriptor input
2714 # Add ACE to the original descriptor test
2717 self.ldb.add_ldif("""
2718 dn: """ + user_dn + """
2720 sAMAccountName: """ + user_name)
2722 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2723 desc = res[0]["nTSecurityDescriptor"][0]
2724 desc = ndr_unpack(security.descriptor, desc)
2725 desc_sddl = desc.as_sddl(self.domain_sid)
2726 sddl = desc_sddl[:desc_sddl.find("(")] + "(A;;RPWP;;;AU)" + desc_sddl[desc_sddl.find("("):]
2728 dn: """ + user_dn + """
2730 replace: nTSecurityDescriptor
2731 nTSecurityDescriptor: """ + sddl
2732 self.ldb.modify_ldif(mod)
2733 # Read modified descriptor
2734 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2735 desc = res[0]["nTSecurityDescriptor"][0]
2736 desc = ndr_unpack(security.descriptor, desc)
2737 desc_sddl = desc.as_sddl(self.domain_sid)
2738 self.assertEqual(desc_sddl, sddl)
2740 delete_force(self.ldb, user_dn)
2742 # Test modify_ldif() with SDDL security descriptor input
2743 # New desctiptor test
2746 self.ldb.add_ldif("""
2747 dn: """ + user_dn + """
2749 sAMAccountName: """ + user_name)
2751 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2753 dn: """ + user_dn + """
2755 replace: nTSecurityDescriptor
2756 nTSecurityDescriptor: """ + sddl
2757 self.ldb.modify_ldif(mod)
2758 # Read modified descriptor
2759 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2760 desc = res[0]["nTSecurityDescriptor"][0]
2761 desc = ndr_unpack(security.descriptor, desc)
2762 desc_sddl = desc.as_sddl(self.domain_sid)
2763 self.assertEqual(desc_sddl, sddl)
2765 delete_force(self.ldb, user_dn)
2767 # Test modify_ldif() with BASE64 security descriptor input
2768 # Add ACE to the original descriptor test
2771 self.ldb.add_ldif("""
2772 dn: """ + user_dn + """
2774 sAMAccountName: """ + user_name)
2776 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2777 desc = res[0]["nTSecurityDescriptor"][0]
2778 desc = ndr_unpack(security.descriptor, desc)
2779 desc_sddl = desc.as_sddl(self.domain_sid)
2780 sddl = desc_sddl[:desc_sddl.find("(")] + "(A;;RPWP;;;AU)" + desc_sddl[desc_sddl.find("("):]
2781 desc = security.descriptor.from_sddl(sddl, self.domain_sid)
2782 desc_base64 = base64.b64encode(ndr_pack(desc))
2784 dn: """ + user_dn + """
2786 replace: nTSecurityDescriptor
2787 nTSecurityDescriptor:: """ + desc_base64
2788 self.ldb.modify_ldif(mod)
2789 # Read modified descriptor
2790 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2791 desc = res[0]["nTSecurityDescriptor"][0]
2792 desc = ndr_unpack(security.descriptor, desc)
2793 desc_sddl = desc.as_sddl(self.domain_sid)
2794 self.assertEqual(desc_sddl, sddl)
2796 delete_force(self.ldb, user_dn)
2798 # Test modify_ldif() with BASE64 security descriptor input
2799 # New descriptor test
2802 delete_force(self.ldb, user_dn)
2803 self.ldb.add_ldif("""
2804 dn: """ + user_dn + """
2806 sAMAccountName: """ + user_name)
2808 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2809 desc = security.descriptor.from_sddl(sddl, self.domain_sid)
2810 desc_base64 = base64.b64encode(ndr_pack(desc))
2812 dn: """ + user_dn + """
2814 replace: nTSecurityDescriptor
2815 nTSecurityDescriptor:: """ + desc_base64
2816 self.ldb.modify_ldif(mod)
2817 # Read modified descriptor
2818 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2819 desc = res[0]["nTSecurityDescriptor"][0]
2820 desc = ndr_unpack(security.descriptor, desc)
2821 desc_sddl = desc.as_sddl(self.domain_sid)
2822 self.assertEqual(desc_sddl, sddl)
2824 delete_force(self.ldb, user_dn)
2826 def test_dsheuristics(self):
2827 """Tests the 'dSHeuristics' attribute"""
2828 print "Tests the 'dSHeuristics' attribute"
2830 # Get the current value to restore it later
2831 dsheuristics = self.ldb.get_dsheuristics()
2832 # Perform the length checks: for each decade (except the 0th) we need
2833 # the first index to be the number. This goes till the 9th one, beyond
2834 # there does not seem to be another limitation.
2837 for i in range(1,11):
2838 # This is in the range
2839 self.ldb.set_dsheuristics(dshstr + "x")
2840 self.ldb.set_dsheuristics(dshstr + "xxxxx")
2841 dshstr = dshstr + "xxxxxxxxx"
2843 # Not anymore in the range, new decade specifier needed
2845 self.ldb.set_dsheuristics(dshstr + "x")
2847 except LdbError, (num, _):
2848 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
2849 dshstr = dshstr + str(i)
2851 # There does not seem to be an upper limit
2852 self.ldb.set_dsheuristics(dshstr + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
2853 # apart from the above, all char values are accepted
2854 self.ldb.set_dsheuristics("123ABC-+!1asdfg@#^")
2855 self.assertEquals(self.ldb.get_dsheuristics(), "123ABC-+!1asdfg@#^")
2858 self.ldb.set_dsheuristics(dsheuristics)
2860 def test_ldapControlReturn(self):
2861 """Testing that if we request a control that return a control it
2862 really return something"""
2863 res = self.ldb.search(attrs=["cn"],
2864 controls=["paged_results:1:10"])
2865 self.assertEquals(len(res.controls), 1)
2866 self.assertEquals(res.controls[0].oid, "1.2.840.113556.1.4.319")
2867 s = str(res.controls[0])
2869 def test_operational(self):
2870 """Tests operational attributes"""
2871 print "Tests operational attributes"
2873 res = self.ldb.search(self.base_dn, scope=SCOPE_BASE,
2874 attrs=["createTimeStamp", "modifyTimeStamp",
2875 "structuralObjectClass", "whenCreated",
2877 self.assertEquals(len(res), 1)
2878 self.assertTrue("createTimeStamp" in res[0])
2879 self.assertTrue("modifyTimeStamp" in res[0])
2880 self.assertTrue("structuralObjectClass" in res[0])
2881 self.assertTrue("whenCreated" in res[0])
2882 self.assertTrue("whenChanged" in res[0])
2884 class BaseDnTests(samba.tests.TestCase):
2887 super(BaseDnTests, self).setUp()
2890 def test_rootdse_attrs(self):
2891 """Testing for all rootDSE attributes"""
2892 res = self.ldb.search("", scope=SCOPE_BASE, attrs=[])
2893 self.assertEquals(len(res), 1)
2895 def test_highestcommittedusn(self):
2896 """Testing for highestCommittedUSN"""
2897 res = self.ldb.search("", scope=SCOPE_BASE, attrs=["highestCommittedUSN"])
2898 self.assertEquals(len(res), 1)
2899 self.assertTrue(int(res[0]["highestCommittedUSN"][0]) != 0)
2901 def test_netlogon(self):
2902 """Testing for netlogon via LDAP"""
2903 res = self.ldb.search("", scope=SCOPE_BASE, attrs=["netlogon"])
2904 self.assertEquals(len(res), 0)
2906 def test_netlogon_highestcommitted_usn(self):
2907 """Testing for netlogon and highestCommittedUSN via LDAP"""
2908 res = self.ldb.search("", scope=SCOPE_BASE,
2909 attrs=["netlogon", "highestCommittedUSN"])
2910 self.assertEquals(len(res), 0)
2912 def test_namingContexts(self):
2913 """Testing for namingContexts in rootDSE"""
2914 res = self.ldb.search("", scope=SCOPE_BASE,
2915 attrs=["namingContexts", "defaultNamingContext", "schemaNamingContext", "configurationNamingContext"])
2916 self.assertEquals(len(res), 1)
2919 for nc in res[0]["namingContexts"]:
2920 self.assertTrue(nc not in ncs)
2923 self.assertTrue(res[0]["defaultNamingContext"][0] in ncs)
2924 self.assertTrue(res[0]["configurationNamingContext"][0] in ncs)
2925 self.assertTrue(res[0]["schemaNamingContext"][0] in ncs)
2927 def test_serverPath(self):
2928 """Testing the server paths in rootDSE"""
2929 res = self.ldb.search("", scope=SCOPE_BASE,
2930 attrs=["dsServiceName", "serverName"])
2931 self.assertEquals(len(res), 1)
2933 self.assertTrue("CN=Servers" in res[0]["dsServiceName"][0])
2934 self.assertTrue("CN=Sites" in res[0]["dsServiceName"][0])
2935 self.assertTrue("CN=NTDS Settings" in res[0]["dsServiceName"][0])
2936 self.assertTrue("CN=Servers" in res[0]["serverName"][0])
2937 self.assertTrue("CN=Sites" in res[0]["serverName"][0])
2938 self.assertFalse("CN=NTDS Settings" in res[0]["serverName"][0])
2940 def test_functionality(self):
2941 """Testing the server paths in rootDSE"""
2942 res = self.ldb.search("", scope=SCOPE_BASE,
2943 attrs=["forestFunctionality", "domainFunctionality", "domainControllerFunctionality"])
2944 self.assertEquals(len(res), 1)
2945 self.assertEquals(len(res[0]["forestFunctionality"]), 1)
2946 self.assertEquals(len(res[0]["domainFunctionality"]), 1)
2947 self.assertEquals(len(res[0]["domainControllerFunctionality"]), 1)
2949 self.assertTrue(int(res[0]["forestFunctionality"][0]) <= int(res[0]["domainFunctionality"][0]))
2950 self.assertTrue(int(res[0]["domainControllerFunctionality"][0]) >= int(res[0]["domainFunctionality"][0]))
2952 res2 = self.ldb.search("", scope=SCOPE_BASE,
2953 attrs=["dsServiceName", "serverName"])
2954 self.assertEquals(len(res2), 1)
2955 self.assertEquals(len(res2[0]["dsServiceName"]), 1)
2957 res3 = self.ldb.search(res2[0]["dsServiceName"][0], scope=SCOPE_BASE, attrs=["msDS-Behavior-Version"])
2958 self.assertEquals(len(res3), 1)
2959 self.assertEquals(len(res3[0]["msDS-Behavior-Version"]), 1)
2960 self.assertEquals(int(res[0]["domainControllerFunctionality"][0]), int(res3[0]["msDS-Behavior-Version"][0]))
2962 res4 = self.ldb.search(ldb.domain_dn(), scope=SCOPE_BASE, attrs=["msDS-Behavior-Version"])
2963 self.assertEquals(len(res4), 1)
2964 self.assertEquals(len(res4[0]["msDS-Behavior-Version"]), 1)
2965 self.assertEquals(int(res[0]["domainFunctionality"][0]), int(res4[0]["msDS-Behavior-Version"][0]))
2967 res5 = self.ldb.search("cn=partitions,%s" % ldb.get_config_basedn(), scope=SCOPE_BASE, attrs=["msDS-Behavior-Version"])
2968 self.assertEquals(len(res5), 1)
2969 self.assertEquals(len(res5[0]["msDS-Behavior-Version"]), 1)
2970 self.assertEquals(int(res[0]["forestFunctionality"][0]), int(res5[0]["msDS-Behavior-Version"][0]))
2972 def test_dnsHostname(self):
2973 """Testing the DNS hostname in rootDSE"""
2974 res = self.ldb.search("", scope=SCOPE_BASE,
2975 attrs=["dnsHostName", "serverName"])
2976 self.assertEquals(len(res), 1)
2978 res2 = self.ldb.search(res[0]["serverName"][0], scope=SCOPE_BASE,
2979 attrs=["dNSHostName"])
2980 self.assertEquals(len(res2), 1)
2982 self.assertEquals(res[0]["dnsHostName"][0], res2[0]["dNSHostName"][0])
2984 def test_ldapServiceName(self):
2985 """Testing the ldap service name in rootDSE"""
2986 res = self.ldb.search("", scope=SCOPE_BASE,
2987 attrs=["ldapServiceName", "dnsHostName"])
2988 self.assertEquals(len(res), 1)
2989 self.assertTrue("ldapServiceName" in res[0])
2990 self.assertTrue("dnsHostName" in res[0])
2992 (hostname, _, dns_domainname) = res[0]["dnsHostName"][0].partition(".")
2994 given = res[0]["ldapServiceName"][0]
2995 expected = "%s:%s$@%s" % (dns_domainname.lower(), hostname.lower(), dns_domainname.upper())
2996 self.assertEquals(given, expected)
2998 if not "://" in host:
2999 if os.path.isfile(host):
3000 host = "tdb://%s" % host
3002 host = "ldap://%s" % host
3004 ldb = SamDB(host, credentials=creds, session_info=system_session(lp), lp=lp)
3005 if not "tdb://" in host:
3006 gc_ldb = Ldb("%s:3268" % host, credentials=creds,
3007 session_info=system_session(lp), lp=lp)
3011 runner = SubunitTestRunner()
3013 if not runner.run(unittest.makeSuite(BaseDnTests)).wasSuccessful():
3015 if not runner.run(unittest.makeSuite(BasicTests)).wasSuccessful():