source: vendor/current/source4/dsdb/tests/python/ldap.py@ 740

Last change on this file since 740 was 740, checked in by Silvan Scherrer, 12 years ago

Samba Server: update vendor to 3.6.0

File size: 124.3 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3# This is a port of the original in testprogs/ejs/ldap.js
4
5import optparse
6import sys
7import time
8import base64
9import os
10
11sys.path.insert(0, "bin/python")
12import samba
13samba.ensure_external_module("testtools", "testtools")
14samba.ensure_external_module("subunit", "subunit/python")
15
16import samba.getopt as options
17
18from samba.auth import system_session
19from ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError
20from ldb import ERR_NO_SUCH_OBJECT, ERR_ATTRIBUTE_OR_VALUE_EXISTS
21from ldb import ERR_ENTRY_ALREADY_EXISTS, ERR_UNWILLING_TO_PERFORM
22from ldb import ERR_NOT_ALLOWED_ON_NON_LEAF, ERR_OTHER, ERR_INVALID_DN_SYNTAX
23from ldb import ERR_NO_SUCH_ATTRIBUTE, ERR_INVALID_ATTRIBUTE_SYNTAX
24from ldb import ERR_OBJECT_CLASS_VIOLATION, ERR_NOT_ALLOWED_ON_RDN
25from ldb import ERR_NAMING_VIOLATION, ERR_CONSTRAINT_VIOLATION
26from ldb import Message, MessageElement, Dn
27from ldb import FLAG_MOD_ADD, FLAG_MOD_REPLACE, FLAG_MOD_DELETE
28from ldb import timestring
29from samba import Ldb
30from samba.samdb import SamDB
31from 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)
37
38from subunit.run import SubunitTestRunner
39import unittest
40
41from samba.ndr import ndr_pack, ndr_unpack
42from samba.dcerpc import security, lsa
43from samba.tests import delete_force
44
45parser = optparse.OptionParser("ldap.py [options] <host>")
46sambaopts = options.SambaOptions(parser)
47parser.add_option_group(sambaopts)
48parser.add_option_group(options.VersionOptions(parser))
49# use command line creds if available
50credopts = options.CredentialsOptions(parser)
51parser.add_option_group(credopts)
52opts, args = parser.parse_args()
53
54if len(args) < 1:
55 parser.print_usage()
56 sys.exit(1)
57
58host = args[0]
59
60lp = sambaopts.get_loadparm()
61creds = credopts.get_credentials(lp)
62
63class BasicTests(unittest.TestCase):
64
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())
73
74 print "baseDN: %s\n" % self.base_dn
75
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)
99
100 def test_objectclasses(self):
101 """Test objectClass behaviour"""
102 print "Test objectClass behaviour"""
103
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)
112
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)
121
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)
130
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)
140
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)
150
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)
159
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)) })
165
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")
170
171 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
172
173 self.ldb.add({
174 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
175 "objectClass": "person" })
176
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)
184
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"])
189
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)
201
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)
212
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)
223
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)
235
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)
246
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)
253
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)
261
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)
267
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)
277
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)
284
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)
294
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)
304
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)
311
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"])
316
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)
322
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)
329
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)
341
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)
348
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)
355
356 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
357
358 def test_system_only(self):
359 """Test systemOnly objects"""
360 print "Test systemOnly objects"""
361
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)
369
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)
377
378 delete_force(self.ldb, "cn=ldaptestobject," + self.base_dn)
379 delete_force(self.ldb, "cn=Test Secret,cn=system," + self.base_dn)
380
381 # Create secret over LSA and try to change it
382
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)
393
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)
403
404 delete_force(self.ldb, "cn=Test Secret,cn=system," + self.base_dn)
405
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)
414
415 self.ldb.add({
416 "dn": "cn=ldaptestcontainer," + self.base_dn,
417 "objectclass": "container"})
418
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)
428
429 delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
430
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")
444
445 def test_invalid_parent(self):
446 """Test adding an object with invalid parent"""
447 print "Test adding an object with invalid parent"""
448
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)
457
458 delete_force(self.ldb, "cn=ldaptestgroup,cn=thisdoesnotexist123,"
459 + self.base_dn)
460
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)
468
469 delete_force(self.ldb, "ou=testou,cn=users," + self.base_dn)
470
471 def test_invalid_attribute(self):
472 """Test invalid attributes on schema/objectclasses"""
473 print "Test invalid attributes on schema/objectclasses"""
474
475 # attributes not in schema test
476
477 # add operation
478
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)
487
488 self.ldb.add({
489 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
490 "objectclass": "group"})
491
492 # modify operation
493
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)
503
504 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
505
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.
509
510 # add operations
511
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)
520
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)
531
532 self.ldb.add({
533 "dn": "cn=ldaptestobject," + self.base_dn,
534 "objectclass": "ipProtocol",
535 "ipProtocolNumber": "1"})
536
537 # modify operations
538
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)
548
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)
559
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)
570
571 delete_force(self.ldb, "cn=ldaptestobject," + self.base_dn)
572
573 def test_single_valued_attributes(self):
574 """Test single-valued attributes"""
575 print "Test single-valued attributes"""
576
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)
585
586 self.ldb.add({
587 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
588 "objectclass": "group"})
589
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)
599
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)
605
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)
615
616 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
617
618 def test_attribute_ranges(self):
619 """Test attribute ranges"""
620 print "Test attribute ranges"""
621
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)
631
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)
641
642 ldb.add({
643 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
644 "objectClass": "person" })
645
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)
655
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)
665
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)
670
671 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
672
673 def test_empty_messages(self):
674 """Test empty messages"""
675 print "Test empty messages"""
676
677 m = Message()
678 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
679
680 try:
681 ldb.add(m)
682 self.fail()
683 except LdbError, (num, _):
684 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
685
686 try:
687 ldb.modify(m)
688 self.fail()
689 except LdbError, (num, _):
690 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
691
692 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
693
694 def test_empty_attributes(self):
695 """Test empty attributes"""
696 print "Test empty attributes"""
697
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")
702
703 try:
704 ldb.add(m)
705 self.fail()
706 except LdbError, (num, _):
707 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
708
709 self.ldb.add({
710 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
711 "objectclass": "group"})
712
713 m = Message()
714 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
715 m["description"] = MessageElement([], FLAG_MOD_ADD, "description")
716
717 try:
718 ldb.modify(m)
719 self.fail()
720 except LdbError, (num, _):
721 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
722
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)
727
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)
736
737 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
738
739 def test_instanceType(self):
740 """Tests the 'instanceType' attribute"""
741 print "Tests the 'instanceType' attribute"""
742
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)
752
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)
762
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)
772
773 self.ldb.add({
774 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
775 "objectclass": "group"})
776
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)
786
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)
796
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)
805
806 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
807
808 def test_distinguished_name(self):
809 """Tests the 'distinguishedName' attribute"""
810 print "Tests the 'distinguishedName' attribute"""
811
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)
823
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})
829
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))
837
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)
849
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")
855
856 try:
857 ldb.modify(m)
858 self.fail()
859 except LdbError, (num, _):
860 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
861
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")
867
868 try:
869 ldb.modify(m)
870 self.fail()
871 except LdbError, (num, _):
872 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
873
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")
879
880 try:
881 ldb.modify(m)
882 self.fail()
883 except LdbError, (num, _):
884 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
885
886 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
887
888 def test_rdn_name(self):
889 """Tests the RDN"""
890 print "Tests the RDN"""
891
892 # Search
893
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)
900
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)
907
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)
913
914 # Add
915
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)
924
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)
933
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)
942
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)
951
952 delete_force(self.ldb, "description=xyz,cn=users," + self.base_dn)
953
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"})
959
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")
966
967 # Modify
968
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)
978
979 # Delete
980
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)
987
988 # Rename
989
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)
997
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)
1005
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)
1013
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)
1021
1022 delete_force(self.ldb, "description=xyz,cn=users," + self.base_dn)
1023
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)
1031
1032 # names
1033
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)
1043
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)
1053
1054 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1055
1056
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 = """
1064dn: %s,%s""" % (rdn,self.base_dn) + """
1065objectClass: container
1066"""
1067 self.ldb.add_ldif(ldif)
1068 delete_force(self.ldb, "%s,%s" % (rdn, self.base_dn))
1069
1070 rdn = "CN=a0123456789012345678901234567890123456789012345678901234567890120";
1071 delete_force(self.ldb, "%s,%s" % (rdn, self.base_dn))
1072 try:
1073 ldif = """
1074dn: %s,%s""" % (rdn,self.base_dn) + """
1075objectClass: container
1076"""
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))
1082
1083 def test_rename(self):
1084 """Tests the rename operation"""
1085 print "Tests the rename operations"""
1086
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)
1093
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)
1100
1101 self.ldb.add({
1102 "dn": "cn=ldaptestuser2,cn=users," + self.base_dn,
1103 "objectclass": "user" })
1104
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)
1108
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)
1115
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)
1122
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)
1129
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)
1136
1137 delete_force(self.ldb, "cn=ldaptestuser3,cn=users," + self.base_dn)
1138
1139 # Performs some "systemFlags" testing
1140
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)
1147
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)
1154
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)
1161
1162 # It's not really possible to test moves on the schema partition since
1163 # there don't exist subcontainers on it.
1164
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)
1171
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)
1178
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)
1185
1186 # Performs some other constraints testing
1187
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)
1193
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"""
1197
1198 self.ldb.add({
1199 "dn": "cn=ldaptestuser5,cn=users," + self.base_dn,
1200 "objectclass": "user" })
1201
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)
1215
1216 def test_objectGUID(self):
1217 """Test objectGUID behaviour"""
1218 print "Testing objectGUID behaviour\n"
1219
1220 # The objectGUID cannot directly be set
1221 try:
1222 self.ldb.add_ldif("""
1223dn: cn=ldaptestcontainer,""" + self.base_dn + """
1224objectClass: container
1225objectGUID: bd3480c9-58af-4cd8-92df-bc4a18b6e44d
1226""")
1227 self.fail()
1228 except LdbError, (num, _):
1229 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1230
1231 self.ldb.add({
1232 "dn": "cn=ldaptestcontainer," + self.base_dn,
1233 "objectClass": "container" })
1234
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])
1244
1245 delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
1246
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())) })
1255
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
1265
1266 delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
1267
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())) })
1276
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])
1288
1289 # The objectGUID cannot directly be changed
1290 try:
1291 self.ldb.modify_ldif("""
1292dn: cn=ldaptestcontainer,""" + self.base_dn + """
1293changetype: modify
1294replace: objectGUID
1295objectGUID: bd3480c9-58af-4cd8-92df-bc4a18b6e44d
1296""")
1297 self.fail()
1298 except LdbError, (num, _):
1299 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
1300
1301 delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
1302
1303 def test_parentGUID(self):
1304 """Test parentGUID behaviour"""
1305 print "Testing parentGUID behaviour\n"
1306
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"]);
1321
1322 """Check if the parentGUID is valid """
1323 self.assertEquals(res1[0]["parentGUID"], res2[0]["objectGUID"]);
1324
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);
1332
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);
1340
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);
1348
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");
1359
1360 print "Testing parentGUID behaviour on rename\n"
1361
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"]);
1373
1374 delete_force(self.ldb, "cn=parentguidtest,cn=testotherusers," + self.base_dn)
1375 delete_force(self.ldb, "cn=testotherusers," + self.base_dn)
1376
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"
1380
1381 res1 = ldb.search(base=self.base_dn, scope=SCOPE_SUBTREE,
1382 attrs=["groupType"], expression="groupType=2147483653");
1383
1384 res2 = ldb.search(base=self.base_dn, scope=SCOPE_SUBTREE,
1385 attrs=["groupType"], expression="groupType=-2147483643");
1386
1387 self.assertEquals(len(res1), len(res2))
1388
1389 self.assertTrue(res1.count > 0)
1390
1391 self.assertEquals(res1[0]["groupType"][0], "-2147483643")
1392
1393 def test_linked_attributes(self):
1394 """This tests the linked attribute behaviour"""
1395 print "Testing linked attribute behaviour\n"
1396
1397 ldb.add({
1398 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
1399 "objectclass": "group"})
1400
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)
1409
1410 ldb.add({
1411 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1412 "objectclass": "user"})
1413
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)
1423
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)
1429
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)
1439
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)
1449
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)
1455
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)
1463
1464 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1465
1466 ldb.add({
1467 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
1468 "objectclass": "group",
1469 "member": "cn=ldaptestuser,cn=users," + self.base_dn})
1470
1471 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1472
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])
1479
1480 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1481
1482 def test_wkguid(self):
1483 """Test Well known GUID behaviours (including DN+Binary)"""
1484 print "Test Well known GUID behaviours (including DN+Binary)"""
1485
1486 res = self.ldb.search(base=("<WKGUID=ab1d30f3768811d1aded00c04fd8d5cd,%s>" % self.base_dn), scope=SCOPE_BASE, attrs=[])
1487 self.assertEquals(len(res), 1)
1488
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)
1491
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)
1498
1499 def test_subschemasubentry(self):
1500 """Test subSchemaSubEntry appears when requested, but not when not requested"""
1501 print "Test subSchemaSubEntry"""
1502
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)
1506
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])
1510
1511 def test_all(self):
1512 """Basic tests"""
1513
1514 print "Testing user add"
1515
1516 ldb.add({
1517 "dn": "cn=ldaptestuser,cn=uSers," + self.base_dn,
1518 "objectclass": "user",
1519 "cN": "LDAPtestUSER",
1520 "givenname": "ldap",
1521 "sn": "testy"})
1522
1523 ldb.add({
1524 "dn": "cn=ldaptestgroup,cn=uSers," + self.base_dn,
1525 "objectclass": "group",
1526 "member": "cn=ldaptestuser,cn=useRs," + self.base_dn})
1527
1528 ldb.add({
1529 "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
1530 "objectclass": "computer",
1531 "cN": "LDAPtestCOMPUTER"})
1532
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"})
1538
1539 try:
1540 ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn,
1541 "objectClass": "computer",
1542 "cn": "LDAPtest2COMPUTER"
1543 })
1544 self.fail()
1545 except LdbError, (num, _):
1546 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1547
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)
1553 })
1554 self.fail()
1555 except LdbError, (num, _):
1556 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1557
1558 ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn,
1559 "objectClass": "computer",
1560 "cn": "LDAPtestCOMPUTER3"
1561 })
1562
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))
1566
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);
1581
1582 delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
1583
1584 print "Testing attribute or value exists behaviour"
1585 try:
1586 ldb.modify_ldif("""
1587dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1588changetype: modify
1589replace: servicePrincipalName
1590servicePrincipalName: host/ldaptest2computer
1591servicePrincipalName: host/ldaptest2computer
1592servicePrincipalName: cifs/ldaptest2computer
1593""")
1594 self.fail()
1595 except LdbError, (num, msg):
1596 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
1597
1598 ldb.modify_ldif("""
1599dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1600changetype: modify
1601replace: servicePrincipalName
1602servicePrincipalName: host/ldaptest2computer
1603servicePrincipalName: cifs/ldaptest2computer
1604""")
1605 try:
1606 ldb.modify_ldif("""
1607dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1608changetype: modify
1609add: servicePrincipalName
1610servicePrincipalName: host/ldaptest2computer
1611""")
1612 self.fail()
1613 except LdbError, (num, msg):
1614 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
1615
1616 print "Testing ranged results"
1617 ldb.modify_ldif("""
1618dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1619changetype: modify
1620replace: servicePrincipalName
1621""")
1622
1623 ldb.modify_ldif("""
1624dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1625changetype: modify
1626add: servicePrincipalName
1627servicePrincipalName: host/ldaptest2computer0
1628servicePrincipalName: host/ldaptest2computer1
1629servicePrincipalName: host/ldaptest2computer2
1630servicePrincipalName: host/ldaptest2computer3
1631servicePrincipalName: host/ldaptest2computer4
1632servicePrincipalName: host/ldaptest2computer5
1633servicePrincipalName: host/ldaptest2computer6
1634servicePrincipalName: host/ldaptest2computer7
1635servicePrincipalName: host/ldaptest2computer8
1636servicePrincipalName: host/ldaptest2computer9
1637servicePrincipalName: host/ldaptest2computer10
1638servicePrincipalName: host/ldaptest2computer11
1639servicePrincipalName: host/ldaptest2computer12
1640servicePrincipalName: host/ldaptest2computer13
1641servicePrincipalName: host/ldaptest2computer14
1642servicePrincipalName: host/ldaptest2computer15
1643servicePrincipalName: host/ldaptest2computer16
1644servicePrincipalName: host/ldaptest2computer17
1645servicePrincipalName: host/ldaptest2computer18
1646servicePrincipalName: host/ldaptest2computer19
1647servicePrincipalName: host/ldaptest2computer20
1648servicePrincipalName: host/ldaptest2computer21
1649servicePrincipalName: host/ldaptest2computer22
1650servicePrincipalName: host/ldaptest2computer23
1651servicePrincipalName: host/ldaptest2computer24
1652servicePrincipalName: host/ldaptest2computer25
1653servicePrincipalName: host/ldaptest2computer26
1654servicePrincipalName: host/ldaptest2computer27
1655servicePrincipalName: host/ldaptest2computer28
1656servicePrincipalName: host/ldaptest2computer29
1657""")
1658
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)
1664
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)
1669
1670
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)
1674
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)
1678
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)
1682
1683
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]
1688
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)
1695
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)
1700
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)
1707
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"})
1715
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))
1720
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))
1724
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))
1728
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))
1732
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")
1736
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))
1740
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))
1744
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))
1749
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")
1753
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))")
1757
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")
1761
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))")
1765
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")
1769
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))")
1773
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")
1777
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))")
1781
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")
1785
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))")
1789
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))")
1793
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))")
1797
1798 print "Testing Renames"
1799
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))")
1804
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)
1807
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))")
1811
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")
1815
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))")
1819
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")
1823
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))")
1827
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")
1831
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))")
1835
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)
1842 # }
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")
1846
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")
1853
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)
1862
1863 # rename back
1864 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser2,cn=users," + self.base_dn)
1865
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)
1873
1874 # ensure can now use that name
1875 ldb.add({"dn": "cn=ldaptestuser3,cn=users," + self.base_dn,
1876 "objectClass": "user",
1877 "cn": "LDAPtestUSER3"})
1878
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))
1890
1891 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser5,cn=users," + self.base_dn)
1892
1893 ldb.delete("cn=ldaptestuser5,cn=users," + self.base_dn)
1894
1895 delete_force(ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
1896
1897 ldb.rename("cn=ldaptestgroup,cn=users," + self.base_dn, "cn=ldaptestgroup2,cn=users," + self.base_dn)
1898
1899 print "Testing subtree renames"
1900
1901 ldb.add({"dn": "cn=ldaptestcontainer," + self.base_dn,
1902 "objectClass": "container"})
1903
1904 ldb.add({"dn": "CN=ldaptestuser4,CN=ldaptestcontainer," + self.base_dn,
1905 "objectClass": "user",
1906 "cn": "LDAPtestUSER4"})
1907
1908 # Here we don't enforce these hard "description" constraints
1909 ldb.modify_ldif("""
1910dn: cn=ldaptestcontainer,""" + self.base_dn + """
1911changetype: modify
1912replace: description
1913description: desc1
1914description: desc2
1915""")
1916
1917 ldb.modify_ldif("""
1918dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
1919changetype: modify
1920add: member
1921member: cn=ldaptestuser4,cn=ldaptestcontainer,""" + self.base_dn + """
1922member: cn=ldaptestcomputer,cn=computers,""" + self.base_dn + """
1923member: cn=ldaptestuser2,cn=users,""" + self.base_dn + """
1924""")
1925
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)
1928
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))")
1932
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)
1941
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)
1949
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)
1953
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())
1956
1957 time.sleep(4)
1958
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?")
1962
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)
1969
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))
1976
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)
1983
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)
1989
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)
1993
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)
1997
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)
2002
2003 ldb.add({"dn": "cn=ldaptestutf8user Úùéìòà,cn=users," + self.base_dn, "objectClass": "user"})
2004
2005 ldb.add({"dn": "cn=ldaptestutf8user2 Úùéìòà,cn=users," + self.base_dn, "objectClass": "user"})
2006
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))")
2010
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)
2022
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 + "))")
2026
2027 self.assertEquals(res[0].dn, res2[0].dn)
2028
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))
2032
2033 self.assertEquals(res[0].dn, res3[0].dn)
2034
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)
2039
2040 self.assertEquals(res[0].dn, res3gc[0].dn)
2041
2042 print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon)) in with 'phantom root' control"
2043
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")
2047
2048 self.assertEquals(res[0].dn, res3control[0].dn)
2049
2050 ldb.delete(res[0].dn)
2051
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))")
2055
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)
2068
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 + "))")
2072
2073 self.assertEquals(res[0].dn, res2[0].dn)
2074
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")
2079
2080 self.assertEquals(res[0].dn, res2gc[0].dn)
2081
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))")
2085
2086 self.assertEquals(res[0].dn, res3[0].dn)
2087
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")
2092
2093 self.assertEquals(res[0].dn, res3gc[0].dn)
2094
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))")
2098
2099 self.assertEquals(res[0].dn, res4[0].dn)
2100
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))")
2104
2105 self.assertEquals(res[0].dn, res5[0].dn)
2106
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))")
2110
2111 self.assertEquals(res[0].dn, res6[0].dn)
2112
2113 ldb.delete("<GUID=" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + ">")
2114
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))")
2118
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)
2128
2129 ldb.delete("<SID=" + ldb.schema_format_value("objectSID", res[0]["objectSID"][0]) + ">")
2130
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))")
2135
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())
2147
2148 ldaptestuser2_sid = res_user[0]["objectSid"][0]
2149 ldaptestuser2_guid = res_user[0]["objectGUID"][0]
2150
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))")
2155
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)
2170
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))")
2173
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()
2179
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)
2181
2182 print "Quicktest for linked attributes"
2183 ldb.modify_ldif("""
2184dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2185changetype: modify
2186replace: member
2187member: CN=ldaptestuser2,CN=Users,""" + self.base_dn + """
2188member: CN=ldaptestutf8user Úùéìòà,CN=Users,""" + self.base_dn + """
2189""")
2190
2191 ldb.modify_ldif("""
2192dn: <GUID=""" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + """>
2193changetype: modify
2194replace: member
2195member: CN=ldaptestutf8user Úùéìòà,CN=Users,""" + self.base_dn + """
2196""")
2197
2198 ldb.modify_ldif("""
2199dn: <SID=""" + ldb.schema_format_value("objectSid", res[0]["objectSid"][0]) + """>
2200changetype: modify
2201delete: member
2202""")
2203
2204 ldb.modify_ldif("""
2205dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2206changetype: modify
2207add: member
2208member: <GUID=""" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + """>
2209member: CN=ldaptestutf8user Úùéìòà,CN=Users,""" + self.base_dn + """
2210""")
2211
2212 ldb.modify_ldif("""
2213dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2214changetype: modify
2215replace: member
2216""")
2217
2218 ldb.modify_ldif("""
2219dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2220changetype: modify
2221add: member
2222member: <SID=""" + ldb.schema_format_value("objectSid", res_user[0]["objectSid"][0]) + """>
2223member: CN=ldaptestutf8user Úùéìòà,CN=Users,""" + self.base_dn + """
2224""")
2225
2226 ldb.modify_ldif("""
2227dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2228changetype: modify
2229delete: member
2230member: CN=ldaptestutf8user Úùéìòà,CN=Users,""" + self.base_dn + """
2231""")
2232
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))")
2235
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)
2239
2240 ldb.delete(("CN=ldaptestuser2,CN=Users," + self.base_dn))
2241
2242 time.sleep(4)
2243
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")
2248
2249 self.assertEquals(str(res[0].dn), ("CN=ldaptestgroup2,CN=Users," + self.base_dn))
2250 self.assertTrue("member" not in res[0])
2251
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))")
2257
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])
2264
2265 ldb.delete(res[0].dn)
2266
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))")
2270
2271 ldb.delete(res[0].dn)
2272
2273 ldb.delete(("CN=ldaptestgroup2,CN=Users," + self.base_dn))
2274
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))")
2279
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)
2283
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)
2287
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"
2290
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)
2293
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)
2297
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)
2301
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)
2305
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)
2309
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)
2314
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)
2318
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)
2323
2324 self.assertEquals(list(res[0]["objectClass"]), ["top", "domain", "domainDNS"])
2325
2326 # check enumeration
2327
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)
2331
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)
2335
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)
2339
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)
2343
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)
2347
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)
2351
2352 print "Testing creating a user with the posixAccount objectClass"
2353 self.ldb.add_ldif("""dn: cn=posixuser,CN=Users,%s
2354objectClass: top
2355objectClass: person
2356objectClass: posixAccount
2357objectClass: user
2358objectClass: organizationalPerson
2359cn: posixuser
2360uid: posixuser
2361sn: posixuser
2362uidNumber: 10126
2363gidNumber: 10126
2364homeDirectory: /home/posixuser
2365loginShell: /bin/bash
2366gecos: Posix User;;;
2367description: A POSIX user"""% (self.base_dn))
2368
2369 print "Testing removing the posixAccount objectClass from an existing user"
2370 self.ldb.modify_ldif("""dn: cn=posixuser,CN=Users,%s
2371changetype: modify
2372delete: objectClass
2373objectClass: posixAccount"""% (self.base_dn))
2374
2375 print "Testing adding the posixAccount objectClass to an existing user"
2376 self.ldb.modify_ldif("""dn: cn=posixuser,CN=Users,%s
2377changetype: modify
2378add: objectClass
2379objectClass: posixAccount"""% (self.base_dn))
2380
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)
2397
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)
2402 #
2403 # Test an empty security descriptor (naturally this shouldn't work)
2404 #
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)
2416 #
2417 # Test add_ldif() with SDDL security descriptor input
2418 #
2419 try:
2420 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2421 self.ldb.add_ldif("""
2422dn: """ + user_dn + """
2423objectclass: user
2424sAMAccountName: """ + user_name + """
2425nTSecurityDescriptor: """ + 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)
2433 #
2434 # Test add_ldif() with BASE64 security descriptor
2435 #
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("""
2442dn: """ + user_dn + """
2443objectclass: user
2444sAMAccountName: """ + user_name + """
2445nTSecurityDescriptor:: """ + 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)
2453
2454 def test_security_descriptor_add_neg(self):
2455 """Test add_ldif() with BASE64 security descriptor input using WRONG domain SID
2456 Negative test
2457 """
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("""
2466dn: """ + user_dn + """
2467objectclass: user
2468sAMAccountName: """ + user_name + """
2469nTSecurityDescriptor:: """ + 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)
2474
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)
2479 #
2480 # Test an empty security descriptor (naturally this shouldn't work)
2481 #
2482 delete_force(self.ldb, user_dn)
2483 self.ldb.add({ "dn": user_dn,
2484 "objectClass": "user",
2485 "sAMAccountName": user_name })
2486
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)
2496
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)
2506
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)
2516
2517 delete_force(self.ldb, user_dn)
2518 #
2519 # Test modify_ldif() with SDDL security descriptor input
2520 # Add ACE to the original descriptor test
2521 #
2522 try:
2523 self.ldb.add_ldif("""
2524dn: """ + user_dn + """
2525objectclass: user
2526sAMAccountName: """ + 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 = """
2534dn: """ + user_dn + """
2535changetype: modify
2536replace: nTSecurityDescriptor
2537nTSecurityDescriptor: """ + 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)
2547 #
2548 # Test modify_ldif() with SDDL security descriptor input
2549 # New desctiptor test
2550 #
2551 try:
2552 self.ldb.add_ldif("""
2553dn: """ + user_dn + """
2554objectclass: user
2555sAMAccountName: """ + user_name)
2556 # Modify descriptor
2557 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2558 mod = """
2559dn: """ + user_dn + """
2560changetype: modify
2561replace: nTSecurityDescriptor
2562nTSecurityDescriptor: """ + 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)
2572 #
2573 # Test modify_ldif() with BASE64 security descriptor input
2574 # Add ACE to the original descriptor test
2575 #
2576 try:
2577 self.ldb.add_ldif("""
2578dn: """ + user_dn + """
2579objectclass: user
2580sAMAccountName: """ + 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 = """
2590dn: """ + user_dn + """
2591changetype: modify
2592replace: nTSecurityDescriptor
2593nTSecurityDescriptor:: """ + 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)
2603 #
2604 # Test modify_ldif() with BASE64 security descriptor input
2605 # New descriptor test
2606 #
2607 try:
2608 delete_force(self.ldb, user_dn)
2609 self.ldb.add_ldif("""
2610dn: """ + user_dn + """
2611objectclass: user
2612sAMAccountName: """ + 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 = """
2618dn: """ + user_dn + """
2619changetype: modify
2620replace: nTSecurityDescriptor
2621nTSecurityDescriptor:: """ + 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)
2631
2632 def test_dsheuristics(self):
2633 """Tests the 'dSHeuristics' attribute"""
2634 print "Tests the 'dSHeuristics' attribute"""
2635
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)
2653
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
2662 def test_operational(self):
2663 """Tests operational attributes"""
2664 print "Tests operational attributes"""
2665
2666 res = self.ldb.search(self.base_dn, scope=SCOPE_BASE,
2667 attrs=["createTimeStamp", "modifyTimeStamp",
2668 "structuralObjectClass", "whenCreated",
2669 "whenChanged"])
2670 self.assertEquals(len(res), 1)
2671 self.assertTrue("createTimeStamp" in res[0])
2672 self.assertTrue("modifyTimeStamp" in res[0])
2673 self.assertTrue("structuralObjectClass" in res[0])
2674 self.assertTrue("whenCreated" in res[0])
2675 self.assertTrue("whenChanged" in res[0])
2676
2677class BaseDnTests(unittest.TestCase):
2678
2679 def setUp(self):
2680 super(BaseDnTests, self).setUp()
2681 self.ldb = ldb
2682
2683 def test_rootdse_attrs(self):
2684 """Testing for all rootDSE attributes"""
2685 res = self.ldb.search("", scope=SCOPE_BASE, attrs=[])
2686 self.assertEquals(len(res), 1)
2687
2688 def test_highestcommittedusn(self):
2689 """Testing for highestCommittedUSN"""
2690 res = self.ldb.search("", scope=SCOPE_BASE, attrs=["highestCommittedUSN"])
2691 self.assertEquals(len(res), 1)
2692 self.assertTrue(int(res[0]["highestCommittedUSN"][0]) != 0)
2693
2694 def test_netlogon(self):
2695 """Testing for netlogon via LDAP"""
2696 res = self.ldb.search("", scope=SCOPE_BASE, attrs=["netlogon"])
2697 self.assertEquals(len(res), 0)
2698
2699 def test_netlogon_highestcommitted_usn(self):
2700 """Testing for netlogon and highestCommittedUSN via LDAP"""
2701 res = self.ldb.search("", scope=SCOPE_BASE,
2702 attrs=["netlogon", "highestCommittedUSN"])
2703 self.assertEquals(len(res), 0)
2704
2705 def test_namingContexts(self):
2706 """Testing for namingContexts in rootDSE"""
2707 res = self.ldb.search("", scope=SCOPE_BASE,
2708 attrs=["namingContexts", "defaultNamingContext", "schemaNamingContext", "configurationNamingContext"])
2709 self.assertEquals(len(res), 1)
2710
2711 ncs = set([])
2712 for nc in res[0]["namingContexts"]:
2713 self.assertTrue(nc not in ncs)
2714 ncs.add(nc)
2715
2716 self.assertTrue(res[0]["defaultNamingContext"][0] in ncs)
2717 self.assertTrue(res[0]["configurationNamingContext"][0] in ncs)
2718 self.assertTrue(res[0]["schemaNamingContext"][0] in ncs)
2719
2720 def test_serverPath(self):
2721 """Testing the server paths in rootDSE"""
2722 res = self.ldb.search("", scope=SCOPE_BASE,
2723 attrs=["dsServiceName", "serverName"])
2724 self.assertEquals(len(res), 1)
2725
2726 self.assertTrue("CN=Servers" in res[0]["dsServiceName"][0])
2727 self.assertTrue("CN=Sites" in res[0]["dsServiceName"][0])
2728 self.assertTrue("CN=NTDS Settings" in res[0]["dsServiceName"][0])
2729 self.assertTrue("CN=Servers" in res[0]["serverName"][0])
2730 self.assertTrue("CN=Sites" in res[0]["serverName"][0])
2731 self.assertFalse("CN=NTDS Settings" in res[0]["serverName"][0])
2732
2733 def test_functionality(self):
2734 """Testing the server paths in rootDSE"""
2735 res = self.ldb.search("", scope=SCOPE_BASE,
2736 attrs=["forestFunctionality", "domainFunctionality", "domainControllerFunctionality"])
2737 self.assertEquals(len(res), 1)
2738 self.assertEquals(len(res[0]["forestFunctionality"]), 1)
2739 self.assertEquals(len(res[0]["domainFunctionality"]), 1)
2740 self.assertEquals(len(res[0]["domainControllerFunctionality"]), 1)
2741
2742 self.assertTrue(int(res[0]["forestFunctionality"][0]) <= int(res[0]["domainFunctionality"][0]))
2743 self.assertTrue(int(res[0]["domainControllerFunctionality"][0]) >= int(res[0]["domainFunctionality"][0]))
2744
2745 res2 = self.ldb.search("", scope=SCOPE_BASE,
2746 attrs=["dsServiceName", "serverName"])
2747 self.assertEquals(len(res2), 1)
2748 self.assertEquals(len(res2[0]["dsServiceName"]), 1)
2749
2750 res3 = self.ldb.search(res2[0]["dsServiceName"][0], scope=SCOPE_BASE, attrs=["msDS-Behavior-Version"])
2751 self.assertEquals(len(res3), 1)
2752 self.assertEquals(len(res3[0]["msDS-Behavior-Version"]), 1)
2753 self.assertEquals(int(res[0]["domainControllerFunctionality"][0]), int(res3[0]["msDS-Behavior-Version"][0]))
2754
2755 res4 = self.ldb.search(ldb.domain_dn(), scope=SCOPE_BASE, attrs=["msDS-Behavior-Version"])
2756 self.assertEquals(len(res4), 1)
2757 self.assertEquals(len(res4[0]["msDS-Behavior-Version"]), 1)
2758 self.assertEquals(int(res[0]["domainFunctionality"][0]), int(res4[0]["msDS-Behavior-Version"][0]))
2759
2760 res5 = self.ldb.search("cn=partitions," + str(ldb.get_config_basedn()), scope=SCOPE_BASE, attrs=["msDS-Behavior-Version"])
2761 self.assertEquals(len(res5), 1)
2762 self.assertEquals(len(res5[0]["msDS-Behavior-Version"]), 1)
2763 self.assertEquals(int(res[0]["forestFunctionality"][0]), int(res5[0]["msDS-Behavior-Version"][0]))
2764
2765 def test_dnsHostname(self):
2766 """Testing the DNS hostname in rootDSE"""
2767 res = self.ldb.search("", scope=SCOPE_BASE,
2768 attrs=["dnsHostName", "serverName"])
2769 self.assertEquals(len(res), 1)
2770
2771 res2 = self.ldb.search(res[0]["serverName"][0], scope=SCOPE_BASE,
2772 attrs=["dNSHostName"])
2773 self.assertEquals(len(res2), 1)
2774
2775 self.assertEquals(res[0]["dnsHostName"][0], res2[0]["dNSHostName"][0])
2776
2777 def test_ldapServiceName(self):
2778 """Testing the ldap service name in rootDSE"""
2779 res = self.ldb.search("", scope=SCOPE_BASE,
2780 attrs=["ldapServiceName", "dNSHostName"])
2781 self.assertEquals(len(res), 1)
2782
2783 (hostname, _, dns_domainname) = res[0]["dNSHostName"][0].partition(".")
2784 self.assertTrue(":%s$@%s" % (hostname, dns_domainname.upper())
2785 in res[0]["ldapServiceName"][0])
2786
2787if not "://" in host:
2788 if os.path.isfile(host):
2789 host = "tdb://%s" % host
2790 else:
2791 host = "ldap://%s" % host
2792
2793ldb = SamDB(host, credentials=creds, session_info=system_session(lp), lp=lp)
2794if not "tdb://" in host:
2795 gc_ldb = Ldb("%s:3268" % host, credentials=creds,
2796 session_info=system_session(lp), lp=lp)
2797else:
2798 gc_ldb = None
2799
2800runner = SubunitTestRunner()
2801rc = 0
2802if not runner.run(unittest.makeSuite(BaseDnTests)).wasSuccessful():
2803 rc = 1
2804if not runner.run(unittest.makeSuite(BasicTests)).wasSuccessful():
2805 rc = 1
2806sys.exit(rc)
Note: See TracBrowser for help on using the repository browser.