s4:ldap.py - fix up the UTF8 tests
[Samba/gebeck_regimport.git] / source4 / dsdb / tests / python / ldap.py
blob3cee5322b4d8e6b41a79b951104d6bc371082156
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.insert(0, "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 ldb import timestring
29 from samba import Ldb
30 from samba.samdb import SamDB
31 from samba.dsdb import (UF_NORMAL_ACCOUNT,
32 UF_WORKSTATION_TRUST_ACCOUNT,
33 UF_PASSWD_NOTREQD, UF_ACCOUNTDISABLE, ATYPE_NORMAL_ACCOUNT,
34 ATYPE_WORKSTATION_TRUST, SYSTEM_FLAG_DOMAIN_DISALLOW_MOVE,
35 SYSTEM_FLAG_CONFIG_ALLOW_RENAME, SYSTEM_FLAG_CONFIG_ALLOW_MOVE,
36 SYSTEM_FLAG_CONFIG_ALLOW_LIMITED_MOVE)
38 from subunit.run import SubunitTestRunner
39 import unittest
41 from samba.ndr import ndr_pack, ndr_unpack
42 from samba.dcerpc import security, lsa
43 from samba.tests import delete_force
45 parser = optparse.OptionParser("ldap.py [options] <host>")
46 sambaopts = options.SambaOptions(parser)
47 parser.add_option_group(sambaopts)
48 parser.add_option_group(options.VersionOptions(parser))
49 # use command line creds if available
50 credopts = options.CredentialsOptions(parser)
51 parser.add_option_group(credopts)
52 opts, args = parser.parse_args()
54 if len(args) < 1:
55 parser.print_usage()
56 sys.exit(1)
58 host = args[0]
60 lp = sambaopts.get_loadparm()
61 creds = credopts.get_credentials(lp)
63 class BasicTests(unittest.TestCase):
65 def setUp(self):
66 super(BasicTests, self).setUp()
67 self.ldb = ldb
68 self.gc_ldb = gc_ldb
69 self.base_dn = ldb.domain_dn()
70 self.configuration_dn = ldb.get_config_basedn().get_linearized()
71 self.schema_dn = ldb.get_schema_basedn().get_linearized()
72 self.domain_sid = security.dom_sid(ldb.get_domain_sid())
74 print "baseDN: %s\n" % self.base_dn
76 delete_force(self.ldb, "cn=posixuser,cn=users," + self.base_dn)
77 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
78 delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
79 delete_force(self.ldb, "cn=ldaptestuser3,cn=users," + self.base_dn)
80 delete_force(self.ldb, "cn=ldaptestuser4,cn=ldaptestcontainer," + self.base_dn)
81 delete_force(self.ldb, "cn=ldaptestuser4,cn=ldaptestcontainer2," + self.base_dn)
82 delete_force(self.ldb, "cn=ldaptestuser5,cn=users," + self.base_dn)
83 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
84 delete_force(self.ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
85 delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
86 delete_force(self.ldb, "cn=ldaptest2computer,cn=computers," + self.base_dn)
87 delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
88 delete_force(self.ldb, "cn=ldaptestutf8user èùéìòà,cn=users," + self.base_dn)
89 delete_force(self.ldb, "cn=ldaptestutf8user2 èùéìòà,cn=users," + self.base_dn)
90 delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
91 delete_force(self.ldb, "cn=ldaptestcontainer2," + self.base_dn)
92 delete_force(self.ldb, "cn=parentguidtest,cn=users," + self.base_dn)
93 delete_force(self.ldb, "cn=parentguidtest,cn=testotherusers," + self.base_dn)
94 delete_force(self.ldb, "cn=testotherusers," + self.base_dn)
95 delete_force(self.ldb, "cn=ldaptestobject," + self.base_dn)
96 delete_force(self.ldb, "description=xyz,cn=users," + self.base_dn)
97 delete_force(self.ldb, "ou=testou,cn=users," + self.base_dn)
98 delete_force(self.ldb, "cn=Test Secret,cn=system," + self.base_dn)
100 def test_objectclasses(self):
101 """Test objectClass behaviour"""
102 print "Test objectClass behaviour"""
104 # We cannot create LSA-specific objects (oc "secret" or "trustedDomain")
105 try:
106 self.ldb.add({
107 "dn": "cn=Test Secret,cn=system," + self.base_dn,
108 "objectClass": "secret" })
109 self.fail()
110 except LdbError, (num, _):
111 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
113 # Invalid objectclass specified
114 try:
115 self.ldb.add({
116 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
117 "objectClass": [] })
118 self.fail()
119 except LdbError, (num, _):
120 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
122 # Invalid objectclass specified
123 try:
124 self.ldb.add({
125 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
126 "objectClass": "X" })
127 self.fail()
128 except LdbError, (num, _):
129 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
131 # Invalid objectCategory specified
132 try:
133 self.ldb.add({
134 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
135 "objectClass": "person",
136 "objectCategory": self.base_dn })
137 self.fail()
138 except LdbError, (num, _):
139 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
141 # Multi-valued "systemFlags"
142 try:
143 self.ldb.add({
144 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
145 "objectClass": "person",
146 "systemFlags": ["0", str(SYSTEM_FLAG_DOMAIN_DISALLOW_MOVE)] })
147 self.fail()
148 except LdbError, (num, _):
149 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
151 # We cannot instanciate from an abstract objectclass
152 try:
153 self.ldb.add({
154 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
155 "objectClass": "connectionPoint" })
156 self.fail()
157 except LdbError, (num, _):
158 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
160 # Test allowed system flags
161 self.ldb.add({
162 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
163 "objectClass": "person",
164 "systemFlags": str(~(SYSTEM_FLAG_CONFIG_ALLOW_RENAME | SYSTEM_FLAG_CONFIG_ALLOW_MOVE | SYSTEM_FLAG_CONFIG_ALLOW_LIMITED_MOVE)) })
166 res = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
167 scope=SCOPE_BASE, attrs=["systemFlags"])
168 self.assertTrue(len(res) == 1)
169 self.assertEquals(res[0]["systemFlags"][0], "0")
171 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
173 self.ldb.add({
174 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
175 "objectClass": "person" })
177 # We can remove derivation classes of the structural objectclass
178 # but they're going to be readded afterwards
179 m = Message()
180 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
181 m["objectClass"] = MessageElement("top", FLAG_MOD_DELETE,
182 "objectClass")
183 ldb.modify(m)
185 res = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
186 scope=SCOPE_BASE, attrs=["objectClass"])
187 self.assertTrue(len(res) == 1)
188 self.assertTrue("top" in res[0]["objectClass"])
190 # The top-most structural class cannot be deleted since there are
191 # attributes of it in use
192 m = Message()
193 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
194 m["objectClass"] = MessageElement("person", FLAG_MOD_DELETE,
195 "objectClass")
196 try:
197 ldb.modify(m)
198 self.fail()
199 except LdbError, (num, _):
200 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
202 # We cannot delete classes which weren't specified
203 m = Message()
204 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
205 m["objectClass"] = MessageElement("computer", FLAG_MOD_DELETE,
206 "objectClass")
207 try:
208 ldb.modify(m)
209 self.fail()
210 except LdbError, (num, _):
211 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
213 # An invalid class cannot be added
214 m = Message()
215 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
216 m["objectClass"] = MessageElement("X", FLAG_MOD_ADD,
217 "objectClass")
218 try:
219 ldb.modify(m)
220 self.fail()
221 except LdbError, (num, _):
222 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
224 # The top-most structural class cannot be changed by adding another
225 # structural one
226 m = Message()
227 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
228 m["objectClass"] = MessageElement("user", FLAG_MOD_ADD,
229 "objectClass")
230 try:
231 ldb.modify(m)
232 self.fail()
233 except LdbError, (num, _):
234 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
236 # An already specified objectclass cannot be added another time
237 m = Message()
238 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
239 m["objectClass"] = MessageElement("person", FLAG_MOD_ADD,
240 "objectClass")
241 try:
242 ldb.modify(m)
243 self.fail()
244 except LdbError, (num, _):
245 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
247 # Auxiliary classes can always be added
248 m = Message()
249 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
250 m["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_ADD,
251 "objectClass")
252 ldb.modify(m)
254 # It's only possible to replace with the same objectclass combination.
255 # So the replace action on "objectClass" attributes is really useless.
256 m = Message()
257 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
258 m["objectClass"] = MessageElement(["top", "person", "bootableDevice"],
259 FLAG_MOD_REPLACE, "objectClass")
260 ldb.modify(m)
262 m = Message()
263 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
264 m["objectClass"] = MessageElement(["person", "bootableDevice"],
265 FLAG_MOD_REPLACE, "objectClass")
266 ldb.modify(m)
268 m = Message()
269 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
270 m["objectClass"] = MessageElement(["top", "person", "bootableDevice",
271 "connectionPoint"], FLAG_MOD_REPLACE, "objectClass")
272 try:
273 ldb.modify(m)
274 self.fail()
275 except LdbError, (num, _):
276 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
278 # More than one change operation is allowed
279 m = Message()
280 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
281 m.add(MessageElement("bootableDevice", FLAG_MOD_DELETE, "objectClass"))
282 m.add(MessageElement("bootableDevice", FLAG_MOD_ADD, "objectClass"))
283 ldb.modify(m)
285 # We cannot remove all object classes by an empty replace
286 m = Message()
287 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
288 m["objectClass"] = MessageElement([], FLAG_MOD_REPLACE, "objectClass")
289 try:
290 ldb.modify(m)
291 self.fail()
292 except LdbError, (num, _):
293 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
295 m = Message()
296 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
297 m["objectClass"] = MessageElement(["top", "computer"], FLAG_MOD_REPLACE,
298 "objectClass")
299 try:
300 ldb.modify(m)
301 self.fail()
302 except LdbError, (num, _):
303 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
305 # Classes can be removed unless attributes of them are used.
306 m = Message()
307 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
308 m["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_DELETE,
309 "objectClass")
310 ldb.modify(m)
312 res = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
313 scope=SCOPE_BASE, attrs=["objectClass"])
314 self.assertTrue(len(res) == 1)
315 self.assertFalse("bootableDevice" in res[0]["objectClass"])
317 m = Message()
318 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
319 m["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_ADD,
320 "objectClass")
321 ldb.modify(m)
323 # Add an attribute specific to the "bootableDevice" class
324 m = Message()
325 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
326 m["bootParameter"] = MessageElement("test", FLAG_MOD_ADD,
327 "bootParameter")
328 ldb.modify(m)
330 # Classes can be removed unless attributes of them are used. Now there
331 # exist such attributes on the entry.
332 m = Message()
333 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
334 m["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_DELETE,
335 "objectClass")
336 try:
337 ldb.modify(m)
338 self.fail()
339 except LdbError, (num, _):
340 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
342 # Remove the previously specified attribute
343 m = Message()
344 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
345 m["bootParameter"] = MessageElement("test", FLAG_MOD_DELETE,
346 "bootParameter")
347 ldb.modify(m)
349 # Classes can be removed unless attributes of them are used.
350 m = Message()
351 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
352 m["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_DELETE,
353 "objectClass")
354 ldb.modify(m)
356 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
358 def test_system_only(self):
359 """Test systemOnly objects"""
360 print "Test systemOnly objects"""
362 try:
363 self.ldb.add({
364 "dn": "cn=ldaptestobject," + self.base_dn,
365 "objectclass": "configuration"})
366 self.fail()
367 except LdbError, (num, _):
368 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
370 try:
371 self.ldb.add({
372 "dn": "cn=Test Secret,cn=system," + self.base_dn,
373 "objectclass": "secret"})
374 self.fail()
375 except LdbError, (num, _):
376 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
378 delete_force(self.ldb, "cn=ldaptestobject," + self.base_dn)
379 delete_force(self.ldb, "cn=Test Secret,cn=system," + self.base_dn)
381 # Create secret over LSA and try to change it
383 lsa_conn = lsa.lsarpc("ncacn_np:%s" % args[0], lp, creds)
384 lsa_handle = lsa_conn.OpenPolicy2(system_name="\\",
385 attr=lsa.ObjectAttribute(),
386 access_mask=security.SEC_FLAG_MAXIMUM_ALLOWED)
387 secret_name = lsa.String()
388 secret_name.string = "G$Test"
389 sec_handle = lsa_conn.CreateSecret(handle=lsa_handle,
390 name=secret_name,
391 access_mask=security.SEC_FLAG_MAXIMUM_ALLOWED)
392 lsa_conn.Close(lsa_handle)
394 m = Message()
395 m.dn = Dn(ldb, "cn=Test Secret,cn=system," + self.base_dn)
396 m["description"] = MessageElement("desc", FLAG_MOD_REPLACE,
397 "description")
398 try:
399 ldb.modify(m)
400 self.fail()
401 except LdbError, (num, _):
402 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
404 delete_force(self.ldb, "cn=Test Secret,cn=system," + self.base_dn)
406 try:
407 self.ldb.add({
408 "dn": "cn=ldaptestcontainer," + self.base_dn,
409 "objectclass": "container",
410 "isCriticalSystemObject": "TRUE"})
411 self.fail()
412 except LdbError, (num, _):
413 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
415 self.ldb.add({
416 "dn": "cn=ldaptestcontainer," + self.base_dn,
417 "objectclass": "container"})
419 m = Message()
420 m.dn = Dn(ldb, "cn=ldaptestcontainer," + self.base_dn)
421 m["isCriticalSystemObject"] = MessageElement("TRUE", FLAG_MOD_REPLACE,
422 "isCriticalSystemObject")
423 try:
424 ldb.modify(m)
425 self.fail()
426 except LdbError, (num, _):
427 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
429 delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
431 # Proof if DC SAM object has "isCriticalSystemObject" set
432 res = self.ldb.search("", scope=SCOPE_BASE, attrs=["serverName"])
433 self.assertTrue(len(res) == 1)
434 self.assertTrue("serverName" in res[0])
435 res = self.ldb.search(res[0]["serverName"][0], scope=SCOPE_BASE,
436 attrs=["serverReference"])
437 self.assertTrue(len(res) == 1)
438 self.assertTrue("serverReference" in res[0])
439 res = self.ldb.search(res[0]["serverReference"][0], scope=SCOPE_BASE,
440 attrs=["isCriticalSystemObject"])
441 self.assertTrue(len(res) == 1)
442 self.assertTrue("isCriticalSystemObject" in res[0])
443 self.assertEquals(res[0]["isCriticalSystemObject"][0], "TRUE")
445 def test_invalid_parent(self):
446 """Test adding an object with invalid parent"""
447 print "Test adding an object with invalid parent"""
449 try:
450 self.ldb.add({
451 "dn": "cn=ldaptestgroup,cn=thisdoesnotexist123,"
452 + self.base_dn,
453 "objectclass": "group"})
454 self.fail()
455 except LdbError, (num, _):
456 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
458 delete_force(self.ldb, "cn=ldaptestgroup,cn=thisdoesnotexist123,"
459 + self.base_dn)
461 try:
462 self.ldb.add({
463 "dn": "ou=testou,cn=users," + self.base_dn,
464 "objectclass": "organizationalUnit"})
465 self.fail()
466 except LdbError, (num, _):
467 self.assertEquals(num, ERR_NAMING_VIOLATION)
469 delete_force(self.ldb, "ou=testou,cn=users," + self.base_dn)
471 def test_invalid_attribute(self):
472 """Test invalid attributes on schema/objectclasses"""
473 print "Test invalid attributes on schema/objectclasses"""
475 # attributes not in schema test
477 # add operation
479 try:
480 self.ldb.add({
481 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
482 "objectclass": "group",
483 "thisdoesnotexist": "x"})
484 self.fail()
485 except LdbError, (num, _):
486 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
488 self.ldb.add({
489 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
490 "objectclass": "group"})
492 # modify operation
494 m = Message()
495 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
496 m["thisdoesnotexist"] = MessageElement("x", FLAG_MOD_REPLACE,
497 "thisdoesnotexist")
498 try:
499 ldb.modify(m)
500 self.fail()
501 except LdbError, (num, _):
502 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
504 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
506 # attributes not in objectclasses and mandatory attributes missing test
507 # Use here a non-SAM entry since it doesn't have special triggers
508 # associated which have an impact on the error results.
510 # add operations
512 # mandatory attribute missing
513 try:
514 self.ldb.add({
515 "dn": "cn=ldaptestobject," + self.base_dn,
516 "objectclass": "ipProtocol"})
517 self.fail()
518 except LdbError, (num, _):
519 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
521 # inadequate but schema-valid attribute specified
522 try:
523 self.ldb.add({
524 "dn": "cn=ldaptestobject," + self.base_dn,
525 "objectclass": "ipProtocol",
526 "ipProtocolNumber": "1",
527 "uid" : "0"})
528 self.fail()
529 except LdbError, (num, _):
530 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
532 self.ldb.add({
533 "dn": "cn=ldaptestobject," + self.base_dn,
534 "objectclass": "ipProtocol",
535 "ipProtocolNumber": "1"})
537 # modify operations
539 # inadequate but schema-valid attribute add trial
540 m = Message()
541 m.dn = Dn(ldb, "cn=ldaptestobject," + self.base_dn)
542 m["uid"] = MessageElement("0", FLAG_MOD_ADD, "uid")
543 try:
544 ldb.modify(m)
545 self.fail()
546 except LdbError, (num, _):
547 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
549 # mandatory attribute delete trial
550 m = Message()
551 m.dn = Dn(ldb, "cn=ldaptestobject," + self.base_dn)
552 m["ipProtocolNumber"] = MessageElement([], FLAG_MOD_DELETE,
553 "ipProtocolNumber")
554 try:
555 ldb.modify(m)
556 self.fail()
557 except LdbError, (num, _):
558 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
560 # mandatory attribute delete trial
561 m = Message()
562 m.dn = Dn(ldb, "cn=ldaptestobject," + self.base_dn)
563 m["ipProtocolNumber"] = MessageElement([], FLAG_MOD_REPLACE,
564 "ipProtocolNumber")
565 try:
566 ldb.modify(m)
567 self.fail()
568 except LdbError, (num, _):
569 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
571 delete_force(self.ldb, "cn=ldaptestobject," + self.base_dn)
573 def test_single_valued_attributes(self):
574 """Test single-valued attributes"""
575 print "Test single-valued attributes"""
577 try:
578 self.ldb.add({
579 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
580 "objectclass": "group",
581 "sAMAccountName": ["nam1", "nam2"]})
582 self.fail()
583 except LdbError, (num, _):
584 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
586 self.ldb.add({
587 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
588 "objectclass": "group"})
590 m = Message()
591 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
592 m["sAMAccountName"] = MessageElement(["nam1","nam2"], FLAG_MOD_REPLACE,
593 "sAMAccountName")
594 try:
595 ldb.modify(m)
596 self.fail()
597 except LdbError, (num, _):
598 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
600 m = Message()
601 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
602 m["sAMAccountName"] = MessageElement("testgroupXX", FLAG_MOD_REPLACE,
603 "sAMAccountName")
604 ldb.modify(m)
606 m = Message()
607 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
608 m["sAMAccountName"] = MessageElement("testgroupXX2", FLAG_MOD_ADD,
609 "sAMAccountName")
610 try:
611 ldb.modify(m)
612 self.fail()
613 except LdbError, (num, _):
614 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
616 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
618 def test_attribute_ranges(self):
619 """Test attribute ranges"""
620 print "Test attribute ranges"""
622 # Too short (min. 1)
623 try:
624 ldb.add({
625 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
626 "objectClass": "person",
627 "sn": "" })
628 self.fail()
629 except LdbError, (num, _):
630 self.assertEquals(num, ERR_INVALID_ATTRIBUTE_SYNTAX)
632 # Too long (max. 64)
633 # try:
634 # ldb.add({
635 # "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
636 # "objectClass": "person",
637 # "sn": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" })
638 # self.fail()
639 # except LdbError, (num, _):
640 # self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
642 ldb.add({
643 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
644 "objectClass": "person" })
646 # Too short (min. 1)
647 m = Message()
648 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
649 m["sn"] = MessageElement("", FLAG_MOD_REPLACE, "sn")
650 try:
651 ldb.modify(m)
652 self.fail()
653 except LdbError, (num, _):
654 self.assertEquals(num, ERR_INVALID_ATTRIBUTE_SYNTAX)
656 # Too long (max. 64)
657 # m = Message()
658 # m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
659 # m["sn"] = MessageElement("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", FLAG_MOD_REPLACE, "sn")
660 # try:
661 # ldb.modify(m)
662 # self.fail()
663 # except LdbError, (num, _):
664 # self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
666 m = Message()
667 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
668 m["sn"] = MessageElement("x", FLAG_MOD_REPLACE, "sn")
669 ldb.modify(m)
671 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
673 def test_empty_messages(self):
674 """Test empty messages"""
675 print "Test empty messages"""
677 m = Message()
678 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
680 try:
681 ldb.add(m)
682 self.fail()
683 except LdbError, (num, _):
684 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
686 try:
687 ldb.modify(m)
688 self.fail()
689 except LdbError, (num, _):
690 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
692 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
694 def test_empty_attributes(self):
695 """Test empty attributes"""
696 print "Test empty attributes"""
698 m = Message()
699 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
700 m["objectClass"] = MessageElement("group", FLAG_MOD_ADD, "objectClass")
701 m["description"] = MessageElement([], FLAG_MOD_ADD, "description")
703 try:
704 ldb.add(m)
705 self.fail()
706 except LdbError, (num, _):
707 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
709 self.ldb.add({
710 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
711 "objectclass": "group"})
713 m = Message()
714 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
715 m["description"] = MessageElement([], FLAG_MOD_ADD, "description")
717 try:
718 ldb.modify(m)
719 self.fail()
720 except LdbError, (num, _):
721 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
723 m = Message()
724 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
725 m["description"] = MessageElement([], FLAG_MOD_REPLACE, "description")
726 ldb.modify(m)
728 m = Message()
729 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
730 m["description"] = MessageElement([], FLAG_MOD_DELETE, "description")
731 try:
732 ldb.modify(m)
733 self.fail()
734 except LdbError, (num, _):
735 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
737 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
739 def test_instanceType(self):
740 """Tests the 'instanceType' attribute"""
741 print "Tests the 'instanceType' attribute"""
743 # The instance type is single-valued
744 try:
745 self.ldb.add({
746 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
747 "objectclass": "group",
748 "instanceType": ["0", "1"]})
749 self.fail()
750 except LdbError, (num, _):
751 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
753 # The head NC flag cannot be set without the write flag
754 try:
755 self.ldb.add({
756 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
757 "objectclass": "group",
758 "instanceType": "1" })
759 self.fail()
760 except LdbError, (num, _):
761 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
763 # We cannot manipulate NCs without the head NC flag
764 try:
765 self.ldb.add({
766 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
767 "objectclass": "group",
768 "instanceType": "32" })
769 self.fail()
770 except LdbError, (num, _):
771 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
773 self.ldb.add({
774 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
775 "objectclass": "group"})
777 m = Message()
778 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
779 m["instanceType"] = MessageElement("0", FLAG_MOD_REPLACE,
780 "instanceType")
781 try:
782 ldb.modify(m)
783 self.fail()
784 except LdbError, (num, _):
785 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
787 m = Message()
788 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
789 m["instanceType"] = MessageElement([], FLAG_MOD_REPLACE,
790 "instanceType")
791 try:
792 ldb.modify(m)
793 self.fail()
794 except LdbError, (num, _):
795 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
797 m = Message()
798 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
799 m["instanceType"] = MessageElement([], FLAG_MOD_DELETE, "instanceType")
800 try:
801 ldb.modify(m)
802 self.fail()
803 except LdbError, (num, _):
804 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
806 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
808 def test_distinguished_name(self):
809 """Tests the 'distinguishedName' attribute"""
810 print "Tests the 'distinguishedName' attribute"""
812 # The "dn" shortcut isn't supported
813 m = Message()
814 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
815 m["objectClass"] = MessageElement("group", 0, "objectClass")
816 m["dn"] = MessageElement("cn=ldaptestgroup,cn=users," + self.base_dn, 0,
817 "dn")
818 try:
819 ldb.add(m)
820 self.fail()
821 except LdbError, (num, _):
822 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
824 # a wrong "distinguishedName" attribute is obviously tolerated
825 self.ldb.add({
826 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
827 "objectclass": "group",
828 "distinguishedName": "cn=ldaptest,cn=users," + self.base_dn})
830 # proof if the DN has been set correctly
831 res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
832 scope=SCOPE_BASE, attrs=["distinguishedName"])
833 self.assertTrue(len(res) == 1)
834 self.assertTrue("distinguishedName" in res[0])
835 self.assertTrue(Dn(ldb, res[0]["distinguishedName"][0])
836 == Dn(ldb, "cn=ldaptestgroup, cn=users," + self.base_dn))
838 # The "dn" shortcut isn't supported
839 m = Message()
840 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
841 m["dn"] = MessageElement(
842 "cn=ldaptestgroup,cn=users," + self.base_dn, FLAG_MOD_REPLACE,
843 "dn")
844 try:
845 ldb.modify(m)
846 self.fail()
847 except LdbError, (num, _):
848 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
850 m = Message()
851 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
852 m["distinguishedName"] = MessageElement(
853 "cn=ldaptestuser,cn=users," + self.base_dn, FLAG_MOD_ADD,
854 "distinguishedName")
856 try:
857 ldb.modify(m)
858 self.fail()
859 except LdbError, (num, _):
860 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
862 m = Message()
863 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
864 m["distinguishedName"] = MessageElement(
865 "cn=ldaptestuser,cn=users," + self.base_dn, FLAG_MOD_REPLACE,
866 "distinguishedName")
868 try:
869 ldb.modify(m)
870 self.fail()
871 except LdbError, (num, _):
872 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
874 m = Message()
875 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
876 m["distinguishedName"] = MessageElement(
877 "cn=ldaptestuser,cn=users," + self.base_dn, FLAG_MOD_DELETE,
878 "distinguishedName")
880 try:
881 ldb.modify(m)
882 self.fail()
883 except LdbError, (num, _):
884 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
886 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
888 def test_rdn_name(self):
889 """Tests the RDN"""
890 print "Tests the RDN"""
892 # Search
894 # empty RDN
895 try:
896 self.ldb.search("=,cn=users," + self.base_dn, scope=SCOPE_BASE)
897 self.fail()
898 except LdbError, (num, _):
899 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
901 # empty RDN name
902 try:
903 self.ldb.search("cn=,cn=users," + self.base_dn, scope=SCOPE_BASE)
904 self.fail()
905 except LdbError, (num, _):
906 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
908 try:
909 self.ldb.search("=ldaptestgroup,cn=users," + self.base_dn, scope=SCOPE_BASE)
910 self.fail()
911 except LdbError, (num, _):
912 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
914 # Add
916 # empty RDN
917 try:
918 self.ldb.add({
919 "dn": "=,cn=users," + self.base_dn,
920 "objectclass": "group"})
921 self.fail()
922 except LdbError, (num, _):
923 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
925 # empty RDN name
926 try:
927 self.ldb.add({
928 "dn": "=ldaptestgroup,cn=users," + self.base_dn,
929 "objectclass": "group"})
930 self.fail()
931 except LdbError, (num, _):
932 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
934 # empty RDN value
935 try:
936 self.ldb.add({
937 "dn": "cn=,cn=users," + self.base_dn,
938 "objectclass": "group"})
939 self.fail()
940 except LdbError, (num, _):
941 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
943 # a wrong RDN candidate
944 try:
945 self.ldb.add({
946 "dn": "description=xyz,cn=users," + self.base_dn,
947 "objectclass": "group"})
948 self.fail()
949 except LdbError, (num, _):
950 self.assertEquals(num, ERR_NAMING_VIOLATION)
952 delete_force(self.ldb, "description=xyz,cn=users," + self.base_dn)
954 # a wrong "name" attribute is obviously tolerated
955 self.ldb.add({
956 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
957 "objectclass": "group",
958 "name": "ldaptestgroupx"})
960 # proof if the name has been set correctly
961 res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
962 scope=SCOPE_BASE, attrs=["name"])
963 self.assertTrue(len(res) == 1)
964 self.assertTrue("name" in res[0])
965 self.assertTrue(res[0]["name"][0] == "ldaptestgroup")
967 # Modify
969 # empty RDN value
970 m = Message()
971 m.dn = Dn(ldb, "cn=,cn=users," + self.base_dn)
972 m["description"] = "test"
973 try:
974 self.ldb.modify(m)
975 self.fail()
976 except LdbError, (num, _):
977 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
979 # Delete
981 # empty RDN value
982 try:
983 self.ldb.delete("cn=,cn=users," + self.base_dn)
984 self.fail()
985 except LdbError, (num, _):
986 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
988 # Rename
990 # new empty RDN
991 try:
992 self.ldb.rename("cn=ldaptestgroup,cn=users," + self.base_dn,
993 "=,cn=users," + self.base_dn)
994 self.fail()
995 except LdbError, (num, _):
996 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
998 # new empty RDN name
999 try:
1000 self.ldb.rename("cn=ldaptestgroup,cn=users," + self.base_dn,
1001 "=ldaptestgroup,cn=users," + self.base_dn)
1002 self.fail()
1003 except LdbError, (num, _):
1004 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1006 # new empty RDN value
1007 try:
1008 self.ldb.rename("cn=ldaptestgroup,cn=users," + self.base_dn,
1009 "cn=,cn=users," + self.base_dn)
1010 self.fail()
1011 except LdbError, (num, _):
1012 self.assertEquals(num, ERR_NAMING_VIOLATION)
1014 # new wrong RDN candidate
1015 try:
1016 self.ldb.rename("cn=ldaptestgroup,cn=users," + self.base_dn,
1017 "description=xyz,cn=users," + self.base_dn)
1018 self.fail()
1019 except LdbError, (num, _):
1020 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1022 delete_force(self.ldb, "description=xyz,cn=users," + self.base_dn)
1024 # old empty RDN value
1025 try:
1026 self.ldb.rename("cn=,cn=users," + self.base_dn,
1027 "cn=ldaptestgroup,cn=users," + self.base_dn)
1028 self.fail()
1029 except LdbError, (num, _):
1030 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1032 # names
1034 m = Message()
1035 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1036 m["name"] = MessageElement("cn=ldaptestuser", FLAG_MOD_REPLACE,
1037 "name")
1038 try:
1039 ldb.modify(m)
1040 self.fail()
1041 except LdbError, (num, _):
1042 self.assertEquals(num, ERR_NOT_ALLOWED_ON_RDN)
1044 m = Message()
1045 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1046 m["cn"] = MessageElement("ldaptestuser",
1047 FLAG_MOD_REPLACE, "cn")
1048 try:
1049 ldb.modify(m)
1050 self.fail()
1051 except LdbError, (num, _):
1052 self.assertEquals(num, ERR_NOT_ALLOWED_ON_RDN)
1054 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1057 # this test needs to be disabled until we really understand
1058 # what the rDN length constraints are
1059 def DISABLED_test_largeRDN(self):
1060 """Testing large rDN (limit 64 characters)"""
1061 rdn = "CN=a012345678901234567890123456789012345678901234567890123456789012";
1062 delete_force(self.ldb, "%s,%s" % (rdn, self.base_dn))
1063 ldif = """
1064 dn: %s,%s""" % (rdn,self.base_dn) + """
1065 objectClass: container
1067 self.ldb.add_ldif(ldif)
1068 delete_force(self.ldb, "%s,%s" % (rdn, self.base_dn))
1070 rdn = "CN=a0123456789012345678901234567890123456789012345678901234567890120";
1071 delete_force(self.ldb, "%s,%s" % (rdn, self.base_dn))
1072 try:
1073 ldif = """
1074 dn: %s,%s""" % (rdn,self.base_dn) + """
1075 objectClass: container
1077 self.ldb.add_ldif(ldif)
1078 self.fail()
1079 except LdbError, (num, _):
1080 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
1081 delete_force(self.ldb, "%s,%s" % (rdn, self.base_dn))
1083 def test_rename(self):
1084 """Tests the rename operation"""
1085 print "Tests the rename operations"""
1087 try:
1088 # cannot rename to be a child of itself
1089 ldb.rename(self.base_dn, "dc=test," + self.base_dn)
1090 self.fail()
1091 except LdbError, (num, _):
1092 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1094 try:
1095 # inexistent object
1096 ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser2,cn=users," + self.base_dn)
1097 self.fail()
1098 except LdbError, (num, _):
1099 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
1101 self.ldb.add({
1102 "dn": "cn=ldaptestuser2,cn=users," + self.base_dn,
1103 "objectclass": "user" })
1105 ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser2,cn=users," + self.base_dn)
1106 ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=users," + self.base_dn)
1107 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestUSER3,cn=users," + self.base_dn)
1109 try:
1110 # containment problem: a user entry cannot contain user entries
1111 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser4,cn=ldaptestuser3,cn=users," + self.base_dn)
1112 self.fail()
1113 except LdbError, (num, _):
1114 self.assertEquals(num, ERR_NAMING_VIOLATION)
1116 try:
1117 # invalid parent
1118 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=people,cn=users," + self.base_dn)
1119 self.fail()
1120 except LdbError, (num, _):
1121 self.assertEquals(num, ERR_OTHER)
1123 try:
1124 # invalid target DN syntax
1125 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, ",cn=users," + self.base_dn)
1126 self.fail()
1127 except LdbError, (num, _):
1128 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1130 try:
1131 # invalid RDN name
1132 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "ou=ldaptestuser3,cn=users," + self.base_dn)
1133 self.fail()
1134 except LdbError, (num, _):
1135 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1137 delete_force(self.ldb, "cn=ldaptestuser3,cn=users," + self.base_dn)
1139 # Performs some "systemFlags" testing
1141 # Move failing since no "SYSTEM_FLAG_CONFIG_ALLOW_MOVE"
1142 try:
1143 ldb.rename("CN=DisplaySpecifiers," + self.configuration_dn, "CN=DisplaySpecifiers,CN=Services," + self.configuration_dn)
1144 self.fail()
1145 except LdbError, (num, _):
1146 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1148 # Limited move failing since no "SYSTEM_FLAG_CONFIG_ALLOW_LIMITED_MOVE"
1149 try:
1150 ldb.rename("CN=Directory Service,CN=Windows NT,CN=Services," + self.configuration_dn, "CN=Directory Service,CN=RRAS,CN=Services," + self.configuration_dn)
1151 self.fail()
1152 except LdbError, (num, _):
1153 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1155 # Rename failing since no "SYSTEM_FLAG_CONFIG_ALLOW_RENAME"
1156 try:
1157 ldb.rename("CN=DisplaySpecifiers," + self.configuration_dn, "CN=DisplaySpecifiers2," + self.configuration_dn)
1158 self.fail()
1159 except LdbError, (num, _):
1160 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1162 # It's not really possible to test moves on the schema partition since
1163 # there don't exist subcontainers on it.
1165 # Rename failing since "SYSTEM_FLAG_SCHEMA_BASE_OBJECT"
1166 try:
1167 ldb.rename("CN=Top," + self.schema_dn, "CN=Top2," + self.schema_dn)
1168 self.fail()
1169 except LdbError, (num, _):
1170 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1172 # Move failing since "SYSTEM_FLAG_DOMAIN_DISALLOW_MOVE"
1173 try:
1174 ldb.rename("CN=Users," + self.base_dn, "CN=Users,CN=Computers," + self.base_dn)
1175 self.fail()
1176 except LdbError, (num, _):
1177 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1179 # Rename failing since "SYSTEM_FLAG_DOMAIN_DISALLOW_RENAME"
1180 try:
1181 ldb.rename("CN=Users," + self.base_dn, "CN=Users2," + self.base_dn)
1182 self.fail()
1183 except LdbError, (num, _):
1184 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1186 # Performs some other constraints testing
1188 try:
1189 ldb.rename("CN=Policies,CN=System," + self.base_dn, "CN=Users2," + self.base_dn)
1190 self.fail()
1191 except LdbError, (num, _):
1192 self.assertEquals(num, ERR_OTHER)
1194 def test_rename_twice(self):
1195 """Tests the rename operation twice - this corresponds to a past bug"""
1196 print "Tests the rename twice operation"""
1198 self.ldb.add({
1199 "dn": "cn=ldaptestuser5,cn=users," + self.base_dn,
1200 "objectclass": "user" })
1202 ldb.rename("cn=ldaptestuser5,cn=users," + self.base_dn, "cn=ldaptestUSER5,cn=users," + self.base_dn)
1203 delete_force(self.ldb, "cn=ldaptestuser5,cn=users," + self.base_dn)
1204 self.ldb.add({
1205 "dn": "cn=ldaptestuser5,cn=users," + self.base_dn,
1206 "objectclass": "user" })
1207 ldb.rename("cn=ldaptestuser5,cn=Users," + self.base_dn, "cn=ldaptestUSER5,cn=users," + self.base_dn)
1208 res = ldb.search(expression="cn=ldaptestuser5")
1209 print "Found %u records" % len(res)
1210 self.assertEquals(len(res), 1, "Wrong number of hits for cn=ldaptestuser5")
1211 res = ldb.search(expression="(&(cn=ldaptestuser5)(objectclass=user))")
1212 print "Found %u records" % len(res)
1213 self.assertEquals(len(res), 1, "Wrong number of hits for (&(cn=ldaptestuser5)(objectclass=user))")
1214 delete_force(self.ldb, "cn=ldaptestuser5,cn=users," + self.base_dn)
1216 def test_objectGUID(self):
1217 """Test objectGUID behaviour"""
1218 print "Testing objectGUID behaviour\n"
1220 # The objectGUID cannot directly be set
1221 try:
1222 self.ldb.add_ldif("""
1223 dn: cn=ldaptestcontainer,""" + self.base_dn + """
1224 objectClass: container
1225 objectGUID: bd3480c9-58af-4cd8-92df-bc4a18b6e44d
1226 """)
1227 self.fail()
1228 except LdbError, (num, _):
1229 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1231 self.ldb.add({
1232 "dn": "cn=ldaptestcontainer," + self.base_dn,
1233 "objectClass": "container" })
1235 res = ldb.search("cn=ldaptestcontainer," + self.base_dn,
1236 scope=SCOPE_BASE,
1237 attrs=["objectGUID", "uSNCreated", "uSNChanged", "whenCreated", "whenChanged"])
1238 self.assertTrue(len(res) == 1)
1239 self.assertTrue("objectGUID" in res[0])
1240 self.assertTrue("uSNCreated" in res[0])
1241 self.assertTrue("uSNChanged" in res[0])
1242 self.assertTrue("whenCreated" in res[0])
1243 self.assertTrue("whenChanged" in res[0])
1245 delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
1247 # All the following attributes are specificable on add operations
1248 self.ldb.add({
1249 "dn": "cn=ldaptestcontainer," + self.base_dn,
1250 "objectClass": "container",
1251 "uSNCreated" : "1",
1252 "uSNChanged" : "1",
1253 "whenCreated": timestring(long(time.time())),
1254 "whenChanged": timestring(long(time.time())) })
1256 res = ldb.search("cn=ldaptestcontainer," + self.base_dn,
1257 scope=SCOPE_BASE,
1258 attrs=["objectGUID", "uSNCreated", "uSNChanged", "whenCreated", "whenChanged"])
1259 self.assertTrue(len(res) == 1)
1260 self.assertTrue("objectGUID" in res[0])
1261 self.assertTrue("uSNCreated" in res[0])
1262 self.assertFalse(res[0]["uSNCreated"][0] == "1") # these are corrected
1263 self.assertTrue("uSNChanged" in res[0])
1264 self.assertFalse(res[0]["uSNChanged"][0] == "1") # these are corrected
1266 delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
1268 # All this attributes are specificable on add operations
1269 self.ldb.add({
1270 "dn": "cn=ldaptestcontainer," + self.base_dn,
1271 "objectclass": "container",
1272 "uSNCreated" : "1",
1273 "uSNChanged" : "1",
1274 "whenCreated": timestring(long(time.time())),
1275 "whenChanged": timestring(long(time.time())) })
1277 res = ldb.search("cn=ldaptestcontainer," + self.base_dn,
1278 scope=SCOPE_BASE,
1279 attrs=["objectGUID", "uSNCreated", "uSNChanged", "whenCreated", "whenChanged"])
1280 self.assertTrue(len(res) == 1)
1281 self.assertTrue("objectGUID" in res[0])
1282 self.assertTrue("uSNCreated" in res[0])
1283 self.assertFalse(res[0]["uSNCreated"][0] == "1") # these are corrected
1284 self.assertTrue("uSNChanged" in res[0])
1285 self.assertFalse(res[0]["uSNChanged"][0] == "1") # these are corrected
1286 self.assertTrue("whenCreated" in res[0])
1287 self.assertTrue("whenChanged" in res[0])
1289 # The objectGUID cannot directly be changed
1290 try:
1291 self.ldb.modify_ldif("""
1292 dn: cn=ldaptestcontainer,""" + self.base_dn + """
1293 changetype: modify
1294 replace: objectGUID
1295 objectGUID: bd3480c9-58af-4cd8-92df-bc4a18b6e44d
1296 """)
1297 self.fail()
1298 except LdbError, (num, _):
1299 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
1301 delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
1303 def test_parentGUID(self):
1304 """Test parentGUID behaviour"""
1305 print "Testing parentGUID behaviour\n"
1307 self.ldb.add({
1308 "dn": "cn=parentguidtest,cn=users," + self.base_dn,
1309 "objectclass":"user",
1310 "samaccountname":"parentguidtest"});
1311 res1 = ldb.search(base="cn=parentguidtest,cn=users," + self.base_dn, scope=SCOPE_BASE,
1312 attrs=["parentGUID", "samaccountname"]);
1313 res2 = ldb.search(base="cn=users," + self.base_dn,scope=SCOPE_BASE,
1314 attrs=["objectGUID"]);
1315 res3 = ldb.search(base=self.base_dn, scope=SCOPE_BASE,
1316 attrs=["parentGUID"]);
1317 res4 = ldb.search(base=self.configuration_dn, scope=SCOPE_BASE,
1318 attrs=["parentGUID"]);
1319 res5 = ldb.search(base=self.schema_dn, scope=SCOPE_BASE,
1320 attrs=["parentGUID"]);
1322 """Check if the parentGUID is valid """
1323 self.assertEquals(res1[0]["parentGUID"], res2[0]["objectGUID"]);
1325 """Check if it returns nothing when there is no parent object - default NC"""
1326 has_parentGUID = False
1327 for key in res3[0].keys():
1328 if key == "parentGUID":
1329 has_parentGUID = True
1330 break
1331 self.assertFalse(has_parentGUID);
1333 """Check if it returns nothing when there is no parent object - configuration NC"""
1334 has_parentGUID = False
1335 for key in res4[0].keys():
1336 if key == "parentGUID":
1337 has_parentGUID = True
1338 break
1339 self.assertFalse(has_parentGUID);
1341 """Check if it returns nothing when there is no parent object - schema NC"""
1342 has_parentGUID = False
1343 for key in res5[0].keys():
1344 if key == "parentGUID":
1345 has_parentGUID = True
1346 break
1347 self.assertFalse(has_parentGUID);
1349 """Ensures that if you look for another object attribute after the constructed
1350 parentGUID, it will return correctly"""
1351 has_another_attribute = False
1352 for key in res1[0].keys():
1353 if key == "sAMAccountName":
1354 has_another_attribute = True
1355 break
1356 self.assertTrue(has_another_attribute)
1357 self.assertTrue(len(res1[0]["samaccountname"]) == 1)
1358 self.assertEquals(res1[0]["samaccountname"][0], "parentguidtest");
1360 print "Testing parentGUID behaviour on rename\n"
1362 self.ldb.add({
1363 "dn": "cn=testotherusers," + self.base_dn,
1364 "objectclass":"container"});
1365 res1 = ldb.search(base="cn=testotherusers," + self.base_dn,scope=SCOPE_BASE,
1366 attrs=["objectGUID"]);
1367 ldb.rename("cn=parentguidtest,cn=users," + self.base_dn,
1368 "cn=parentguidtest,cn=testotherusers," + self.base_dn);
1369 res2 = ldb.search(base="cn=parentguidtest,cn=testotherusers," + self.base_dn,
1370 scope=SCOPE_BASE,
1371 attrs=["parentGUID"]);
1372 self.assertEquals(res1[0]["objectGUID"], res2[0]["parentGUID"]);
1374 delete_force(self.ldb, "cn=parentguidtest,cn=testotherusers," + self.base_dn)
1375 delete_force(self.ldb, "cn=testotherusers," + self.base_dn)
1377 def test_groupType_int32(self):
1378 """Test groupType (int32) behaviour (should appear to be casted to a 32 bit signed integer before comparsion)"""
1379 print "Testing groupType (int32) behaviour\n"
1381 res1 = ldb.search(base=self.base_dn, scope=SCOPE_SUBTREE,
1382 attrs=["groupType"], expression="groupType=2147483653");
1384 res2 = ldb.search(base=self.base_dn, scope=SCOPE_SUBTREE,
1385 attrs=["groupType"], expression="groupType=-2147483643");
1387 self.assertEquals(len(res1), len(res2))
1389 self.assertTrue(res1.count > 0)
1391 self.assertEquals(res1[0]["groupType"][0], "-2147483643")
1393 def test_linked_attributes(self):
1394 """This tests the linked attribute behaviour"""
1395 print "Testing linked attribute behaviour\n"
1397 ldb.add({
1398 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
1399 "objectclass": "group"})
1401 # This should not work since "memberOf" is linked to "member"
1402 try:
1403 ldb.add({
1404 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1405 "objectclass": "user",
1406 "memberOf": "cn=ldaptestgroup,cn=users," + self.base_dn})
1407 except LdbError, (num, _):
1408 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1410 ldb.add({
1411 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1412 "objectclass": "user"})
1414 m = Message()
1415 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1416 m["memberOf"] = MessageElement("cn=ldaptestgroup,cn=users," + self.base_dn,
1417 FLAG_MOD_ADD, "memberOf")
1418 try:
1419 ldb.modify(m)
1420 self.fail()
1421 except LdbError, (num, _):
1422 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1424 m = Message()
1425 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1426 m["member"] = MessageElement("cn=ldaptestuser,cn=users," + self.base_dn,
1427 FLAG_MOD_ADD, "member")
1428 ldb.modify(m)
1430 m = Message()
1431 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1432 m["memberOf"] = MessageElement("cn=ldaptestgroup,cn=users," + self.base_dn,
1433 FLAG_MOD_REPLACE, "memberOf")
1434 try:
1435 ldb.modify(m)
1436 self.fail()
1437 except LdbError, (num, _):
1438 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1440 m = Message()
1441 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1442 m["memberOf"] = MessageElement("cn=ldaptestgroup,cn=users," + self.base_dn,
1443 FLAG_MOD_DELETE, "memberOf")
1444 try:
1445 ldb.modify(m)
1446 self.fail()
1447 except LdbError, (num, _):
1448 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1450 m = Message()
1451 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1452 m["member"] = MessageElement("cn=ldaptestuser,cn=users," + self.base_dn,
1453 FLAG_MOD_DELETE, "member")
1454 ldb.modify(m)
1456 # This should yield no results since the member attribute for
1457 # "ldaptestuser" should have been deleted
1458 res1 = ldb.search("cn=ldaptestgroup, cn=users," + self.base_dn,
1459 scope=SCOPE_BASE,
1460 expression="(member=cn=ldaptestuser,cn=users," + self.base_dn + ")",
1461 attrs=[])
1462 self.assertTrue(len(res1) == 0)
1464 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1466 ldb.add({
1467 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
1468 "objectclass": "group",
1469 "member": "cn=ldaptestuser,cn=users," + self.base_dn})
1471 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1473 # Make sure that the "member" attribute for "ldaptestuser" has been
1474 # removed
1475 res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
1476 scope=SCOPE_BASE, attrs=["member"])
1477 self.assertTrue(len(res) == 1)
1478 self.assertFalse("member" in res[0])
1480 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1482 def test_wkguid(self):
1483 """Test Well known GUID behaviours (including DN+Binary)"""
1484 print "Test Well known GUID behaviours (including DN+Binary)"""
1486 res = self.ldb.search(base=("<WKGUID=ab1d30f3768811d1aded00c04fd8d5cd,%s>" % self.base_dn), scope=SCOPE_BASE, attrs=[])
1487 self.assertEquals(len(res), 1)
1489 res2 = self.ldb.search(scope=SCOPE_BASE, attrs=["wellKnownObjects"], expression=("wellKnownObjects=B:32:ab1d30f3768811d1aded00c04fd8d5cd:%s" % res[0].dn))
1490 self.assertEquals(len(res2), 1)
1492 # Prove that the matching rule is over the whole DN+Binary
1493 res2 = self.ldb.search(scope=SCOPE_BASE, attrs=["wellKnownObjects"], expression=("wellKnownObjects=B:32:ab1d30f3768811d1aded00c04fd8d5cd"))
1494 self.assertEquals(len(res2), 0)
1495 # Prove that the matching rule is over the whole DN+Binary
1496 res2 = self.ldb.search(scope=SCOPE_BASE, attrs=["wellKnownObjects"], expression=("wellKnownObjects=%s") % res[0].dn)
1497 self.assertEquals(len(res2), 0)
1499 def test_subschemasubentry(self):
1500 """Test subSchemaSubEntry appears when requested, but not when not requested"""
1501 print "Test subSchemaSubEntry"""
1503 res = self.ldb.search(base=self.base_dn, scope=SCOPE_BASE, attrs=["subSchemaSubEntry"])
1504 self.assertEquals(len(res), 1)
1505 self.assertEquals(res[0]["subSchemaSubEntry"][0], "CN=Aggregate,"+self.schema_dn)
1507 res = self.ldb.search(base=self.base_dn, scope=SCOPE_BASE, attrs=["*"])
1508 self.assertEquals(len(res), 1)
1509 self.assertTrue("subScheamSubEntry" not in res[0])
1511 def test_all(self):
1512 """Basic tests"""
1514 print "Testing user add"
1516 ldb.add({
1517 "dn": "cn=ldaptestuser,cn=uSers," + self.base_dn,
1518 "objectclass": "user",
1519 "cN": "LDAPtestUSER",
1520 "givenname": "ldap",
1521 "sn": "testy"})
1523 ldb.add({
1524 "dn": "cn=ldaptestgroup,cn=uSers," + self.base_dn,
1525 "objectclass": "group",
1526 "member": "cn=ldaptestuser,cn=useRs," + self.base_dn})
1528 ldb.add({
1529 "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
1530 "objectclass": "computer",
1531 "cN": "LDAPtestCOMPUTER"})
1533 ldb.add({"dn": "cn=ldaptest2computer,cn=computers," + self.base_dn,
1534 "objectClass": "computer",
1535 "cn": "LDAPtest2COMPUTER",
1536 "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT),
1537 "displayname": "ldap testy"})
1539 try:
1540 ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn,
1541 "objectClass": "computer",
1542 "cn": "LDAPtest2COMPUTER"
1544 self.fail()
1545 except LdbError, (num, _):
1546 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1548 try:
1549 ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn,
1550 "objectClass": "computer",
1551 "cn": "ldaptestcomputer3",
1552 "sAMAccountType": str(ATYPE_NORMAL_ACCOUNT)
1554 self.fail()
1555 except LdbError, (num, _):
1556 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1558 ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn,
1559 "objectClass": "computer",
1560 "cn": "LDAPtestCOMPUTER3"
1563 print "Testing ldb.search for (&(cn=ldaptestcomputer3)(objectClass=user))";
1564 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestcomputer3)(objectClass=user))");
1565 self.assertEquals(len(res), 1, "Found only %d for (&(cn=ldaptestcomputer3)(objectClass=user))" % len(res))
1567 self.assertEquals(str(res[0].dn), ("CN=ldaptestcomputer3,CN=Computers," + self.base_dn));
1568 self.assertEquals(res[0]["cn"][0], "ldaptestcomputer3");
1569 self.assertEquals(res[0]["name"][0], "ldaptestcomputer3");
1570 self.assertEquals(res[0]["objectClass"][0], "top");
1571 self.assertEquals(res[0]["objectClass"][1], "person");
1572 self.assertEquals(res[0]["objectClass"][2], "organizationalPerson");
1573 self.assertEquals(res[0]["objectClass"][3], "user");
1574 self.assertEquals(res[0]["objectClass"][4], "computer");
1575 self.assertTrue("objectGUID" in res[0])
1576 self.assertTrue("whenCreated" in res[0])
1577 self.assertEquals(res[0]["objectCategory"][0], ("CN=Computer,%s" % ldb.get_schema_basedn()))
1578 self.assertEquals(int(res[0]["primaryGroupID"][0]), 513);
1579 self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_NORMAL_ACCOUNT);
1580 self.assertEquals(int(res[0]["userAccountControl"][0]), UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE);
1582 delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
1584 print "Testing attribute or value exists behaviour"
1585 try:
1586 ldb.modify_ldif("""
1587 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1588 changetype: modify
1589 replace: servicePrincipalName
1590 servicePrincipalName: host/ldaptest2computer
1591 servicePrincipalName: host/ldaptest2computer
1592 servicePrincipalName: cifs/ldaptest2computer
1593 """)
1594 self.fail()
1595 except LdbError, (num, msg):
1596 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
1598 ldb.modify_ldif("""
1599 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1600 changetype: modify
1601 replace: servicePrincipalName
1602 servicePrincipalName: host/ldaptest2computer
1603 servicePrincipalName: cifs/ldaptest2computer
1604 """)
1605 try:
1606 ldb.modify_ldif("""
1607 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1608 changetype: modify
1609 add: servicePrincipalName
1610 servicePrincipalName: host/ldaptest2computer
1611 """)
1612 self.fail()
1613 except LdbError, (num, msg):
1614 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
1616 print "Testing ranged results"
1617 ldb.modify_ldif("""
1618 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1619 changetype: modify
1620 replace: servicePrincipalName
1621 """)
1623 ldb.modify_ldif("""
1624 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1625 changetype: modify
1626 add: servicePrincipalName
1627 servicePrincipalName: host/ldaptest2computer0
1628 servicePrincipalName: host/ldaptest2computer1
1629 servicePrincipalName: host/ldaptest2computer2
1630 servicePrincipalName: host/ldaptest2computer3
1631 servicePrincipalName: host/ldaptest2computer4
1632 servicePrincipalName: host/ldaptest2computer5
1633 servicePrincipalName: host/ldaptest2computer6
1634 servicePrincipalName: host/ldaptest2computer7
1635 servicePrincipalName: host/ldaptest2computer8
1636 servicePrincipalName: host/ldaptest2computer9
1637 servicePrincipalName: host/ldaptest2computer10
1638 servicePrincipalName: host/ldaptest2computer11
1639 servicePrincipalName: host/ldaptest2computer12
1640 servicePrincipalName: host/ldaptest2computer13
1641 servicePrincipalName: host/ldaptest2computer14
1642 servicePrincipalName: host/ldaptest2computer15
1643 servicePrincipalName: host/ldaptest2computer16
1644 servicePrincipalName: host/ldaptest2computer17
1645 servicePrincipalName: host/ldaptest2computer18
1646 servicePrincipalName: host/ldaptest2computer19
1647 servicePrincipalName: host/ldaptest2computer20
1648 servicePrincipalName: host/ldaptest2computer21
1649 servicePrincipalName: host/ldaptest2computer22
1650 servicePrincipalName: host/ldaptest2computer23
1651 servicePrincipalName: host/ldaptest2computer24
1652 servicePrincipalName: host/ldaptest2computer25
1653 servicePrincipalName: host/ldaptest2computer26
1654 servicePrincipalName: host/ldaptest2computer27
1655 servicePrincipalName: host/ldaptest2computer28
1656 servicePrincipalName: host/ldaptest2computer29
1657 """)
1659 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE,
1660 attrs=["servicePrincipalName;range=0-*"])
1661 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1662 #print len(res[0]["servicePrincipalName;range=0-*"])
1663 self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30)
1665 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-19"])
1666 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1667 # print res[0]["servicePrincipalName;range=0-19"].length
1668 self.assertEquals(len(res[0]["servicePrincipalName;range=0-19"]), 20)
1671 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-30"])
1672 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1673 self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30)
1675 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-40"])
1676 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1677 self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30)
1679 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=30-40"])
1680 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1681 self.assertEquals(len(res[0]["servicePrincipalName;range=30-*"]), 0)
1684 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=10-40"])
1685 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1686 self.assertEquals(len(res[0]["servicePrincipalName;range=10-*"]), 20)
1687 # pos_11 = res[0]["servicePrincipalName;range=10-*"][18]
1689 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=11-40"])
1690 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1691 self.assertEquals(len(res[0]["servicePrincipalName;range=11-*"]), 19)
1692 # print res[0]["servicePrincipalName;range=11-*"][18]
1693 # print pos_11
1694 # self.assertEquals((res[0]["servicePrincipalName;range=11-*"][18]), pos_11)
1696 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=11-15"])
1697 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1698 self.assertEquals(len(res[0]["servicePrincipalName;range=11-15"]), 5)
1699 # self.assertEquals(res[0]["servicePrincipalName;range=11-15"][4], pos_11)
1701 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName"])
1702 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1703 # print res[0]["servicePrincipalName"][18]
1704 # print pos_11
1705 self.assertEquals(len(res[0]["servicePrincipalName"]), 30)
1706 # self.assertEquals(res[0]["servicePrincipalName"][18], pos_11)
1708 delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
1709 ldb.add({
1710 "dn": "cn=ldaptestuser2,cn=useRs," + self.base_dn,
1711 "objectClass": "user",
1712 "cn": "LDAPtestUSER2",
1713 "givenname": "testy",
1714 "sn": "ldap user2"})
1716 print "Testing Ambigious Name Resolution"
1717 # Testing ldb.search for (&(anr=ldap testy)(objectClass=user))
1718 res = ldb.search(expression="(&(anr=ldap testy)(objectClass=user))")
1719 self.assertEquals(len(res), 3, "Found only %d of 3 for (&(anr=ldap testy)(objectClass=user))" % len(res))
1721 # Testing ldb.search for (&(anr=testy ldap)(objectClass=user))
1722 res = ldb.search(expression="(&(anr=testy ldap)(objectClass=user))")
1723 self.assertEquals(len(res), 2, "Found only %d of 2 for (&(anr=testy ldap)(objectClass=user))" % len(res))
1725 # Testing ldb.search for (&(anr=ldap)(objectClass=user))
1726 res = ldb.search(expression="(&(anr=ldap)(objectClass=user))")
1727 self.assertEquals(len(res), 4, "Found only %d of 4 for (&(anr=ldap)(objectClass=user))" % len(res))
1729 # Testing ldb.search for (&(anr==ldap)(objectClass=user))
1730 res = ldb.search(expression="(&(anr==ldap)(objectClass=user))")
1731 self.assertEquals(len(res), 1, "Could not find (&(anr==ldap)(objectClass=user)). Found only %d for (&(anr=ldap)(objectClass=user))" % len(res))
1733 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
1734 self.assertEquals(res[0]["cn"][0], "ldaptestuser")
1735 self.assertEquals(str(res[0]["name"]), "ldaptestuser")
1737 # Testing ldb.search for (&(anr=testy)(objectClass=user))
1738 res = ldb.search(expression="(&(anr=testy)(objectClass=user))")
1739 self.assertEquals(len(res), 2, "Found only %d for (&(anr=testy)(objectClass=user))" % len(res))
1741 # Testing ldb.search for (&(anr=testy ldap)(objectClass=user))
1742 res = ldb.search(expression="(&(anr=testy ldap)(objectClass=user))")
1743 self.assertEquals(len(res), 2, "Found only %d for (&(anr=testy ldap)(objectClass=user))" % len(res))
1745 # Testing ldb.search for (&(anr==testy ldap)(objectClass=user))
1746 # this test disabled for the moment, as anr with == tests are not understood
1747 # res = ldb.search(expression="(&(anr==testy ldap)(objectClass=user))")
1748 # self.assertEquals(len(res), 1, "Found only %d for (&(anr==testy ldap)(objectClass=user))" % len(res))
1750 # self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
1751 # self.assertEquals(res[0]["cn"][0], "ldaptestuser")
1752 # self.assertEquals(res[0]["name"][0], "ldaptestuser")
1754 # Testing ldb.search for (&(anr==testy ldap)(objectClass=user))
1755 # res = ldb.search(expression="(&(anr==testy ldap)(objectClass=user))")
1756 # self.assertEquals(len(res), 1, "Could not find (&(anr==testy ldap)(objectClass=user))")
1758 # self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
1759 # self.assertEquals(res[0]["cn"][0], "ldaptestuser")
1760 # self.assertEquals(res[0]["name"][0], "ldaptestuser")
1762 # Testing ldb.search for (&(anr=testy ldap user)(objectClass=user))
1763 res = ldb.search(expression="(&(anr=testy ldap user)(objectClass=user))")
1764 self.assertEquals(len(res), 1, "Could not find (&(anr=testy ldap user)(objectClass=user))")
1766 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
1767 self.assertEquals(str(res[0]["cn"]), "ldaptestuser2")
1768 self.assertEquals(str(res[0]["name"]), "ldaptestuser2")
1770 # Testing ldb.search for (&(anr==testy ldap user2)(objectClass=user))
1771 # res = ldb.search(expression="(&(anr==testy ldap user2)(objectClass=user))")
1772 # self.assertEquals(len(res), 1, "Could not find (&(anr==testy ldap user2)(objectClass=user))")
1774 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
1775 self.assertEquals(str(res[0]["cn"]), "ldaptestuser2")
1776 self.assertEquals(str(res[0]["name"]), "ldaptestuser2")
1778 # Testing ldb.search for (&(anr==ldap user2)(objectClass=user))
1779 # res = ldb.search(expression="(&(anr==ldap user2)(objectClass=user))")
1780 # self.assertEquals(len(res), 1, "Could not find (&(anr==ldap user2)(objectClass=user))")
1782 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
1783 self.assertEquals(str(res[0]["cn"]), "ldaptestuser2")
1784 self.assertEquals(str(res[0]["name"]), "ldaptestuser2")
1786 # Testing ldb.search for (&(anr==not ldap user2)(objectClass=user))
1787 # res = ldb.search(expression="(&(anr==not ldap user2)(objectClass=user))")
1788 # self.assertEquals(len(res), 0, "Must not find (&(anr==not ldap user2)(objectClass=user))")
1790 # Testing ldb.search for (&(anr=not ldap user2)(objectClass=user))
1791 res = ldb.search(expression="(&(anr=not ldap user2)(objectClass=user))")
1792 self.assertEquals(len(res), 0, "Must not find (&(anr=not ldap user2)(objectClass=user))")
1794 # Testing ldb.search for (&(anr="testy ldap")(objectClass=user)) (ie, with quotes)
1795 # res = ldb.search(expression="(&(anr==\"testy ldap\")(objectClass=user))")
1796 # self.assertEquals(len(res), 0, "Found (&(anr==\"testy ldap\")(objectClass=user))")
1798 print "Testing Renames"
1800 attrs = ["objectGUID", "objectSid"]
1801 print "Testing ldb.search for (&(cn=ldaptestUSer2)(objectClass=user))"
1802 res_user = ldb.search(self.base_dn, expression="(&(cn=ldaptestUSer2)(objectClass=user))", scope=SCOPE_SUBTREE, attrs=attrs)
1803 self.assertEquals(len(res_user), 1, "Could not find (&(cn=ldaptestUSer2)(objectClass=user))")
1805 # Check rename works with extended/alternate DN forms
1806 ldb.rename("<SID=" + ldb.schema_format_value("objectSID", res_user[0]["objectSID"][0]) + ">" , "cn=ldaptestUSER3,cn=users," + self.base_dn)
1808 print "Testing ldb.search for (&(cn=ldaptestuser3)(objectClass=user))"
1809 res = ldb.search(expression="(&(cn=ldaptestuser3)(objectClass=user))")
1810 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser3)(objectClass=user))")
1812 self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
1813 self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3")
1814 self.assertEquals(str(res[0]["name"]), "ldaptestUSER3")
1816 #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))"
1817 res = ldb.search(expression="(&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))")
1818 self.assertEquals(len(res), 1, "(&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))")
1820 self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
1821 self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3")
1822 self.assertEquals(str(res[0]["name"]), "ldaptestUSER3")
1824 #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))"
1825 res = ldb.search(expression="(&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))")
1826 self.assertEquals(len(res), 1, "(&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))")
1828 self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
1829 self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3")
1830 self.assertEquals(str(res[0]["name"]), "ldaptestUSER3")
1832 #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))"
1833 res = ldb.search(expression="(&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))")
1834 self.assertEquals(len(res), 0, "(&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))")
1836 # This is a Samba special, and does not exist in real AD
1837 # print "Testing ldb.search for (dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")"
1838 # res = ldb.search("(dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")")
1839 # if (res.error != 0 || len(res) != 1) {
1840 # print "Could not find (dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")"
1841 # self.assertEquals(len(res), 1)
1843 # self.assertEquals(res[0].dn, ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
1844 # self.assertEquals(res[0].cn, "ldaptestUSER3")
1845 # self.assertEquals(res[0].name, "ldaptestUSER3")
1847 print "Testing ldb.search for (distinguishedName=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")"
1848 res = ldb.search(expression="(distinguishedName=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")")
1849 self.assertEquals(len(res), 1, "Could not find (dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")")
1850 self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
1851 self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3")
1852 self.assertEquals(str(res[0]["name"]), "ldaptestUSER3")
1854 # ensure we cannot add it again
1855 try:
1856 ldb.add({"dn": "cn=ldaptestuser3,cn=userS," + self.base_dn,
1857 "objectClass": "user",
1858 "cn": "LDAPtestUSER3"})
1859 self.fail()
1860 except LdbError, (num, _):
1861 self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
1863 # rename back
1864 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser2,cn=users," + self.base_dn)
1866 # ensure we cannot rename it twice
1867 try:
1868 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn,
1869 "cn=ldaptestuser2,cn=users," + self.base_dn)
1870 self.fail()
1871 except LdbError, (num, _):
1872 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
1874 # ensure can now use that name
1875 ldb.add({"dn": "cn=ldaptestuser3,cn=users," + self.base_dn,
1876 "objectClass": "user",
1877 "cn": "LDAPtestUSER3"})
1879 # ensure we now cannot rename
1880 try:
1881 ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=users," + self.base_dn)
1882 self.fail()
1883 except LdbError, (num, _):
1884 self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
1885 try:
1886 ldb.rename("cn=ldaptestuser3,cn=users,%s" % self.base_dn, "cn=ldaptestuser3,%s" % ldb.get_config_basedn())
1887 self.fail()
1888 except LdbError, (num, _):
1889 self.assertTrue(num in (71, 64))
1891 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser5,cn=users," + self.base_dn)
1893 ldb.delete("cn=ldaptestuser5,cn=users," + self.base_dn)
1895 delete_force(ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
1897 ldb.rename("cn=ldaptestgroup,cn=users," + self.base_dn, "cn=ldaptestgroup2,cn=users," + self.base_dn)
1899 print "Testing subtree renames"
1901 ldb.add({"dn": "cn=ldaptestcontainer," + self.base_dn,
1902 "objectClass": "container"})
1904 ldb.add({"dn": "CN=ldaptestuser4,CN=ldaptestcontainer," + self.base_dn,
1905 "objectClass": "user",
1906 "cn": "LDAPtestUSER4"})
1908 # Here we don't enforce these hard "description" constraints
1909 ldb.modify_ldif("""
1910 dn: cn=ldaptestcontainer,""" + self.base_dn + """
1911 changetype: modify
1912 replace: description
1913 description: desc1
1914 description: desc2
1915 """)
1917 ldb.modify_ldif("""
1918 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
1919 changetype: modify
1920 add: member
1921 member: cn=ldaptestuser4,cn=ldaptestcontainer,""" + self.base_dn + """
1922 member: cn=ldaptestcomputer,cn=computers,""" + self.base_dn + """
1923 member: cn=ldaptestuser2,cn=users,""" + self.base_dn + """
1924 """)
1926 print "Testing ldb.rename of cn=ldaptestcontainer," + self.base_dn + " to cn=ldaptestcontainer2," + self.base_dn
1927 ldb.rename("CN=ldaptestcontainer," + self.base_dn, "CN=ldaptestcontainer2," + self.base_dn)
1929 print "Testing ldb.search for (&(cn=ldaptestuser4)(objectClass=user))"
1930 res = ldb.search(expression="(&(cn=ldaptestuser4)(objectClass=user))")
1931 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser4)(objectClass=user))")
1933 print "Testing subtree ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in (just renamed from) cn=ldaptestcontainer," + self.base_dn
1934 try:
1935 res = ldb.search("cn=ldaptestcontainer," + self.base_dn,
1936 expression="(&(cn=ldaptestuser4)(objectClass=user))",
1937 scope=SCOPE_SUBTREE)
1938 self.fail(res)
1939 except LdbError, (num, _):
1940 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
1942 print "Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in (just renamed from) cn=ldaptestcontainer," + self.base_dn
1943 try:
1944 res = ldb.search("cn=ldaptestcontainer," + self.base_dn,
1945 expression="(&(cn=ldaptestuser4)(objectClass=user))", scope=SCOPE_ONELEVEL)
1946 self.fail()
1947 except LdbError, (num, _):
1948 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
1950 print "Testing ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in renamed container"
1951 res = ldb.search("cn=ldaptestcontainer2," + self.base_dn, expression="(&(cn=ldaptestuser4)(objectClass=user))", scope=SCOPE_SUBTREE)
1952 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser4)(objectClass=user)) under cn=ldaptestcontainer2," + self.base_dn)
1954 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn))
1955 self.assertEquals(res[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
1957 time.sleep(4)
1959 print "Testing ldb.search for (&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn + ")(objectclass=group)) to check subtree renames and linked attributes"
1960 res = ldb.search(self.base_dn, expression="(&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn + ")(objectclass=group))", scope=SCOPE_SUBTREE)
1961 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?")
1963 print "Testing ldb.rename (into itself) of cn=ldaptestcontainer2," + self.base_dn + " to cn=ldaptestcontainer,cn=ldaptestcontainer2," + self.base_dn
1964 try:
1965 ldb.rename("cn=ldaptestcontainer2," + self.base_dn, "cn=ldaptestcontainer,cn=ldaptestcontainer2," + self.base_dn)
1966 self.fail()
1967 except LdbError, (num, _):
1968 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1970 print "Testing ldb.rename (into non-existent container) of cn=ldaptestcontainer2," + self.base_dn + " to cn=ldaptestcontainer,cn=ldaptestcontainer3," + self.base_dn
1971 try:
1972 ldb.rename("cn=ldaptestcontainer2," + self.base_dn, "cn=ldaptestcontainer,cn=ldaptestcontainer3," + self.base_dn)
1973 self.fail()
1974 except LdbError, (num, _):
1975 self.assertTrue(num in (ERR_UNWILLING_TO_PERFORM, ERR_OTHER))
1977 print "Testing delete (should fail, not a leaf node) of renamed cn=ldaptestcontainer2," + self.base_dn
1978 try:
1979 ldb.delete("cn=ldaptestcontainer2," + self.base_dn)
1980 self.fail()
1981 except LdbError, (num, _):
1982 self.assertEquals(num, ERR_NOT_ALLOWED_ON_NON_LEAF)
1984 print "Testing base ldb.search for CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn
1985 res = ldb.search(expression="(objectclass=*)", base=("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn), scope=SCOPE_BASE)
1986 self.assertEquals(len(res), 1)
1987 res = ldb.search(expression="(cn=ldaptestuser40)", base=("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn), scope=SCOPE_BASE)
1988 self.assertEquals(len(res), 0)
1990 print "Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in cn=ldaptestcontainer2," + self.base_dn
1991 res = ldb.search(expression="(&(cn=ldaptestuser4)(objectClass=user))", base=("cn=ldaptestcontainer2," + self.base_dn), scope=SCOPE_ONELEVEL)
1992 self.assertEquals(len(res), 1)
1994 print "Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in cn=ldaptestcontainer2," + self.base_dn
1995 res = ldb.search(expression="(&(cn=ldaptestuser4)(objectClass=user))", base=("cn=ldaptestcontainer2," + self.base_dn), scope=SCOPE_SUBTREE)
1996 self.assertEquals(len(res), 1)
1998 print "Testing delete of subtree renamed "+("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn)
1999 ldb.delete(("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn))
2000 print "Testing delete of renamed cn=ldaptestcontainer2," + self.base_dn
2001 ldb.delete("cn=ldaptestcontainer2," + self.base_dn)
2003 ldb.add({"dn": "cn=ldaptestutf8user èùéìòà,cn=users," + self.base_dn, "objectClass": "user"})
2005 ldb.add({"dn": "cn=ldaptestutf8user2 èùéìòà,cn=users," + self.base_dn, "objectClass": "user"})
2007 print "Testing ldb.search for (&(cn=ldaptestuser)(objectClass=user))"
2008 res = ldb.search(expression="(&(cn=ldaptestuser)(objectClass=user))")
2009 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser)(objectClass=user))")
2011 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
2012 self.assertEquals(str(res[0]["cn"]), "ldaptestuser")
2013 self.assertEquals(str(res[0]["name"]), "ldaptestuser")
2014 self.assertEquals(set(res[0]["objectClass"]), set(["top", "person", "organizationalPerson", "user"]))
2015 self.assertTrue("objectGUID" in res[0])
2016 self.assertTrue("whenCreated" in res[0])
2017 self.assertEquals(str(res[0]["objectCategory"]), ("CN=Person,%s" % ldb.get_schema_basedn()))
2018 self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_NORMAL_ACCOUNT)
2019 self.assertEquals(int(res[0]["userAccountControl"][0]), UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE)
2020 self.assertEquals(res[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
2021 self.assertEquals(len(res[0]["memberOf"]), 1)
2023 print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=cn=person,%s))" % ldb.get_schema_basedn()
2024 res2 = ldb.search(expression="(&(cn=ldaptestuser)(objectCategory=cn=person,%s))" % ldb.get_schema_basedn())
2025 self.assertEquals(len(res2), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=cn=person,%s))" % ldb.get_schema_basedn())
2027 self.assertEquals(res[0].dn, res2[0].dn)
2029 print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon))"
2030 res3 = ldb.search(expression="(&(cn=ldaptestuser)(objectCategory=PerSon))")
2031 self.assertEquals(len(res3), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=PerSon)): matched %d" % len(res3))
2033 self.assertEquals(res[0].dn, res3[0].dn)
2035 if gc_ldb is not None:
2036 print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon)) in Global Catalog"
2037 res3gc = gc_ldb.search(expression="(&(cn=ldaptestuser)(objectCategory=PerSon))")
2038 self.assertEquals(len(res3gc), 1)
2040 self.assertEquals(res[0].dn, res3gc[0].dn)
2042 print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon)) in with 'phantom root' control"
2044 if gc_ldb is not None:
2045 res3control = gc_ldb.search(self.base_dn, expression="(&(cn=ldaptestuser)(objectCategory=PerSon))", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["search_options:1:2"])
2046 self.assertEquals(len(res3control), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=PerSon)) in Global Catalog")
2048 self.assertEquals(res[0].dn, res3control[0].dn)
2050 ldb.delete(res[0].dn)
2052 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectClass=user))"
2053 res = ldb.search(expression="(&(cn=ldaptestcomputer)(objectClass=user))")
2054 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser)(objectClass=user))")
2056 self.assertEquals(str(res[0].dn), ("CN=ldaptestcomputer,CN=Computers," + self.base_dn))
2057 self.assertEquals(str(res[0]["cn"]), "ldaptestcomputer")
2058 self.assertEquals(str(res[0]["name"]), "ldaptestcomputer")
2059 self.assertEquals(set(res[0]["objectClass"]), set(["top", "person", "organizationalPerson", "user", "computer"]))
2060 self.assertTrue("objectGUID" in res[0])
2061 self.assertTrue("whenCreated" in res[0])
2062 self.assertEquals(str(res[0]["objectCategory"]), ("CN=Computer,%s" % ldb.get_schema_basedn()))
2063 self.assertEquals(int(res[0]["primaryGroupID"][0]), 513)
2064 self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_NORMAL_ACCOUNT)
2065 self.assertEquals(int(res[0]["userAccountControl"][0]), UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE)
2066 self.assertEquals(res[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
2067 self.assertEquals(len(res[0]["memberOf"]), 1)
2069 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=cn=computer,%s))" % ldb.get_schema_basedn()
2070 res2 = ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=cn=computer,%s))" % ldb.get_schema_basedn())
2071 self.assertEquals(len(res2), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=cn=computer,%s))" % ldb.get_schema_basedn())
2073 self.assertEquals(res[0].dn, res2[0].dn)
2075 if gc_ldb is not None:
2076 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=cn=computer,%s)) in Global Catalog" % gc_ldb.get_schema_basedn()
2077 res2gc = gc_ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=cn=computer,%s))" % gc_ldb.get_schema_basedn())
2078 self.assertEquals(len(res2gc), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=cn=computer,%s)) In Global Catalog" % gc_ldb.get_schema_basedn())
2080 self.assertEquals(res[0].dn, res2gc[0].dn)
2082 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=compuTER))"
2083 res3 = ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=compuTER))")
2084 self.assertEquals(len(res3), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=compuTER))")
2086 self.assertEquals(res[0].dn, res3[0].dn)
2088 if gc_ldb is not None:
2089 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=compuTER)) in Global Catalog"
2090 res3gc = gc_ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=compuTER))")
2091 self.assertEquals(len(res3gc), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=compuTER)) in Global Catalog")
2093 self.assertEquals(res[0].dn, res3gc[0].dn)
2095 print "Testing ldb.search for (&(cn=ldaptestcomp*r)(objectCategory=compuTER))"
2096 res4 = ldb.search(expression="(&(cn=ldaptestcomp*r)(objectCategory=compuTER))")
2097 self.assertEquals(len(res4), 1, "Could not find (&(cn=ldaptestcomp*r)(objectCategory=compuTER))")
2099 self.assertEquals(res[0].dn, res4[0].dn)
2101 print "Testing ldb.search for (&(cn=ldaptestcomput*)(objectCategory=compuTER))"
2102 res5 = ldb.search(expression="(&(cn=ldaptestcomput*)(objectCategory=compuTER))")
2103 self.assertEquals(len(res5), 1, "Could not find (&(cn=ldaptestcomput*)(objectCategory=compuTER))")
2105 self.assertEquals(res[0].dn, res5[0].dn)
2107 print "Testing ldb.search for (&(cn=*daptestcomputer)(objectCategory=compuTER))"
2108 res6 = ldb.search(expression="(&(cn=*daptestcomputer)(objectCategory=compuTER))")
2109 self.assertEquals(len(res6), 1, "Could not find (&(cn=*daptestcomputer)(objectCategory=compuTER))")
2111 self.assertEquals(res[0].dn, res6[0].dn)
2113 ldb.delete("<GUID=" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + ">")
2115 print "Testing ldb.search for (&(cn=ldaptest2computer)(objectClass=user))"
2116 res = ldb.search(expression="(&(cn=ldaptest2computer)(objectClass=user))")
2117 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptest2computer)(objectClass=user))")
2119 self.assertEquals(str(res[0].dn), "CN=ldaptest2computer,CN=Computers," + self.base_dn)
2120 self.assertEquals(str(res[0]["cn"]), "ldaptest2computer")
2121 self.assertEquals(str(res[0]["name"]), "ldaptest2computer")
2122 self.assertEquals(list(res[0]["objectClass"]), ["top", "person", "organizationalPerson", "user", "computer"])
2123 self.assertTrue("objectGUID" in res[0])
2124 self.assertTrue("whenCreated" in res[0])
2125 self.assertEquals(res[0]["objectCategory"][0], "CN=Computer,%s" % ldb.get_schema_basedn())
2126 self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_WORKSTATION_TRUST)
2127 self.assertEquals(int(res[0]["userAccountControl"][0]), UF_WORKSTATION_TRUST_ACCOUNT)
2129 ldb.delete("<SID=" + ldb.schema_format_value("objectSID", res[0]["objectSID"][0]) + ">")
2131 attrs = ["cn", "name", "objectClass", "objectGUID", "objectSID", "whenCreated", "nTSecurityDescriptor", "memberOf", "allowedAttributes", "allowedAttributesEffective"]
2132 print "Testing ldb.search for (&(cn=ldaptestUSer2)(objectClass=user))"
2133 res_user = ldb.search(self.base_dn, expression="(&(cn=ldaptestUSer2)(objectClass=user))", scope=SCOPE_SUBTREE, attrs=attrs)
2134 self.assertEquals(len(res_user), 1, "Could not find (&(cn=ldaptestUSer2)(objectClass=user))")
2136 self.assertEquals(str(res_user[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
2137 self.assertEquals(str(res_user[0]["cn"]), "ldaptestuser2")
2138 self.assertEquals(str(res_user[0]["name"]), "ldaptestuser2")
2139 self.assertEquals(list(res_user[0]["objectClass"]), ["top", "person", "organizationalPerson", "user"])
2140 self.assertTrue("objectSid" in res_user[0])
2141 self.assertTrue("objectGUID" in res_user[0])
2142 self.assertTrue("whenCreated" in res_user[0])
2143 self.assertTrue("nTSecurityDescriptor" in res_user[0])
2144 self.assertTrue("allowedAttributes" in res_user[0])
2145 self.assertTrue("allowedAttributesEffective" in res_user[0])
2146 self.assertEquals(res_user[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
2148 ldaptestuser2_sid = res_user[0]["objectSid"][0]
2149 ldaptestuser2_guid = res_user[0]["objectGUID"][0]
2151 attrs = ["cn", "name", "objectClass", "objectGUID", "objectSID", "whenCreated", "nTSecurityDescriptor", "member", "allowedAttributes", "allowedAttributesEffective"]
2152 print "Testing ldb.search for (&(cn=ldaptestgroup2)(objectClass=group))"
2153 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs)
2154 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))")
2156 self.assertEquals(str(res[0].dn), ("CN=ldaptestgroup2,CN=Users," + self.base_dn))
2157 self.assertEquals(str(res[0]["cn"]), "ldaptestgroup2")
2158 self.assertEquals(str(res[0]["name"]), "ldaptestgroup2")
2159 self.assertEquals(list(res[0]["objectClass"]), ["top", "group"])
2160 self.assertTrue("objectGUID" in res[0])
2161 self.assertTrue("objectSid" in res[0])
2162 self.assertTrue("whenCreated" in res[0])
2163 self.assertTrue("nTSecurityDescriptor" in res[0])
2164 self.assertTrue("allowedAttributes" in res[0])
2165 self.assertTrue("allowedAttributesEffective" in res[0])
2166 memberUP = []
2167 for m in res[0]["member"]:
2168 memberUP.append(m.upper())
2169 self.assertTrue(("CN=ldaptestuser2,CN=Users," + self.base_dn).upper() in memberUP)
2171 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs, controls=["extended_dn:1:1"])
2172 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))")
2174 print res[0]["member"]
2175 memberUP = []
2176 for m in res[0]["member"]:
2177 memberUP.append(m.upper())
2178 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()
2180 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)
2182 print "Quicktest for linked attributes"
2183 ldb.modify_ldif("""
2184 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2185 changetype: modify
2186 replace: member
2187 member: CN=ldaptestuser2,CN=Users,""" + self.base_dn + """
2188 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
2189 """)
2191 ldb.modify_ldif("""
2192 dn: <GUID=""" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + """>
2193 changetype: modify
2194 replace: member
2195 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
2196 """)
2198 ldb.modify_ldif("""
2199 dn: <SID=""" + ldb.schema_format_value("objectSid", res[0]["objectSid"][0]) + """>
2200 changetype: modify
2201 delete: member
2202 """)
2204 ldb.modify_ldif("""
2205 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2206 changetype: modify
2207 add: member
2208 member: <GUID=""" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + """>
2209 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
2210 """)
2212 ldb.modify_ldif("""
2213 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2214 changetype: modify
2215 replace: member
2216 """)
2218 ldb.modify_ldif("""
2219 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2220 changetype: modify
2221 add: member
2222 member: <SID=""" + ldb.schema_format_value("objectSid", res_user[0]["objectSid"][0]) + """>
2223 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
2224 """)
2226 ldb.modify_ldif("""
2227 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2228 changetype: modify
2229 delete: member
2230 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
2231 """)
2233 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs)
2234 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))")
2236 self.assertEquals(str(res[0].dn), ("CN=ldaptestgroup2,CN=Users," + self.base_dn))
2237 self.assertEquals(res[0]["member"][0], ("CN=ldaptestuser2,CN=Users," + self.base_dn))
2238 self.assertEquals(len(res[0]["member"]), 1)
2240 ldb.delete(("CN=ldaptestuser2,CN=Users," + self.base_dn))
2242 time.sleep(4)
2244 attrs = ["cn", "name", "objectClass", "objectGUID", "whenCreated", "nTSecurityDescriptor", "member"]
2245 print "Testing ldb.search for (&(cn=ldaptestgroup2)(objectClass=group)) to check linked delete"
2246 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs)
2247 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group)) to check linked delete")
2249 self.assertEquals(str(res[0].dn), ("CN=ldaptestgroup2,CN=Users," + self.base_dn))
2250 self.assertTrue("member" not in res[0])
2252 print "Testing ldb.search for (&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))"
2253 res = ldb.search(expression="(&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
2254 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
2255 res = ldb.search(expression="(&(cn=ldaptestutf8user èùéìòà)(objectclass=user))")
2256 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
2258 self.assertEquals(str(res[0].dn), ("CN=ldaptestutf8user èùéìòà,CN=Users," + self.base_dn))
2259 self.assertEquals(str(res[0]["cn"]), "ldaptestutf8user èùéìòà")
2260 self.assertEquals(str(res[0]["name"]), "ldaptestutf8user èùéìòà")
2261 self.assertEquals(list(res[0]["objectClass"]), ["top", "person", "organizationalPerson", "user"])
2262 self.assertTrue("objectGUID" in res[0])
2263 self.assertTrue("whenCreated" in res[0])
2265 # delete "ldaptestutf8user"
2266 ldb.delete(res[0].dn)
2268 print "Testing ldb.search for (&(cn=ldaptestutf8user2*)(objectClass=user))"
2269 res = ldb.search(expression="(&(cn=ldaptestutf8user2*)(objectClass=user))")
2270 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestutf8user2*)(objectClass=user))")
2272 print "Testing ldb.search for (&(cn=ldaptestutf8user2 ÈÙÉÌÒÀ)(objectClass=user))"
2273 res = ldb.search(expression="(&(cn=ldaptestutf8user2 ÈÙÉÌÒÀ)(objectClass=user))")
2274 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestutf8user2 ÈÙÉÌÒÀ)(objectClass=user))")
2276 # delete "ldaptestutf8user2 "
2277 ldb.delete(res[0].dn)
2279 ldb.delete(("CN=ldaptestgroup2,CN=Users," + self.base_dn))
2281 print "Testing that we can't get at the configuration DN from the main search base"
2282 res = ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
2283 self.assertEquals(len(res), 0)
2285 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"
2286 res = ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["search_options:1:2"])
2287 self.assertTrue(len(res) > 0)
2289 if gc_ldb is not None:
2290 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"
2292 res = gc_ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["search_options:1:0"])
2293 self.assertTrue(len(res) > 0)
2295 print "Testing that we do find configuration elements in the global catlog"
2296 res = gc_ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
2297 self.assertTrue(len(res) > 0)
2299 print "Testing that we do find configuration elements and user elements at the same time"
2300 res = gc_ldb.search(self.base_dn, expression="(|(objectClass=crossRef)(objectClass=person))", scope=SCOPE_SUBTREE, attrs=["cn"])
2301 self.assertTrue(len(res) > 0)
2303 print "Testing that we do find configuration elements in the global catlog, with the configuration basedn"
2304 res = gc_ldb.search(self.configuration_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
2305 self.assertTrue(len(res) > 0)
2307 print "Testing that we can get at the configuration DN on the main LDAP port"
2308 res = ldb.search(self.configuration_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
2309 self.assertTrue(len(res) > 0)
2311 print "Testing objectCategory canonacolisation"
2312 res = ldb.search(self.configuration_dn, expression="objectCategory=ntDsDSA", scope=SCOPE_SUBTREE, attrs=["cn"])
2313 self.assertTrue(len(res) > 0, "Didn't find any records with objectCategory=ntDsDSA")
2314 self.assertTrue(len(res) != 0)
2316 res = ldb.search(self.configuration_dn, expression="objectCategory=CN=ntDs-DSA," + self.schema_dn, scope=SCOPE_SUBTREE, attrs=["cn"])
2317 self.assertTrue(len(res) > 0, "Didn't find any records with objectCategory=CN=ntDs-DSA," + self.schema_dn)
2318 self.assertTrue(len(res) != 0)
2320 print "Testing objectClass attribute order on "+ self.base_dn
2321 res = ldb.search(expression="objectClass=domain", base=self.base_dn,
2322 scope=SCOPE_BASE, attrs=["objectClass"])
2323 self.assertEquals(len(res), 1)
2325 self.assertEquals(list(res[0]["objectClass"]), ["top", "domain", "domainDNS"])
2327 # check enumeration
2329 print "Testing ldb.search for objectCategory=person"
2330 res = ldb.search(self.base_dn, expression="objectCategory=person", scope=SCOPE_SUBTREE, attrs=["cn"])
2331 self.assertTrue(len(res) > 0)
2333 print "Testing ldb.search for objectCategory=person with domain scope control"
2334 res = ldb.search(self.base_dn, expression="objectCategory=person", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["domain_scope:1"])
2335 self.assertTrue(len(res) > 0)
2337 print "Testing ldb.search for objectCategory=user"
2338 res = ldb.search(self.base_dn, expression="objectCategory=user", scope=SCOPE_SUBTREE, attrs=["cn"])
2339 self.assertTrue(len(res) > 0)
2341 print "Testing ldb.search for objectCategory=user with domain scope control"
2342 res = ldb.search(self.base_dn, expression="objectCategory=user", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["domain_scope:1"])
2343 self.assertTrue(len(res) > 0)
2345 print "Testing ldb.search for objectCategory=group"
2346 res = ldb.search(self.base_dn, expression="objectCategory=group", scope=SCOPE_SUBTREE, attrs=["cn"])
2347 self.assertTrue(len(res) > 0)
2349 print "Testing ldb.search for objectCategory=group with domain scope control"
2350 res = ldb.search(self.base_dn, expression="objectCategory=group", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["domain_scope:1"])
2351 self.assertTrue(len(res) > 0)
2353 print "Testing creating a user with the posixAccount objectClass"
2354 self.ldb.add_ldif("""dn: cn=posixuser,CN=Users,%s
2355 objectClass: top
2356 objectClass: person
2357 objectClass: posixAccount
2358 objectClass: user
2359 objectClass: organizationalPerson
2360 cn: posixuser
2361 uid: posixuser
2362 sn: posixuser
2363 uidNumber: 10126
2364 gidNumber: 10126
2365 homeDirectory: /home/posixuser
2366 loginShell: /bin/bash
2367 gecos: Posix User;;;
2368 description: A POSIX user"""% (self.base_dn))
2370 print "Testing removing the posixAccount objectClass from an existing user"
2371 self.ldb.modify_ldif("""dn: cn=posixuser,CN=Users,%s
2372 changetype: modify
2373 delete: objectClass
2374 objectClass: posixAccount"""% (self.base_dn))
2376 print "Testing adding the posixAccount objectClass to an existing user"
2377 self.ldb.modify_ldif("""dn: cn=posixuser,CN=Users,%s
2378 changetype: modify
2379 add: objectClass
2380 objectClass: posixAccount"""% (self.base_dn))
2382 delete_force(self.ldb, "cn=posixuser,cn=users," + self.base_dn)
2383 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
2384 delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
2385 delete_force(self.ldb, "cn=ldaptestuser3,cn=users," + self.base_dn)
2386 delete_force(self.ldb, "cn=ldaptestuser4,cn=ldaptestcontainer," + self.base_dn)
2387 delete_force(self.ldb, "cn=ldaptestuser4,cn=ldaptestcontainer2," + self.base_dn)
2388 delete_force(self.ldb, "cn=ldaptestuser5,cn=users," + self.base_dn)
2389 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
2390 delete_force(self.ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
2391 delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2392 delete_force(self.ldb, "cn=ldaptest2computer,cn=computers," + self.base_dn)
2393 delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
2394 delete_force(self.ldb, "cn=ldaptestutf8user èùéìòà,cn=users," + self.base_dn)
2395 delete_force(self.ldb, "cn=ldaptestutf8user2 èùéìòà,cn=users," + self.base_dn)
2396 delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
2397 delete_force(self.ldb, "cn=ldaptestcontainer2," + self.base_dn)
2399 def test_security_descriptor_add(self):
2400 """ Testing ldb.add_ldif() for nTSecurityDescriptor """
2401 user_name = "testdescriptoruser1"
2402 user_dn = "CN=%s,CN=Users,%s" % (user_name, self.base_dn)
2404 # Test an empty security descriptor (naturally this shouldn't work)
2406 delete_force(self.ldb, user_dn)
2407 try:
2408 self.ldb.add({ "dn": user_dn,
2409 "objectClass": "user",
2410 "sAMAccountName": user_name,
2411 "nTSecurityDescriptor": [] })
2412 self.fail()
2413 except LdbError, (num, _):
2414 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
2415 finally:
2416 delete_force(self.ldb, user_dn)
2418 # Test add_ldif() with SDDL security descriptor input
2420 try:
2421 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2422 self.ldb.add_ldif("""
2423 dn: """ + user_dn + """
2424 objectclass: user
2425 sAMAccountName: """ + user_name + """
2426 nTSecurityDescriptor: """ + sddl)
2427 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2428 desc = res[0]["nTSecurityDescriptor"][0]
2429 desc = ndr_unpack( security.descriptor, desc )
2430 desc_sddl = desc.as_sddl( self.domain_sid )
2431 self.assertEqual(desc_sddl, sddl)
2432 finally:
2433 delete_force(self.ldb, user_dn)
2435 # Test add_ldif() with BASE64 security descriptor
2437 try:
2438 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2439 desc = security.descriptor.from_sddl(sddl, self.domain_sid)
2440 desc_binary = ndr_pack(desc)
2441 desc_base64 = base64.b64encode(desc_binary)
2442 self.ldb.add_ldif("""
2443 dn: """ + user_dn + """
2444 objectclass: user
2445 sAMAccountName: """ + user_name + """
2446 nTSecurityDescriptor:: """ + desc_base64)
2447 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2448 desc = res[0]["nTSecurityDescriptor"][0]
2449 desc = ndr_unpack(security.descriptor, desc)
2450 desc_sddl = desc.as_sddl(self.domain_sid)
2451 self.assertEqual(desc_sddl, sddl)
2452 finally:
2453 delete_force(self.ldb, user_dn)
2455 def test_security_descriptor_add_neg(self):
2456 """Test add_ldif() with BASE64 security descriptor input using WRONG domain SID
2457 Negative test
2459 user_name = "testdescriptoruser1"
2460 user_dn = "CN=%s,CN=Users,%s" % (user_name, self.base_dn)
2461 delete_force(self.ldb, user_dn)
2462 try:
2463 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2464 desc = security.descriptor.from_sddl(sddl, security.dom_sid('S-1-5-21'))
2465 desc_base64 = base64.b64encode( ndr_pack(desc) )
2466 self.ldb.add_ldif("""
2467 dn: """ + user_dn + """
2468 objectclass: user
2469 sAMAccountName: """ + user_name + """
2470 nTSecurityDescriptor:: """ + desc_base64)
2471 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2472 self.assertTrue("nTSecurityDescriptor" in res[0])
2473 finally:
2474 delete_force(self.ldb, user_dn)
2476 def test_security_descriptor_modify(self):
2477 """ Testing ldb.modify_ldif() for nTSecurityDescriptor """
2478 user_name = "testdescriptoruser2"
2479 user_dn = "CN=%s,CN=Users,%s" % (user_name, self.base_dn)
2481 # Test an empty security descriptor (naturally this shouldn't work)
2483 delete_force(self.ldb, user_dn)
2484 self.ldb.add({ "dn": user_dn,
2485 "objectClass": "user",
2486 "sAMAccountName": user_name })
2488 m = Message()
2489 m.dn = Dn(ldb, user_dn)
2490 m["nTSecurityDescriptor"] = MessageElement([], FLAG_MOD_ADD,
2491 "nTSecurityDescriptor")
2492 try:
2493 self.ldb.modify(m)
2494 self.fail()
2495 except LdbError, (num, _):
2496 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
2498 m = Message()
2499 m.dn = Dn(ldb, user_dn)
2500 m["nTSecurityDescriptor"] = MessageElement([], FLAG_MOD_REPLACE,
2501 "nTSecurityDescriptor")
2502 try:
2503 self.ldb.modify(m)
2504 self.fail()
2505 except LdbError, (num, _):
2506 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
2508 m = Message()
2509 m.dn = Dn(ldb, user_dn)
2510 m["nTSecurityDescriptor"] = MessageElement([], FLAG_MOD_DELETE,
2511 "nTSecurityDescriptor")
2512 try:
2513 self.ldb.modify(m)
2514 self.fail()
2515 except LdbError, (num, _):
2516 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
2518 delete_force(self.ldb, user_dn)
2520 # Test modify_ldif() with SDDL security descriptor input
2521 # Add ACE to the original descriptor test
2523 try:
2524 self.ldb.add_ldif("""
2525 dn: """ + user_dn + """
2526 objectclass: user
2527 sAMAccountName: """ + user_name)
2528 # Modify descriptor
2529 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2530 desc = res[0]["nTSecurityDescriptor"][0]
2531 desc = ndr_unpack(security.descriptor, desc)
2532 desc_sddl = desc.as_sddl(self.domain_sid)
2533 sddl = desc_sddl[:desc_sddl.find("(")] + "(A;;RPWP;;;AU)" + desc_sddl[desc_sddl.find("("):]
2534 mod = """
2535 dn: """ + user_dn + """
2536 changetype: modify
2537 replace: nTSecurityDescriptor
2538 nTSecurityDescriptor: """ + sddl
2539 self.ldb.modify_ldif(mod)
2540 # Read modified descriptor
2541 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2542 desc = res[0]["nTSecurityDescriptor"][0]
2543 desc = ndr_unpack(security.descriptor, desc)
2544 desc_sddl = desc.as_sddl(self.domain_sid)
2545 self.assertEqual(desc_sddl, sddl)
2546 finally:
2547 delete_force(self.ldb, user_dn)
2549 # Test modify_ldif() with SDDL security descriptor input
2550 # New desctiptor test
2552 try:
2553 self.ldb.add_ldif("""
2554 dn: """ + user_dn + """
2555 objectclass: user
2556 sAMAccountName: """ + user_name)
2557 # Modify descriptor
2558 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2559 mod = """
2560 dn: """ + user_dn + """
2561 changetype: modify
2562 replace: nTSecurityDescriptor
2563 nTSecurityDescriptor: """ + sddl
2564 self.ldb.modify_ldif(mod)
2565 # Read modified descriptor
2566 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2567 desc = res[0]["nTSecurityDescriptor"][0]
2568 desc = ndr_unpack(security.descriptor, desc)
2569 desc_sddl = desc.as_sddl(self.domain_sid)
2570 self.assertEqual(desc_sddl, sddl)
2571 finally:
2572 delete_force(self.ldb, user_dn)
2574 # Test modify_ldif() with BASE64 security descriptor input
2575 # Add ACE to the original descriptor test
2577 try:
2578 self.ldb.add_ldif("""
2579 dn: """ + user_dn + """
2580 objectclass: user
2581 sAMAccountName: """ + user_name)
2582 # Modify descriptor
2583 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2584 desc = res[0]["nTSecurityDescriptor"][0]
2585 desc = ndr_unpack(security.descriptor, desc)
2586 desc_sddl = desc.as_sddl(self.domain_sid)
2587 sddl = desc_sddl[:desc_sddl.find("(")] + "(A;;RPWP;;;AU)" + desc_sddl[desc_sddl.find("("):]
2588 desc = security.descriptor.from_sddl(sddl, self.domain_sid)
2589 desc_base64 = base64.b64encode(ndr_pack(desc))
2590 mod = """
2591 dn: """ + user_dn + """
2592 changetype: modify
2593 replace: nTSecurityDescriptor
2594 nTSecurityDescriptor:: """ + desc_base64
2595 self.ldb.modify_ldif(mod)
2596 # Read modified descriptor
2597 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2598 desc = res[0]["nTSecurityDescriptor"][0]
2599 desc = ndr_unpack(security.descriptor, desc)
2600 desc_sddl = desc.as_sddl(self.domain_sid)
2601 self.assertEqual(desc_sddl, sddl)
2602 finally:
2603 delete_force(self.ldb, user_dn)
2605 # Test modify_ldif() with BASE64 security descriptor input
2606 # New descriptor test
2608 try:
2609 delete_force(self.ldb, user_dn)
2610 self.ldb.add_ldif("""
2611 dn: """ + user_dn + """
2612 objectclass: user
2613 sAMAccountName: """ + user_name)
2614 # Modify descriptor
2615 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2616 desc = security.descriptor.from_sddl(sddl, self.domain_sid)
2617 desc_base64 = base64.b64encode(ndr_pack(desc))
2618 mod = """
2619 dn: """ + user_dn + """
2620 changetype: modify
2621 replace: nTSecurityDescriptor
2622 nTSecurityDescriptor:: """ + desc_base64
2623 self.ldb.modify_ldif(mod)
2624 # Read modified descriptor
2625 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2626 desc = res[0]["nTSecurityDescriptor"][0]
2627 desc = ndr_unpack(security.descriptor, desc)
2628 desc_sddl = desc.as_sddl(self.domain_sid)
2629 self.assertEqual(desc_sddl, sddl)
2630 finally:
2631 delete_force(self.ldb, user_dn)
2633 def test_dsheuristics(self):
2634 """Tests the 'dSHeuristics' attribute"""
2635 print "Tests the 'dSHeuristics' attribute"""
2637 # Get the current value to restore it later
2638 dsheuristics = self.ldb.get_dsheuristics()
2639 # Should not be longer than 18 chars?
2640 try:
2641 self.ldb.set_dsheuristics("123ABC-+!1asdfg@#^12")
2642 except LdbError, (num, _):
2643 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
2644 # If it is >= 10 chars, tenthChar should be 1
2645 try:
2646 self.ldb.set_dsheuristics("00020000000002")
2647 except LdbError, (num, _):
2648 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
2649 # apart from the above, all char values are accepted
2650 self.ldb.set_dsheuristics("123ABC-+!1asdfg@#^")
2651 self.assertEquals(self.ldb.get_dsheuristics(), "123ABC-+!1asdfg@#^")
2652 # restore old value
2653 self.ldb.set_dsheuristics(dsheuristics)
2655 def test_ldapControlReturn(self):
2656 """Testing that if we request a control that return a control it
2657 really return something"""
2658 res = self.ldb.search(attrs=["cn"],
2659 controls=["paged_results:1:10"])
2660 self.assertEquals(len(res.controls), 1)
2661 self.assertEquals(res.controls[0].oid, "1.2.840.113556.1.4.319")
2662 s = str(res.controls[0])
2664 def test_operational(self):
2665 """Tests operational attributes"""
2666 print "Tests operational attributes"""
2668 res = self.ldb.search(self.base_dn, scope=SCOPE_BASE,
2669 attrs=["createTimeStamp", "modifyTimeStamp",
2670 "structuralObjectClass", "whenCreated",
2671 "whenChanged"])
2672 self.assertEquals(len(res), 1)
2673 self.assertTrue("createTimeStamp" in res[0])
2674 self.assertTrue("modifyTimeStamp" in res[0])
2675 self.assertTrue("structuralObjectClass" in res[0])
2676 self.assertTrue("whenCreated" in res[0])
2677 self.assertTrue("whenChanged" in res[0])
2679 class BaseDnTests(unittest.TestCase):
2681 def setUp(self):
2682 super(BaseDnTests, self).setUp()
2683 self.ldb = ldb
2685 def test_rootdse_attrs(self):
2686 """Testing for all rootDSE attributes"""
2687 res = self.ldb.search("", scope=SCOPE_BASE, attrs=[])
2688 self.assertEquals(len(res), 1)
2690 def test_highestcommittedusn(self):
2691 """Testing for highestCommittedUSN"""
2692 res = self.ldb.search("", scope=SCOPE_BASE, attrs=["highestCommittedUSN"])
2693 self.assertEquals(len(res), 1)
2694 self.assertTrue(int(res[0]["highestCommittedUSN"][0]) != 0)
2696 def test_netlogon(self):
2697 """Testing for netlogon via LDAP"""
2698 res = self.ldb.search("", scope=SCOPE_BASE, attrs=["netlogon"])
2699 self.assertEquals(len(res), 0)
2701 def test_netlogon_highestcommitted_usn(self):
2702 """Testing for netlogon and highestCommittedUSN via LDAP"""
2703 res = self.ldb.search("", scope=SCOPE_BASE,
2704 attrs=["netlogon", "highestCommittedUSN"])
2705 self.assertEquals(len(res), 0)
2707 def test_namingContexts(self):
2708 """Testing for namingContexts in rootDSE"""
2709 res = self.ldb.search("", scope=SCOPE_BASE,
2710 attrs=["namingContexts", "defaultNamingContext", "schemaNamingContext", "configurationNamingContext"])
2711 self.assertEquals(len(res), 1)
2713 ncs = set([])
2714 for nc in res[0]["namingContexts"]:
2715 self.assertTrue(nc not in ncs)
2716 ncs.add(nc)
2718 self.assertTrue(res[0]["defaultNamingContext"][0] in ncs)
2719 self.assertTrue(res[0]["configurationNamingContext"][0] in ncs)
2720 self.assertTrue(res[0]["schemaNamingContext"][0] in ncs)
2722 def test_serverPath(self):
2723 """Testing the server paths in rootDSE"""
2724 res = self.ldb.search("", scope=SCOPE_BASE,
2725 attrs=["dsServiceName", "serverName"])
2726 self.assertEquals(len(res), 1)
2728 self.assertTrue("CN=Servers" in res[0]["dsServiceName"][0])
2729 self.assertTrue("CN=Sites" in res[0]["dsServiceName"][0])
2730 self.assertTrue("CN=NTDS Settings" in res[0]["dsServiceName"][0])
2731 self.assertTrue("CN=Servers" in res[0]["serverName"][0])
2732 self.assertTrue("CN=Sites" in res[0]["serverName"][0])
2733 self.assertFalse("CN=NTDS Settings" in res[0]["serverName"][0])
2735 def test_functionality(self):
2736 """Testing the server paths in rootDSE"""
2737 res = self.ldb.search("", scope=SCOPE_BASE,
2738 attrs=["forestFunctionality", "domainFunctionality", "domainControllerFunctionality"])
2739 self.assertEquals(len(res), 1)
2740 self.assertEquals(len(res[0]["forestFunctionality"]), 1)
2741 self.assertEquals(len(res[0]["domainFunctionality"]), 1)
2742 self.assertEquals(len(res[0]["domainControllerFunctionality"]), 1)
2744 self.assertTrue(int(res[0]["forestFunctionality"][0]) <= int(res[0]["domainFunctionality"][0]))
2745 self.assertTrue(int(res[0]["domainControllerFunctionality"][0]) >= int(res[0]["domainFunctionality"][0]))
2747 res2 = self.ldb.search("", scope=SCOPE_BASE,
2748 attrs=["dsServiceName", "serverName"])
2749 self.assertEquals(len(res2), 1)
2750 self.assertEquals(len(res2[0]["dsServiceName"]), 1)
2752 res3 = self.ldb.search(res2[0]["dsServiceName"][0], scope=SCOPE_BASE, attrs=["msDS-Behavior-Version"])
2753 self.assertEquals(len(res3), 1)
2754 self.assertEquals(len(res3[0]["msDS-Behavior-Version"]), 1)
2755 self.assertEquals(int(res[0]["domainControllerFunctionality"][0]), int(res3[0]["msDS-Behavior-Version"][0]))
2757 res4 = self.ldb.search(ldb.domain_dn(), scope=SCOPE_BASE, attrs=["msDS-Behavior-Version"])
2758 self.assertEquals(len(res4), 1)
2759 self.assertEquals(len(res4[0]["msDS-Behavior-Version"]), 1)
2760 self.assertEquals(int(res[0]["domainFunctionality"][0]), int(res4[0]["msDS-Behavior-Version"][0]))
2762 res5 = self.ldb.search("cn=partitions,%s" % ldb.get_config_basedn(), scope=SCOPE_BASE, attrs=["msDS-Behavior-Version"])
2763 self.assertEquals(len(res5), 1)
2764 self.assertEquals(len(res5[0]["msDS-Behavior-Version"]), 1)
2765 self.assertEquals(int(res[0]["forestFunctionality"][0]), int(res5[0]["msDS-Behavior-Version"][0]))
2767 def test_dnsHostname(self):
2768 """Testing the DNS hostname in rootDSE"""
2769 res = self.ldb.search("", scope=SCOPE_BASE,
2770 attrs=["dnsHostName", "serverName"])
2771 self.assertEquals(len(res), 1)
2773 res2 = self.ldb.search(res[0]["serverName"][0], scope=SCOPE_BASE,
2774 attrs=["dNSHostName"])
2775 self.assertEquals(len(res2), 1)
2777 self.assertEquals(res[0]["dnsHostName"][0], res2[0]["dNSHostName"][0])
2779 def test_ldapServiceName(self):
2780 """Testing the ldap service name in rootDSE"""
2781 res = self.ldb.search("", scope=SCOPE_BASE,
2782 attrs=["ldapServiceName", "dNSHostName"])
2783 self.assertEquals(len(res), 1)
2785 (hostname, _, dns_domainname) = res[0]["dNSHostName"][0].partition(".")
2786 self.assertTrue(":%s$@%s" % (hostname, dns_domainname.upper())
2787 in res[0]["ldapServiceName"][0])
2789 if not "://" in host:
2790 if os.path.isfile(host):
2791 host = "tdb://%s" % host
2792 else:
2793 host = "ldap://%s" % host
2795 ldb = SamDB(host, credentials=creds, session_info=system_session(lp), lp=lp)
2796 if not "tdb://" in host:
2797 gc_ldb = Ldb("%s:3268" % host, credentials=creds,
2798 session_info=system_session(lp), lp=lp)
2799 else:
2800 gc_ldb = None
2802 runner = SubunitTestRunner()
2803 rc = 0
2804 if not runner.run(unittest.makeSuite(BaseDnTests)).wasSuccessful():
2805 rc = 1
2806 if not runner.run(unittest.makeSuite(BasicTests)).wasSuccessful():
2807 rc = 1
2808 sys.exit(rc)