pyldb: add more tests for control manipulation
[Samba/gebeck_regimport.git] / source4 / dsdb / tests / python / ldap.py
bloba49dbf0023f11bd4f7960a43a2c5af5d8b297d35
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,CN=Schema,CN=Configuration," + self.base_dn));
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," + self.base_dn, "cn=ldaptestuser3,cn=configuration," + self.base_dn)
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 # FIXME: self.assertEquals(len(res), 0)
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 # FIXME: self.assertEquals(len(res), 0)
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,CN=Schema,CN=Configuration," + self.base_dn))
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,cn=schema,cn=configuration," + self.base_dn + "))"
2024 res2 = ldb.search(expression="(&(cn=ldaptestuser)(objectCategory=cn=person,cn=schema,cn=configuration," + self.base_dn + "))")
2025 self.assertEquals(len(res2), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=cn=person,cn=schema,cn=configuration," + self.base_dn + "))")
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,CN=Schema,CN=Configuration," + self.base_dn))
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,cn=schema,cn=configuration," + self.base_dn + "))"
2070 res2 = ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + "))")
2071 self.assertEquals(len(res2), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + "))")
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,cn=schema,cn=configuration," + self.base_dn + ")) in Global Catlog"
2077 res2gc = gc_ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + "))")
2078 self.assertEquals(len(res2gc), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + ")) in Global Catlog")
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,CN=Schema,CN=Configuration," + self.base_dn)
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 # TODO UTF8 users don't seem to work fully anymore
2254 # res = ldb.search(expression="(&(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 ldb.delete(res[0].dn)
2267 print "Testing ldb.search for (&(cn=ldaptestutf8user2*)(objectClass=user))"
2268 res = ldb.search(expression="(&(cn=ldaptestutf8user2*)(objectClass=user))")
2269 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestutf8user2*)(objectClass=user))")
2271 ldb.delete(res[0].dn)
2273 ldb.delete(("CN=ldaptestgroup2,CN=Users," + self.base_dn))
2275 print "Testing ldb.search for (&(cn=ldaptestutf8user2 ÈÙÉÌÒÀ)(objectClass=user))"
2276 # TODO UTF8 users don't seem to work fully anymore
2277 # res = ldb.search(expression="(&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
2278 # self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
2280 print "Testing that we can't get at the configuration DN from the main search base"
2281 res = ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
2282 self.assertEquals(len(res), 0)
2284 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"
2285 res = ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["search_options:1:2"])
2286 self.assertTrue(len(res) > 0)
2288 if gc_ldb is not None:
2289 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"
2291 res = gc_ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["search_options:1:0"])
2292 self.assertTrue(len(res) > 0)
2294 print "Testing that we do find configuration elements in the global catlog"
2295 res = gc_ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
2296 self.assertTrue(len(res) > 0)
2298 print "Testing that we do find configuration elements and user elements at the same time"
2299 res = gc_ldb.search(self.base_dn, expression="(|(objectClass=crossRef)(objectClass=person))", scope=SCOPE_SUBTREE, attrs=["cn"])
2300 self.assertTrue(len(res) > 0)
2302 print "Testing that we do find configuration elements in the global catlog, with the configuration basedn"
2303 res = gc_ldb.search(self.configuration_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
2304 self.assertTrue(len(res) > 0)
2306 print "Testing that we can get at the configuration DN on the main LDAP port"
2307 res = ldb.search(self.configuration_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
2308 self.assertTrue(len(res) > 0)
2310 print "Testing objectCategory canonacolisation"
2311 res = ldb.search(self.configuration_dn, expression="objectCategory=ntDsDSA", scope=SCOPE_SUBTREE, attrs=["cn"])
2312 self.assertTrue(len(res) > 0, "Didn't find any records with objectCategory=ntDsDSA")
2313 self.assertTrue(len(res) != 0)
2315 res = ldb.search(self.configuration_dn, expression="objectCategory=CN=ntDs-DSA," + self.schema_dn, scope=SCOPE_SUBTREE, attrs=["cn"])
2316 self.assertTrue(len(res) > 0, "Didn't find any records with objectCategory=CN=ntDs-DSA," + self.schema_dn)
2317 self.assertTrue(len(res) != 0)
2319 print "Testing objectClass attribute order on "+ self.base_dn
2320 res = ldb.search(expression="objectClass=domain", base=self.base_dn,
2321 scope=SCOPE_BASE, attrs=["objectClass"])
2322 self.assertEquals(len(res), 1)
2324 self.assertEquals(list(res[0]["objectClass"]), ["top", "domain", "domainDNS"])
2326 # check enumeration
2328 print "Testing ldb.search for objectCategory=person"
2329 res = ldb.search(self.base_dn, expression="objectCategory=person", scope=SCOPE_SUBTREE, attrs=["cn"])
2330 self.assertTrue(len(res) > 0)
2332 print "Testing ldb.search for objectCategory=person with domain scope control"
2333 res = ldb.search(self.base_dn, expression="objectCategory=person", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["domain_scope:1"])
2334 self.assertTrue(len(res) > 0)
2336 print "Testing ldb.search for objectCategory=user"
2337 res = ldb.search(self.base_dn, expression="objectCategory=user", scope=SCOPE_SUBTREE, attrs=["cn"])
2338 self.assertTrue(len(res) > 0)
2340 print "Testing ldb.search for objectCategory=user with domain scope control"
2341 res = ldb.search(self.base_dn, expression="objectCategory=user", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["domain_scope:1"])
2342 self.assertTrue(len(res) > 0)
2344 print "Testing ldb.search for objectCategory=group"
2345 res = ldb.search(self.base_dn, expression="objectCategory=group", scope=SCOPE_SUBTREE, attrs=["cn"])
2346 self.assertTrue(len(res) > 0)
2348 print "Testing ldb.search for objectCategory=group with domain scope control"
2349 res = ldb.search(self.base_dn, expression="objectCategory=group", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["domain_scope:1"])
2350 self.assertTrue(len(res) > 0)
2352 print "Testing creating a user with the posixAccount objectClass"
2353 self.ldb.add_ldif("""dn: cn=posixuser,CN=Users,%s
2354 objectClass: top
2355 objectClass: person
2356 objectClass: posixAccount
2357 objectClass: user
2358 objectClass: organizationalPerson
2359 cn: posixuser
2360 uid: posixuser
2361 sn: posixuser
2362 uidNumber: 10126
2363 gidNumber: 10126
2364 homeDirectory: /home/posixuser
2365 loginShell: /bin/bash
2366 gecos: Posix User;;;
2367 description: A POSIX user"""% (self.base_dn))
2369 print "Testing removing the posixAccount objectClass from an existing user"
2370 self.ldb.modify_ldif("""dn: cn=posixuser,CN=Users,%s
2371 changetype: modify
2372 delete: objectClass
2373 objectClass: posixAccount"""% (self.base_dn))
2375 print "Testing adding the posixAccount objectClass to an existing user"
2376 self.ldb.modify_ldif("""dn: cn=posixuser,CN=Users,%s
2377 changetype: modify
2378 add: objectClass
2379 objectClass: posixAccount"""% (self.base_dn))
2381 delete_force(self.ldb, "cn=posixuser,cn=users," + self.base_dn)
2382 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
2383 delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
2384 delete_force(self.ldb, "cn=ldaptestuser3,cn=users," + self.base_dn)
2385 delete_force(self.ldb, "cn=ldaptestuser4,cn=ldaptestcontainer," + self.base_dn)
2386 delete_force(self.ldb, "cn=ldaptestuser4,cn=ldaptestcontainer2," + self.base_dn)
2387 delete_force(self.ldb, "cn=ldaptestuser5,cn=users," + self.base_dn)
2388 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
2389 delete_force(self.ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
2390 delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2391 delete_force(self.ldb, "cn=ldaptest2computer,cn=computers," + self.base_dn)
2392 delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
2393 delete_force(self.ldb, "cn=ldaptestutf8user èùéìòà,cn=users," + self.base_dn)
2394 delete_force(self.ldb, "cn=ldaptestutf8user2 èùéìòà,cn=users," + self.base_dn)
2395 delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
2396 delete_force(self.ldb, "cn=ldaptestcontainer2," + self.base_dn)
2398 def test_security_descriptor_add(self):
2399 """ Testing ldb.add_ldif() for nTSecurityDescriptor """
2400 user_name = "testdescriptoruser1"
2401 user_dn = "CN=%s,CN=Users,%s" % (user_name, self.base_dn)
2403 # Test an empty security descriptor (naturally this shouldn't work)
2405 delete_force(self.ldb, user_dn)
2406 try:
2407 self.ldb.add({ "dn": user_dn,
2408 "objectClass": "user",
2409 "sAMAccountName": user_name,
2410 "nTSecurityDescriptor": [] })
2411 self.fail()
2412 except LdbError, (num, _):
2413 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
2414 finally:
2415 delete_force(self.ldb, user_dn)
2417 # Test add_ldif() with SDDL security descriptor input
2419 try:
2420 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2421 self.ldb.add_ldif("""
2422 dn: """ + user_dn + """
2423 objectclass: user
2424 sAMAccountName: """ + user_name + """
2425 nTSecurityDescriptor: """ + sddl)
2426 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2427 desc = res[0]["nTSecurityDescriptor"][0]
2428 desc = ndr_unpack( security.descriptor, desc )
2429 desc_sddl = desc.as_sddl( self.domain_sid )
2430 self.assertEqual(desc_sddl, sddl)
2431 finally:
2432 delete_force(self.ldb, user_dn)
2434 # Test add_ldif() with BASE64 security descriptor
2436 try:
2437 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2438 desc = security.descriptor.from_sddl(sddl, self.domain_sid)
2439 desc_binary = ndr_pack(desc)
2440 desc_base64 = base64.b64encode(desc_binary)
2441 self.ldb.add_ldif("""
2442 dn: """ + user_dn + """
2443 objectclass: user
2444 sAMAccountName: """ + user_name + """
2445 nTSecurityDescriptor:: """ + desc_base64)
2446 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2447 desc = res[0]["nTSecurityDescriptor"][0]
2448 desc = ndr_unpack(security.descriptor, desc)
2449 desc_sddl = desc.as_sddl(self.domain_sid)
2450 self.assertEqual(desc_sddl, sddl)
2451 finally:
2452 delete_force(self.ldb, user_dn)
2454 def test_security_descriptor_add_neg(self):
2455 """Test add_ldif() with BASE64 security descriptor input using WRONG domain SID
2456 Negative test
2458 user_name = "testdescriptoruser1"
2459 user_dn = "CN=%s,CN=Users,%s" % (user_name, self.base_dn)
2460 delete_force(self.ldb, user_dn)
2461 try:
2462 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2463 desc = security.descriptor.from_sddl(sddl, security.dom_sid('S-1-5-21'))
2464 desc_base64 = base64.b64encode( ndr_pack(desc) )
2465 self.ldb.add_ldif("""
2466 dn: """ + user_dn + """
2467 objectclass: user
2468 sAMAccountName: """ + user_name + """
2469 nTSecurityDescriptor:: """ + desc_base64)
2470 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2471 self.assertTrue("nTSecurityDescriptor" in res[0])
2472 finally:
2473 delete_force(self.ldb, user_dn)
2475 def test_security_descriptor_modify(self):
2476 """ Testing ldb.modify_ldif() for nTSecurityDescriptor """
2477 user_name = "testdescriptoruser2"
2478 user_dn = "CN=%s,CN=Users,%s" % (user_name, self.base_dn)
2480 # Test an empty security descriptor (naturally this shouldn't work)
2482 delete_force(self.ldb, user_dn)
2483 self.ldb.add({ "dn": user_dn,
2484 "objectClass": "user",
2485 "sAMAccountName": user_name })
2487 m = Message()
2488 m.dn = Dn(ldb, user_dn)
2489 m["nTSecurityDescriptor"] = MessageElement([], FLAG_MOD_ADD,
2490 "nTSecurityDescriptor")
2491 try:
2492 self.ldb.modify(m)
2493 self.fail()
2494 except LdbError, (num, _):
2495 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
2497 m = Message()
2498 m.dn = Dn(ldb, user_dn)
2499 m["nTSecurityDescriptor"] = MessageElement([], FLAG_MOD_REPLACE,
2500 "nTSecurityDescriptor")
2501 try:
2502 self.ldb.modify(m)
2503 self.fail()
2504 except LdbError, (num, _):
2505 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
2507 m = Message()
2508 m.dn = Dn(ldb, user_dn)
2509 m["nTSecurityDescriptor"] = MessageElement([], FLAG_MOD_DELETE,
2510 "nTSecurityDescriptor")
2511 try:
2512 self.ldb.modify(m)
2513 self.fail()
2514 except LdbError, (num, _):
2515 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
2517 delete_force(self.ldb, user_dn)
2519 # Test modify_ldif() with SDDL security descriptor input
2520 # Add ACE to the original descriptor test
2522 try:
2523 self.ldb.add_ldif("""
2524 dn: """ + user_dn + """
2525 objectclass: user
2526 sAMAccountName: """ + user_name)
2527 # Modify descriptor
2528 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2529 desc = res[0]["nTSecurityDescriptor"][0]
2530 desc = ndr_unpack(security.descriptor, desc)
2531 desc_sddl = desc.as_sddl(self.domain_sid)
2532 sddl = desc_sddl[:desc_sddl.find("(")] + "(A;;RPWP;;;AU)" + desc_sddl[desc_sddl.find("("):]
2533 mod = """
2534 dn: """ + user_dn + """
2535 changetype: modify
2536 replace: nTSecurityDescriptor
2537 nTSecurityDescriptor: """ + sddl
2538 self.ldb.modify_ldif(mod)
2539 # Read modified descriptor
2540 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2541 desc = res[0]["nTSecurityDescriptor"][0]
2542 desc = ndr_unpack(security.descriptor, desc)
2543 desc_sddl = desc.as_sddl(self.domain_sid)
2544 self.assertEqual(desc_sddl, sddl)
2545 finally:
2546 delete_force(self.ldb, user_dn)
2548 # Test modify_ldif() with SDDL security descriptor input
2549 # New desctiptor test
2551 try:
2552 self.ldb.add_ldif("""
2553 dn: """ + user_dn + """
2554 objectclass: user
2555 sAMAccountName: """ + user_name)
2556 # Modify descriptor
2557 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2558 mod = """
2559 dn: """ + user_dn + """
2560 changetype: modify
2561 replace: nTSecurityDescriptor
2562 nTSecurityDescriptor: """ + sddl
2563 self.ldb.modify_ldif(mod)
2564 # Read modified descriptor
2565 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2566 desc = res[0]["nTSecurityDescriptor"][0]
2567 desc = ndr_unpack(security.descriptor, desc)
2568 desc_sddl = desc.as_sddl(self.domain_sid)
2569 self.assertEqual(desc_sddl, sddl)
2570 finally:
2571 delete_force(self.ldb, user_dn)
2573 # Test modify_ldif() with BASE64 security descriptor input
2574 # Add ACE to the original descriptor test
2576 try:
2577 self.ldb.add_ldif("""
2578 dn: """ + user_dn + """
2579 objectclass: user
2580 sAMAccountName: """ + user_name)
2581 # Modify descriptor
2582 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2583 desc = res[0]["nTSecurityDescriptor"][0]
2584 desc = ndr_unpack(security.descriptor, desc)
2585 desc_sddl = desc.as_sddl(self.domain_sid)
2586 sddl = desc_sddl[:desc_sddl.find("(")] + "(A;;RPWP;;;AU)" + desc_sddl[desc_sddl.find("("):]
2587 desc = security.descriptor.from_sddl(sddl, self.domain_sid)
2588 desc_base64 = base64.b64encode(ndr_pack(desc))
2589 mod = """
2590 dn: """ + user_dn + """
2591 changetype: modify
2592 replace: nTSecurityDescriptor
2593 nTSecurityDescriptor:: """ + desc_base64
2594 self.ldb.modify_ldif(mod)
2595 # Read modified descriptor
2596 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2597 desc = res[0]["nTSecurityDescriptor"][0]
2598 desc = ndr_unpack(security.descriptor, desc)
2599 desc_sddl = desc.as_sddl(self.domain_sid)
2600 self.assertEqual(desc_sddl, sddl)
2601 finally:
2602 delete_force(self.ldb, user_dn)
2604 # Test modify_ldif() with BASE64 security descriptor input
2605 # New descriptor test
2607 try:
2608 delete_force(self.ldb, user_dn)
2609 self.ldb.add_ldif("""
2610 dn: """ + user_dn + """
2611 objectclass: user
2612 sAMAccountName: """ + user_name)
2613 # Modify descriptor
2614 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2615 desc = security.descriptor.from_sddl(sddl, self.domain_sid)
2616 desc_base64 = base64.b64encode(ndr_pack(desc))
2617 mod = """
2618 dn: """ + user_dn + """
2619 changetype: modify
2620 replace: nTSecurityDescriptor
2621 nTSecurityDescriptor:: """ + desc_base64
2622 self.ldb.modify_ldif(mod)
2623 # Read modified descriptor
2624 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2625 desc = res[0]["nTSecurityDescriptor"][0]
2626 desc = ndr_unpack(security.descriptor, desc)
2627 desc_sddl = desc.as_sddl(self.domain_sid)
2628 self.assertEqual(desc_sddl, sddl)
2629 finally:
2630 delete_force(self.ldb, user_dn)
2632 def test_dsheuristics(self):
2633 """Tests the 'dSHeuristics' attribute"""
2634 print "Tests the 'dSHeuristics' attribute"""
2636 # Get the current value to restore it later
2637 dsheuristics = self.ldb.get_dsheuristics()
2638 # Should not be longer than 18 chars?
2639 try:
2640 self.ldb.set_dsheuristics("123ABC-+!1asdfg@#^12")
2641 except LdbError, (num, _):
2642 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
2643 # If it is >= 10 chars, tenthChar should be 1
2644 try:
2645 self.ldb.set_dsheuristics("00020000000002")
2646 except LdbError, (num, _):
2647 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
2648 # apart from the above, all char values are accepted
2649 self.ldb.set_dsheuristics("123ABC-+!1asdfg@#^")
2650 self.assertEquals(self.ldb.get_dsheuristics(), "123ABC-+!1asdfg@#^")
2651 # restore old value
2652 self.ldb.set_dsheuristics(dsheuristics)
2654 def test_ldapControlReturn(self):
2655 """Testing that if we request a control that return a control it
2656 really return something"""
2657 res = self.ldb.search(attrs=["cn"],
2658 controls=["paged_result:1:10"])
2659 self.assertEquals(len(res.controls), 1)
2660 self.assertEquals(res.controls[0].oid, "1.2.840.113556.1.4.319")
2661 try:
2662 s = str(res.controls[0])
2663 except:
2664 self.assertFalse(True)
2666 def test_operational(self):
2667 """Tests operational attributes"""
2668 print "Tests operational attributes"""
2670 res = self.ldb.search(self.base_dn, scope=SCOPE_BASE,
2671 attrs=["createTimeStamp", "modifyTimeStamp",
2672 "structuralObjectClass", "whenCreated",
2673 "whenChanged"])
2674 self.assertEquals(len(res), 1)
2675 self.assertTrue("createTimeStamp" in res[0])
2676 self.assertTrue("modifyTimeStamp" in res[0])
2677 self.assertTrue("structuralObjectClass" in res[0])
2678 self.assertTrue("whenCreated" in res[0])
2679 self.assertTrue("whenChanged" in res[0])
2681 class BaseDnTests(unittest.TestCase):
2683 def setUp(self):
2684 super(BaseDnTests, self).setUp()
2685 self.ldb = ldb
2687 def test_rootdse_attrs(self):
2688 """Testing for all rootDSE attributes"""
2689 res = self.ldb.search("", scope=SCOPE_BASE, attrs=[])
2690 self.assertEquals(len(res), 1)
2692 def test_highestcommittedusn(self):
2693 """Testing for highestCommittedUSN"""
2694 res = self.ldb.search("", scope=SCOPE_BASE, attrs=["highestCommittedUSN"])
2695 self.assertEquals(len(res), 1)
2696 self.assertTrue(int(res[0]["highestCommittedUSN"][0]) != 0)
2698 def test_netlogon(self):
2699 """Testing for netlogon via LDAP"""
2700 res = self.ldb.search("", scope=SCOPE_BASE, attrs=["netlogon"])
2701 self.assertEquals(len(res), 0)
2703 def test_netlogon_highestcommitted_usn(self):
2704 """Testing for netlogon and highestCommittedUSN via LDAP"""
2705 res = self.ldb.search("", scope=SCOPE_BASE,
2706 attrs=["netlogon", "highestCommittedUSN"])
2707 self.assertEquals(len(res), 0)
2709 def test_namingContexts(self):
2710 """Testing for namingContexts in rootDSE"""
2711 res = self.ldb.search("", scope=SCOPE_BASE,
2712 attrs=["namingContexts", "defaultNamingContext", "schemaNamingContext", "configurationNamingContext"])
2713 self.assertEquals(len(res), 1)
2715 ncs = set([])
2716 for nc in res[0]["namingContexts"]:
2717 self.assertTrue(nc not in ncs)
2718 ncs.add(nc)
2720 self.assertTrue(res[0]["defaultNamingContext"][0] in ncs)
2721 self.assertTrue(res[0]["configurationNamingContext"][0] in ncs)
2722 self.assertTrue(res[0]["schemaNamingContext"][0] in ncs)
2724 def test_serverPath(self):
2725 """Testing the server paths in rootDSE"""
2726 res = self.ldb.search("", scope=SCOPE_BASE,
2727 attrs=["dsServiceName", "serverName"])
2728 self.assertEquals(len(res), 1)
2730 self.assertTrue("CN=Servers" in res[0]["dsServiceName"][0])
2731 self.assertTrue("CN=Sites" in res[0]["dsServiceName"][0])
2732 self.assertTrue("CN=NTDS Settings" in res[0]["dsServiceName"][0])
2733 self.assertTrue("CN=Servers" in res[0]["serverName"][0])
2734 self.assertTrue("CN=Sites" in res[0]["serverName"][0])
2735 self.assertFalse("CN=NTDS Settings" in res[0]["serverName"][0])
2737 def test_functionality(self):
2738 """Testing the server paths in rootDSE"""
2739 res = self.ldb.search("", scope=SCOPE_BASE,
2740 attrs=["forestFunctionality", "domainFunctionality", "domainControllerFunctionality"])
2741 self.assertEquals(len(res), 1)
2742 self.assertEquals(len(res[0]["forestFunctionality"]), 1)
2743 self.assertEquals(len(res[0]["domainFunctionality"]), 1)
2744 self.assertEquals(len(res[0]["domainControllerFunctionality"]), 1)
2746 self.assertTrue(int(res[0]["forestFunctionality"][0]) <= int(res[0]["domainFunctionality"][0]))
2747 self.assertTrue(int(res[0]["domainControllerFunctionality"][0]) >= int(res[0]["domainFunctionality"][0]))
2749 res2 = self.ldb.search("", scope=SCOPE_BASE,
2750 attrs=["dsServiceName", "serverName"])
2751 self.assertEquals(len(res2), 1)
2752 self.assertEquals(len(res2[0]["dsServiceName"]), 1)
2754 res3 = self.ldb.search(res2[0]["dsServiceName"][0], scope=SCOPE_BASE, attrs=["msDS-Behavior-Version"])
2755 self.assertEquals(len(res3), 1)
2756 self.assertEquals(len(res3[0]["msDS-Behavior-Version"]), 1)
2757 self.assertEquals(int(res[0]["domainControllerFunctionality"][0]), int(res3[0]["msDS-Behavior-Version"][0]))
2759 res4 = self.ldb.search(ldb.domain_dn(), scope=SCOPE_BASE, attrs=["msDS-Behavior-Version"])
2760 self.assertEquals(len(res4), 1)
2761 self.assertEquals(len(res4[0]["msDS-Behavior-Version"]), 1)
2762 self.assertEquals(int(res[0]["domainFunctionality"][0]), int(res4[0]["msDS-Behavior-Version"][0]))
2764 res5 = self.ldb.search("cn=partitions," + str(ldb.get_config_basedn()), scope=SCOPE_BASE, attrs=["msDS-Behavior-Version"])
2765 self.assertEquals(len(res5), 1)
2766 self.assertEquals(len(res5[0]["msDS-Behavior-Version"]), 1)
2767 self.assertEquals(int(res[0]["forestFunctionality"][0]), int(res5[0]["msDS-Behavior-Version"][0]))
2769 def test_dnsHostname(self):
2770 """Testing the DNS hostname in rootDSE"""
2771 res = self.ldb.search("", scope=SCOPE_BASE,
2772 attrs=["dnsHostName", "serverName"])
2773 self.assertEquals(len(res), 1)
2775 res2 = self.ldb.search(res[0]["serverName"][0], scope=SCOPE_BASE,
2776 attrs=["dNSHostName"])
2777 self.assertEquals(len(res2), 1)
2779 self.assertEquals(res[0]["dnsHostName"][0], res2[0]["dNSHostName"][0])
2781 def test_ldapServiceName(self):
2782 """Testing the ldap service name in rootDSE"""
2783 res = self.ldb.search("", scope=SCOPE_BASE,
2784 attrs=["ldapServiceName", "dNSHostName"])
2785 self.assertEquals(len(res), 1)
2787 (hostname, _, dns_domainname) = res[0]["dNSHostName"][0].partition(".")
2788 self.assertTrue(":%s$@%s" % (hostname, dns_domainname.upper())
2789 in res[0]["ldapServiceName"][0])
2791 if not "://" in host:
2792 if os.path.isfile(host):
2793 host = "tdb://%s" % host
2794 else:
2795 host = "ldap://%s" % host
2797 ldb = SamDB(host, credentials=creds, session_info=system_session(lp), lp=lp)
2798 if not "tdb://" in host:
2799 gc_ldb = Ldb("%s:3268" % host, credentials=creds,
2800 session_info=system_session(lp), lp=lp)
2801 else:
2802 gc_ldb = None
2804 runner = SubunitTestRunner()
2805 rc = 0
2806 if not runner.run(unittest.makeSuite(BaseDnTests)).wasSuccessful():
2807 rc = 1
2808 if not runner.run(unittest.makeSuite(BasicTests)).wasSuccessful():
2809 rc = 1
2810 sys.exit(rc)