s4:ldap.py - enhance the "distinguishedName" tests
[Samba/gebeck_regimport.git] / source4 / dsdb / tests / python / ldap.py
blobb4fe8cd2ee4896be94088056a7e17eafb5c92095
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 # This is a port of the original in testprogs/ejs/ldap.js
5 import optparse
6 import sys
7 import time
8 import base64
9 import os
11 sys.path.append("bin/python")
12 import samba
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 samba import Ldb
29 from samba.dsdb import (UF_NORMAL_ACCOUNT,
30 UF_WORKSTATION_TRUST_ACCOUNT,
31 UF_PASSWD_NOTREQD, UF_ACCOUNTDISABLE, ATYPE_NORMAL_ACCOUNT,
32 ATYPE_WORKSTATION_TRUST, SYSTEM_FLAG_DOMAIN_DISALLOW_MOVE,
33 SYSTEM_FLAG_CONFIG_ALLOW_RENAME, SYSTEM_FLAG_CONFIG_ALLOW_MOVE,
34 SYSTEM_FLAG_CONFIG_ALLOW_LIMITED_MOVE)
36 from subunit.run import SubunitTestRunner
37 import unittest
39 from samba.ndr import ndr_pack, ndr_unpack
40 from samba.dcerpc import security
42 parser = optparse.OptionParser("ldap.py [options] <host>")
43 sambaopts = options.SambaOptions(parser)
44 parser.add_option_group(sambaopts)
45 parser.add_option_group(options.VersionOptions(parser))
46 # use command line creds if available
47 credopts = options.CredentialsOptions(parser)
48 parser.add_option_group(credopts)
49 opts, args = parser.parse_args()
51 if len(args) < 1:
52 parser.print_usage()
53 sys.exit(1)
55 host = args[0]
57 lp = sambaopts.get_loadparm()
58 creds = credopts.get_credentials(lp)
60 class BasicTests(unittest.TestCase):
62 def delete_force(self, ldb, dn):
63 try:
64 ldb.delete(dn)
65 except LdbError, (num, _):
66 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
68 def find_basedn(self, ldb):
69 res = ldb.search(base="", expression="", scope=SCOPE_BASE,
70 attrs=["defaultNamingContext"])
71 self.assertEquals(len(res), 1)
72 return res[0]["defaultNamingContext"][0]
74 def find_configurationdn(self, ldb):
75 res = ldb.search(base="", expression="", scope=SCOPE_BASE, attrs=["configurationNamingContext"])
76 self.assertEquals(len(res), 1)
77 return res[0]["configurationNamingContext"][0]
79 def find_schemadn(self, ldb):
80 res = ldb.search(base="", expression="", scope=SCOPE_BASE, attrs=["schemaNamingContext"])
81 self.assertEquals(len(res), 1)
82 return res[0]["schemaNamingContext"][0]
84 def find_domain_sid(self):
85 res = self.ldb.search(base=self.base_dn, expression="(objectClass=*)", scope=SCOPE_BASE)
86 return ndr_unpack( security.dom_sid,res[0]["objectSid"][0])
88 def set_dsheuristics(self, dsheuristics):
89 m = Message()
90 m.dn = Dn(self.ldb, "CN=Directory Service, CN=Windows NT, CN=Services, "
91 + self.configuration_dn)
92 if dsheuristics is not None:
93 m["dSHeuristics"] = MessageElement(dsheuristics, FLAG_MOD_REPLACE,
94 "dSHeuristics")
95 else:
96 m["dSHeuristics"] = MessageElement([], FLAG_MOD_DELETE, "dsHeuristics")
97 self.ldb.modify(m)
99 def setUp(self):
100 super(BasicTests, self).setUp()
101 self.ldb = ldb
102 self.gc_ldb = gc_ldb
103 self.base_dn = self.find_basedn(ldb)
104 self.configuration_dn = self.find_configurationdn(ldb)
105 self.schema_dn = self.find_schemadn(ldb)
106 self.domain_sid = self.find_domain_sid()
108 print "baseDN: %s\n" % self.base_dn
110 self.delete_force(self.ldb, "cn=posixuser,cn=users," + self.base_dn)
111 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
112 self.delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
113 self.delete_force(self.ldb, "cn=ldaptestuser3,cn=users," + self.base_dn)
114 self.delete_force(self.ldb, "cn=ldaptestuser4,cn=ldaptestcontainer," + self.base_dn)
115 self.delete_force(self.ldb, "cn=ldaptestuser4,cn=ldaptestcontainer2," + self.base_dn)
116 self.delete_force(self.ldb, "cn=ldaptestuser5,cn=users," + self.base_dn)
117 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
118 self.delete_force(self.ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
119 self.delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
120 self.delete_force(self.ldb, "cn=ldaptest2computer,cn=computers," + self.base_dn)
121 self.delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
122 self.delete_force(self.ldb, "cn=ldaptestutf8user èùéìòà,cn=users," + self.base_dn)
123 self.delete_force(self.ldb, "cn=ldaptestutf8user2 èùéìòà,cn=users," + self.base_dn)
124 self.delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
125 self.delete_force(self.ldb, "cn=ldaptestcontainer2," + self.base_dn)
126 self.delete_force(self.ldb, "cn=parentguidtest,cn=users," + self.base_dn)
127 self.delete_force(self.ldb, "cn=parentguidtest,cn=testotherusers," + self.base_dn)
128 self.delete_force(self.ldb, "cn=testotherusers," + self.base_dn)
129 self.delete_force(self.ldb, "cn=ldaptestobject," + self.base_dn)
130 self.delete_force(self.ldb, "description=xyz,cn=users," + self.base_dn)
131 self.delete_force(self.ldb, "ou=testou,cn=users," + self.base_dn)
132 self.delete_force(self.ldb, "cn=testsecret,cn=system," + self.base_dn)
134 def test_objectclasses(self):
135 """Test objectClass behaviour"""
136 print "Test objectClass behaviour"""
138 # We cannot create LSA-specific objects (oc "secret" or "trustedDomain")
139 try:
140 self.ldb.add({
141 "dn": "cn=testsecret,cn=system," + self.base_dn,
142 "objectClass": "secret" })
143 self.fail()
144 except LdbError, (num, _):
145 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
147 # Invalid objectclass specified
148 try:
149 self.ldb.add({
150 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
151 "objectClass": [] })
152 self.fail()
153 except LdbError, (num, _):
154 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
156 # Invalid objectclass specified
157 try:
158 self.ldb.add({
159 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
160 "objectClass": "X" })
161 self.fail()
162 except LdbError, (num, _):
163 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
165 # Invalid objectCategory specified
166 try:
167 self.ldb.add({
168 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
169 "objectClass": "person",
170 "objectCategory": self.base_dn })
171 self.fail()
172 except LdbError, (num, _):
173 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
175 # Multi-valued "systemFlags"
176 try:
177 self.ldb.add({
178 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
179 "objectClass": "person",
180 "systemFlags": ["0", str(SYSTEM_FLAG_DOMAIN_DISALLOW_MOVE)] })
181 self.fail()
182 except LdbError, (num, _):
183 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
185 # We cannot instanciate from an abstract objectclass
186 try:
187 self.ldb.add({
188 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
189 "objectClass": "connectionPoint" })
190 self.fail()
191 except LdbError, (num, _):
192 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
194 # Test allowed system flags
195 self.ldb.add({
196 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
197 "objectClass": "person",
198 "systemFlags": str(~(SYSTEM_FLAG_CONFIG_ALLOW_RENAME | SYSTEM_FLAG_CONFIG_ALLOW_MOVE | SYSTEM_FLAG_CONFIG_ALLOW_LIMITED_MOVE)) })
200 res = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
201 scope=SCOPE_BASE, attrs=["systemFlags"])
202 self.assertTrue(len(res) == 1)
203 self.assertEquals(res[0]["systemFlags"][0], "0")
205 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
207 self.ldb.add({
208 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
209 "objectClass": "person" })
211 # We can remove derivation classes of the structural objectclass
212 # but they're going to be readded afterwards
213 m = Message()
214 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
215 m["objectClass"] = MessageElement("top", FLAG_MOD_DELETE,
216 "objectClass")
217 ldb.modify(m)
219 res = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
220 scope=SCOPE_BASE, attrs=["objectClass"])
221 self.assertTrue(len(res) == 1)
222 self.assertTrue("top" in res[0]["objectClass"])
224 # The top-most structural class cannot be deleted since there are
225 # attributes of it in use
226 m = Message()
227 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
228 m["objectClass"] = MessageElement("person", FLAG_MOD_DELETE,
229 "objectClass")
230 try:
231 ldb.modify(m)
232 self.fail()
233 except LdbError, (num, _):
234 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
236 # We cannot delete classes which weren't specified
237 m = Message()
238 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
239 m["objectClass"] = MessageElement("computer", FLAG_MOD_DELETE,
240 "objectClass")
241 try:
242 ldb.modify(m)
243 self.fail()
244 except LdbError, (num, _):
245 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
247 # An invalid class cannot be added
248 m = Message()
249 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
250 m["objectClass"] = MessageElement("X", FLAG_MOD_ADD,
251 "objectClass")
252 try:
253 ldb.modify(m)
254 self.fail()
255 except LdbError, (num, _):
256 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
258 # The top-most structural class cannot be changed by adding another
259 # structural one
260 m = Message()
261 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
262 m["objectClass"] = MessageElement("user", FLAG_MOD_ADD,
263 "objectClass")
264 try:
265 ldb.modify(m)
266 self.fail()
267 except LdbError, (num, _):
268 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
270 # An already specified objectclass cannot be added another time
271 m = Message()
272 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
273 m["objectClass"] = MessageElement("person", FLAG_MOD_ADD,
274 "objectClass")
275 try:
276 ldb.modify(m)
277 self.fail()
278 except LdbError, (num, _):
279 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
281 # Auxiliary classes can always be added
282 m = Message()
283 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
284 m["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_ADD,
285 "objectClass")
286 ldb.modify(m)
288 # It's only possible to replace with the same objectclass combination.
289 # So the replace action on "objectClass" attributes is really useless.
290 m = Message()
291 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
292 m["objectClass"] = MessageElement(["top", "person", "bootableDevice"],
293 FLAG_MOD_REPLACE, "objectClass")
294 ldb.modify(m)
296 m = Message()
297 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
298 m["objectClass"] = MessageElement(["person", "bootableDevice"],
299 FLAG_MOD_REPLACE, "objectClass")
300 ldb.modify(m)
302 m = Message()
303 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
304 m["objectClass"] = MessageElement(["top", "person", "bootableDevice",
305 "connectionPoint"], FLAG_MOD_REPLACE, "objectClass")
306 try:
307 ldb.modify(m)
308 self.fail()
309 except LdbError, (num, _):
310 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
312 # We cannot remove all object classes by an empty replace
313 m = Message()
314 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
315 m["objectClass"] = MessageElement([], FLAG_MOD_REPLACE, "objectClass")
316 try:
317 ldb.modify(m)
318 self.fail()
319 except LdbError, (num, _):
320 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
322 m = Message()
323 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
324 m["objectClass"] = MessageElement(["top", "computer"], FLAG_MOD_REPLACE,
325 "objectClass")
326 try:
327 ldb.modify(m)
328 self.fail()
329 except LdbError, (num, _):
330 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
332 # Classes can be removed unless attributes of them are used.
333 m = Message()
334 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
335 m["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_DELETE,
336 "objectClass")
337 ldb.modify(m)
339 res = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
340 scope=SCOPE_BASE, attrs=["objectClass"])
341 self.assertTrue(len(res) == 1)
342 self.assertFalse("bootableDevice" in res[0]["objectClass"])
344 m = Message()
345 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
346 m["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_ADD,
347 "objectClass")
348 ldb.modify(m)
350 # Add an attribute specific to the "bootableDevice" class
351 m = Message()
352 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
353 m["bootParameter"] = MessageElement("test", FLAG_MOD_ADD,
354 "bootParameter")
355 ldb.modify(m)
357 # Classes can be removed unless attributes of them are used. Now there
358 # exist such attributes on the entry.
359 m = Message()
360 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
361 m["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_DELETE,
362 "objectClass")
363 try:
364 ldb.modify(m)
365 self.fail()
366 except LdbError, (num, _):
367 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
369 # Remove the previously specified attribute
370 m = Message()
371 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
372 m["bootParameter"] = MessageElement("test", FLAG_MOD_DELETE,
373 "bootParameter")
374 ldb.modify(m)
376 # Classes can be removed unless attributes of them are used.
377 m = Message()
378 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
379 m["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_DELETE,
380 "objectClass")
381 ldb.modify(m)
383 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
385 def test_system_only(self):
386 """Test systemOnly objects"""
387 print "Test systemOnly objects"""
389 try:
390 self.ldb.add({
391 "dn": "cn=ldaptestobject," + self.base_dn,
392 "objectclass": "configuration"})
393 self.fail()
394 except LdbError, (num, _):
395 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
397 try:
398 self.ldb.add({
399 "dn": "cn=testsecret,cn=system," + self.base_dn,
400 "objectclass": "secret"})
401 self.fail()
402 except LdbError, (num, _):
403 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
405 self.delete_force(self.ldb, "cn=ldaptestobject," + self.base_dn)
406 self.delete_force(self.ldb, "cn=testsecret,cn=system," + self.base_dn)
408 try:
409 self.ldb.add({
410 "dn": "cn=ldaptestcontainer," + self.base_dn,
411 "objectclass": "container",
412 "isCriticalSystemObject": "TRUE"})
413 self.fail()
414 except LdbError, (num, _):
415 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
417 self.ldb.add({
418 "dn": "cn=ldaptestcontainer," + self.base_dn,
419 "objectclass": "container"})
421 m = Message()
422 m.dn = Dn(ldb, "cn=ldaptestcontainer," + self.base_dn)
423 m["isCriticalSystemObject"] = MessageElement("TRUE", FLAG_MOD_REPLACE,
424 "isCriticalSystemObject")
425 try:
426 ldb.modify(m)
427 self.fail()
428 except LdbError, (num, _):
429 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
431 self.delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
433 # Proof if DC SAM object has "isCriticalSystemObject" set
434 res = self.ldb.search("", scope=SCOPE_BASE, attrs=["serverName"])
435 self.assertTrue(len(res) == 1)
436 self.assertTrue("serverName" in res[0])
437 res = self.ldb.search(res[0]["serverName"][0], scope=SCOPE_BASE,
438 attrs=["serverReference"])
439 self.assertTrue(len(res) == 1)
440 self.assertTrue("serverReference" in res[0])
441 res = self.ldb.search(res[0]["serverReference"][0], scope=SCOPE_BASE,
442 attrs=["isCriticalSystemObject"])
443 self.assertTrue(len(res) == 1)
444 self.assertTrue("isCriticalSystemObject" in res[0])
445 self.assertEquals(res[0]["isCriticalSystemObject"][0], "TRUE")
447 def test_invalid_parent(self):
448 """Test adding an object with invalid parent"""
449 print "Test adding an object with invalid parent"""
451 try:
452 self.ldb.add({
453 "dn": "cn=ldaptestgroup,cn=thisdoesnotexist123,"
454 + self.base_dn,
455 "objectclass": "group"})
456 self.fail()
457 except LdbError, (num, _):
458 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
460 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=thisdoesnotexist123,"
461 + self.base_dn)
463 try:
464 self.ldb.add({
465 "dn": "ou=testou,cn=users," + self.base_dn,
466 "objectclass": "organizationalUnit"})
467 self.fail()
468 except LdbError, (num, _):
469 self.assertEquals(num, ERR_NAMING_VIOLATION)
471 self.delete_force(self.ldb, "ou=testou,cn=users," + self.base_dn)
473 def test_invalid_attribute(self):
474 """Test invalid attributes on schema/objectclasses"""
475 print "Test invalid attributes on schema/objectclasses"""
477 # attributes not in schema test
479 # add operation
481 try:
482 self.ldb.add({
483 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
484 "objectclass": "group",
485 "thisdoesnotexist": "x"})
486 self.fail()
487 except LdbError, (num, _):
488 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
490 self.ldb.add({
491 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
492 "objectclass": "group"})
494 # modify operation
496 m = Message()
497 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
498 m["thisdoesnotexist"] = MessageElement("x", FLAG_MOD_REPLACE,
499 "thisdoesnotexist")
500 try:
501 ldb.modify(m)
502 self.fail()
503 except LdbError, (num, _):
504 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
506 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
508 # attributes not in objectclasses and mandatory attributes missing test
509 # Use here a non-SAM entry since it doesn't have special triggers
510 # associated which have an impact on the error results.
512 # add operations
514 # mandatory attribute missing
515 try:
516 self.ldb.add({
517 "dn": "cn=ldaptestobject," + self.base_dn,
518 "objectclass": "ipProtocol"})
519 self.fail()
520 except LdbError, (num, _):
521 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
523 # inadequate but schema-valid attribute specified
524 try:
525 self.ldb.add({
526 "dn": "cn=ldaptestobject," + self.base_dn,
527 "objectclass": "ipProtocol",
528 "ipProtocolNumber": "1",
529 "uid" : "0"})
530 self.fail()
531 except LdbError, (num, _):
532 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
534 self.ldb.add({
535 "dn": "cn=ldaptestobject," + self.base_dn,
536 "objectclass": "ipProtocol",
537 "ipProtocolNumber": "1"})
539 # modify operations
541 # inadequate but schema-valid attribute add trial
542 m = Message()
543 m.dn = Dn(ldb, "cn=ldaptestobject," + self.base_dn)
544 m["uid"] = MessageElement("0", FLAG_MOD_ADD, "uid")
545 try:
546 ldb.modify(m)
547 self.fail()
548 except LdbError, (num, _):
549 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
551 # mandatory attribute delete trial
552 m = Message()
553 m.dn = Dn(ldb, "cn=ldaptestobject," + self.base_dn)
554 m["ipProtocolNumber"] = MessageElement([], FLAG_MOD_DELETE,
555 "ipProtocolNumber")
556 try:
557 ldb.modify(m)
558 self.fail()
559 except LdbError, (num, _):
560 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
562 # mandatory attribute delete trial
563 m = Message()
564 m.dn = Dn(ldb, "cn=ldaptestobject," + self.base_dn)
565 m["ipProtocolNumber"] = MessageElement([], FLAG_MOD_REPLACE,
566 "ipProtocolNumber")
567 try:
568 ldb.modify(m)
569 self.fail()
570 except LdbError, (num, _):
571 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
573 self.delete_force(self.ldb, "cn=ldaptestobject," + self.base_dn)
575 def test_single_valued_attributes(self):
576 """Test single-valued attributes"""
577 print "Test single-valued attributes"""
579 try:
580 self.ldb.add({
581 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
582 "objectclass": "group",
583 "sAMAccountName": ["nam1", "nam2"]})
584 self.fail()
585 except LdbError, (num, _):
586 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
588 self.ldb.add({
589 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
590 "objectclass": "group"})
592 m = Message()
593 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
594 m["sAMAccountName"] = MessageElement(["nam1","nam2"], FLAG_MOD_REPLACE,
595 "sAMAccountName")
596 try:
597 ldb.modify(m)
598 self.fail()
599 except LdbError, (num, _):
600 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
602 m = Message()
603 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
604 m["sAMAccountName"] = MessageElement("testgroupXX", FLAG_MOD_REPLACE,
605 "sAMAccountName")
606 ldb.modify(m)
608 m = Message()
609 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
610 m["sAMAccountName"] = MessageElement("testgroupXX2", FLAG_MOD_ADD,
611 "sAMAccountName")
612 try:
613 ldb.modify(m)
614 self.fail()
615 except LdbError, (num, _):
616 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
618 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
620 def test_description_attribute(self):
621 """Test description attribute"""
622 print "Test description attribute"""
624 self.ldb.add({
625 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
626 "description": "desc2",
627 "objectclass": "group",
628 "description": "desc1"})
630 res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
631 scope=SCOPE_BASE, attrs=["description"])
632 self.assertTrue(len(res) == 1)
633 self.assertTrue("description" in res[0])
634 self.assertTrue(len(res[0]["description"]) == 1)
635 self.assertEquals(res[0]["description"][0], "desc1")
637 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
639 self.ldb.add({
640 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
641 "objectclass": "group",
642 "description": ["desc1", "desc2"]})
644 res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
645 scope=SCOPE_BASE, attrs=["description"])
646 self.assertTrue(len(res) == 1)
647 self.assertTrue("description" in res[0])
648 self.assertTrue(len(res[0]["description"]) == 2)
649 self.assertTrue(res[0]["description"][0] == "desc1" or
650 res[0]["description"][1] == "desc1")
651 self.assertTrue(res[0]["description"][0] == "desc2" or
652 res[0]["description"][1] == "desc2")
654 m = Message()
655 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
656 m["description"] = MessageElement(["desc1","desc2"], FLAG_MOD_REPLACE,
657 "description")
658 try:
659 ldb.modify(m)
660 self.fail()
661 except LdbError, (num, _):
662 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
664 m = Message()
665 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
666 m["description"] = MessageElement(["desc1","desc2"], FLAG_MOD_DELETE,
667 "description")
668 ldb.modify(m)
670 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
672 self.ldb.add({
673 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
674 "objectclass": "group" })
676 m = Message()
677 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
678 m["description"] = MessageElement("desc1", FLAG_MOD_REPLACE,
679 "description")
680 ldb.modify(m)
682 res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
683 scope=SCOPE_BASE, attrs=["description"])
684 self.assertTrue(len(res) == 1)
685 self.assertTrue("description" in res[0])
686 self.assertTrue(len(res[0]["description"]) == 1)
687 self.assertEquals(res[0]["description"][0], "desc1")
689 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
691 self.ldb.add({
692 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
693 "objectclass": "group",
694 "description": ["desc1", "desc2"]})
696 m = Message()
697 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
698 m["description"] = MessageElement("desc1", FLAG_MOD_REPLACE,
699 "description")
700 ldb.modify(m)
702 res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
703 scope=SCOPE_BASE, attrs=["description"])
704 self.assertTrue(len(res) == 1)
705 self.assertTrue("description" in res[0])
706 self.assertTrue(len(res[0]["description"]) == 1)
707 self.assertEquals(res[0]["description"][0], "desc1")
709 m = Message()
710 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
711 m["description"] = MessageElement("desc3", FLAG_MOD_ADD,
712 "description")
713 try:
714 ldb.modify(m)
715 self.fail()
716 except LdbError, (num, _):
717 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
719 m = Message()
720 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
721 m["description"] = MessageElement(["desc1","desc2"], FLAG_MOD_DELETE,
722 "description")
723 try:
724 ldb.modify(m)
725 self.fail()
726 except LdbError, (num, _):
727 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
729 m = Message()
730 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
731 m["description"] = MessageElement("desc1", FLAG_MOD_DELETE,
732 "description")
733 ldb.modify(m)
734 res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
735 scope=SCOPE_BASE, attrs=["description"])
736 self.assertTrue(len(res) == 1)
737 self.assertFalse("description" in res[0])
739 m = Message()
740 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
741 m["description"] = MessageElement(["desc1","desc2"], FLAG_MOD_REPLACE,
742 "description")
743 try:
744 ldb.modify(m)
745 self.fail()
746 except LdbError, (num, _):
747 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
749 m = Message()
750 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
751 m["description"] = MessageElement(["desc3", "desc4"], FLAG_MOD_ADD,
752 "description")
753 try:
754 ldb.modify(m)
755 self.fail()
756 except LdbError, (num, _):
757 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
759 m = Message()
760 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
761 m["description"] = MessageElement("desc1", FLAG_MOD_ADD,
762 "description")
763 ldb.modify(m)
765 res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
766 scope=SCOPE_BASE, attrs=["description"])
767 self.assertTrue(len(res) == 1)
768 self.assertTrue("description" in res[0])
769 self.assertTrue(len(res[0]["description"]) == 1)
770 self.assertEquals(res[0]["description"][0], "desc1")
772 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
774 def test_attribute_ranges(self):
775 """Test attribute ranges"""
776 print "Test attribute ranges"""
778 # Too short (min. 1)
779 try:
780 ldb.add({
781 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
782 "objectClass": "person",
783 "sn": "" })
784 self.fail()
785 except LdbError, (num, _):
786 self.assertEquals(num, ERR_INVALID_ATTRIBUTE_SYNTAX)
788 # Too long (max. 64)
789 # try:
790 # ldb.add({
791 # "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
792 # "objectClass": "person",
793 # "sn": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" })
794 # self.fail()
795 # except LdbError, (num, _):
796 # self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
798 ldb.add({
799 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
800 "objectClass": "person" })
802 # Too short (min. 1)
803 m = Message()
804 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
805 m["sn"] = MessageElement("", FLAG_MOD_REPLACE, "sn")
806 try:
807 ldb.modify(m)
808 self.fail()
809 except LdbError, (num, _):
810 self.assertEquals(num, ERR_INVALID_ATTRIBUTE_SYNTAX)
812 # Too long (max. 64)
813 # m = Message()
814 # m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
815 # m["sn"] = MessageElement("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", FLAG_MOD_REPLACE, "sn")
816 # try:
817 # ldb.modify(m)
818 # self.fail()
819 # except LdbError, (num, _):
820 # self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
822 m = Message()
823 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
824 m["sn"] = MessageElement("x", FLAG_MOD_REPLACE, "sn")
825 ldb.modify(m)
827 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
829 def test_empty_messages(self):
830 """Test empty messages"""
831 print "Test empty messages"""
833 m = Message()
834 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
836 try:
837 ldb.add(m)
838 self.fail()
839 except LdbError, (num, _):
840 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
842 try:
843 ldb.modify(m)
844 self.fail()
845 except LdbError, (num, _):
846 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
848 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
850 def test_empty_attributes(self):
851 """Test empty attributes"""
852 print "Test empty attributes"""
854 m = Message()
855 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
856 m["objectClass"] = MessageElement("group", FLAG_MOD_ADD, "objectClass")
857 m["description"] = MessageElement([], FLAG_MOD_ADD, "description")
859 try:
860 ldb.add(m)
861 self.fail()
862 except LdbError, (num, _):
863 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
865 self.ldb.add({
866 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
867 "objectclass": "group"})
869 m = Message()
870 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
871 m["description"] = MessageElement([], FLAG_MOD_ADD, "description")
873 try:
874 ldb.modify(m)
875 self.fail()
876 except LdbError, (num, _):
877 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
879 m = Message()
880 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
881 m["description"] = MessageElement([], FLAG_MOD_REPLACE, "description")
882 ldb.modify(m)
884 m = Message()
885 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
886 m["description"] = MessageElement([], FLAG_MOD_DELETE, "description")
887 try:
888 ldb.modify(m)
889 self.fail()
890 except LdbError, (num, _):
891 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
893 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
895 def test_instanceType(self):
896 """Tests the 'instanceType' attribute"""
897 print "Tests the 'instanceType' attribute"""
899 # The instance type is single-valued
900 try:
901 self.ldb.add({
902 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
903 "objectclass": "group",
904 "instanceType": ["0", "1"]})
905 self.fail()
906 except LdbError, (num, _):
907 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
909 # The head NC flag cannot be set without the write flag
910 try:
911 self.ldb.add({
912 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
913 "objectclass": "group",
914 "instanceType": "1" })
915 self.fail()
916 except LdbError, (num, _):
917 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
919 # We cannot manipulate NCs without the head NC flag
920 try:
921 self.ldb.add({
922 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
923 "objectclass": "group",
924 "instanceType": "32" })
925 self.fail()
926 except LdbError, (num, _):
927 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
929 self.ldb.add({
930 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
931 "objectclass": "group"})
933 m = Message()
934 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
935 m["instanceType"] = MessageElement("0", FLAG_MOD_REPLACE,
936 "instanceType")
937 try:
938 ldb.modify(m)
939 self.fail()
940 except LdbError, (num, _):
941 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
943 m = Message()
944 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
945 m["instanceType"] = MessageElement([], FLAG_MOD_REPLACE,
946 "instanceType")
947 try:
948 ldb.modify(m)
949 self.fail()
950 except LdbError, (num, _):
951 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
953 m = Message()
954 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
955 m["instanceType"] = MessageElement([], FLAG_MOD_DELETE, "instanceType")
956 try:
957 ldb.modify(m)
958 self.fail()
959 except LdbError, (num, _):
960 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
962 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
964 def test_distinguished_name(self):
965 """Tests the 'distinguishedName' attribute"""
966 print "Tests the 'distinguishedName' attribute"""
968 # The "dn" shortcut isn't supported
969 m = Message()
970 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
971 m["objectClass"] = MessageElement("group", 0, "objectClass")
972 m["dn"] = MessageElement("cn=ldaptestgroup,cn=users," + self.base_dn, 0,
973 "dn")
974 try:
975 ldb.add(m)
976 self.fail()
977 except LdbError, (num, _):
978 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
980 # a wrong "distinguishedName" attribute is obviously tolerated
981 self.ldb.add({
982 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
983 "objectclass": "group",
984 "distinguishedName": "cn=ldaptest,cn=users," + self.base_dn})
986 # proof if the DN has been set correctly
987 res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
988 scope=SCOPE_BASE, attrs=["distinguishedName"])
989 self.assertTrue(len(res) == 1)
990 self.assertTrue("distinguishedName" in res[0])
991 self.assertTrue(Dn(ldb, res[0]["distinguishedName"][0])
992 == Dn(ldb, "cn=ldaptestgroup, cn=users," + self.base_dn))
994 # The "dn" shortcut isn't supported
995 m = Message()
996 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
997 m["dn"] = MessageElement(
998 "cn=ldaptestgroup,cn=users," + self.base_dn, FLAG_MOD_REPLACE,
999 "dn")
1000 try:
1001 ldb.modify(m)
1002 self.fail()
1003 except LdbError, (num, _):
1004 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
1006 m = Message()
1007 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1008 m["distinguishedName"] = MessageElement(
1009 "cn=ldaptestuser,cn=users," + self.base_dn, FLAG_MOD_ADD,
1010 "distinguishedName")
1012 try:
1013 ldb.modify(m)
1014 self.fail()
1015 except LdbError, (num, _):
1016 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
1018 m = Message()
1019 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1020 m["distinguishedName"] = MessageElement(
1021 "cn=ldaptestuser,cn=users," + self.base_dn, FLAG_MOD_REPLACE,
1022 "distinguishedName")
1024 try:
1025 ldb.modify(m)
1026 self.fail()
1027 except LdbError, (num, _):
1028 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
1030 m = Message()
1031 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1032 m["distinguishedName"] = MessageElement(
1033 "cn=ldaptestuser,cn=users," + self.base_dn, FLAG_MOD_DELETE,
1034 "distinguishedName")
1036 try:
1037 ldb.modify(m)
1038 self.fail()
1039 except LdbError, (num, _):
1040 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
1042 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1044 def test_rdn_name(self):
1045 """Tests the RDN"""
1046 print "Tests the RDN"""
1048 try:
1049 self.ldb.add({
1050 "dn": "description=xyz,cn=users," + self.base_dn,
1051 "objectclass": "group"})
1052 self.fail()
1053 except LdbError, (num, _):
1054 self.assertEquals(num, ERR_NAMING_VIOLATION)
1056 self.delete_force(self.ldb, "description=xyz,cn=users," + self.base_dn)
1058 # a wrong "name" attribute is obviously tolerated
1059 self.ldb.add({
1060 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
1061 "objectclass": "group",
1062 "name": "ldaptestgroupx"})
1064 # proof if the name has been set correctly
1065 res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
1066 scope=SCOPE_BASE, attrs=["name"])
1067 self.assertTrue(len(res) == 1)
1068 self.assertTrue("name" in res[0])
1069 self.assertTrue(res[0]["name"][0] == "ldaptestgroup")
1071 m = Message()
1072 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1073 m["name"] = MessageElement("cn=ldaptestuser", FLAG_MOD_REPLACE,
1074 "name")
1075 try:
1076 ldb.modify(m)
1077 self.fail()
1078 except LdbError, (num, _):
1079 self.assertEquals(num, ERR_NOT_ALLOWED_ON_RDN)
1081 m = Message()
1082 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1083 m["cn"] = MessageElement("ldaptestuser",
1084 FLAG_MOD_REPLACE, "cn")
1085 try:
1086 ldb.modify(m)
1087 self.fail()
1088 except LdbError, (num, _):
1089 self.assertEquals(num, ERR_NOT_ALLOWED_ON_RDN)
1091 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1094 # this test needs to be disabled until we really understand
1095 # what the rDN length constraints are
1096 def DISABLED_test_largeRDN(self):
1097 """Testing large rDN (limit 64 characters)"""
1098 rdn = "CN=a012345678901234567890123456789012345678901234567890123456789012";
1099 self.delete_force(self.ldb, "%s,%s" % (rdn, self.base_dn))
1100 ldif = """
1101 dn: %s,%s""" % (rdn,self.base_dn) + """
1102 objectClass: container
1104 self.ldb.add_ldif(ldif)
1105 self.delete_force(self.ldb, "%s,%s" % (rdn, self.base_dn))
1107 rdn = "CN=a0123456789012345678901234567890123456789012345678901234567890120";
1108 self.delete_force(self.ldb, "%s,%s" % (rdn, self.base_dn))
1109 try:
1110 ldif = """
1111 dn: %s,%s""" % (rdn,self.base_dn) + """
1112 objectClass: container
1114 self.ldb.add_ldif(ldif)
1115 self.fail()
1116 except LdbError, (num, _):
1117 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
1118 self.delete_force(self.ldb, "%s,%s" % (rdn, self.base_dn))
1120 def test_rename(self):
1121 """Tests the rename operation"""
1122 print "Tests the rename operations"""
1124 try:
1125 # cannot rename to be a child of itself
1126 ldb.rename(self.base_dn, "dc=test," + self.base_dn)
1127 self.fail()
1128 except LdbError, (num, _):
1129 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1131 try:
1132 # inexistent object
1133 ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser2,cn=users," + self.base_dn)
1134 self.fail()
1135 except LdbError, (num, _):
1136 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
1138 self.ldb.add({
1139 "dn": "cn=ldaptestuser2,cn=users," + self.base_dn,
1140 "objectclass": "user" })
1142 ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser2,cn=users," + self.base_dn)
1143 ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=users," + self.base_dn)
1144 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestUSER3,cn=users," + self.base_dn)
1146 try:
1147 # containment problem: a user entry cannot contain user entries
1148 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser4,cn=ldaptestuser3,cn=users," + self.base_dn)
1149 self.fail()
1150 except LdbError, (num, _):
1151 self.assertEquals(num, ERR_NAMING_VIOLATION)
1153 try:
1154 # invalid parent
1155 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=people,cn=users," + self.base_dn)
1156 self.fail()
1157 except LdbError, (num, _):
1158 self.assertEquals(num, ERR_OTHER)
1160 try:
1161 # invalid target DN syntax
1162 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, ",cn=users," + self.base_dn)
1163 self.fail()
1164 except LdbError, (num, _):
1165 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1167 try:
1168 # invalid RDN name
1169 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "ou=ldaptestuser3,cn=users," + self.base_dn)
1170 self.fail()
1171 except LdbError, (num, _):
1172 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1174 self.delete_force(self.ldb, "cn=ldaptestuser3,cn=users," + self.base_dn)
1176 # Performs some "systemFlags" testing
1178 # Move failing since no "SYSTEM_FLAG_CONFIG_ALLOW_MOVE"
1179 try:
1180 ldb.rename("CN=DisplaySpecifiers," + self.configuration_dn, "CN=DisplaySpecifiers,CN=Services," + self.configuration_dn)
1181 self.fail()
1182 except LdbError, (num, _):
1183 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1185 # Limited move failing since no "SYSTEM_FLAG_CONFIG_ALLOW_LIMITED_MOVE"
1186 try:
1187 ldb.rename("CN=Directory Service,CN=Windows NT,CN=Services," + self.configuration_dn, "CN=Directory Service,CN=RRAS,CN=Services," + self.configuration_dn)
1188 self.fail()
1189 except LdbError, (num, _):
1190 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1192 # Rename failing since no "SYSTEM_FLAG_CONFIG_ALLOW_RENAME"
1193 try:
1194 ldb.rename("CN=DisplaySpecifiers," + self.configuration_dn, "CN=DisplaySpecifiers2," + self.configuration_dn)
1195 self.fail()
1196 except LdbError, (num, _):
1197 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1199 # It's not really possible to test moves on the schema partition since
1200 # there don't exist subcontainers on it.
1202 # Rename failing since "SYSTEM_FLAG_SCHEMA_BASE_OBJECT"
1203 try:
1204 ldb.rename("CN=Top," + self.schema_dn, "CN=Top2," + self.schema_dn)
1205 self.fail()
1206 except LdbError, (num, _):
1207 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1209 # Move failing since "SYSTEM_FLAG_DOMAIN_DISALLOW_MOVE"
1210 try:
1211 ldb.rename("CN=Users," + self.base_dn, "CN=Users,CN=Computers," + self.base_dn)
1212 self.fail()
1213 except LdbError, (num, _):
1214 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1216 # Rename failing since "SYSTEM_FLAG_DOMAIN_DISALLOW_RENAME"
1217 try:
1218 ldb.rename("CN=Users," + self.base_dn, "CN=Users2," + self.base_dn)
1219 self.fail()
1220 except LdbError, (num, _):
1221 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1223 # Performs some other constraints testing
1225 try:
1226 ldb.rename("CN=Policies,CN=System," + self.base_dn, "CN=Users2," + self.base_dn)
1227 self.fail()
1228 except LdbError, (num, _):
1229 self.assertEquals(num, ERR_OTHER)
1231 def test_rename_twice(self):
1232 """Tests the rename operation twice - this corresponds to a past bug"""
1233 print "Tests the rename twice operation"""
1235 self.ldb.add({
1236 "dn": "cn=ldaptestuser5,cn=users," + self.base_dn,
1237 "objectclass": "user" })
1239 ldb.rename("cn=ldaptestuser5,cn=users," + self.base_dn, "cn=ldaptestUSER5,cn=users," + self.base_dn)
1240 self.delete_force(self.ldb, "cn=ldaptestuser5,cn=users," + self.base_dn)
1241 self.ldb.add({
1242 "dn": "cn=ldaptestuser5,cn=users," + self.base_dn,
1243 "objectclass": "user" })
1244 ldb.rename("cn=ldaptestuser5,cn=Users," + self.base_dn, "cn=ldaptestUSER5,cn=users," + self.base_dn)
1245 res = ldb.search(expression="cn=ldaptestuser5")
1246 print "Found %u records" % len(res)
1247 self.assertEquals(len(res), 1, "Wrong number of hits for cn=ldaptestuser5")
1248 res = ldb.search(expression="(&(cn=ldaptestuser5)(objectclass=user))")
1249 print "Found %u records" % len(res)
1250 self.assertEquals(len(res), 1, "Wrong number of hits for (&(cn=ldaptestuser5)(objectclass=user))")
1251 self.delete_force(self.ldb, "cn=ldaptestuser5,cn=users," + self.base_dn)
1253 def test_parentGUID(self):
1254 """Test parentGUID behaviour"""
1255 print "Testing parentGUID behaviour\n"
1257 # TODO: This seems to fail on Windows Server. Hidden attribute?
1259 self.ldb.add({
1260 "dn": "cn=parentguidtest,cn=users," + self.base_dn,
1261 "objectclass":"user",
1262 "samaccountname":"parentguidtest"});
1263 res1 = ldb.search(base="cn=parentguidtest,cn=users," + self.base_dn, scope=SCOPE_BASE,
1264 attrs=["parentGUID", "samaccountname"]);
1265 res2 = ldb.search(base="cn=users," + self.base_dn,scope=SCOPE_BASE,
1266 attrs=["objectGUID"]);
1267 res3 = ldb.search(base=self.base_dn, scope=SCOPE_BASE,
1268 attrs=["parentGUID"]);
1269 res4 = ldb.search(base=self.configuration_dn, scope=SCOPE_BASE,
1270 attrs=["parentGUID"]);
1271 res5 = ldb.search(base=self.schema_dn, scope=SCOPE_BASE,
1272 attrs=["parentGUID"]);
1274 """Check if the parentGUID is valid """
1275 self.assertEquals(res1[0]["parentGUID"], res2[0]["objectGUID"]);
1277 """Check if it returns nothing when there is no parent object - default NC"""
1278 has_parentGUID = False
1279 for key in res3[0].keys():
1280 if key == "parentGUID":
1281 has_parentGUID = True
1282 break
1283 self.assertFalse(has_parentGUID);
1285 """Check if it returns nothing when there is no parent object - configuration NC"""
1286 has_parentGUID = False
1287 for key in res4[0].keys():
1288 if key == "parentGUID":
1289 has_parentGUID = True
1290 break
1291 self.assertFalse(has_parentGUID);
1293 """Check if it returns nothing when there is no parent object - schema NC"""
1294 has_parentGUID = False
1295 for key in res5[0].keys():
1296 if key == "parentGUID":
1297 has_parentGUID = True
1298 break
1299 self.assertFalse(has_parentGUID);
1301 """Ensures that if you look for another object attribute after the constructed
1302 parentGUID, it will return correctly"""
1303 has_another_attribute = False
1304 for key in res1[0].keys():
1305 if key == "sAMAccountName":
1306 has_another_attribute = True
1307 break
1308 self.assertTrue(has_another_attribute)
1309 self.assertTrue(len(res1[0]["samaccountname"]) == 1)
1310 self.assertEquals(res1[0]["samaccountname"][0], "parentguidtest");
1312 print "Testing parentGUID behaviour on rename\n"
1314 self.ldb.add({
1315 "dn": "cn=testotherusers," + self.base_dn,
1316 "objectclass":"container"});
1317 res1 = ldb.search(base="cn=testotherusers," + self.base_dn,scope=SCOPE_BASE,
1318 attrs=["objectGUID"]);
1319 ldb.rename("cn=parentguidtest,cn=users," + self.base_dn,
1320 "cn=parentguidtest,cn=testotherusers," + self.base_dn);
1321 res2 = ldb.search(base="cn=parentguidtest,cn=testotherusers," + self.base_dn,
1322 scope=SCOPE_BASE,
1323 attrs=["parentGUID"]);
1324 self.assertEquals(res1[0]["objectGUID"], res2[0]["parentGUID"]);
1326 self.delete_force(self.ldb, "cn=parentguidtest,cn=testotherusers," + self.base_dn)
1327 self.delete_force(self.ldb, "cn=testotherusers," + self.base_dn)
1329 def test_groupType_int32(self):
1330 """Test groupType (int32) behaviour (should appear to be casted to a 32 bit signed integer before comparsion)"""
1331 print "Testing groupType (int32) behaviour\n"
1333 res1 = ldb.search(base=self.base_dn, scope=SCOPE_SUBTREE,
1334 attrs=["groupType"], expression="groupType=2147483653");
1336 res2 = ldb.search(base=self.base_dn, scope=SCOPE_SUBTREE,
1337 attrs=["groupType"], expression="groupType=-2147483643");
1339 self.assertEquals(len(res1), len(res2))
1341 self.assertTrue(res1.count > 0)
1343 self.assertEquals(res1[0]["groupType"][0], "-2147483643")
1345 def test_linked_attributes(self):
1346 """This tests the linked attribute behaviour"""
1347 print "Testing linked attribute behaviour\n"
1349 ldb.add({
1350 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
1351 "objectclass": "group"})
1353 # This should not work since "memberOf" is linked to "member"
1354 try:
1355 ldb.add({
1356 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1357 "objectclass": "user",
1358 "memberOf": "cn=ldaptestgroup,cn=users," + self.base_dn})
1359 except LdbError, (num, _):
1360 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1362 ldb.add({
1363 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1364 "objectclass": "user"})
1366 m = Message()
1367 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1368 m["memberOf"] = MessageElement("cn=ldaptestgroup,cn=users," + self.base_dn,
1369 FLAG_MOD_ADD, "memberOf")
1370 try:
1371 ldb.modify(m)
1372 self.fail()
1373 except LdbError, (num, _):
1374 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1376 m = Message()
1377 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1378 m["member"] = MessageElement("cn=ldaptestuser,cn=users," + self.base_dn,
1379 FLAG_MOD_ADD, "member")
1380 ldb.modify(m)
1382 m = Message()
1383 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1384 m["memberOf"] = MessageElement("cn=ldaptestgroup,cn=users," + self.base_dn,
1385 FLAG_MOD_REPLACE, "memberOf")
1386 try:
1387 ldb.modify(m)
1388 self.fail()
1389 except LdbError, (num, _):
1390 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1392 m = Message()
1393 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1394 m["memberOf"] = MessageElement("cn=ldaptestgroup,cn=users," + self.base_dn,
1395 FLAG_MOD_DELETE, "memberOf")
1396 try:
1397 ldb.modify(m)
1398 self.fail()
1399 except LdbError, (num, _):
1400 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1402 m = Message()
1403 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1404 m["member"] = MessageElement("cn=ldaptestuser,cn=users," + self.base_dn,
1405 FLAG_MOD_DELETE, "member")
1406 ldb.modify(m)
1408 # This should yield no results since the member attribute for
1409 # "ldaptestuser" should have been deleted
1410 res1 = ldb.search("cn=ldaptestgroup, cn=users," + self.base_dn,
1411 scope=SCOPE_BASE,
1412 expression="(member=cn=ldaptestuser,cn=users," + self.base_dn + ")",
1413 attrs=[])
1414 self.assertTrue(len(res1) == 0)
1416 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1418 ldb.add({
1419 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
1420 "objectclass": "group",
1421 "member": "cn=ldaptestuser,cn=users," + self.base_dn})
1423 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1425 # Make sure that the "member" attribute for "ldaptestuser" has been
1426 # removed
1427 res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
1428 scope=SCOPE_BASE, attrs=["member"])
1429 self.assertTrue(len(res) == 1)
1430 self.assertFalse("member" in res[0])
1432 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1434 def test_wkguid(self):
1435 """Test Well known GUID behaviours (including DN+Binary)"""
1436 print "Test Well known GUID behaviours (including DN+Binary)"""
1438 res = self.ldb.search(base=("<WKGUID=ab1d30f3768811d1aded00c04fd8d5cd,%s>" % self.base_dn), scope=SCOPE_BASE, attrs=[])
1439 self.assertEquals(len(res), 1)
1441 res2 = self.ldb.search(scope=SCOPE_BASE, attrs=["wellKnownObjects"], expression=("wellKnownObjects=B:32:ab1d30f3768811d1aded00c04fd8d5cd:%s" % res[0].dn))
1442 self.assertEquals(len(res2), 1)
1444 # Prove that the matching rule is over the whole DN+Binary
1445 res2 = self.ldb.search(scope=SCOPE_BASE, attrs=["wellKnownObjects"], expression=("wellKnownObjects=B:32:ab1d30f3768811d1aded00c04fd8d5cd"))
1446 self.assertEquals(len(res2), 0)
1447 # Prove that the matching rule is over the whole DN+Binary
1448 res2 = self.ldb.search(scope=SCOPE_BASE, attrs=["wellKnownObjects"], expression=("wellKnownObjects=%s") % res[0].dn)
1449 self.assertEquals(len(res2), 0)
1451 def test_subschemasubentry(self):
1452 """Test subSchemaSubEntry appears when requested, but not when not requested"""
1453 print "Test subSchemaSubEntry"""
1455 res = self.ldb.search(base=self.base_dn, scope=SCOPE_BASE, attrs=["subSchemaSubEntry"])
1456 self.assertEquals(len(res), 1)
1457 self.assertEquals(res[0]["subSchemaSubEntry"][0], "CN=Aggregate,"+self.schema_dn)
1459 res = self.ldb.search(base=self.base_dn, scope=SCOPE_BASE, attrs=["*"])
1460 self.assertEquals(len(res), 1)
1461 self.assertTrue("subScheamSubEntry" not in res[0])
1463 def test_all(self):
1464 """Basic tests"""
1466 print "Testing user add"
1468 ldb.add({
1469 "dn": "cn=ldaptestuser,cn=uSers," + self.base_dn,
1470 "objectclass": "user",
1471 "cN": "LDAPtestUSER",
1472 "givenname": "ldap",
1473 "sn": "testy"})
1475 ldb.add({
1476 "dn": "cn=ldaptestgroup,cn=uSers," + self.base_dn,
1477 "objectclass": "group",
1478 "member": "cn=ldaptestuser,cn=useRs," + self.base_dn})
1480 ldb.add({
1481 "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
1482 "objectclass": "computer",
1483 "cN": "LDAPtestCOMPUTER"})
1485 ldb.add({"dn": "cn=ldaptest2computer,cn=computers," + self.base_dn,
1486 "objectClass": "computer",
1487 "cn": "LDAPtest2COMPUTER",
1488 "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT),
1489 "displayname": "ldap testy"})
1491 try:
1492 ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn,
1493 "objectClass": "computer",
1494 "cn": "LDAPtest2COMPUTER"
1496 self.fail()
1497 except LdbError, (num, _):
1498 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1500 try:
1501 ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn,
1502 "objectClass": "computer",
1503 "cn": "ldaptestcomputer3",
1504 "sAMAccountType": str(ATYPE_NORMAL_ACCOUNT)
1506 self.fail()
1507 except LdbError, (num, _):
1508 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1510 ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn,
1511 "objectClass": "computer",
1512 "cn": "LDAPtestCOMPUTER3"
1515 print "Testing ldb.search for (&(cn=ldaptestcomputer3)(objectClass=user))";
1516 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestcomputer3)(objectClass=user))");
1517 self.assertEquals(len(res), 1, "Found only %d for (&(cn=ldaptestcomputer3)(objectClass=user))" % len(res))
1519 self.assertEquals(str(res[0].dn), ("CN=ldaptestcomputer3,CN=Computers," + self.base_dn));
1520 self.assertEquals(res[0]["cn"][0], "ldaptestcomputer3");
1521 self.assertEquals(res[0]["name"][0], "ldaptestcomputer3");
1522 self.assertEquals(res[0]["objectClass"][0], "top");
1523 self.assertEquals(res[0]["objectClass"][1], "person");
1524 self.assertEquals(res[0]["objectClass"][2], "organizationalPerson");
1525 self.assertEquals(res[0]["objectClass"][3], "user");
1526 self.assertEquals(res[0]["objectClass"][4], "computer");
1527 self.assertTrue("objectGUID" in res[0])
1528 self.assertTrue("whenCreated" in res[0])
1529 self.assertEquals(res[0]["objectCategory"][0], ("CN=Computer,CN=Schema,CN=Configuration," + self.base_dn));
1530 self.assertEquals(int(res[0]["primaryGroupID"][0]), 513);
1531 self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_NORMAL_ACCOUNT);
1532 self.assertEquals(int(res[0]["userAccountControl"][0]), UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE);
1534 self.delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
1536 print "Testing attribute or value exists behaviour"
1537 try:
1538 ldb.modify_ldif("""
1539 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1540 changetype: modify
1541 replace: servicePrincipalName
1542 servicePrincipalName: host/ldaptest2computer
1543 servicePrincipalName: host/ldaptest2computer
1544 servicePrincipalName: cifs/ldaptest2computer
1545 """)
1546 self.fail()
1547 except LdbError, (num, msg):
1548 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
1550 ldb.modify_ldif("""
1551 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1552 changetype: modify
1553 replace: servicePrincipalName
1554 servicePrincipalName: host/ldaptest2computer
1555 servicePrincipalName: cifs/ldaptest2computer
1556 """)
1557 try:
1558 ldb.modify_ldif("""
1559 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1560 changetype: modify
1561 add: servicePrincipalName
1562 servicePrincipalName: host/ldaptest2computer
1563 """)
1564 self.fail()
1565 except LdbError, (num, msg):
1566 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
1568 print "Testing ranged results"
1569 ldb.modify_ldif("""
1570 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1571 changetype: modify
1572 replace: servicePrincipalName
1573 """)
1575 ldb.modify_ldif("""
1576 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1577 changetype: modify
1578 add: servicePrincipalName
1579 servicePrincipalName: host/ldaptest2computer0
1580 servicePrincipalName: host/ldaptest2computer1
1581 servicePrincipalName: host/ldaptest2computer2
1582 servicePrincipalName: host/ldaptest2computer3
1583 servicePrincipalName: host/ldaptest2computer4
1584 servicePrincipalName: host/ldaptest2computer5
1585 servicePrincipalName: host/ldaptest2computer6
1586 servicePrincipalName: host/ldaptest2computer7
1587 servicePrincipalName: host/ldaptest2computer8
1588 servicePrincipalName: host/ldaptest2computer9
1589 servicePrincipalName: host/ldaptest2computer10
1590 servicePrincipalName: host/ldaptest2computer11
1591 servicePrincipalName: host/ldaptest2computer12
1592 servicePrincipalName: host/ldaptest2computer13
1593 servicePrincipalName: host/ldaptest2computer14
1594 servicePrincipalName: host/ldaptest2computer15
1595 servicePrincipalName: host/ldaptest2computer16
1596 servicePrincipalName: host/ldaptest2computer17
1597 servicePrincipalName: host/ldaptest2computer18
1598 servicePrincipalName: host/ldaptest2computer19
1599 servicePrincipalName: host/ldaptest2computer20
1600 servicePrincipalName: host/ldaptest2computer21
1601 servicePrincipalName: host/ldaptest2computer22
1602 servicePrincipalName: host/ldaptest2computer23
1603 servicePrincipalName: host/ldaptest2computer24
1604 servicePrincipalName: host/ldaptest2computer25
1605 servicePrincipalName: host/ldaptest2computer26
1606 servicePrincipalName: host/ldaptest2computer27
1607 servicePrincipalName: host/ldaptest2computer28
1608 servicePrincipalName: host/ldaptest2computer29
1609 """)
1611 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE,
1612 attrs=["servicePrincipalName;range=0-*"])
1613 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1614 #print len(res[0]["servicePrincipalName;range=0-*"])
1615 self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30)
1617 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-19"])
1618 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1619 # print res[0]["servicePrincipalName;range=0-19"].length
1620 self.assertEquals(len(res[0]["servicePrincipalName;range=0-19"]), 20)
1623 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-30"])
1624 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1625 self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30)
1627 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-40"])
1628 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1629 self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30)
1631 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=30-40"])
1632 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1633 self.assertEquals(len(res[0]["servicePrincipalName;range=30-*"]), 0)
1636 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=10-40"])
1637 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1638 self.assertEquals(len(res[0]["servicePrincipalName;range=10-*"]), 20)
1639 # pos_11 = res[0]["servicePrincipalName;range=10-*"][18]
1641 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=11-40"])
1642 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1643 self.assertEquals(len(res[0]["servicePrincipalName;range=11-*"]), 19)
1644 # print res[0]["servicePrincipalName;range=11-*"][18]
1645 # print pos_11
1646 # self.assertEquals((res[0]["servicePrincipalName;range=11-*"][18]), pos_11)
1648 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=11-15"])
1649 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1650 self.assertEquals(len(res[0]["servicePrincipalName;range=11-15"]), 5)
1651 # self.assertEquals(res[0]["servicePrincipalName;range=11-15"][4], pos_11)
1653 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName"])
1654 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1655 # print res[0]["servicePrincipalName"][18]
1656 # print pos_11
1657 self.assertEquals(len(res[0]["servicePrincipalName"]), 30)
1658 # self.assertEquals(res[0]["servicePrincipalName"][18], pos_11)
1660 self.delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
1661 ldb.add({
1662 "dn": "cn=ldaptestuser2,cn=useRs," + self.base_dn,
1663 "objectClass": "user",
1664 "cn": "LDAPtestUSER2",
1665 "givenname": "testy",
1666 "sn": "ldap user2"})
1668 print "Testing Ambigious Name Resolution"
1669 # Testing ldb.search for (&(anr=ldap testy)(objectClass=user))
1670 res = ldb.search(expression="(&(anr=ldap testy)(objectClass=user))")
1671 self.assertEquals(len(res), 3, "Found only %d of 3 for (&(anr=ldap testy)(objectClass=user))" % len(res))
1673 # Testing ldb.search for (&(anr=testy ldap)(objectClass=user))
1674 res = ldb.search(expression="(&(anr=testy ldap)(objectClass=user))")
1675 self.assertEquals(len(res), 2, "Found only %d of 2 for (&(anr=testy ldap)(objectClass=user))" % len(res))
1677 # Testing ldb.search for (&(anr=ldap)(objectClass=user))
1678 res = ldb.search(expression="(&(anr=ldap)(objectClass=user))")
1679 self.assertEquals(len(res), 4, "Found only %d of 4 for (&(anr=ldap)(objectClass=user))" % len(res))
1681 # Testing ldb.search for (&(anr==ldap)(objectClass=user))
1682 res = ldb.search(expression="(&(anr==ldap)(objectClass=user))")
1683 self.assertEquals(len(res), 1, "Could not find (&(anr==ldap)(objectClass=user)). Found only %d for (&(anr=ldap)(objectClass=user))" % len(res))
1685 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
1686 self.assertEquals(res[0]["cn"][0], "ldaptestuser")
1687 self.assertEquals(str(res[0]["name"]), "ldaptestuser")
1689 # Testing ldb.search for (&(anr=testy)(objectClass=user))
1690 res = ldb.search(expression="(&(anr=testy)(objectClass=user))")
1691 self.assertEquals(len(res), 2, "Found only %d for (&(anr=testy)(objectClass=user))" % len(res))
1693 # Testing ldb.search for (&(anr=testy ldap)(objectClass=user))
1694 res = ldb.search(expression="(&(anr=testy ldap)(objectClass=user))")
1695 self.assertEquals(len(res), 2, "Found only %d for (&(anr=testy ldap)(objectClass=user))" % len(res))
1697 # Testing ldb.search for (&(anr==testy ldap)(objectClass=user))
1698 # this test disabled for the moment, as anr with == tests are not understood
1699 # res = ldb.search(expression="(&(anr==testy ldap)(objectClass=user))")
1700 # self.assertEquals(len(res), 1, "Found only %d for (&(anr==testy ldap)(objectClass=user))" % len(res))
1702 # self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
1703 # self.assertEquals(res[0]["cn"][0], "ldaptestuser")
1704 # self.assertEquals(res[0]["name"][0], "ldaptestuser")
1706 # Testing ldb.search for (&(anr==testy ldap)(objectClass=user))
1707 # res = ldb.search(expression="(&(anr==testy ldap)(objectClass=user))")
1708 # self.assertEquals(len(res), 1, "Could not find (&(anr==testy ldap)(objectClass=user))")
1710 # self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
1711 # self.assertEquals(res[0]["cn"][0], "ldaptestuser")
1712 # self.assertEquals(res[0]["name"][0], "ldaptestuser")
1714 # Testing ldb.search for (&(anr=testy ldap user)(objectClass=user))
1715 res = ldb.search(expression="(&(anr=testy ldap user)(objectClass=user))")
1716 self.assertEquals(len(res), 1, "Could not find (&(anr=testy ldap user)(objectClass=user))")
1718 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
1719 self.assertEquals(str(res[0]["cn"]), "ldaptestuser2")
1720 self.assertEquals(str(res[0]["name"]), "ldaptestuser2")
1722 # Testing ldb.search for (&(anr==testy ldap user2)(objectClass=user))
1723 # res = ldb.search(expression="(&(anr==testy ldap user2)(objectClass=user))")
1724 # self.assertEquals(len(res), 1, "Could not find (&(anr==testy ldap user2)(objectClass=user))")
1726 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
1727 self.assertEquals(str(res[0]["cn"]), "ldaptestuser2")
1728 self.assertEquals(str(res[0]["name"]), "ldaptestuser2")
1730 # Testing ldb.search for (&(anr==ldap user2)(objectClass=user))
1731 # res = ldb.search(expression="(&(anr==ldap user2)(objectClass=user))")
1732 # self.assertEquals(len(res), 1, "Could not find (&(anr==ldap user2)(objectClass=user))")
1734 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
1735 self.assertEquals(str(res[0]["cn"]), "ldaptestuser2")
1736 self.assertEquals(str(res[0]["name"]), "ldaptestuser2")
1738 # Testing ldb.search for (&(anr==not ldap user2)(objectClass=user))
1739 # res = ldb.search(expression="(&(anr==not ldap user2)(objectClass=user))")
1740 # self.assertEquals(len(res), 0, "Must not find (&(anr==not ldap user2)(objectClass=user))")
1742 # Testing ldb.search for (&(anr=not ldap user2)(objectClass=user))
1743 res = ldb.search(expression="(&(anr=not ldap user2)(objectClass=user))")
1744 self.assertEquals(len(res), 0, "Must not find (&(anr=not ldap user2)(objectClass=user))")
1746 # Testing ldb.search for (&(anr="testy ldap")(objectClass=user)) (ie, with quotes)
1747 # res = ldb.search(expression="(&(anr==\"testy ldap\")(objectClass=user))")
1748 # self.assertEquals(len(res), 0, "Found (&(anr==\"testy ldap\")(objectClass=user))")
1750 print "Testing Renames"
1752 attrs = ["objectGUID", "objectSid"]
1753 print "Testing ldb.search for (&(cn=ldaptestUSer2)(objectClass=user))"
1754 res_user = ldb.search(self.base_dn, expression="(&(cn=ldaptestUSer2)(objectClass=user))", scope=SCOPE_SUBTREE, attrs=attrs)
1755 self.assertEquals(len(res_user), 1, "Could not find (&(cn=ldaptestUSer2)(objectClass=user))")
1757 # Check rename works with extended/alternate DN forms
1758 ldb.rename("<SID=" + ldb.schema_format_value("objectSID", res_user[0]["objectSID"][0]) + ">" , "cn=ldaptestUSER3,cn=users," + self.base_dn)
1760 print "Testing ldb.search for (&(cn=ldaptestuser3)(objectClass=user))"
1761 res = ldb.search(expression="(&(cn=ldaptestuser3)(objectClass=user))")
1762 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser3)(objectClass=user))")
1764 self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
1765 self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3")
1766 self.assertEquals(str(res[0]["name"]), "ldaptestUSER3")
1768 #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))"
1769 res = ldb.search(expression="(&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))")
1770 self.assertEquals(len(res), 1, "(&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))")
1772 self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
1773 self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3")
1774 self.assertEquals(str(res[0]["name"]), "ldaptestUSER3")
1776 #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))"
1777 res = ldb.search(expression="(&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))")
1778 self.assertEquals(len(res), 1, "(&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))")
1780 self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
1781 self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3")
1782 self.assertEquals(str(res[0]["name"]), "ldaptestUSER3")
1784 #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))"
1785 res = ldb.search(expression="(&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))")
1786 self.assertEquals(len(res), 0, "(&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))")
1788 # This is a Samba special, and does not exist in real AD
1789 # print "Testing ldb.search for (dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")"
1790 # res = ldb.search("(dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")")
1791 # if (res.error != 0 || len(res) != 1) {
1792 # print "Could not find (dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")"
1793 # self.assertEquals(len(res), 1)
1795 # self.assertEquals(res[0].dn, ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
1796 # self.assertEquals(res[0].cn, "ldaptestUSER3")
1797 # self.assertEquals(res[0].name, "ldaptestUSER3")
1799 print "Testing ldb.search for (distinguishedName=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")"
1800 res = ldb.search(expression="(distinguishedName=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")")
1801 self.assertEquals(len(res), 1, "Could not find (dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")")
1802 self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
1803 self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3")
1804 self.assertEquals(str(res[0]["name"]), "ldaptestUSER3")
1806 # ensure we cannot add it again
1807 try:
1808 ldb.add({"dn": "cn=ldaptestuser3,cn=userS," + self.base_dn,
1809 "objectClass": "user",
1810 "cn": "LDAPtestUSER3"})
1811 self.fail()
1812 except LdbError, (num, _):
1813 self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
1815 # rename back
1816 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser2,cn=users," + self.base_dn)
1818 # ensure we cannot rename it twice
1819 try:
1820 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn,
1821 "cn=ldaptestuser2,cn=users," + self.base_dn)
1822 self.fail()
1823 except LdbError, (num, _):
1824 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
1826 # ensure can now use that name
1827 ldb.add({"dn": "cn=ldaptestuser3,cn=users," + self.base_dn,
1828 "objectClass": "user",
1829 "cn": "LDAPtestUSER3"})
1831 # ensure we now cannot rename
1832 try:
1833 ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=users," + self.base_dn)
1834 self.fail()
1835 except LdbError, (num, _):
1836 self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
1837 try:
1838 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=configuration," + self.base_dn)
1839 self.fail()
1840 except LdbError, (num, _):
1841 self.assertTrue(num in (71, 64))
1843 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser5,cn=users," + self.base_dn)
1845 ldb.delete("cn=ldaptestuser5,cn=users," + self.base_dn)
1847 self.delete_force(ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
1849 ldb.rename("cn=ldaptestgroup,cn=users," + self.base_dn, "cn=ldaptestgroup2,cn=users," + self.base_dn)
1851 print "Testing subtree renames"
1853 ldb.add({"dn": "cn=ldaptestcontainer," + self.base_dn,
1854 "objectClass": "container"})
1856 ldb.add({"dn": "CN=ldaptestuser4,CN=ldaptestcontainer," + self.base_dn,
1857 "objectClass": "user",
1858 "cn": "LDAPtestUSER4"})
1860 ldb.modify_ldif("""
1861 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
1862 changetype: modify
1863 add: member
1864 member: cn=ldaptestuser4,cn=ldaptestcontainer,""" + self.base_dn + """
1865 member: cn=ldaptestcomputer,cn=computers,""" + self.base_dn + """
1866 member: cn=ldaptestuser2,cn=users,""" + self.base_dn + """
1867 """)
1869 print "Testing ldb.rename of cn=ldaptestcontainer," + self.base_dn + " to cn=ldaptestcontainer2," + self.base_dn
1870 ldb.rename("CN=ldaptestcontainer," + self.base_dn, "CN=ldaptestcontainer2," + self.base_dn)
1872 print "Testing ldb.search for (&(cn=ldaptestuser4)(objectClass=user))"
1873 res = ldb.search(expression="(&(cn=ldaptestuser4)(objectClass=user))")
1874 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser4)(objectClass=user))")
1876 print "Testing subtree ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in (just renamed from) cn=ldaptestcontainer," + self.base_dn
1877 try:
1878 res = ldb.search("cn=ldaptestcontainer," + self.base_dn,
1879 expression="(&(cn=ldaptestuser4)(objectClass=user))",
1880 scope=SCOPE_SUBTREE)
1881 self.fail(res)
1882 except LdbError, (num, _):
1883 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
1885 print "Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in (just renamed from) cn=ldaptestcontainer," + self.base_dn
1886 try:
1887 res = ldb.search("cn=ldaptestcontainer," + self.base_dn,
1888 expression="(&(cn=ldaptestuser4)(objectClass=user))", scope=SCOPE_ONELEVEL)
1889 self.fail()
1890 except LdbError, (num, _):
1891 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
1893 print "Testing ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in renamed container"
1894 res = ldb.search("cn=ldaptestcontainer2," + self.base_dn, expression="(&(cn=ldaptestuser4)(objectClass=user))", scope=SCOPE_SUBTREE)
1895 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser4)(objectClass=user)) under cn=ldaptestcontainer2," + self.base_dn)
1897 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn))
1898 self.assertEquals(res[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
1900 time.sleep(4)
1902 print "Testing ldb.search for (&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn + ")(objectclass=group)) to check subtree renames and linked attributes"
1903 res = ldb.search(self.base_dn, expression="(&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn + ")(objectclass=group))", scope=SCOPE_SUBTREE)
1904 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?")
1906 print "Testing ldb.rename (into itself) of cn=ldaptestcontainer2," + self.base_dn + " to cn=ldaptestcontainer,cn=ldaptestcontainer2," + self.base_dn
1907 try:
1908 ldb.rename("cn=ldaptestcontainer2," + self.base_dn, "cn=ldaptestcontainer,cn=ldaptestcontainer2," + self.base_dn)
1909 self.fail()
1910 except LdbError, (num, _):
1911 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1913 print "Testing ldb.rename (into non-existent container) of cn=ldaptestcontainer2," + self.base_dn + " to cn=ldaptestcontainer,cn=ldaptestcontainer3," + self.base_dn
1914 try:
1915 ldb.rename("cn=ldaptestcontainer2," + self.base_dn, "cn=ldaptestcontainer,cn=ldaptestcontainer3," + self.base_dn)
1916 self.fail()
1917 except LdbError, (num, _):
1918 self.assertTrue(num in (ERR_UNWILLING_TO_PERFORM, ERR_OTHER))
1920 print "Testing delete (should fail, not a leaf node) of renamed cn=ldaptestcontainer2," + self.base_dn
1921 try:
1922 ldb.delete("cn=ldaptestcontainer2," + self.base_dn)
1923 self.fail()
1924 except LdbError, (num, _):
1925 self.assertEquals(num, ERR_NOT_ALLOWED_ON_NON_LEAF)
1927 print "Testing base ldb.search for CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn
1928 res = ldb.search(expression="(objectclass=*)", base=("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn), scope=SCOPE_BASE)
1929 self.assertEquals(len(res), 1)
1930 res = ldb.search(expression="(cn=ldaptestuser40)", base=("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn), scope=SCOPE_BASE)
1931 self.assertEquals(len(res), 0)
1933 print "Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in cn=ldaptestcontainer2," + self.base_dn
1934 res = ldb.search(expression="(&(cn=ldaptestuser4)(objectClass=user))", base=("cn=ldaptestcontainer2," + self.base_dn), scope=SCOPE_ONELEVEL)
1935 # FIXME: self.assertEquals(len(res), 0)
1937 print "Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in cn=ldaptestcontainer2," + self.base_dn
1938 res = ldb.search(expression="(&(cn=ldaptestuser4)(objectClass=user))", base=("cn=ldaptestcontainer2," + self.base_dn), scope=SCOPE_SUBTREE)
1939 # FIXME: self.assertEquals(len(res), 0)
1941 print "Testing delete of subtree renamed "+("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn)
1942 ldb.delete(("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn))
1943 print "Testing delete of renamed cn=ldaptestcontainer2," + self.base_dn
1944 ldb.delete("cn=ldaptestcontainer2," + self.base_dn)
1946 ldb.add({"dn": "cn=ldaptestutf8user èùéìòà,cn=users," + self.base_dn, "objectClass": "user"})
1948 ldb.add({"dn": "cn=ldaptestutf8user2 èùéìòà,cn=users," + self.base_dn, "objectClass": "user"})
1950 print "Testing ldb.search for (&(cn=ldaptestuser)(objectClass=user))"
1951 res = ldb.search(expression="(&(cn=ldaptestuser)(objectClass=user))")
1952 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser)(objectClass=user))")
1954 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
1955 self.assertEquals(str(res[0]["cn"]), "ldaptestuser")
1956 self.assertEquals(str(res[0]["name"]), "ldaptestuser")
1957 self.assertEquals(set(res[0]["objectClass"]), set(["top", "person", "organizationalPerson", "user"]))
1958 self.assertTrue("objectGUID" in res[0])
1959 self.assertTrue("whenCreated" in res[0])
1960 self.assertEquals(str(res[0]["objectCategory"]), ("CN=Person,CN=Schema,CN=Configuration," + self.base_dn))
1961 self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_NORMAL_ACCOUNT)
1962 self.assertEquals(int(res[0]["userAccountControl"][0]), UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE)
1963 self.assertEquals(res[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
1964 self.assertEquals(len(res[0]["memberOf"]), 1)
1966 print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=cn=person,cn=schema,cn=configuration," + self.base_dn + "))"
1967 res2 = ldb.search(expression="(&(cn=ldaptestuser)(objectCategory=cn=person,cn=schema,cn=configuration," + self.base_dn + "))")
1968 self.assertEquals(len(res2), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=cn=person,cn=schema,cn=configuration," + self.base_dn + "))")
1970 self.assertEquals(res[0].dn, res2[0].dn)
1972 print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon))"
1973 res3 = ldb.search(expression="(&(cn=ldaptestuser)(objectCategory=PerSon))")
1974 self.assertEquals(len(res3), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=PerSon)): matched %d" % len(res3))
1976 self.assertEquals(res[0].dn, res3[0].dn)
1978 if gc_ldb is not None:
1979 print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon)) in Global Catalog"
1980 res3gc = gc_ldb.search(expression="(&(cn=ldaptestuser)(objectCategory=PerSon))")
1981 self.assertEquals(len(res3gc), 1)
1983 self.assertEquals(res[0].dn, res3gc[0].dn)
1985 print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon)) in with 'phantom root' control"
1987 if gc_ldb is not None:
1988 res3control = gc_ldb.search(self.base_dn, expression="(&(cn=ldaptestuser)(objectCategory=PerSon))", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["search_options:1:2"])
1989 self.assertEquals(len(res3control), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=PerSon)) in Global Catalog")
1991 self.assertEquals(res[0].dn, res3control[0].dn)
1993 ldb.delete(res[0].dn)
1995 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectClass=user))"
1996 res = ldb.search(expression="(&(cn=ldaptestcomputer)(objectClass=user))")
1997 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser)(objectClass=user))")
1999 self.assertEquals(str(res[0].dn), ("CN=ldaptestcomputer,CN=Computers," + self.base_dn))
2000 self.assertEquals(str(res[0]["cn"]), "ldaptestcomputer")
2001 self.assertEquals(str(res[0]["name"]), "ldaptestcomputer")
2002 self.assertEquals(set(res[0]["objectClass"]), set(["top", "person", "organizationalPerson", "user", "computer"]))
2003 self.assertTrue("objectGUID" in res[0])
2004 self.assertTrue("whenCreated" in res[0])
2005 self.assertEquals(str(res[0]["objectCategory"]), ("CN=Computer,CN=Schema,CN=Configuration," + self.base_dn))
2006 self.assertEquals(int(res[0]["primaryGroupID"][0]), 513)
2007 self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_NORMAL_ACCOUNT)
2008 self.assertEquals(int(res[0]["userAccountControl"][0]), UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE)
2009 self.assertEquals(res[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
2010 self.assertEquals(len(res[0]["memberOf"]), 1)
2012 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + "))"
2013 res2 = ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + "))")
2014 self.assertEquals(len(res2), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + "))")
2016 self.assertEquals(res[0].dn, res2[0].dn)
2018 if gc_ldb is not None:
2019 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + ")) in Global Catlog"
2020 res2gc = gc_ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + "))")
2021 self.assertEquals(len(res2gc), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + ")) in Global Catlog")
2023 self.assertEquals(res[0].dn, res2gc[0].dn)
2025 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=compuTER))"
2026 res3 = ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=compuTER))")
2027 self.assertEquals(len(res3), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=compuTER))")
2029 self.assertEquals(res[0].dn, res3[0].dn)
2031 if gc_ldb is not None:
2032 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=compuTER)) in Global Catalog"
2033 res3gc = gc_ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=compuTER))")
2034 self.assertEquals(len(res3gc), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=compuTER)) in Global Catalog")
2036 self.assertEquals(res[0].dn, res3gc[0].dn)
2038 print "Testing ldb.search for (&(cn=ldaptestcomp*r)(objectCategory=compuTER))"
2039 res4 = ldb.search(expression="(&(cn=ldaptestcomp*r)(objectCategory=compuTER))")
2040 self.assertEquals(len(res4), 1, "Could not find (&(cn=ldaptestcomp*r)(objectCategory=compuTER))")
2042 self.assertEquals(res[0].dn, res4[0].dn)
2044 print "Testing ldb.search for (&(cn=ldaptestcomput*)(objectCategory=compuTER))"
2045 res5 = ldb.search(expression="(&(cn=ldaptestcomput*)(objectCategory=compuTER))")
2046 self.assertEquals(len(res5), 1, "Could not find (&(cn=ldaptestcomput*)(objectCategory=compuTER))")
2048 self.assertEquals(res[0].dn, res5[0].dn)
2050 print "Testing ldb.search for (&(cn=*daptestcomputer)(objectCategory=compuTER))"
2051 res6 = ldb.search(expression="(&(cn=*daptestcomputer)(objectCategory=compuTER))")
2052 self.assertEquals(len(res6), 1, "Could not find (&(cn=*daptestcomputer)(objectCategory=compuTER))")
2054 self.assertEquals(res[0].dn, res6[0].dn)
2056 ldb.delete("<GUID=" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + ">")
2058 print "Testing ldb.search for (&(cn=ldaptest2computer)(objectClass=user))"
2059 res = ldb.search(expression="(&(cn=ldaptest2computer)(objectClass=user))")
2060 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptest2computer)(objectClass=user))")
2062 self.assertEquals(str(res[0].dn), "CN=ldaptest2computer,CN=Computers," + self.base_dn)
2063 self.assertEquals(str(res[0]["cn"]), "ldaptest2computer")
2064 self.assertEquals(str(res[0]["name"]), "ldaptest2computer")
2065 self.assertEquals(list(res[0]["objectClass"]), ["top", "person", "organizationalPerson", "user", "computer"])
2066 self.assertTrue("objectGUID" in res[0])
2067 self.assertTrue("whenCreated" in res[0])
2068 self.assertEquals(res[0]["objectCategory"][0], "CN=Computer,CN=Schema,CN=Configuration," + self.base_dn)
2069 self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_WORKSTATION_TRUST)
2070 self.assertEquals(int(res[0]["userAccountControl"][0]), UF_WORKSTATION_TRUST_ACCOUNT)
2072 ldb.delete("<SID=" + ldb.schema_format_value("objectSID", res[0]["objectSID"][0]) + ">")
2074 attrs = ["cn", "name", "objectClass", "objectGUID", "objectSID", "whenCreated", "nTSecurityDescriptor", "memberOf", "allowedAttributes", "allowedAttributesEffective"]
2075 print "Testing ldb.search for (&(cn=ldaptestUSer2)(objectClass=user))"
2076 res_user = ldb.search(self.base_dn, expression="(&(cn=ldaptestUSer2)(objectClass=user))", scope=SCOPE_SUBTREE, attrs=attrs)
2077 self.assertEquals(len(res_user), 1, "Could not find (&(cn=ldaptestUSer2)(objectClass=user))")
2079 self.assertEquals(str(res_user[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
2080 self.assertEquals(str(res_user[0]["cn"]), "ldaptestuser2")
2081 self.assertEquals(str(res_user[0]["name"]), "ldaptestuser2")
2082 self.assertEquals(list(res_user[0]["objectClass"]), ["top", "person", "organizationalPerson", "user"])
2083 self.assertTrue("objectSid" in res_user[0])
2084 self.assertTrue("objectGUID" in res_user[0])
2085 self.assertTrue("whenCreated" in res_user[0])
2086 self.assertTrue("nTSecurityDescriptor" in res_user[0])
2087 self.assertTrue("allowedAttributes" in res_user[0])
2088 self.assertTrue("allowedAttributesEffective" in res_user[0])
2089 self.assertEquals(res_user[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
2091 ldaptestuser2_sid = res_user[0]["objectSid"][0]
2092 ldaptestuser2_guid = res_user[0]["objectGUID"][0]
2094 attrs = ["cn", "name", "objectClass", "objectGUID", "objectSID", "whenCreated", "nTSecurityDescriptor", "member", "allowedAttributes", "allowedAttributesEffective"]
2095 print "Testing ldb.search for (&(cn=ldaptestgroup2)(objectClass=group))"
2096 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs)
2097 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))")
2099 self.assertEquals(str(res[0].dn), ("CN=ldaptestgroup2,CN=Users," + self.base_dn))
2100 self.assertEquals(str(res[0]["cn"]), "ldaptestgroup2")
2101 self.assertEquals(str(res[0]["name"]), "ldaptestgroup2")
2102 self.assertEquals(list(res[0]["objectClass"]), ["top", "group"])
2103 self.assertTrue("objectGUID" in res[0])
2104 self.assertTrue("objectSid" in res[0])
2105 self.assertTrue("whenCreated" in res[0])
2106 self.assertTrue("nTSecurityDescriptor" in res[0])
2107 self.assertTrue("allowedAttributes" in res[0])
2108 self.assertTrue("allowedAttributesEffective" in res[0])
2109 memberUP = []
2110 for m in res[0]["member"]:
2111 memberUP.append(m.upper())
2112 self.assertTrue(("CN=ldaptestuser2,CN=Users," + self.base_dn).upper() in memberUP)
2114 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs, controls=["extended_dn:1:1"])
2115 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))")
2117 print res[0]["member"]
2118 memberUP = []
2119 for m in res[0]["member"]:
2120 memberUP.append(m.upper())
2121 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()
2123 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)
2125 print "Quicktest for linked attributes"
2126 ldb.modify_ldif("""
2127 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2128 changetype: modify
2129 replace: member
2130 member: CN=ldaptestuser2,CN=Users,""" + self.base_dn + """
2131 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
2132 """)
2134 ldb.modify_ldif("""
2135 dn: <GUID=""" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + """>
2136 changetype: modify
2137 replace: member
2138 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
2139 """)
2141 ldb.modify_ldif("""
2142 dn: <SID=""" + ldb.schema_format_value("objectSid", res[0]["objectSid"][0]) + """>
2143 changetype: modify
2144 delete: member
2145 """)
2147 ldb.modify_ldif("""
2148 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2149 changetype: modify
2150 add: member
2151 member: <GUID=""" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + """>
2152 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
2153 """)
2155 ldb.modify_ldif("""
2156 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2157 changetype: modify
2158 replace: member
2159 """)
2161 ldb.modify_ldif("""
2162 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2163 changetype: modify
2164 add: member
2165 member: <SID=""" + ldb.schema_format_value("objectSid", res_user[0]["objectSid"][0]) + """>
2166 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
2167 """)
2169 ldb.modify_ldif("""
2170 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2171 changetype: modify
2172 delete: member
2173 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
2174 """)
2176 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs)
2177 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))")
2179 self.assertEquals(str(res[0].dn), ("CN=ldaptestgroup2,CN=Users," + self.base_dn))
2180 self.assertEquals(res[0]["member"][0], ("CN=ldaptestuser2,CN=Users," + self.base_dn))
2181 self.assertEquals(len(res[0]["member"]), 1)
2183 ldb.delete(("CN=ldaptestuser2,CN=Users," + self.base_dn))
2185 time.sleep(4)
2187 attrs = ["cn", "name", "objectClass", "objectGUID", "whenCreated", "nTSecurityDescriptor", "member"]
2188 print "Testing ldb.search for (&(cn=ldaptestgroup2)(objectClass=group)) to check linked delete"
2189 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs)
2190 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group)) to check linked delete")
2192 self.assertEquals(str(res[0].dn), ("CN=ldaptestgroup2,CN=Users," + self.base_dn))
2193 self.assertTrue("member" not in res[0])
2195 print "Testing ldb.search for (&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))"
2196 # TODO UTF8 users don't seem to work fully anymore
2197 # res = ldb.search(expression="(&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
2198 res = ldb.search(expression="(&(cn=ldaptestutf8user èùéìòà)(objectclass=user))")
2199 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
2201 self.assertEquals(str(res[0].dn), ("CN=ldaptestutf8user èùéìòà,CN=Users," + self.base_dn))
2202 self.assertEquals(str(res[0]["cn"]), "ldaptestutf8user èùéìòà")
2203 self.assertEquals(str(res[0]["name"]), "ldaptestutf8user èùéìòà")
2204 self.assertEquals(list(res[0]["objectClass"]), ["top", "person", "organizationalPerson", "user"])
2205 self.assertTrue("objectGUID" in res[0])
2206 self.assertTrue("whenCreated" in res[0])
2208 ldb.delete(res[0].dn)
2210 print "Testing ldb.search for (&(cn=ldaptestutf8user2*)(objectClass=user))"
2211 res = ldb.search(expression="(&(cn=ldaptestutf8user2*)(objectClass=user))")
2212 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestutf8user2*)(objectClass=user))")
2214 ldb.delete(res[0].dn)
2216 ldb.delete(("CN=ldaptestgroup2,CN=Users," + self.base_dn))
2218 print "Testing ldb.search for (&(cn=ldaptestutf8user2 ÈÙÉÌÒÀ)(objectClass=user))"
2219 # TODO UTF8 users don't seem to work fully anymore
2220 # res = ldb.search(expression="(&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
2221 # self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
2223 print "Testing that we can't get at the configuration DN from the main search base"
2224 res = ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
2225 self.assertEquals(len(res), 0)
2227 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"
2228 res = ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["search_options:1:2"])
2229 self.assertTrue(len(res) > 0)
2231 if gc_ldb is not None:
2232 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"
2234 res = gc_ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["search_options:1:0"])
2235 self.assertTrue(len(res) > 0)
2237 print "Testing that we do find configuration elements in the global catlog"
2238 res = gc_ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
2239 self.assertTrue(len(res) > 0)
2241 print "Testing that we do find configuration elements and user elements at the same time"
2242 res = gc_ldb.search(self.base_dn, expression="(|(objectClass=crossRef)(objectClass=person))", scope=SCOPE_SUBTREE, attrs=["cn"])
2243 self.assertTrue(len(res) > 0)
2245 print "Testing that we do find configuration elements in the global catlog, with the configuration basedn"
2246 res = gc_ldb.search(self.configuration_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
2247 self.assertTrue(len(res) > 0)
2249 print "Testing that we can get at the configuration DN on the main LDAP port"
2250 res = ldb.search(self.configuration_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
2251 self.assertTrue(len(res) > 0)
2253 print "Testing objectCategory canonacolisation"
2254 res = ldb.search(self.configuration_dn, expression="objectCategory=ntDsDSA", scope=SCOPE_SUBTREE, attrs=["cn"])
2255 self.assertTrue(len(res) > 0, "Didn't find any records with objectCategory=ntDsDSA")
2256 self.assertTrue(len(res) != 0)
2258 res = ldb.search(self.configuration_dn, expression="objectCategory=CN=ntDs-DSA," + self.schema_dn, scope=SCOPE_SUBTREE, attrs=["cn"])
2259 self.assertTrue(len(res) > 0, "Didn't find any records with objectCategory=CN=ntDs-DSA," + self.schema_dn)
2260 self.assertTrue(len(res) != 0)
2262 print "Testing objectClass attribute order on "+ self.base_dn
2263 res = ldb.search(expression="objectClass=domain", base=self.base_dn,
2264 scope=SCOPE_BASE, attrs=["objectClass"])
2265 self.assertEquals(len(res), 1)
2267 self.assertEquals(list(res[0]["objectClass"]), ["top", "domain", "domainDNS"])
2269 # check enumeration
2271 print "Testing ldb.search for objectCategory=person"
2272 res = ldb.search(self.base_dn, expression="objectCategory=person", scope=SCOPE_SUBTREE, attrs=["cn"])
2273 self.assertTrue(len(res) > 0)
2275 print "Testing ldb.search for objectCategory=person with domain scope control"
2276 res = ldb.search(self.base_dn, expression="objectCategory=person", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["domain_scope:1"])
2277 self.assertTrue(len(res) > 0)
2279 print "Testing ldb.search for objectCategory=user"
2280 res = ldb.search(self.base_dn, expression="objectCategory=user", scope=SCOPE_SUBTREE, attrs=["cn"])
2281 self.assertTrue(len(res) > 0)
2283 print "Testing ldb.search for objectCategory=user with domain scope control"
2284 res = ldb.search(self.base_dn, expression="objectCategory=user", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["domain_scope:1"])
2285 self.assertTrue(len(res) > 0)
2287 print "Testing ldb.search for objectCategory=group"
2288 res = ldb.search(self.base_dn, expression="objectCategory=group", scope=SCOPE_SUBTREE, attrs=["cn"])
2289 self.assertTrue(len(res) > 0)
2291 print "Testing ldb.search for objectCategory=group with domain scope control"
2292 res = ldb.search(self.base_dn, expression="objectCategory=group", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["domain_scope:1"])
2293 self.assertTrue(len(res) > 0)
2295 print "Testing creating a user with the posixAccount objectClass"
2296 self.ldb.add_ldif("""dn: cn=posixuser,CN=Users,%s
2297 objectClass: top
2298 objectClass: person
2299 objectClass: posixAccount
2300 objectClass: user
2301 objectClass: organizationalPerson
2302 cn: posixuser
2303 uid: posixuser
2304 sn: posixuser
2305 uidNumber: 10126
2306 gidNumber: 10126
2307 homeDirectory: /home/posixuser
2308 loginShell: /bin/bash
2309 gecos: Posix User;;;
2310 description: A POSIX user"""% (self.base_dn))
2312 print "Testing removing the posixAccount objectClass from an existing user"
2313 self.ldb.modify_ldif("""dn: cn=posixuser,CN=Users,%s
2314 changetype: modify
2315 delete: objectClass
2316 objectClass: posixAccount"""% (self.base_dn))
2318 print "Testing adding the posixAccount objectClass to an existing user"
2319 self.ldb.modify_ldif("""dn: cn=posixuser,CN=Users,%s
2320 changetype: modify
2321 add: objectClass
2322 objectClass: posixAccount"""% (self.base_dn))
2324 self.delete_force(self.ldb, "cn=posixuser,cn=users," + self.base_dn)
2325 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
2326 self.delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
2327 self.delete_force(self.ldb, "cn=ldaptestuser3,cn=users," + self.base_dn)
2328 self.delete_force(self.ldb, "cn=ldaptestuser4,cn=ldaptestcontainer," + self.base_dn)
2329 self.delete_force(self.ldb, "cn=ldaptestuser4,cn=ldaptestcontainer2," + self.base_dn)
2330 self.delete_force(self.ldb, "cn=ldaptestuser5,cn=users," + self.base_dn)
2331 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
2332 self.delete_force(self.ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
2333 self.delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2334 self.delete_force(self.ldb, "cn=ldaptest2computer,cn=computers," + self.base_dn)
2335 self.delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
2336 self.delete_force(self.ldb, "cn=ldaptestutf8user èùéìòà,cn=users," + self.base_dn)
2337 self.delete_force(self.ldb, "cn=ldaptestutf8user2 èùéìòà,cn=users," + self.base_dn)
2338 self.delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
2339 self.delete_force(self.ldb, "cn=ldaptestcontainer2," + self.base_dn)
2341 def test_security_descriptor_add(self):
2342 """ Testing ldb.add_ldif() for nTSecurityDescriptor """
2343 user_name = "testdescriptoruser1"
2344 user_dn = "CN=%s,CN=Users,%s" % (user_name, self.base_dn)
2346 # Test add_ldif() with SDDL security descriptor input
2348 self.delete_force(self.ldb, user_dn)
2349 try:
2350 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2351 self.ldb.add_ldif("""
2352 dn: """ + user_dn + """
2353 objectclass: user
2354 sAMAccountName: """ + user_name + """
2355 nTSecurityDescriptor: """ + sddl)
2356 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2357 desc = res[0]["nTSecurityDescriptor"][0]
2358 desc = ndr_unpack( security.descriptor, desc )
2359 desc_sddl = desc.as_sddl( self.domain_sid )
2360 self.assertEqual(desc_sddl, sddl)
2361 finally:
2362 self.delete_force(self.ldb, user_dn)
2364 # Test add_ldif() with BASE64 security descriptor
2366 try:
2367 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2368 desc = security.descriptor.from_sddl(sddl, self.domain_sid)
2369 desc_binary = ndr_pack(desc)
2370 desc_base64 = base64.b64encode(desc_binary)
2371 self.ldb.add_ldif("""
2372 dn: """ + user_dn + """
2373 objectclass: user
2374 sAMAccountName: """ + user_name + """
2375 nTSecurityDescriptor:: """ + desc_base64)
2376 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2377 desc = res[0]["nTSecurityDescriptor"][0]
2378 desc = ndr_unpack(security.descriptor, desc)
2379 desc_sddl = desc.as_sddl(self.domain_sid)
2380 self.assertEqual(desc_sddl, sddl)
2381 finally:
2382 self.delete_force(self.ldb, user_dn)
2384 def test_security_descriptor_add_neg(self):
2385 """Test add_ldif() with BASE64 security descriptor input using WRONG domain SID
2386 Negative test
2388 user_name = "testdescriptoruser1"
2389 user_dn = "CN=%s,CN=Users,%s" % (user_name, self.base_dn)
2390 self.delete_force(self.ldb, user_dn)
2391 try:
2392 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2393 desc = security.descriptor.from_sddl(sddl, security.dom_sid('S-1-5-21'))
2394 desc_base64 = base64.b64encode( ndr_pack(desc) )
2395 self.ldb.add_ldif("""
2396 dn: """ + user_dn + """
2397 objectclass: user
2398 sAMAccountName: """ + user_name + """
2399 nTSecurityDescriptor:: """ + desc_base64)
2400 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2401 self.assertTrue("nTSecurityDescriptor" in res[0])
2402 finally:
2403 self.delete_force(self.ldb, user_dn)
2405 def test_security_descriptor_modify(self):
2406 """ Testing ldb.modify_ldif() for nTSecurityDescriptor """
2407 user_name = "testdescriptoruser2"
2408 user_dn = "CN=%s,CN=Users,%s" % (user_name, self.base_dn)
2410 # Delete user object and test modify_ldif() with SDDL security descriptor input
2411 # Add ACE to the original descriptor test
2413 try:
2414 self.delete_force(self.ldb, user_dn)
2415 self.ldb.add_ldif("""
2416 dn: """ + user_dn + """
2417 objectclass: user
2418 sAMAccountName: """ + user_name)
2419 # Modify descriptor
2420 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2421 desc = res[0]["nTSecurityDescriptor"][0]
2422 desc = ndr_unpack(security.descriptor, desc)
2423 desc_sddl = desc.as_sddl(self.domain_sid)
2424 sddl = desc_sddl[:desc_sddl.find("(")] + "(A;;RPWP;;;AU)" + desc_sddl[desc_sddl.find("("):]
2425 mod = """
2426 dn: """ + user_dn + """
2427 changetype: modify
2428 replace: nTSecurityDescriptor
2429 nTSecurityDescriptor: """ + sddl
2430 self.ldb.modify_ldif(mod)
2431 # Read modified descriptor
2432 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2433 desc = res[0]["nTSecurityDescriptor"][0]
2434 desc = ndr_unpack(security.descriptor, desc)
2435 desc_sddl = desc.as_sddl(self.domain_sid)
2436 self.assertEqual(desc_sddl, sddl)
2437 finally:
2438 self.delete_force(self.ldb, user_dn)
2440 # Test modify_ldif() with SDDL security descriptor input
2441 # New desctiptor test
2443 try:
2444 self.ldb.add_ldif("""
2445 dn: """ + user_dn + """
2446 objectclass: user
2447 sAMAccountName: """ + user_name)
2448 # Modify descriptor
2449 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2450 mod = """
2451 dn: """ + user_dn + """
2452 changetype: modify
2453 replace: nTSecurityDescriptor
2454 nTSecurityDescriptor: """ + sddl
2455 self.ldb.modify_ldif(mod)
2456 # Read modified descriptor
2457 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2458 desc = res[0]["nTSecurityDescriptor"][0]
2459 desc = ndr_unpack(security.descriptor, desc)
2460 desc_sddl = desc.as_sddl(self.domain_sid)
2461 self.assertEqual(desc_sddl, sddl)
2462 finally:
2463 self.delete_force(self.ldb, user_dn)
2465 # Test modify_ldif() with BASE64 security descriptor input
2466 # Add ACE to the original descriptor test
2468 try:
2469 self.ldb.add_ldif("""
2470 dn: """ + user_dn + """
2471 objectclass: user
2472 sAMAccountName: """ + user_name)
2473 # Modify descriptor
2474 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2475 desc = res[0]["nTSecurityDescriptor"][0]
2476 desc = ndr_unpack(security.descriptor, desc)
2477 desc_sddl = desc.as_sddl(self.domain_sid)
2478 sddl = desc_sddl[:desc_sddl.find("(")] + "(A;;RPWP;;;AU)" + desc_sddl[desc_sddl.find("("):]
2479 desc = security.descriptor.from_sddl(sddl, self.domain_sid)
2480 desc_base64 = base64.b64encode(ndr_pack(desc))
2481 mod = """
2482 dn: """ + user_dn + """
2483 changetype: modify
2484 replace: nTSecurityDescriptor
2485 nTSecurityDescriptor:: """ + desc_base64
2486 self.ldb.modify_ldif(mod)
2487 # Read modified descriptor
2488 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2489 desc = res[0]["nTSecurityDescriptor"][0]
2490 desc = ndr_unpack(security.descriptor, desc)
2491 desc_sddl = desc.as_sddl(self.domain_sid)
2492 self.assertEqual(desc_sddl, sddl)
2493 finally:
2494 self.delete_force(self.ldb, user_dn)
2496 # Test modify_ldif() with BASE64 security descriptor input
2497 # New descriptor test
2499 try:
2500 self.delete_force(self.ldb, user_dn)
2501 self.ldb.add_ldif("""
2502 dn: """ + user_dn + """
2503 objectclass: user
2504 sAMAccountName: """ + user_name)
2505 # Modify descriptor
2506 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2507 desc = security.descriptor.from_sddl(sddl, self.domain_sid)
2508 desc_base64 = base64.b64encode(ndr_pack(desc))
2509 mod = """
2510 dn: """ + user_dn + """
2511 changetype: modify
2512 replace: nTSecurityDescriptor
2513 nTSecurityDescriptor:: """ + desc_base64
2514 self.ldb.modify_ldif(mod)
2515 # Read modified descriptor
2516 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2517 desc = res[0]["nTSecurityDescriptor"][0]
2518 desc = ndr_unpack(security.descriptor, desc)
2519 desc_sddl = desc.as_sddl(self.domain_sid)
2520 self.assertEqual(desc_sddl, sddl)
2521 finally:
2522 self.delete_force(self.ldb, user_dn)
2524 def test_dsheuristics(self):
2525 """Tests the 'dSHeuristics' attribute"""
2526 print "Tests the 'dSHeuristics' attribute"""
2528 # Get the current value to restore it later
2529 res = self.ldb.search("CN=Directory Service, CN=Windows NT, CN=Services, "
2530 + self.configuration_dn, scope=SCOPE_BASE, attrs=["dSHeuristics"])
2531 if "dSHeuristics" in res[0]:
2532 dsheuristics = res[0]["dSHeuristics"][0]
2533 else:
2534 dsheuristics = None
2535 # Should not be longer than 18 chars?
2536 try:
2537 self.set_dsheuristics("123ABC-+!1asdfg@#^12")
2538 except LdbError, (num, _):
2539 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
2540 # If it is >= 10 chars, tenthChar should be 1
2541 try:
2542 self.set_dsheuristics("00020000000002")
2543 except LdbError, (num, _):
2544 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
2545 # apart from the above, all char values are accepted
2546 self.set_dsheuristics("123ABC-+!1asdfg@#^")
2547 res = self.ldb.search("CN=Directory Service, CN=Windows NT, CN=Services, "
2548 + self.configuration_dn, scope=SCOPE_BASE, attrs=["dSHeuristics"])
2549 self.assertTrue("dSHeuristics" in res[0])
2550 self.assertEquals(res[0]["dSHeuristics"][0], "123ABC-+!1asdfg@#^")
2551 # restore old value
2552 self.set_dsheuristics(dsheuristics)
2555 class BaseDnTests(unittest.TestCase):
2557 def setUp(self):
2558 super(BaseDnTests, self).setUp()
2559 self.ldb = ldb
2561 def test_rootdse_attrs(self):
2562 """Testing for all rootDSE attributes"""
2563 res = self.ldb.search(scope=SCOPE_BASE, attrs=[])
2564 self.assertEquals(len(res), 1)
2566 def test_highestcommittedusn(self):
2567 """Testing for highestCommittedUSN"""
2568 res = self.ldb.search("", scope=SCOPE_BASE, attrs=["highestCommittedUSN"])
2569 self.assertEquals(len(res), 1)
2570 self.assertTrue(int(res[0]["highestCommittedUSN"][0]) != 0)
2572 def test_netlogon(self):
2573 """Testing for netlogon via LDAP"""
2574 res = self.ldb.search("", scope=SCOPE_BASE, attrs=["netlogon"])
2575 self.assertEquals(len(res), 0)
2577 def test_netlogon_highestcommitted_usn(self):
2578 """Testing for netlogon and highestCommittedUSN via LDAP"""
2579 res = self.ldb.search("", scope=SCOPE_BASE,
2580 attrs=["netlogon", "highestCommittedUSN"])
2581 self.assertEquals(len(res), 0)
2583 def test_namingContexts(self):
2584 """Testing for namingContexts in rootDSE"""
2585 res = self.ldb.search("", scope=SCOPE_BASE,
2586 attrs=["namingContexts", "defaultNamingContext", "schemaNamingContext", "configurationNamingContext"])
2587 self.assertEquals(len(res), 1)
2589 ncs = set([])
2590 for nc in res[0]["namingContexts"]:
2591 self.assertTrue(nc not in ncs)
2592 ncs.add(nc)
2594 self.assertTrue(res[0]["defaultNamingContext"][0] in ncs)
2595 self.assertTrue(res[0]["configurationNamingContext"][0] in ncs)
2596 self.assertTrue(res[0]["schemaNamingContext"][0] in ncs)
2598 def test_serverPath(self):
2599 """Testing the server paths in rootDSE"""
2600 res = self.ldb.search("", scope=SCOPE_BASE,
2601 attrs=["dsServiceName", "serverName"])
2602 self.assertEquals(len(res), 1)
2604 self.assertTrue("CN=Servers" in res[0]["dsServiceName"][0])
2605 self.assertTrue("CN=Sites" in res[0]["dsServiceName"][0])
2606 self.assertTrue("CN=NTDS Settings" in res[0]["dsServiceName"][0])
2607 self.assertTrue("CN=Servers" in res[0]["serverName"][0])
2608 self.assertTrue("CN=Sites" in res[0]["serverName"][0])
2609 self.assertFalse("CN=NTDS Settings" in res[0]["serverName"][0])
2611 def test_dnsHostname(self):
2612 """Testing the DNS hostname in rootDSE"""
2613 res = self.ldb.search("", scope=SCOPE_BASE,
2614 attrs=["dnsHostName", "serverName"])
2615 self.assertEquals(len(res), 1)
2617 res2 = self.ldb.search(res[0]["serverName"][0], scope=SCOPE_BASE,
2618 attrs=["dNSHostName"])
2619 self.assertEquals(len(res2), 1)
2621 self.assertEquals(res[0]["dnsHostName"][0], res2[0]["dNSHostName"][0])
2623 def test_ldapServiceName(self):
2624 """Testing the ldap service name in rootDSE"""
2625 res = self.ldb.search("", scope=SCOPE_BASE,
2626 attrs=["ldapServiceName", "dNSHostName"])
2627 self.assertEquals(len(res), 1)
2629 (hostname, _, dns_domainname) = res[0]["dNSHostName"][0].partition(".")
2630 self.assertTrue(":%s$@%s" % (hostname, dns_domainname.upper())
2631 in res[0]["ldapServiceName"][0])
2633 if not "://" in host:
2634 if os.path.isfile(host):
2635 host = "tdb://%s" % host
2636 else:
2637 host = "ldap://%s" % host
2639 ldb = Ldb(host, credentials=creds, session_info=system_session(), lp=lp)
2640 if not "tdb://" in host:
2641 gc_ldb = Ldb("%s:3268" % host, credentials=creds,
2642 session_info=system_session(), lp=lp)
2643 else:
2644 gc_ldb = None
2646 runner = SubunitTestRunner()
2647 rc = 0
2648 if not runner.run(unittest.makeSuite(BaseDnTests)).wasSuccessful():
2649 rc = 1
2650 if not runner.run(unittest.makeSuite(BasicTests)).wasSuccessful():
2651 rc = 1
2652 sys.exit(rc)