s4-dsdb-test/reanimate: Fix whitespaces according to PEP8
[Samba.git] / source4 / dsdb / tests / python / ldap.py
blob63eb9a5d62c941b508acd3a84ff046f1bb066623
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 # This is a port of the original in testprogs/ejs/ldap.js
5 # Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2008-2011
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20 import optparse
21 import sys
22 import time
23 import base64
24 import os
26 sys.path.insert(0, "bin/python")
27 import samba
28 from samba.tests.subunitrun import SubunitOptions, TestProgram
29 import samba.getopt as options
31 from samba.auth import system_session
32 from ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError
33 from ldb import ERR_NO_SUCH_OBJECT, ERR_ATTRIBUTE_OR_VALUE_EXISTS
34 from ldb import ERR_ENTRY_ALREADY_EXISTS, ERR_UNWILLING_TO_PERFORM
35 from ldb import ERR_NOT_ALLOWED_ON_NON_LEAF, ERR_OTHER, ERR_INVALID_DN_SYNTAX
36 from ldb import ERR_NO_SUCH_ATTRIBUTE, ERR_INVALID_ATTRIBUTE_SYNTAX
37 from ldb import ERR_OBJECT_CLASS_VIOLATION, ERR_NOT_ALLOWED_ON_RDN
38 from ldb import ERR_NAMING_VIOLATION, ERR_CONSTRAINT_VIOLATION
39 from ldb import Message, MessageElement, Dn
40 from ldb import FLAG_MOD_ADD, FLAG_MOD_REPLACE, FLAG_MOD_DELETE
41 from ldb import timestring
42 from samba import Ldb
43 from samba.samdb import SamDB
44 from samba.dsdb import (UF_NORMAL_ACCOUNT,
45 UF_WORKSTATION_TRUST_ACCOUNT,
46 UF_PASSWD_NOTREQD, UF_ACCOUNTDISABLE, ATYPE_NORMAL_ACCOUNT,
47 ATYPE_WORKSTATION_TRUST, SYSTEM_FLAG_DOMAIN_DISALLOW_MOVE,
48 SYSTEM_FLAG_CONFIG_ALLOW_RENAME, SYSTEM_FLAG_CONFIG_ALLOW_MOVE,
49 SYSTEM_FLAG_CONFIG_ALLOW_LIMITED_MOVE)
51 from samba.ndr import ndr_pack, ndr_unpack
52 from samba.dcerpc import security, lsa
53 from samba.tests import delete_force
55 parser = optparse.OptionParser("ldap.py [options] <host>")
56 sambaopts = options.SambaOptions(parser)
57 parser.add_option_group(sambaopts)
58 parser.add_option_group(options.VersionOptions(parser))
59 # use command line creds if available
60 credopts = options.CredentialsOptions(parser)
61 parser.add_option_group(credopts)
62 subunitopts = SubunitOptions(parser)
63 parser.add_option_group(subunitopts)
64 opts, args = parser.parse_args()
66 if len(args) < 1:
67 parser.print_usage()
68 sys.exit(1)
70 host = args[0]
72 lp = sambaopts.get_loadparm()
73 creds = credopts.get_credentials(lp)
75 class BasicTests(samba.tests.TestCase):
77 def setUp(self):
78 super(BasicTests, self).setUp()
79 self.ldb = ldb
80 self.gc_ldb = gc_ldb
81 self.base_dn = ldb.domain_dn()
82 self.configuration_dn = ldb.get_config_basedn().get_linearized()
83 self.schema_dn = ldb.get_schema_basedn().get_linearized()
84 self.domain_sid = security.dom_sid(ldb.get_domain_sid())
86 delete_force(self.ldb, "cn=posixuser,cn=users," + self.base_dn)
87 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
88 delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
89 delete_force(self.ldb, "cn=ldaptestuser3,cn=users," + self.base_dn)
90 delete_force(self.ldb, "cn=ldaptestuser4,cn=ldaptestcontainer," + self.base_dn)
91 delete_force(self.ldb, "cn=ldaptestuser4,cn=ldaptestcontainer2," + self.base_dn)
92 delete_force(self.ldb, "cn=ldaptestuser5,cn=users," + self.base_dn)
93 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
94 delete_force(self.ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
95 delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
96 delete_force(self.ldb, "cn=ldaptest2computer,cn=computers," + self.base_dn)
97 delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
98 delete_force(self.ldb, "cn=ldaptestutf8user èùéìòà,cn=users," + self.base_dn)
99 delete_force(self.ldb, "cn=ldaptestutf8user2 èùéìòà,cn=users," + self.base_dn)
100 delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
101 delete_force(self.ldb, "cn=ldaptestcontainer2," + self.base_dn)
102 delete_force(self.ldb, "cn=parentguidtest,cn=users," + self.base_dn)
103 delete_force(self.ldb, "cn=parentguidtest,cn=testotherusers," + self.base_dn)
104 delete_force(self.ldb, "cn=testotherusers," + self.base_dn)
105 delete_force(self.ldb, "cn=ldaptestobject," + self.base_dn)
106 delete_force(self.ldb, "description=xyz,cn=users," + self.base_dn)
107 delete_force(self.ldb, "ou=testou,cn=users," + self.base_dn)
108 delete_force(self.ldb, "cn=Test Secret,cn=system," + self.base_dn)
109 delete_force(self.ldb, "cn=testtimevaluesuser1,cn=users," + self.base_dn)
111 def test_objectclasses(self):
112 """Test objectClass behaviour"""
113 # Invalid objectclass specified
114 try:
115 self.ldb.add({
116 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
117 "objectClass": [] })
118 self.fail()
119 except LdbError, (num, _):
120 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
122 # Invalid objectclass specified
123 try:
124 self.ldb.add({
125 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
126 "objectClass": "X" })
127 self.fail()
128 except LdbError, (num, _):
129 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
131 # Invalid objectCategory specified
132 try:
133 self.ldb.add({
134 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
135 "objectClass": "person",
136 "objectCategory": self.base_dn })
137 self.fail()
138 except LdbError, (num, _):
139 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
141 # Multi-valued "systemFlags"
142 try:
143 self.ldb.add({
144 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
145 "objectClass": "person",
146 "systemFlags": ["0", str(SYSTEM_FLAG_DOMAIN_DISALLOW_MOVE)] })
147 self.fail()
148 except LdbError, (num, _):
149 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
151 # We cannot instanciate from an abstract object class ("connectionPoint"
152 # or "leaf"). In the first case we use "connectionPoint" (subclass of
153 # "leaf") to prevent a naming violation - this returns us a
154 # "ERR_UNWILLING_TO_PERFORM" since it is not structural. In the second
155 # case however we get "ERR_OBJECT_CLASS_VIOLATION" since an abstract
156 # class is also not allowed to be auxiliary.
157 try:
158 self.ldb.add({
159 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
160 "objectClass": "connectionPoint" })
161 self.fail()
162 except LdbError, (num, _):
163 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
164 try:
165 self.ldb.add({
166 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
167 "objectClass": ["person", "leaf"] })
168 self.fail()
169 except LdbError, (num, _):
170 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
172 # Objects instanciated using "satisfied" abstract classes (concrete
173 # subclasses) are allowed
174 self.ldb.add({
175 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
176 "objectClass": ["top", "leaf", "connectionPoint", "serviceConnectionPoint"] })
178 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
180 # Two disjoint top-most structural object classes aren't allowed
181 try:
182 self.ldb.add({
183 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
184 "objectClass": ["person", "container"] })
185 self.fail()
186 except LdbError, (num, _):
187 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
189 # Test allowed system flags
190 self.ldb.add({
191 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
192 "objectClass": "person",
193 "systemFlags": str(~(SYSTEM_FLAG_CONFIG_ALLOW_RENAME | SYSTEM_FLAG_CONFIG_ALLOW_MOVE | SYSTEM_FLAG_CONFIG_ALLOW_LIMITED_MOVE)) })
195 res = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
196 scope=SCOPE_BASE, attrs=["systemFlags"])
197 self.assertTrue(len(res) == 1)
198 self.assertEquals(res[0]["systemFlags"][0], "0")
200 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
202 self.ldb.add({
203 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
204 "objectClass": "person" })
206 # We can remove derivation classes of the structural objectclass
207 # but they're going to be readded afterwards
208 m = Message()
209 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
210 m["objectClass"] = MessageElement("top", FLAG_MOD_DELETE,
211 "objectClass")
212 ldb.modify(m)
214 res = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
215 scope=SCOPE_BASE, attrs=["objectClass"])
216 self.assertTrue(len(res) == 1)
217 self.assertTrue("top" in res[0]["objectClass"])
219 # The top-most structural class cannot be deleted since there are
220 # attributes of it in use
221 m = Message()
222 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
223 m["objectClass"] = MessageElement("person", FLAG_MOD_DELETE,
224 "objectClass")
225 try:
226 ldb.modify(m)
227 self.fail()
228 except LdbError, (num, _):
229 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
231 # We cannot delete classes which weren't specified
232 m = Message()
233 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
234 m["objectClass"] = MessageElement("computer", FLAG_MOD_DELETE,
235 "objectClass")
236 try:
237 ldb.modify(m)
238 self.fail()
239 except LdbError, (num, _):
240 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
242 # An invalid class cannot be added
243 m = Message()
244 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
245 m["objectClass"] = MessageElement("X", FLAG_MOD_ADD,
246 "objectClass")
247 try:
248 ldb.modify(m)
249 self.fail()
250 except LdbError, (num, _):
251 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
253 # We cannot add a the new top-most structural class "user" here since
254 # we are missing at least one new mandatory attribute (in this case
255 # "sAMAccountName")
256 m = Message()
257 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
258 m["objectClass"] = MessageElement("user", FLAG_MOD_ADD,
259 "objectClass")
260 try:
261 ldb.modify(m)
262 self.fail()
263 except LdbError, (num, _):
264 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
266 # An already specified objectclass cannot be added another time
267 m = Message()
268 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
269 m["objectClass"] = MessageElement("person", FLAG_MOD_ADD,
270 "objectClass")
271 try:
272 ldb.modify(m)
273 self.fail()
274 except LdbError, (num, _):
275 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
277 # Auxiliary classes can always be added
278 m = Message()
279 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
280 m["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_ADD,
281 "objectClass")
282 ldb.modify(m)
284 # This does not work since object class "leaf" is not auxiliary nor it
285 # stands in direct relation to "person" (and it is abstract too!)
286 m = Message()
287 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
288 m["objectClass"] = MessageElement("leaf", FLAG_MOD_ADD,
289 "objectClass")
290 try:
291 ldb.modify(m)
292 self.fail()
293 except LdbError, (num, _):
294 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
296 # Objectclass replace operations can be performed as well
297 m = Message()
298 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
299 m["objectClass"] = MessageElement(["top", "person", "bootableDevice"],
300 FLAG_MOD_REPLACE, "objectClass")
301 ldb.modify(m)
303 m = Message()
304 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
305 m["objectClass"] = MessageElement(["person", "bootableDevice"],
306 FLAG_MOD_REPLACE, "objectClass")
307 ldb.modify(m)
309 # This does not work since object class "leaf" is not auxiliary nor it
310 # stands in direct relation to "person" (and it is abstract too!)
311 m = Message()
312 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
313 m["objectClass"] = MessageElement(["top", "person", "bootableDevice",
314 "leaf"], FLAG_MOD_REPLACE, "objectClass")
315 try:
316 ldb.modify(m)
317 self.fail()
318 except LdbError, (num, _):
319 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
321 # More than one change operation is allowed
322 m = Message()
323 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
324 m.add(MessageElement("bootableDevice", FLAG_MOD_DELETE, "objectClass"))
325 m.add(MessageElement("bootableDevice", FLAG_MOD_ADD, "objectClass"))
326 ldb.modify(m)
328 # We cannot remove all object classes by an empty replace
329 m = Message()
330 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
331 m["objectClass"] = MessageElement([], FLAG_MOD_REPLACE, "objectClass")
332 try:
333 ldb.modify(m)
334 self.fail()
335 except LdbError, (num, _):
336 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
338 m = Message()
339 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
340 m["objectClass"] = MessageElement(["top", "computer"], FLAG_MOD_REPLACE,
341 "objectClass")
342 try:
343 ldb.modify(m)
344 self.fail()
345 except LdbError, (num, _):
346 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
348 # Classes can be removed unless attributes of them are used.
349 m = Message()
350 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
351 m["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_DELETE,
352 "objectClass")
353 ldb.modify(m)
355 res = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
356 scope=SCOPE_BASE, attrs=["objectClass"])
357 self.assertTrue(len(res) == 1)
358 self.assertFalse("bootableDevice" in res[0]["objectClass"])
360 m = Message()
361 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
362 m["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_ADD,
363 "objectClass")
364 ldb.modify(m)
366 # Add an attribute specific to the "bootableDevice" class
367 m = Message()
368 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
369 m["bootParameter"] = MessageElement("test", FLAG_MOD_ADD,
370 "bootParameter")
371 ldb.modify(m)
373 # Classes can be removed unless attributes of them are used. Now there
374 # exist such attributes on the entry.
375 m = Message()
376 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
377 m["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_DELETE,
378 "objectClass")
379 try:
380 ldb.modify(m)
381 self.fail()
382 except LdbError, (num, _):
383 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
385 # Remove the previously specified attribute
386 m = Message()
387 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
388 m["bootParameter"] = MessageElement("test", FLAG_MOD_DELETE,
389 "bootParameter")
390 ldb.modify(m)
392 # Classes can be removed unless attributes of them are used.
393 m = Message()
394 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
395 m["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_DELETE,
396 "objectClass")
397 ldb.modify(m)
399 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
401 self.ldb.add({
402 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
403 "objectClass": "user" })
405 # Add a new top-most structural class "container". This does not work
406 # since it stands in no direct relation to the current one.
407 m = Message()
408 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
409 m["objectClass"] = MessageElement("container", FLAG_MOD_ADD,
410 "objectClass")
411 try:
412 ldb.modify(m)
413 self.fail()
414 except LdbError, (num, _):
415 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
417 # Add a new top-most structural class "inetOrgPerson" and remove it
418 # afterwards
419 m = Message()
420 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
421 m["objectClass"] = MessageElement("inetOrgPerson", FLAG_MOD_ADD,
422 "objectClass")
423 ldb.modify(m)
425 m = Message()
426 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
427 m["objectClass"] = MessageElement("inetOrgPerson", FLAG_MOD_DELETE,
428 "objectClass")
429 ldb.modify(m)
431 # Replace top-most structural class to "inetOrgPerson" and reset it
432 # back to "user"
433 m = Message()
434 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
435 m["objectClass"] = MessageElement("inetOrgPerson", FLAG_MOD_REPLACE,
436 "objectClass")
437 ldb.modify(m)
439 m = Message()
440 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
441 m["objectClass"] = MessageElement("user", FLAG_MOD_REPLACE,
442 "objectClass")
443 ldb.modify(m)
445 # Add a new auxiliary object class "posixAccount" to "ldaptestuser"
446 m = Message()
447 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
448 m["objectClass"] = MessageElement("posixAccount", FLAG_MOD_ADD,
449 "objectClass")
450 ldb.modify(m)
452 # Be sure that "top" is the first and the (most) structural object class
453 # the last value of the "objectClass" attribute - MS-ADTS 3.1.1.1.4
454 res = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
455 scope=SCOPE_BASE, attrs=["objectClass"])
456 self.assertTrue(len(res) == 1)
457 self.assertEquals(res[0]["objectClass"][0], "top")
458 self.assertEquals(res[0]["objectClass"][len(res[0]["objectClass"])-1], "user")
460 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
462 def test_system_only(self):
463 """Test systemOnly objects"""
464 try:
465 self.ldb.add({
466 "dn": "cn=ldaptestobject," + self.base_dn,
467 "objectclass": "configuration"})
468 self.fail()
469 except LdbError, (num, _):
470 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
472 try:
473 self.ldb.add({
474 "dn": "cn=Test Secret,cn=system," + self.base_dn,
475 "objectclass": "secret"})
476 self.fail()
477 except LdbError, (num, _):
478 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
480 delete_force(self.ldb, "cn=ldaptestobject," + self.base_dn)
481 delete_force(self.ldb, "cn=Test Secret,cn=system," + self.base_dn)
483 # Create secret over LSA and try to change it
485 lsa_conn = lsa.lsarpc("ncacn_np:%s" % args[0], lp, creds)
486 lsa_handle = lsa_conn.OpenPolicy2(system_name="\\",
487 attr=lsa.ObjectAttribute(),
488 access_mask=security.SEC_FLAG_MAXIMUM_ALLOWED)
489 secret_name = lsa.String()
490 secret_name.string = "G$Test"
491 sec_handle = lsa_conn.CreateSecret(handle=lsa_handle,
492 name=secret_name,
493 access_mask=security.SEC_FLAG_MAXIMUM_ALLOWED)
494 lsa_conn.Close(lsa_handle)
496 m = Message()
497 m.dn = Dn(ldb, "cn=Test Secret,cn=system," + self.base_dn)
498 m["description"] = MessageElement("desc", FLAG_MOD_REPLACE,
499 "description")
500 try:
501 ldb.modify(m)
502 self.fail()
503 except LdbError, (num, _):
504 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
506 delete_force(self.ldb, "cn=Test Secret,cn=system," + self.base_dn)
508 try:
509 self.ldb.add({
510 "dn": "cn=ldaptestcontainer," + self.base_dn,
511 "objectclass": "container",
512 "isCriticalSystemObject": "TRUE"})
513 self.fail()
514 except LdbError, (num, _):
515 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
517 self.ldb.add({
518 "dn": "cn=ldaptestcontainer," + self.base_dn,
519 "objectclass": "container"})
521 m = Message()
522 m.dn = Dn(ldb, "cn=ldaptestcontainer," + self.base_dn)
523 m["isCriticalSystemObject"] = MessageElement("TRUE", FLAG_MOD_REPLACE,
524 "isCriticalSystemObject")
525 try:
526 ldb.modify(m)
527 self.fail()
528 except LdbError, (num, _):
529 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
531 delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
533 # Proof if DC SAM object has "isCriticalSystemObject" set
534 res = self.ldb.search("", scope=SCOPE_BASE, attrs=["serverName"])
535 self.assertTrue(len(res) == 1)
536 self.assertTrue("serverName" in res[0])
537 res = self.ldb.search(res[0]["serverName"][0], scope=SCOPE_BASE,
538 attrs=["serverReference"])
539 self.assertTrue(len(res) == 1)
540 self.assertTrue("serverReference" in res[0])
541 res = self.ldb.search(res[0]["serverReference"][0], scope=SCOPE_BASE,
542 attrs=["isCriticalSystemObject"])
543 self.assertTrue(len(res) == 1)
544 self.assertTrue("isCriticalSystemObject" in res[0])
545 self.assertEquals(res[0]["isCriticalSystemObject"][0], "TRUE")
547 def test_invalid_parent(self):
548 """Test adding an object with invalid parent"""
549 try:
550 self.ldb.add({
551 "dn": "cn=ldaptestgroup,cn=thisdoesnotexist123,"
552 + self.base_dn,
553 "objectclass": "group"})
554 self.fail()
555 except LdbError, (num, _):
556 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
558 delete_force(self.ldb, "cn=ldaptestgroup,cn=thisdoesnotexist123,"
559 + self.base_dn)
561 try:
562 self.ldb.add({
563 "dn": "ou=testou,cn=users," + self.base_dn,
564 "objectclass": "organizationalUnit"})
565 self.fail()
566 except LdbError, (num, _):
567 self.assertEquals(num, ERR_NAMING_VIOLATION)
569 delete_force(self.ldb, "ou=testou,cn=users," + self.base_dn)
571 def test_invalid_attribute(self):
572 """Test invalid attributes on schema/objectclasses"""
573 # attributes not in schema test
575 # add operation
577 try:
578 self.ldb.add({
579 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
580 "objectclass": "group",
581 "thisdoesnotexist": "x"})
582 self.fail()
583 except LdbError, (num, _):
584 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
586 self.ldb.add({
587 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
588 "objectclass": "group"})
590 # modify operation
592 m = Message()
593 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
594 m["thisdoesnotexist"] = MessageElement("x", FLAG_MOD_REPLACE,
595 "thisdoesnotexist")
596 try:
597 ldb.modify(m)
598 self.fail()
599 except LdbError, (num, _):
600 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
602 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
604 # attributes not in objectclasses and mandatory attributes missing test
605 # Use here a non-SAM entry since it doesn't have special triggers
606 # associated which have an impact on the error results.
608 # add operations
610 # mandatory attribute missing
611 try:
612 self.ldb.add({
613 "dn": "cn=ldaptestobject," + self.base_dn,
614 "objectclass": "ipProtocol"})
615 self.fail()
616 except LdbError, (num, _):
617 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
619 # inadequate but schema-valid attribute specified
620 try:
621 self.ldb.add({
622 "dn": "cn=ldaptestobject," + self.base_dn,
623 "objectclass": "ipProtocol",
624 "ipProtocolNumber": "1",
625 "uid" : "0"})
626 self.fail()
627 except LdbError, (num, _):
628 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
630 self.ldb.add({
631 "dn": "cn=ldaptestobject," + self.base_dn,
632 "objectclass": "ipProtocol",
633 "ipProtocolNumber": "1"})
635 # modify operations
637 # inadequate but schema-valid attribute add trial
638 m = Message()
639 m.dn = Dn(ldb, "cn=ldaptestobject," + self.base_dn)
640 m["uid"] = MessageElement("0", FLAG_MOD_ADD, "uid")
641 try:
642 ldb.modify(m)
643 self.fail()
644 except LdbError, (num, _):
645 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
647 # mandatory attribute delete trial
648 m = Message()
649 m.dn = Dn(ldb, "cn=ldaptestobject," + self.base_dn)
650 m["ipProtocolNumber"] = MessageElement([], FLAG_MOD_DELETE,
651 "ipProtocolNumber")
652 try:
653 ldb.modify(m)
654 self.fail()
655 except LdbError, (num, _):
656 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
658 # mandatory attribute delete trial
659 m = Message()
660 m.dn = Dn(ldb, "cn=ldaptestobject," + self.base_dn)
661 m["ipProtocolNumber"] = MessageElement([], FLAG_MOD_REPLACE,
662 "ipProtocolNumber")
663 try:
664 ldb.modify(m)
665 self.fail()
666 except LdbError, (num, _):
667 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
669 delete_force(self.ldb, "cn=ldaptestobject," + self.base_dn)
671 def test_single_valued_attributes(self):
672 """Test single-valued attributes"""
673 try:
674 self.ldb.add({
675 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
676 "objectclass": "group",
677 "sAMAccountName": ["nam1", "nam2"]})
678 self.fail()
679 except LdbError, (num, _):
680 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
682 self.ldb.add({
683 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
684 "objectclass": "group"})
686 m = Message()
687 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
688 m["sAMAccountName"] = MessageElement(["nam1","nam2"], FLAG_MOD_REPLACE,
689 "sAMAccountName")
690 try:
691 ldb.modify(m)
692 self.fail()
693 except LdbError, (num, _):
694 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
696 m = Message()
697 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
698 m["sAMAccountName"] = MessageElement("testgroupXX", FLAG_MOD_REPLACE,
699 "sAMAccountName")
700 ldb.modify(m)
702 m = Message()
703 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
704 m["sAMAccountName"] = MessageElement("testgroupXX2", FLAG_MOD_ADD,
705 "sAMAccountName")
706 try:
707 ldb.modify(m)
708 self.fail()
709 except LdbError, (num, _):
710 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
712 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
714 def test_attribute_ranges(self):
715 """Test attribute ranges"""
716 # Too short (min. 1)
717 try:
718 ldb.add({
719 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
720 "objectClass": "person",
721 "sn": "" })
722 self.fail()
723 except LdbError, (num, _):
724 self.assertEquals(num, ERR_INVALID_ATTRIBUTE_SYNTAX)
726 # Too long (max. 64)
727 # try:
728 # ldb.add({
729 # "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
730 # "objectClass": "person",
731 # "sn": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" })
732 # self.fail()
733 # except LdbError, (num, _):
734 # self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
736 ldb.add({
737 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
738 "objectClass": "person" })
740 # Too short (min. 1)
741 m = Message()
742 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
743 m["sn"] = MessageElement("", FLAG_MOD_REPLACE, "sn")
744 try:
745 ldb.modify(m)
746 self.fail()
747 except LdbError, (num, _):
748 self.assertEquals(num, ERR_INVALID_ATTRIBUTE_SYNTAX)
750 # Too long (max. 64)
751 # m = Message()
752 # m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
753 # m["sn"] = MessageElement("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", FLAG_MOD_REPLACE, "sn")
754 # try:
755 # ldb.modify(m)
756 # self.fail()
757 # except LdbError, (num, _):
758 # self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
760 m = Message()
761 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
762 m["sn"] = MessageElement("x", FLAG_MOD_REPLACE, "sn")
763 ldb.modify(m)
765 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
767 def test_empty_messages(self):
768 """Test empty messages"""
769 m = Message()
770 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
772 try:
773 ldb.add(m)
774 self.fail()
775 except LdbError, (num, _):
776 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
778 try:
779 ldb.modify(m)
780 self.fail()
781 except LdbError, (num, _):
782 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
784 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
786 def test_empty_attributes(self):
787 """Test empty attributes"""
788 m = Message()
789 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
790 m["objectClass"] = MessageElement("group", FLAG_MOD_ADD, "objectClass")
791 m["description"] = MessageElement([], FLAG_MOD_ADD, "description")
793 try:
794 ldb.add(m)
795 self.fail()
796 except LdbError, (num, _):
797 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
799 self.ldb.add({
800 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
801 "objectclass": "group"})
803 m = Message()
804 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
805 m["description"] = MessageElement([], FLAG_MOD_ADD, "description")
807 try:
808 ldb.modify(m)
809 self.fail()
810 except LdbError, (num, _):
811 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
813 m = Message()
814 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
815 m["description"] = MessageElement([], FLAG_MOD_REPLACE, "description")
816 ldb.modify(m)
818 m = Message()
819 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
820 m["description"] = MessageElement([], FLAG_MOD_DELETE, "description")
821 try:
822 ldb.modify(m)
823 self.fail()
824 except LdbError, (num, _):
825 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
827 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
829 def test_instanceType(self):
830 """Tests the 'instanceType' attribute"""
831 # The instance type is single-valued
832 try:
833 self.ldb.add({
834 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
835 "objectclass": "group",
836 "instanceType": ["0", "1"]})
837 self.fail()
838 except LdbError, (num, _):
839 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
841 # The head NC flag cannot be set without the write flag
842 try:
843 self.ldb.add({
844 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
845 "objectclass": "group",
846 "instanceType": "1" })
847 self.fail()
848 except LdbError, (num, _):
849 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
851 # We cannot manipulate NCs without the head NC flag
852 try:
853 self.ldb.add({
854 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
855 "objectclass": "group",
856 "instanceType": "32" })
857 self.fail()
858 except LdbError, (num, _):
859 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
861 self.ldb.add({
862 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
863 "objectclass": "group"})
865 m = Message()
866 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
867 m["instanceType"] = MessageElement("0", FLAG_MOD_REPLACE,
868 "instanceType")
869 try:
870 ldb.modify(m)
871 self.fail()
872 except LdbError, (num, _):
873 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
875 m = Message()
876 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
877 m["instanceType"] = MessageElement([], FLAG_MOD_REPLACE,
878 "instanceType")
879 try:
880 ldb.modify(m)
881 self.fail()
882 except LdbError, (num, _):
883 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
885 m = Message()
886 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
887 m["instanceType"] = MessageElement([], FLAG_MOD_DELETE, "instanceType")
888 try:
889 ldb.modify(m)
890 self.fail()
891 except LdbError, (num, _):
892 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
894 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
896 #only write is allowed with NC_HEAD for originating updates
897 try:
898 self.ldb.add({
899 "dn": "cn=ldaptestuser2,cn=users," + self.base_dn,
900 "objectclass": "user",
901 "instanceType": "3" })
902 self.fail()
903 except LdbError, (num, _):
904 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
905 delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
907 def test_distinguished_name(self):
908 """Tests the 'distinguishedName' attribute"""
909 # The "dn" shortcut isn't supported
910 m = Message()
911 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
912 m["objectClass"] = MessageElement("group", 0, "objectClass")
913 m["dn"] = MessageElement("cn=ldaptestgroup,cn=users," + self.base_dn, 0,
914 "dn")
915 try:
916 ldb.add(m)
917 self.fail()
918 except LdbError, (num, _):
919 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
921 # a wrong "distinguishedName" attribute is obviously tolerated
922 self.ldb.add({
923 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
924 "objectclass": "group",
925 "distinguishedName": "cn=ldaptest,cn=users," + self.base_dn})
927 # proof if the DN has been set correctly
928 res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
929 scope=SCOPE_BASE, attrs=["distinguishedName"])
930 self.assertTrue(len(res) == 1)
931 self.assertTrue("distinguishedName" in res[0])
932 self.assertTrue(Dn(ldb, res[0]["distinguishedName"][0])
933 == Dn(ldb, "cn=ldaptestgroup, cn=users," + self.base_dn))
935 # The "dn" shortcut isn't supported
936 m = Message()
937 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
938 m["dn"] = MessageElement(
939 "cn=ldaptestgroup,cn=users," + self.base_dn, FLAG_MOD_REPLACE,
940 "dn")
941 try:
942 ldb.modify(m)
943 self.fail()
944 except LdbError, (num, _):
945 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
947 m = Message()
948 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
949 m["distinguishedName"] = MessageElement(
950 "cn=ldaptestuser,cn=users," + self.base_dn, FLAG_MOD_ADD,
951 "distinguishedName")
953 try:
954 ldb.modify(m)
955 self.fail()
956 except LdbError, (num, _):
957 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
959 m = Message()
960 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
961 m["distinguishedName"] = MessageElement(
962 "cn=ldaptestuser,cn=users," + self.base_dn, FLAG_MOD_REPLACE,
963 "distinguishedName")
965 try:
966 ldb.modify(m)
967 self.fail()
968 except LdbError, (num, _):
969 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
971 m = Message()
972 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
973 m["distinguishedName"] = MessageElement(
974 "cn=ldaptestuser,cn=users," + self.base_dn, FLAG_MOD_DELETE,
975 "distinguishedName")
977 try:
978 ldb.modify(m)
979 self.fail()
980 except LdbError, (num, _):
981 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
983 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
985 def test_rdn_name(self):
986 """Tests the RDN"""
987 # Search
989 # empty RDN
990 try:
991 self.ldb.search("=,cn=users," + self.base_dn, scope=SCOPE_BASE)
992 self.fail()
993 except LdbError, (num, _):
994 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
996 # empty RDN name
997 try:
998 self.ldb.search("cn=,cn=users," + self.base_dn, scope=SCOPE_BASE)
999 self.fail()
1000 except LdbError, (num, _):
1001 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1003 try:
1004 self.ldb.search("=ldaptestgroup,cn=users," + self.base_dn, scope=SCOPE_BASE)
1005 self.fail()
1006 except LdbError, (num, _):
1007 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1009 # Add
1011 # empty RDN
1012 try:
1013 self.ldb.add({
1014 "dn": "=,cn=users," + self.base_dn,
1015 "objectclass": "group"})
1016 self.fail()
1017 except LdbError, (num, _):
1018 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1020 # empty RDN name
1021 try:
1022 self.ldb.add({
1023 "dn": "=ldaptestgroup,cn=users," + self.base_dn,
1024 "objectclass": "group"})
1025 self.fail()
1026 except LdbError, (num, _):
1027 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1029 # empty RDN value
1030 try:
1031 self.ldb.add({
1032 "dn": "cn=,cn=users," + self.base_dn,
1033 "objectclass": "group"})
1034 self.fail()
1035 except LdbError, (num, _):
1036 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1038 # a wrong RDN candidate
1039 try:
1040 self.ldb.add({
1041 "dn": "description=xyz,cn=users," + self.base_dn,
1042 "objectclass": "group"})
1043 self.fail()
1044 except LdbError, (num, _):
1045 self.assertEquals(num, ERR_NAMING_VIOLATION)
1047 delete_force(self.ldb, "description=xyz,cn=users," + self.base_dn)
1049 # a wrong "name" attribute is obviously tolerated
1050 self.ldb.add({
1051 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
1052 "objectclass": "group",
1053 "name": "ldaptestgroupx"})
1055 # proof if the name has been set correctly
1056 res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
1057 scope=SCOPE_BASE, attrs=["name"])
1058 self.assertTrue(len(res) == 1)
1059 self.assertTrue("name" in res[0])
1060 self.assertTrue(res[0]["name"][0] == "ldaptestgroup")
1062 # Modify
1064 # empty RDN value
1065 m = Message()
1066 m.dn = Dn(ldb, "cn=,cn=users," + self.base_dn)
1067 m["description"] = "test"
1068 try:
1069 self.ldb.modify(m)
1070 self.fail()
1071 except LdbError, (num, _):
1072 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1074 # Delete
1076 # empty RDN value
1077 try:
1078 self.ldb.delete("cn=,cn=users," + self.base_dn)
1079 self.fail()
1080 except LdbError, (num, _):
1081 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1083 # Rename
1085 # new empty RDN
1086 try:
1087 self.ldb.rename("cn=ldaptestgroup,cn=users," + self.base_dn,
1088 "=,cn=users," + self.base_dn)
1089 self.fail()
1090 except LdbError, (num, _):
1091 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1093 # new empty RDN name
1094 try:
1095 self.ldb.rename("cn=ldaptestgroup,cn=users," + self.base_dn,
1096 "=ldaptestgroup,cn=users," + self.base_dn)
1097 self.fail()
1098 except LdbError, (num, _):
1099 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1101 # new empty RDN value
1102 try:
1103 self.ldb.rename("cn=ldaptestgroup,cn=users," + self.base_dn,
1104 "cn=,cn=users," + self.base_dn)
1105 self.fail()
1106 except LdbError, (num, _):
1107 self.assertEquals(num, ERR_NAMING_VIOLATION)
1109 # new wrong RDN candidate
1110 try:
1111 self.ldb.rename("cn=ldaptestgroup,cn=users," + self.base_dn,
1112 "description=xyz,cn=users," + self.base_dn)
1113 self.fail()
1114 except LdbError, (num, _):
1115 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1117 delete_force(self.ldb, "description=xyz,cn=users," + self.base_dn)
1119 # old empty RDN value
1120 try:
1121 self.ldb.rename("cn=,cn=users," + self.base_dn,
1122 "cn=ldaptestgroup,cn=users," + self.base_dn)
1123 self.fail()
1124 except LdbError, (num, _):
1125 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1127 # names
1129 m = Message()
1130 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1131 m["name"] = MessageElement("cn=ldaptestuser", FLAG_MOD_REPLACE,
1132 "name")
1133 try:
1134 ldb.modify(m)
1135 self.fail()
1136 except LdbError, (num, _):
1137 self.assertEquals(num, ERR_NOT_ALLOWED_ON_RDN)
1139 m = Message()
1140 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1141 m["cn"] = MessageElement("ldaptestuser",
1142 FLAG_MOD_REPLACE, "cn")
1143 try:
1144 ldb.modify(m)
1145 self.fail()
1146 except LdbError, (num, _):
1147 self.assertEquals(num, ERR_NOT_ALLOWED_ON_RDN)
1149 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1152 # this test needs to be disabled until we really understand
1153 # what the rDN length constraints are
1154 def DISABLED_test_largeRDN(self):
1155 """Testing large rDN (limit 64 characters)"""
1156 rdn = "CN=a012345678901234567890123456789012345678901234567890123456789012"
1157 delete_force(self.ldb, "%s,%s" % (rdn, self.base_dn))
1158 ldif = """
1159 dn: %s,%s""" % (rdn,self.base_dn) + """
1160 objectClass: container
1162 self.ldb.add_ldif(ldif)
1163 delete_force(self.ldb, "%s,%s" % (rdn, self.base_dn))
1165 rdn = "CN=a0123456789012345678901234567890123456789012345678901234567890120"
1166 delete_force(self.ldb, "%s,%s" % (rdn, self.base_dn))
1167 try:
1168 ldif = """
1169 dn: %s,%s""" % (rdn,self.base_dn) + """
1170 objectClass: container
1172 self.ldb.add_ldif(ldif)
1173 self.fail()
1174 except LdbError, (num, _):
1175 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
1176 delete_force(self.ldb, "%s,%s" % (rdn, self.base_dn))
1178 def test_rename(self):
1179 """Tests the rename operation"""
1180 try:
1181 # cannot rename to be a child of itself
1182 ldb.rename(self.base_dn, "dc=test," + self.base_dn)
1183 self.fail()
1184 except LdbError, (num, _):
1185 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1187 try:
1188 # inexistent object
1189 ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser2,cn=users," + self.base_dn)
1190 self.fail()
1191 except LdbError, (num, _):
1192 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
1194 self.ldb.add({
1195 "dn": "cn=ldaptestuser2,cn=users," + self.base_dn,
1196 "objectclass": "user" })
1198 ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser2,cn=users," + self.base_dn)
1199 ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=users," + self.base_dn)
1200 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestUSER3,cn=users," + self.base_dn)
1202 try:
1203 # containment problem: a user entry cannot contain user entries
1204 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser4,cn=ldaptestuser3,cn=users," + self.base_dn)
1205 self.fail()
1206 except LdbError, (num, _):
1207 self.assertEquals(num, ERR_NAMING_VIOLATION)
1209 try:
1210 # invalid parent
1211 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=people,cn=users," + self.base_dn)
1212 self.fail()
1213 except LdbError, (num, _):
1214 self.assertEquals(num, ERR_OTHER)
1216 try:
1217 # invalid target DN syntax
1218 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, ",cn=users," + self.base_dn)
1219 self.fail()
1220 except LdbError, (num, _):
1221 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1223 try:
1224 # invalid RDN name
1225 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "ou=ldaptestuser3,cn=users," + self.base_dn)
1226 self.fail()
1227 except LdbError, (num, _):
1228 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1230 delete_force(self.ldb, "cn=ldaptestuser3,cn=users," + self.base_dn)
1232 # Performs some "systemFlags" testing
1234 # Move failing since no "SYSTEM_FLAG_CONFIG_ALLOW_MOVE"
1235 try:
1236 ldb.rename("CN=DisplaySpecifiers," + self.configuration_dn, "CN=DisplaySpecifiers,CN=Services," + self.configuration_dn)
1237 self.fail()
1238 except LdbError, (num, _):
1239 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1241 # Limited move failing since no "SYSTEM_FLAG_CONFIG_ALLOW_LIMITED_MOVE"
1242 try:
1243 ldb.rename("CN=Directory Service,CN=Windows NT,CN=Services," + self.configuration_dn, "CN=Directory Service,CN=RRAS,CN=Services," + self.configuration_dn)
1244 self.fail()
1245 except LdbError, (num, _):
1246 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1248 # Rename failing since no "SYSTEM_FLAG_CONFIG_ALLOW_RENAME"
1249 try:
1250 ldb.rename("CN=DisplaySpecifiers," + self.configuration_dn, "CN=DisplaySpecifiers2," + self.configuration_dn)
1251 self.fail()
1252 except LdbError, (num, _):
1253 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1255 # It's not really possible to test moves on the schema partition since
1256 # there don't exist subcontainers on it.
1258 # Rename failing since "SYSTEM_FLAG_SCHEMA_BASE_OBJECT"
1259 try:
1260 ldb.rename("CN=Top," + self.schema_dn, "CN=Top2," + self.schema_dn)
1261 self.fail()
1262 except LdbError, (num, _):
1263 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1265 # Move failing since "SYSTEM_FLAG_DOMAIN_DISALLOW_MOVE"
1266 try:
1267 ldb.rename("CN=Users," + self.base_dn, "CN=Users,CN=Computers," + self.base_dn)
1268 self.fail()
1269 except LdbError, (num, _):
1270 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1272 # Rename failing since "SYSTEM_FLAG_DOMAIN_DISALLOW_RENAME"
1273 try:
1274 ldb.rename("CN=Users," + self.base_dn, "CN=Users2," + self.base_dn)
1275 self.fail()
1276 except LdbError, (num, _):
1277 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1279 # Performs some other constraints testing
1281 try:
1282 ldb.rename("CN=Policies,CN=System," + self.base_dn, "CN=Users2," + self.base_dn)
1283 self.fail()
1284 except LdbError, (num, _):
1285 self.assertEquals(num, ERR_OTHER)
1287 def test_rename_twice(self):
1288 """Tests the rename operation twice - this corresponds to a past bug"""
1289 self.ldb.add({
1290 "dn": "cn=ldaptestuser5,cn=users," + self.base_dn,
1291 "objectclass": "user" })
1293 ldb.rename("cn=ldaptestuser5,cn=users," + self.base_dn, "cn=ldaptestUSER5,cn=users," + self.base_dn)
1294 delete_force(self.ldb, "cn=ldaptestuser5,cn=users," + self.base_dn)
1295 self.ldb.add({
1296 "dn": "cn=ldaptestuser5,cn=users," + self.base_dn,
1297 "objectclass": "user" })
1298 ldb.rename("cn=ldaptestuser5,cn=Users," + self.base_dn, "cn=ldaptestUSER5,cn=users," + self.base_dn)
1299 res = ldb.search(expression="cn=ldaptestuser5")
1300 self.assertEquals(len(res), 1, "Wrong number of hits for cn=ldaptestuser5")
1301 res = ldb.search(expression="(&(cn=ldaptestuser5)(objectclass=user))")
1302 self.assertEquals(len(res), 1, "Wrong number of hits for (&(cn=ldaptestuser5)(objectclass=user))")
1303 delete_force(self.ldb, "cn=ldaptestuser5,cn=users," + self.base_dn)
1305 def test_objectGUID(self):
1306 """Test objectGUID behaviour"""
1307 # The objectGUID cannot directly be set
1308 try:
1309 self.ldb.add_ldif("""
1310 dn: cn=ldaptestcontainer,""" + self.base_dn + """
1311 objectClass: container
1312 objectGUID: bd3480c9-58af-4cd8-92df-bc4a18b6e44d
1313 """)
1314 self.fail()
1315 except LdbError, (num, _):
1316 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1318 self.ldb.add({
1319 "dn": "cn=ldaptestcontainer," + self.base_dn,
1320 "objectClass": "container" })
1322 # The objectGUID cannot directly be changed
1323 try:
1324 self.ldb.modify_ldif("""
1325 dn: cn=ldaptestcontainer,""" + self.base_dn + """
1326 changetype: modify
1327 replace: objectGUID
1328 objectGUID: bd3480c9-58af-4cd8-92df-bc4a18b6e44d
1329 """)
1330 self.fail()
1331 except LdbError, (num, _):
1332 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
1334 delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
1336 def test_parentGUID(self):
1337 """Test parentGUID behaviour"""
1338 self.ldb.add({
1339 "dn": "cn=parentguidtest,cn=users," + self.base_dn,
1340 "objectclass":"user",
1341 "samaccountname":"parentguidtest"})
1342 res1 = ldb.search(base="cn=parentguidtest,cn=users," + self.base_dn, scope=SCOPE_BASE,
1343 attrs=["parentGUID", "samaccountname"])
1344 res2 = ldb.search(base="cn=users," + self.base_dn,scope=SCOPE_BASE,
1345 attrs=["objectGUID"])
1346 res3 = ldb.search(base=self.base_dn, scope=SCOPE_BASE,
1347 attrs=["parentGUID"])
1348 res4 = ldb.search(base=self.configuration_dn, scope=SCOPE_BASE,
1349 attrs=["parentGUID"])
1350 res5 = ldb.search(base=self.schema_dn, scope=SCOPE_BASE,
1351 attrs=["parentGUID"])
1353 """Check if the parentGUID is valid """
1354 self.assertEquals(res1[0]["parentGUID"], res2[0]["objectGUID"])
1356 """Check if it returns nothing when there is no parent object - default NC"""
1357 has_parentGUID = False
1358 for key in res3[0].keys():
1359 if key == "parentGUID":
1360 has_parentGUID = True
1361 break
1362 self.assertFalse(has_parentGUID)
1364 """Check if it returns nothing when there is no parent object - configuration NC"""
1365 has_parentGUID = False
1366 for key in res4[0].keys():
1367 if key == "parentGUID":
1368 has_parentGUID = True
1369 break
1370 self.assertFalse(has_parentGUID)
1372 """Check if it returns nothing when there is no parent object - schema NC"""
1373 has_parentGUID = False
1374 for key in res5[0].keys():
1375 if key == "parentGUID":
1376 has_parentGUID = True
1377 break
1378 self.assertFalse(has_parentGUID)
1380 """Ensures that if you look for another object attribute after the constructed
1381 parentGUID, it will return correctly"""
1382 has_another_attribute = False
1383 for key in res1[0].keys():
1384 if key == "sAMAccountName":
1385 has_another_attribute = True
1386 break
1387 self.assertTrue(has_another_attribute)
1388 self.assertTrue(len(res1[0]["samaccountname"]) == 1)
1389 self.assertEquals(res1[0]["samaccountname"][0], "parentguidtest")
1391 # Testing parentGUID behaviour on rename\
1393 self.ldb.add({
1394 "dn": "cn=testotherusers," + self.base_dn,
1395 "objectclass":"container"})
1396 res1 = ldb.search(base="cn=testotherusers," + self.base_dn,scope=SCOPE_BASE,
1397 attrs=["objectGUID"])
1398 ldb.rename("cn=parentguidtest,cn=users," + self.base_dn,
1399 "cn=parentguidtest,cn=testotherusers," + self.base_dn)
1400 res2 = ldb.search(base="cn=parentguidtest,cn=testotherusers," + self.base_dn,
1401 scope=SCOPE_BASE,
1402 attrs=["parentGUID"])
1403 self.assertEquals(res1[0]["objectGUID"], res2[0]["parentGUID"])
1405 delete_force(self.ldb, "cn=parentguidtest,cn=testotherusers," + self.base_dn)
1406 delete_force(self.ldb, "cn=testotherusers," + self.base_dn)
1408 def test_usnChanged(self):
1409 """Test usnChanged behaviour"""
1411 self.ldb.add({
1412 "dn": "cn=ldaptestcontainer," + self.base_dn,
1413 "objectClass": "container" })
1415 res = ldb.search("cn=ldaptestcontainer," + self.base_dn,
1416 scope=SCOPE_BASE,
1417 attrs=["objectGUID", "uSNCreated", "uSNChanged", "whenCreated", "whenChanged", "description"])
1418 self.assertTrue(len(res) == 1)
1419 self.assertFalse("description" in res[0])
1420 self.assertTrue("objectGUID" in res[0])
1421 self.assertTrue("uSNCreated" in res[0])
1422 self.assertTrue("uSNChanged" in res[0])
1423 self.assertTrue("whenCreated" in res[0])
1424 self.assertTrue("whenChanged" in res[0])
1426 delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
1428 # All this attributes are specificable on add operations
1429 self.ldb.add({
1430 "dn": "cn=ldaptestcontainer," + self.base_dn,
1431 "objectclass": "container",
1432 "uSNCreated" : "1",
1433 "uSNChanged" : "1",
1434 "whenCreated": timestring(long(time.time())),
1435 "whenChanged": timestring(long(time.time())) })
1437 res = ldb.search("cn=ldaptestcontainer," + self.base_dn,
1438 scope=SCOPE_BASE,
1439 attrs=["objectGUID", "uSNCreated", "uSNChanged", "whenCreated", "whenChanged", "description"])
1440 self.assertTrue(len(res) == 1)
1441 self.assertFalse("description" in res[0])
1442 self.assertTrue("objectGUID" in res[0])
1443 self.assertTrue("uSNCreated" in res[0])
1444 self.assertFalse(res[0]["uSNCreated"][0] == "1") # these are corrected
1445 self.assertTrue("uSNChanged" in res[0])
1446 self.assertFalse(res[0]["uSNChanged"][0] == "1") # these are corrected
1447 self.assertTrue("whenCreated" in res[0])
1448 self.assertTrue("whenChanged" in res[0])
1450 ldb.modify_ldif("""
1451 dn: cn=ldaptestcontainer,""" + self.base_dn + """
1452 changetype: modify
1453 replace: description
1454 """)
1456 res2 = ldb.search("cn=ldaptestcontainer," + self.base_dn,
1457 scope=SCOPE_BASE,
1458 attrs=["uSNCreated", "uSNChanged", "description"])
1459 self.assertTrue(len(res) == 1)
1460 self.assertFalse("description" in res2[0])
1461 self.assertEqual(res[0]["usnCreated"], res2[0]["usnCreated"])
1462 self.assertEqual(res[0]["usnCreated"], res2[0]["usnChanged"])
1463 self.assertEqual(res[0]["usnChanged"], res2[0]["usnChanged"])
1465 ldb.modify_ldif("""
1466 dn: cn=ldaptestcontainer,""" + self.base_dn + """
1467 changetype: modify
1468 replace: description
1469 description: test
1470 """)
1472 res3 = ldb.search("cn=ldaptestcontainer," + self.base_dn,
1473 scope=SCOPE_BASE,
1474 attrs=["uSNCreated", "uSNChanged", "description"])
1475 self.assertTrue(len(res) == 1)
1476 self.assertTrue("description" in res3[0])
1477 self.assertEqual("test", str(res3[0]["description"][0]))
1478 self.assertEqual(res[0]["usnCreated"], res3[0]["usnCreated"])
1479 self.assertNotEqual(res[0]["usnCreated"], res3[0]["usnChanged"])
1480 self.assertNotEqual(res[0]["usnChanged"], res3[0]["usnChanged"])
1482 ldb.modify_ldif("""
1483 dn: cn=ldaptestcontainer,""" + self.base_dn + """
1484 changetype: modify
1485 replace: description
1486 description: test
1487 """)
1489 res4 = ldb.search("cn=ldaptestcontainer," + self.base_dn,
1490 scope=SCOPE_BASE,
1491 attrs=["uSNCreated", "uSNChanged", "description"])
1492 self.assertTrue(len(res) == 1)
1493 self.assertTrue("description" in res4[0])
1494 self.assertEqual("test", str(res4[0]["description"][0]))
1495 self.assertEqual(res[0]["usnCreated"], res4[0]["usnCreated"])
1496 self.assertNotEqual(res3[0]["usnCreated"], res4[0]["usnChanged"])
1497 self.assertEqual(res3[0]["usnChanged"], res4[0]["usnChanged"])
1499 ldb.modify_ldif("""
1500 dn: cn=ldaptestcontainer,""" + self.base_dn + """
1501 changetype: modify
1502 replace: description
1503 description: test2
1504 """)
1506 res5 = ldb.search("cn=ldaptestcontainer," + self.base_dn,
1507 scope=SCOPE_BASE,
1508 attrs=["uSNCreated", "uSNChanged", "description"])
1509 self.assertTrue(len(res) == 1)
1510 self.assertTrue("description" in res5[0])
1511 self.assertEqual("test2", str(res5[0]["description"][0]))
1512 self.assertEqual(res[0]["usnCreated"], res5[0]["usnCreated"])
1513 self.assertNotEqual(res3[0]["usnChanged"], res5[0]["usnChanged"])
1515 ldb.modify_ldif("""
1516 dn: cn=ldaptestcontainer,""" + self.base_dn + """
1517 changetype: modify
1518 delete: description
1519 description: test2
1520 """)
1522 res6 = ldb.search("cn=ldaptestcontainer," + self.base_dn,
1523 scope=SCOPE_BASE,
1524 attrs=["uSNCreated", "uSNChanged", "description"])
1525 self.assertTrue(len(res) == 1)
1526 self.assertFalse("description" in res6[0])
1527 self.assertEqual(res[0]["usnCreated"], res6[0]["usnCreated"])
1528 self.assertNotEqual(res5[0]["usnChanged"], res6[0]["usnChanged"])
1530 ldb.modify_ldif("""
1531 dn: cn=ldaptestcontainer,""" + self.base_dn + """
1532 changetype: modify
1533 add: description
1534 description: test3
1535 """)
1537 res7 = ldb.search("cn=ldaptestcontainer," + self.base_dn,
1538 scope=SCOPE_BASE,
1539 attrs=["uSNCreated", "uSNChanged", "description"])
1540 self.assertTrue(len(res) == 1)
1541 self.assertTrue("description" in res7[0])
1542 self.assertEqual("test3", str(res7[0]["description"][0]))
1543 self.assertEqual(res[0]["usnCreated"], res7[0]["usnCreated"])
1544 self.assertNotEqual(res6[0]["usnChanged"], res7[0]["usnChanged"])
1546 ldb.modify_ldif("""
1547 dn: cn=ldaptestcontainer,""" + self.base_dn + """
1548 changetype: modify
1549 delete: description
1550 """)
1552 res8 = ldb.search("cn=ldaptestcontainer," + self.base_dn,
1553 scope=SCOPE_BASE,
1554 attrs=["uSNCreated", "uSNChanged", "description"])
1555 self.assertTrue(len(res) == 1)
1556 self.assertFalse("description" in res8[0])
1557 self.assertEqual(res[0]["usnCreated"], res8[0]["usnCreated"])
1558 self.assertNotEqual(res7[0]["usnChanged"], res8[0]["usnChanged"])
1560 delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
1562 def test_groupType_int32(self):
1563 """Test groupType (int32) behaviour (should appear to be casted to a 32 bit signed integer before comparsion)"""
1565 res1 = ldb.search(base=self.base_dn, scope=SCOPE_SUBTREE,
1566 attrs=["groupType"], expression="groupType=2147483653")
1568 res2 = ldb.search(base=self.base_dn, scope=SCOPE_SUBTREE,
1569 attrs=["groupType"], expression="groupType=-2147483643")
1571 self.assertEquals(len(res1), len(res2))
1573 self.assertTrue(res1.count > 0)
1575 self.assertEquals(res1[0]["groupType"][0], "-2147483643")
1577 def test_linked_attributes(self):
1578 """This tests the linked attribute behaviour"""
1580 ldb.add({
1581 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
1582 "objectclass": "group"})
1584 # This should not work since "memberOf" is linked to "member"
1585 try:
1586 ldb.add({
1587 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1588 "objectclass": "user",
1589 "memberOf": "cn=ldaptestgroup,cn=users," + self.base_dn})
1590 except LdbError, (num, _):
1591 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1593 ldb.add({
1594 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1595 "objectclass": "user"})
1597 m = Message()
1598 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1599 m["memberOf"] = MessageElement("cn=ldaptestgroup,cn=users," + self.base_dn,
1600 FLAG_MOD_ADD, "memberOf")
1601 try:
1602 ldb.modify(m)
1603 self.fail()
1604 except LdbError, (num, _):
1605 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1607 m = Message()
1608 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1609 m["member"] = MessageElement("cn=ldaptestuser,cn=users," + self.base_dn,
1610 FLAG_MOD_ADD, "member")
1611 ldb.modify(m)
1613 m = Message()
1614 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1615 m["memberOf"] = MessageElement("cn=ldaptestgroup,cn=users," + self.base_dn,
1616 FLAG_MOD_REPLACE, "memberOf")
1617 try:
1618 ldb.modify(m)
1619 self.fail()
1620 except LdbError, (num, _):
1621 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1623 m = Message()
1624 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1625 m["memberOf"] = MessageElement("cn=ldaptestgroup,cn=users," + self.base_dn,
1626 FLAG_MOD_DELETE, "memberOf")
1627 try:
1628 ldb.modify(m)
1629 self.fail()
1630 except LdbError, (num, _):
1631 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1633 m = Message()
1634 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1635 m["member"] = MessageElement("cn=ldaptestuser,cn=users," + self.base_dn,
1636 FLAG_MOD_DELETE, "member")
1637 ldb.modify(m)
1639 # This should yield no results since the member attribute for
1640 # "ldaptestuser" should have been deleted
1641 res1 = ldb.search("cn=ldaptestgroup, cn=users," + self.base_dn,
1642 scope=SCOPE_BASE,
1643 expression="(member=cn=ldaptestuser,cn=users," + self.base_dn + ")",
1644 attrs=[])
1645 self.assertTrue(len(res1) == 0)
1647 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1649 ldb.add({
1650 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
1651 "objectclass": "group",
1652 "member": "cn=ldaptestuser,cn=users," + self.base_dn})
1654 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1656 # Make sure that the "member" attribute for "ldaptestuser" has been
1657 # removed
1658 res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
1659 scope=SCOPE_BASE, attrs=["member"])
1660 self.assertTrue(len(res) == 1)
1661 self.assertFalse("member" in res[0])
1663 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1665 def test_wkguid(self):
1666 """Test Well known GUID behaviours (including DN+Binary)"""
1668 res = self.ldb.search(base=("<WKGUID=ab1d30f3768811d1aded00c04fd8d5cd,%s>" % self.base_dn), scope=SCOPE_BASE, attrs=[])
1669 self.assertEquals(len(res), 1)
1671 res2 = self.ldb.search(scope=SCOPE_BASE, attrs=["wellKnownObjects"], expression=("wellKnownObjects=B:32:ab1d30f3768811d1aded00c04fd8d5cd:%s" % res[0].dn))
1672 self.assertEquals(len(res2), 1)
1674 # Prove that the matching rule is over the whole DN+Binary
1675 res2 = self.ldb.search(scope=SCOPE_BASE, attrs=["wellKnownObjects"], expression=("wellKnownObjects=B:32:ab1d30f3768811d1aded00c04fd8d5cd"))
1676 self.assertEquals(len(res2), 0)
1677 # Prove that the matching rule is over the whole DN+Binary
1678 res2 = self.ldb.search(scope=SCOPE_BASE, attrs=["wellKnownObjects"], expression=("wellKnownObjects=%s") % res[0].dn)
1679 self.assertEquals(len(res2), 0)
1681 def test_subschemasubentry(self):
1682 """Test subSchemaSubEntry appears when requested, but not when not requested"""
1684 res = self.ldb.search(base=self.base_dn, scope=SCOPE_BASE, attrs=["subSchemaSubEntry"])
1685 self.assertEquals(len(res), 1)
1686 self.assertEquals(res[0]["subSchemaSubEntry"][0], "CN=Aggregate,"+self.schema_dn)
1688 res = self.ldb.search(base=self.base_dn, scope=SCOPE_BASE, attrs=["*"])
1689 self.assertEquals(len(res), 1)
1690 self.assertTrue("subScheamSubEntry" not in res[0])
1692 def test_all(self):
1693 """Basic tests"""
1695 # Testing user add
1697 ldb.add({
1698 "dn": "cn=ldaptestuser,cn=uSers," + self.base_dn,
1699 "objectclass": "user",
1700 "cN": "LDAPtestUSER",
1701 "givenname": "ldap",
1702 "sn": "testy"})
1704 ldb.add({
1705 "dn": "cn=ldaptestgroup,cn=uSers," + self.base_dn,
1706 "objectclass": "group",
1707 "member": "cn=ldaptestuser,cn=useRs," + self.base_dn})
1709 ldb.add({
1710 "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
1711 "objectclass": "computer",
1712 "cN": "LDAPtestCOMPUTER"})
1714 ldb.add({"dn": "cn=ldaptest2computer,cn=computers," + self.base_dn,
1715 "objectClass": "computer",
1716 "cn": "LDAPtest2COMPUTER",
1717 "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT),
1718 "displayname": "ldap testy"})
1720 try:
1721 ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn,
1722 "objectClass": "computer",
1723 "cn": "LDAPtest2COMPUTER"
1725 self.fail()
1726 except LdbError, (num, _):
1727 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1729 try:
1730 ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn,
1731 "objectClass": "computer",
1732 "cn": "ldaptestcomputer3",
1733 "sAMAccountType": str(ATYPE_NORMAL_ACCOUNT)
1735 self.fail()
1736 except LdbError, (num, _):
1737 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1739 ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn,
1740 "objectClass": "computer",
1741 "cn": "LDAPtestCOMPUTER3"
1744 # Testing ldb.search for (&(cn=ldaptestcomputer3)(objectClass=user))
1745 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestcomputer3)(objectClass=user))")
1746 self.assertEquals(len(res), 1, "Found only %d for (&(cn=ldaptestcomputer3)(objectClass=user))" % len(res))
1748 self.assertEquals(str(res[0].dn), ("CN=ldaptestcomputer3,CN=Computers," + self.base_dn))
1749 self.assertEquals(res[0]["cn"][0], "ldaptestcomputer3")
1750 self.assertEquals(res[0]["name"][0], "ldaptestcomputer3")
1751 self.assertEquals(res[0]["objectClass"][0], "top")
1752 self.assertEquals(res[0]["objectClass"][1], "person")
1753 self.assertEquals(res[0]["objectClass"][2], "organizationalPerson")
1754 self.assertEquals(res[0]["objectClass"][3], "user")
1755 self.assertEquals(res[0]["objectClass"][4], "computer")
1756 self.assertTrue("objectGUID" in res[0])
1757 self.assertTrue("whenCreated" in res[0])
1758 self.assertEquals(res[0]["objectCategory"][0], ("CN=Computer,%s" % ldb.get_schema_basedn()))
1759 self.assertEquals(int(res[0]["primaryGroupID"][0]), 513)
1760 self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_NORMAL_ACCOUNT)
1761 self.assertEquals(int(res[0]["userAccountControl"][0]), UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE)
1763 delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
1765 # Testing attribute or value exists behaviour
1766 try:
1767 ldb.modify_ldif("""
1768 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1769 changetype: modify
1770 replace: servicePrincipalName
1771 servicePrincipalName: host/ldaptest2computer
1772 servicePrincipalName: host/ldaptest2computer
1773 servicePrincipalName: cifs/ldaptest2computer
1774 """)
1775 self.fail()
1776 except LdbError, (num, msg):
1777 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
1779 ldb.modify_ldif("""
1780 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1781 changetype: modify
1782 replace: servicePrincipalName
1783 servicePrincipalName: host/ldaptest2computer
1784 servicePrincipalName: cifs/ldaptest2computer
1785 """)
1786 try:
1787 ldb.modify_ldif("""
1788 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1789 changetype: modify
1790 add: servicePrincipalName
1791 servicePrincipalName: host/ldaptest2computer
1792 """)
1793 self.fail()
1794 except LdbError, (num, msg):
1795 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
1797 # Testing ranged results
1798 ldb.modify_ldif("""
1799 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1800 changetype: modify
1801 replace: servicePrincipalName
1802 """)
1804 ldb.modify_ldif("""
1805 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1806 changetype: modify
1807 add: servicePrincipalName
1808 servicePrincipalName: host/ldaptest2computer0
1809 servicePrincipalName: host/ldaptest2computer1
1810 servicePrincipalName: host/ldaptest2computer2
1811 servicePrincipalName: host/ldaptest2computer3
1812 servicePrincipalName: host/ldaptest2computer4
1813 servicePrincipalName: host/ldaptest2computer5
1814 servicePrincipalName: host/ldaptest2computer6
1815 servicePrincipalName: host/ldaptest2computer7
1816 servicePrincipalName: host/ldaptest2computer8
1817 servicePrincipalName: host/ldaptest2computer9
1818 servicePrincipalName: host/ldaptest2computer10
1819 servicePrincipalName: host/ldaptest2computer11
1820 servicePrincipalName: host/ldaptest2computer12
1821 servicePrincipalName: host/ldaptest2computer13
1822 servicePrincipalName: host/ldaptest2computer14
1823 servicePrincipalName: host/ldaptest2computer15
1824 servicePrincipalName: host/ldaptest2computer16
1825 servicePrincipalName: host/ldaptest2computer17
1826 servicePrincipalName: host/ldaptest2computer18
1827 servicePrincipalName: host/ldaptest2computer19
1828 servicePrincipalName: host/ldaptest2computer20
1829 servicePrincipalName: host/ldaptest2computer21
1830 servicePrincipalName: host/ldaptest2computer22
1831 servicePrincipalName: host/ldaptest2computer23
1832 servicePrincipalName: host/ldaptest2computer24
1833 servicePrincipalName: host/ldaptest2computer25
1834 servicePrincipalName: host/ldaptest2computer26
1835 servicePrincipalName: host/ldaptest2computer27
1836 servicePrincipalName: host/ldaptest2computer28
1837 servicePrincipalName: host/ldaptest2computer29
1838 """)
1840 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE,
1841 attrs=["servicePrincipalName;range=0-*"])
1842 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1843 self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30)
1845 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-19"])
1846 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1847 self.assertEquals(len(res[0]["servicePrincipalName;range=0-19"]), 20)
1850 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-30"])
1851 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1852 self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30)
1854 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-40"])
1855 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1856 self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30)
1858 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=30-40"])
1859 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1860 self.assertEquals(len(res[0]["servicePrincipalName;range=30-*"]), 0)
1863 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=10-40"])
1864 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1865 self.assertEquals(len(res[0]["servicePrincipalName;range=10-*"]), 20)
1866 # pos_11 = res[0]["servicePrincipalName;range=10-*"][18]
1868 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=11-40"])
1869 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1870 self.assertEquals(len(res[0]["servicePrincipalName;range=11-*"]), 19)
1871 # self.assertEquals((res[0]["servicePrincipalName;range=11-*"][18]), pos_11)
1873 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=11-15"])
1874 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1875 self.assertEquals(len(res[0]["servicePrincipalName;range=11-15"]), 5)
1876 # self.assertEquals(res[0]["servicePrincipalName;range=11-15"][4], pos_11)
1878 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName"])
1879 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1880 self.assertEquals(len(res[0]["servicePrincipalName"]), 30)
1881 # self.assertEquals(res[0]["servicePrincipalName"][18], pos_11)
1883 delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
1884 ldb.add({
1885 "dn": "cn=ldaptestuser2,cn=useRs," + self.base_dn,
1886 "objectClass": "user",
1887 "cn": "LDAPtestUSER2",
1888 "givenname": "testy",
1889 "sn": "ldap user2"})
1891 # Testing Ambigious Name Resolution
1892 # Testing ldb.search for (&(anr=ldap testy)(objectClass=user))
1893 res = ldb.search(expression="(&(anr=ldap testy)(objectClass=user))")
1894 self.assertEquals(len(res), 3, "Found only %d of 3 for (&(anr=ldap testy)(objectClass=user))" % len(res))
1896 # Testing ldb.search for (&(anr=testy ldap)(objectClass=user))
1897 res = ldb.search(expression="(&(anr=testy ldap)(objectClass=user))")
1898 self.assertEquals(len(res), 2, "Found only %d of 2 for (&(anr=testy ldap)(objectClass=user))" % len(res))
1900 # Testing ldb.search for (&(anr=ldap)(objectClass=user))
1901 res = ldb.search(expression="(&(anr=ldap)(objectClass=user))")
1902 self.assertEquals(len(res), 4, "Found only %d of 4 for (&(anr=ldap)(objectClass=user))" % len(res))
1904 # Testing ldb.search for (&(anr==ldap)(objectClass=user))
1905 res = ldb.search(expression="(&(anr==ldap)(objectClass=user))")
1906 self.assertEquals(len(res), 1, "Could not find (&(anr==ldap)(objectClass=user)). Found only %d for (&(anr=ldap)(objectClass=user))" % len(res))
1908 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
1909 self.assertEquals(res[0]["cn"][0], "ldaptestuser")
1910 self.assertEquals(str(res[0]["name"]), "ldaptestuser")
1912 # Testing ldb.search for (&(anr=testy)(objectClass=user))
1913 res = ldb.search(expression="(&(anr=testy)(objectClass=user))")
1914 self.assertEquals(len(res), 2, "Found only %d for (&(anr=testy)(objectClass=user))" % len(res))
1916 # Testing ldb.search for (&(anr=testy ldap)(objectClass=user))
1917 res = ldb.search(expression="(&(anr=testy ldap)(objectClass=user))")
1918 self.assertEquals(len(res), 2, "Found only %d for (&(anr=testy ldap)(objectClass=user))" % len(res))
1920 # Testing ldb.search for (&(anr==testy ldap)(objectClass=user))
1921 # this test disabled for the moment, as anr with == tests are not understood
1922 # res = ldb.search(expression="(&(anr==testy ldap)(objectClass=user))")
1923 # self.assertEquals(len(res), 1, "Found only %d for (&(anr==testy ldap)(objectClass=user))" % len(res))
1925 # self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
1926 # self.assertEquals(res[0]["cn"][0], "ldaptestuser")
1927 # self.assertEquals(res[0]["name"][0], "ldaptestuser")
1929 # Testing ldb.search for (&(anr==testy ldap)(objectClass=user))
1930 # res = ldb.search(expression="(&(anr==testy ldap)(objectClass=user))")
1931 # self.assertEquals(len(res), 1, "Could not find (&(anr==testy ldap)(objectClass=user))")
1933 # self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
1934 # self.assertEquals(res[0]["cn"][0], "ldaptestuser")
1935 # self.assertEquals(res[0]["name"][0], "ldaptestuser")
1937 # Testing ldb.search for (&(anr=testy ldap user)(objectClass=user))
1938 res = ldb.search(expression="(&(anr=testy ldap user)(objectClass=user))")
1939 self.assertEquals(len(res), 1, "Could not find (&(anr=testy ldap user)(objectClass=user))")
1941 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
1942 self.assertEquals(str(res[0]["cn"]), "ldaptestuser2")
1943 self.assertEquals(str(res[0]["name"]), "ldaptestuser2")
1945 # Testing ldb.search for (&(anr==testy ldap user2)(objectClass=user))
1946 # res = ldb.search(expression="(&(anr==testy ldap user2)(objectClass=user))")
1947 # self.assertEquals(len(res), 1, "Could not find (&(anr==testy ldap user2)(objectClass=user))")
1949 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
1950 self.assertEquals(str(res[0]["cn"]), "ldaptestuser2")
1951 self.assertEquals(str(res[0]["name"]), "ldaptestuser2")
1953 # Testing ldb.search for (&(anr==ldap user2)(objectClass=user))
1954 # res = ldb.search(expression="(&(anr==ldap user2)(objectClass=user))")
1955 # self.assertEquals(len(res), 1, "Could not find (&(anr==ldap user2)(objectClass=user))")
1957 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
1958 self.assertEquals(str(res[0]["cn"]), "ldaptestuser2")
1959 self.assertEquals(str(res[0]["name"]), "ldaptestuser2")
1961 # Testing ldb.search for (&(anr==not ldap user2)(objectClass=user))
1962 # res = ldb.search(expression="(&(anr==not ldap user2)(objectClass=user))")
1963 # self.assertEquals(len(res), 0, "Must not find (&(anr==not ldap user2)(objectClass=user))")
1965 # Testing ldb.search for (&(anr=not ldap user2)(objectClass=user))
1966 res = ldb.search(expression="(&(anr=not ldap user2)(objectClass=user))")
1967 self.assertEquals(len(res), 0, "Must not find (&(anr=not ldap user2)(objectClass=user))")
1969 # Testing ldb.search for (&(anr="testy ldap")(objectClass=user)) (ie, with quotes)
1970 # res = ldb.search(expression="(&(anr==\"testy ldap\")(objectClass=user))")
1971 # self.assertEquals(len(res), 0, "Found (&(anr==\"testy ldap\")(objectClass=user))")
1973 # Testing Renames
1975 attrs = ["objectGUID", "objectSid"]
1976 # Testing ldb.search for (&(cn=ldaptestUSer2)(objectClass=user))
1977 res_user = ldb.search(self.base_dn, expression="(&(cn=ldaptestUSer2)(objectClass=user))", scope=SCOPE_SUBTREE, attrs=attrs)
1978 self.assertEquals(len(res_user), 1, "Could not find (&(cn=ldaptestUSer2)(objectClass=user))")
1980 # Check rename works with extended/alternate DN forms
1981 ldb.rename("<SID=" + ldb.schema_format_value("objectSID", res_user[0]["objectSID"][0]) + ">" , "cn=ldaptestUSER3,cn=users," + self.base_dn)
1983 # Testing ldb.search for (&(cn=ldaptestuser3)(objectClass=user))
1984 res = ldb.search(expression="(&(cn=ldaptestuser3)(objectClass=user))")
1985 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser3)(objectClass=user))")
1987 self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
1988 self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3")
1989 self.assertEquals(str(res[0]["name"]), "ldaptestUSER3")
1991 #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))"
1992 res = ldb.search(expression="(&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))")
1993 self.assertEquals(len(res), 1, "(&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))")
1995 self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
1996 self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3")
1997 self.assertEquals(str(res[0]["name"]), "ldaptestUSER3")
1999 #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))"
2000 res = ldb.search(expression="(&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))")
2001 self.assertEquals(len(res), 1, "(&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))")
2003 self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
2004 self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3")
2005 self.assertEquals(str(res[0]["name"]), "ldaptestUSER3")
2007 #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))"
2008 res = ldb.search(expression="(&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))")
2009 self.assertEquals(len(res), 0, "(&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))")
2011 # Testing ldb.search for (dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ") - should not work
2012 res = ldb.search(expression="(dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")")
2013 self.assertEquals(len(res), 0, "Could find (dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")")
2015 # Testing ldb.search for (distinguishedName=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")
2016 res = ldb.search(expression="(distinguishedName=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")")
2017 self.assertEquals(len(res), 1, "Could not find (distinguishedName=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")")
2018 self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
2019 self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3")
2020 self.assertEquals(str(res[0]["name"]), "ldaptestUSER3")
2022 # ensure we cannot add it again
2023 try:
2024 ldb.add({"dn": "cn=ldaptestuser3,cn=userS," + self.base_dn,
2025 "objectClass": "user",
2026 "cn": "LDAPtestUSER3"})
2027 self.fail()
2028 except LdbError, (num, _):
2029 self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
2031 # rename back
2032 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser2,cn=users," + self.base_dn)
2034 # ensure we cannot rename it twice
2035 try:
2036 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn,
2037 "cn=ldaptestuser2,cn=users," + self.base_dn)
2038 self.fail()
2039 except LdbError, (num, _):
2040 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
2042 # ensure can now use that name
2043 ldb.add({"dn": "cn=ldaptestuser3,cn=users," + self.base_dn,
2044 "objectClass": "user",
2045 "cn": "LDAPtestUSER3"})
2047 # ensure we now cannot rename
2048 try:
2049 ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=users," + self.base_dn)
2050 self.fail()
2051 except LdbError, (num, _):
2052 self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
2053 try:
2054 ldb.rename("cn=ldaptestuser3,cn=users,%s" % self.base_dn, "cn=ldaptestuser3,%s" % ldb.get_config_basedn())
2055 self.fail()
2056 except LdbError, (num, _):
2057 self.assertTrue(num in (71, 64))
2059 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser5,cn=users," + self.base_dn)
2061 ldb.delete("cn=ldaptestuser5,cn=users," + self.base_dn)
2063 delete_force(ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
2065 ldb.rename("cn=ldaptestgroup,cn=users," + self.base_dn, "cn=ldaptestgroup2,cn=users," + self.base_dn)
2067 # Testing subtree renames
2069 ldb.add({"dn": "cn=ldaptestcontainer," + self.base_dn,
2070 "objectClass": "container"})
2072 ldb.add({"dn": "CN=ldaptestuser4,CN=ldaptestcontainer," + self.base_dn,
2073 "objectClass": "user",
2074 "cn": "LDAPtestUSER4"})
2076 # Here we don't enforce these hard "description" constraints
2077 ldb.modify_ldif("""
2078 dn: cn=ldaptestcontainer,""" + self.base_dn + """
2079 changetype: modify
2080 replace: description
2081 description: desc1
2082 description: desc2
2083 """)
2085 ldb.modify_ldif("""
2086 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2087 changetype: modify
2088 add: member
2089 member: cn=ldaptestuser4,cn=ldaptestcontainer,""" + self.base_dn + """
2090 member: cn=ldaptestcomputer,cn=computers,""" + self.base_dn + """
2091 member: cn=ldaptestuser2,cn=users,""" + self.base_dn + """
2092 """)
2094 # Testing ldb.rename of cn=ldaptestcontainer," + self.base_dn + " to cn=ldaptestcontainer2," + self.base_dn
2095 ldb.rename("CN=ldaptestcontainer," + self.base_dn, "CN=ldaptestcontainer2," + self.base_dn)
2097 # Testing ldb.search for (&(cn=ldaptestuser4)(objectClass=user))
2098 res = ldb.search(expression="(&(cn=ldaptestuser4)(objectClass=user))")
2099 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser4)(objectClass=user))")
2101 # Testing subtree ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in (just renamed from) cn=ldaptestcontainer," + self.base_dn
2102 try:
2103 res = ldb.search("cn=ldaptestcontainer," + self.base_dn,
2104 expression="(&(cn=ldaptestuser4)(objectClass=user))",
2105 scope=SCOPE_SUBTREE)
2106 self.fail(res)
2107 except LdbError, (num, _):
2108 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
2110 # Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in (just renamed from) cn=ldaptestcontainer," + self.base_dn
2111 try:
2112 res = ldb.search("cn=ldaptestcontainer," + self.base_dn,
2113 expression="(&(cn=ldaptestuser4)(objectClass=user))", scope=SCOPE_ONELEVEL)
2114 self.fail()
2115 except LdbError, (num, _):
2116 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
2118 # Testing ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in renamed container"
2119 res = ldb.search("cn=ldaptestcontainer2," + self.base_dn, expression="(&(cn=ldaptestuser4)(objectClass=user))", scope=SCOPE_SUBTREE)
2120 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser4)(objectClass=user)) under cn=ldaptestcontainer2," + self.base_dn)
2122 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn))
2123 self.assertEquals(res[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
2125 time.sleep(4)
2127 # Testing ldb.search for (&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn + ")(objectclass=group)) to check subtree renames and linked attributes"
2128 res = ldb.search(self.base_dn, expression="(&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn + ")(objectclass=group))", scope=SCOPE_SUBTREE)
2129 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?")
2131 # Testing ldb.rename (into itself) of cn=ldaptestcontainer2," + self.base_dn + " to cn=ldaptestcontainer,cn=ldaptestcontainer2," + self.base_dn
2132 try:
2133 ldb.rename("cn=ldaptestcontainer2," + self.base_dn, "cn=ldaptestcontainer,cn=ldaptestcontainer2," + self.base_dn)
2134 self.fail()
2135 except LdbError, (num, _):
2136 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
2138 # Testing ldb.rename (into non-existent container) of cn=ldaptestcontainer2," + self.base_dn + " to cn=ldaptestcontainer,cn=ldaptestcontainer3," + self.base_dn
2139 try:
2140 ldb.rename("cn=ldaptestcontainer2," + self.base_dn, "cn=ldaptestcontainer,cn=ldaptestcontainer3," + self.base_dn)
2141 self.fail()
2142 except LdbError, (num, _):
2143 self.assertTrue(num in (ERR_UNWILLING_TO_PERFORM, ERR_OTHER))
2145 # Testing delete (should fail, not a leaf node) of renamed cn=ldaptestcontainer2," + self.base_dn
2146 try:
2147 ldb.delete("cn=ldaptestcontainer2," + self.base_dn)
2148 self.fail()
2149 except LdbError, (num, _):
2150 self.assertEquals(num, ERR_NOT_ALLOWED_ON_NON_LEAF)
2152 # Testing base ldb.search for CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn
2153 res = ldb.search(expression="(objectclass=*)", base=("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn), scope=SCOPE_BASE)
2154 self.assertEquals(len(res), 1)
2155 res = ldb.search(expression="(cn=ldaptestuser40)", base=("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn), scope=SCOPE_BASE)
2156 self.assertEquals(len(res), 0)
2158 # Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in cn=ldaptestcontainer2," + self.base_dn
2159 res = ldb.search(expression="(&(cn=ldaptestuser4)(objectClass=user))", base=("cn=ldaptestcontainer2," + self.base_dn), scope=SCOPE_ONELEVEL)
2160 self.assertEquals(len(res), 1)
2162 # Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in cn=ldaptestcontainer2," + self.base_dn
2163 res = ldb.search(expression="(&(cn=ldaptestuser4)(objectClass=user))", base=("cn=ldaptestcontainer2," + self.base_dn), scope=SCOPE_SUBTREE)
2164 self.assertEquals(len(res), 1)
2166 # Testing delete of subtree renamed "+("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn)
2167 ldb.delete(("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn))
2168 # Testing delete of renamed cn=ldaptestcontainer2," + self.base_dn
2169 ldb.delete("cn=ldaptestcontainer2," + self.base_dn)
2171 ldb.add({"dn": "cn=ldaptestutf8user èùéìòà,cn=users," + self.base_dn, "objectClass": "user"})
2173 ldb.add({"dn": "cn=ldaptestutf8user2 èùéìòà,cn=users," + self.base_dn, "objectClass": "user"})
2175 # Testing ldb.search for (&(cn=ldaptestuser)(objectClass=user))"
2176 res = ldb.search(expression="(&(cn=ldaptestuser)(objectClass=user))")
2177 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser)(objectClass=user))")
2179 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
2180 self.assertEquals(str(res[0]["cn"]), "ldaptestuser")
2181 self.assertEquals(str(res[0]["name"]), "ldaptestuser")
2182 self.assertEquals(set(res[0]["objectClass"]), set(["top", "person", "organizationalPerson", "user"]))
2183 self.assertTrue("objectGUID" in res[0])
2184 self.assertTrue("whenCreated" in res[0])
2185 self.assertEquals(str(res[0]["objectCategory"]), ("CN=Person,%s" % ldb.get_schema_basedn()))
2186 self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_NORMAL_ACCOUNT)
2187 self.assertEquals(int(res[0]["userAccountControl"][0]), UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE)
2188 self.assertEquals(res[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
2189 self.assertEquals(len(res[0]["memberOf"]), 1)
2191 # Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=cn=person,%s))" % ldb.get_schema_basedn()
2192 res2 = ldb.search(expression="(&(cn=ldaptestuser)(objectCategory=cn=person,%s))" % ldb.get_schema_basedn())
2193 self.assertEquals(len(res2), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=cn=person,%s))" % ldb.get_schema_basedn())
2195 self.assertEquals(res[0].dn, res2[0].dn)
2197 # Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon))"
2198 res3 = ldb.search(expression="(&(cn=ldaptestuser)(objectCategory=PerSon))")
2199 self.assertEquals(len(res3), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=PerSon)): matched %d" % len(res3))
2201 self.assertEquals(res[0].dn, res3[0].dn)
2203 if gc_ldb is not None:
2204 # Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon)) in Global Catalog"
2205 res3gc = gc_ldb.search(expression="(&(cn=ldaptestuser)(objectCategory=PerSon))")
2206 self.assertEquals(len(res3gc), 1)
2208 self.assertEquals(res[0].dn, res3gc[0].dn)
2210 # Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon)) in with 'phantom root' control"
2212 if gc_ldb is not None:
2213 res3control = gc_ldb.search(self.base_dn, expression="(&(cn=ldaptestuser)(objectCategory=PerSon))", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["search_options:1:2"])
2214 self.assertEquals(len(res3control), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=PerSon)) in Global Catalog")
2216 self.assertEquals(res[0].dn, res3control[0].dn)
2218 ldb.delete(res[0].dn)
2220 # Testing ldb.search for (&(cn=ldaptestcomputer)(objectClass=user))"
2221 res = ldb.search(expression="(&(cn=ldaptestcomputer)(objectClass=user))")
2222 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser)(objectClass=user))")
2224 self.assertEquals(str(res[0].dn), ("CN=ldaptestcomputer,CN=Computers," + self.base_dn))
2225 self.assertEquals(str(res[0]["cn"]), "ldaptestcomputer")
2226 self.assertEquals(str(res[0]["name"]), "ldaptestcomputer")
2227 self.assertEquals(set(res[0]["objectClass"]), set(["top", "person", "organizationalPerson", "user", "computer"]))
2228 self.assertTrue("objectGUID" in res[0])
2229 self.assertTrue("whenCreated" in res[0])
2230 self.assertEquals(str(res[0]["objectCategory"]), ("CN=Computer,%s" % ldb.get_schema_basedn()))
2231 self.assertEquals(int(res[0]["primaryGroupID"][0]), 513)
2232 self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_NORMAL_ACCOUNT)
2233 self.assertEquals(int(res[0]["userAccountControl"][0]), UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE)
2234 self.assertEquals(res[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
2235 self.assertEquals(len(res[0]["memberOf"]), 1)
2237 # Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=cn=computer,%s))" % ldb.get_schema_basedn()
2238 res2 = ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=cn=computer,%s))" % ldb.get_schema_basedn())
2239 self.assertEquals(len(res2), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=cn=computer,%s))" % ldb.get_schema_basedn())
2241 self.assertEquals(res[0].dn, res2[0].dn)
2243 if gc_ldb is not None:
2244 # Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=cn=computer,%s)) in Global Catalog" % gc_ldb.get_schema_basedn()
2245 res2gc = gc_ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=cn=computer,%s))" % gc_ldb.get_schema_basedn())
2246 self.assertEquals(len(res2gc), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=cn=computer,%s)) In Global Catalog" % gc_ldb.get_schema_basedn())
2248 self.assertEquals(res[0].dn, res2gc[0].dn)
2250 # Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=compuTER))"
2251 res3 = ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=compuTER))")
2252 self.assertEquals(len(res3), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=compuTER))")
2254 self.assertEquals(res[0].dn, res3[0].dn)
2256 if gc_ldb is not None:
2257 # Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=compuTER)) in Global Catalog"
2258 res3gc = gc_ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=compuTER))")
2259 self.assertEquals(len(res3gc), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=compuTER)) in Global Catalog")
2261 self.assertEquals(res[0].dn, res3gc[0].dn)
2263 # Testing ldb.search for (&(cn=ldaptestcomp*r)(objectCategory=compuTER))"
2264 res4 = ldb.search(expression="(&(cn=ldaptestcomp*r)(objectCategory=compuTER))")
2265 self.assertEquals(len(res4), 1, "Could not find (&(cn=ldaptestcomp*r)(objectCategory=compuTER))")
2267 self.assertEquals(res[0].dn, res4[0].dn)
2269 # Testing ldb.search for (&(cn=ldaptestcomput*)(objectCategory=compuTER))"
2270 res5 = ldb.search(expression="(&(cn=ldaptestcomput*)(objectCategory=compuTER))")
2271 self.assertEquals(len(res5), 1, "Could not find (&(cn=ldaptestcomput*)(objectCategory=compuTER))")
2273 self.assertEquals(res[0].dn, res5[0].dn)
2275 # Testing ldb.search for (&(cn=*daptestcomputer)(objectCategory=compuTER))"
2276 res6 = ldb.search(expression="(&(cn=*daptestcomputer)(objectCategory=compuTER))")
2277 self.assertEquals(len(res6), 1, "Could not find (&(cn=*daptestcomputer)(objectCategory=compuTER))")
2279 self.assertEquals(res[0].dn, res6[0].dn)
2281 ldb.delete("<GUID=" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + ">")
2283 # Testing ldb.search for (&(cn=ldaptest2computer)(objectClass=user))"
2284 res = ldb.search(expression="(&(cn=ldaptest2computer)(objectClass=user))")
2285 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptest2computer)(objectClass=user))")
2287 self.assertEquals(str(res[0].dn), "CN=ldaptest2computer,CN=Computers," + self.base_dn)
2288 self.assertEquals(str(res[0]["cn"]), "ldaptest2computer")
2289 self.assertEquals(str(res[0]["name"]), "ldaptest2computer")
2290 self.assertEquals(list(res[0]["objectClass"]), ["top", "person", "organizationalPerson", "user", "computer"])
2291 self.assertTrue("objectGUID" in res[0])
2292 self.assertTrue("whenCreated" in res[0])
2293 self.assertEquals(res[0]["objectCategory"][0], "CN=Computer,%s" % ldb.get_schema_basedn())
2294 self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_WORKSTATION_TRUST)
2295 self.assertEquals(int(res[0]["userAccountControl"][0]), UF_WORKSTATION_TRUST_ACCOUNT)
2297 ldb.delete("<SID=" + ldb.schema_format_value("objectSID", res[0]["objectSID"][0]) + ">")
2299 attrs = ["cn", "name", "objectClass", "objectGUID", "objectSID", "whenCreated", "nTSecurityDescriptor", "memberOf", "allowedAttributes", "allowedAttributesEffective"]
2300 # Testing ldb.search for (&(cn=ldaptestUSer2)(objectClass=user))"
2301 res_user = ldb.search(self.base_dn, expression="(&(cn=ldaptestUSer2)(objectClass=user))", scope=SCOPE_SUBTREE, attrs=attrs)
2302 self.assertEquals(len(res_user), 1, "Could not find (&(cn=ldaptestUSer2)(objectClass=user))")
2304 self.assertEquals(str(res_user[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
2305 self.assertEquals(str(res_user[0]["cn"]), "ldaptestuser2")
2306 self.assertEquals(str(res_user[0]["name"]), "ldaptestuser2")
2307 self.assertEquals(list(res_user[0]["objectClass"]), ["top", "person", "organizationalPerson", "user"])
2308 self.assertTrue("objectSid" in res_user[0])
2309 self.assertTrue("objectGUID" in res_user[0])
2310 self.assertTrue("whenCreated" in res_user[0])
2311 self.assertTrue("nTSecurityDescriptor" in res_user[0])
2312 self.assertTrue("allowedAttributes" in res_user[0])
2313 self.assertTrue("allowedAttributesEffective" in res_user[0])
2314 self.assertEquals(res_user[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
2316 ldaptestuser2_sid = res_user[0]["objectSid"][0]
2317 ldaptestuser2_guid = res_user[0]["objectGUID"][0]
2319 attrs = ["cn", "name", "objectClass", "objectGUID", "objectSID", "whenCreated", "nTSecurityDescriptor", "member", "allowedAttributes", "allowedAttributesEffective"]
2320 # Testing ldb.search for (&(cn=ldaptestgroup2)(objectClass=group))"
2321 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs)
2322 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))")
2324 self.assertEquals(str(res[0].dn), ("CN=ldaptestgroup2,CN=Users," + self.base_dn))
2325 self.assertEquals(str(res[0]["cn"]), "ldaptestgroup2")
2326 self.assertEquals(str(res[0]["name"]), "ldaptestgroup2")
2327 self.assertEquals(list(res[0]["objectClass"]), ["top", "group"])
2328 self.assertTrue("objectGUID" in res[0])
2329 self.assertTrue("objectSid" in res[0])
2330 self.assertTrue("whenCreated" in res[0])
2331 self.assertTrue("nTSecurityDescriptor" in res[0])
2332 self.assertTrue("allowedAttributes" in res[0])
2333 self.assertTrue("allowedAttributesEffective" in res[0])
2334 memberUP = []
2335 for m in res[0]["member"]:
2336 memberUP.append(m.upper())
2337 self.assertTrue(("CN=ldaptestuser2,CN=Users," + self.base_dn).upper() in memberUP)
2339 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs, controls=["extended_dn:1:1"])
2340 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))")
2342 print res[0]["member"]
2343 memberUP = []
2344 for m in res[0]["member"]:
2345 memberUP.append(m.upper())
2346 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()
2348 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)
2350 # Quicktest for linked attributes"
2351 ldb.modify_ldif("""
2352 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2353 changetype: modify
2354 replace: member
2355 member: CN=ldaptestuser2,CN=Users,""" + self.base_dn + """
2356 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
2357 """)
2359 ldb.modify_ldif("""
2360 dn: <GUID=""" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + """>
2361 changetype: modify
2362 replace: member
2363 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
2364 """)
2366 ldb.modify_ldif("""
2367 dn: <SID=""" + ldb.schema_format_value("objectSid", res[0]["objectSid"][0]) + """>
2368 changetype: modify
2369 delete: member
2370 """)
2372 ldb.modify_ldif("""
2373 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2374 changetype: modify
2375 add: member
2376 member: <GUID=""" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + """>
2377 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
2378 """)
2380 ldb.modify_ldif("""
2381 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2382 changetype: modify
2383 replace: member
2384 """)
2386 ldb.modify_ldif("""
2387 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2388 changetype: modify
2389 add: member
2390 member: <SID=""" + ldb.schema_format_value("objectSid", res_user[0]["objectSid"][0]) + """>
2391 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
2392 """)
2394 ldb.modify_ldif("""
2395 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2396 changetype: modify
2397 delete: member
2398 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
2399 """)
2401 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs)
2402 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))")
2404 self.assertEquals(str(res[0].dn), ("CN=ldaptestgroup2,CN=Users," + self.base_dn))
2405 self.assertEquals(res[0]["member"][0], ("CN=ldaptestuser2,CN=Users," + self.base_dn))
2406 self.assertEquals(len(res[0]["member"]), 1)
2408 ldb.delete(("CN=ldaptestuser2,CN=Users," + self.base_dn))
2410 time.sleep(4)
2412 attrs = ["cn", "name", "objectClass", "objectGUID", "whenCreated", "nTSecurityDescriptor", "member"]
2413 # Testing ldb.search for (&(cn=ldaptestgroup2)(objectClass=group)) to check linked delete"
2414 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs)
2415 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group)) to check linked delete")
2417 self.assertEquals(str(res[0].dn), ("CN=ldaptestgroup2,CN=Users," + self.base_dn))
2418 self.assertTrue("member" not in res[0])
2420 # Testing ldb.search for (&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))"
2421 res = ldb.search(expression="(&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
2422 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
2423 res = ldb.search(expression="(&(cn=ldaptestutf8user èùéìòà)(objectclass=user))")
2424 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
2426 self.assertEquals(str(res[0].dn), ("CN=ldaptestutf8user èùéìòà,CN=Users," + self.base_dn))
2427 self.assertEquals(str(res[0]["cn"]), "ldaptestutf8user èùéìòà")
2428 self.assertEquals(str(res[0]["name"]), "ldaptestutf8user èùéìòà")
2429 self.assertEquals(list(res[0]["objectClass"]), ["top", "person", "organizationalPerson", "user"])
2430 self.assertTrue("objectGUID" in res[0])
2431 self.assertTrue("whenCreated" in res[0])
2433 # delete "ldaptestutf8user"
2434 ldb.delete(res[0].dn)
2436 # Testing ldb.search for (&(cn=ldaptestutf8user2*)(objectClass=user))"
2437 res = ldb.search(expression="(&(cn=ldaptestutf8user2*)(objectClass=user))")
2438 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestutf8user2*)(objectClass=user))")
2440 # Testing ldb.search for (&(cn=ldaptestutf8user2 ÈÙÉÌÒÀ)(objectClass=user))"
2441 res = ldb.search(expression="(&(cn=ldaptestutf8user2 ÈÙÉÌÒÀ)(objectClass=user))")
2442 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestutf8user2 ÈÙÉÌÒÀ)(objectClass=user))")
2444 # delete "ldaptestutf8user2 "
2445 ldb.delete(res[0].dn)
2447 ldb.delete(("CN=ldaptestgroup2,CN=Users," + self.base_dn))
2449 # Testing that we can't get at the configuration DN from the main search base"
2450 res = ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
2451 self.assertEquals(len(res), 0)
2453 # 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"
2454 res = ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["search_options:1:2"])
2455 self.assertTrue(len(res) > 0)
2457 if gc_ldb is not None:
2458 # Testing that we can get at the configuration DN from the main search base on the GC port with the search_options control == 0"
2460 res = gc_ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["search_options:1:0"])
2461 self.assertTrue(len(res) > 0)
2463 # Testing that we do find configuration elements in the global catlog"
2464 res = gc_ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
2465 self.assertTrue(len(res) > 0)
2467 # Testing that we do find configuration elements and user elements at the same time"
2468 res = gc_ldb.search(self.base_dn, expression="(|(objectClass=crossRef)(objectClass=person))", scope=SCOPE_SUBTREE, attrs=["cn"])
2469 self.assertTrue(len(res) > 0)
2471 # Testing that we do find configuration elements in the global catlog, with the configuration basedn"
2472 res = gc_ldb.search(self.configuration_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
2473 self.assertTrue(len(res) > 0)
2475 # Testing that we can get at the configuration DN on the main LDAP port"
2476 res = ldb.search(self.configuration_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
2477 self.assertTrue(len(res) > 0)
2479 # Testing objectCategory canonacolisation"
2480 res = ldb.search(self.configuration_dn, expression="objectCategory=ntDsDSA", scope=SCOPE_SUBTREE, attrs=["cn"])
2481 self.assertTrue(len(res) > 0, "Didn't find any records with objectCategory=ntDsDSA")
2482 self.assertTrue(len(res) != 0)
2484 res = ldb.search(self.configuration_dn, expression="objectCategory=CN=ntDs-DSA," + self.schema_dn, scope=SCOPE_SUBTREE, attrs=["cn"])
2485 self.assertTrue(len(res) > 0, "Didn't find any records with objectCategory=CN=ntDs-DSA," + self.schema_dn)
2486 self.assertTrue(len(res) != 0)
2488 # Testing objectClass attribute order on "+ self.base_dn
2489 res = ldb.search(expression="objectClass=domain", base=self.base_dn,
2490 scope=SCOPE_BASE, attrs=["objectClass"])
2491 self.assertEquals(len(res), 1)
2493 self.assertEquals(list(res[0]["objectClass"]), ["top", "domain", "domainDNS"])
2495 # check enumeration
2497 # Testing ldb.search for objectCategory=person"
2498 res = ldb.search(self.base_dn, expression="objectCategory=person", scope=SCOPE_SUBTREE, attrs=["cn"])
2499 self.assertTrue(len(res) > 0)
2501 # Testing ldb.search for objectCategory=person with domain scope control"
2502 res = ldb.search(self.base_dn, expression="objectCategory=person", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["domain_scope:1"])
2503 self.assertTrue(len(res) > 0)
2505 # Testing ldb.search for objectCategory=user"
2506 res = ldb.search(self.base_dn, expression="objectCategory=user", scope=SCOPE_SUBTREE, attrs=["cn"])
2507 self.assertTrue(len(res) > 0)
2509 # Testing ldb.search for objectCategory=user with domain scope control"
2510 res = ldb.search(self.base_dn, expression="objectCategory=user", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["domain_scope:1"])
2511 self.assertTrue(len(res) > 0)
2513 # Testing ldb.search for objectCategory=group"
2514 res = ldb.search(self.base_dn, expression="objectCategory=group", scope=SCOPE_SUBTREE, attrs=["cn"])
2515 self.assertTrue(len(res) > 0)
2517 # Testing ldb.search for objectCategory=group with domain scope control"
2518 res = ldb.search(self.base_dn, expression="objectCategory=group", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["domain_scope:1"])
2519 self.assertTrue(len(res) > 0)
2521 # Testing creating a user with the posixAccount objectClass"
2522 self.ldb.add_ldif("""dn: cn=posixuser,CN=Users,%s
2523 objectClass: top
2524 objectClass: person
2525 objectClass: posixAccount
2526 objectClass: user
2527 objectClass: organizationalPerson
2528 cn: posixuser
2529 uid: posixuser
2530 sn: posixuser
2531 uidNumber: 10126
2532 gidNumber: 10126
2533 homeDirectory: /home/posixuser
2534 loginShell: /bin/bash
2535 gecos: Posix User;;;
2536 description: A POSIX user"""% (self.base_dn))
2538 # Testing removing the posixAccount objectClass from an existing user"
2539 self.ldb.modify_ldif("""dn: cn=posixuser,CN=Users,%s
2540 changetype: modify
2541 delete: objectClass
2542 objectClass: posixAccount"""% (self.base_dn))
2544 # Testing adding the posixAccount objectClass to an existing user"
2545 self.ldb.modify_ldif("""dn: cn=posixuser,CN=Users,%s
2546 changetype: modify
2547 add: objectClass
2548 objectClass: posixAccount"""% (self.base_dn))
2550 delete_force(self.ldb, "cn=posixuser,cn=users," + self.base_dn)
2551 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
2552 delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
2553 delete_force(self.ldb, "cn=ldaptestuser3,cn=users," + self.base_dn)
2554 delete_force(self.ldb, "cn=ldaptestuser4,cn=ldaptestcontainer," + self.base_dn)
2555 delete_force(self.ldb, "cn=ldaptestuser4,cn=ldaptestcontainer2," + self.base_dn)
2556 delete_force(self.ldb, "cn=ldaptestuser5,cn=users," + self.base_dn)
2557 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
2558 delete_force(self.ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
2559 delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2560 delete_force(self.ldb, "cn=ldaptest2computer,cn=computers," + self.base_dn)
2561 delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
2562 delete_force(self.ldb, "cn=ldaptestutf8user èùéìòà,cn=users," + self.base_dn)
2563 delete_force(self.ldb, "cn=ldaptestutf8user2 èùéìòà,cn=users," + self.base_dn)
2564 delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
2565 delete_force(self.ldb, "cn=ldaptestcontainer2," + self.base_dn)
2567 def test_security_descriptor_add(self):
2568 """ Testing ldb.add_ldif() for nTSecurityDescriptor """
2569 user_name = "testdescriptoruser1"
2570 user_dn = "CN=%s,CN=Users,%s" % (user_name, self.base_dn)
2572 # Test an empty security descriptor (naturally this shouldn't work)
2574 delete_force(self.ldb, user_dn)
2575 try:
2576 self.ldb.add({ "dn": user_dn,
2577 "objectClass": "user",
2578 "sAMAccountName": user_name,
2579 "nTSecurityDescriptor": [] })
2580 self.fail()
2581 except LdbError, (num, _):
2582 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
2583 finally:
2584 delete_force(self.ldb, user_dn)
2586 # Test add_ldif() with SDDL security descriptor input
2588 try:
2589 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2590 self.ldb.add_ldif("""
2591 dn: """ + user_dn + """
2592 objectclass: user
2593 sAMAccountName: """ + user_name + """
2594 nTSecurityDescriptor: """ + sddl)
2595 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2596 desc = res[0]["nTSecurityDescriptor"][0]
2597 desc = ndr_unpack( security.descriptor, desc )
2598 desc_sddl = desc.as_sddl( self.domain_sid )
2599 self.assertEqual(desc_sddl, sddl)
2600 finally:
2601 delete_force(self.ldb, user_dn)
2603 # Test add_ldif() with BASE64 security descriptor
2605 try:
2606 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2607 desc = security.descriptor.from_sddl(sddl, self.domain_sid)
2608 desc_binary = ndr_pack(desc)
2609 desc_base64 = base64.b64encode(desc_binary)
2610 self.ldb.add_ldif("""
2611 dn: """ + user_dn + """
2612 objectclass: user
2613 sAMAccountName: """ + user_name + """
2614 nTSecurityDescriptor:: """ + desc_base64)
2615 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2616 desc = res[0]["nTSecurityDescriptor"][0]
2617 desc = ndr_unpack(security.descriptor, desc)
2618 desc_sddl = desc.as_sddl(self.domain_sid)
2619 self.assertEqual(desc_sddl, sddl)
2620 finally:
2621 delete_force(self.ldb, user_dn)
2623 def test_security_descriptor_add_neg(self):
2624 """Test add_ldif() with BASE64 security descriptor input using WRONG domain SID
2625 Negative test
2627 user_name = "testdescriptoruser1"
2628 user_dn = "CN=%s,CN=Users,%s" % (user_name, self.base_dn)
2629 delete_force(self.ldb, user_dn)
2630 try:
2631 sddl = "O:DUG:DUD:AI(A;;RPWP;;;AU)S:PAI"
2632 desc = security.descriptor.from_sddl(sddl, security.dom_sid('S-1-5-21'))
2633 desc_base64 = base64.b64encode( ndr_pack(desc) )
2634 self.ldb.add_ldif("""
2635 dn: """ + user_dn + """
2636 objectclass: user
2637 sAMAccountName: """ + user_name + """
2638 nTSecurityDescriptor:: """ + desc_base64)
2639 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2640 self.assertTrue("nTSecurityDescriptor" in res[0])
2641 desc = res[0]["nTSecurityDescriptor"][0]
2642 desc = ndr_unpack(security.descriptor, desc)
2643 desc_sddl = desc.as_sddl(self.domain_sid)
2644 self.assertTrue("O:S-1-5-21-513G:S-1-5-21-513D:AI(A;;RPWP;;;AU)" in desc_sddl)
2645 finally:
2646 delete_force(self.ldb, user_dn)
2648 def test_security_descriptor_modify(self):
2649 """ Testing ldb.modify_ldif() for nTSecurityDescriptor """
2650 user_name = "testdescriptoruser2"
2651 user_dn = "CN=%s,CN=Users,%s" % (user_name, self.base_dn)
2653 # Test an empty security descriptor (naturally this shouldn't work)
2655 delete_force(self.ldb, user_dn)
2656 self.ldb.add({ "dn": user_dn,
2657 "objectClass": "user",
2658 "sAMAccountName": user_name })
2660 m = Message()
2661 m.dn = Dn(ldb, user_dn)
2662 m["nTSecurityDescriptor"] = MessageElement([], FLAG_MOD_ADD,
2663 "nTSecurityDescriptor")
2664 try:
2665 self.ldb.modify(m)
2666 self.fail()
2667 except LdbError, (num, _):
2668 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
2670 m = Message()
2671 m.dn = Dn(ldb, user_dn)
2672 m["nTSecurityDescriptor"] = MessageElement([], FLAG_MOD_REPLACE,
2673 "nTSecurityDescriptor")
2674 try:
2675 self.ldb.modify(m)
2676 self.fail()
2677 except LdbError, (num, _):
2678 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
2680 m = Message()
2681 m.dn = Dn(ldb, user_dn)
2682 m["nTSecurityDescriptor"] = MessageElement([], FLAG_MOD_DELETE,
2683 "nTSecurityDescriptor")
2684 try:
2685 self.ldb.modify(m)
2686 self.fail()
2687 except LdbError, (num, _):
2688 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
2690 delete_force(self.ldb, user_dn)
2692 # Test modify_ldif() with SDDL security descriptor input
2693 # Add ACE to the original descriptor test
2695 try:
2696 self.ldb.add_ldif("""
2697 dn: """ + user_dn + """
2698 objectclass: user
2699 sAMAccountName: """ + user_name)
2700 # Modify descriptor
2701 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2702 desc = res[0]["nTSecurityDescriptor"][0]
2703 desc = ndr_unpack(security.descriptor, desc)
2704 desc_sddl = desc.as_sddl(self.domain_sid)
2705 sddl = desc_sddl[:desc_sddl.find("(")] + "(A;;RPWP;;;AU)" + desc_sddl[desc_sddl.find("("):]
2706 mod = """
2707 dn: """ + user_dn + """
2708 changetype: modify
2709 replace: nTSecurityDescriptor
2710 nTSecurityDescriptor: """ + sddl
2711 self.ldb.modify_ldif(mod)
2712 # Read modified descriptor
2713 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2714 desc = res[0]["nTSecurityDescriptor"][0]
2715 desc = ndr_unpack(security.descriptor, desc)
2716 desc_sddl = desc.as_sddl(self.domain_sid)
2717 self.assertEqual(desc_sddl, sddl)
2718 finally:
2719 delete_force(self.ldb, user_dn)
2721 # Test modify_ldif() with SDDL security descriptor input
2722 # New desctiptor test
2724 try:
2725 self.ldb.add_ldif("""
2726 dn: """ + user_dn + """
2727 objectclass: user
2728 sAMAccountName: """ + user_name)
2729 # Modify descriptor
2730 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2731 mod = """
2732 dn: """ + user_dn + """
2733 changetype: modify
2734 replace: nTSecurityDescriptor
2735 nTSecurityDescriptor: """ + sddl
2736 self.ldb.modify_ldif(mod)
2737 # Read modified descriptor
2738 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2739 desc = res[0]["nTSecurityDescriptor"][0]
2740 desc = ndr_unpack(security.descriptor, desc)
2741 desc_sddl = desc.as_sddl(self.domain_sid)
2742 self.assertEqual(desc_sddl, sddl)
2743 finally:
2744 delete_force(self.ldb, user_dn)
2746 # Test modify_ldif() with BASE64 security descriptor input
2747 # Add ACE to the original descriptor test
2749 try:
2750 self.ldb.add_ldif("""
2751 dn: """ + user_dn + """
2752 objectclass: user
2753 sAMAccountName: """ + user_name)
2754 # Modify descriptor
2755 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2756 desc = res[0]["nTSecurityDescriptor"][0]
2757 desc = ndr_unpack(security.descriptor, desc)
2758 desc_sddl = desc.as_sddl(self.domain_sid)
2759 sddl = desc_sddl[:desc_sddl.find("(")] + "(A;;RPWP;;;AU)" + desc_sddl[desc_sddl.find("("):]
2760 desc = security.descriptor.from_sddl(sddl, self.domain_sid)
2761 desc_base64 = base64.b64encode(ndr_pack(desc))
2762 mod = """
2763 dn: """ + user_dn + """
2764 changetype: modify
2765 replace: nTSecurityDescriptor
2766 nTSecurityDescriptor:: """ + desc_base64
2767 self.ldb.modify_ldif(mod)
2768 # Read modified descriptor
2769 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2770 desc = res[0]["nTSecurityDescriptor"][0]
2771 desc = ndr_unpack(security.descriptor, desc)
2772 desc_sddl = desc.as_sddl(self.domain_sid)
2773 self.assertEqual(desc_sddl, sddl)
2774 finally:
2775 delete_force(self.ldb, user_dn)
2777 # Test modify_ldif() with BASE64 security descriptor input
2778 # New descriptor test
2780 try:
2781 delete_force(self.ldb, user_dn)
2782 self.ldb.add_ldif("""
2783 dn: """ + user_dn + """
2784 objectclass: user
2785 sAMAccountName: """ + user_name)
2786 # Modify descriptor
2787 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2788 desc = security.descriptor.from_sddl(sddl, self.domain_sid)
2789 desc_base64 = base64.b64encode(ndr_pack(desc))
2790 mod = """
2791 dn: """ + user_dn + """
2792 changetype: modify
2793 replace: nTSecurityDescriptor
2794 nTSecurityDescriptor:: """ + desc_base64
2795 self.ldb.modify_ldif(mod)
2796 # Read modified descriptor
2797 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2798 desc = res[0]["nTSecurityDescriptor"][0]
2799 desc = ndr_unpack(security.descriptor, desc)
2800 desc_sddl = desc.as_sddl(self.domain_sid)
2801 self.assertEqual(desc_sddl, sddl)
2802 finally:
2803 delete_force(self.ldb, user_dn)
2805 def test_dsheuristics(self):
2806 """Tests the 'dSHeuristics' attribute"""
2807 # Tests the 'dSHeuristics' attribute"
2809 # Get the current value to restore it later
2810 dsheuristics = self.ldb.get_dsheuristics()
2811 # Perform the length checks: for each decade (except the 0th) we need
2812 # the first index to be the number. This goes till the 9th one, beyond
2813 # there does not seem to be another limitation.
2814 try:
2815 dshstr = ""
2816 for i in range(1,11):
2817 # This is in the range
2818 self.ldb.set_dsheuristics(dshstr + "x")
2819 self.ldb.set_dsheuristics(dshstr + "xxxxx")
2820 dshstr = dshstr + "xxxxxxxxx"
2821 if i < 10:
2822 # Not anymore in the range, new decade specifier needed
2823 try:
2824 self.ldb.set_dsheuristics(dshstr + "x")
2825 self.fail()
2826 except LdbError, (num, _):
2827 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
2828 dshstr = dshstr + str(i)
2829 else:
2830 # There does not seem to be an upper limit
2831 self.ldb.set_dsheuristics(dshstr + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
2832 # apart from the above, all char values are accepted
2833 self.ldb.set_dsheuristics("123ABC-+!1asdfg@#^")
2834 self.assertEquals(self.ldb.get_dsheuristics(), "123ABC-+!1asdfg@#^")
2835 finally:
2836 # restore old value
2837 self.ldb.set_dsheuristics(dsheuristics)
2839 def test_ldapControlReturn(self):
2840 """Testing that if we request a control that return a control it
2841 really return something"""
2842 res = self.ldb.search(attrs=["cn"],
2843 controls=["paged_results:1:10"])
2844 self.assertEquals(len(res.controls), 1)
2845 self.assertEquals(res.controls[0].oid, "1.2.840.113556.1.4.319")
2846 s = str(res.controls[0])
2848 def test_operational(self):
2849 """Tests operational attributes"""
2850 # Tests operational attributes"
2852 res = self.ldb.search(self.base_dn, scope=SCOPE_BASE,
2853 attrs=["createTimeStamp", "modifyTimeStamp",
2854 "structuralObjectClass", "whenCreated",
2855 "whenChanged"])
2856 self.assertEquals(len(res), 1)
2857 self.assertTrue("createTimeStamp" in res[0])
2858 self.assertTrue("modifyTimeStamp" in res[0])
2859 self.assertTrue("structuralObjectClass" in res[0])
2860 self.assertTrue("whenCreated" in res[0])
2861 self.assertTrue("whenChanged" in res[0])
2863 def test_timevalues1(self):
2864 """Tests possible syntax of time attributes"""
2866 user_name = "testtimevaluesuser1"
2867 user_dn = "CN=%s,CN=Users,%s" % (user_name, self.base_dn)
2869 delete_force(self.ldb, user_dn)
2870 self.ldb.add({ "dn": user_dn,
2871 "objectClass": "user",
2872 "sAMAccountName": user_name })
2875 # We check the following values:
2877 # 370101000000Z => 20370101000000.0Z
2878 # 20370102000000.*Z => 20370102000000.0Z
2880 ext = [ "Z", ".0Z", ".Z", ".000Z", ".RandomIgnoredCharacters...987654321Z" ]
2881 for i in range(0, len(ext)):
2882 v_raw = "203701%02d000000" % (i + 1)
2883 if ext[i] == "Z":
2884 v_set = v_raw[2:] + ext[i]
2885 else:
2886 v_set = v_raw + ext[i]
2887 v_get = v_raw + ".0Z"
2889 m = Message()
2890 m.dn = Dn(ldb, user_dn)
2891 m["msTSExpireDate"] = MessageElement([v_set],
2892 FLAG_MOD_REPLACE,
2893 "msTSExpireDate")
2894 self.ldb.modify(m)
2896 res = self.ldb.search(base=user_dn, scope=SCOPE_BASE, attrs=["msTSExpireDate"])
2897 self.assertTrue(len(res) == 1)
2898 self.assertTrue("msTSExpireDate" in res[0])
2899 self.assertTrue(len(res[0]["msTSExpireDate"]) == 1)
2900 self.assertEquals(res[0]["msTSExpireDate"][0], v_get)
2902 class BaseDnTests(samba.tests.TestCase):
2904 def setUp(self):
2905 super(BaseDnTests, self).setUp()
2906 self.ldb = ldb
2908 def test_rootdse_attrs(self):
2909 """Testing for all rootDSE attributes"""
2910 res = self.ldb.search("", scope=SCOPE_BASE, attrs=[])
2911 self.assertEquals(len(res), 1)
2913 def test_highestcommittedusn(self):
2914 """Testing for highestCommittedUSN"""
2915 res = self.ldb.search("", scope=SCOPE_BASE, attrs=["highestCommittedUSN"])
2916 self.assertEquals(len(res), 1)
2917 self.assertTrue(int(res[0]["highestCommittedUSN"][0]) != 0)
2919 def test_netlogon(self):
2920 """Testing for netlogon via LDAP"""
2921 res = self.ldb.search("", scope=SCOPE_BASE, attrs=["netlogon"])
2922 self.assertEquals(len(res), 0)
2924 def test_netlogon_highestcommitted_usn(self):
2925 """Testing for netlogon and highestCommittedUSN via LDAP"""
2926 res = self.ldb.search("", scope=SCOPE_BASE,
2927 attrs=["netlogon", "highestCommittedUSN"])
2928 self.assertEquals(len(res), 0)
2930 def test_namingContexts(self):
2931 """Testing for namingContexts in rootDSE"""
2932 res = self.ldb.search("", scope=SCOPE_BASE,
2933 attrs=["namingContexts", "defaultNamingContext", "schemaNamingContext", "configurationNamingContext"])
2934 self.assertEquals(len(res), 1)
2936 ncs = set([])
2937 for nc in res[0]["namingContexts"]:
2938 self.assertTrue(nc not in ncs)
2939 ncs.add(nc)
2941 self.assertTrue(res[0]["defaultNamingContext"][0] in ncs)
2942 self.assertTrue(res[0]["configurationNamingContext"][0] in ncs)
2943 self.assertTrue(res[0]["schemaNamingContext"][0] in ncs)
2945 def test_serverPath(self):
2946 """Testing the server paths in rootDSE"""
2947 res = self.ldb.search("", scope=SCOPE_BASE,
2948 attrs=["dsServiceName", "serverName"])
2949 self.assertEquals(len(res), 1)
2951 self.assertTrue("CN=Servers" in res[0]["dsServiceName"][0])
2952 self.assertTrue("CN=Sites" in res[0]["dsServiceName"][0])
2953 self.assertTrue("CN=NTDS Settings" in res[0]["dsServiceName"][0])
2954 self.assertTrue("CN=Servers" in res[0]["serverName"][0])
2955 self.assertTrue("CN=Sites" in res[0]["serverName"][0])
2956 self.assertFalse("CN=NTDS Settings" in res[0]["serverName"][0])
2958 def test_functionality(self):
2959 """Testing the server paths in rootDSE"""
2960 res = self.ldb.search("", scope=SCOPE_BASE,
2961 attrs=["forestFunctionality", "domainFunctionality", "domainControllerFunctionality"])
2962 self.assertEquals(len(res), 1)
2963 self.assertEquals(len(res[0]["forestFunctionality"]), 1)
2964 self.assertEquals(len(res[0]["domainFunctionality"]), 1)
2965 self.assertEquals(len(res[0]["domainControllerFunctionality"]), 1)
2967 self.assertTrue(int(res[0]["forestFunctionality"][0]) <= int(res[0]["domainFunctionality"][0]))
2968 self.assertTrue(int(res[0]["domainControllerFunctionality"][0]) >= int(res[0]["domainFunctionality"][0]))
2970 res2 = self.ldb.search("", scope=SCOPE_BASE,
2971 attrs=["dsServiceName", "serverName"])
2972 self.assertEquals(len(res2), 1)
2973 self.assertEquals(len(res2[0]["dsServiceName"]), 1)
2975 res3 = self.ldb.search(res2[0]["dsServiceName"][0], scope=SCOPE_BASE, attrs=["msDS-Behavior-Version"])
2976 self.assertEquals(len(res3), 1)
2977 self.assertEquals(len(res3[0]["msDS-Behavior-Version"]), 1)
2978 self.assertEquals(int(res[0]["domainControllerFunctionality"][0]), int(res3[0]["msDS-Behavior-Version"][0]))
2980 res4 = self.ldb.search(ldb.domain_dn(), scope=SCOPE_BASE, attrs=["msDS-Behavior-Version"])
2981 self.assertEquals(len(res4), 1)
2982 self.assertEquals(len(res4[0]["msDS-Behavior-Version"]), 1)
2983 self.assertEquals(int(res[0]["domainFunctionality"][0]), int(res4[0]["msDS-Behavior-Version"][0]))
2985 res5 = self.ldb.search("cn=partitions,%s" % ldb.get_config_basedn(), scope=SCOPE_BASE, attrs=["msDS-Behavior-Version"])
2986 self.assertEquals(len(res5), 1)
2987 self.assertEquals(len(res5[0]["msDS-Behavior-Version"]), 1)
2988 self.assertEquals(int(res[0]["forestFunctionality"][0]), int(res5[0]["msDS-Behavior-Version"][0]))
2990 def test_dnsHostname(self):
2991 """Testing the DNS hostname in rootDSE"""
2992 res = self.ldb.search("", scope=SCOPE_BASE,
2993 attrs=["dnsHostName", "serverName"])
2994 self.assertEquals(len(res), 1)
2996 res2 = self.ldb.search(res[0]["serverName"][0], scope=SCOPE_BASE,
2997 attrs=["dNSHostName"])
2998 self.assertEquals(len(res2), 1)
3000 self.assertEquals(res[0]["dnsHostName"][0], res2[0]["dNSHostName"][0])
3002 def test_ldapServiceName(self):
3003 """Testing the ldap service name in rootDSE"""
3004 res = self.ldb.search("", scope=SCOPE_BASE,
3005 attrs=["ldapServiceName", "dnsHostName"])
3006 self.assertEquals(len(res), 1)
3007 self.assertTrue("ldapServiceName" in res[0])
3008 self.assertTrue("dnsHostName" in res[0])
3010 (hostname, _, dns_domainname) = res[0]["dnsHostName"][0].partition(".")
3012 given = res[0]["ldapServiceName"][0]
3013 expected = "%s:%s$@%s" % (dns_domainname.lower(), hostname.lower(), dns_domainname.upper())
3014 self.assertEquals(given, expected)
3016 if not "://" in host:
3017 if os.path.isfile(host):
3018 host = "tdb://%s" % host
3019 else:
3020 host = "ldap://%s" % host
3022 ldb = SamDB(host, credentials=creds, session_info=system_session(lp), lp=lp)
3023 if not "tdb://" in host:
3024 gc_ldb = Ldb("%s:3268" % host, credentials=creds,
3025 session_info=system_session(lp), lp=lp)
3026 else:
3027 gc_ldb = None
3029 TestProgram(module=__name__, opts=subunitopts)