s4:ldap.py - add some "objectclass" behaviour tests
[Samba.git] / source4 / lib / ldb / tests / python / ldap.py
blobfa902a0c9170dd54eb49b0c5ad956fef0cd9d5f7
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 # This is a port of the original in testprogs/ejs/ldap.js
5 import optparse
6 import sys
7 import time
8 import base64
9 import os
11 sys.path.append("bin/python")
13 import samba.getopt as options
15 from samba.auth import system_session
16 from ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError
17 from ldb import ERR_NO_SUCH_OBJECT, ERR_ATTRIBUTE_OR_VALUE_EXISTS
18 from ldb import ERR_ENTRY_ALREADY_EXISTS, ERR_UNWILLING_TO_PERFORM
19 from ldb import ERR_NOT_ALLOWED_ON_NON_LEAF, ERR_OTHER, ERR_INVALID_DN_SYNTAX
20 from ldb import ERR_NO_SUCH_ATTRIBUTE
21 from ldb import ERR_OBJECT_CLASS_VIOLATION, ERR_NOT_ALLOWED_ON_RDN
22 from ldb import ERR_NAMING_VIOLATION, ERR_CONSTRAINT_VIOLATION
23 from ldb import ERR_UNDEFINED_ATTRIBUTE_TYPE
24 from ldb import Message, MessageElement, Dn
25 from ldb import FLAG_MOD_ADD, FLAG_MOD_REPLACE, FLAG_MOD_DELETE
26 from samba import Ldb
27 from samba.dsdb import (UF_NORMAL_ACCOUNT, UF_WORKSTATION_TRUST_ACCOUNT,
28 UF_PASSWD_NOTREQD, UF_ACCOUNTDISABLE, ATYPE_NORMAL_ACCOUNT,
29 ATYPE_WORKSTATION_TRUST)
31 from subunit.run import SubunitTestRunner
32 import unittest
34 from samba.ndr import ndr_pack, ndr_unpack
35 from samba.dcerpc import security
37 parser = optparse.OptionParser("ldap [options] <host>")
38 sambaopts = options.SambaOptions(parser)
39 parser.add_option_group(sambaopts)
40 parser.add_option_group(options.VersionOptions(parser))
41 # use command line creds if available
42 credopts = options.CredentialsOptions(parser)
43 parser.add_option_group(credopts)
44 opts, args = parser.parse_args()
46 if len(args) < 1:
47 parser.print_usage()
48 sys.exit(1)
50 host = args[0]
52 lp = sambaopts.get_loadparm()
53 creds = credopts.get_credentials(lp)
55 class BasicTests(unittest.TestCase):
57 def delete_force(self, ldb, dn):
58 try:
59 ldb.delete(dn)
60 except LdbError, (num, _):
61 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
63 def find_basedn(self, ldb):
64 res = ldb.search(base="", expression="", scope=SCOPE_BASE,
65 attrs=["defaultNamingContext"])
66 self.assertEquals(len(res), 1)
67 return res[0]["defaultNamingContext"][0]
69 def find_configurationdn(self, ldb):
70 res = ldb.search(base="", expression="", scope=SCOPE_BASE, attrs=["configurationNamingContext"])
71 self.assertEquals(len(res), 1)
72 return res[0]["configurationNamingContext"][0]
74 def find_schemadn(self, ldb):
75 res = ldb.search(base="", expression="", scope=SCOPE_BASE, attrs=["schemaNamingContext"])
76 self.assertEquals(len(res), 1)
77 return res[0]["schemaNamingContext"][0]
79 def find_domain_sid(self):
80 res = self.ldb.search(base=self.base_dn, expression="(objectClass=*)", scope=SCOPE_BASE)
81 return ndr_unpack( security.dom_sid,res[0]["objectSid"][0])
83 def setUp(self):
84 self.ldb = ldb
85 self.gc_ldb = gc_ldb
86 self.base_dn = self.find_basedn(ldb)
87 self.configuration_dn = self.find_configurationdn(ldb)
88 self.schema_dn = self.find_schemadn(ldb)
89 self.domain_sid = self.find_domain_sid()
91 print "baseDN: %s\n" % self.base_dn
93 self.delete_force(self.ldb, "cn=posixuser,cn=users," + self.base_dn)
94 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
95 self.delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
96 self.delete_force(self.ldb, "cn=ldaptestuser3,cn=users," + self.base_dn)
97 self.delete_force(self.ldb, "cn=ldaptestuser4,cn=ldaptestcontainer," + self.base_dn)
98 self.delete_force(self.ldb, "cn=ldaptestuser4,cn=ldaptestcontainer2," + self.base_dn)
99 self.delete_force(self.ldb, "cn=ldaptestuser5,cn=users," + self.base_dn)
100 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
101 self.delete_force(self.ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
102 self.delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
103 self.delete_force(self.ldb, "cn=ldaptest2computer,cn=computers," + self.base_dn)
104 self.delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
105 self.delete_force(self.ldb, "cn=ldaptestutf8user èùéìòà,cn=users," + self.base_dn)
106 self.delete_force(self.ldb, "cn=ldaptestutf8user2 èùéìòà,cn=users," + self.base_dn)
107 self.delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
108 self.delete_force(self.ldb, "cn=ldaptestcontainer2," + self.base_dn)
109 self.delete_force(self.ldb, "cn=parentguidtest,cn=users," + self.base_dn)
110 self.delete_force(self.ldb, "cn=parentguidtest,cn=testotherusers," + self.base_dn)
111 self.delete_force(self.ldb, "cn=testotherusers," + self.base_dn)
112 self.delete_force(self.ldb, "cn=ldaptestobject," + self.base_dn)
113 self.delete_force(self.ldb, "description=xyz,cn=users," + self.base_dn)
114 self.delete_force(self.ldb, "ou=testou,cn=users," + self.base_dn)
116 def test_objectclasses(self):
117 """Test objectClass behaviour"""
118 print "Test objectClass behaviour"""
120 # Invalid objectclass specified
121 try:
122 self.ldb.add({
123 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
124 "objectClass": "X" })
125 self.fail()
126 except LdbError, (num, _):
127 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
129 # We cannot instanciate from an abstract objectclass
130 try:
131 self.ldb.add({
132 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
133 "objectClass": "connectionPoint" })
134 self.fail()
135 except LdbError, (num, _):
136 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
138 self.ldb.add({
139 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
140 "objectClass": "person" })
142 # We can remove derivation classes of the structural objectclass
143 # but they're going to be readded afterwards
144 m = Message()
145 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
146 m["objectClass"] = MessageElement("top", FLAG_MOD_DELETE,
147 "objectClass")
148 ldb.modify(m)
150 res = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
151 scope=SCOPE_BASE, attrs=["objectClass"])
152 self.assertTrue(len(res) == 1)
153 self.assertTrue("top" in res[0]["objectClass"])
155 # The top-most structural class cannot be deleted since there are
156 # attributes of it in use
157 m = Message()
158 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
159 m["objectClass"] = MessageElement("person", FLAG_MOD_DELETE,
160 "objectClass")
161 try:
162 ldb.modify(m)
163 self.fail()
164 except LdbError, (num, _):
165 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
167 # We cannot delete classes which weren't specified
168 m = Message()
169 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
170 m["objectClass"] = MessageElement("computer", FLAG_MOD_DELETE,
171 "objectClass")
172 try:
173 ldb.modify(m)
174 self.fail()
175 except LdbError, (num, _):
176 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
178 # An invalid class cannot be added
179 m = Message()
180 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
181 m["objectClass"] = MessageElement("X", FLAG_MOD_ADD,
182 "objectClass")
183 try:
184 ldb.modify(m)
185 self.fail()
186 except LdbError, (num, _):
187 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
189 # The top-most structural class cannot be changed by adding another
190 # structural one
191 m = Message()
192 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
193 m["objectClass"] = MessageElement("user", FLAG_MOD_ADD,
194 "objectClass")
195 try:
196 ldb.modify(m)
197 self.fail()
198 except LdbError, (num, _):
199 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
201 # An already specified objectclass cannot be added another time
202 m = Message()
203 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
204 m["objectClass"] = MessageElement("person", FLAG_MOD_ADD,
205 "objectClass")
206 try:
207 ldb.modify(m)
208 self.fail()
209 except LdbError, (num, _):
210 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
212 # Auxiliary classes can always be added
213 m = Message()
214 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
215 m["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_ADD,
216 "objectClass")
217 ldb.modify(m)
219 # It's only possible to replace with the same objectclass combination.
220 # So the replace action on "objectClass" attributes is really useless.
221 m = Message()
222 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
223 m["objectClass"] = MessageElement(["top", "person", "bootableDevice"],
224 FLAG_MOD_REPLACE, "objectClass")
225 ldb.modify(m)
227 m = Message()
228 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
229 m["objectClass"] = MessageElement(["person", "bootableDevice"],
230 FLAG_MOD_REPLACE, "objectClass")
231 ldb.modify(m)
233 m = Message()
234 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
235 m["objectClass"] = MessageElement(["top", "person", "bootableDevice",
236 "connectionPoint"], FLAG_MOD_REPLACE, "objectClass")
237 try:
238 ldb.modify(m)
239 self.fail()
240 except LdbError, (num, _):
241 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
243 m = Message()
244 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
245 m["objectClass"] = MessageElement(["top", "computer"], FLAG_MOD_REPLACE,
246 "objectClass")
247 try:
248 ldb.modify(m)
249 self.fail()
250 except LdbError, (num, _):
251 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
253 # Classes can be removed unless attributes of them are used.
254 m = Message()
255 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
256 m["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_DELETE,
257 "objectClass")
258 ldb.modify(m)
260 res = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
261 scope=SCOPE_BASE, attrs=["objectClass"])
262 self.assertTrue(len(res) == 1)
263 self.assertFalse("bootableDevice" in res[0]["objectClass"])
265 m = Message()
266 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
267 m["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_ADD,
268 "objectClass")
269 ldb.modify(m)
271 # Add an attribute specific to the "bootableDevice" class
272 m = Message()
273 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
274 m["bootParameter"] = MessageElement("test", FLAG_MOD_ADD,
275 "bootParameter")
276 ldb.modify(m)
278 # Classes can be removed unless attributes of them are used. Now there
279 # exist such attributes on the entry.
280 m = Message()
281 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
282 m["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_DELETE,
283 "objectClass")
284 try:
285 ldb.modify(m)
286 self.fail()
287 except LdbError, (num, _):
288 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
290 # Remove the previously specified attribute
291 m = Message()
292 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
293 m["bootParameter"] = MessageElement("test", FLAG_MOD_DELETE,
294 "bootParameter")
295 ldb.modify(m)
297 # Classes can be removed unless attributes of them are used.
298 m = Message()
299 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
300 m["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_DELETE,
301 "objectClass")
302 ldb.modify(m)
304 self.delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
306 def test_system_only(self):
307 """Test systemOnly objects"""
308 print "Test systemOnly objects"""
310 try:
311 self.ldb.add({
312 "dn": "cn=ldaptestobject," + self.base_dn,
313 "objectclass": "configuration"})
314 self.fail()
315 except LdbError, (num, _):
316 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
318 self.delete_force(self.ldb, "cn=ldaptestobject," + self.base_dn)
320 def test_invalid_parent(self):
321 """Test adding an object with invalid parent"""
322 print "Test adding an object with invalid parent"""
324 try:
325 self.ldb.add({
326 "dn": "cn=ldaptestgroup,cn=thisdoesnotexist123,"
327 + self.base_dn,
328 "objectclass": "group"})
329 self.fail()
330 except LdbError, (num, _):
331 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
333 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=thisdoesnotexist123,"
334 + self.base_dn)
336 try:
337 self.ldb.add({
338 "dn": "ou=testou,cn=users," + self.base_dn,
339 "objectclass": "organizationalUnit"})
340 self.fail()
341 except LdbError, (num, _):
342 self.assertEquals(num, ERR_NAMING_VIOLATION)
344 self.delete_force(self.ldb, "ou=testou,cn=users," + self.base_dn)
346 def test_invalid_attribute(self):
347 """Test invalid attributes on schema/objectclasses"""
348 print "Test invalid attributes on schema/objectclasses"""
350 # attributes not in schema test
352 # add operation
354 try:
355 self.ldb.add({
356 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
357 "objectclass": "group",
358 "thisdoesnotexist": "x"})
359 self.fail()
360 except LdbError, (num, _):
361 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
363 self.ldb.add({
364 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
365 "objectclass": "group"})
367 # modify operation
369 m = Message()
370 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
371 m["thisdoesnotexist"] = MessageElement("x", FLAG_MOD_REPLACE,
372 "thisdoesnotexist")
373 try:
374 ldb.modify(m)
375 self.fail()
376 except LdbError, (num, _):
377 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
379 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
381 # attributes not in objectclasses and mandatory attributes missing test
382 # Use here a non-SAM entry since it doesn't have special triggers
383 # associated which have an impact on the error results.
385 # add operations
387 # mandatory attribute missing
388 try:
389 self.ldb.add({
390 "dn": "cn=ldaptestobject," + self.base_dn,
391 "objectclass": "ipProtocol"})
392 self.fail()
393 except LdbError, (num, _):
394 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
396 # inadequate but schema-valid attribute specified
397 try:
398 self.ldb.add({
399 "dn": "cn=ldaptestobject," + self.base_dn,
400 "objectclass": "ipProtocol",
401 "ipProtocolNumber": "1",
402 "uid" : "0"})
403 self.fail()
404 except LdbError, (num, _):
405 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
407 self.ldb.add({
408 "dn": "cn=ldaptestobject," + self.base_dn,
409 "objectclass": "ipProtocol",
410 "ipProtocolNumber": "1"})
412 # modify operations
414 # inadequate but schema-valid attribute add trial
415 m = Message()
416 m.dn = Dn(ldb, "cn=ldaptestobject," + self.base_dn)
417 m["uid"] = MessageElement("0", FLAG_MOD_ADD, "uid")
418 try:
419 ldb.modify(m)
420 self.fail()
421 except LdbError, (num, _):
422 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
424 # mandatory attribute delete trial
425 m = Message()
426 m.dn = Dn(ldb, "cn=ldaptestobject," + self.base_dn)
427 m["ipProtocolNumber"] = MessageElement([], FLAG_MOD_DELETE,
428 "ipProtocolNumber")
429 try:
430 ldb.modify(m)
431 self.fail()
432 except LdbError, (num, _):
433 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
435 # mandatory attribute delete trial
436 m = Message()
437 m.dn = Dn(ldb, "cn=ldaptestobject," + self.base_dn)
438 m["ipProtocolNumber"] = MessageElement([], FLAG_MOD_REPLACE,
439 "ipProtocolNumber")
440 try:
441 ldb.modify(m)
442 self.fail()
443 except LdbError, (num, _):
444 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
446 self.delete_force(self.ldb, "cn=ldaptestobject," + self.base_dn)
448 def test_single_valued_attributes(self):
449 """Test single-valued attributes"""
450 print "Test single-valued attributes"""
452 try:
453 self.ldb.add({
454 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
455 "objectclass": "group",
456 "sAMAccountName": ["nam1", "nam2"]})
457 self.fail()
458 except LdbError, (num, _):
459 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
461 self.ldb.add({
462 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
463 "objectclass": "group"})
465 m = Message()
466 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
467 m["sAMAccountName"] = MessageElement(["nam1","nam2"], FLAG_MOD_REPLACE,
468 "sAMAccountName")
469 try:
470 ldb.modify(m)
471 self.fail()
472 except LdbError, (num, _):
473 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
475 m = Message()
476 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
477 m["sAMAccountName"] = MessageElement("testgroupXX", FLAG_MOD_REPLACE,
478 "sAMAccountName")
479 ldb.modify(m)
481 m = Message()
482 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
483 m["sAMAccountName"] = MessageElement("testgroupXX2", FLAG_MOD_ADD,
484 "sAMAccountName")
485 try:
486 ldb.modify(m)
487 self.fail()
488 except LdbError, (num, _):
489 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
491 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
493 def test_multi_valued_attributes(self):
494 """Test multi-valued attributes"""
495 print "Test multi-valued attributes"""
497 # TODO: In this test I added some special tests where I got very unusual
498 # results back from a real AD. s4 doesn't match them and I've no idea how to
499 # implement those error cases (maybe there exists a special trigger for
500 # "description" attributes which handle them)
502 self.ldb.add({
503 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
504 "description": "desc2",
505 "objectclass": "group",
506 "description": "desc1"})
508 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
510 self.ldb.add({
511 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
512 "objectclass": "group",
513 "description": ["desc1", "desc2"]})
515 # m = Message()
516 # m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
517 # m["description"] = MessageElement(["desc1","desc2"], FLAG_MOD_REPLACE,
518 # "description")
519 # try:
520 # ldb.modify(m)
521 # self.fail()
522 # except LdbError, (num, _):
523 # self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
525 m = Message()
526 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
527 m["description"] = MessageElement("desc1", FLAG_MOD_REPLACE,
528 "description")
529 ldb.modify(m)
531 # m = Message()
532 # m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
533 # m["description"] = MessageElement("desc3", FLAG_MOD_ADD,
534 # "description")
535 # try:
536 # ldb.modify(m)
537 # self.fail()
538 # except LdbError, (num, _):
539 # self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
541 m = Message()
542 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
543 m["description"] = MessageElement(["desc1","desc2"], FLAG_MOD_DELETE,
544 "description")
545 try:
546 ldb.modify(m)
547 self.fail()
548 except LdbError, (num, _):
549 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
551 m = Message()
552 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
553 m["description"] = MessageElement("desc1", FLAG_MOD_DELETE,
554 "description")
555 ldb.modify(m)
557 # m = Message()
558 # m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
559 # m["description"] = MessageElement(["desc1","desc2"], FLAG_MOD_REPLACE,
560 # "description")
561 # try:
562 # ldb.modify(m)
563 # self.fail()
564 # except LdbError, (num, _):
565 # self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
567 # m = Message()
568 # m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
569 # m["description"] = MessageElement(["desc3", "desc4"], FLAG_MOD_ADD,
570 # "description")
571 # try:
572 # ldb.modify(m)
573 # self.fail()
574 # except LdbError, (num, _):
575 # self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
577 m = Message()
578 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
579 m["description"] = MessageElement("desc3", FLAG_MOD_ADD,
580 "description")
581 ldb.modify(m)
583 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
585 def test_empty_messages(self):
586 """Test empty messages"""
587 print "Test empty messages"""
589 m = Message()
590 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
592 try:
593 ldb.add(m)
594 self.fail()
595 except LdbError, (num, _):
596 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
598 try:
599 ldb.modify(m)
600 self.fail()
601 except LdbError, (num, _):
602 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
604 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
606 def test_empty_attributes(self):
607 """Test empty attributes"""
608 print "Test empty attributes"""
610 m = Message()
611 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
612 m["objectClass"] = MessageElement("group", FLAG_MOD_ADD, "objectClass")
613 m["description"] = MessageElement([], FLAG_MOD_ADD, "description")
615 try:
616 ldb.add(m)
617 self.fail()
618 except LdbError, (num, _):
619 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
621 self.ldb.add({
622 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
623 "objectclass": "group"})
625 m = Message()
626 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
627 m["description"] = MessageElement([], FLAG_MOD_ADD, "description")
629 try:
630 ldb.modify(m)
631 self.fail()
632 except LdbError, (num, _):
633 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
635 m = Message()
636 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
637 m["description"] = MessageElement([], FLAG_MOD_REPLACE, "description")
638 ldb.modify(m)
640 m = Message()
641 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
642 m["description"] = MessageElement([], FLAG_MOD_DELETE, "description")
643 try:
644 ldb.modify(m)
645 self.fail()
646 except LdbError, (num, _):
647 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
649 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
651 def test_distinguished_name(self):
652 """Tests the 'distinguishedName' attribute"""
653 print "Tests the 'distinguishedName' attribute"""
655 self.ldb.add({
656 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
657 "objectclass": "group"})
659 m = Message()
660 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
661 m["distinguishedName"] = MessageElement(
662 "cn=ldaptestuser,cn=users," + self.base_dn, FLAG_MOD_ADD,
663 "distinguishedName")
665 try:
666 ldb.modify(m)
667 self.fail()
668 except LdbError, (num, _):
669 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
671 m = Message()
672 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
673 m["distinguishedName"] = MessageElement(
674 "cn=ldaptestuser,cn=users," + self.base_dn, FLAG_MOD_REPLACE,
675 "distinguishedName")
677 try:
678 ldb.modify(m)
679 self.fail()
680 except LdbError, (num, _):
681 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
683 m = Message()
684 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
685 m["distinguishedName"] = MessageElement(
686 "cn=ldaptestuser,cn=users," + self.base_dn, FLAG_MOD_DELETE,
687 "distinguishedName")
689 try:
690 ldb.modify(m)
691 self.fail()
692 except LdbError, (num, _):
693 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
695 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
697 def test_rdn_name(self):
698 """Tests the RDN"""
699 print "Tests the RDN"""
701 try:
702 self.ldb.add({
703 "dn": "description=xyz,cn=users," + self.base_dn,
704 "objectclass": "group"})
705 self.fail()
706 except LdbError, (num, _):
707 self.assertEquals(num, ERR_NAMING_VIOLATION)
709 self.delete_force(self.ldb, "description=xyz,cn=users," + self.base_dn)
711 # a wrong "name" attribute is obviously tolerated
712 self.ldb.add({
713 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
714 "objectclass": "group",
715 "name": "ldaptestgroupx"})
717 m = Message()
718 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
719 m["name"] = MessageElement("cn=ldaptestuser", FLAG_MOD_REPLACE,
720 "name")
722 try:
723 ldb.modify(m)
724 self.fail()
725 except LdbError, (num, _):
726 self.assertEquals(num, ERR_NOT_ALLOWED_ON_RDN)
728 m = Message()
729 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
730 m["cn"] = MessageElement("ldaptestuser",
731 FLAG_MOD_REPLACE, "cn")
733 try:
734 ldb.modify(m)
735 self.fail()
736 except LdbError, (num, _):
737 self.assertEquals(num, ERR_NOT_ALLOWED_ON_RDN)
739 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
742 # this test needs to be disabled until we really understand
743 # what the rDN length constraints are
744 def DISABLED_test_largeRDN(self):
745 """Testing large rDN (limit 64 characters)"""
746 rdn = "CN=a012345678901234567890123456789012345678901234567890123456789012";
747 self.delete_force(self.ldb, "%s,%s" % (rdn, self.base_dn))
748 ldif = """
749 dn: %s,%s""" % (rdn,self.base_dn) + """
750 objectClass: container
752 self.ldb.add_ldif(ldif)
753 self.delete_force(self.ldb, "%s,%s" % (rdn, self.base_dn))
755 rdn = "CN=a0123456789012345678901234567890123456789012345678901234567890120";
756 self.delete_force(self.ldb, "%s,%s" % (rdn, self.base_dn))
757 try:
758 ldif = """
759 dn: %s,%s""" % (rdn,self.base_dn) + """
760 objectClass: container
762 self.ldb.add_ldif(ldif)
763 self.fail()
764 except LdbError, (num, _):
765 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
766 self.delete_force(self.ldb, "%s,%s" % (rdn, self.base_dn))
768 def test_rename(self):
769 """Tests the rename operation"""
770 print "Tests the rename operations"""
772 try:
773 # cannot rename to be a child of itself
774 ldb.rename(self.base_dn, "dc=test," + self.base_dn)
775 self.fail()
776 except LdbError, (num, _):
777 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
779 try:
780 # inexistent object
781 ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser2,cn=users," + self.base_dn)
782 self.fail()
783 except LdbError, (num, _):
784 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
786 self.ldb.add({
787 "dn": "cn=ldaptestuser2,cn=users," + self.base_dn,
788 "objectclass": ["user", "person"] })
790 ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser2,cn=users," + self.base_dn)
791 ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=users," + self.base_dn)
792 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestUSER3,cn=users," + self.base_dn)
794 try:
795 # containment problem: a user entry cannot contain user entries
796 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser4,cn=ldaptestuser3,cn=users," + self.base_dn)
797 self.fail()
798 except LdbError, (num, _):
799 self.assertEquals(num, ERR_NAMING_VIOLATION)
801 try:
802 # invalid parent
803 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=people,cn=users," + self.base_dn)
804 self.fail()
805 except LdbError, (num, _):
806 self.assertEquals(num, ERR_OTHER)
808 try:
809 # invalid target DN syntax
810 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, ",cn=users," + self.base_dn)
811 self.fail()
812 except LdbError, (num, _):
813 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
815 try:
816 # invalid RDN name
817 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "ou=ldaptestuser3,cn=users," + self.base_dn)
818 self.fail()
819 except LdbError, (num, _):
820 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
822 self.delete_force(self.ldb, "cn=ldaptestuser3,cn=users," + self.base_dn)
824 def test_rename_twice(self):
825 """Tests the rename operation twice - this corresponds to a past bug"""
826 print "Tests the rename twice operation"""
828 self.ldb.add({
829 "dn": "cn=ldaptestuser5,cn=users," + self.base_dn,
830 "objectclass": ["user", "person"] })
832 ldb.rename("cn=ldaptestuser5,cn=users," + self.base_dn, "cn=ldaptestUSER5,cn=users," + self.base_dn)
833 self.delete_force(self.ldb, "cn=ldaptestuser5,cn=users," + self.base_dn)
834 self.ldb.add({
835 "dn": "cn=ldaptestuser5,cn=users," + self.base_dn,
836 "objectclass": ["user", "person"] })
837 ldb.rename("cn=ldaptestuser5,cn=Users," + self.base_dn, "cn=ldaptestUSER5,cn=users," + self.base_dn)
838 res = ldb.search(expression="cn=ldaptestuser5")
839 print "Found %u records" % len(res)
840 self.assertEquals(len(res), 1, "Wrong number of hits for cn=ldaptestuser5")
841 res = ldb.search(expression="(&(cn=ldaptestuser5)(objectclass=user))")
842 print "Found %u records" % len(res)
843 self.assertEquals(len(res), 1, "Wrong number of hits for (&(cn=ldaptestuser5)(objectclass=user))")
844 self.delete_force(self.ldb, "cn=ldaptestuser5,cn=users," + self.base_dn)
846 def test_parentGUID(self):
847 """Test parentGUID behaviour"""
848 print "Testing parentGUID behaviour\n"
850 # TODO: This seems to fail on Windows Server. Hidden attribute?
852 self.ldb.add({
853 "dn": "cn=parentguidtest,cn=users," + self.base_dn,
854 "objectclass":"user",
855 "samaccountname":"parentguidtest"});
856 res1 = ldb.search(base="cn=parentguidtest,cn=users," + self.base_dn, scope=SCOPE_BASE,
857 attrs=["parentGUID", "samaccountname"]);
858 res2 = ldb.search(base="cn=users," + self.base_dn,scope=SCOPE_BASE,
859 attrs=["objectGUID"]);
860 res3 = ldb.search(base=self.base_dn, scope=SCOPE_BASE,
861 attrs=["parentGUID"]);
863 """Check if the parentGUID is valid """
864 self.assertEquals(res1[0]["parentGUID"], res2[0]["objectGUID"]);
866 """Check if it returns nothing when there is no parent object"""
867 has_parentGUID = False
868 for key in res3[0].keys():
869 if key == "parentGUID":
870 has_parentGUID = True
871 break
872 self.assertFalse(has_parentGUID);
874 """Ensures that if you look for another object attribute after the constructed
875 parentGUID, it will return correctly"""
876 has_another_attribute = False
877 for key in res1[0].keys():
878 if key == "sAMAccountName":
879 has_another_attribute = True
880 break
881 self.assertTrue(has_another_attribute)
882 self.assertTrue(len(res1[0]["samaccountname"]) == 1)
883 self.assertEquals(res1[0]["samaccountname"][0], "parentguidtest");
885 print "Testing parentGUID behaviour on rename\n"
887 self.ldb.add({
888 "dn": "cn=testotherusers," + self.base_dn,
889 "objectclass":"container"});
890 res1 = ldb.search(base="cn=testotherusers," + self.base_dn,scope=SCOPE_BASE,
891 attrs=["objectGUID"]);
892 ldb.rename("cn=parentguidtest,cn=users," + self.base_dn,
893 "cn=parentguidtest,cn=testotherusers," + self.base_dn);
894 res2 = ldb.search(base="cn=parentguidtest,cn=testotherusers," + self.base_dn,
895 scope=SCOPE_BASE,
896 attrs=["parentGUID"]);
897 self.assertEquals(res1[0]["objectGUID"], res2[0]["parentGUID"]);
899 self.delete_force(self.ldb, "cn=parentguidtest,cn=testotherusers," + self.base_dn)
900 self.delete_force(self.ldb, "cn=testotherusers," + self.base_dn)
902 def test_groupType_int32(self):
903 """Test groupType (int32) behaviour (should appear to be casted to a 32 bit signed integer before comparsion)"""
904 print "Testing groupType (int32) behaviour\n"
906 res1 = ldb.search(base=self.base_dn, scope=SCOPE_SUBTREE,
907 attrs=["groupType"], expression="groupType=2147483653");
909 res2 = ldb.search(base=self.base_dn, scope=SCOPE_SUBTREE,
910 attrs=["groupType"], expression="groupType=-2147483643");
912 self.assertEquals(len(res1), len(res2))
914 self.assertTrue(res1.count > 0)
916 self.assertEquals(res1[0]["groupType"][0], "-2147483643")
918 def test_groups(self):
919 """This tests the group behaviour (setting, changing) of a user account"""
920 print "Testing group behaviour\n"
922 ldb.add({
923 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
924 "objectclass": "group"})
926 ldb.add({
927 "dn": "cn=ldaptestgroup2,cn=users," + self.base_dn,
928 "objectclass": "group"})
930 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
931 scope=SCOPE_BASE, attrs=["objectSID"])
932 self.assertTrue(len(res1) == 1)
933 group_rid_1 = security.dom_sid(ldb.schema_format_value("objectSID",
934 res1[0]["objectSID"][0])).split()[1]
936 res1 = ldb.search("cn=ldaptestgroup2,cn=users," + self.base_dn,
937 scope=SCOPE_BASE, attrs=["objectSID"])
938 self.assertTrue(len(res1) == 1)
939 group_rid_2 = security.dom_sid(ldb.schema_format_value("objectSID",
940 res1[0]["objectSID"][0])).split()[1]
942 # Try to create a user with an invalid primary group
943 try:
944 ldb.add({
945 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
946 "objectclass": ["user", "person"],
947 "primaryGroupID": "0"})
948 self.fail()
949 except LdbError, (num, _):
950 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
951 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
953 # Try to Create a user with a valid primary group
954 # TODO Some more investigation needed here
955 # try:
956 # ldb.add({
957 # "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
958 # "objectclass": ["user", "person"],
959 # "primaryGroupID": str(group_rid_1)})
960 # self.fail()
961 # except LdbError, (num, _):
962 # self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
963 # self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
965 # Test to see how we should behave when the user account doesn't
966 # exist
967 m = Message()
968 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
969 m["primaryGroupID"] = MessageElement("0", FLAG_MOD_REPLACE,
970 "primaryGroupID")
971 try:
972 ldb.modify(m)
973 self.fail()
974 except LdbError, (num, _):
975 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
977 # Test to see how we should behave when the account isn't a user
978 m = Message()
979 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
980 m["primaryGroupID"] = MessageElement("0", FLAG_MOD_REPLACE,
981 "primaryGroupID")
982 try:
983 ldb.modify(m)
984 self.fail()
985 except LdbError, (num, _):
986 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
988 ldb.add({
989 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
990 "objectclass": ["user", "person"]})
992 # Try to add invalid primary group
993 m = Message()
994 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
995 m["primaryGroupID"] = MessageElement("0", FLAG_MOD_REPLACE,
996 "primaryGroupID")
997 try:
998 ldb.modify(m)
999 self.fail()
1000 except LdbError, (num, _):
1001 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1003 # Try to make group 1 primary - should be denied since it is not yet
1004 # secondary
1005 m = Message()
1006 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1007 m["primaryGroupID"] = MessageElement(str(group_rid_1),
1008 FLAG_MOD_REPLACE, "primaryGroupID")
1009 try:
1010 ldb.modify(m)
1011 self.fail()
1012 except LdbError, (num, _):
1013 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1015 # Make group 1 secondary
1016 m = Message()
1017 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1018 m["member"] = MessageElement("cn=ldaptestuser,cn=users," + self.base_dn,
1019 FLAG_MOD_REPLACE, "member")
1020 ldb.modify(m)
1022 # Make group 1 primary
1023 m = Message()
1024 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1025 m["primaryGroupID"] = MessageElement(str(group_rid_1),
1026 FLAG_MOD_REPLACE, "primaryGroupID")
1027 ldb.modify(m)
1029 # Try to delete group 1 - should be denied
1030 try:
1031 ldb.delete("cn=ldaptestgroup,cn=users," + self.base_dn)
1032 self.fail()
1033 except LdbError, (num, _):
1034 self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
1036 # Try to add group 1 also as secondary - should be denied
1037 m = Message()
1038 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1039 m["member"] = MessageElement("cn=ldaptestuser,cn=users," + self.base_dn,
1040 FLAG_MOD_ADD, "member")
1041 try:
1042 ldb.modify(m)
1043 self.fail()
1044 except LdbError, (num, _):
1045 self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
1047 # Try to add invalid member to group 1 - should be denied
1048 m = Message()
1049 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1050 m["member"] = MessageElement(
1051 "cn=ldaptestuser3,cn=users," + self.base_dn,
1052 FLAG_MOD_ADD, "member")
1053 try:
1054 ldb.modify(m)
1055 self.fail()
1056 except LdbError, (num, _):
1057 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
1059 # Make group 2 secondary
1060 m = Message()
1061 m.dn = Dn(ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
1062 m["member"] = MessageElement("cn=ldaptestuser,cn=users," + self.base_dn,
1063 FLAG_MOD_ADD, "member")
1064 ldb.modify(m)
1066 # Swap the groups
1067 m = Message()
1068 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1069 m["primaryGroupID"] = MessageElement(str(group_rid_2),
1070 FLAG_MOD_REPLACE, "primaryGroupID")
1071 ldb.modify(m)
1073 # Old primary group should contain a "member" attribute for the user,
1074 # the new shouldn't contain anymore one
1075 res1 = ldb.search("cn=ldaptestgroup, cn=users," + self.base_dn,
1076 scope=SCOPE_BASE, attrs=["member"])
1077 self.assertTrue(len(res1) == 1)
1078 self.assertTrue(len(res1[0]["member"]) == 1)
1079 self.assertEquals(res1[0]["member"][0].lower(),
1080 ("cn=ldaptestuser,cn=users," + self.base_dn).lower())
1082 res1 = ldb.search("cn=ldaptestgroup2, cn=users," + self.base_dn,
1083 scope=SCOPE_BASE, attrs=["member"])
1084 self.assertTrue(len(res1) == 1)
1085 self.assertFalse("member" in res1[0])
1087 # Also this should be denied
1088 try:
1089 ldb.add({
1090 "dn": "cn=ldaptestuser1,cn=users," + self.base_dn,
1091 "objectclass": ["user", "person"],
1092 "primaryGroupID": "0"})
1093 self.fail()
1094 except LdbError, (num, _):
1095 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1097 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1098 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1099 self.delete_force(self.ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
1101 def test_sam_attributes(self):
1102 """Test the behaviour of special attributes of SAM objects"""
1103 print "Testing the behaviour of special attributes of SAM objects\n"""
1105 ldb.add({
1106 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1107 "objectclass": ["user", "person"]})
1108 ldb.add({
1109 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
1110 "objectclass": "group"})
1112 m = Message()
1113 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1114 m["groupType"] = MessageElement("0", FLAG_MOD_ADD,
1115 "groupType")
1116 try:
1117 ldb.modify(m)
1118 self.fail()
1119 except LdbError, (num, _):
1120 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
1122 m = Message()
1123 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1124 m["groupType"] = MessageElement([], FLAG_MOD_DELETE,
1125 "groupType")
1126 try:
1127 ldb.modify(m)
1128 self.fail()
1129 except LdbError, (num, _):
1130 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1132 m = Message()
1133 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1134 m["primaryGroupID"] = MessageElement("0", FLAG_MOD_ADD,
1135 "primaryGroupID")
1136 try:
1137 ldb.modify(m)
1138 self.fail()
1139 except LdbError, (num, _):
1140 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
1142 m = Message()
1143 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1144 m["primaryGroupID"] = MessageElement([], FLAG_MOD_DELETE,
1145 "primaryGroupID")
1146 try:
1147 ldb.modify(m)
1148 self.fail()
1149 except LdbError, (num, _):
1150 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1152 m = Message()
1153 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1154 m["userAccountControl"] = MessageElement("0", FLAG_MOD_ADD,
1155 "userAccountControl")
1156 try:
1157 ldb.modify(m)
1158 self.fail()
1159 except LdbError, (num, _):
1160 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
1162 m = Message()
1163 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1164 m["userAccountControl"] = MessageElement([], FLAG_MOD_DELETE,
1165 "userAccountControl")
1166 try:
1167 ldb.modify(m)
1168 self.fail()
1169 except LdbError, (num, _):
1170 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1172 m = Message()
1173 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1174 m["sAMAccountType"] = MessageElement("0", FLAG_MOD_ADD,
1175 "sAMAccountType")
1176 try:
1177 ldb.modify(m)
1178 self.fail()
1179 except LdbError, (num, _):
1180 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1182 m = Message()
1183 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1184 m["sAMAccountType"] = MessageElement([], FLAG_MOD_REPLACE,
1185 "sAMAccountType")
1186 try:
1187 ldb.modify(m)
1188 self.fail()
1189 except LdbError, (num, _):
1190 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1192 m = Message()
1193 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1194 m["sAMAccountType"] = MessageElement([], FLAG_MOD_DELETE,
1195 "sAMAccountType")
1196 try:
1197 ldb.modify(m)
1198 self.fail()
1199 except LdbError, (num, _):
1200 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1202 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1203 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1205 def test_primary_group_token_constructed(self):
1206 """Test the primary group token behaviour (hidden-generated-readonly attribute on groups) and some other constructed attributes"""
1207 print "Testing primary group token behaviour and other constructed attributes\n"
1209 try:
1210 ldb.add({
1211 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
1212 "objectclass": "group",
1213 "primaryGroupToken": "100"})
1214 self.fail()
1215 except LdbError, (num, _):
1216 self.assertEquals(num, ERR_UNDEFINED_ATTRIBUTE_TYPE)
1217 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1219 ldb.add({
1220 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1221 "objectclass": ["user", "person"]})
1223 ldb.add({
1224 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
1225 "objectclass": "group"})
1227 # Testing for one invalid, and one valid operational attribute, but also the things they are built from
1228 res1 = ldb.search(self.base_dn,
1229 scope=SCOPE_BASE, attrs=["primaryGroupToken", "canonicalName", "objectClass", "objectSid"])
1230 self.assertTrue(len(res1) == 1)
1231 self.assertFalse("primaryGroupToken" in res1[0])
1232 self.assertTrue("canonicalName" in res1[0])
1233 self.assertTrue("objectClass" in res1[0])
1234 self.assertTrue("objectSid" in res1[0])
1236 res1 = ldb.search(self.base_dn,
1237 scope=SCOPE_BASE, attrs=["primaryGroupToken", "canonicalName"])
1238 self.assertTrue(len(res1) == 1)
1239 self.assertFalse("primaryGroupToken" in res1[0])
1240 self.assertFalse("objectSid" in res1[0])
1241 self.assertFalse("objectClass" in res1[0])
1242 self.assertTrue("canonicalName" in res1[0])
1244 res1 = ldb.search("cn=users,"+self.base_dn,
1245 scope=SCOPE_BASE, attrs=["primaryGroupToken"])
1246 self.assertTrue(len(res1) == 1)
1247 self.assertFalse("primaryGroupToken" in res1[0])
1249 res1 = ldb.search("cn=ldaptestuser, cn=users," + self.base_dn,
1250 scope=SCOPE_BASE, attrs=["primaryGroupToken"])
1251 self.assertTrue(len(res1) == 1)
1252 self.assertFalse("primaryGroupToken" in res1[0])
1254 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
1255 scope=SCOPE_BASE)
1256 self.assertTrue(len(res1) == 1)
1257 self.assertFalse("primaryGroupToken" in res1[0])
1259 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
1260 scope=SCOPE_BASE, attrs=["primaryGroupToken", "objectSID"])
1261 self.assertTrue(len(res1) == 1)
1262 primary_group_token = int(res1[0]["primaryGroupToken"][0])
1264 rid = security.dom_sid(ldb.schema_format_value("objectSID", res1[0]["objectSID"][0])).split()[1]
1265 self.assertEquals(primary_group_token, rid)
1267 m = Message()
1268 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1269 m["primaryGroupToken"] = "100"
1270 try:
1271 ldb.modify(m)
1272 self.fail()
1273 except LdbError, (num, _):
1274 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
1276 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1277 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1279 def test_tokenGroups(self):
1280 """Test the tokenGroups behaviour (hidden-generated-readonly attribute on SAM objects)"""
1281 print "Testing tokenGroups behaviour\n"
1283 # The domain object shouldn't contain any "tokenGroups" entry
1284 res = ldb.search(self.base_dn, scope=SCOPE_BASE, attrs=["tokenGroups"])
1285 self.assertTrue(len(res) == 1)
1286 self.assertFalse("tokenGroups" in res[0])
1288 # The domain administrator should contain "tokenGroups" entries
1289 # (the exact number depends on the domain/forest function level and the
1290 # DC software versions)
1291 res = ldb.search("cn=Administrator,cn=Users," + self.base_dn,
1292 scope=SCOPE_BASE, attrs=["tokenGroups"])
1293 self.assertTrue(len(res) == 1)
1294 self.assertTrue("tokenGroups" in res[0])
1296 ldb.add({
1297 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1298 "objectclass": ["user", "person"]})
1300 # This testuser should contain at least two "tokenGroups" entries
1301 # (exactly two on an unmodified "Domain Users" and "Users" group)
1302 res = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
1303 scope=SCOPE_BASE, attrs=["tokenGroups"])
1304 self.assertTrue(len(res) == 1)
1305 self.assertTrue(len(res[0]["tokenGroups"]) >= 2)
1307 # one entry which we need to find should point to domains "Domain Users"
1308 # group and another entry should point to the builtin "Users"group
1309 domain_users_group_found = False
1310 users_group_found = False
1311 for sid in res[0]["tokenGroups"]:
1312 rid = security.dom_sid(ldb.schema_format_value("objectSID", sid)).split()[1]
1313 if rid == 513:
1314 domain_users_group_found = True
1315 if rid == 545:
1316 users_group_found = True
1318 self.assertTrue(domain_users_group_found)
1319 self.assertTrue(users_group_found)
1321 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1323 def test_wkguid(self):
1324 """Test Well known GUID behaviours (including DN+Binary)"""
1325 print "Test Well known GUID behaviours (including DN+Binary)"""
1327 res = self.ldb.search(base=("<WKGUID=ab1d30f3768811d1aded00c04fd8d5cd,%s>" % self.base_dn), scope=SCOPE_BASE, attrs=[])
1328 self.assertEquals(len(res), 1)
1330 res2 = self.ldb.search(scope=SCOPE_BASE, attrs=["wellKnownObjects"], expression=("wellKnownObjects=B:32:ab1d30f3768811d1aded00c04fd8d5cd:%s" % res[0].dn))
1331 self.assertEquals(len(res2), 1)
1333 # Prove that the matching rule is over the whole DN+Binary
1334 res2 = self.ldb.search(scope=SCOPE_BASE, attrs=["wellKnownObjects"], expression=("wellKnownObjects=B:32:ab1d30f3768811d1aded00c04fd8d5cd"))
1335 self.assertEquals(len(res2), 0)
1336 # Prove that the matching rule is over the whole DN+Binary
1337 res2 = self.ldb.search(scope=SCOPE_BASE, attrs=["wellKnownObjects"], expression=("wellKnownObjects=%s") % res[0].dn)
1338 self.assertEquals(len(res2), 0)
1340 def test_subschemasubentry(self):
1341 """Test subSchemaSubEntry appears when requested, but not when not requested"""
1342 print "Test subSchemaSubEntry"""
1344 res = self.ldb.search(base=self.base_dn, scope=SCOPE_BASE, attrs=["subSchemaSubEntry"])
1345 self.assertEquals(len(res), 1)
1346 self.assertEquals(res[0]["subSchemaSubEntry"][0], "CN=Aggregate,"+self.schema_dn)
1348 res = self.ldb.search(base=self.base_dn, scope=SCOPE_BASE, attrs=["*"])
1349 self.assertEquals(len(res), 1)
1350 self.assertTrue("subScheamSubEntry" not in res[0])
1352 def test_all(self):
1353 """Basic tests"""
1355 print "Testing user add"
1357 ldb.add({
1358 "dn": "cn=ldaptestuser,cn=uSers," + self.base_dn,
1359 "objectclass": ["user", "person"],
1360 "cN": "LDAPtestUSER",
1361 "givenname": "ldap",
1362 "sn": "testy"})
1364 ldb.add({
1365 "dn": "cn=ldaptestgroup,cn=uSers," + self.base_dn,
1366 "objectclass": "group",
1367 "member": "cn=ldaptestuser,cn=useRs," + self.base_dn})
1369 ldb.add({
1370 "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
1371 "objectclass": "computer",
1372 "cN": "LDAPtestCOMPUTER"})
1374 ldb.add({"dn": "cn=ldaptest2computer,cn=computers," + self.base_dn,
1375 "objectClass": "computer",
1376 "cn": "LDAPtest2COMPUTER",
1377 "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT),
1378 "displayname": "ldap testy"})
1380 try:
1381 ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn,
1382 "objectClass": "computer",
1383 "cn": "LDAPtest2COMPUTER"
1385 self.fail()
1386 except LdbError, (num, _):
1387 self.assertEquals(num, ERR_INVALID_DN_SYNTAX)
1389 try:
1390 ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn,
1391 "objectClass": "computer",
1392 "cn": "ldaptestcomputer3",
1393 "sAMAccountType": str(ATYPE_NORMAL_ACCOUNT)
1395 self.fail()
1396 except LdbError, (num, _):
1397 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1399 ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn,
1400 "objectClass": "computer",
1401 "cn": "LDAPtestCOMPUTER3"
1404 print "Testing ldb.search for (&(cn=ldaptestcomputer3)(objectClass=user))";
1405 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestcomputer3)(objectClass=user))");
1406 self.assertEquals(len(res), 1, "Found only %d for (&(cn=ldaptestcomputer3)(objectClass=user))" % len(res))
1408 self.assertEquals(str(res[0].dn), ("CN=ldaptestcomputer3,CN=Computers," + self.base_dn));
1409 self.assertEquals(res[0]["cn"][0], "ldaptestcomputer3");
1410 self.assertEquals(res[0]["name"][0], "ldaptestcomputer3");
1411 self.assertEquals(res[0]["objectClass"][0], "top");
1412 self.assertEquals(res[0]["objectClass"][1], "person");
1413 self.assertEquals(res[0]["objectClass"][2], "organizationalPerson");
1414 self.assertEquals(res[0]["objectClass"][3], "user");
1415 self.assertEquals(res[0]["objectClass"][4], "computer");
1416 self.assertTrue("objectGUID" in res[0])
1417 self.assertTrue("whenCreated" in res[0])
1418 self.assertEquals(res[0]["objectCategory"][0], ("CN=Computer,CN=Schema,CN=Configuration," + self.base_dn));
1419 self.assertEquals(int(res[0]["primaryGroupID"][0]), 513);
1420 self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_NORMAL_ACCOUNT);
1421 self.assertEquals(int(res[0]["userAccountControl"][0]), UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE);
1423 self.delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
1425 print "Testing attribute or value exists behaviour"
1426 try:
1427 ldb.modify_ldif("""
1428 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1429 changetype: modify
1430 replace: servicePrincipalName
1431 servicePrincipalName: host/ldaptest2computer
1432 servicePrincipalName: host/ldaptest2computer
1433 servicePrincipalName: cifs/ldaptest2computer
1434 """)
1435 self.fail()
1436 except LdbError, (num, msg):
1437 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
1439 ldb.modify_ldif("""
1440 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1441 changetype: modify
1442 replace: servicePrincipalName
1443 servicePrincipalName: host/ldaptest2computer
1444 servicePrincipalName: cifs/ldaptest2computer
1445 """)
1446 try:
1447 ldb.modify_ldif("""
1448 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1449 changetype: modify
1450 add: servicePrincipalName
1451 servicePrincipalName: host/ldaptest2computer
1452 """)
1453 self.fail()
1454 except LdbError, (num, msg):
1455 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
1457 print "Testing ranged results"
1458 ldb.modify_ldif("""
1459 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1460 changetype: modify
1461 replace: servicePrincipalName
1462 """)
1464 ldb.modify_ldif("""
1465 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
1466 changetype: modify
1467 add: servicePrincipalName
1468 servicePrincipalName: host/ldaptest2computer0
1469 servicePrincipalName: host/ldaptest2computer1
1470 servicePrincipalName: host/ldaptest2computer2
1471 servicePrincipalName: host/ldaptest2computer3
1472 servicePrincipalName: host/ldaptest2computer4
1473 servicePrincipalName: host/ldaptest2computer5
1474 servicePrincipalName: host/ldaptest2computer6
1475 servicePrincipalName: host/ldaptest2computer7
1476 servicePrincipalName: host/ldaptest2computer8
1477 servicePrincipalName: host/ldaptest2computer9
1478 servicePrincipalName: host/ldaptest2computer10
1479 servicePrincipalName: host/ldaptest2computer11
1480 servicePrincipalName: host/ldaptest2computer12
1481 servicePrincipalName: host/ldaptest2computer13
1482 servicePrincipalName: host/ldaptest2computer14
1483 servicePrincipalName: host/ldaptest2computer15
1484 servicePrincipalName: host/ldaptest2computer16
1485 servicePrincipalName: host/ldaptest2computer17
1486 servicePrincipalName: host/ldaptest2computer18
1487 servicePrincipalName: host/ldaptest2computer19
1488 servicePrincipalName: host/ldaptest2computer20
1489 servicePrincipalName: host/ldaptest2computer21
1490 servicePrincipalName: host/ldaptest2computer22
1491 servicePrincipalName: host/ldaptest2computer23
1492 servicePrincipalName: host/ldaptest2computer24
1493 servicePrincipalName: host/ldaptest2computer25
1494 servicePrincipalName: host/ldaptest2computer26
1495 servicePrincipalName: host/ldaptest2computer27
1496 servicePrincipalName: host/ldaptest2computer28
1497 servicePrincipalName: host/ldaptest2computer29
1498 """)
1500 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE,
1501 attrs=["servicePrincipalName;range=0-*"])
1502 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1503 #print len(res[0]["servicePrincipalName;range=0-*"])
1504 self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30)
1506 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-19"])
1507 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1508 # print res[0]["servicePrincipalName;range=0-19"].length
1509 self.assertEquals(len(res[0]["servicePrincipalName;range=0-19"]), 20)
1512 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-30"])
1513 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1514 self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30)
1516 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-40"])
1517 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1518 self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30)
1520 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=30-40"])
1521 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1522 self.assertEquals(len(res[0]["servicePrincipalName;range=30-*"]), 0)
1525 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=10-40"])
1526 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1527 self.assertEquals(len(res[0]["servicePrincipalName;range=10-*"]), 20)
1528 # pos_11 = res[0]["servicePrincipalName;range=10-*"][18]
1530 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=11-40"])
1531 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1532 self.assertEquals(len(res[0]["servicePrincipalName;range=11-*"]), 19)
1533 # print res[0]["servicePrincipalName;range=11-*"][18]
1534 # print pos_11
1535 # self.assertEquals((res[0]["servicePrincipalName;range=11-*"][18]), pos_11)
1537 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=11-15"])
1538 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1539 self.assertEquals(len(res[0]["servicePrincipalName;range=11-15"]), 5)
1540 # self.assertEquals(res[0]["servicePrincipalName;range=11-15"][4], pos_11)
1542 res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName"])
1543 self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
1544 # print res[0]["servicePrincipalName"][18]
1545 # print pos_11
1546 self.assertEquals(len(res[0]["servicePrincipalName"]), 30)
1547 # self.assertEquals(res[0]["servicePrincipalName"][18], pos_11)
1549 self.delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
1550 ldb.add({
1551 "dn": "cn=ldaptestuser2,cn=useRs," + self.base_dn,
1552 "objectClass": ["person", "user"],
1553 "cn": "LDAPtestUSER2",
1554 "givenname": "testy",
1555 "sn": "ldap user2"})
1557 print "Testing Ambigious Name Resolution"
1558 # Testing ldb.search for (&(anr=ldap testy)(objectClass=user))
1559 res = ldb.search(expression="(&(anr=ldap testy)(objectClass=user))")
1560 self.assertEquals(len(res), 3, "Found only %d of 3 for (&(anr=ldap testy)(objectClass=user))" % len(res))
1562 # Testing ldb.search for (&(anr=testy ldap)(objectClass=user))
1563 res = ldb.search(expression="(&(anr=testy ldap)(objectClass=user))")
1564 self.assertEquals(len(res), 2, "Found only %d of 2 for (&(anr=testy ldap)(objectClass=user))" % len(res))
1566 # Testing ldb.search for (&(anr=ldap)(objectClass=user))
1567 res = ldb.search(expression="(&(anr=ldap)(objectClass=user))")
1568 self.assertEquals(len(res), 4, "Found only %d of 4 for (&(anr=ldap)(objectClass=user))" % len(res))
1570 # Testing ldb.search for (&(anr==ldap)(objectClass=user))
1571 res = ldb.search(expression="(&(anr==ldap)(objectClass=user))")
1572 self.assertEquals(len(res), 1, "Could not find (&(anr==ldap)(objectClass=user)). Found only %d for (&(anr=ldap)(objectClass=user))" % len(res))
1574 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
1575 self.assertEquals(res[0]["cn"][0], "ldaptestuser")
1576 self.assertEquals(str(res[0]["name"]), "ldaptestuser")
1578 # Testing ldb.search for (&(anr=testy)(objectClass=user))
1579 res = ldb.search(expression="(&(anr=testy)(objectClass=user))")
1580 self.assertEquals(len(res), 2, "Found only %d for (&(anr=testy)(objectClass=user))" % len(res))
1582 # Testing ldb.search for (&(anr=testy ldap)(objectClass=user))
1583 res = ldb.search(expression="(&(anr=testy ldap)(objectClass=user))")
1584 self.assertEquals(len(res), 2, "Found only %d for (&(anr=testy ldap)(objectClass=user))" % len(res))
1586 # Testing ldb.search for (&(anr==testy ldap)(objectClass=user))
1587 # this test disabled for the moment, as anr with == tests are not understood
1588 # res = ldb.search(expression="(&(anr==testy ldap)(objectClass=user))")
1589 # self.assertEquals(len(res), 1, "Found only %d for (&(anr==testy ldap)(objectClass=user))" % len(res))
1591 # self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
1592 # self.assertEquals(res[0]["cn"][0], "ldaptestuser")
1593 # self.assertEquals(res[0]["name"][0], "ldaptestuser")
1595 # Testing ldb.search for (&(anr==testy ldap)(objectClass=user))
1596 # res = ldb.search(expression="(&(anr==testy ldap)(objectClass=user))")
1597 # self.assertEquals(len(res), 1, "Could not find (&(anr==testy ldap)(objectClass=user))")
1599 # self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
1600 # self.assertEquals(res[0]["cn"][0], "ldaptestuser")
1601 # self.assertEquals(res[0]["name"][0], "ldaptestuser")
1603 # Testing ldb.search for (&(anr=testy ldap user)(objectClass=user))
1604 res = ldb.search(expression="(&(anr=testy ldap user)(objectClass=user))")
1605 self.assertEquals(len(res), 1, "Could not find (&(anr=testy ldap user)(objectClass=user))")
1607 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
1608 self.assertEquals(str(res[0]["cn"]), "ldaptestuser2")
1609 self.assertEquals(str(res[0]["name"]), "ldaptestuser2")
1611 # Testing ldb.search for (&(anr==testy ldap user2)(objectClass=user))
1612 # res = ldb.search(expression="(&(anr==testy ldap user2)(objectClass=user))")
1613 # self.assertEquals(len(res), 1, "Could not find (&(anr==testy ldap user2)(objectClass=user))")
1615 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
1616 self.assertEquals(str(res[0]["cn"]), "ldaptestuser2")
1617 self.assertEquals(str(res[0]["name"]), "ldaptestuser2")
1619 # Testing ldb.search for (&(anr==ldap user2)(objectClass=user))
1620 # res = ldb.search(expression="(&(anr==ldap user2)(objectClass=user))")
1621 # self.assertEquals(len(res), 1, "Could not find (&(anr==ldap user2)(objectClass=user))")
1623 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
1624 self.assertEquals(str(res[0]["cn"]), "ldaptestuser2")
1625 self.assertEquals(str(res[0]["name"]), "ldaptestuser2")
1627 # Testing ldb.search for (&(anr==not ldap user2)(objectClass=user))
1628 # res = ldb.search(expression="(&(anr==not ldap user2)(objectClass=user))")
1629 # self.assertEquals(len(res), 0, "Must not find (&(anr==not ldap user2)(objectClass=user))")
1631 # Testing ldb.search for (&(anr=not ldap user2)(objectClass=user))
1632 res = ldb.search(expression="(&(anr=not ldap user2)(objectClass=user))")
1633 self.assertEquals(len(res), 0, "Must not find (&(anr=not ldap user2)(objectClass=user))")
1635 # Testing ldb.search for (&(anr="testy ldap")(objectClass=user)) (ie, with quotes)
1636 # res = ldb.search(expression="(&(anr==\"testy ldap\")(objectClass=user))")
1637 # self.assertEquals(len(res), 0, "Found (&(anr==\"testy ldap\")(objectClass=user))")
1639 print "Testing Renames"
1641 attrs = ["objectGUID", "objectSid"]
1642 print "Testing ldb.search for (&(cn=ldaptestUSer2)(objectClass=user))"
1643 res_user = ldb.search(self.base_dn, expression="(&(cn=ldaptestUSer2)(objectClass=user))", scope=SCOPE_SUBTREE, attrs=attrs)
1644 self.assertEquals(len(res_user), 1, "Could not find (&(cn=ldaptestUSer2)(objectClass=user))")
1646 # Check rename works with extended/alternate DN forms
1647 ldb.rename("<SID=" + ldb.schema_format_value("objectSID", res_user[0]["objectSID"][0]) + ">" , "cn=ldaptestUSER3,cn=users," + self.base_dn)
1649 print "Testing ldb.search for (&(cn=ldaptestuser3)(objectClass=user))"
1650 res = ldb.search(expression="(&(cn=ldaptestuser3)(objectClass=user))")
1651 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser3)(objectClass=user))")
1653 self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
1654 self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3")
1655 self.assertEquals(str(res[0]["name"]), "ldaptestUSER3")
1657 #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))"
1658 res = ldb.search(expression="(&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))")
1659 self.assertEquals(len(res), 1, "(&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))")
1661 self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
1662 self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3")
1663 self.assertEquals(str(res[0]["name"]), "ldaptestUSER3")
1665 #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))"
1666 res = ldb.search(expression="(&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))")
1667 self.assertEquals(len(res), 1, "(&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))")
1669 self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
1670 self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3")
1671 self.assertEquals(str(res[0]["name"]), "ldaptestUSER3")
1673 #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))"
1674 res = ldb.search(expression="(&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))")
1675 self.assertEquals(len(res), 0, "(&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))")
1677 # This is a Samba special, and does not exist in real AD
1678 # print "Testing ldb.search for (dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")"
1679 # res = ldb.search("(dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")")
1680 # if (res.error != 0 || len(res) != 1) {
1681 # print "Could not find (dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")"
1682 # self.assertEquals(len(res), 1)
1684 # self.assertEquals(res[0].dn, ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
1685 # self.assertEquals(res[0].cn, "ldaptestUSER3")
1686 # self.assertEquals(res[0].name, "ldaptestUSER3")
1688 print "Testing ldb.search for (distinguishedName=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")"
1689 res = ldb.search(expression="(distinguishedName=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")")
1690 self.assertEquals(len(res), 1, "Could not find (dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")")
1691 self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
1692 self.assertEquals(str(res[0]["cn"]), "ldaptestUSER3")
1693 self.assertEquals(str(res[0]["name"]), "ldaptestUSER3")
1695 # ensure we cannot add it again
1696 try:
1697 ldb.add({"dn": "cn=ldaptestuser3,cn=userS," + self.base_dn,
1698 "objectClass": ["person", "user"],
1699 "cn": "LDAPtestUSER3"})
1700 self.fail()
1701 except LdbError, (num, _):
1702 self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
1704 # rename back
1705 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser2,cn=users," + self.base_dn)
1707 # ensure we cannot rename it twice
1708 try:
1709 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn,
1710 "cn=ldaptestuser2,cn=users," + self.base_dn)
1711 self.fail()
1712 except LdbError, (num, _):
1713 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
1715 # ensure can now use that name
1716 ldb.add({"dn": "cn=ldaptestuser3,cn=users," + self.base_dn,
1717 "objectClass": ["person", "user"],
1718 "cn": "LDAPtestUSER3"})
1720 # ensure we now cannot rename
1721 try:
1722 ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=users," + self.base_dn)
1723 self.fail()
1724 except LdbError, (num, _):
1725 self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
1726 try:
1727 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=configuration," + self.base_dn)
1728 self.fail()
1729 except LdbError, (num, _):
1730 self.assertTrue(num in (71, 64))
1732 ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser5,cn=users," + self.base_dn)
1734 ldb.delete("cn=ldaptestuser5,cn=users," + self.base_dn)
1736 self.delete_force(ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
1738 ldb.rename("cn=ldaptestgroup,cn=users," + self.base_dn, "cn=ldaptestgroup2,cn=users," + self.base_dn)
1740 print "Testing subtree renames"
1742 ldb.add({"dn": "cn=ldaptestcontainer," + self.base_dn,
1743 "objectClass": "container"})
1745 ldb.add({"dn": "CN=ldaptestuser4,CN=ldaptestcontainer," + self.base_dn,
1746 "objectClass": ["person", "user"],
1747 "cn": "LDAPtestUSER4"})
1749 ldb.modify_ldif("""
1750 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
1751 changetype: modify
1752 add: member
1753 member: cn=ldaptestuser4,cn=ldaptestcontainer,""" + self.base_dn + """
1754 member: cn=ldaptestcomputer,cn=computers,""" + self.base_dn + """
1755 member: cn=ldaptestuser2,cn=users,""" + self.base_dn + """
1756 """)
1758 print "Testing ldb.rename of cn=ldaptestcontainer," + self.base_dn + " to cn=ldaptestcontainer2," + self.base_dn
1759 ldb.rename("CN=ldaptestcontainer," + self.base_dn, "CN=ldaptestcontainer2," + self.base_dn)
1761 print "Testing ldb.search for (&(cn=ldaptestuser4)(objectClass=user))"
1762 res = ldb.search(expression="(&(cn=ldaptestuser4)(objectClass=user))")
1763 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser4)(objectClass=user))")
1765 print "Testing subtree ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in (just renamed from) cn=ldaptestcontainer," + self.base_dn
1766 try:
1767 res = ldb.search("cn=ldaptestcontainer," + self.base_dn,
1768 expression="(&(cn=ldaptestuser4)(objectClass=user))",
1769 scope=SCOPE_SUBTREE)
1770 self.fail(res)
1771 except LdbError, (num, _):
1772 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
1774 print "Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in (just renamed from) cn=ldaptestcontainer," + self.base_dn
1775 try:
1776 res = ldb.search("cn=ldaptestcontainer," + self.base_dn,
1777 expression="(&(cn=ldaptestuser4)(objectClass=user))", scope=SCOPE_ONELEVEL)
1778 self.fail()
1779 except LdbError, (num, _):
1780 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
1782 print "Testing ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in renamed container"
1783 res = ldb.search("cn=ldaptestcontainer2," + self.base_dn, expression="(&(cn=ldaptestuser4)(objectClass=user))", scope=SCOPE_SUBTREE)
1784 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser4)(objectClass=user)) under cn=ldaptestcontainer2," + self.base_dn)
1786 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn))
1787 self.assertEquals(res[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
1789 time.sleep(4)
1791 print "Testing ldb.search for (&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn + ")(objectclass=group)) to check subtree renames and linked attributes"
1792 res = ldb.search(self.base_dn, expression="(&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn + ")(objectclass=group))", scope=SCOPE_SUBTREE)
1793 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?")
1795 print "Testing ldb.rename (into itself) of cn=ldaptestcontainer2," + self.base_dn + " to cn=ldaptestcontainer,cn=ldaptestcontainer2," + self.base_dn
1796 try:
1797 ldb.rename("cn=ldaptestcontainer2," + self.base_dn, "cn=ldaptestcontainer,cn=ldaptestcontainer2," + self.base_dn)
1798 self.fail()
1799 except LdbError, (num, _):
1800 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1802 print "Testing ldb.rename (into non-existent container) of cn=ldaptestcontainer2," + self.base_dn + " to cn=ldaptestcontainer,cn=ldaptestcontainer3," + self.base_dn
1803 try:
1804 ldb.rename("cn=ldaptestcontainer2," + self.base_dn, "cn=ldaptestcontainer,cn=ldaptestcontainer3," + self.base_dn)
1805 self.fail()
1806 except LdbError, (num, _):
1807 self.assertTrue(num in (ERR_UNWILLING_TO_PERFORM, ERR_OTHER))
1809 print "Testing delete (should fail, not a leaf node) of renamed cn=ldaptestcontainer2," + self.base_dn
1810 try:
1811 ldb.delete("cn=ldaptestcontainer2," + self.base_dn)
1812 self.fail()
1813 except LdbError, (num, _):
1814 self.assertEquals(num, ERR_NOT_ALLOWED_ON_NON_LEAF)
1816 print "Testing base ldb.search for CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn
1817 res = ldb.search(expression="(objectclass=*)", base=("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn), scope=SCOPE_BASE)
1818 self.assertEquals(len(res), 1)
1819 res = ldb.search(expression="(cn=ldaptestuser40)", base=("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn), scope=SCOPE_BASE)
1820 self.assertEquals(len(res), 0)
1822 print "Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in cn=ldaptestcontainer2," + self.base_dn
1823 res = ldb.search(expression="(&(cn=ldaptestuser4)(objectClass=user))", base=("cn=ldaptestcontainer2," + self.base_dn), scope=SCOPE_ONELEVEL)
1824 # FIXME: self.assertEquals(len(res), 0)
1826 print "Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in cn=ldaptestcontainer2," + self.base_dn
1827 res = ldb.search(expression="(&(cn=ldaptestuser4)(objectClass=user))", base=("cn=ldaptestcontainer2," + self.base_dn), scope=SCOPE_SUBTREE)
1828 # FIXME: self.assertEquals(len(res), 0)
1830 print "Testing delete of subtree renamed "+("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn)
1831 ldb.delete(("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn))
1832 print "Testing delete of renamed cn=ldaptestcontainer2," + self.base_dn
1833 ldb.delete("cn=ldaptestcontainer2," + self.base_dn)
1835 ldb.add({"dn": "cn=ldaptestutf8user èùéìòà,cn=users," + self.base_dn, "objectClass": "user"})
1837 ldb.add({"dn": "cn=ldaptestutf8user2 èùéìòà,cn=users," + self.base_dn, "objectClass": "user"})
1839 print "Testing ldb.search for (&(cn=ldaptestuser)(objectClass=user))"
1840 res = ldb.search(expression="(&(cn=ldaptestuser)(objectClass=user))")
1841 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser)(objectClass=user))")
1843 self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
1844 self.assertEquals(str(res[0]["cn"]), "ldaptestuser")
1845 self.assertEquals(str(res[0]["name"]), "ldaptestuser")
1846 self.assertEquals(set(res[0]["objectClass"]), set(["top", "person", "organizationalPerson", "user"]))
1847 self.assertTrue("objectGUID" in res[0])
1848 self.assertTrue("whenCreated" in res[0])
1849 self.assertEquals(str(res[0]["objectCategory"]), ("CN=Person,CN=Schema,CN=Configuration," + self.base_dn))
1850 self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_NORMAL_ACCOUNT)
1851 self.assertEquals(int(res[0]["userAccountControl"][0]), UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE)
1852 self.assertEquals(res[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
1853 self.assertEquals(len(res[0]["memberOf"]), 1)
1855 print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=cn=person,cn=schema,cn=configuration," + self.base_dn + "))"
1856 res2 = ldb.search(expression="(&(cn=ldaptestuser)(objectCategory=cn=person,cn=schema,cn=configuration," + self.base_dn + "))")
1857 self.assertEquals(len(res2), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=cn=person,cn=schema,cn=configuration," + self.base_dn + "))")
1859 self.assertEquals(res[0].dn, res2[0].dn)
1861 print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon))"
1862 res3 = ldb.search(expression="(&(cn=ldaptestuser)(objectCategory=PerSon))")
1863 self.assertEquals(len(res3), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=PerSon)): matched %d" % len(res3))
1865 self.assertEquals(res[0].dn, res3[0].dn)
1867 if gc_ldb is not None:
1868 print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon)) in Global Catalog"
1869 res3gc = gc_ldb.search(expression="(&(cn=ldaptestuser)(objectCategory=PerSon))")
1870 self.assertEquals(len(res3gc), 1)
1872 self.assertEquals(res[0].dn, res3gc[0].dn)
1874 print "Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon)) in with 'phantom root' control"
1876 if gc_ldb is not None:
1877 res3control = gc_ldb.search(self.base_dn, expression="(&(cn=ldaptestuser)(objectCategory=PerSon))", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["search_options:1:2"])
1878 self.assertEquals(len(res3control), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=PerSon)) in Global Catalog")
1880 self.assertEquals(res[0].dn, res3control[0].dn)
1882 ldb.delete(res[0].dn)
1884 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectClass=user))"
1885 res = ldb.search(expression="(&(cn=ldaptestcomputer)(objectClass=user))")
1886 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestuser)(objectClass=user))")
1888 self.assertEquals(str(res[0].dn), ("CN=ldaptestcomputer,CN=Computers," + self.base_dn))
1889 self.assertEquals(str(res[0]["cn"]), "ldaptestcomputer")
1890 self.assertEquals(str(res[0]["name"]), "ldaptestcomputer")
1891 self.assertEquals(set(res[0]["objectClass"]), set(["top", "person", "organizationalPerson", "user", "computer"]))
1892 self.assertTrue("objectGUID" in res[0])
1893 self.assertTrue("whenCreated" in res[0])
1894 self.assertEquals(str(res[0]["objectCategory"]), ("CN=Computer,CN=Schema,CN=Configuration," + self.base_dn))
1895 self.assertEquals(int(res[0]["primaryGroupID"][0]), 513)
1896 self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_NORMAL_ACCOUNT)
1897 self.assertEquals(int(res[0]["userAccountControl"][0]), UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE)
1898 self.assertEquals(res[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
1899 self.assertEquals(len(res[0]["memberOf"]), 1)
1901 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + "))"
1902 res2 = ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + "))")
1903 self.assertEquals(len(res2), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + "))")
1905 self.assertEquals(res[0].dn, res2[0].dn)
1907 if gc_ldb is not None:
1908 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + ")) in Global Catlog"
1909 res2gc = gc_ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + "))")
1910 self.assertEquals(len(res2gc), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + self.base_dn + ")) in Global Catlog")
1912 self.assertEquals(res[0].dn, res2gc[0].dn)
1914 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=compuTER))"
1915 res3 = ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=compuTER))")
1916 self.assertEquals(len(res3), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=compuTER))")
1918 self.assertEquals(res[0].dn, res3[0].dn)
1920 if gc_ldb is not None:
1921 print "Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=compuTER)) in Global Catalog"
1922 res3gc = gc_ldb.search(expression="(&(cn=ldaptestcomputer)(objectCategory=compuTER))")
1923 self.assertEquals(len(res3gc), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=compuTER)) in Global Catalog")
1925 self.assertEquals(res[0].dn, res3gc[0].dn)
1927 print "Testing ldb.search for (&(cn=ldaptestcomp*r)(objectCategory=compuTER))"
1928 res4 = ldb.search(expression="(&(cn=ldaptestcomp*r)(objectCategory=compuTER))")
1929 self.assertEquals(len(res4), 1, "Could not find (&(cn=ldaptestcomp*r)(objectCategory=compuTER))")
1931 self.assertEquals(res[0].dn, res4[0].dn)
1933 print "Testing ldb.search for (&(cn=ldaptestcomput*)(objectCategory=compuTER))"
1934 res5 = ldb.search(expression="(&(cn=ldaptestcomput*)(objectCategory=compuTER))")
1935 self.assertEquals(len(res5), 1, "Could not find (&(cn=ldaptestcomput*)(objectCategory=compuTER))")
1937 self.assertEquals(res[0].dn, res5[0].dn)
1939 print "Testing ldb.search for (&(cn=*daptestcomputer)(objectCategory=compuTER))"
1940 res6 = ldb.search(expression="(&(cn=*daptestcomputer)(objectCategory=compuTER))")
1941 self.assertEquals(len(res6), 1, "Could not find (&(cn=*daptestcomputer)(objectCategory=compuTER))")
1943 self.assertEquals(res[0].dn, res6[0].dn)
1945 ldb.delete("<GUID=" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + ">")
1947 print "Testing ldb.search for (&(cn=ldaptest2computer)(objectClass=user))"
1948 res = ldb.search(expression="(&(cn=ldaptest2computer)(objectClass=user))")
1949 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptest2computer)(objectClass=user))")
1951 self.assertEquals(str(res[0].dn), "CN=ldaptest2computer,CN=Computers," + self.base_dn)
1952 self.assertEquals(str(res[0]["cn"]), "ldaptest2computer")
1953 self.assertEquals(str(res[0]["name"]), "ldaptest2computer")
1954 self.assertEquals(list(res[0]["objectClass"]), ["top", "person", "organizationalPerson", "user", "computer"])
1955 self.assertTrue("objectGUID" in res[0])
1956 self.assertTrue("whenCreated" in res[0])
1957 self.assertEquals(res[0]["objectCategory"][0], "CN=Computer,CN=Schema,CN=Configuration," + self.base_dn)
1958 self.assertEquals(int(res[0]["sAMAccountType"][0]), ATYPE_WORKSTATION_TRUST)
1959 self.assertEquals(int(res[0]["userAccountControl"][0]), UF_WORKSTATION_TRUST_ACCOUNT)
1961 ldb.delete("<SID=" + ldb.schema_format_value("objectSID", res[0]["objectSID"][0]) + ">")
1963 attrs = ["cn", "name", "objectClass", "objectGUID", "objectSID", "whenCreated", "nTSecurityDescriptor", "memberOf", "allowedAttributes", "allowedAttributesEffective"]
1964 print "Testing ldb.search for (&(cn=ldaptestUSer2)(objectClass=user))"
1965 res_user = ldb.search(self.base_dn, expression="(&(cn=ldaptestUSer2)(objectClass=user))", scope=SCOPE_SUBTREE, attrs=attrs)
1966 self.assertEquals(len(res_user), 1, "Could not find (&(cn=ldaptestUSer2)(objectClass=user))")
1968 self.assertEquals(str(res_user[0].dn), ("CN=ldaptestuser2,CN=Users," + self.base_dn))
1969 self.assertEquals(str(res_user[0]["cn"]), "ldaptestuser2")
1970 self.assertEquals(str(res_user[0]["name"]), "ldaptestuser2")
1971 self.assertEquals(list(res_user[0]["objectClass"]), ["top", "person", "organizationalPerson", "user"])
1972 self.assertTrue("objectSid" in res_user[0])
1973 self.assertTrue("objectGUID" in res_user[0])
1974 self.assertTrue("whenCreated" in res_user[0])
1975 self.assertTrue("nTSecurityDescriptor" in res_user[0])
1976 self.assertTrue("allowedAttributes" in res_user[0])
1977 self.assertTrue("allowedAttributesEffective" in res_user[0])
1978 self.assertEquals(res_user[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
1980 ldaptestuser2_sid = res_user[0]["objectSid"][0]
1981 ldaptestuser2_guid = res_user[0]["objectGUID"][0]
1983 attrs = ["cn", "name", "objectClass", "objectGUID", "objectSID", "whenCreated", "nTSecurityDescriptor", "member", "allowedAttributes", "allowedAttributesEffective"]
1984 print "Testing ldb.search for (&(cn=ldaptestgroup2)(objectClass=group))"
1985 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs)
1986 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))")
1988 self.assertEquals(str(res[0].dn), ("CN=ldaptestgroup2,CN=Users," + self.base_dn))
1989 self.assertEquals(str(res[0]["cn"]), "ldaptestgroup2")
1990 self.assertEquals(str(res[0]["name"]), "ldaptestgroup2")
1991 self.assertEquals(list(res[0]["objectClass"]), ["top", "group"])
1992 self.assertTrue("objectGUID" in res[0])
1993 self.assertTrue("objectSid" in res[0])
1994 self.assertTrue("whenCreated" in res[0])
1995 self.assertTrue("nTSecurityDescriptor" in res[0])
1996 self.assertTrue("allowedAttributes" in res[0])
1997 self.assertTrue("allowedAttributesEffective" in res[0])
1998 memberUP = []
1999 for m in res[0]["member"]:
2000 memberUP.append(m.upper())
2001 self.assertTrue(("CN=ldaptestuser2,CN=Users," + self.base_dn).upper() in memberUP)
2003 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs, controls=["extended_dn:1:1"])
2004 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))")
2006 print res[0]["member"]
2007 memberUP = []
2008 for m in res[0]["member"]:
2009 memberUP.append(m.upper())
2010 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()
2012 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)
2014 print "Testing Linked attribute behaviours"
2015 ldb.modify_ldif("""
2016 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2017 changetype: modify
2018 replace: member
2019 member: CN=ldaptestuser2,CN=Users,""" + self.base_dn + """
2020 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
2021 """)
2023 ldb.modify_ldif("""
2024 dn: <GUID=""" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + """>
2025 changetype: modify
2026 replace: member
2027 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
2028 """)
2030 ldb.modify_ldif("""
2031 dn: <SID=""" + ldb.schema_format_value("objectSid", res[0]["objectSid"][0]) + """>
2032 changetype: modify
2033 delete: member
2034 """)
2036 ldb.modify_ldif("""
2037 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2038 changetype: modify
2039 add: member
2040 member: <GUID=""" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + """>
2041 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
2042 """)
2044 ldb.modify_ldif("""
2045 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2046 changetype: modify
2047 replace: member
2048 """)
2050 ldb.modify_ldif("""
2051 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2052 changetype: modify
2053 add: member
2054 member: <SID=""" + ldb.schema_format_value("objectSid", res_user[0]["objectSid"][0]) + """>
2055 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
2056 """)
2058 ldb.modify_ldif("""
2059 dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
2060 changetype: modify
2061 delete: member
2062 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
2063 """)
2065 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs)
2066 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))")
2068 self.assertEquals(str(res[0].dn), ("CN=ldaptestgroup2,CN=Users," + self.base_dn))
2069 self.assertEquals(res[0]["member"][0], ("CN=ldaptestuser2,CN=Users," + self.base_dn))
2070 self.assertEquals(len(res[0]["member"]), 1)
2072 ldb.delete(("CN=ldaptestuser2,CN=Users," + self.base_dn))
2074 time.sleep(4)
2076 attrs = ["cn", "name", "objectClass", "objectGUID", "whenCreated", "nTSecurityDescriptor", "member"]
2077 print "Testing ldb.search for (&(cn=ldaptestgroup2)(objectClass=group)) to check linked delete"
2078 res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs)
2079 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group)) to check linked delete")
2081 self.assertEquals(str(res[0].dn), ("CN=ldaptestgroup2,CN=Users," + self.base_dn))
2082 self.assertTrue("member" not in res[0])
2084 print "Testing ldb.search for (&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))"
2085 # TODO UTF8 users don't seem to work fully anymore
2086 # res = ldb.search(expression="(&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
2087 res = ldb.search(expression="(&(cn=ldaptestutf8user èùéìòà)(objectclass=user))")
2088 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
2090 self.assertEquals(str(res[0].dn), ("CN=ldaptestutf8user èùéìòà,CN=Users," + self.base_dn))
2091 self.assertEquals(str(res[0]["cn"]), "ldaptestutf8user èùéìòà")
2092 self.assertEquals(str(res[0]["name"]), "ldaptestutf8user èùéìòà")
2093 self.assertEquals(list(res[0]["objectClass"]), ["top", "person", "organizationalPerson", "user"])
2094 self.assertTrue("objectGUID" in res[0])
2095 self.assertTrue("whenCreated" in res[0])
2097 ldb.delete(res[0].dn)
2099 print "Testing ldb.search for (&(cn=ldaptestutf8user2*)(objectClass=user))"
2100 res = ldb.search(expression="(&(cn=ldaptestutf8user2*)(objectClass=user))")
2101 self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestutf8user2*)(objectClass=user))")
2103 ldb.delete(res[0].dn)
2105 ldb.delete(("CN=ldaptestgroup2,CN=Users," + self.base_dn))
2107 print "Testing ldb.search for (&(cn=ldaptestutf8user2 ÈÙÉÌÒÀ)(objectClass=user))"
2108 # TODO UTF8 users don't seem to work fully anymore
2109 # res = ldb.search(expression="(&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
2110 # self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
2112 print "Testing that we can't get at the configuration DN from the main search base"
2113 res = ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
2114 self.assertEquals(len(res), 0)
2116 print "Testing that we can get at the configuration DN from the main search base on the LDAP port with the 'phantom root' search_options control"
2117 res = ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["search_options:1:2"])
2118 self.assertTrue(len(res) > 0)
2120 if gc_ldb is not None:
2121 print "Testing that we can get at the configuration DN from the main search base on the GC port with the search_options control == 0"
2123 res = gc_ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["search_options:1:0"])
2124 self.assertTrue(len(res) > 0)
2126 print "Testing that we do find configuration elements in the global catlog"
2127 res = gc_ldb.search(self.base_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
2128 self.assertTrue(len(res) > 0)
2130 print "Testing that we do find configuration elements and user elements at the same time"
2131 res = gc_ldb.search(self.base_dn, expression="(|(objectClass=crossRef)(objectClass=person))", scope=SCOPE_SUBTREE, attrs=["cn"])
2132 self.assertTrue(len(res) > 0)
2134 print "Testing that we do find configuration elements in the global catlog, with the configuration basedn"
2135 res = gc_ldb.search(self.configuration_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
2136 self.assertTrue(len(res) > 0)
2138 print "Testing that we can get at the configuration DN on the main LDAP port"
2139 res = ldb.search(self.configuration_dn, expression="objectClass=crossRef", scope=SCOPE_SUBTREE, attrs=["cn"])
2140 self.assertTrue(len(res) > 0)
2142 print "Testing objectCategory canonacolisation"
2143 res = ldb.search(self.configuration_dn, expression="objectCategory=ntDsDSA", scope=SCOPE_SUBTREE, attrs=["cn"])
2144 self.assertTrue(len(res) > 0, "Didn't find any records with objectCategory=ntDsDSA")
2145 self.assertTrue(len(res) != 0)
2147 res = ldb.search(self.configuration_dn, expression="objectCategory=CN=ntDs-DSA," + self.schema_dn, scope=SCOPE_SUBTREE, attrs=["cn"])
2148 self.assertTrue(len(res) > 0, "Didn't find any records with objectCategory=CN=ntDs-DSA," + self.schema_dn)
2149 self.assertTrue(len(res) != 0)
2151 print "Testing objectClass attribute order on "+ self.base_dn
2152 res = ldb.search(expression="objectClass=domain", base=self.base_dn,
2153 scope=SCOPE_BASE, attrs=["objectClass"])
2154 self.assertEquals(len(res), 1)
2156 self.assertEquals(list(res[0]["objectClass"]), ["top", "domain", "domainDNS"])
2158 # check enumeration
2160 print "Testing ldb.search for objectCategory=person"
2161 res = ldb.search(self.base_dn, expression="objectCategory=person", scope=SCOPE_SUBTREE, attrs=["cn"])
2162 self.assertTrue(len(res) > 0)
2164 print "Testing ldb.search for objectCategory=person with domain scope control"
2165 res = ldb.search(self.base_dn, expression="objectCategory=person", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["domain_scope:1"])
2166 self.assertTrue(len(res) > 0)
2168 print "Testing ldb.search for objectCategory=user"
2169 res = ldb.search(self.base_dn, expression="objectCategory=user", scope=SCOPE_SUBTREE, attrs=["cn"])
2170 self.assertTrue(len(res) > 0)
2172 print "Testing ldb.search for objectCategory=user with domain scope control"
2173 res = ldb.search(self.base_dn, expression="objectCategory=user", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["domain_scope:1"])
2174 self.assertTrue(len(res) > 0)
2176 print "Testing ldb.search for objectCategory=group"
2177 res = ldb.search(self.base_dn, expression="objectCategory=group", scope=SCOPE_SUBTREE, attrs=["cn"])
2178 self.assertTrue(len(res) > 0)
2180 print "Testing ldb.search for objectCategory=group with domain scope control"
2181 res = ldb.search(self.base_dn, expression="objectCategory=group", scope=SCOPE_SUBTREE, attrs=["cn"], controls=["domain_scope:1"])
2182 self.assertTrue(len(res) > 0)
2184 print "Testing creating a user with the posixAccount objectClass"
2185 self.ldb.add_ldif("""dn: cn=posixuser,CN=Users,%s
2186 objectClass: top
2187 objectClass: person
2188 objectClass: posixAccount
2189 objectClass: user
2190 objectClass: organizationalPerson
2191 cn: posixuser
2192 uid: posixuser
2193 sn: posixuser
2194 uidNumber: 10126
2195 gidNumber: 10126
2196 homeDirectory: /home/posixuser
2197 loginShell: /bin/bash
2198 gecos: Posix User;;;
2199 description: A POSIX user"""% (self.base_dn))
2201 print "Testing removing the posixAccount objectClass from an existing user"
2202 self.ldb.modify_ldif("""dn: cn=posixuser,CN=Users,%s
2203 changetype: modify
2204 delete: objectClass
2205 objectClass: posixAccount"""% (self.base_dn))
2207 print "Testing adding the posixAccount objectClass to an existing user"
2208 self.ldb.modify_ldif("""dn: cn=posixuser,CN=Users,%s
2209 changetype: modify
2210 add: objectClass
2211 objectClass: posixAccount"""% (self.base_dn))
2213 self.delete_force(self.ldb, "cn=posixuser,cn=users," + self.base_dn)
2214 self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
2215 self.delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
2216 self.delete_force(self.ldb, "cn=ldaptestuser3,cn=users," + self.base_dn)
2217 self.delete_force(self.ldb, "cn=ldaptestuser4,cn=ldaptestcontainer," + self.base_dn)
2218 self.delete_force(self.ldb, "cn=ldaptestuser4,cn=ldaptestcontainer2," + self.base_dn)
2219 self.delete_force(self.ldb, "cn=ldaptestuser5,cn=users," + self.base_dn)
2220 self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
2221 self.delete_force(self.ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
2222 self.delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2223 self.delete_force(self.ldb, "cn=ldaptest2computer,cn=computers," + self.base_dn)
2224 self.delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
2225 self.delete_force(self.ldb, "cn=ldaptestutf8user èùéìòà,cn=users," + self.base_dn)
2226 self.delete_force(self.ldb, "cn=ldaptestutf8user2 èùéìòà,cn=users," + self.base_dn)
2227 self.delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
2228 self.delete_force(self.ldb, "cn=ldaptestcontainer2," + self.base_dn)
2230 def test_security_descriptor_add(self):
2231 """ Testing ldb.add_ldif() for nTSecurityDescriptor """
2232 user_name = "testdescriptoruser1"
2233 user_dn = "CN=%s,CN=Users,%s" % (user_name, self.base_dn)
2235 # Test add_ldif() with SDDL security descriptor input
2237 self.delete_force(self.ldb, user_dn)
2238 try:
2239 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2240 self.ldb.add_ldif("""
2241 dn: """ + user_dn + """
2242 objectclass: user
2243 sAMAccountName: """ + user_name + """
2244 nTSecurityDescriptor: """ + sddl)
2245 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2246 desc = res[0]["nTSecurityDescriptor"][0]
2247 desc = ndr_unpack( security.descriptor, desc )
2248 desc_sddl = desc.as_sddl( self.domain_sid )
2249 self.assertEqual(desc_sddl, sddl)
2250 finally:
2251 self.delete_force(self.ldb, user_dn)
2253 # Test add_ldif() with BASE64 security descriptor
2255 try:
2256 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2257 desc = security.descriptor.from_sddl(sddl, self.domain_sid)
2258 desc_binary = ndr_pack(desc)
2259 desc_base64 = base64.b64encode(desc_binary)
2260 self.ldb.add_ldif("""
2261 dn: """ + user_dn + """
2262 objectclass: user
2263 sAMAccountName: """ + user_name + """
2264 nTSecurityDescriptor:: """ + desc_base64)
2265 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2266 desc = res[0]["nTSecurityDescriptor"][0]
2267 desc = ndr_unpack(security.descriptor, desc)
2268 desc_sddl = desc.as_sddl(self.domain_sid)
2269 self.assertEqual(desc_sddl, sddl)
2270 finally:
2271 self.delete_force(self.ldb, user_dn)
2273 def test_security_descriptor_add_neg(self):
2274 """Test add_ldif() with BASE64 security descriptor input using WRONG domain SID
2275 Negative test
2277 user_name = "testdescriptoruser1"
2278 user_dn = "CN=%s,CN=Users,%s" % (user_name, self.base_dn)
2279 self.delete_force(self.ldb, user_dn)
2280 try:
2281 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2282 desc = security.descriptor.from_sddl(sddl, security.dom_sid('S-1-5-21'))
2283 desc_base64 = base64.b64encode( ndr_pack(desc) )
2284 self.ldb.add_ldif("""
2285 dn: """ + user_dn + """
2286 objectclass: user
2287 sAMAccountName: """ + user_name + """
2288 nTSecurityDescriptor:: """ + desc_base64)
2289 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2290 self.assertTrue("nTSecurityDescriptor" in res[0])
2291 finally:
2292 self.delete_force(self.ldb, user_dn)
2294 def test_security_descriptor_modify(self):
2295 """ Testing ldb.modify_ldif() for nTSecurityDescriptor """
2296 user_name = "testdescriptoruser2"
2297 user_dn = "CN=%s,CN=Users,%s" % (user_name, self.base_dn)
2299 # Delete user object and test modify_ldif() with SDDL security descriptor input
2300 # Add ACE to the original descriptor test
2302 try:
2303 self.delete_force(self.ldb, user_dn)
2304 self.ldb.add_ldif("""
2305 dn: """ + user_dn + """
2306 objectclass: user
2307 sAMAccountName: """ + user_name)
2308 # Modify descriptor
2309 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2310 desc = res[0]["nTSecurityDescriptor"][0]
2311 desc = ndr_unpack(security.descriptor, desc)
2312 desc_sddl = desc.as_sddl(self.domain_sid)
2313 sddl = desc_sddl[:desc_sddl.find("(")] + "(A;;RPWP;;;AU)" + desc_sddl[desc_sddl.find("("):]
2314 mod = """
2315 dn: """ + user_dn + """
2316 changetype: modify
2317 replace: nTSecurityDescriptor
2318 nTSecurityDescriptor: """ + sddl
2319 self.ldb.modify_ldif(mod)
2320 # Read modified descriptor
2321 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2322 desc = res[0]["nTSecurityDescriptor"][0]
2323 desc = ndr_unpack(security.descriptor, desc)
2324 desc_sddl = desc.as_sddl(self.domain_sid)
2325 self.assertEqual(desc_sddl, sddl)
2326 finally:
2327 self.delete_force(self.ldb, user_dn)
2329 # Test modify_ldif() with SDDL security descriptor input
2330 # New desctiptor test
2332 try:
2333 self.ldb.add_ldif("""
2334 dn: """ + user_dn + """
2335 objectclass: user
2336 sAMAccountName: """ + user_name)
2337 # Modify descriptor
2338 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2339 mod = """
2340 dn: """ + user_dn + """
2341 changetype: modify
2342 replace: nTSecurityDescriptor
2343 nTSecurityDescriptor: """ + sddl
2344 self.ldb.modify_ldif(mod)
2345 # Read modified descriptor
2346 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2347 desc = res[0]["nTSecurityDescriptor"][0]
2348 desc = ndr_unpack(security.descriptor, desc)
2349 desc_sddl = desc.as_sddl(self.domain_sid)
2350 self.assertEqual(desc_sddl, sddl)
2351 finally:
2352 self.delete_force(self.ldb, user_dn)
2354 # Test modify_ldif() with BASE64 security descriptor input
2355 # Add ACE to the original descriptor test
2357 try:
2358 self.ldb.add_ldif("""
2359 dn: """ + user_dn + """
2360 objectclass: user
2361 sAMAccountName: """ + user_name)
2362 # Modify descriptor
2363 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2364 desc = res[0]["nTSecurityDescriptor"][0]
2365 desc = ndr_unpack(security.descriptor, desc)
2366 desc_sddl = desc.as_sddl(self.domain_sid)
2367 sddl = desc_sddl[:desc_sddl.find("(")] + "(A;;RPWP;;;AU)" + desc_sddl[desc_sddl.find("("):]
2368 desc = security.descriptor.from_sddl(sddl, self.domain_sid)
2369 desc_base64 = base64.b64encode(ndr_pack(desc))
2370 mod = """
2371 dn: """ + user_dn + """
2372 changetype: modify
2373 replace: nTSecurityDescriptor
2374 nTSecurityDescriptor:: """ + desc_base64
2375 self.ldb.modify_ldif(mod)
2376 # Read modified descriptor
2377 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2378 desc = res[0]["nTSecurityDescriptor"][0]
2379 desc = ndr_unpack(security.descriptor, desc)
2380 desc_sddl = desc.as_sddl(self.domain_sid)
2381 self.assertEqual(desc_sddl, sddl)
2382 finally:
2383 self.delete_force(self.ldb, user_dn)
2385 # Test modify_ldif() with BASE64 security descriptor input
2386 # New descriptor test
2388 try:
2389 self.delete_force(self.ldb, user_dn)
2390 self.ldb.add_ldif("""
2391 dn: """ + user_dn + """
2392 objectclass: user
2393 sAMAccountName: """ + user_name)
2394 # Modify descriptor
2395 sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2396 desc = security.descriptor.from_sddl(sddl, self.domain_sid)
2397 desc_base64 = base64.b64encode(ndr_pack(desc))
2398 mod = """
2399 dn: """ + user_dn + """
2400 changetype: modify
2401 replace: nTSecurityDescriptor
2402 nTSecurityDescriptor:: """ + desc_base64
2403 self.ldb.modify_ldif(mod)
2404 # Read modified descriptor
2405 res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
2406 desc = res[0]["nTSecurityDescriptor"][0]
2407 desc = ndr_unpack(security.descriptor, desc)
2408 desc_sddl = desc.as_sddl(self.domain_sid)
2409 self.assertEqual(desc_sddl, sddl)
2410 finally:
2411 self.delete_force(self.ldb, user_dn)
2413 class BaseDnTests(unittest.TestCase):
2414 def setUp(self):
2415 self.ldb = ldb
2417 def test_rootdse_attrs(self):
2418 """Testing for all rootDSE attributes"""
2419 res = self.ldb.search(scope=SCOPE_BASE, attrs=[])
2420 self.assertEquals(len(res), 1)
2422 def test_highestcommittedusn(self):
2423 """Testing for highestCommittedUSN"""
2424 res = self.ldb.search("", scope=SCOPE_BASE, attrs=["highestCommittedUSN"])
2425 self.assertEquals(len(res), 1)
2426 self.assertTrue(int(res[0]["highestCommittedUSN"][0]) != 0)
2428 def test_netlogon(self):
2429 """Testing for netlogon via LDAP"""
2430 res = self.ldb.search("", scope=SCOPE_BASE, attrs=["netlogon"])
2431 self.assertEquals(len(res), 0)
2433 def test_netlogon_highestcommitted_usn(self):
2434 """Testing for netlogon and highestCommittedUSN via LDAP"""
2435 res = self.ldb.search("", scope=SCOPE_BASE,
2436 attrs=["netlogon", "highestCommittedUSN"])
2437 self.assertEquals(len(res), 0)
2439 def test_namingContexts(self):
2440 """Testing for namingContexts in rootDSE"""
2441 res = self.ldb.search("", scope=SCOPE_BASE,
2442 attrs=["namingContexts", "defaultNamingContext", "schemaNamingContext", "configurationNamingContext"])
2443 self.assertEquals(len(res), 1)
2445 ncs = set([])
2446 for nc in res[0]["namingContexts"]:
2447 self.assertTrue(nc not in ncs)
2448 ncs.add(nc)
2450 self.assertTrue(res[0]["defaultNamingContext"][0] in ncs)
2451 self.assertTrue(res[0]["configurationNamingContext"][0] in ncs)
2452 self.assertTrue(res[0]["schemaNamingContext"][0] in ncs)
2455 if not "://" in host:
2456 if os.path.isfile(host):
2457 host = "tdb://%s" % host
2458 else:
2459 host = "ldap://%s" % host
2461 ldb = Ldb(host, credentials=creds, session_info=system_session(), lp=lp)
2462 if not "tdb://" in host:
2463 gc_ldb = Ldb("%s:3268" % host, credentials=creds,
2464 session_info=system_session(), lp=lp)
2465 else:
2466 gc_ldb = None
2468 runner = SubunitTestRunner()
2469 rc = 0
2470 if not runner.run(unittest.makeSuite(BaseDnTests)).wasSuccessful():
2471 rc = 1
2472 if not runner.run(unittest.makeSuite(BasicTests)).wasSuccessful():
2473 rc = 1
2474 sys.exit(rc)