2 # -*- coding: utf-8 -*-
3 # This is a port of the original in testprogs/ejs/ldap.js
5 # Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2008-2011
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20 from __future__
import print_function
27 sys
.path
.insert(0, "bin/python")
29 from samba
.tests
.subunitrun
import SubunitOptions
, TestProgram
30 import samba
.getopt
as options
32 from samba
.auth
import system_session
33 from ldb
import SCOPE_SUBTREE
, SCOPE_ONELEVEL
, SCOPE_BASE
, LdbError
34 from ldb
import ERR_NO_SUCH_OBJECT
, ERR_ATTRIBUTE_OR_VALUE_EXISTS
35 from ldb
import ERR_ENTRY_ALREADY_EXISTS
, ERR_UNWILLING_TO_PERFORM
36 from ldb
import ERR_NOT_ALLOWED_ON_NON_LEAF
, ERR_OTHER
, ERR_INVALID_DN_SYNTAX
37 from ldb
import ERR_NO_SUCH_ATTRIBUTE
, ERR_INVALID_ATTRIBUTE_SYNTAX
38 from ldb
import ERR_OBJECT_CLASS_VIOLATION
, ERR_NOT_ALLOWED_ON_RDN
39 from ldb
import ERR_NAMING_VIOLATION
, ERR_CONSTRAINT_VIOLATION
40 from ldb
import Message
, MessageElement
, Dn
41 from ldb
import FLAG_MOD_ADD
, FLAG_MOD_REPLACE
, FLAG_MOD_DELETE
42 from ldb
import timestring
44 from samba
.samdb
import SamDB
45 from samba
.dsdb
import (UF_NORMAL_ACCOUNT
,
46 UF_WORKSTATION_TRUST_ACCOUNT
,
47 UF_PASSWD_NOTREQD
, UF_ACCOUNTDISABLE
, ATYPE_NORMAL_ACCOUNT
,
48 ATYPE_WORKSTATION_TRUST
, SYSTEM_FLAG_DOMAIN_DISALLOW_MOVE
,
49 SYSTEM_FLAG_CONFIG_ALLOW_RENAME
, SYSTEM_FLAG_CONFIG_ALLOW_MOVE
,
50 SYSTEM_FLAG_CONFIG_ALLOW_LIMITED_MOVE
)
52 from samba
.ndr
import ndr_pack
, ndr_unpack
53 from samba
.dcerpc
import security
, lsa
54 from samba
.tests
import delete_force
56 parser
= optparse
.OptionParser("ldap.py [options] <host>")
57 sambaopts
= options
.SambaOptions(parser
)
58 parser
.add_option_group(sambaopts
)
59 parser
.add_option_group(options
.VersionOptions(parser
))
60 # use command line creds if available
61 credopts
= options
.CredentialsOptions(parser
)
62 parser
.add_option_group(credopts
)
63 subunitopts
= SubunitOptions(parser
)
64 parser
.add_option_group(subunitopts
)
65 opts
, args
= parser
.parse_args()
73 lp
= sambaopts
.get_loadparm()
74 creds
= credopts
.get_credentials(lp
)
76 class BasicTests(samba
.tests
.TestCase
):
79 super(BasicTests
, self
).setUp()
82 self
.base_dn
= ldb
.domain_dn()
83 self
.configuration_dn
= ldb
.get_config_basedn().get_linearized()
84 self
.schema_dn
= ldb
.get_schema_basedn().get_linearized()
85 self
.domain_sid
= security
.dom_sid(ldb
.get_domain_sid())
87 delete_force(self
.ldb
, "cn=posixuser,cn=users," + self
.base_dn
)
88 delete_force(self
.ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
89 delete_force(self
.ldb
, "cn=ldaptestuser2,cn=users," + self
.base_dn
)
90 delete_force(self
.ldb
, "cn=ldaptestuser3,cn=users," + self
.base_dn
)
91 delete_force(self
.ldb
, "cn=ldaptestuser4,cn=ldaptestcontainer," + self
.base_dn
)
92 delete_force(self
.ldb
, "cn=ldaptestuser4,cn=ldaptestcontainer2," + self
.base_dn
)
93 delete_force(self
.ldb
, "cn=ldaptestuser5,cn=users," + self
.base_dn
)
94 delete_force(self
.ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
95 delete_force(self
.ldb
, "cn=ldaptestgroup2,cn=users," + self
.base_dn
)
96 delete_force(self
.ldb
, "cn=ldaptestcomputer,cn=computers," + self
.base_dn
)
97 delete_force(self
.ldb
, "cn=ldaptest2computer,cn=computers," + self
.base_dn
)
98 delete_force(self
.ldb
, "cn=ldaptestcomputer3,cn=computers," + self
.base_dn
)
99 delete_force(self
.ldb
, "cn=ldaptestutf8user èùéìòà,cn=users," + self
.base_dn
)
100 delete_force(self
.ldb
, "cn=ldaptestutf8user2 èùéìòà,cn=users," + self
.base_dn
)
101 delete_force(self
.ldb
, "cn=ldaptestcontainer," + self
.base_dn
)
102 delete_force(self
.ldb
, "cn=ldaptestcontainer2," + self
.base_dn
)
103 delete_force(self
.ldb
, "cn=parentguidtest,cn=users," + self
.base_dn
)
104 delete_force(self
.ldb
, "cn=parentguidtest,cn=testotherusers," + self
.base_dn
)
105 delete_force(self
.ldb
, "cn=testotherusers," + self
.base_dn
)
106 delete_force(self
.ldb
, "cn=ldaptestobject," + self
.base_dn
)
107 delete_force(self
.ldb
, "description=xyz,cn=users," + self
.base_dn
)
108 delete_force(self
.ldb
, "ou=testou,cn=users," + self
.base_dn
)
109 delete_force(self
.ldb
, "cn=Test Secret,cn=system," + self
.base_dn
)
110 delete_force(self
.ldb
, "cn=testtimevaluesuser1,cn=users," + self
.base_dn
)
112 def test_objectclasses(self
):
113 """Test objectClass behaviour"""
114 # Invalid objectclass specified
117 "dn": "cn=ldaptestuser,cn=users," + self
.base_dn
,
120 except LdbError
as e1
:
122 self
.assertEquals(num
, ERR_CONSTRAINT_VIOLATION
)
124 # Invalid objectclass specified
127 "dn": "cn=ldaptestuser,cn=users," + self
.base_dn
,
128 "objectClass": "X" })
130 except LdbError
as e2
:
132 self
.assertEquals(num
, ERR_NO_SUCH_ATTRIBUTE
)
134 # Invalid objectCategory specified
137 "dn": "cn=ldaptestuser,cn=users," + self
.base_dn
,
138 "objectClass": "person",
139 "objectCategory": self
.base_dn
})
141 except LdbError
as e3
:
143 self
.assertEquals(num
, ERR_OBJECT_CLASS_VIOLATION
)
145 # Multi-valued "systemFlags"
148 "dn": "cn=ldaptestuser,cn=users," + self
.base_dn
,
149 "objectClass": "person",
150 "systemFlags": ["0", str(SYSTEM_FLAG_DOMAIN_DISALLOW_MOVE
)] })
152 except LdbError
as e4
:
154 self
.assertEquals(num
, ERR_CONSTRAINT_VIOLATION
)
156 # We cannot instanciate from an abstract object class ("connectionPoint"
157 # or "leaf"). In the first case we use "connectionPoint" (subclass of
158 # "leaf") to prevent a naming violation - this returns us a
159 # "ERR_UNWILLING_TO_PERFORM" since it is not structural. In the second
160 # case however we get "ERR_OBJECT_CLASS_VIOLATION" since an abstract
161 # class is also not allowed to be auxiliary.
164 "dn": "cn=ldaptestuser,cn=users," + self
.base_dn
,
165 "objectClass": "connectionPoint" })
167 except LdbError
as e5
:
169 self
.assertEquals(num
, ERR_UNWILLING_TO_PERFORM
)
172 "dn": "cn=ldaptestuser,cn=users," + self
.base_dn
,
173 "objectClass": ["person", "leaf"] })
175 except LdbError
as e6
:
177 self
.assertEquals(num
, ERR_OBJECT_CLASS_VIOLATION
)
179 # Objects instanciated using "satisfied" abstract classes (concrete
180 # subclasses) are allowed
182 "dn": "cn=ldaptestuser,cn=users," + self
.base_dn
,
183 "objectClass": ["top", "leaf", "connectionPoint", "serviceConnectionPoint"] })
185 delete_force(self
.ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
187 # Two disjoint top-most structural object classes aren't allowed
190 "dn": "cn=ldaptestuser,cn=users," + self
.base_dn
,
191 "objectClass": ["person", "container"] })
193 except LdbError
as e7
:
195 self
.assertEquals(num
, ERR_OBJECT_CLASS_VIOLATION
)
197 # Test allowed system flags
199 "dn": "cn=ldaptestuser,cn=users," + self
.base_dn
,
200 "objectClass": "person",
201 "systemFlags": str(~
(SYSTEM_FLAG_CONFIG_ALLOW_RENAME | SYSTEM_FLAG_CONFIG_ALLOW_MOVE | SYSTEM_FLAG_CONFIG_ALLOW_LIMITED_MOVE
)) })
203 res
= ldb
.search("cn=ldaptestuser,cn=users," + self
.base_dn
,
204 scope
=SCOPE_BASE
, attrs
=["systemFlags"])
205 self
.assertTrue(len(res
) == 1)
206 self
.assertEquals(res
[0]["systemFlags"][0], "0")
208 delete_force(self
.ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
211 "dn": "cn=ldaptestuser,cn=users," + self
.base_dn
,
212 "objectClass": "person" })
214 # We can remove derivation classes of the structural objectclass
215 # but they're going to be readded afterwards
217 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
218 m
["objectClass"] = MessageElement("top", FLAG_MOD_DELETE
,
222 res
= ldb
.search("cn=ldaptestuser,cn=users," + self
.base_dn
,
223 scope
=SCOPE_BASE
, attrs
=["objectClass"])
224 self
.assertTrue(len(res
) == 1)
225 self
.assertTrue("top" in res
[0]["objectClass"])
227 # The top-most structural class cannot be deleted since there are
228 # attributes of it in use
230 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
231 m
["objectClass"] = MessageElement("person", FLAG_MOD_DELETE
,
236 except LdbError
as e8
:
238 self
.assertEquals(num
, ERR_OBJECT_CLASS_VIOLATION
)
240 # We cannot delete classes which weren't specified
242 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
243 m
["objectClass"] = MessageElement("computer", FLAG_MOD_DELETE
,
248 except LdbError
as e9
:
250 self
.assertEquals(num
, ERR_NO_SUCH_ATTRIBUTE
)
252 # An invalid class cannot be added
254 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
255 m
["objectClass"] = MessageElement("X", FLAG_MOD_ADD
,
260 except LdbError
as e10
:
262 self
.assertEquals(num
, ERR_NO_SUCH_ATTRIBUTE
)
264 # We cannot add a the new top-most structural class "user" here since
265 # we are missing at least one new mandatory attribute (in this case
268 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
269 m
["objectClass"] = MessageElement("user", FLAG_MOD_ADD
,
274 except LdbError
as e11
:
276 self
.assertEquals(num
, ERR_OBJECT_CLASS_VIOLATION
)
278 # An already specified objectclass cannot be added another time
280 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
281 m
["objectClass"] = MessageElement("person", FLAG_MOD_ADD
,
286 except LdbError
as e12
:
288 self
.assertEquals(num
, ERR_ATTRIBUTE_OR_VALUE_EXISTS
)
290 # Auxiliary classes can always be added
292 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
293 m
["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_ADD
,
297 # This does not work since object class "leaf" is not auxiliary nor it
298 # stands in direct relation to "person" (and it is abstract too!)
300 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
301 m
["objectClass"] = MessageElement("leaf", FLAG_MOD_ADD
,
306 except LdbError
as e13
:
308 self
.assertEquals(num
, ERR_OBJECT_CLASS_VIOLATION
)
310 # Objectclass replace operations can be performed as well
312 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
313 m
["objectClass"] = MessageElement(["top", "person", "bootableDevice"],
314 FLAG_MOD_REPLACE
, "objectClass")
318 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
319 m
["objectClass"] = MessageElement(["person", "bootableDevice"],
320 FLAG_MOD_REPLACE
, "objectClass")
323 # This does not work since object class "leaf" is not auxiliary nor it
324 # stands in direct relation to "person" (and it is abstract too!)
326 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
327 m
["objectClass"] = MessageElement(["top", "person", "bootableDevice",
328 "leaf"], FLAG_MOD_REPLACE
, "objectClass")
332 except LdbError
as e14
:
334 self
.assertEquals(num
, ERR_OBJECT_CLASS_VIOLATION
)
336 # More than one change operation is allowed
338 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
339 m
.add(MessageElement("bootableDevice", FLAG_MOD_DELETE
, "objectClass"))
340 m
.add(MessageElement("bootableDevice", FLAG_MOD_ADD
, "objectClass"))
343 # We cannot remove all object classes by an empty replace
345 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
346 m
["objectClass"] = MessageElement([], FLAG_MOD_REPLACE
, "objectClass")
350 except LdbError
as e15
:
352 self
.assertEquals(num
, ERR_OBJECT_CLASS_VIOLATION
)
355 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
356 m
["objectClass"] = MessageElement(["top", "computer"], FLAG_MOD_REPLACE
,
361 except LdbError
as e16
:
363 self
.assertEquals(num
, ERR_OBJECT_CLASS_VIOLATION
)
365 # Classes can be removed unless attributes of them are used.
367 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
368 m
["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_DELETE
,
372 res
= ldb
.search("cn=ldaptestuser,cn=users," + self
.base_dn
,
373 scope
=SCOPE_BASE
, attrs
=["objectClass"])
374 self
.assertTrue(len(res
) == 1)
375 self
.assertFalse("bootableDevice" in res
[0]["objectClass"])
378 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
379 m
["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_ADD
,
383 # Add an attribute specific to the "bootableDevice" class
385 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
386 m
["bootParameter"] = MessageElement("test", FLAG_MOD_ADD
,
390 # Classes can be removed unless attributes of them are used. Now there
391 # exist such attributes on the entry.
393 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
394 m
["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_DELETE
,
399 except LdbError
as e17
:
401 self
.assertEquals(num
, ERR_OBJECT_CLASS_VIOLATION
)
403 # Remove the previously specified attribute
405 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
406 m
["bootParameter"] = MessageElement("test", FLAG_MOD_DELETE
,
410 # Classes can be removed unless attributes of them are used.
412 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
413 m
["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_DELETE
,
417 delete_force(self
.ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
420 "dn": "cn=ldaptestuser,cn=users," + self
.base_dn
,
421 "objectClass": "user" })
423 # Add a new top-most structural class "container". This does not work
424 # since it stands in no direct relation to the current one.
426 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
427 m
["objectClass"] = MessageElement("container", FLAG_MOD_ADD
,
432 except LdbError
as e18
:
434 self
.assertEquals(num
, ERR_OBJECT_CLASS_VIOLATION
)
436 # Add a new top-most structural class "inetOrgPerson" and remove it
439 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
440 m
["objectClass"] = MessageElement("inetOrgPerson", FLAG_MOD_ADD
,
445 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
446 m
["objectClass"] = MessageElement("inetOrgPerson", FLAG_MOD_DELETE
,
450 # Replace top-most structural class to "inetOrgPerson" and reset it
453 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
454 m
["objectClass"] = MessageElement("inetOrgPerson", FLAG_MOD_REPLACE
,
459 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
460 m
["objectClass"] = MessageElement("user", FLAG_MOD_REPLACE
,
464 # Add a new auxiliary object class "posixAccount" to "ldaptestuser"
466 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
467 m
["objectClass"] = MessageElement("posixAccount", FLAG_MOD_ADD
,
471 # Be sure that "top" is the first and the (most) structural object class
472 # the last value of the "objectClass" attribute - MS-ADTS 3.1.1.1.4
473 res
= ldb
.search("cn=ldaptestuser,cn=users," + self
.base_dn
,
474 scope
=SCOPE_BASE
, attrs
=["objectClass"])
475 self
.assertTrue(len(res
) == 1)
476 self
.assertEquals(res
[0]["objectClass"][0], "top")
477 self
.assertEquals(res
[0]["objectClass"][len(res
[0]["objectClass"])-1], "user")
479 delete_force(self
.ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
481 def test_system_only(self
):
482 """Test systemOnly objects"""
485 "dn": "cn=ldaptestobject," + self
.base_dn
,
486 "objectclass": "configuration"})
488 except LdbError
as e19
:
490 self
.assertEquals(num
, ERR_UNWILLING_TO_PERFORM
)
494 "dn": "cn=Test Secret,cn=system," + self
.base_dn
,
495 "objectclass": "secret"})
497 except LdbError
as e20
:
499 self
.assertEquals(num
, ERR_UNWILLING_TO_PERFORM
)
501 delete_force(self
.ldb
, "cn=ldaptestobject," + self
.base_dn
)
502 delete_force(self
.ldb
, "cn=Test Secret,cn=system," + self
.base_dn
)
504 # Create secret over LSA and try to change it
506 lsa_conn
= lsa
.lsarpc("ncacn_np:%s" % args
[0], lp
, creds
)
507 lsa_handle
= lsa_conn
.OpenPolicy2(system_name
="\\",
508 attr
=lsa
.ObjectAttribute(),
509 access_mask
=security
.SEC_FLAG_MAXIMUM_ALLOWED
)
510 secret_name
= lsa
.String()
511 secret_name
.string
= "G$Test"
512 sec_handle
= lsa_conn
.CreateSecret(handle
=lsa_handle
,
514 access_mask
=security
.SEC_FLAG_MAXIMUM_ALLOWED
)
515 lsa_conn
.Close(lsa_handle
)
518 m
.dn
= Dn(ldb
, "cn=Test Secret,cn=system," + self
.base_dn
)
519 m
["description"] = MessageElement("desc", FLAG_MOD_REPLACE
,
524 except LdbError
as e21
:
526 self
.assertEquals(num
, ERR_UNWILLING_TO_PERFORM
)
528 delete_force(self
.ldb
, "cn=Test Secret,cn=system," + self
.base_dn
)
532 "dn": "cn=ldaptestcontainer," + self
.base_dn
,
533 "objectclass": "container",
534 "isCriticalSystemObject": "TRUE"})
536 except LdbError
as e22
:
538 self
.assertEquals(num
, ERR_UNWILLING_TO_PERFORM
)
541 "dn": "cn=ldaptestcontainer," + self
.base_dn
,
542 "objectclass": "container"})
545 m
.dn
= Dn(ldb
, "cn=ldaptestcontainer," + self
.base_dn
)
546 m
["isCriticalSystemObject"] = MessageElement("TRUE", FLAG_MOD_REPLACE
,
547 "isCriticalSystemObject")
551 except LdbError
as e23
:
553 self
.assertEquals(num
, ERR_UNWILLING_TO_PERFORM
)
555 delete_force(self
.ldb
, "cn=ldaptestcontainer," + self
.base_dn
)
557 # Proof if DC SAM object has "isCriticalSystemObject" set
558 res
= self
.ldb
.search("", scope
=SCOPE_BASE
, attrs
=["serverName"])
559 self
.assertTrue(len(res
) == 1)
560 self
.assertTrue("serverName" in res
[0])
561 res
= self
.ldb
.search(res
[0]["serverName"][0], scope
=SCOPE_BASE
,
562 attrs
=["serverReference"])
563 self
.assertTrue(len(res
) == 1)
564 self
.assertTrue("serverReference" in res
[0])
565 res
= self
.ldb
.search(res
[0]["serverReference"][0], scope
=SCOPE_BASE
,
566 attrs
=["isCriticalSystemObject"])
567 self
.assertTrue(len(res
) == 1)
568 self
.assertTrue("isCriticalSystemObject" in res
[0])
569 self
.assertEquals(res
[0]["isCriticalSystemObject"][0], "TRUE")
571 def test_invalid_parent(self
):
572 """Test adding an object with invalid parent"""
575 "dn": "cn=ldaptestgroup,cn=thisdoesnotexist123,"
577 "objectclass": "group"})
579 except LdbError
as e24
:
581 self
.assertEquals(num
, ERR_NO_SUCH_OBJECT
)
583 delete_force(self
.ldb
, "cn=ldaptestgroup,cn=thisdoesnotexist123,"
588 "dn": "ou=testou,cn=users," + self
.base_dn
,
589 "objectclass": "organizationalUnit"})
591 except LdbError
as e25
:
593 self
.assertEquals(num
, ERR_NAMING_VIOLATION
)
595 delete_force(self
.ldb
, "ou=testou,cn=users," + self
.base_dn
)
597 def test_invalid_attribute(self
):
598 """Test invalid attributes on schema/objectclasses"""
599 # attributes not in schema test
605 "dn": "cn=ldaptestgroup,cn=users," + self
.base_dn
,
606 "objectclass": "group",
607 "thisdoesnotexist": "x"})
609 except LdbError
as e26
:
611 self
.assertEquals(num
, ERR_NO_SUCH_ATTRIBUTE
)
614 "dn": "cn=ldaptestgroup,cn=users," + self
.base_dn
,
615 "objectclass": "group"})
620 m
.dn
= Dn(ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
621 m
["thisdoesnotexist"] = MessageElement("x", FLAG_MOD_REPLACE
,
626 except LdbError
as e27
:
628 self
.assertEquals(num
, ERR_NO_SUCH_ATTRIBUTE
)
631 # When searching the unknown attribute should be ignored
632 expr
= "(|(cn=ldaptestgroup)(thisdoesnotexist=x))"
633 res
= ldb
.search(base
=self
.base_dn
,
636 self
.assertTrue(len(res
) == 1,
637 "Search including unknown attribute failed")
639 delete_force(self
.ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
641 # attributes not in objectclasses and mandatory attributes missing test
642 # Use here a non-SAM entry since it doesn't have special triggers
643 # associated which have an impact on the error results.
647 # mandatory attribute missing
650 "dn": "cn=ldaptestobject," + self
.base_dn
,
651 "objectclass": "ipProtocol"})
653 except LdbError
as e28
:
655 self
.assertEquals(num
, ERR_OBJECT_CLASS_VIOLATION
)
657 # inadequate but schema-valid attribute specified
660 "dn": "cn=ldaptestobject," + self
.base_dn
,
661 "objectclass": "ipProtocol",
662 "ipProtocolNumber": "1",
665 except LdbError
as e29
:
667 self
.assertEquals(num
, ERR_OBJECT_CLASS_VIOLATION
)
670 "dn": "cn=ldaptestobject," + self
.base_dn
,
671 "objectclass": "ipProtocol",
672 "ipProtocolNumber": "1"})
676 # inadequate but schema-valid attribute add trial
678 m
.dn
= Dn(ldb
, "cn=ldaptestobject," + self
.base_dn
)
679 m
["uid"] = MessageElement("0", FLAG_MOD_ADD
, "uid")
683 except LdbError
as e30
:
685 self
.assertEquals(num
, ERR_OBJECT_CLASS_VIOLATION
)
687 # mandatory attribute delete trial
689 m
.dn
= Dn(ldb
, "cn=ldaptestobject," + self
.base_dn
)
690 m
["ipProtocolNumber"] = MessageElement([], FLAG_MOD_DELETE
,
695 except LdbError
as e31
:
697 self
.assertEquals(num
, ERR_OBJECT_CLASS_VIOLATION
)
699 # mandatory attribute delete trial
701 m
.dn
= Dn(ldb
, "cn=ldaptestobject," + self
.base_dn
)
702 m
["ipProtocolNumber"] = MessageElement([], FLAG_MOD_REPLACE
,
707 except LdbError
as e32
:
709 self
.assertEquals(num
, ERR_OBJECT_CLASS_VIOLATION
)
711 delete_force(self
.ldb
, "cn=ldaptestobject," + self
.base_dn
)
713 def test_single_valued_attributes(self
):
714 """Test single-valued attributes"""
717 "dn": "cn=ldaptestgroup,cn=users," + self
.base_dn
,
718 "objectclass": "group",
719 "sAMAccountName": ["nam1", "nam2"]})
721 except LdbError
as e33
:
723 self
.assertEquals(num
, ERR_CONSTRAINT_VIOLATION
)
726 "dn": "cn=ldaptestgroup,cn=users," + self
.base_dn
,
727 "objectclass": "group"})
730 m
.dn
= Dn(ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
731 m
["sAMAccountName"] = MessageElement(["nam1","nam2"], FLAG_MOD_REPLACE
,
736 except LdbError
as e34
:
738 self
.assertEquals(num
, ERR_ATTRIBUTE_OR_VALUE_EXISTS
)
741 m
.dn
= Dn(ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
742 m
["sAMAccountName"] = MessageElement("testgroupXX", FLAG_MOD_REPLACE
,
747 m
.dn
= Dn(ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
748 m
["sAMAccountName"] = MessageElement("testgroupXX2", FLAG_MOD_ADD
,
753 except LdbError
as e35
:
755 self
.assertEquals(num
, ERR_ATTRIBUTE_OR_VALUE_EXISTS
)
757 delete_force(self
.ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
759 def test_single_valued_linked_attributes(self
):
760 """Test managedBy, a single-valued linked attribute.
762 (The single-valuedness of this is enforced differently, in
765 ou
= 'OU=svla,%s' % (self
.base_dn
)
767 delete_force(self
.ldb
, ou
, controls
=['tree_delete:1'])
769 self
.ldb
.add({'objectclass': 'organizationalUnit',
775 m
= "cn=manager%d,%s" % (x
, ou
)
778 "objectclass": "user"})
783 "dn": "cn=group1," + ou
,
784 "objectclass": "group",
785 "managedBy": managers
787 self
.fail("failed to fail to add multiple managedBy attributes")
788 except LdbError
as e36
:
790 self
.assertEquals(num
, ERR_CONSTRAINT_VIOLATION
)
792 managee
= "cn=group2," + ou
795 "objectclass": "group",
796 "managedBy": [managers
[0]]})
799 m
.dn
= Dn(ldb
, managee
)
800 m
["managedBy"] = MessageElement(managers
, FLAG_MOD_REPLACE
,
805 except LdbError
as e37
:
807 self
.assertEquals(num
, ERR_CONSTRAINT_VIOLATION
)
810 m
.dn
= Dn(ldb
, managee
)
811 m
["managedBy"] = MessageElement(managers
[1], FLAG_MOD_REPLACE
,
816 m
.dn
= Dn(ldb
, managee
)
817 m
["managedBy"] = MessageElement(managers
[2], FLAG_MOD_ADD
,
822 except LdbError
as e38
:
824 self
.assertEquals(num
, ERR_ATTRIBUTE_OR_VALUE_EXISTS
)
826 self
.ldb
.delete(ou
, ['tree_delete:1'])
829 def test_multivalued_attributes(self
):
830 """Test multi-valued attributes"""
831 ou
= 'OU=mvattr,%s' % (self
.base_dn
)
832 delete_force(self
.ldb
, ou
, controls
=['tree_delete:1'])
833 self
.ldb
.add({'objectclass': 'organizationalUnit',
836 # beyond 1210, Win2012r2 gives LDAP_ADMIN_LIMIT_EXCEEDED
837 ranges
= (3, 30, 300, 1210)
841 "dn": "cn=ldaptestuser%d,%s" % (n
, ou
),
842 "objectclass": "user",
843 "carLicense": ["car%d" % x
for x
in range(n
)]})
848 m
.dn
= Dn(ldb
, "cn=ldaptestuser%d,%s" % (n
, ou
))
849 m
["carLicense"] = MessageElement(["another"],
855 m
.dn
= Dn(ldb
, "cn=ldaptestuser%d,%s" % (n
, ou
))
856 m
["carLicense"] = MessageElement(["foo%d" % x
for x
in range(4)],
862 m
.dn
= Dn(ldb
, "cn=ldaptestuser%d,%s" % (n
, ou
))
863 m
["carLicense"] = MessageElement(["bar%d" % x
for x
in range(40)],
870 dn
= "cn=ldaptestuser%d,%s" % (n
, ou
)
872 m
["carLicense"] = MessageElement(["replacement"],
879 m
["carLicense"] = MessageElement(["replacement%d" % x
for x
in range(n
)],
886 m
["carLicense"] = MessageElement(["again%d" % x
for x
in range(n
)],
893 m
["carLicense"] = MessageElement(["andagain%d" % x
for x
in range(n
)],
898 self
.ldb
.delete(ou
, ['tree_delete:1'])
901 def test_attribute_ranges(self
):
902 """Test attribute ranges"""
906 "dn": "cn=ldaptestuser,cn=users," + self
.base_dn
,
907 "objectClass": "person",
910 except LdbError
as e39
:
912 self
.assertEquals(num
, ERR_INVALID_ATTRIBUTE_SYNTAX
)
917 # "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
918 # "objectClass": "person",
919 # "sn": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" })
921 # except LdbError, (num, _):
922 # self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
925 "dn": "cn=ldaptestuser,cn=users," + self
.base_dn
,
926 "objectClass": "person" })
930 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
931 m
["sn"] = MessageElement("", FLAG_MOD_REPLACE
, "sn")
935 except LdbError
as e40
:
937 self
.assertEquals(num
, ERR_INVALID_ATTRIBUTE_SYNTAX
)
941 # m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
942 # m["sn"] = MessageElement("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", FLAG_MOD_REPLACE, "sn")
946 # except LdbError, (num, _):
947 # self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
950 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
951 m
["sn"] = MessageElement("x", FLAG_MOD_REPLACE
, "sn")
954 delete_force(self
.ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
956 def test_empty_messages(self
):
957 """Test empty messages"""
959 m
.dn
= Dn(ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
964 except LdbError
as e41
:
966 self
.assertEquals(num
, ERR_OBJECT_CLASS_VIOLATION
)
971 except LdbError
as e42
:
973 self
.assertEquals(num
, ERR_UNWILLING_TO_PERFORM
)
975 delete_force(self
.ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
977 def test_empty_attributes(self
):
978 """Test empty attributes"""
980 m
.dn
= Dn(ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
981 m
["objectClass"] = MessageElement("group", FLAG_MOD_ADD
, "objectClass")
982 m
["description"] = MessageElement([], FLAG_MOD_ADD
, "description")
987 except LdbError
as e43
:
989 self
.assertEquals(num
, ERR_CONSTRAINT_VIOLATION
)
992 "dn": "cn=ldaptestgroup,cn=users," + self
.base_dn
,
993 "objectclass": "group"})
996 m
.dn
= Dn(ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
997 m
["description"] = MessageElement([], FLAG_MOD_ADD
, "description")
1002 except LdbError
as e44
:
1004 self
.assertEquals(num
, ERR_CONSTRAINT_VIOLATION
)
1007 m
.dn
= Dn(ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
1008 m
["description"] = MessageElement([], FLAG_MOD_REPLACE
, "description")
1012 m
.dn
= Dn(ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
1013 m
["description"] = MessageElement([], FLAG_MOD_DELETE
, "description")
1017 except LdbError
as e45
:
1019 self
.assertEquals(num
, ERR_NO_SUCH_ATTRIBUTE
)
1021 delete_force(self
.ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
1023 def test_instanceType(self
):
1024 """Tests the 'instanceType' attribute"""
1025 # The instance type is single-valued
1028 "dn": "cn=ldaptestgroup,cn=users," + self
.base_dn
,
1029 "objectclass": "group",
1030 "instanceType": ["0", "1"]})
1032 except LdbError
as e46
:
1034 self
.assertEquals(num
, ERR_UNWILLING_TO_PERFORM
)
1036 # The head NC flag cannot be set without the write flag
1039 "dn": "cn=ldaptestgroup,cn=users," + self
.base_dn
,
1040 "objectclass": "group",
1041 "instanceType": "1" })
1043 except LdbError
as e47
:
1045 self
.assertEquals(num
, ERR_UNWILLING_TO_PERFORM
)
1047 # We cannot manipulate NCs without the head NC flag
1050 "dn": "cn=ldaptestgroup,cn=users," + self
.base_dn
,
1051 "objectclass": "group",
1052 "instanceType": "32" })
1054 except LdbError
as e48
:
1056 self
.assertEquals(num
, ERR_UNWILLING_TO_PERFORM
)
1059 "dn": "cn=ldaptestgroup,cn=users," + self
.base_dn
,
1060 "objectclass": "group"})
1063 m
.dn
= Dn(ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
1064 m
["instanceType"] = MessageElement("0", FLAG_MOD_REPLACE
,
1069 except LdbError
as e49
:
1071 self
.assertEquals(num
, ERR_CONSTRAINT_VIOLATION
)
1074 m
.dn
= Dn(ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
1075 m
["instanceType"] = MessageElement([], FLAG_MOD_REPLACE
,
1080 except LdbError
as e50
:
1082 self
.assertEquals(num
, ERR_CONSTRAINT_VIOLATION
)
1085 m
.dn
= Dn(ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
1086 m
["instanceType"] = MessageElement([], FLAG_MOD_DELETE
, "instanceType")
1090 except LdbError
as e51
:
1092 self
.assertEquals(num
, ERR_CONSTRAINT_VIOLATION
)
1094 delete_force(self
.ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
1096 #only write is allowed with NC_HEAD for originating updates
1099 "dn": "cn=ldaptestuser2,cn=users," + self
.base_dn
,
1100 "objectclass": "user",
1101 "instanceType": "3" })
1103 except LdbError
as e52
:
1105 self
.assertEquals(num
, ERR_UNWILLING_TO_PERFORM
)
1106 delete_force(self
.ldb
, "cn=ldaptestuser2,cn=users," + self
.base_dn
)
1108 def test_distinguished_name(self
):
1109 """Tests the 'distinguishedName' attribute"""
1110 # The "dn" shortcut isn't supported
1112 m
.dn
= Dn(ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
1113 m
["objectClass"] = MessageElement("group", 0, "objectClass")
1114 m
["dn"] = MessageElement("cn=ldaptestgroup,cn=users," + self
.base_dn
, 0,
1119 except LdbError
as e53
:
1121 self
.assertEquals(num
, ERR_NO_SUCH_ATTRIBUTE
)
1123 # a wrong "distinguishedName" attribute is obviously tolerated
1125 "dn": "cn=ldaptestgroup,cn=users," + self
.base_dn
,
1126 "objectclass": "group",
1127 "distinguishedName": "cn=ldaptest,cn=users," + self
.base_dn
})
1129 # proof if the DN has been set correctly
1130 res
= ldb
.search("cn=ldaptestgroup,cn=users," + self
.base_dn
,
1131 scope
=SCOPE_BASE
, attrs
=["distinguishedName"])
1132 self
.assertTrue(len(res
) == 1)
1133 self
.assertTrue("distinguishedName" in res
[0])
1134 self
.assertTrue(Dn(ldb
, res
[0]["distinguishedName"][0])
1135 == Dn(ldb
, "cn=ldaptestgroup, cn=users," + self
.base_dn
))
1137 # The "dn" shortcut isn't supported
1139 m
.dn
= Dn(ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
1140 m
["dn"] = MessageElement(
1141 "cn=ldaptestgroup,cn=users," + self
.base_dn
, FLAG_MOD_REPLACE
,
1146 except LdbError
as e54
:
1148 self
.assertEquals(num
, ERR_NO_SUCH_ATTRIBUTE
)
1151 m
.dn
= Dn(ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
1152 m
["distinguishedName"] = MessageElement(
1153 "cn=ldaptestuser,cn=users," + self
.base_dn
, FLAG_MOD_ADD
,
1154 "distinguishedName")
1159 except LdbError
as e55
:
1161 self
.assertEquals(num
, ERR_UNWILLING_TO_PERFORM
)
1164 m
.dn
= Dn(ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
1165 m
["distinguishedName"] = MessageElement(
1166 "cn=ldaptestuser,cn=users," + self
.base_dn
, FLAG_MOD_REPLACE
,
1167 "distinguishedName")
1172 except LdbError
as e56
:
1174 self
.assertEquals(num
, ERR_CONSTRAINT_VIOLATION
)
1177 m
.dn
= Dn(ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
1178 m
["distinguishedName"] = MessageElement(
1179 "cn=ldaptestuser,cn=users," + self
.base_dn
, FLAG_MOD_DELETE
,
1180 "distinguishedName")
1185 except LdbError
as e57
:
1187 self
.assertEquals(num
, ERR_UNWILLING_TO_PERFORM
)
1189 delete_force(self
.ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
1191 def test_rdn_name(self
):
1197 self
.ldb
.search("=,cn=users," + self
.base_dn
, scope
=SCOPE_BASE
)
1199 except LdbError
as e58
:
1201 self
.assertEquals(num
, ERR_INVALID_DN_SYNTAX
)
1205 self
.ldb
.search("cn=,cn=users," + self
.base_dn
, scope
=SCOPE_BASE
)
1207 except LdbError
as e59
:
1209 self
.assertEquals(num
, ERR_INVALID_DN_SYNTAX
)
1212 self
.ldb
.search("=ldaptestgroup,cn=users," + self
.base_dn
, scope
=SCOPE_BASE
)
1214 except LdbError
as e60
:
1216 self
.assertEquals(num
, ERR_INVALID_DN_SYNTAX
)
1223 "dn": "=,cn=users," + self
.base_dn
,
1224 "objectclass": "group"})
1226 except LdbError
as e61
:
1228 self
.assertEquals(num
, ERR_INVALID_DN_SYNTAX
)
1233 "dn": "=ldaptestgroup,cn=users," + self
.base_dn
,
1234 "objectclass": "group"})
1236 except LdbError
as e62
:
1238 self
.assertEquals(num
, ERR_INVALID_DN_SYNTAX
)
1243 "dn": "cn=,cn=users," + self
.base_dn
,
1244 "objectclass": "group"})
1246 except LdbError
as e63
:
1248 self
.assertEquals(num
, ERR_INVALID_DN_SYNTAX
)
1250 # a wrong RDN candidate
1253 "dn": "description=xyz,cn=users," + self
.base_dn
,
1254 "objectclass": "group"})
1256 except LdbError
as e64
:
1258 self
.assertEquals(num
, ERR_NAMING_VIOLATION
)
1260 delete_force(self
.ldb
, "description=xyz,cn=users," + self
.base_dn
)
1262 # a wrong "name" attribute is obviously tolerated
1264 "dn": "cn=ldaptestgroup,cn=users," + self
.base_dn
,
1265 "objectclass": "group",
1266 "name": "ldaptestgroupx"})
1268 # proof if the name has been set correctly
1269 res
= ldb
.search("cn=ldaptestgroup,cn=users," + self
.base_dn
,
1270 scope
=SCOPE_BASE
, attrs
=["name"])
1271 self
.assertTrue(len(res
) == 1)
1272 self
.assertTrue("name" in res
[0])
1273 self
.assertTrue(res
[0]["name"][0] == "ldaptestgroup")
1279 m
.dn
= Dn(ldb
, "cn=,cn=users," + self
.base_dn
)
1280 m
["description"] = "test"
1284 except LdbError
as e65
:
1286 self
.assertEquals(num
, ERR_INVALID_DN_SYNTAX
)
1292 self
.ldb
.delete("cn=,cn=users," + self
.base_dn
)
1294 except LdbError
as e66
:
1296 self
.assertEquals(num
, ERR_INVALID_DN_SYNTAX
)
1302 self
.ldb
.rename("cn=ldaptestgroup,cn=users," + self
.base_dn
,
1303 "=,cn=users," + self
.base_dn
)
1305 except LdbError
as e67
:
1307 self
.assertEquals(num
, ERR_INVALID_DN_SYNTAX
)
1309 # new empty RDN name
1311 self
.ldb
.rename("cn=ldaptestgroup,cn=users," + self
.base_dn
,
1312 "=ldaptestgroup,cn=users," + self
.base_dn
)
1314 except LdbError
as e68
:
1316 self
.assertEquals(num
, ERR_INVALID_DN_SYNTAX
)
1318 # new empty RDN value
1320 self
.ldb
.rename("cn=ldaptestgroup,cn=users," + self
.base_dn
,
1321 "cn=,cn=users," + self
.base_dn
)
1323 except LdbError
as e69
:
1325 self
.assertEquals(num
, ERR_NAMING_VIOLATION
)
1327 # new wrong RDN candidate
1329 self
.ldb
.rename("cn=ldaptestgroup,cn=users," + self
.base_dn
,
1330 "description=xyz,cn=users," + self
.base_dn
)
1332 except LdbError
as e70
:
1334 self
.assertEquals(num
, ERR_UNWILLING_TO_PERFORM
)
1336 delete_force(self
.ldb
, "description=xyz,cn=users," + self
.base_dn
)
1338 # old empty RDN value
1340 self
.ldb
.rename("cn=,cn=users," + self
.base_dn
,
1341 "cn=ldaptestgroup,cn=users," + self
.base_dn
)
1343 except LdbError
as e71
:
1345 self
.assertEquals(num
, ERR_INVALID_DN_SYNTAX
)
1350 m
.dn
= Dn(ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
1351 m
["name"] = MessageElement("cn=ldaptestuser", FLAG_MOD_REPLACE
,
1356 except LdbError
as e72
:
1358 self
.assertEquals(num
, ERR_NOT_ALLOWED_ON_RDN
)
1361 m
.dn
= Dn(ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
1362 m
["cn"] = MessageElement("ldaptestuser",
1363 FLAG_MOD_REPLACE
, "cn")
1367 except LdbError
as e73
:
1369 self
.assertEquals(num
, ERR_NOT_ALLOWED_ON_RDN
)
1371 delete_force(self
.ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
1374 # this test needs to be disabled until we really understand
1375 # what the rDN length constraints are
1376 def DISABLED_test_largeRDN(self
):
1377 """Testing large rDN (limit 64 characters)"""
1378 rdn
= "CN=a012345678901234567890123456789012345678901234567890123456789012"
1379 delete_force(self
.ldb
, "%s,%s" % (rdn
, self
.base_dn
))
1381 dn: %s,%s""" % (rdn
,self
.base_dn
) + """
1382 objectClass: container
1384 self
.ldb
.add_ldif(ldif
)
1385 delete_force(self
.ldb
, "%s,%s" % (rdn
, self
.base_dn
))
1387 rdn
= "CN=a0123456789012345678901234567890123456789012345678901234567890120"
1388 delete_force(self
.ldb
, "%s,%s" % (rdn
, self
.base_dn
))
1391 dn: %s,%s""" % (rdn
,self
.base_dn
) + """
1392 objectClass: container
1394 self
.ldb
.add_ldif(ldif
)
1396 except LdbError
as e74
:
1398 self
.assertEquals(num
, ERR_CONSTRAINT_VIOLATION
)
1399 delete_force(self
.ldb
, "%s,%s" % (rdn
, self
.base_dn
))
1401 def test_rename(self
):
1402 """Tests the rename operation"""
1404 # cannot rename to be a child of itself
1405 ldb
.rename(self
.base_dn
, "dc=test," + self
.base_dn
)
1407 except LdbError
as e75
:
1409 self
.assertEquals(num
, ERR_UNWILLING_TO_PERFORM
)
1413 ldb
.rename("cn=ldaptestuser2,cn=users," + self
.base_dn
, "cn=ldaptestuser2,cn=users," + self
.base_dn
)
1415 except LdbError
as e76
:
1417 self
.assertEquals(num
, ERR_NO_SUCH_OBJECT
)
1420 "dn": "cn=ldaptestuser2,cn=users," + self
.base_dn
,
1421 "objectclass": "user" })
1423 ldb
.rename("cn=ldaptestuser2,cn=users," + self
.base_dn
, "cn=ldaptestuser2,cn=users," + self
.base_dn
)
1424 ldb
.rename("cn=ldaptestuser2,cn=users," + self
.base_dn
, "cn=ldaptestuser3,cn=users," + self
.base_dn
)
1425 ldb
.rename("cn=ldaptestuser3,cn=users," + self
.base_dn
, "cn=ldaptestUSER3,cn=users," + self
.base_dn
)
1428 # containment problem: a user entry cannot contain user entries
1429 ldb
.rename("cn=ldaptestuser3,cn=users," + self
.base_dn
, "cn=ldaptestuser4,cn=ldaptestuser3,cn=users," + self
.base_dn
)
1431 except LdbError
as e77
:
1433 self
.assertEquals(num
, ERR_NAMING_VIOLATION
)
1437 ldb
.rename("cn=ldaptestuser3,cn=users," + self
.base_dn
, "cn=ldaptestuser3,cn=people,cn=users," + self
.base_dn
)
1439 except LdbError
as e78
:
1441 self
.assertEquals(num
, ERR_OTHER
)
1444 # invalid target DN syntax
1445 ldb
.rename("cn=ldaptestuser3,cn=users," + self
.base_dn
, ",cn=users," + self
.base_dn
)
1447 except LdbError
as e79
:
1449 self
.assertEquals(num
, ERR_INVALID_DN_SYNTAX
)
1453 ldb
.rename("cn=ldaptestuser3,cn=users," + self
.base_dn
, "ou=ldaptestuser3,cn=users," + self
.base_dn
)
1455 except LdbError
as e80
:
1457 self
.assertEquals(num
, ERR_UNWILLING_TO_PERFORM
)
1459 delete_force(self
.ldb
, "cn=ldaptestuser3,cn=users," + self
.base_dn
)
1461 # Performs some "systemFlags" testing
1463 # Move failing since no "SYSTEM_FLAG_CONFIG_ALLOW_MOVE"
1465 ldb
.rename("CN=DisplaySpecifiers," + self
.configuration_dn
, "CN=DisplaySpecifiers,CN=Services," + self
.configuration_dn
)
1467 except LdbError
as e81
:
1469 self
.assertEquals(num
, ERR_UNWILLING_TO_PERFORM
)
1471 # Limited move failing since no "SYSTEM_FLAG_CONFIG_ALLOW_LIMITED_MOVE"
1473 ldb
.rename("CN=Directory Service,CN=Windows NT,CN=Services," + self
.configuration_dn
, "CN=Directory Service,CN=RRAS,CN=Services," + self
.configuration_dn
)
1475 except LdbError
as e82
:
1477 self
.assertEquals(num
, ERR_UNWILLING_TO_PERFORM
)
1479 # Rename failing since no "SYSTEM_FLAG_CONFIG_ALLOW_RENAME"
1481 ldb
.rename("CN=DisplaySpecifiers," + self
.configuration_dn
, "CN=DisplaySpecifiers2," + self
.configuration_dn
)
1483 except LdbError
as e83
:
1485 self
.assertEquals(num
, ERR_UNWILLING_TO_PERFORM
)
1487 # It's not really possible to test moves on the schema partition since
1488 # there don't exist subcontainers on it.
1490 # Rename failing since "SYSTEM_FLAG_SCHEMA_BASE_OBJECT"
1492 ldb
.rename("CN=Top," + self
.schema_dn
, "CN=Top2," + self
.schema_dn
)
1494 except LdbError
as e84
:
1496 self
.assertEquals(num
, ERR_UNWILLING_TO_PERFORM
)
1498 # Move failing since "SYSTEM_FLAG_DOMAIN_DISALLOW_MOVE"
1500 ldb
.rename("CN=Users," + self
.base_dn
, "CN=Users,CN=Computers," + self
.base_dn
)
1502 except LdbError
as e85
:
1504 self
.assertEquals(num
, ERR_UNWILLING_TO_PERFORM
)
1506 # Rename failing since "SYSTEM_FLAG_DOMAIN_DISALLOW_RENAME"
1508 ldb
.rename("CN=Users," + self
.base_dn
, "CN=Users2," + self
.base_dn
)
1510 except LdbError
as e86
:
1512 self
.assertEquals(num
, ERR_UNWILLING_TO_PERFORM
)
1514 # Performs some other constraints testing
1517 ldb
.rename("CN=Policies,CN=System," + self
.base_dn
, "CN=Users2," + self
.base_dn
)
1519 except LdbError
as e87
:
1521 self
.assertEquals(num
, ERR_OTHER
)
1523 def test_rename_twice(self
):
1524 """Tests the rename operation twice - this corresponds to a past bug"""
1526 "dn": "cn=ldaptestuser5,cn=users," + self
.base_dn
,
1527 "objectclass": "user" })
1529 ldb
.rename("cn=ldaptestuser5,cn=users," + self
.base_dn
, "cn=ldaptestUSER5,cn=users," + self
.base_dn
)
1530 delete_force(self
.ldb
, "cn=ldaptestuser5,cn=users," + self
.base_dn
)
1532 "dn": "cn=ldaptestuser5,cn=users," + self
.base_dn
,
1533 "objectclass": "user" })
1534 ldb
.rename("cn=ldaptestuser5,cn=Users," + self
.base_dn
, "cn=ldaptestUSER5,cn=users," + self
.base_dn
)
1535 res
= ldb
.search(expression
="cn=ldaptestuser5")
1536 self
.assertEquals(len(res
), 1, "Wrong number of hits for cn=ldaptestuser5")
1537 res
= ldb
.search(expression
="(&(cn=ldaptestuser5)(objectclass=user))")
1538 self
.assertEquals(len(res
), 1, "Wrong number of hits for (&(cn=ldaptestuser5)(objectclass=user))")
1539 delete_force(self
.ldb
, "cn=ldaptestuser5,cn=users," + self
.base_dn
)
1541 def test_objectGUID(self
):
1542 """Test objectGUID behaviour"""
1543 # The objectGUID cannot directly be set
1545 self
.ldb
.add_ldif("""
1546 dn: cn=ldaptestcontainer,""" + self
.base_dn
+ """
1547 objectClass: container
1548 objectGUID: bd3480c9-58af-4cd8-92df-bc4a18b6e44d
1551 except LdbError
as e88
:
1553 self
.assertEquals(num
, ERR_UNWILLING_TO_PERFORM
)
1556 "dn": "cn=ldaptestcontainer," + self
.base_dn
,
1557 "objectClass": "container" })
1559 # The objectGUID cannot directly be changed
1561 self
.ldb
.modify_ldif("""
1562 dn: cn=ldaptestcontainer,""" + self
.base_dn
+ """
1565 objectGUID: bd3480c9-58af-4cd8-92df-bc4a18b6e44d
1568 except LdbError
as e89
:
1570 self
.assertEquals(num
, ERR_CONSTRAINT_VIOLATION
)
1572 delete_force(self
.ldb
, "cn=ldaptestcontainer," + self
.base_dn
)
1574 def test_parentGUID(self
):
1575 """Test parentGUID behaviour"""
1577 "dn": "cn=parentguidtest,cn=users," + self
.base_dn
,
1578 "objectclass":"user",
1579 "samaccountname":"parentguidtest"})
1580 res1
= ldb
.search(base
="cn=parentguidtest,cn=users," + self
.base_dn
, scope
=SCOPE_BASE
,
1581 attrs
=["parentGUID", "samaccountname"])
1582 res2
= ldb
.search(base
="cn=users," + self
.base_dn
,scope
=SCOPE_BASE
,
1583 attrs
=["objectGUID"])
1584 res3
= ldb
.search(base
=self
.base_dn
, scope
=SCOPE_BASE
,
1585 attrs
=["parentGUID"])
1586 res4
= ldb
.search(base
=self
.configuration_dn
, scope
=SCOPE_BASE
,
1587 attrs
=["parentGUID"])
1588 res5
= ldb
.search(base
=self
.schema_dn
, scope
=SCOPE_BASE
,
1589 attrs
=["parentGUID"])
1591 """Check if the parentGUID is valid """
1592 self
.assertEquals(res1
[0]["parentGUID"], res2
[0]["objectGUID"])
1594 """Check if it returns nothing when there is no parent object - default NC"""
1595 has_parentGUID
= False
1596 for key
in res3
[0].keys():
1597 if key
== "parentGUID":
1598 has_parentGUID
= True
1600 self
.assertFalse(has_parentGUID
)
1602 """Check if it returns nothing when there is no parent object - configuration NC"""
1603 has_parentGUID
= False
1604 for key
in res4
[0].keys():
1605 if key
== "parentGUID":
1606 has_parentGUID
= True
1608 self
.assertFalse(has_parentGUID
)
1610 """Check if it returns nothing when there is no parent object - schema NC"""
1611 has_parentGUID
= False
1612 for key
in res5
[0].keys():
1613 if key
== "parentGUID":
1614 has_parentGUID
= True
1616 self
.assertFalse(has_parentGUID
)
1618 """Ensures that if you look for another object attribute after the constructed
1619 parentGUID, it will return correctly"""
1620 has_another_attribute
= False
1621 for key
in res1
[0].keys():
1622 if key
== "sAMAccountName":
1623 has_another_attribute
= True
1625 self
.assertTrue(has_another_attribute
)
1626 self
.assertTrue(len(res1
[0]["samaccountname"]) == 1)
1627 self
.assertEquals(res1
[0]["samaccountname"][0], "parentguidtest")
1629 # Testing parentGUID behaviour on rename\
1632 "dn": "cn=testotherusers," + self
.base_dn
,
1633 "objectclass":"container"})
1634 res1
= ldb
.search(base
="cn=testotherusers," + self
.base_dn
,scope
=SCOPE_BASE
,
1635 attrs
=["objectGUID"])
1636 ldb
.rename("cn=parentguidtest,cn=users," + self
.base_dn
,
1637 "cn=parentguidtest,cn=testotherusers," + self
.base_dn
)
1638 res2
= ldb
.search(base
="cn=parentguidtest,cn=testotherusers," + self
.base_dn
,
1640 attrs
=["parentGUID"])
1641 self
.assertEquals(res1
[0]["objectGUID"], res2
[0]["parentGUID"])
1643 delete_force(self
.ldb
, "cn=parentguidtest,cn=testotherusers," + self
.base_dn
)
1644 delete_force(self
.ldb
, "cn=testotherusers," + self
.base_dn
)
1646 def test_usnChanged(self
):
1647 """Test usnChanged behaviour"""
1650 "dn": "cn=ldaptestcontainer," + self
.base_dn
,
1651 "objectClass": "container" })
1653 res
= ldb
.search("cn=ldaptestcontainer," + self
.base_dn
,
1655 attrs
=["objectGUID", "uSNCreated", "uSNChanged", "whenCreated", "whenChanged", "description"])
1656 self
.assertTrue(len(res
) == 1)
1657 self
.assertFalse("description" in res
[0])
1658 self
.assertTrue("objectGUID" in res
[0])
1659 self
.assertTrue("uSNCreated" in res
[0])
1660 self
.assertTrue("uSNChanged" in res
[0])
1661 self
.assertTrue("whenCreated" in res
[0])
1662 self
.assertTrue("whenChanged" in res
[0])
1664 delete_force(self
.ldb
, "cn=ldaptestcontainer," + self
.base_dn
)
1666 # All this attributes are specificable on add operations
1668 "dn": "cn=ldaptestcontainer," + self
.base_dn
,
1669 "objectclass": "container",
1672 "whenCreated": timestring(long(time
.time())),
1673 "whenChanged": timestring(long(time
.time())) })
1675 res
= ldb
.search("cn=ldaptestcontainer," + self
.base_dn
,
1677 attrs
=["objectGUID", "uSNCreated", "uSNChanged", "whenCreated", "whenChanged", "description"])
1678 self
.assertTrue(len(res
) == 1)
1679 self
.assertFalse("description" in res
[0])
1680 self
.assertTrue("objectGUID" in res
[0])
1681 self
.assertTrue("uSNCreated" in res
[0])
1682 self
.assertFalse(res
[0]["uSNCreated"][0] == "1") # these are corrected
1683 self
.assertTrue("uSNChanged" in res
[0])
1684 self
.assertFalse(res
[0]["uSNChanged"][0] == "1") # these are corrected
1685 self
.assertTrue("whenCreated" in res
[0])
1686 self
.assertTrue("whenChanged" in res
[0])
1689 dn: cn=ldaptestcontainer,""" + self
.base_dn
+ """
1691 replace: description
1694 res2
= ldb
.search("cn=ldaptestcontainer," + self
.base_dn
,
1696 attrs
=["uSNCreated", "uSNChanged", "description"])
1697 self
.assertTrue(len(res
) == 1)
1698 self
.assertFalse("description" in res2
[0])
1699 self
.assertEqual(res
[0]["usnCreated"], res2
[0]["usnCreated"])
1700 self
.assertEqual(res
[0]["usnCreated"], res2
[0]["usnChanged"])
1701 self
.assertEqual(res
[0]["usnChanged"], res2
[0]["usnChanged"])
1704 dn: cn=ldaptestcontainer,""" + self
.base_dn
+ """
1706 replace: description
1710 res3
= ldb
.search("cn=ldaptestcontainer," + self
.base_dn
,
1712 attrs
=["uSNCreated", "uSNChanged", "description"])
1713 self
.assertTrue(len(res
) == 1)
1714 self
.assertTrue("description" in res3
[0])
1715 self
.assertEqual("test", str(res3
[0]["description"][0]))
1716 self
.assertEqual(res
[0]["usnCreated"], res3
[0]["usnCreated"])
1717 self
.assertNotEqual(res
[0]["usnCreated"], res3
[0]["usnChanged"])
1718 self
.assertNotEqual(res
[0]["usnChanged"], res3
[0]["usnChanged"])
1721 dn: cn=ldaptestcontainer,""" + self
.base_dn
+ """
1723 replace: description
1727 res4
= ldb
.search("cn=ldaptestcontainer," + self
.base_dn
,
1729 attrs
=["uSNCreated", "uSNChanged", "description"])
1730 self
.assertTrue(len(res
) == 1)
1731 self
.assertTrue("description" in res4
[0])
1732 self
.assertEqual("test", str(res4
[0]["description"][0]))
1733 self
.assertEqual(res
[0]["usnCreated"], res4
[0]["usnCreated"])
1734 self
.assertNotEqual(res3
[0]["usnCreated"], res4
[0]["usnChanged"])
1735 self
.assertEqual(res3
[0]["usnChanged"], res4
[0]["usnChanged"])
1738 dn: cn=ldaptestcontainer,""" + self
.base_dn
+ """
1740 replace: description
1744 res5
= ldb
.search("cn=ldaptestcontainer," + self
.base_dn
,
1746 attrs
=["uSNCreated", "uSNChanged", "description"])
1747 self
.assertTrue(len(res
) == 1)
1748 self
.assertTrue("description" in res5
[0])
1749 self
.assertEqual("test2", str(res5
[0]["description"][0]))
1750 self
.assertEqual(res
[0]["usnCreated"], res5
[0]["usnCreated"])
1751 self
.assertNotEqual(res3
[0]["usnChanged"], res5
[0]["usnChanged"])
1754 dn: cn=ldaptestcontainer,""" + self
.base_dn
+ """
1760 res6
= ldb
.search("cn=ldaptestcontainer," + self
.base_dn
,
1762 attrs
=["uSNCreated", "uSNChanged", "description"])
1763 self
.assertTrue(len(res
) == 1)
1764 self
.assertFalse("description" in res6
[0])
1765 self
.assertEqual(res
[0]["usnCreated"], res6
[0]["usnCreated"])
1766 self
.assertNotEqual(res5
[0]["usnChanged"], res6
[0]["usnChanged"])
1769 dn: cn=ldaptestcontainer,""" + self
.base_dn
+ """
1775 res7
= ldb
.search("cn=ldaptestcontainer," + self
.base_dn
,
1777 attrs
=["uSNCreated", "uSNChanged", "description"])
1778 self
.assertTrue(len(res
) == 1)
1779 self
.assertTrue("description" in res7
[0])
1780 self
.assertEqual("test3", str(res7
[0]["description"][0]))
1781 self
.assertEqual(res
[0]["usnCreated"], res7
[0]["usnCreated"])
1782 self
.assertNotEqual(res6
[0]["usnChanged"], res7
[0]["usnChanged"])
1785 dn: cn=ldaptestcontainer,""" + self
.base_dn
+ """
1790 res8
= ldb
.search("cn=ldaptestcontainer," + self
.base_dn
,
1792 attrs
=["uSNCreated", "uSNChanged", "description"])
1793 self
.assertTrue(len(res
) == 1)
1794 self
.assertFalse("description" in res8
[0])
1795 self
.assertEqual(res
[0]["usnCreated"], res8
[0]["usnCreated"])
1796 self
.assertNotEqual(res7
[0]["usnChanged"], res8
[0]["usnChanged"])
1798 delete_force(self
.ldb
, "cn=ldaptestcontainer," + self
.base_dn
)
1800 def test_groupType_int32(self
):
1801 """Test groupType (int32) behaviour (should appear to be casted to a 32 bit signed integer before comparsion)"""
1803 res1
= ldb
.search(base
=self
.base_dn
, scope
=SCOPE_SUBTREE
,
1804 attrs
=["groupType"], expression
="groupType=2147483653")
1806 res2
= ldb
.search(base
=self
.base_dn
, scope
=SCOPE_SUBTREE
,
1807 attrs
=["groupType"], expression
="groupType=-2147483643")
1809 self
.assertEquals(len(res1
), len(res2
))
1811 self
.assertTrue(res1
.count
> 0)
1813 self
.assertEquals(res1
[0]["groupType"][0], "-2147483643")
1815 def test_linked_attributes(self
):
1816 """This tests the linked attribute behaviour"""
1819 "dn": "cn=ldaptestgroup,cn=users," + self
.base_dn
,
1820 "objectclass": "group"})
1822 # This should not work since "memberOf" is linked to "member"
1825 "dn": "cn=ldaptestuser,cn=users," + self
.base_dn
,
1826 "objectclass": "user",
1827 "memberOf": "cn=ldaptestgroup,cn=users," + self
.base_dn
})
1828 except LdbError
as e90
:
1830 self
.assertEquals(num
, ERR_UNWILLING_TO_PERFORM
)
1833 "dn": "cn=ldaptestuser,cn=users," + self
.base_dn
,
1834 "objectclass": "user"})
1837 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
1838 m
["memberOf"] = MessageElement("cn=ldaptestgroup,cn=users," + self
.base_dn
,
1839 FLAG_MOD_ADD
, "memberOf")
1843 except LdbError
as e91
:
1845 self
.assertEquals(num
, ERR_UNWILLING_TO_PERFORM
)
1848 m
.dn
= Dn(ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
1849 m
["member"] = MessageElement("cn=ldaptestuser,cn=users," + self
.base_dn
,
1850 FLAG_MOD_ADD
, "member")
1854 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
1855 m
["memberOf"] = MessageElement("cn=ldaptestgroup,cn=users," + self
.base_dn
,
1856 FLAG_MOD_REPLACE
, "memberOf")
1860 except LdbError
as e92
:
1862 self
.assertEquals(num
, ERR_UNWILLING_TO_PERFORM
)
1865 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
1866 m
["memberOf"] = MessageElement("cn=ldaptestgroup,cn=users," + self
.base_dn
,
1867 FLAG_MOD_DELETE
, "memberOf")
1871 except LdbError
as e93
:
1873 self
.assertEquals(num
, ERR_UNWILLING_TO_PERFORM
)
1876 m
.dn
= Dn(ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
1877 m
["member"] = MessageElement("cn=ldaptestuser,cn=users," + self
.base_dn
,
1878 FLAG_MOD_DELETE
, "member")
1881 # This should yield no results since the member attribute for
1882 # "ldaptestuser" should have been deleted
1883 res1
= ldb
.search("cn=ldaptestgroup, cn=users," + self
.base_dn
,
1885 expression
="(member=cn=ldaptestuser,cn=users," + self
.base_dn
+ ")",
1887 self
.assertTrue(len(res1
) == 0)
1889 delete_force(self
.ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
1892 "dn": "cn=ldaptestgroup,cn=users," + self
.base_dn
,
1893 "objectclass": "group",
1894 "member": "cn=ldaptestuser,cn=users," + self
.base_dn
})
1896 delete_force(self
.ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
1898 # Make sure that the "member" attribute for "ldaptestuser" has been
1900 res
= ldb
.search("cn=ldaptestgroup,cn=users," + self
.base_dn
,
1901 scope
=SCOPE_BASE
, attrs
=["member"])
1902 self
.assertTrue(len(res
) == 1)
1903 self
.assertFalse("member" in res
[0])
1905 delete_force(self
.ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
1907 def test_wkguid(self
):
1908 """Test Well known GUID behaviours (including DN+Binary)"""
1910 res
= self
.ldb
.search(base
=("<WKGUID=ab1d30f3768811d1aded00c04fd8d5cd,%s>" % self
.base_dn
), scope
=SCOPE_BASE
, attrs
=[])
1911 self
.assertEquals(len(res
), 1)
1913 res2
= self
.ldb
.search(scope
=SCOPE_BASE
, attrs
=["wellKnownObjects"], expression
=("wellKnownObjects=B:32:ab1d30f3768811d1aded00c04fd8d5cd:%s" % res
[0].dn
))
1914 self
.assertEquals(len(res2
), 1)
1916 # Prove that the matching rule is over the whole DN+Binary
1917 res2
= self
.ldb
.search(scope
=SCOPE_BASE
, attrs
=["wellKnownObjects"], expression
=("wellKnownObjects=B:32:ab1d30f3768811d1aded00c04fd8d5cd"))
1918 self
.assertEquals(len(res2
), 0)
1919 # Prove that the matching rule is over the whole DN+Binary
1920 res2
= self
.ldb
.search(scope
=SCOPE_BASE
, attrs
=["wellKnownObjects"], expression
=("wellKnownObjects=%s") % res
[0].dn
)
1921 self
.assertEquals(len(res2
), 0)
1923 def test_subschemasubentry(self
):
1924 """Test subSchemaSubEntry appears when requested, but not when not requested"""
1926 res
= self
.ldb
.search(base
=self
.base_dn
, scope
=SCOPE_BASE
, attrs
=["subSchemaSubEntry"])
1927 self
.assertEquals(len(res
), 1)
1928 self
.assertEquals(res
[0]["subSchemaSubEntry"][0], "CN=Aggregate,"+self
.schema_dn
)
1930 res
= self
.ldb
.search(base
=self
.base_dn
, scope
=SCOPE_BASE
, attrs
=["*"])
1931 self
.assertEquals(len(res
), 1)
1932 self
.assertTrue("subScheamSubEntry" not in res
[0])
1940 "dn": "cn=ldaptestuser,cn=uSers," + self
.base_dn
,
1941 "objectclass": "user",
1942 "cN": "LDAPtestUSER",
1943 "givenname": "ldap",
1947 "dn": "cn=ldaptestgroup,cn=uSers," + self
.base_dn
,
1948 "objectclass": "group",
1949 "member": "cn=ldaptestuser,cn=useRs," + self
.base_dn
})
1952 "dn": "cn=ldaptestcomputer,cn=computers," + self
.base_dn
,
1953 "objectclass": "computer",
1954 "cN": "LDAPtestCOMPUTER"})
1956 ldb
.add({"dn": "cn=ldaptest2computer,cn=computers," + self
.base_dn
,
1957 "objectClass": "computer",
1958 "cn": "LDAPtest2COMPUTER",
1959 "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT
),
1960 "displayname": "ldap testy"})
1963 ldb
.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self
.base_dn
,
1964 "objectClass": "computer",
1965 "cn": "LDAPtest2COMPUTER"
1968 except LdbError
as e94
:
1970 self
.assertEquals(num
, ERR_INVALID_DN_SYNTAX
)
1973 ldb
.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self
.base_dn
,
1974 "objectClass": "computer",
1975 "cn": "ldaptestcomputer3",
1976 "sAMAccountType": str(ATYPE_NORMAL_ACCOUNT
)
1979 except LdbError
as e95
:
1981 self
.assertEquals(num
, ERR_UNWILLING_TO_PERFORM
)
1983 ldb
.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self
.base_dn
,
1984 "objectClass": "computer",
1985 "cn": "LDAPtestCOMPUTER3"
1988 # Testing ldb.search for (&(cn=ldaptestcomputer3)(objectClass=user))
1989 res
= ldb
.search(self
.base_dn
, expression
="(&(cn=ldaptestcomputer3)(objectClass=user))")
1990 self
.assertEquals(len(res
), 1, "Found only %d for (&(cn=ldaptestcomputer3)(objectClass=user))" % len(res
))
1992 self
.assertEquals(str(res
[0].dn
), ("CN=ldaptestcomputer3,CN=Computers," + self
.base_dn
))
1993 self
.assertEquals(res
[0]["cn"][0], "ldaptestcomputer3")
1994 self
.assertEquals(res
[0]["name"][0], "ldaptestcomputer3")
1995 self
.assertEquals(res
[0]["objectClass"][0], "top")
1996 self
.assertEquals(res
[0]["objectClass"][1], "person")
1997 self
.assertEquals(res
[0]["objectClass"][2], "organizationalPerson")
1998 self
.assertEquals(res
[0]["objectClass"][3], "user")
1999 self
.assertEquals(res
[0]["objectClass"][4], "computer")
2000 self
.assertTrue("objectGUID" in res
[0])
2001 self
.assertTrue("whenCreated" in res
[0])
2002 self
.assertEquals(res
[0]["objectCategory"][0], ("CN=Computer,%s" % ldb
.get_schema_basedn()))
2003 self
.assertEquals(int(res
[0]["primaryGroupID"][0]), 513)
2004 self
.assertEquals(int(res
[0]["sAMAccountType"][0]), ATYPE_NORMAL_ACCOUNT
)
2005 self
.assertEquals(int(res
[0]["userAccountControl"][0]), UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE
)
2007 delete_force(self
.ldb
, "cn=ldaptestcomputer3,cn=computers," + self
.base_dn
)
2009 # Testing attribute or value exists behaviour
2012 dn: cn=ldaptest2computer,cn=computers,""" + self
.base_dn
+ """
2014 replace: servicePrincipalName
2015 servicePrincipalName: host/ldaptest2computer
2016 servicePrincipalName: host/ldaptest2computer
2017 servicePrincipalName: cifs/ldaptest2computer
2020 except LdbError
as e96
:
2021 (num
, msg
) = e96
.args
2022 self
.assertEquals(num
, ERR_ATTRIBUTE_OR_VALUE_EXISTS
)
2025 dn: cn=ldaptest2computer,cn=computers,""" + self
.base_dn
+ """
2027 replace: servicePrincipalName
2028 servicePrincipalName: host/ldaptest2computer
2029 servicePrincipalName: cifs/ldaptest2computer
2033 dn: cn=ldaptest2computer,cn=computers,""" + self
.base_dn
+ """
2035 add: servicePrincipalName
2036 servicePrincipalName: host/ldaptest2computer
2039 except LdbError
as e97
:
2040 (num
, msg
) = e97
.args
2041 self
.assertEquals(num
, ERR_ATTRIBUTE_OR_VALUE_EXISTS
)
2043 # Testing ranged results
2045 dn: cn=ldaptest2computer,cn=computers,""" + self
.base_dn
+ """
2047 replace: servicePrincipalName
2051 dn: cn=ldaptest2computer,cn=computers,""" + self
.base_dn
+ """
2053 add: servicePrincipalName
2054 servicePrincipalName: host/ldaptest2computer0
2055 servicePrincipalName: host/ldaptest2computer1
2056 servicePrincipalName: host/ldaptest2computer2
2057 servicePrincipalName: host/ldaptest2computer3
2058 servicePrincipalName: host/ldaptest2computer4
2059 servicePrincipalName: host/ldaptest2computer5
2060 servicePrincipalName: host/ldaptest2computer6
2061 servicePrincipalName: host/ldaptest2computer7
2062 servicePrincipalName: host/ldaptest2computer8
2063 servicePrincipalName: host/ldaptest2computer9
2064 servicePrincipalName: host/ldaptest2computer10
2065 servicePrincipalName: host/ldaptest2computer11
2066 servicePrincipalName: host/ldaptest2computer12
2067 servicePrincipalName: host/ldaptest2computer13
2068 servicePrincipalName: host/ldaptest2computer14
2069 servicePrincipalName: host/ldaptest2computer15
2070 servicePrincipalName: host/ldaptest2computer16
2071 servicePrincipalName: host/ldaptest2computer17
2072 servicePrincipalName: host/ldaptest2computer18
2073 servicePrincipalName: host/ldaptest2computer19
2074 servicePrincipalName: host/ldaptest2computer20
2075 servicePrincipalName: host/ldaptest2computer21
2076 servicePrincipalName: host/ldaptest2computer22
2077 servicePrincipalName: host/ldaptest2computer23
2078 servicePrincipalName: host/ldaptest2computer24
2079 servicePrincipalName: host/ldaptest2computer25
2080 servicePrincipalName: host/ldaptest2computer26
2081 servicePrincipalName: host/ldaptest2computer27
2082 servicePrincipalName: host/ldaptest2computer28
2083 servicePrincipalName: host/ldaptest2computer29
2086 res
= ldb
.search(self
.base_dn
, expression
="(cn=ldaptest2computer))", scope
=SCOPE_SUBTREE
,
2087 attrs
=["servicePrincipalName;range=0-*"])
2088 self
.assertEquals(len(res
), 1, "Could not find (cn=ldaptest2computer)")
2089 self
.assertEquals(len(res
[0]["servicePrincipalName;range=0-*"]), 30)
2091 res
= ldb
.search(self
.base_dn
, expression
="(cn=ldaptest2computer))", scope
=SCOPE_SUBTREE
, attrs
=["servicePrincipalName;range=0-19"])
2092 self
.assertEquals(len(res
), 1, "Could not find (cn=ldaptest2computer)")
2093 self
.assertEquals(len(res
[0]["servicePrincipalName;range=0-19"]), 20)
2096 res
= ldb
.search(self
.base_dn
, expression
="(cn=ldaptest2computer))", scope
=SCOPE_SUBTREE
, attrs
=["servicePrincipalName;range=0-30"])
2097 self
.assertEquals(len(res
), 1, "Could not find (cn=ldaptest2computer)")
2098 self
.assertEquals(len(res
[0]["servicePrincipalName;range=0-*"]), 30)
2100 res
= ldb
.search(self
.base_dn
, expression
="(cn=ldaptest2computer))", scope
=SCOPE_SUBTREE
, attrs
=["servicePrincipalName;range=0-40"])
2101 self
.assertEquals(len(res
), 1, "Could not find (cn=ldaptest2computer)")
2102 self
.assertEquals(len(res
[0]["servicePrincipalName;range=0-*"]), 30)
2104 res
= ldb
.search(self
.base_dn
, expression
="(cn=ldaptest2computer))", scope
=SCOPE_SUBTREE
, attrs
=["servicePrincipalName;range=30-40"])
2105 self
.assertEquals(len(res
), 1, "Could not find (cn=ldaptest2computer)")
2106 self
.assertEquals(len(res
[0]["servicePrincipalName;range=30-*"]), 0)
2109 res
= ldb
.search(self
.base_dn
, expression
="(cn=ldaptest2computer))", scope
=SCOPE_SUBTREE
, attrs
=["servicePrincipalName;range=10-40"])
2110 self
.assertEquals(len(res
), 1, "Could not find (cn=ldaptest2computer)")
2111 self
.assertEquals(len(res
[0]["servicePrincipalName;range=10-*"]), 20)
2112 # pos_11 = res[0]["servicePrincipalName;range=10-*"][18]
2114 res
= ldb
.search(self
.base_dn
, expression
="(cn=ldaptest2computer))", scope
=SCOPE_SUBTREE
, attrs
=["servicePrincipalName;range=11-40"])
2115 self
.assertEquals(len(res
), 1, "Could not find (cn=ldaptest2computer)")
2116 self
.assertEquals(len(res
[0]["servicePrincipalName;range=11-*"]), 19)
2117 # self.assertEquals((res[0]["servicePrincipalName;range=11-*"][18]), pos_11)
2119 res
= ldb
.search(self
.base_dn
, expression
="(cn=ldaptest2computer))", scope
=SCOPE_SUBTREE
, attrs
=["servicePrincipalName;range=11-15"])
2120 self
.assertEquals(len(res
), 1, "Could not find (cn=ldaptest2computer)")
2121 self
.assertEquals(len(res
[0]["servicePrincipalName;range=11-15"]), 5)
2122 # self.assertEquals(res[0]["servicePrincipalName;range=11-15"][4], pos_11)
2124 res
= ldb
.search(self
.base_dn
, expression
="(cn=ldaptest2computer))", scope
=SCOPE_SUBTREE
, attrs
=["servicePrincipalName"])
2125 self
.assertEquals(len(res
), 1, "Could not find (cn=ldaptest2computer)")
2126 self
.assertEquals(len(res
[0]["servicePrincipalName"]), 30)
2127 # self.assertEquals(res[0]["servicePrincipalName"][18], pos_11)
2129 delete_force(self
.ldb
, "cn=ldaptestuser2,cn=users," + self
.base_dn
)
2131 "dn": "cn=ldaptestuser2,cn=useRs," + self
.base_dn
,
2132 "objectClass": "user",
2133 "cn": "LDAPtestUSER2",
2134 "givenname": "testy",
2135 "sn": "ldap user2"})
2137 # Testing Ambigious Name Resolution
2138 # Testing ldb.search for (&(anr=ldap testy)(objectClass=user))
2139 res
= ldb
.search(expression
="(&(anr=ldap testy)(objectClass=user))")
2140 self
.assertEquals(len(res
), 3, "Found only %d of 3 for (&(anr=ldap testy)(objectClass=user))" % len(res
))
2142 # Testing ldb.search for (&(anr=testy ldap)(objectClass=user))
2143 res
= ldb
.search(expression
="(&(anr=testy ldap)(objectClass=user))")
2144 self
.assertEquals(len(res
), 2, "Found only %d of 2 for (&(anr=testy ldap)(objectClass=user))" % len(res
))
2146 # Testing ldb.search for (&(anr=ldap)(objectClass=user))
2147 res
= ldb
.search(expression
="(&(anr=ldap)(objectClass=user))")
2148 self
.assertEquals(len(res
), 4, "Found only %d of 4 for (&(anr=ldap)(objectClass=user))" % len(res
))
2150 # Testing ldb.search for (&(anr==ldap)(objectClass=user))
2151 res
= ldb
.search(expression
="(&(anr==ldap)(objectClass=user))")
2152 self
.assertEquals(len(res
), 1, "Could not find (&(anr==ldap)(objectClass=user)). Found only %d for (&(anr=ldap)(objectClass=user))" % len(res
))
2154 self
.assertEquals(str(res
[0].dn
), ("CN=ldaptestuser,CN=Users," + self
.base_dn
))
2155 self
.assertEquals(res
[0]["cn"][0], "ldaptestuser")
2156 self
.assertEquals(str(res
[0]["name"]), "ldaptestuser")
2158 # Testing ldb.search for (&(anr=testy)(objectClass=user))
2159 res
= ldb
.search(expression
="(&(anr=testy)(objectClass=user))")
2160 self
.assertEquals(len(res
), 2, "Found only %d for (&(anr=testy)(objectClass=user))" % len(res
))
2162 # Testing ldb.search for (&(anr=testy ldap)(objectClass=user))
2163 res
= ldb
.search(expression
="(&(anr=testy ldap)(objectClass=user))")
2164 self
.assertEquals(len(res
), 2, "Found only %d for (&(anr=testy ldap)(objectClass=user))" % len(res
))
2166 # Testing ldb.search for (&(anr==testy ldap)(objectClass=user))
2167 # this test disabled for the moment, as anr with == tests are not understood
2168 # res = ldb.search(expression="(&(anr==testy ldap)(objectClass=user))")
2169 # self.assertEquals(len(res), 1, "Found only %d for (&(anr==testy ldap)(objectClass=user))" % len(res))
2171 # self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
2172 # self.assertEquals(res[0]["cn"][0], "ldaptestuser")
2173 # self.assertEquals(res[0]["name"][0], "ldaptestuser")
2175 # Testing ldb.search for (&(anr==testy ldap)(objectClass=user))
2176 # res = ldb.search(expression="(&(anr==testy ldap)(objectClass=user))")
2177 # self.assertEquals(len(res), 1, "Could not find (&(anr==testy ldap)(objectClass=user))")
2179 # self.assertEquals(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
2180 # self.assertEquals(res[0]["cn"][0], "ldaptestuser")
2181 # self.assertEquals(res[0]["name"][0], "ldaptestuser")
2183 # Testing ldb.search for (&(anr=testy ldap user)(objectClass=user))
2184 res
= ldb
.search(expression
="(&(anr=testy ldap user)(objectClass=user))")
2185 self
.assertEquals(len(res
), 1, "Could not find (&(anr=testy ldap user)(objectClass=user))")
2187 self
.assertEquals(str(res
[0].dn
), ("CN=ldaptestuser2,CN=Users," + self
.base_dn
))
2188 self
.assertEquals(str(res
[0]["cn"]), "ldaptestuser2")
2189 self
.assertEquals(str(res
[0]["name"]), "ldaptestuser2")
2191 # Testing ldb.search for (&(anr==testy ldap user2)(objectClass=user))
2192 # res = ldb.search(expression="(&(anr==testy ldap user2)(objectClass=user))")
2193 # self.assertEquals(len(res), 1, "Could not find (&(anr==testy ldap user2)(objectClass=user))")
2195 self
.assertEquals(str(res
[0].dn
), ("CN=ldaptestuser2,CN=Users," + self
.base_dn
))
2196 self
.assertEquals(str(res
[0]["cn"]), "ldaptestuser2")
2197 self
.assertEquals(str(res
[0]["name"]), "ldaptestuser2")
2199 # Testing ldb.search for (&(anr==ldap user2)(objectClass=user))
2200 # res = ldb.search(expression="(&(anr==ldap user2)(objectClass=user))")
2201 # self.assertEquals(len(res), 1, "Could not find (&(anr==ldap user2)(objectClass=user))")
2203 self
.assertEquals(str(res
[0].dn
), ("CN=ldaptestuser2,CN=Users," + self
.base_dn
))
2204 self
.assertEquals(str(res
[0]["cn"]), "ldaptestuser2")
2205 self
.assertEquals(str(res
[0]["name"]), "ldaptestuser2")
2207 # Testing ldb.search for (&(anr==not ldap user2)(objectClass=user))
2208 # res = ldb.search(expression="(&(anr==not ldap user2)(objectClass=user))")
2209 # self.assertEquals(len(res), 0, "Must not find (&(anr==not ldap user2)(objectClass=user))")
2211 # Testing ldb.search for (&(anr=not ldap user2)(objectClass=user))
2212 res
= ldb
.search(expression
="(&(anr=not ldap user2)(objectClass=user))")
2213 self
.assertEquals(len(res
), 0, "Must not find (&(anr=not ldap user2)(objectClass=user))")
2215 # Testing ldb.search for (&(anr="testy ldap")(objectClass=user)) (ie, with quotes)
2216 # res = ldb.search(expression="(&(anr==\"testy ldap\")(objectClass=user))")
2217 # self.assertEquals(len(res), 0, "Found (&(anr==\"testy ldap\")(objectClass=user))")
2221 attrs
= ["objectGUID", "objectSid"]
2222 # Testing ldb.search for (&(cn=ldaptestUSer2)(objectClass=user))
2223 res_user
= ldb
.search(self
.base_dn
, expression
="(&(cn=ldaptestUSer2)(objectClass=user))", scope
=SCOPE_SUBTREE
, attrs
=attrs
)
2224 self
.assertEquals(len(res_user
), 1, "Could not find (&(cn=ldaptestUSer2)(objectClass=user))")
2226 # Check rename works with extended/alternate DN forms
2227 ldb
.rename("<SID=" + ldb
.schema_format_value("objectSID", res_user
[0]["objectSID"][0]) + ">" , "cn=ldaptestUSER3,cn=users," + self
.base_dn
)
2229 # Testing ldb.search for (&(cn=ldaptestuser3)(objectClass=user))
2230 res
= ldb
.search(expression
="(&(cn=ldaptestuser3)(objectClass=user))")
2231 self
.assertEquals(len(res
), 1, "Could not find (&(cn=ldaptestuser3)(objectClass=user))")
2233 self
.assertEquals(str(res
[0].dn
), ("CN=ldaptestUSER3,CN=Users," + self
.base_dn
))
2234 self
.assertEquals(str(res
[0]["cn"]), "ldaptestUSER3")
2235 self
.assertEquals(str(res
[0]["name"]), "ldaptestUSER3")
2237 #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))"
2238 res
= ldb
.search(expression
="(&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))")
2239 self
.assertEquals(len(res
), 1, "(&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))")
2241 self
.assertEquals(str(res
[0].dn
), ("CN=ldaptestUSER3,CN=Users," + self
.base_dn
))
2242 self
.assertEquals(str(res
[0]["cn"]), "ldaptestUSER3")
2243 self
.assertEquals(str(res
[0]["name"]), "ldaptestUSER3")
2245 #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))"
2246 res
= ldb
.search(expression
="(&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))")
2247 self
.assertEquals(len(res
), 1, "(&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))")
2249 self
.assertEquals(str(res
[0].dn
), ("CN=ldaptestUSER3,CN=Users," + self
.base_dn
))
2250 self
.assertEquals(str(res
[0]["cn"]), "ldaptestUSER3")
2251 self
.assertEquals(str(res
[0]["name"]), "ldaptestUSER3")
2253 #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))"
2254 res
= ldb
.search(expression
="(&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))")
2255 self
.assertEquals(len(res
), 0, "(&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))")
2257 # Testing ldb.search for (dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ") - should not work
2258 res
= ldb
.search(expression
="(dn=CN=ldaptestUSER3,CN=Users," + self
.base_dn
+ ")")
2259 self
.assertEquals(len(res
), 0, "Could find (dn=CN=ldaptestUSER3,CN=Users," + self
.base_dn
+ ")")
2261 # Testing ldb.search for (distinguishedName=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")
2262 res
= ldb
.search(expression
="(distinguishedName=CN=ldaptestUSER3,CN=Users," + self
.base_dn
+ ")")
2263 self
.assertEquals(len(res
), 1, "Could not find (distinguishedName=CN=ldaptestUSER3,CN=Users," + self
.base_dn
+ ")")
2264 self
.assertEquals(str(res
[0].dn
), ("CN=ldaptestUSER3,CN=Users," + self
.base_dn
))
2265 self
.assertEquals(str(res
[0]["cn"]), "ldaptestUSER3")
2266 self
.assertEquals(str(res
[0]["name"]), "ldaptestUSER3")
2268 # ensure we cannot add it again
2270 ldb
.add({"dn": "cn=ldaptestuser3,cn=userS," + self
.base_dn
,
2271 "objectClass": "user",
2272 "cn": "LDAPtestUSER3"})
2274 except LdbError
as e98
:
2276 self
.assertEquals(num
, ERR_ENTRY_ALREADY_EXISTS
)
2279 ldb
.rename("cn=ldaptestuser3,cn=users," + self
.base_dn
, "cn=ldaptestuser2,cn=users," + self
.base_dn
)
2281 # ensure we cannot rename it twice
2283 ldb
.rename("cn=ldaptestuser3,cn=users," + self
.base_dn
,
2284 "cn=ldaptestuser2,cn=users," + self
.base_dn
)
2286 except LdbError
as e99
:
2288 self
.assertEquals(num
, ERR_NO_SUCH_OBJECT
)
2290 # ensure can now use that name
2291 ldb
.add({"dn": "cn=ldaptestuser3,cn=users," + self
.base_dn
,
2292 "objectClass": "user",
2293 "cn": "LDAPtestUSER3"})
2295 # ensure we now cannot rename
2297 ldb
.rename("cn=ldaptestuser2,cn=users," + self
.base_dn
, "cn=ldaptestuser3,cn=users," + self
.base_dn
)
2299 except LdbError
as e100
:
2300 (num
, _
) = e100
.args
2301 self
.assertEquals(num
, ERR_ENTRY_ALREADY_EXISTS
)
2303 ldb
.rename("cn=ldaptestuser3,cn=users,%s" % self
.base_dn
, "cn=ldaptestuser3,%s" % ldb
.get_config_basedn())
2305 except LdbError
as e101
:
2306 (num
, _
) = e101
.args
2307 self
.assertTrue(num
in (71, 64))
2309 ldb
.rename("cn=ldaptestuser3,cn=users," + self
.base_dn
, "cn=ldaptestuser5,cn=users," + self
.base_dn
)
2311 ldb
.delete("cn=ldaptestuser5,cn=users," + self
.base_dn
)
2313 delete_force(ldb
, "cn=ldaptestgroup2,cn=users," + self
.base_dn
)
2315 ldb
.rename("cn=ldaptestgroup,cn=users," + self
.base_dn
, "cn=ldaptestgroup2,cn=users," + self
.base_dn
)
2317 # Testing subtree renames
2319 ldb
.add({"dn": "cn=ldaptestcontainer," + self
.base_dn
,
2320 "objectClass": "container"})
2322 ldb
.add({"dn": "CN=ldaptestuser4,CN=ldaptestcontainer," + self
.base_dn
,
2323 "objectClass": "user",
2324 "cn": "LDAPtestUSER4"})
2326 # Here we don't enforce these hard "description" constraints
2328 dn: cn=ldaptestcontainer,""" + self
.base_dn
+ """
2330 replace: description
2336 dn: cn=ldaptestgroup2,cn=users,""" + self
.base_dn
+ """
2339 member: cn=ldaptestuser4,cn=ldaptestcontainer,""" + self
.base_dn
+ """
2340 member: cn=ldaptestcomputer,cn=computers,""" + self
.base_dn
+ """
2341 member: cn=ldaptestuser2,cn=users,""" + self
.base_dn
+ """
2344 # Testing ldb.rename of cn=ldaptestcontainer," + self.base_dn + " to cn=ldaptestcontainer2," + self.base_dn
2345 ldb
.rename("CN=ldaptestcontainer," + self
.base_dn
, "CN=ldaptestcontainer2," + self
.base_dn
)
2347 # Testing ldb.search for (&(cn=ldaptestuser4)(objectClass=user))
2348 res
= ldb
.search(expression
="(&(cn=ldaptestuser4)(objectClass=user))")
2349 self
.assertEquals(len(res
), 1, "Could not find (&(cn=ldaptestuser4)(objectClass=user))")
2351 # Testing subtree ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in (just renamed from) cn=ldaptestcontainer," + self.base_dn
2353 res
= ldb
.search("cn=ldaptestcontainer," + self
.base_dn
,
2354 expression
="(&(cn=ldaptestuser4)(objectClass=user))",
2355 scope
=SCOPE_SUBTREE
)
2357 except LdbError
as e102
:
2358 (num
, _
) = e102
.args
2359 self
.assertEquals(num
, ERR_NO_SUCH_OBJECT
)
2361 # Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in (just renamed from) cn=ldaptestcontainer," + self.base_dn
2363 res
= ldb
.search("cn=ldaptestcontainer," + self
.base_dn
,
2364 expression
="(&(cn=ldaptestuser4)(objectClass=user))", scope
=SCOPE_ONELEVEL
)
2366 except LdbError
as e103
:
2367 (num
, _
) = e103
.args
2368 self
.assertEquals(num
, ERR_NO_SUCH_OBJECT
)
2370 # Testing ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in renamed container"
2371 res
= ldb
.search("cn=ldaptestcontainer2," + self
.base_dn
, expression
="(&(cn=ldaptestuser4)(objectClass=user))", scope
=SCOPE_SUBTREE
)
2372 self
.assertEquals(len(res
), 1, "Could not find (&(cn=ldaptestuser4)(objectClass=user)) under cn=ldaptestcontainer2," + self
.base_dn
)
2374 self
.assertEquals(str(res
[0].dn
), ("CN=ldaptestuser4,CN=ldaptestcontainer2," + self
.base_dn
))
2375 self
.assertEquals(res
[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self
.base_dn
).upper())
2379 # Testing ldb.search for (&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn + ")(objectclass=group)) to check subtree renames and linked attributes"
2380 res
= ldb
.search(self
.base_dn
, expression
="(&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + self
.base_dn
+ ")(objectclass=group))", scope
=SCOPE_SUBTREE
)
2381 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?")
2383 # Testing ldb.rename (into itself) of cn=ldaptestcontainer2," + self.base_dn + " to cn=ldaptestcontainer,cn=ldaptestcontainer2," + self.base_dn
2385 ldb
.rename("cn=ldaptestcontainer2," + self
.base_dn
, "cn=ldaptestcontainer,cn=ldaptestcontainer2," + self
.base_dn
)
2387 except LdbError
as e104
:
2388 (num
, _
) = e104
.args
2389 self
.assertEquals(num
, ERR_UNWILLING_TO_PERFORM
)
2391 # Testing ldb.rename (into non-existent container) of cn=ldaptestcontainer2," + self.base_dn + " to cn=ldaptestcontainer,cn=ldaptestcontainer3," + self.base_dn
2393 ldb
.rename("cn=ldaptestcontainer2," + self
.base_dn
, "cn=ldaptestcontainer,cn=ldaptestcontainer3," + self
.base_dn
)
2395 except LdbError
as e105
:
2396 (num
, _
) = e105
.args
2397 self
.assertTrue(num
in (ERR_UNWILLING_TO_PERFORM
, ERR_OTHER
))
2399 # Testing delete (should fail, not a leaf node) of renamed cn=ldaptestcontainer2," + self.base_dn
2401 ldb
.delete("cn=ldaptestcontainer2," + self
.base_dn
)
2403 except LdbError
as e106
:
2404 (num
, _
) = e106
.args
2405 self
.assertEquals(num
, ERR_NOT_ALLOWED_ON_NON_LEAF
)
2407 # Testing base ldb.search for CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn
2408 res
= ldb
.search(expression
="(objectclass=*)", base
=("CN=ldaptestuser4,CN=ldaptestcontainer2," + self
.base_dn
), scope
=SCOPE_BASE
)
2409 self
.assertEquals(len(res
), 1)
2410 res
= ldb
.search(expression
="(cn=ldaptestuser40)", base
=("CN=ldaptestuser4,CN=ldaptestcontainer2," + self
.base_dn
), scope
=SCOPE_BASE
)
2411 self
.assertEquals(len(res
), 0)
2413 # Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in cn=ldaptestcontainer2," + self.base_dn
2414 res
= ldb
.search(expression
="(&(cn=ldaptestuser4)(objectClass=user))", base
=("cn=ldaptestcontainer2," + self
.base_dn
), scope
=SCOPE_ONELEVEL
)
2415 self
.assertEquals(len(res
), 1)
2417 # Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in cn=ldaptestcontainer2," + self.base_dn
2418 res
= ldb
.search(expression
="(&(cn=ldaptestuser4)(objectClass=user))", base
=("cn=ldaptestcontainer2," + self
.base_dn
), scope
=SCOPE_SUBTREE
)
2419 self
.assertEquals(len(res
), 1)
2421 # Testing delete of subtree renamed "+("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn)
2422 ldb
.delete(("CN=ldaptestuser4,CN=ldaptestcontainer2," + self
.base_dn
))
2423 # Testing delete of renamed cn=ldaptestcontainer2," + self.base_dn
2424 ldb
.delete("cn=ldaptestcontainer2," + self
.base_dn
)
2426 ldb
.add({"dn": "cn=ldaptestutf8user èùéìòà,cn=users," + self
.base_dn
, "objectClass": "user"})
2428 ldb
.add({"dn": "cn=ldaptestutf8user2 èùéìòà,cn=users," + self
.base_dn
, "objectClass": "user"})
2430 # Testing ldb.search for (&(cn=ldaptestuser)(objectClass=user))"
2431 res
= ldb
.search(expression
="(&(cn=ldaptestuser)(objectClass=user))")
2432 self
.assertEquals(len(res
), 1, "Could not find (&(cn=ldaptestuser)(objectClass=user))")
2434 self
.assertEquals(str(res
[0].dn
), ("CN=ldaptestuser,CN=Users," + self
.base_dn
))
2435 self
.assertEquals(str(res
[0]["cn"]), "ldaptestuser")
2436 self
.assertEquals(str(res
[0]["name"]), "ldaptestuser")
2437 self
.assertEquals(set(res
[0]["objectClass"]), set(["top", "person", "organizationalPerson", "user"]))
2438 self
.assertTrue("objectGUID" in res
[0])
2439 self
.assertTrue("whenCreated" in res
[0])
2440 self
.assertEquals(str(res
[0]["objectCategory"]), ("CN=Person,%s" % ldb
.get_schema_basedn()))
2441 self
.assertEquals(int(res
[0]["sAMAccountType"][0]), ATYPE_NORMAL_ACCOUNT
)
2442 self
.assertEquals(int(res
[0]["userAccountControl"][0]), UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE
)
2443 self
.assertEquals(res
[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self
.base_dn
).upper())
2444 self
.assertEquals(len(res
[0]["memberOf"]), 1)
2446 # Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=cn=person,%s))" % ldb.get_schema_basedn()
2447 res2
= ldb
.search(expression
="(&(cn=ldaptestuser)(objectCategory=cn=person,%s))" % ldb
.get_schema_basedn())
2448 self
.assertEquals(len(res2
), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=cn=person,%s))" % ldb
.get_schema_basedn())
2450 self
.assertEquals(res
[0].dn
, res2
[0].dn
)
2452 # Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon))"
2453 res3
= ldb
.search(expression
="(&(cn=ldaptestuser)(objectCategory=PerSon))")
2454 self
.assertEquals(len(res3
), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=PerSon)): matched %d" % len(res3
))
2456 self
.assertEquals(res
[0].dn
, res3
[0].dn
)
2458 if gc_ldb
is not None:
2459 # Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon)) in Global Catalog"
2460 res3gc
= gc_ldb
.search(expression
="(&(cn=ldaptestuser)(objectCategory=PerSon))")
2461 self
.assertEquals(len(res3gc
), 1)
2463 self
.assertEquals(res
[0].dn
, res3gc
[0].dn
)
2465 # Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon)) in with 'phantom root' control"
2467 if gc_ldb
is not None:
2468 res3control
= gc_ldb
.search(self
.base_dn
, expression
="(&(cn=ldaptestuser)(objectCategory=PerSon))", scope
=SCOPE_SUBTREE
, attrs
=["cn"], controls
=["search_options:1:2"])
2469 self
.assertEquals(len(res3control
), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=PerSon)) in Global Catalog")
2471 self
.assertEquals(res
[0].dn
, res3control
[0].dn
)
2473 ldb
.delete(res
[0].dn
)
2475 # Testing ldb.search for (&(cn=ldaptestcomputer)(objectClass=user))"
2476 res
= ldb
.search(expression
="(&(cn=ldaptestcomputer)(objectClass=user))")
2477 self
.assertEquals(len(res
), 1, "Could not find (&(cn=ldaptestuser)(objectClass=user))")
2479 self
.assertEquals(str(res
[0].dn
), ("CN=ldaptestcomputer,CN=Computers," + self
.base_dn
))
2480 self
.assertEquals(str(res
[0]["cn"]), "ldaptestcomputer")
2481 self
.assertEquals(str(res
[0]["name"]), "ldaptestcomputer")
2482 self
.assertEquals(set(res
[0]["objectClass"]), set(["top", "person", "organizationalPerson", "user", "computer"]))
2483 self
.assertTrue("objectGUID" in res
[0])
2484 self
.assertTrue("whenCreated" in res
[0])
2485 self
.assertEquals(str(res
[0]["objectCategory"]), ("CN=Computer,%s" % ldb
.get_schema_basedn()))
2486 self
.assertEquals(int(res
[0]["primaryGroupID"][0]), 513)
2487 self
.assertEquals(int(res
[0]["sAMAccountType"][0]), ATYPE_NORMAL_ACCOUNT
)
2488 self
.assertEquals(int(res
[0]["userAccountControl"][0]), UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE
)
2489 self
.assertEquals(res
[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self
.base_dn
).upper())
2490 self
.assertEquals(len(res
[0]["memberOf"]), 1)
2492 # Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=cn=computer,%s))" % ldb.get_schema_basedn()
2493 res2
= ldb
.search(expression
="(&(cn=ldaptestcomputer)(objectCategory=cn=computer,%s))" % ldb
.get_schema_basedn())
2494 self
.assertEquals(len(res2
), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=cn=computer,%s))" % ldb
.get_schema_basedn())
2496 self
.assertEquals(res
[0].dn
, res2
[0].dn
)
2498 if gc_ldb
is not None:
2499 # Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=cn=computer,%s)) in Global Catalog" % gc_ldb.get_schema_basedn()
2500 res2gc
= gc_ldb
.search(expression
="(&(cn=ldaptestcomputer)(objectCategory=cn=computer,%s))" % gc_ldb
.get_schema_basedn())
2501 self
.assertEquals(len(res2gc
), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=cn=computer,%s)) In Global Catalog" % gc_ldb
.get_schema_basedn())
2503 self
.assertEquals(res
[0].dn
, res2gc
[0].dn
)
2505 # Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=compuTER))"
2506 res3
= ldb
.search(expression
="(&(cn=ldaptestcomputer)(objectCategory=compuTER))")
2507 self
.assertEquals(len(res3
), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=compuTER))")
2509 self
.assertEquals(res
[0].dn
, res3
[0].dn
)
2511 if gc_ldb
is not None:
2512 # Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=compuTER)) in Global Catalog"
2513 res3gc
= gc_ldb
.search(expression
="(&(cn=ldaptestcomputer)(objectCategory=compuTER))")
2514 self
.assertEquals(len(res3gc
), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=compuTER)) in Global Catalog")
2516 self
.assertEquals(res
[0].dn
, res3gc
[0].dn
)
2518 # Testing ldb.search for (&(cn=ldaptestcomp*r)(objectCategory=compuTER))"
2519 res4
= ldb
.search(expression
="(&(cn=ldaptestcomp*r)(objectCategory=compuTER))")
2520 self
.assertEquals(len(res4
), 1, "Could not find (&(cn=ldaptestcomp*r)(objectCategory=compuTER))")
2522 self
.assertEquals(res
[0].dn
, res4
[0].dn
)
2524 # Testing ldb.search for (&(cn=ldaptestcomput*)(objectCategory=compuTER))"
2525 res5
= ldb
.search(expression
="(&(cn=ldaptestcomput*)(objectCategory=compuTER))")
2526 self
.assertEquals(len(res5
), 1, "Could not find (&(cn=ldaptestcomput*)(objectCategory=compuTER))")
2528 self
.assertEquals(res
[0].dn
, res5
[0].dn
)
2530 # Testing ldb.search for (&(cn=*daptestcomputer)(objectCategory=compuTER))"
2531 res6
= ldb
.search(expression
="(&(cn=*daptestcomputer)(objectCategory=compuTER))")
2532 self
.assertEquals(len(res6
), 1, "Could not find (&(cn=*daptestcomputer)(objectCategory=compuTER))")
2534 self
.assertEquals(res
[0].dn
, res6
[0].dn
)
2536 ldb
.delete("<GUID=" + ldb
.schema_format_value("objectGUID", res
[0]["objectGUID"][0]) + ">")
2538 # Testing ldb.search for (&(cn=ldaptest2computer)(objectClass=user))"
2539 res
= ldb
.search(expression
="(&(cn=ldaptest2computer)(objectClass=user))")
2540 self
.assertEquals(len(res
), 1, "Could not find (&(cn=ldaptest2computer)(objectClass=user))")
2542 self
.assertEquals(str(res
[0].dn
), "CN=ldaptest2computer,CN=Computers," + self
.base_dn
)
2543 self
.assertEquals(str(res
[0]["cn"]), "ldaptest2computer")
2544 self
.assertEquals(str(res
[0]["name"]), "ldaptest2computer")
2545 self
.assertEquals(list(res
[0]["objectClass"]), ["top", "person", "organizationalPerson", "user", "computer"])
2546 self
.assertTrue("objectGUID" in res
[0])
2547 self
.assertTrue("whenCreated" in res
[0])
2548 self
.assertEquals(res
[0]["objectCategory"][0], "CN=Computer,%s" % ldb
.get_schema_basedn())
2549 self
.assertEquals(int(res
[0]["sAMAccountType"][0]), ATYPE_WORKSTATION_TRUST
)
2550 self
.assertEquals(int(res
[0]["userAccountControl"][0]), UF_WORKSTATION_TRUST_ACCOUNT
)
2552 ldb
.delete("<SID=" + ldb
.schema_format_value("objectSID", res
[0]["objectSID"][0]) + ">")
2554 attrs
= ["cn", "name", "objectClass", "objectGUID", "objectSID", "whenCreated", "nTSecurityDescriptor", "memberOf", "allowedAttributes", "allowedAttributesEffective"]
2555 # Testing ldb.search for (&(cn=ldaptestUSer2)(objectClass=user))"
2556 res_user
= ldb
.search(self
.base_dn
, expression
="(&(cn=ldaptestUSer2)(objectClass=user))", scope
=SCOPE_SUBTREE
, attrs
=attrs
)
2557 self
.assertEquals(len(res_user
), 1, "Could not find (&(cn=ldaptestUSer2)(objectClass=user))")
2559 self
.assertEquals(str(res_user
[0].dn
), ("CN=ldaptestuser2,CN=Users," + self
.base_dn
))
2560 self
.assertEquals(str(res_user
[0]["cn"]), "ldaptestuser2")
2561 self
.assertEquals(str(res_user
[0]["name"]), "ldaptestuser2")
2562 self
.assertEquals(list(res_user
[0]["objectClass"]), ["top", "person", "organizationalPerson", "user"])
2563 self
.assertTrue("objectSid" in res_user
[0])
2564 self
.assertTrue("objectGUID" in res_user
[0])
2565 self
.assertTrue("whenCreated" in res_user
[0])
2566 self
.assertTrue("nTSecurityDescriptor" in res_user
[0])
2567 self
.assertTrue("allowedAttributes" in res_user
[0])
2568 self
.assertTrue("allowedAttributesEffective" in res_user
[0])
2569 self
.assertEquals(res_user
[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self
.base_dn
).upper())
2571 ldaptestuser2_sid
= res_user
[0]["objectSid"][0]
2572 ldaptestuser2_guid
= res_user
[0]["objectGUID"][0]
2574 attrs
= ["cn", "name", "objectClass", "objectGUID", "objectSID", "whenCreated", "nTSecurityDescriptor", "member", "allowedAttributes", "allowedAttributesEffective"]
2575 # Testing ldb.search for (&(cn=ldaptestgroup2)(objectClass=group))"
2576 res
= ldb
.search(self
.base_dn
, expression
="(&(cn=ldaptestgroup2)(objectClass=group))", scope
=SCOPE_SUBTREE
, attrs
=attrs
)
2577 self
.assertEquals(len(res
), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))")
2579 self
.assertEquals(str(res
[0].dn
), ("CN=ldaptestgroup2,CN=Users," + self
.base_dn
))
2580 self
.assertEquals(str(res
[0]["cn"]), "ldaptestgroup2")
2581 self
.assertEquals(str(res
[0]["name"]), "ldaptestgroup2")
2582 self
.assertEquals(list(res
[0]["objectClass"]), ["top", "group"])
2583 self
.assertTrue("objectGUID" in res
[0])
2584 self
.assertTrue("objectSid" in res
[0])
2585 self
.assertTrue("whenCreated" in res
[0])
2586 self
.assertTrue("nTSecurityDescriptor" in res
[0])
2587 self
.assertTrue("allowedAttributes" in res
[0])
2588 self
.assertTrue("allowedAttributesEffective" in res
[0])
2590 for m
in res
[0]["member"]:
2591 memberUP
.append(m
.upper())
2592 self
.assertTrue(("CN=ldaptestuser2,CN=Users," + self
.base_dn
).upper() in memberUP
)
2594 res
= ldb
.search(self
.base_dn
, expression
="(&(cn=ldaptestgroup2)(objectClass=group))", scope
=SCOPE_SUBTREE
, attrs
=attrs
, controls
=["extended_dn:1:1"])
2595 self
.assertEquals(len(res
), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))")
2597 print(res
[0]["member"])
2599 for m
in res
[0]["member"]:
2600 memberUP
.append(m
.upper())
2601 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())
2603 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
)
2605 # Quicktest for linked attributes"
2607 dn: cn=ldaptestgroup2,cn=users,""" + self
.base_dn
+ """
2610 member: CN=ldaptestuser2,CN=Users,""" + self
.base_dn
+ """
2611 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self
.base_dn
+ """
2615 dn: <GUID=""" + ldb
.schema_format_value("objectGUID", res
[0]["objectGUID"][0]) + """>
2618 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self
.base_dn
+ """
2622 dn: <SID=""" + ldb
.schema_format_value("objectSid", res
[0]["objectSid"][0]) + """>
2628 dn: cn=ldaptestgroup2,cn=users,""" + self
.base_dn
+ """
2631 member: <GUID=""" + ldb
.schema_format_value("objectGUID", res
[0]["objectGUID"][0]) + """>
2632 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self
.base_dn
+ """
2636 dn: cn=ldaptestgroup2,cn=users,""" + self
.base_dn
+ """
2642 dn: cn=ldaptestgroup2,cn=users,""" + self
.base_dn
+ """
2645 member: <SID=""" + ldb
.schema_format_value("objectSid", res_user
[0]["objectSid"][0]) + """>
2646 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self
.base_dn
+ """
2650 dn: cn=ldaptestgroup2,cn=users,""" + self
.base_dn
+ """
2653 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self
.base_dn
+ """
2656 res
= ldb
.search(self
.base_dn
, expression
="(&(cn=ldaptestgroup2)(objectClass=group))", scope
=SCOPE_SUBTREE
, attrs
=attrs
)
2657 self
.assertEquals(len(res
), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))")
2659 self
.assertEquals(str(res
[0].dn
), ("CN=ldaptestgroup2,CN=Users," + self
.base_dn
))
2660 self
.assertEquals(res
[0]["member"][0], ("CN=ldaptestuser2,CN=Users," + self
.base_dn
))
2661 self
.assertEquals(len(res
[0]["member"]), 1)
2663 ldb
.delete(("CN=ldaptestuser2,CN=Users," + self
.base_dn
))
2667 attrs
= ["cn", "name", "objectClass", "objectGUID", "whenCreated", "nTSecurityDescriptor", "member"]
2668 # Testing ldb.search for (&(cn=ldaptestgroup2)(objectClass=group)) to check linked delete"
2669 res
= ldb
.search(self
.base_dn
, expression
="(&(cn=ldaptestgroup2)(objectClass=group))", scope
=SCOPE_SUBTREE
, attrs
=attrs
)
2670 self
.assertEquals(len(res
), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group)) to check linked delete")
2672 self
.assertEquals(str(res
[0].dn
), ("CN=ldaptestgroup2,CN=Users," + self
.base_dn
))
2673 self
.assertTrue("member" not in res
[0])
2675 # Testing ldb.search for (&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))"
2676 res
= ldb
.search(expression
="(&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
2677 self
.assertEquals(len(res
), 1, "Could not find (&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
2678 res
= ldb
.search(expression
="(&(cn=ldaptestutf8user èùéìòà)(objectclass=user))")
2679 self
.assertEquals(len(res
), 1, "Could not find (&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
2681 self
.assertEquals(str(res
[0].dn
), ("CN=ldaptestutf8user èùéìòà,CN=Users," + self
.base_dn
))
2682 self
.assertEquals(str(res
[0]["cn"]), "ldaptestutf8user èùéìòà")
2683 self
.assertEquals(str(res
[0]["name"]), "ldaptestutf8user èùéìòà")
2684 self
.assertEquals(list(res
[0]["objectClass"]), ["top", "person", "organizationalPerson", "user"])
2685 self
.assertTrue("objectGUID" in res
[0])
2686 self
.assertTrue("whenCreated" in res
[0])
2688 # delete "ldaptestutf8user"
2689 ldb
.delete(res
[0].dn
)
2691 # Testing ldb.search for (&(cn=ldaptestutf8user2*)(objectClass=user))"
2692 res
= ldb
.search(expression
="(&(cn=ldaptestutf8user2*)(objectClass=user))")
2693 self
.assertEquals(len(res
), 1, "Could not find (&(cn=ldaptestutf8user2*)(objectClass=user))")
2695 # Testing ldb.search for (&(cn=ldaptestutf8user2 ÈÙÉÌÒÀ)(objectClass=user))"
2696 res
= ldb
.search(expression
="(&(cn=ldaptestutf8user2 ÈÙÉÌÒÀ)(objectClass=user))")
2697 self
.assertEquals(len(res
), 1, "Could not find (&(cn=ldaptestutf8user2 ÈÙÉÌÒÀ)(objectClass=user))")
2699 # delete "ldaptestutf8user2 "
2700 ldb
.delete(res
[0].dn
)
2702 ldb
.delete(("CN=ldaptestgroup2,CN=Users," + self
.base_dn
))
2704 # Testing that we can't get at the configuration DN from the main search base"
2705 res
= ldb
.search(self
.base_dn
, expression
="objectClass=crossRef", scope
=SCOPE_SUBTREE
, attrs
=["cn"])
2706 self
.assertEquals(len(res
), 0)
2708 # 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"
2709 res
= ldb
.search(self
.base_dn
, expression
="objectClass=crossRef", scope
=SCOPE_SUBTREE
, attrs
=["cn"], controls
=["search_options:1:2"])
2710 self
.assertTrue(len(res
) > 0)
2712 if gc_ldb
is not None:
2713 # Testing that we can get at the configuration DN from the main search base on the GC port with the search_options control == 0"
2715 res
= gc_ldb
.search(self
.base_dn
, expression
="objectClass=crossRef", scope
=SCOPE_SUBTREE
, attrs
=["cn"], controls
=["search_options:1:0"])
2716 self
.assertTrue(len(res
) > 0)
2718 # Testing that we do find configuration elements in the global catlog"
2719 res
= gc_ldb
.search(self
.base_dn
, expression
="objectClass=crossRef", scope
=SCOPE_SUBTREE
, attrs
=["cn"])
2720 self
.assertTrue(len(res
) > 0)
2722 # Testing that we do find configuration elements and user elements at the same time"
2723 res
= gc_ldb
.search(self
.base_dn
, expression
="(|(objectClass=crossRef)(objectClass=person))", scope
=SCOPE_SUBTREE
, attrs
=["cn"])
2724 self
.assertTrue(len(res
) > 0)
2726 # Testing that we do find configuration elements in the global catlog, with the configuration basedn"
2727 res
= gc_ldb
.search(self
.configuration_dn
, expression
="objectClass=crossRef", scope
=SCOPE_SUBTREE
, attrs
=["cn"])
2728 self
.assertTrue(len(res
) > 0)
2730 # Testing that we can get at the configuration DN on the main LDAP port"
2731 res
= ldb
.search(self
.configuration_dn
, expression
="objectClass=crossRef", scope
=SCOPE_SUBTREE
, attrs
=["cn"])
2732 self
.assertTrue(len(res
) > 0)
2734 # Testing objectCategory canonacolisation"
2735 res
= ldb
.search(self
.configuration_dn
, expression
="objectCategory=ntDsDSA", scope
=SCOPE_SUBTREE
, attrs
=["cn"])
2736 self
.assertTrue(len(res
) > 0, "Didn't find any records with objectCategory=ntDsDSA")
2737 self
.assertTrue(len(res
) != 0)
2739 res
= ldb
.search(self
.configuration_dn
, expression
="objectCategory=CN=ntDs-DSA," + self
.schema_dn
, scope
=SCOPE_SUBTREE
, attrs
=["cn"])
2740 self
.assertTrue(len(res
) > 0, "Didn't find any records with objectCategory=CN=ntDs-DSA," + self
.schema_dn
)
2741 self
.assertTrue(len(res
) != 0)
2743 # Testing objectClass attribute order on "+ self.base_dn
2744 res
= ldb
.search(expression
="objectClass=domain", base
=self
.base_dn
,
2745 scope
=SCOPE_BASE
, attrs
=["objectClass"])
2746 self
.assertEquals(len(res
), 1)
2748 self
.assertEquals(list(res
[0]["objectClass"]), ["top", "domain", "domainDNS"])
2752 # Testing ldb.search for objectCategory=person"
2753 res
= ldb
.search(self
.base_dn
, expression
="objectCategory=person", scope
=SCOPE_SUBTREE
, attrs
=["cn"])
2754 self
.assertTrue(len(res
) > 0)
2756 # Testing ldb.search for objectCategory=person with domain scope control"
2757 res
= ldb
.search(self
.base_dn
, expression
="objectCategory=person", scope
=SCOPE_SUBTREE
, attrs
=["cn"], controls
=["domain_scope:1"])
2758 self
.assertTrue(len(res
) > 0)
2760 # Testing ldb.search for objectCategory=user"
2761 res
= ldb
.search(self
.base_dn
, expression
="objectCategory=user", scope
=SCOPE_SUBTREE
, attrs
=["cn"])
2762 self
.assertTrue(len(res
) > 0)
2764 # Testing ldb.search for objectCategory=user with domain scope control"
2765 res
= ldb
.search(self
.base_dn
, expression
="objectCategory=user", scope
=SCOPE_SUBTREE
, attrs
=["cn"], controls
=["domain_scope:1"])
2766 self
.assertTrue(len(res
) > 0)
2768 # Testing ldb.search for objectCategory=group"
2769 res
= ldb
.search(self
.base_dn
, expression
="objectCategory=group", scope
=SCOPE_SUBTREE
, attrs
=["cn"])
2770 self
.assertTrue(len(res
) > 0)
2772 # Testing ldb.search for objectCategory=group with domain scope control"
2773 res
= ldb
.search(self
.base_dn
, expression
="objectCategory=group", scope
=SCOPE_SUBTREE
, attrs
=["cn"], controls
=["domain_scope:1"])
2774 self
.assertTrue(len(res
) > 0)
2776 # Testing creating a user with the posixAccount objectClass"
2777 self
.ldb
.add_ldif("""dn: cn=posixuser,CN=Users,%s
2780 objectClass: posixAccount
2782 objectClass: organizationalPerson
2788 homeDirectory: /home/posixuser
2789 loginShell: /bin/bash
2790 gecos: Posix User;;;
2791 description: A POSIX user"""% (self
.base_dn
))
2793 # Testing removing the posixAccount objectClass from an existing user"
2794 self
.ldb
.modify_ldif("""dn: cn=posixuser,CN=Users,%s
2797 objectClass: posixAccount"""% (self
.base_dn
))
2799 # Testing adding the posixAccount objectClass to an existing user"
2800 self
.ldb
.modify_ldif("""dn: cn=posixuser,CN=Users,%s
2803 objectClass: posixAccount"""% (self
.base_dn
))
2805 delete_force(self
.ldb
, "cn=posixuser,cn=users," + self
.base_dn
)
2806 delete_force(self
.ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
2807 delete_force(self
.ldb
, "cn=ldaptestuser2,cn=users," + self
.base_dn
)
2808 delete_force(self
.ldb
, "cn=ldaptestuser3,cn=users," + self
.base_dn
)
2809 delete_force(self
.ldb
, "cn=ldaptestuser4,cn=ldaptestcontainer," + self
.base_dn
)
2810 delete_force(self
.ldb
, "cn=ldaptestuser4,cn=ldaptestcontainer2," + self
.base_dn
)
2811 delete_force(self
.ldb
, "cn=ldaptestuser5,cn=users," + self
.base_dn
)
2812 delete_force(self
.ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
2813 delete_force(self
.ldb
, "cn=ldaptestgroup2,cn=users," + self
.base_dn
)
2814 delete_force(self
.ldb
, "cn=ldaptestcomputer,cn=computers," + self
.base_dn
)
2815 delete_force(self
.ldb
, "cn=ldaptest2computer,cn=computers," + self
.base_dn
)
2816 delete_force(self
.ldb
, "cn=ldaptestcomputer3,cn=computers," + self
.base_dn
)
2817 delete_force(self
.ldb
, "cn=ldaptestutf8user èùéìòà,cn=users," + self
.base_dn
)
2818 delete_force(self
.ldb
, "cn=ldaptestutf8user2 èùéìòà,cn=users," + self
.base_dn
)
2819 delete_force(self
.ldb
, "cn=ldaptestcontainer," + self
.base_dn
)
2820 delete_force(self
.ldb
, "cn=ldaptestcontainer2," + self
.base_dn
)
2822 def test_security_descriptor_add(self
):
2823 """ Testing ldb.add_ldif() for nTSecurityDescriptor """
2824 user_name
= "testdescriptoruser1"
2825 user_dn
= "CN=%s,CN=Users,%s" % (user_name
, self
.base_dn
)
2827 # Test an empty security descriptor (naturally this shouldn't work)
2829 delete_force(self
.ldb
, user_dn
)
2831 self
.ldb
.add({ "dn": user_dn
,
2832 "objectClass": "user",
2833 "sAMAccountName": user_name
,
2834 "nTSecurityDescriptor": [] })
2836 except LdbError
as e107
:
2837 (num
, _
) = e107
.args
2838 self
.assertEquals(num
, ERR_CONSTRAINT_VIOLATION
)
2840 delete_force(self
.ldb
, user_dn
)
2842 # Test add_ldif() with SDDL security descriptor input
2845 sddl
= "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2846 self
.ldb
.add_ldif("""
2847 dn: """ + user_dn
+ """
2849 sAMAccountName: """ + user_name
+ """
2850 nTSecurityDescriptor: """ + sddl
)
2851 res
= self
.ldb
.search(base
=user_dn
, attrs
=["nTSecurityDescriptor"])
2852 desc
= res
[0]["nTSecurityDescriptor"][0]
2853 desc
= ndr_unpack( security
.descriptor
, desc
)
2854 desc_sddl
= desc
.as_sddl( self
.domain_sid
)
2855 self
.assertEqual(desc_sddl
, sddl
)
2857 delete_force(self
.ldb
, user_dn
)
2859 # Test add_ldif() with BASE64 security descriptor
2862 sddl
= "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2863 desc
= security
.descriptor
.from_sddl(sddl
, self
.domain_sid
)
2864 desc_binary
= ndr_pack(desc
)
2865 desc_base64
= base64
.b64encode(desc_binary
).decode('utf8')
2866 self
.ldb
.add_ldif("""
2867 dn: """ + user_dn
+ """
2869 sAMAccountName: """ + user_name
+ """
2870 nTSecurityDescriptor:: """ + desc_base64
)
2871 res
= self
.ldb
.search(base
=user_dn
, attrs
=["nTSecurityDescriptor"])
2872 desc
= res
[0]["nTSecurityDescriptor"][0]
2873 desc
= ndr_unpack(security
.descriptor
, desc
)
2874 desc_sddl
= desc
.as_sddl(self
.domain_sid
)
2875 self
.assertEqual(desc_sddl
, sddl
)
2877 delete_force(self
.ldb
, user_dn
)
2879 def test_security_descriptor_add_neg(self
):
2880 """Test add_ldif() with BASE64 security descriptor input using WRONG domain SID
2883 user_name
= "testdescriptoruser1"
2884 user_dn
= "CN=%s,CN=Users,%s" % (user_name
, self
.base_dn
)
2885 delete_force(self
.ldb
, user_dn
)
2887 sddl
= "O:DUG:DUD:AI(A;;RPWP;;;AU)S:PAI"
2888 desc
= security
.descriptor
.from_sddl(sddl
, security
.dom_sid('S-1-5-21'))
2889 desc_base64
= base64
.b64encode( ndr_pack(desc
) ).decode('utf8')
2890 self
.ldb
.add_ldif("""
2891 dn: """ + user_dn
+ """
2893 sAMAccountName: """ + user_name
+ """
2894 nTSecurityDescriptor:: """ + desc_base64
)
2895 res
= self
.ldb
.search(base
=user_dn
, attrs
=["nTSecurityDescriptor"])
2896 self
.assertTrue("nTSecurityDescriptor" in res
[0])
2897 desc
= res
[0]["nTSecurityDescriptor"][0]
2898 desc
= ndr_unpack(security
.descriptor
, desc
)
2899 desc_sddl
= desc
.as_sddl(self
.domain_sid
)
2900 self
.assertTrue("O:S-1-5-21-513G:S-1-5-21-513D:AI(A;;RPWP;;;AU)" in desc_sddl
)
2902 delete_force(self
.ldb
, user_dn
)
2904 def test_security_descriptor_modify(self
):
2905 """ Testing ldb.modify_ldif() for nTSecurityDescriptor """
2906 user_name
= "testdescriptoruser2"
2907 user_dn
= "CN=%s,CN=Users,%s" % (user_name
, self
.base_dn
)
2909 # Test an empty security descriptor (naturally this shouldn't work)
2911 delete_force(self
.ldb
, user_dn
)
2912 self
.ldb
.add({ "dn": user_dn
,
2913 "objectClass": "user",
2914 "sAMAccountName": user_name
})
2917 m
.dn
= Dn(ldb
, user_dn
)
2918 m
["nTSecurityDescriptor"] = MessageElement([], FLAG_MOD_ADD
,
2919 "nTSecurityDescriptor")
2923 except LdbError
as e108
:
2924 (num
, _
) = e108
.args
2925 self
.assertEquals(num
, ERR_CONSTRAINT_VIOLATION
)
2928 m
.dn
= Dn(ldb
, user_dn
)
2929 m
["nTSecurityDescriptor"] = MessageElement([], FLAG_MOD_REPLACE
,
2930 "nTSecurityDescriptor")
2934 except LdbError
as e109
:
2935 (num
, _
) = e109
.args
2936 self
.assertEquals(num
, ERR_UNWILLING_TO_PERFORM
)
2939 m
.dn
= Dn(ldb
, user_dn
)
2940 m
["nTSecurityDescriptor"] = MessageElement([], FLAG_MOD_DELETE
,
2941 "nTSecurityDescriptor")
2945 except LdbError
as e110
:
2946 (num
, _
) = e110
.args
2947 self
.assertEquals(num
, ERR_UNWILLING_TO_PERFORM
)
2949 delete_force(self
.ldb
, user_dn
)
2951 # Test modify_ldif() with SDDL security descriptor input
2952 # Add ACE to the original descriptor test
2955 self
.ldb
.add_ldif("""
2956 dn: """ + user_dn
+ """
2958 sAMAccountName: """ + user_name
)
2960 res
= self
.ldb
.search(base
=user_dn
, attrs
=["nTSecurityDescriptor"])
2961 desc
= res
[0]["nTSecurityDescriptor"][0]
2962 desc
= ndr_unpack(security
.descriptor
, desc
)
2963 desc_sddl
= desc
.as_sddl(self
.domain_sid
)
2964 sddl
= desc_sddl
[:desc_sddl
.find("(")] + "(A;;RPWP;;;AU)" + desc_sddl
[desc_sddl
.find("("):]
2966 dn: """ + user_dn
+ """
2968 replace: nTSecurityDescriptor
2969 nTSecurityDescriptor: """ + sddl
2970 self
.ldb
.modify_ldif(mod
)
2971 # Read modified descriptor
2972 res
= self
.ldb
.search(base
=user_dn
, attrs
=["nTSecurityDescriptor"])
2973 desc
= res
[0]["nTSecurityDescriptor"][0]
2974 desc
= ndr_unpack(security
.descriptor
, desc
)
2975 desc_sddl
= desc
.as_sddl(self
.domain_sid
)
2976 self
.assertEqual(desc_sddl
, sddl
)
2978 delete_force(self
.ldb
, user_dn
)
2980 # Test modify_ldif() with SDDL security descriptor input
2981 # New desctiptor test
2984 self
.ldb
.add_ldif("""
2985 dn: """ + user_dn
+ """
2987 sAMAccountName: """ + user_name
)
2989 sddl
= "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2991 dn: """ + user_dn
+ """
2993 replace: nTSecurityDescriptor
2994 nTSecurityDescriptor: """ + sddl
2995 self
.ldb
.modify_ldif(mod
)
2996 # Read modified descriptor
2997 res
= self
.ldb
.search(base
=user_dn
, attrs
=["nTSecurityDescriptor"])
2998 desc
= res
[0]["nTSecurityDescriptor"][0]
2999 desc
= ndr_unpack(security
.descriptor
, desc
)
3000 desc_sddl
= desc
.as_sddl(self
.domain_sid
)
3001 self
.assertEqual(desc_sddl
, sddl
)
3003 delete_force(self
.ldb
, user_dn
)
3005 # Test modify_ldif() with BASE64 security descriptor input
3006 # Add ACE to the original descriptor test
3009 self
.ldb
.add_ldif("""
3010 dn: """ + user_dn
+ """
3012 sAMAccountName: """ + user_name
)
3014 res
= self
.ldb
.search(base
=user_dn
, attrs
=["nTSecurityDescriptor"])
3015 desc
= res
[0]["nTSecurityDescriptor"][0]
3016 desc
= ndr_unpack(security
.descriptor
, desc
)
3017 desc_sddl
= desc
.as_sddl(self
.domain_sid
)
3018 sddl
= desc_sddl
[:desc_sddl
.find("(")] + "(A;;RPWP;;;AU)" + desc_sddl
[desc_sddl
.find("("):]
3019 desc
= security
.descriptor
.from_sddl(sddl
, self
.domain_sid
)
3020 desc_base64
= base64
.b64encode(ndr_pack(desc
)).decode('utf8')
3022 dn: """ + user_dn
+ """
3024 replace: nTSecurityDescriptor
3025 nTSecurityDescriptor:: """ + desc_base64
3026 self
.ldb
.modify_ldif(mod
)
3027 # Read modified descriptor
3028 res
= self
.ldb
.search(base
=user_dn
, attrs
=["nTSecurityDescriptor"])
3029 desc
= res
[0]["nTSecurityDescriptor"][0]
3030 desc
= ndr_unpack(security
.descriptor
, desc
)
3031 desc_sddl
= desc
.as_sddl(self
.domain_sid
)
3032 self
.assertEqual(desc_sddl
, sddl
)
3034 delete_force(self
.ldb
, user_dn
)
3036 # Test modify_ldif() with BASE64 security descriptor input
3037 # New descriptor test
3040 delete_force(self
.ldb
, user_dn
)
3041 self
.ldb
.add_ldif("""
3042 dn: """ + user_dn
+ """
3044 sAMAccountName: """ + user_name
)
3046 sddl
= "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
3047 desc
= security
.descriptor
.from_sddl(sddl
, self
.domain_sid
)
3048 desc_base64
= base64
.b64encode(ndr_pack(desc
)).decode('utf8')
3050 dn: """ + user_dn
+ """
3052 replace: nTSecurityDescriptor
3053 nTSecurityDescriptor:: """ + desc_base64
3054 self
.ldb
.modify_ldif(mod
)
3055 # Read modified descriptor
3056 res
= self
.ldb
.search(base
=user_dn
, attrs
=["nTSecurityDescriptor"])
3057 desc
= res
[0]["nTSecurityDescriptor"][0]
3058 desc
= ndr_unpack(security
.descriptor
, desc
)
3059 desc_sddl
= desc
.as_sddl(self
.domain_sid
)
3060 self
.assertEqual(desc_sddl
, sddl
)
3062 delete_force(self
.ldb
, user_dn
)
3064 def test_dsheuristics(self
):
3065 """Tests the 'dSHeuristics' attribute"""
3066 # Tests the 'dSHeuristics' attribute"
3068 # Get the current value to restore it later
3069 dsheuristics
= self
.ldb
.get_dsheuristics()
3070 # Perform the length checks: for each decade (except the 0th) we need
3071 # the first index to be the number. This goes till the 9th one, beyond
3072 # there does not seem to be another limitation.
3075 for i
in range(1,11):
3076 # This is in the range
3077 self
.ldb
.set_dsheuristics(dshstr
+ "x")
3078 self
.ldb
.set_dsheuristics(dshstr
+ "xxxxx")
3079 dshstr
= dshstr
+ "xxxxxxxxx"
3081 # Not anymore in the range, new decade specifier needed
3083 self
.ldb
.set_dsheuristics(dshstr
+ "x")
3085 except LdbError
as e
:
3087 self
.assertEquals(num
, ERR_CONSTRAINT_VIOLATION
)
3088 dshstr
= dshstr
+ str(i
)
3090 # There does not seem to be an upper limit
3091 self
.ldb
.set_dsheuristics(dshstr
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
3092 # apart from the above, all char values are accepted
3093 self
.ldb
.set_dsheuristics("123ABC-+!1asdfg@#^")
3094 self
.assertEquals(self
.ldb
.get_dsheuristics(), "123ABC-+!1asdfg@#^")
3097 self
.ldb
.set_dsheuristics(dsheuristics
)
3099 def test_ldapControlReturn(self
):
3100 """Testing that if we request a control that return a control it
3101 really return something"""
3102 res
= self
.ldb
.search(attrs
=["cn"],
3103 controls
=["paged_results:1:10"])
3104 self
.assertEquals(len(res
.controls
), 1)
3105 self
.assertEquals(res
.controls
[0].oid
, "1.2.840.113556.1.4.319")
3106 s
= str(res
.controls
[0])
3108 def test_operational(self
):
3109 """Tests operational attributes"""
3110 # Tests operational attributes"
3112 res
= self
.ldb
.search(self
.base_dn
, scope
=SCOPE_BASE
,
3113 attrs
=["createTimeStamp", "modifyTimeStamp",
3114 "structuralObjectClass", "whenCreated",
3116 self
.assertEquals(len(res
), 1)
3117 self
.assertTrue("createTimeStamp" in res
[0])
3118 self
.assertTrue("modifyTimeStamp" in res
[0])
3119 self
.assertTrue("structuralObjectClass" in res
[0])
3120 self
.assertTrue("whenCreated" in res
[0])
3121 self
.assertTrue("whenChanged" in res
[0])
3123 def test_timevalues1(self
):
3124 """Tests possible syntax of time attributes"""
3126 user_name
= "testtimevaluesuser1"
3127 user_dn
= "CN=%s,CN=Users,%s" % (user_name
, self
.base_dn
)
3129 delete_force(self
.ldb
, user_dn
)
3130 self
.ldb
.add({ "dn": user_dn
,
3131 "objectClass": "user",
3132 "sAMAccountName": user_name
})
3135 # We check the following values:
3137 # 370101000000Z => 20370101000000.0Z
3138 # 20370102000000.*Z => 20370102000000.0Z
3140 ext
= [ "Z", ".0Z", ".Z", ".000Z", ".RandomIgnoredCharacters...987654321Z" ]
3141 for i
in range(0, len(ext
)):
3142 v_raw
= "203701%02d000000" % (i
+ 1)
3144 v_set
= v_raw
[2:] + ext
[i
]
3146 v_set
= v_raw
+ ext
[i
]
3147 v_get
= v_raw
+ ".0Z"
3150 m
.dn
= Dn(ldb
, user_dn
)
3151 m
["msTSExpireDate"] = MessageElement([v_set
],
3156 res
= self
.ldb
.search(base
=user_dn
, scope
=SCOPE_BASE
, attrs
=["msTSExpireDate"])
3157 self
.assertTrue(len(res
) == 1)
3158 self
.assertTrue("msTSExpireDate" in res
[0])
3159 self
.assertTrue(len(res
[0]["msTSExpireDate"]) == 1)
3160 self
.assertEquals(res
[0]["msTSExpireDate"][0], v_get
)
3162 class BaseDnTests(samba
.tests
.TestCase
):
3165 super(BaseDnTests
, self
).setUp()
3168 def test_rootdse_attrs(self
):
3169 """Testing for all rootDSE attributes"""
3170 res
= self
.ldb
.search("", scope
=SCOPE_BASE
, attrs
=[])
3171 self
.assertEquals(len(res
), 1)
3173 def test_highestcommittedusn(self
):
3174 """Testing for highestCommittedUSN"""
3175 res
= self
.ldb
.search("", scope
=SCOPE_BASE
, attrs
=["highestCommittedUSN"])
3176 self
.assertEquals(len(res
), 1)
3177 self
.assertTrue(int(res
[0]["highestCommittedUSN"][0]) != 0)
3179 def test_netlogon(self
):
3180 """Testing for netlogon via LDAP"""
3181 res
= self
.ldb
.search("", scope
=SCOPE_BASE
, attrs
=["netlogon"])
3182 self
.assertEquals(len(res
), 0)
3184 def test_netlogon_highestcommitted_usn(self
):
3185 """Testing for netlogon and highestCommittedUSN via LDAP"""
3186 res
= self
.ldb
.search("", scope
=SCOPE_BASE
,
3187 attrs
=["netlogon", "highestCommittedUSN"])
3188 self
.assertEquals(len(res
), 0)
3190 def test_namingContexts(self
):
3191 """Testing for namingContexts in rootDSE"""
3192 res
= self
.ldb
.search("", scope
=SCOPE_BASE
,
3193 attrs
=["namingContexts", "defaultNamingContext", "schemaNamingContext", "configurationNamingContext"])
3194 self
.assertEquals(len(res
), 1)
3197 for nc
in res
[0]["namingContexts"]:
3198 self
.assertTrue(nc
not in ncs
)
3201 self
.assertTrue(res
[0]["defaultNamingContext"][0] in ncs
)
3202 self
.assertTrue(res
[0]["configurationNamingContext"][0] in ncs
)
3203 self
.assertTrue(res
[0]["schemaNamingContext"][0] in ncs
)
3205 def test_serverPath(self
):
3206 """Testing the server paths in rootDSE"""
3207 res
= self
.ldb
.search("", scope
=SCOPE_BASE
,
3208 attrs
=["dsServiceName", "serverName"])
3209 self
.assertEquals(len(res
), 1)
3211 self
.assertTrue("CN=Servers" in res
[0]["dsServiceName"][0])
3212 self
.assertTrue("CN=Sites" in res
[0]["dsServiceName"][0])
3213 self
.assertTrue("CN=NTDS Settings" in res
[0]["dsServiceName"][0])
3214 self
.assertTrue("CN=Servers" in res
[0]["serverName"][0])
3215 self
.assertTrue("CN=Sites" in res
[0]["serverName"][0])
3216 self
.assertFalse("CN=NTDS Settings" in res
[0]["serverName"][0])
3218 def test_functionality(self
):
3219 """Testing the server paths in rootDSE"""
3220 res
= self
.ldb
.search("", scope
=SCOPE_BASE
,
3221 attrs
=["forestFunctionality", "domainFunctionality", "domainControllerFunctionality"])
3222 self
.assertEquals(len(res
), 1)
3223 self
.assertEquals(len(res
[0]["forestFunctionality"]), 1)
3224 self
.assertEquals(len(res
[0]["domainFunctionality"]), 1)
3225 self
.assertEquals(len(res
[0]["domainControllerFunctionality"]), 1)
3227 self
.assertTrue(int(res
[0]["forestFunctionality"][0]) <= int(res
[0]["domainFunctionality"][0]))
3228 self
.assertTrue(int(res
[0]["domainControllerFunctionality"][0]) >= int(res
[0]["domainFunctionality"][0]))
3230 res2
= self
.ldb
.search("", scope
=SCOPE_BASE
,
3231 attrs
=["dsServiceName", "serverName"])
3232 self
.assertEquals(len(res2
), 1)
3233 self
.assertEquals(len(res2
[0]["dsServiceName"]), 1)
3235 res3
= self
.ldb
.search(res2
[0]["dsServiceName"][0], scope
=SCOPE_BASE
, attrs
=["msDS-Behavior-Version"])
3236 self
.assertEquals(len(res3
), 1)
3237 self
.assertEquals(len(res3
[0]["msDS-Behavior-Version"]), 1)
3238 self
.assertEquals(int(res
[0]["domainControllerFunctionality"][0]), int(res3
[0]["msDS-Behavior-Version"][0]))
3240 res4
= self
.ldb
.search(ldb
.domain_dn(), scope
=SCOPE_BASE
, attrs
=["msDS-Behavior-Version"])
3241 self
.assertEquals(len(res4
), 1)
3242 self
.assertEquals(len(res4
[0]["msDS-Behavior-Version"]), 1)
3243 self
.assertEquals(int(res
[0]["domainFunctionality"][0]), int(res4
[0]["msDS-Behavior-Version"][0]))
3245 res5
= self
.ldb
.search("cn=partitions,%s" % ldb
.get_config_basedn(), scope
=SCOPE_BASE
, attrs
=["msDS-Behavior-Version"])
3246 self
.assertEquals(len(res5
), 1)
3247 self
.assertEquals(len(res5
[0]["msDS-Behavior-Version"]), 1)
3248 self
.assertEquals(int(res
[0]["forestFunctionality"][0]), int(res5
[0]["msDS-Behavior-Version"][0]))
3250 def test_dnsHostname(self
):
3251 """Testing the DNS hostname in rootDSE"""
3252 res
= self
.ldb
.search("", scope
=SCOPE_BASE
,
3253 attrs
=["dnsHostName", "serverName"])
3254 self
.assertEquals(len(res
), 1)
3256 res2
= self
.ldb
.search(res
[0]["serverName"][0], scope
=SCOPE_BASE
,
3257 attrs
=["dNSHostName"])
3258 self
.assertEquals(len(res2
), 1)
3260 self
.assertEquals(res
[0]["dnsHostName"][0], res2
[0]["dNSHostName"][0])
3262 def test_ldapServiceName(self
):
3263 """Testing the ldap service name in rootDSE"""
3264 res
= self
.ldb
.search("", scope
=SCOPE_BASE
,
3265 attrs
=["ldapServiceName", "dnsHostName"])
3266 self
.assertEquals(len(res
), 1)
3267 self
.assertTrue("ldapServiceName" in res
[0])
3268 self
.assertTrue("dnsHostName" in res
[0])
3270 (hostname
, _
, dns_domainname
) = res
[0]["dnsHostName"][0].partition(".")
3272 given
= res
[0]["ldapServiceName"][0]
3273 expected
= "%s:%s$@%s" % (dns_domainname
.lower(), hostname
.lower(), dns_domainname
.upper())
3274 self
.assertEquals(given
, expected
)
3276 if not "://" in host
:
3277 if os
.path
.isfile(host
):
3278 host
= "tdb://%s" % host
3280 host
= "ldap://%s" % host
3282 ldb
= SamDB(host
, credentials
=creds
, session_info
=system_session(lp
), lp
=lp
)
3283 if not "tdb://" in host
:
3284 gc_ldb
= Ldb("%s:3268" % host
, credentials
=creds
,
3285 session_info
=system_session(lp
), lp
=lp
)
3289 TestProgram(module
=__name__
, opts
=subunitopts
)