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/>.
26 sys
.path
.insert(0, "bin/python")
28 from samba
.tests
.subunitrun
import SubunitOptions
, TestProgram
29 import samba
.getopt
as options
31 from samba
.auth
import system_session
32 from ldb
import SCOPE_SUBTREE
, SCOPE_ONELEVEL
, SCOPE_BASE
, LdbError
33 from ldb
import ERR_NO_SUCH_OBJECT
, ERR_ATTRIBUTE_OR_VALUE_EXISTS
34 from ldb
import ERR_ENTRY_ALREADY_EXISTS
, ERR_UNWILLING_TO_PERFORM
35 from ldb
import ERR_NOT_ALLOWED_ON_NON_LEAF
, ERR_OTHER
, ERR_INVALID_DN_SYNTAX
36 from ldb
import ERR_NO_SUCH_ATTRIBUTE
, ERR_INVALID_ATTRIBUTE_SYNTAX
37 from ldb
import ERR_OBJECT_CLASS_VIOLATION
, ERR_NOT_ALLOWED_ON_RDN
38 from ldb
import ERR_NAMING_VIOLATION
, ERR_CONSTRAINT_VIOLATION
39 from ldb
import Message
, MessageElement
, Dn
40 from ldb
import FLAG_MOD_ADD
, FLAG_MOD_REPLACE
, FLAG_MOD_DELETE
41 from ldb
import timestring
43 from samba
.samdb
import SamDB
44 from samba
.dsdb
import (UF_NORMAL_ACCOUNT
,
45 UF_WORKSTATION_TRUST_ACCOUNT
,
46 UF_PASSWD_NOTREQD
, UF_ACCOUNTDISABLE
, ATYPE_NORMAL_ACCOUNT
,
47 ATYPE_WORKSTATION_TRUST
, SYSTEM_FLAG_DOMAIN_DISALLOW_MOVE
,
48 SYSTEM_FLAG_CONFIG_ALLOW_RENAME
, SYSTEM_FLAG_CONFIG_ALLOW_MOVE
,
49 SYSTEM_FLAG_CONFIG_ALLOW_LIMITED_MOVE
)
50 from samba
.dcerpc
.security
import DOMAIN_RID_DOMAIN_MEMBERS
52 from samba
.ndr
import ndr_pack
, ndr_unpack
53 from samba
.dcerpc
import security
, lsa
54 from samba
.tests
import delete_force
55 from samba
.common
import get_string
57 parser
= optparse
.OptionParser("ldap.py [options] <host>")
58 sambaopts
= options
.SambaOptions(parser
)
59 parser
.add_option_group(sambaopts
)
60 parser
.add_option_group(options
.VersionOptions(parser
))
61 # use command line creds if available
62 credopts
= options
.CredentialsOptions(parser
)
63 parser
.add_option_group(credopts
)
64 subunitopts
= SubunitOptions(parser
)
65 parser
.add_option_group(subunitopts
)
66 opts
, args
= parser
.parse_args()
74 lp
= sambaopts
.get_loadparm()
75 creds
= credopts
.get_credentials(lp
)
78 class BasicTests(samba
.tests
.TestCase
):
81 super(BasicTests
, self
).setUp()
84 self
.base_dn
= ldb
.domain_dn()
85 self
.configuration_dn
= ldb
.get_config_basedn().get_linearized()
86 self
.schema_dn
= ldb
.get_schema_basedn().get_linearized()
87 self
.domain_sid
= security
.dom_sid(ldb
.get_domain_sid())
89 delete_force(self
.ldb
, "cn=posixuser,cn=users," + self
.base_dn
)
90 delete_force(self
.ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
91 delete_force(self
.ldb
, "cn=ldaptestuser2,cn=users," + self
.base_dn
)
92 delete_force(self
.ldb
, "cn=ldaptestuser3,cn=users," + self
.base_dn
)
93 delete_force(self
.ldb
, "cn=ldaptestuser4,cn=ldaptestcontainer," + self
.base_dn
)
94 delete_force(self
.ldb
, "cn=ldaptestuser4,cn=ldaptestcontainer2," + self
.base_dn
)
95 delete_force(self
.ldb
, "cn=ldaptestuser5,cn=users," + self
.base_dn
)
96 delete_force(self
.ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
97 delete_force(self
.ldb
, "cn=ldaptestgroup2,cn=users," + self
.base_dn
)
98 delete_force(self
.ldb
, "cn=ldaptestcomputer,cn=computers," + self
.base_dn
)
99 delete_force(self
.ldb
, "cn=ldaptest2computer,cn=computers," + self
.base_dn
)
100 delete_force(self
.ldb
, "cn=ldaptestcomputer3,cn=computers," + self
.base_dn
)
101 delete_force(self
.ldb
, "cn=ldaptestutf8user èùéìòà,cn=users," + self
.base_dn
)
102 delete_force(self
.ldb
, "cn=ldaptestutf8user2 èùéìòà,cn=users," + self
.base_dn
)
103 delete_force(self
.ldb
, "cn=ldaptestcontainer," + self
.base_dn
)
104 delete_force(self
.ldb
, "cn=ldaptestcontainer2," + self
.base_dn
)
105 delete_force(self
.ldb
, "cn=parentguidtest,cn=users," + self
.base_dn
)
106 delete_force(self
.ldb
, "cn=parentguidtest,cn=testotherusers," + self
.base_dn
)
107 delete_force(self
.ldb
, "cn=testotherusers," + self
.base_dn
)
108 delete_force(self
.ldb
, "cn=ldaptestobject," + self
.base_dn
)
109 delete_force(self
.ldb
, "description=xyz,cn=users," + self
.base_dn
)
110 delete_force(self
.ldb
, "ou=testou,cn=users," + self
.base_dn
)
111 delete_force(self
.ldb
, "cn=Test Secret,cn=system," + self
.base_dn
)
112 delete_force(self
.ldb
, "cn=testtimevaluesuser1,cn=users," + self
.base_dn
)
114 def test_objectclasses(self
):
115 """Test objectClass behaviour"""
116 # Invalid objectclass specified
119 "dn": "cn=ldaptestuser,cn=users," + self
.base_dn
,
122 except LdbError
as e
:
124 self
.assertEqual(num
, ERR_CONSTRAINT_VIOLATION
)
126 # Invalid objectclass specified
129 "dn": "cn=ldaptestuser,cn=users," + self
.base_dn
,
132 except LdbError
as e
:
134 self
.assertEqual(num
, ERR_NO_SUCH_ATTRIBUTE
)
136 # Invalid objectCategory specified
139 "dn": "cn=ldaptestuser,cn=users," + self
.base_dn
,
140 "objectClass": "person",
141 "objectCategory": self
.base_dn
})
143 except LdbError
as e
:
145 self
.assertEqual(num
, ERR_OBJECT_CLASS_VIOLATION
)
147 # Multi-valued "systemFlags"
150 "dn": "cn=ldaptestuser,cn=users," + self
.base_dn
,
151 "objectClass": "person",
152 "systemFlags": ["0", str(SYSTEM_FLAG_DOMAIN_DISALLOW_MOVE
)]})
154 except LdbError
as e
:
156 self
.assertEqual(num
, ERR_CONSTRAINT_VIOLATION
)
158 # We cannot instantiate from an abstract object class ("connectionPoint"
159 # or "leaf"). In the first case we use "connectionPoint" (subclass of
160 # "leaf") to prevent a naming violation - this returns us a
161 # "ERR_UNWILLING_TO_PERFORM" since it is not structural. In the second
162 # case however we get "ERR_OBJECT_CLASS_VIOLATION" since an abstract
163 # class is also not allowed to be auxiliary.
166 "dn": "cn=ldaptestuser,cn=users," + self
.base_dn
,
167 "objectClass": "connectionPoint"})
169 except LdbError
as e
:
171 self
.assertEqual(num
, ERR_UNWILLING_TO_PERFORM
)
174 "dn": "cn=ldaptestuser,cn=users," + self
.base_dn
,
175 "objectClass": ["person", "leaf"]})
177 except LdbError
as e
:
179 self
.assertEqual(num
, ERR_OBJECT_CLASS_VIOLATION
)
181 # Objects instantiated using "satisfied" abstract classes (concrete
182 # subclasses) are allowed
184 "dn": "cn=ldaptestuser,cn=users," + self
.base_dn
,
185 "objectClass": ["top", "leaf", "connectionPoint", "serviceConnectionPoint"]})
187 delete_force(self
.ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
189 # Two disjoint top-most structural object classes aren't allowed
192 "dn": "cn=ldaptestuser,cn=users," + self
.base_dn
,
193 "objectClass": ["person", "container"]})
195 except LdbError
as e
:
197 self
.assertEqual(num
, ERR_OBJECT_CLASS_VIOLATION
)
199 # Test allowed system flags
201 "dn": "cn=ldaptestuser,cn=users," + self
.base_dn
,
202 "objectClass": "person",
203 "systemFlags": str(~
(SYSTEM_FLAG_CONFIG_ALLOW_RENAME | SYSTEM_FLAG_CONFIG_ALLOW_MOVE | SYSTEM_FLAG_CONFIG_ALLOW_LIMITED_MOVE
))})
205 res
= ldb
.search("cn=ldaptestuser,cn=users," + self
.base_dn
,
206 scope
=SCOPE_BASE
, attrs
=["systemFlags"])
207 self
.assertTrue(len(res
) == 1)
208 self
.assertEqual(str(res
[0]["systemFlags"][0]), "0")
210 delete_force(self
.ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
213 "dn": "cn=ldaptestuser,cn=users," + self
.base_dn
,
214 "objectClass": "person"})
216 # We can remove derivation classes of the structural objectclass
217 # but they're going to be re-added afterwards
219 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
220 m
["objectClass"] = MessageElement("top", FLAG_MOD_DELETE
,
224 res
= ldb
.search("cn=ldaptestuser,cn=users," + self
.base_dn
,
225 scope
=SCOPE_BASE
, attrs
=["objectClass"])
226 self
.assertTrue(len(res
) == 1)
227 self
.assertTrue(b
"top" in res
[0]["objectClass"])
229 # The top-most structural class cannot be deleted since there are
230 # attributes of it in use
232 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
233 m
["objectClass"] = MessageElement("person", FLAG_MOD_DELETE
,
238 except LdbError
as e
:
240 self
.assertEqual(num
, ERR_OBJECT_CLASS_VIOLATION
)
242 # We cannot delete classes which weren't specified
244 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
245 m
["objectClass"] = MessageElement("computer", FLAG_MOD_DELETE
,
250 except LdbError
as e
:
252 self
.assertEqual(num
, ERR_NO_SUCH_ATTRIBUTE
)
254 # An invalid class cannot be added
256 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
257 m
["objectClass"] = MessageElement("X", FLAG_MOD_ADD
,
262 except LdbError
as e
:
264 self
.assertEqual(num
, ERR_NO_SUCH_ATTRIBUTE
)
266 # We cannot add a new top-most structural class "user" here since
267 # we are missing at least one new mandatory attribute (in this case
270 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
271 m
["objectClass"] = MessageElement("user", FLAG_MOD_ADD
,
276 except LdbError
as e
:
278 self
.assertEqual(num
, ERR_OBJECT_CLASS_VIOLATION
)
280 # An already specified objectclass cannot be added another time
282 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
283 m
["objectClass"] = MessageElement("person", FLAG_MOD_ADD
,
288 except LdbError
as e
:
290 self
.assertEqual(num
, ERR_ATTRIBUTE_OR_VALUE_EXISTS
)
292 # Auxiliary classes can always be added
294 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
295 m
["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_ADD
,
299 # This does not work since object class "leaf" is not auxiliary nor it
300 # stands in direct relation to "person" (and it is abstract too!)
302 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
303 m
["objectClass"] = MessageElement("leaf", FLAG_MOD_ADD
,
308 except LdbError
as e
:
310 self
.assertEqual(num
, ERR_OBJECT_CLASS_VIOLATION
)
312 # Objectclass replace operations can be performed as well
314 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
315 m
["objectClass"] = MessageElement(["top", "person", "bootableDevice"],
316 FLAG_MOD_REPLACE
, "objectClass")
320 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
321 m
["objectClass"] = MessageElement(["person", "bootableDevice"],
322 FLAG_MOD_REPLACE
, "objectClass")
325 # This does not work since object class "leaf" is not auxiliary nor it
326 # stands in direct relation to "person" (and it is abstract too!)
328 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
329 m
["objectClass"] = MessageElement(["top", "person", "bootableDevice",
330 "leaf"], FLAG_MOD_REPLACE
, "objectClass")
334 except LdbError
as e
:
336 self
.assertEqual(num
, ERR_OBJECT_CLASS_VIOLATION
)
338 # More than one change operation is allowed
340 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
341 m
.add(MessageElement("bootableDevice", FLAG_MOD_DELETE
, "objectClass"))
342 m
.add(MessageElement("bootableDevice", FLAG_MOD_ADD
, "objectClass"))
345 # We cannot remove all object classes by an empty replace
347 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
348 m
["objectClass"] = MessageElement([], FLAG_MOD_REPLACE
, "objectClass")
352 except LdbError
as e
:
354 self
.assertEqual(num
, ERR_OBJECT_CLASS_VIOLATION
)
357 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
358 m
["objectClass"] = MessageElement(["top", "computer"], FLAG_MOD_REPLACE
,
363 except LdbError
as e
:
365 self
.assertEqual(num
, ERR_OBJECT_CLASS_VIOLATION
)
367 # Classes can be removed unless attributes of them are used.
369 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
370 m
["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_DELETE
,
374 res
= ldb
.search("cn=ldaptestuser,cn=users," + self
.base_dn
,
375 scope
=SCOPE_BASE
, attrs
=["objectClass"])
376 self
.assertTrue(len(res
) == 1)
377 self
.assertFalse("bootableDevice" in res
[0]["objectClass"])
380 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
381 m
["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_ADD
,
385 # Add an attribute specific to the "bootableDevice" class
387 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
388 m
["bootParameter"] = MessageElement("test", FLAG_MOD_ADD
,
392 # Classes can be removed unless attributes of them are used. Now there
393 # exist such attributes on the entry.
395 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
396 m
["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_DELETE
,
401 except LdbError
as e
:
403 self
.assertEqual(num
, ERR_OBJECT_CLASS_VIOLATION
)
405 # Remove the previously specified attribute
407 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
408 m
["bootParameter"] = MessageElement("test", FLAG_MOD_DELETE
,
412 # Classes can be removed unless attributes of them are used.
414 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
415 m
["objectClass"] = MessageElement("bootableDevice", FLAG_MOD_DELETE
,
419 delete_force(self
.ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
422 "dn": "cn=ldaptestuser,cn=users," + self
.base_dn
,
423 "objectClass": "user"})
425 # Add a new top-most structural class "container". This does not work
426 # since it stands in no direct relation to the current one.
428 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
429 m
["objectClass"] = MessageElement("container", FLAG_MOD_ADD
,
434 except LdbError
as e
:
436 self
.assertEqual(num
, ERR_OBJECT_CLASS_VIOLATION
)
438 # Try to add a new top-most structural class "inetOrgPerson"
440 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
441 m
["objectClass"] = MessageElement("inetOrgPerson", FLAG_MOD_ADD
,
446 except LdbError
as e
:
448 self
.assertEqual(num
, ERR_OBJECT_CLASS_VIOLATION
)
450 # Try to remove the structural class "user"
452 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
453 m
["objectClass"] = MessageElement("user", FLAG_MOD_DELETE
,
458 except LdbError
as e
:
460 self
.assertEqual(num
, ERR_OBJECT_CLASS_VIOLATION
)
462 # Try to replace top-most structural class to "inetOrgPerson"
464 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
465 m
["objectClass"] = MessageElement("inetOrgPerson", FLAG_MOD_REPLACE
,
470 except LdbError
as e
:
472 self
.assertEqual(num
, ERR_OBJECT_CLASS_VIOLATION
)
474 # Add a new auxiliary object class "posixAccount" to "ldaptestuser"
476 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
477 m
["objectClass"] = MessageElement("posixAccount", FLAG_MOD_ADD
,
481 # Be sure that "top" is the first and the (most) structural object class
482 # the last value of the "objectClass" attribute - MS-ADTS 3.1.1.1.4
483 res
= ldb
.search("cn=ldaptestuser,cn=users," + self
.base_dn
,
484 scope
=SCOPE_BASE
, attrs
=["objectClass"])
485 self
.assertTrue(len(res
) == 1)
486 self
.assertEqual(str(res
[0]["objectClass"][0]), "top")
487 self
.assertEqual(str(res
[0]["objectClass"][len(res
[0]["objectClass"]) - 1]), "user")
489 delete_force(self
.ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
491 def test_system_only(self
):
492 """Test systemOnly objects"""
495 "dn": "cn=ldaptestobject," + self
.base_dn
,
496 "objectclass": "configuration"})
498 except LdbError
as e
:
500 self
.assertEqual(num
, ERR_UNWILLING_TO_PERFORM
)
504 "dn": "cn=Test Secret,cn=system," + self
.base_dn
,
505 "objectclass": "secret"})
507 except LdbError
as e
:
509 self
.assertEqual(num
, ERR_UNWILLING_TO_PERFORM
)
511 delete_force(self
.ldb
, "cn=ldaptestobject," + self
.base_dn
)
512 delete_force(self
.ldb
, "cn=Test Secret,cn=system," + self
.base_dn
)
514 # Create secret over LSA and try to change it
516 lsa_conn
= lsa
.lsarpc("ncacn_np:%s" % args
[0], lp
, creds
)
517 lsa_handle
= lsa_conn
.OpenPolicy2(system_name
="\\",
518 attr
=lsa
.ObjectAttribute(),
519 access_mask
=security
.SEC_FLAG_MAXIMUM_ALLOWED
)
520 secret_name
= lsa
.String()
521 secret_name
.string
= "G$Test"
522 sec_handle
= lsa_conn
.CreateSecret(handle
=lsa_handle
,
524 access_mask
=security
.SEC_FLAG_MAXIMUM_ALLOWED
)
525 lsa_conn
.Close(lsa_handle
)
528 m
.dn
= Dn(ldb
, "cn=Test Secret,cn=system," + self
.base_dn
)
529 m
["description"] = MessageElement("desc", FLAG_MOD_REPLACE
,
534 except LdbError
as e
:
536 self
.assertEqual(num
, ERR_UNWILLING_TO_PERFORM
)
538 delete_force(self
.ldb
, "cn=Test Secret,cn=system," + self
.base_dn
)
542 "dn": "cn=ldaptestcontainer," + self
.base_dn
,
543 "objectclass": "container",
544 "isCriticalSystemObject": "TRUE"})
546 except LdbError
as e
:
548 self
.assertEqual(num
, ERR_UNWILLING_TO_PERFORM
)
551 "dn": "cn=ldaptestcontainer," + self
.base_dn
,
552 "objectclass": "container"})
555 m
.dn
= Dn(ldb
, "cn=ldaptestcontainer," + self
.base_dn
)
556 m
["isCriticalSystemObject"] = MessageElement("TRUE", FLAG_MOD_REPLACE
,
557 "isCriticalSystemObject")
561 except LdbError
as e
:
563 self
.assertEqual(num
, ERR_UNWILLING_TO_PERFORM
)
565 delete_force(self
.ldb
, "cn=ldaptestcontainer," + self
.base_dn
)
567 # Proof if DC SAM object has "isCriticalSystemObject" set
568 res
= self
.ldb
.search("", scope
=SCOPE_BASE
, attrs
=["serverName"])
569 self
.assertTrue(len(res
) == 1)
570 self
.assertTrue("serverName" in res
[0])
571 res
= self
.ldb
.search(res
[0]["serverName"][0], scope
=SCOPE_BASE
,
572 attrs
=["serverReference"])
573 self
.assertTrue(len(res
) == 1)
574 self
.assertTrue("serverReference" in res
[0])
575 res
= self
.ldb
.search(res
[0]["serverReference"][0], scope
=SCOPE_BASE
,
576 attrs
=["isCriticalSystemObject"])
577 self
.assertTrue(len(res
) == 1)
578 self
.assertTrue("isCriticalSystemObject" in res
[0])
579 self
.assertEqual(str(res
[0]["isCriticalSystemObject"][0]), "TRUE")
581 def test_invalid_parent(self
):
582 """Test adding an object with invalid parent"""
585 "dn": "cn=ldaptestgroup,cn=thisdoesnotexist123,"
587 "objectclass": "group"})
589 except LdbError
as e
:
591 self
.assertEqual(num
, ERR_NO_SUCH_OBJECT
)
593 delete_force(self
.ldb
, "cn=ldaptestgroup,cn=thisdoesnotexist123,"
598 "dn": "ou=testou,cn=users," + self
.base_dn
,
599 "objectclass": "organizationalUnit"})
601 except LdbError
as e
:
603 self
.assertEqual(num
, ERR_NAMING_VIOLATION
)
605 delete_force(self
.ldb
, "ou=testou,cn=users," + self
.base_dn
)
607 def test_invalid_attribute(self
):
608 """Test invalid attributes on schema/objectclasses"""
609 # attributes not in schema test
615 "dn": "cn=ldaptestgroup,cn=users," + self
.base_dn
,
616 "objectclass": "group",
617 "thisdoesnotexist": "x"})
619 except LdbError
as e
:
621 self
.assertEqual(num
, ERR_NO_SUCH_ATTRIBUTE
)
624 "dn": "cn=ldaptestgroup,cn=users," + self
.base_dn
,
625 "objectclass": "group"})
630 m
.dn
= Dn(ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
631 m
["thisdoesnotexist"] = MessageElement("x", FLAG_MOD_REPLACE
,
636 except LdbError
as e
:
638 self
.assertEqual(num
, ERR_NO_SUCH_ATTRIBUTE
)
641 # When searching the unknown attribute should be ignored
642 expr
= "(|(cn=ldaptestgroup)(thisdoesnotexist=x))"
643 res
= ldb
.search(base
=self
.base_dn
,
646 self
.assertTrue(len(res
) == 1,
647 "Search including unknown attribute failed")
649 # likewise, if we specifically request an unknown attribute
650 res
= ldb
.search(base
=self
.base_dn
,
651 expression
="(cn=ldaptestgroup)",
653 attrs
=["thisdoesnotexist"])
654 self
.assertTrue(len(res
) == 1,
655 "Search requesting unknown attribute failed")
657 delete_force(self
.ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
659 # attributes not in objectclasses and mandatory attributes missing test
660 # Use here a non-SAM entry since it doesn't have special triggers
661 # associated which have an impact on the error results.
665 # mandatory attribute missing
668 "dn": "cn=ldaptestobject," + self
.base_dn
,
669 "objectclass": "ipProtocol"})
671 except LdbError
as e
:
673 self
.assertEqual(num
, ERR_OBJECT_CLASS_VIOLATION
)
675 # inadequate but schema-valid attribute specified
678 "dn": "cn=ldaptestobject," + self
.base_dn
,
679 "objectclass": "ipProtocol",
680 "ipProtocolNumber": "1",
683 except LdbError
as e
:
685 self
.assertEqual(num
, ERR_OBJECT_CLASS_VIOLATION
)
688 "dn": "cn=ldaptestobject," + self
.base_dn
,
689 "objectclass": "ipProtocol",
690 "ipProtocolNumber": "1"})
694 # inadequate but schema-valid attribute add trial
696 m
.dn
= Dn(ldb
, "cn=ldaptestobject," + self
.base_dn
)
697 m
["uid"] = MessageElement("0", FLAG_MOD_ADD
, "uid")
701 except LdbError
as e
:
703 self
.assertEqual(num
, ERR_OBJECT_CLASS_VIOLATION
)
705 # mandatory attribute delete trial
707 m
.dn
= Dn(ldb
, "cn=ldaptestobject," + self
.base_dn
)
708 m
["ipProtocolNumber"] = MessageElement([], FLAG_MOD_DELETE
,
713 except LdbError
as e
:
715 self
.assertEqual(num
, ERR_OBJECT_CLASS_VIOLATION
)
717 # mandatory attribute delete trial
719 m
.dn
= Dn(ldb
, "cn=ldaptestobject," + self
.base_dn
)
720 m
["ipProtocolNumber"] = MessageElement([], FLAG_MOD_REPLACE
,
725 except LdbError
as e
:
727 self
.assertEqual(num
, ERR_OBJECT_CLASS_VIOLATION
)
729 delete_force(self
.ldb
, "cn=ldaptestobject," + self
.base_dn
)
731 def test_single_valued_attributes(self
):
732 """Test single-valued attributes"""
735 "dn": "cn=ldaptestgroup,cn=users," + self
.base_dn
,
736 "objectclass": "group",
737 "sAMAccountName": ["nam1", "nam2"]})
739 except LdbError
as e
:
741 self
.assertEqual(num
, ERR_CONSTRAINT_VIOLATION
)
744 "dn": "cn=ldaptestgroup,cn=users," + self
.base_dn
,
745 "objectclass": "group"})
748 m
.dn
= Dn(ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
749 m
["sAMAccountName"] = MessageElement(["nam1", "nam2"], FLAG_MOD_REPLACE
,
754 except LdbError
as e
:
756 self
.assertEqual(num
, ERR_ATTRIBUTE_OR_VALUE_EXISTS
)
759 m
.dn
= Dn(ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
760 m
["sAMAccountName"] = MessageElement("testgroupXX", FLAG_MOD_REPLACE
,
765 m
.dn
= Dn(ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
766 m
["sAMAccountName"] = MessageElement("testgroupXX2", FLAG_MOD_ADD
,
771 except LdbError
as e
:
773 self
.assertEqual(num
, ERR_ATTRIBUTE_OR_VALUE_EXISTS
)
775 delete_force(self
.ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
777 def test_single_valued_linked_attributes(self
):
778 """Test managedBy, a single-valued linked attribute.
780 (The single-valuedness of this is enforced differently, in
783 ou
= 'OU=svla,%s' % (self
.base_dn
)
785 delete_force(self
.ldb
, ou
, controls
=['tree_delete:1'])
787 self
.ldb
.add({'objectclass': 'organizationalUnit',
792 m
= "cn=manager%d,%s" % (x
, ou
)
795 "objectclass": "user"})
800 "dn": "cn=group1," + ou
,
801 "objectclass": "group",
802 "managedBy": managers
804 self
.fail("failed to fail to add multiple managedBy attributes")
805 except LdbError
as e
:
807 self
.assertEqual(num
, ERR_CONSTRAINT_VIOLATION
)
809 managee
= "cn=group2," + ou
812 "objectclass": "group",
813 "managedBy": [managers
[0]]})
816 m
.dn
= Dn(ldb
, managee
)
817 m
["managedBy"] = MessageElement(managers
, FLAG_MOD_REPLACE
,
822 except LdbError
as e
:
824 self
.assertEqual(num
, ERR_CONSTRAINT_VIOLATION
)
827 m
.dn
= Dn(ldb
, managee
)
828 m
["managedBy"] = MessageElement(managers
[1], FLAG_MOD_REPLACE
,
833 m
.dn
= Dn(ldb
, managee
)
834 m
["managedBy"] = MessageElement(managers
[2], FLAG_MOD_ADD
,
839 except LdbError
as e
:
841 self
.assertEqual(num
, ERR_ATTRIBUTE_OR_VALUE_EXISTS
)
843 self
.ldb
.delete(ou
, ['tree_delete:1'])
845 def test_multivalued_attributes(self
):
846 """Test multi-valued attributes"""
847 ou
= 'OU=mvattr,%s' % (self
.base_dn
)
848 delete_force(self
.ldb
, ou
, controls
=['tree_delete:1'])
849 self
.ldb
.add({'objectclass': 'organizationalUnit',
852 # beyond 1210, Win2012r2 gives LDAP_ADMIN_LIMIT_EXCEEDED
853 ranges
= (3, 30, 300, 1210)
857 "dn": "cn=ldaptestuser%d,%s" % (n
, ou
),
858 "objectclass": "user",
859 "carLicense": ["car%d" % x
for x
in range(n
)]})
864 m
.dn
= Dn(ldb
, "cn=ldaptestuser%d,%s" % (n
, ou
))
865 m
["carLicense"] = MessageElement(["another"],
871 m
.dn
= Dn(ldb
, "cn=ldaptestuser%d,%s" % (n
, ou
))
872 m
["carLicense"] = MessageElement(["foo%d" % x
for x
in range(4)],
878 m
.dn
= Dn(ldb
, "cn=ldaptestuser%d,%s" % (n
, ou
))
879 m
["carLicense"] = MessageElement(["bar%d" % x
for x
in range(40)],
886 dn
= "cn=ldaptestuser%d,%s" % (n
, ou
)
888 m
["carLicense"] = MessageElement(["replacement"],
895 m
["carLicense"] = MessageElement(["replacement%d" % x
for x
in range(n
)],
902 m
["carLicense"] = MessageElement(["again%d" % x
for x
in range(n
)],
909 m
["carLicense"] = MessageElement(["andagain%d" % x
for x
in range(n
)],
914 self
.ldb
.delete(ou
, ['tree_delete:1'])
916 def test_attribute_ranges(self
):
917 """Test attribute ranges"""
921 "dn": "cn=ldaptestuser,cn=users," + self
.base_dn
,
922 "objectClass": "person",
925 except LdbError
as e
:
927 self
.assertEqual(num
, ERR_INVALID_ATTRIBUTE_SYNTAX
)
930 "dn": "cn=ldaptestuser,cn=users," + self
.base_dn
,
931 "objectClass": "person"})
935 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
936 m
["sn"] = MessageElement("", FLAG_MOD_REPLACE
, "sn")
940 except LdbError
as e
:
942 self
.assertEqual(num
, ERR_INVALID_ATTRIBUTE_SYNTAX
)
946 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
947 m
["sn"] = MessageElement("x", FLAG_MOD_REPLACE
, "sn")
950 delete_force(self
.ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
952 def test_attribute_ranges_too_long(self
):
953 """Test attribute ranges"""
954 # This is knownfail with the wrong error
955 # (INVALID_ATTRIBUTE_SYNTAX vs CONSTRAINT_VIOLATION per Windows)
960 "dn": "cn=ldaptestuser,cn=users," + self
.base_dn
,
961 "objectClass": "person",
964 except LdbError
as e
:
966 self
.assertEqual(num
, ERR_CONSTRAINT_VIOLATION
)
969 "dn": "cn=ldaptestuser,cn=users," + self
.base_dn
,
970 "objectClass": "person"})
974 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
975 m
["sn"] = MessageElement("x" * 66, FLAG_MOD_REPLACE
, "sn")
979 except LdbError
as e
:
980 self
.assertEqual(e
.args
[0], ERR_CONSTRAINT_VIOLATION
)
982 def test_empty_messages(self
):
983 """Test empty messages"""
985 m
.dn
= Dn(ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
990 except LdbError
as e
:
992 self
.assertEqual(num
, ERR_OBJECT_CLASS_VIOLATION
)
997 except LdbError
as e
:
999 self
.assertEqual(num
, ERR_UNWILLING_TO_PERFORM
)
1001 delete_force(self
.ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
1003 def test_empty_attributes(self
):
1004 """Test empty attributes"""
1006 m
.dn
= Dn(ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
1007 m
["objectClass"] = MessageElement("group", FLAG_MOD_ADD
, "objectClass")
1008 m
["description"] = MessageElement([], FLAG_MOD_ADD
, "description")
1013 except LdbError
as e
:
1015 self
.assertEqual(num
, ERR_CONSTRAINT_VIOLATION
)
1018 "dn": "cn=ldaptestgroup,cn=users," + self
.base_dn
,
1019 "objectclass": "group"})
1022 m
.dn
= Dn(ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
1023 m
["description"] = MessageElement([], FLAG_MOD_ADD
, "description")
1028 except LdbError
as e
:
1030 self
.assertEqual(num
, ERR_CONSTRAINT_VIOLATION
)
1033 m
.dn
= Dn(ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
1034 m
["description"] = MessageElement([], FLAG_MOD_REPLACE
, "description")
1038 m
.dn
= Dn(ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
1039 m
["description"] = MessageElement([], FLAG_MOD_DELETE
, "description")
1043 except LdbError
as e
:
1045 self
.assertEqual(num
, ERR_NO_SUCH_ATTRIBUTE
)
1047 delete_force(self
.ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
1049 def test_instanceType(self
):
1050 """Tests the 'instanceType' attribute"""
1051 # The instance type is single-valued
1054 "dn": "cn=ldaptestgroup,cn=users," + self
.base_dn
,
1055 "objectclass": "group",
1056 "instanceType": ["0", "1"]})
1058 except LdbError
as e
:
1060 self
.assertEqual(num
, ERR_UNWILLING_TO_PERFORM
)
1062 # The head NC flag cannot be set without the write flag
1065 "dn": "cn=ldaptestgroup,cn=users," + self
.base_dn
,
1066 "objectclass": "group",
1067 "instanceType": "1"})
1069 except LdbError
as e
:
1071 self
.assertEqual(num
, ERR_UNWILLING_TO_PERFORM
)
1073 # We cannot manipulate NCs without the head NC flag
1076 "dn": "cn=ldaptestgroup,cn=users," + self
.base_dn
,
1077 "objectclass": "group",
1078 "instanceType": "32"})
1080 except LdbError
as e
:
1082 self
.assertEqual(num
, ERR_UNWILLING_TO_PERFORM
)
1085 "dn": "cn=ldaptestgroup,cn=users," + self
.base_dn
,
1086 "objectclass": "group"})
1089 m
.dn
= Dn(ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
1090 m
["instanceType"] = MessageElement("0", FLAG_MOD_REPLACE
,
1095 except LdbError
as e
:
1097 self
.assertEqual(num
, ERR_CONSTRAINT_VIOLATION
)
1100 m
.dn
= Dn(ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
1101 m
["instanceType"] = MessageElement([], FLAG_MOD_REPLACE
,
1106 except LdbError
as e
:
1108 self
.assertEqual(num
, ERR_CONSTRAINT_VIOLATION
)
1111 m
.dn
= Dn(ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
1112 m
["instanceType"] = MessageElement([], FLAG_MOD_DELETE
, "instanceType")
1116 except LdbError
as e
:
1118 self
.assertEqual(num
, ERR_CONSTRAINT_VIOLATION
)
1120 delete_force(self
.ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
1122 # only write is allowed with NC_HEAD for originating updates
1125 "dn": "cn=ldaptestuser2,cn=users," + self
.base_dn
,
1126 "objectclass": "user",
1127 "instanceType": "3"})
1129 except LdbError
as e
:
1131 self
.assertEqual(num
, ERR_UNWILLING_TO_PERFORM
)
1132 delete_force(self
.ldb
, "cn=ldaptestuser2,cn=users," + self
.base_dn
)
1134 def test_distinguished_name(self
):
1135 """Tests the 'distinguishedName' attribute"""
1136 # The "dn" shortcut isn't supported
1138 m
.dn
= Dn(ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
1139 m
["objectClass"] = MessageElement("group", 0, "objectClass")
1140 m
["dn"] = MessageElement("cn=ldaptestgroup,cn=users," + self
.base_dn
, 0,
1145 except LdbError
as e
:
1147 self
.assertEqual(num
, ERR_NO_SUCH_ATTRIBUTE
)
1149 # a wrong "distinguishedName" attribute is obviously tolerated
1151 "dn": "cn=ldaptestgroup,cn=users," + self
.base_dn
,
1152 "objectclass": "group",
1153 "distinguishedName": "cn=ldaptest,cn=users," + self
.base_dn
})
1155 # proof if the DN has been set correctly
1156 res
= ldb
.search("cn=ldaptestgroup,cn=users," + self
.base_dn
,
1157 scope
=SCOPE_BASE
, attrs
=["distinguishedName"])
1158 self
.assertTrue(len(res
) == 1)
1159 self
.assertTrue("distinguishedName" in res
[0])
1160 self
.assertTrue(Dn(ldb
, str(res
[0]["distinguishedName"][0]))
1161 == Dn(ldb
, "cn=ldaptestgroup, cn=users," + self
.base_dn
))
1163 # The "dn" shortcut isn't supported
1165 m
.dn
= Dn(ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
1166 m
["dn"] = MessageElement(
1167 "cn=ldaptestgroup,cn=users," + self
.base_dn
, FLAG_MOD_REPLACE
,
1172 except LdbError
as e
:
1174 self
.assertEqual(num
, ERR_NO_SUCH_ATTRIBUTE
)
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_ADD
,
1180 "distinguishedName")
1185 except LdbError
as e
:
1187 self
.assertEqual(num
, ERR_UNWILLING_TO_PERFORM
)
1190 m
.dn
= Dn(ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
1191 m
["distinguishedName"] = MessageElement(
1192 "cn=ldaptestuser,cn=users," + self
.base_dn
, FLAG_MOD_REPLACE
,
1193 "distinguishedName")
1198 except LdbError
as e
:
1200 self
.assertEqual(num
, ERR_CONSTRAINT_VIOLATION
)
1203 m
.dn
= Dn(ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
1204 m
["distinguishedName"] = MessageElement(
1205 "cn=ldaptestuser,cn=users," + self
.base_dn
, FLAG_MOD_DELETE
,
1206 "distinguishedName")
1211 except LdbError
as e
:
1213 self
.assertEqual(num
, ERR_UNWILLING_TO_PERFORM
)
1215 delete_force(self
.ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
1217 def test_rdn_name(self
):
1223 self
.ldb
.search("=,cn=users," + self
.base_dn
, scope
=SCOPE_BASE
)
1225 except LdbError
as e
:
1227 self
.assertEqual(num
, ERR_INVALID_DN_SYNTAX
)
1231 self
.ldb
.search("cn=,cn=users," + self
.base_dn
, scope
=SCOPE_BASE
)
1233 except LdbError
as e
:
1235 self
.assertEqual(num
, ERR_INVALID_DN_SYNTAX
)
1238 self
.ldb
.search("=ldaptestgroup,cn=users," + self
.base_dn
, scope
=SCOPE_BASE
)
1240 except LdbError
as e
:
1242 self
.assertEqual(num
, ERR_INVALID_DN_SYNTAX
)
1249 "dn": "=,cn=users," + self
.base_dn
,
1250 "objectclass": "group"})
1252 except LdbError
as e
:
1254 self
.assertEqual(num
, ERR_INVALID_DN_SYNTAX
)
1259 "dn": "=ldaptestgroup,cn=users," + self
.base_dn
,
1260 "objectclass": "group"})
1262 except LdbError
as e
:
1264 self
.assertEqual(num
, ERR_INVALID_DN_SYNTAX
)
1269 "dn": "cn=,cn=users," + self
.base_dn
,
1270 "objectclass": "group"})
1272 except LdbError
as e
:
1274 self
.assertEqual(num
, ERR_INVALID_DN_SYNTAX
)
1276 # a wrong RDN candidate
1279 "dn": "description=xyz,cn=users," + self
.base_dn
,
1280 "objectclass": "group"})
1282 except LdbError
as e
:
1284 self
.assertEqual(num
, ERR_NAMING_VIOLATION
)
1286 delete_force(self
.ldb
, "description=xyz,cn=users," + self
.base_dn
)
1288 # a wrong "name" attribute is obviously tolerated
1290 "dn": "cn=ldaptestgroup,cn=users," + self
.base_dn
,
1291 "objectclass": "group",
1292 "name": "ldaptestgroupx"})
1294 # proof if the name has been set correctly
1295 res
= ldb
.search("cn=ldaptestgroup,cn=users," + self
.base_dn
,
1296 scope
=SCOPE_BASE
, attrs
=["name"])
1297 self
.assertTrue(len(res
) == 1)
1298 self
.assertTrue("name" in res
[0])
1299 self
.assertTrue(str(res
[0]["name"][0]) == "ldaptestgroup")
1305 m
.dn
= Dn(ldb
, "cn=,cn=users," + self
.base_dn
)
1306 m
["description"] = "test"
1310 except LdbError
as e
:
1312 self
.assertEqual(num
, ERR_INVALID_DN_SYNTAX
)
1318 self
.ldb
.delete("cn=,cn=users," + self
.base_dn
)
1320 except LdbError
as e
:
1322 self
.assertEqual(num
, ERR_INVALID_DN_SYNTAX
)
1328 self
.ldb
.rename("cn=ldaptestgroup,cn=users," + self
.base_dn
,
1329 "=,cn=users," + self
.base_dn
)
1331 except LdbError
as e
:
1333 self
.assertEqual(num
, ERR_INVALID_DN_SYNTAX
)
1335 # new empty RDN name
1337 self
.ldb
.rename("cn=ldaptestgroup,cn=users," + self
.base_dn
,
1338 "=ldaptestgroup,cn=users," + self
.base_dn
)
1340 except LdbError
as e
:
1342 self
.assertEqual(num
, ERR_INVALID_DN_SYNTAX
)
1344 # new empty RDN value
1346 self
.ldb
.rename("cn=ldaptestgroup,cn=users," + self
.base_dn
,
1347 "cn=,cn=users," + self
.base_dn
)
1349 except LdbError
as e
:
1351 self
.assertEqual(num
, ERR_NAMING_VIOLATION
)
1353 # new wrong RDN candidate
1355 self
.ldb
.rename("cn=ldaptestgroup,cn=users," + self
.base_dn
,
1356 "description=xyz,cn=users," + self
.base_dn
)
1358 except LdbError
as e
:
1360 self
.assertEqual(num
, ERR_UNWILLING_TO_PERFORM
)
1362 delete_force(self
.ldb
, "description=xyz,cn=users," + self
.base_dn
)
1364 # old empty RDN value
1366 self
.ldb
.rename("cn=,cn=users," + self
.base_dn
,
1367 "cn=ldaptestgroup,cn=users," + self
.base_dn
)
1369 except LdbError
as e
:
1371 self
.assertEqual(num
, ERR_INVALID_DN_SYNTAX
)
1376 m
.dn
= Dn(ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
1377 m
["name"] = MessageElement("cn=ldaptestuser", FLAG_MOD_REPLACE
,
1382 except LdbError
as e
:
1384 self
.assertEqual(num
, ERR_NOT_ALLOWED_ON_RDN
)
1387 m
.dn
= Dn(ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
1388 m
["cn"] = MessageElement("ldaptestuser",
1389 FLAG_MOD_REPLACE
, "cn")
1393 except LdbError
as e
:
1395 self
.assertEqual(num
, ERR_NOT_ALLOWED_ON_RDN
)
1397 delete_force(self
.ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
1399 # this test needs to be disabled until we really understand
1400 # what the rDN length constraints are
1402 def DISABLED_test_largeRDN(self
):
1403 """Testing large rDN (limit 64 characters)"""
1404 rdn
= "CN=a012345678901234567890123456789012345678901234567890123456789012"
1405 delete_force(self
.ldb
, "%s,%s" % (rdn
, self
.base_dn
))
1407 dn: %s,%s""" % (rdn
, self
.base_dn
) + """
1408 objectClass: container
1410 self
.ldb
.add_ldif(ldif
)
1411 delete_force(self
.ldb
, "%s,%s" % (rdn
, self
.base_dn
))
1413 rdn
= "CN=a0123456789012345678901234567890123456789012345678901234567890120"
1414 delete_force(self
.ldb
, "%s,%s" % (rdn
, self
.base_dn
))
1417 dn: %s,%s""" % (rdn
, self
.base_dn
) + """
1418 objectClass: container
1420 self
.ldb
.add_ldif(ldif
)
1422 except LdbError
as e
:
1424 self
.assertEqual(num
, ERR_CONSTRAINT_VIOLATION
)
1425 delete_force(self
.ldb
, "%s,%s" % (rdn
, self
.base_dn
))
1427 def test_rename(self
):
1428 """Tests the rename operation"""
1430 # cannot rename to be a child of itself
1431 ldb
.rename(self
.base_dn
, "dc=test," + self
.base_dn
)
1433 except LdbError
as e
:
1435 self
.assertEqual(num
, ERR_UNWILLING_TO_PERFORM
)
1439 ldb
.rename("cn=ldaptestuser2,cn=users," + self
.base_dn
, "cn=ldaptestuser2,cn=users," + self
.base_dn
)
1441 except LdbError
as e
:
1443 self
.assertEqual(num
, ERR_NO_SUCH_OBJECT
)
1446 "dn": "cn=ldaptestuser2,cn=users," + self
.base_dn
,
1447 "objectclass": "user"})
1449 ldb
.rename("cn=ldaptestuser2,cn=users," + self
.base_dn
, "cn=ldaptestuser2,cn=users," + self
.base_dn
)
1450 ldb
.rename("cn=ldaptestuser2,cn=users," + self
.base_dn
, "cn=ldaptestuser3,cn=users," + self
.base_dn
)
1451 ldb
.rename("cn=ldaptestuser3,cn=users," + self
.base_dn
, "cn=ldaptestUSER3,cn=users," + self
.base_dn
)
1454 # containment problem: a user entry cannot contain user entries
1455 ldb
.rename("cn=ldaptestuser3,cn=users," + self
.base_dn
, "cn=ldaptestuser4,cn=ldaptestuser3,cn=users," + self
.base_dn
)
1457 except LdbError
as e
:
1459 self
.assertEqual(num
, ERR_NAMING_VIOLATION
)
1463 ldb
.rename("cn=ldaptestuser3,cn=users," + self
.base_dn
, "cn=ldaptestuser3,cn=people,cn=users," + self
.base_dn
)
1465 except LdbError
as e
:
1467 self
.assertEqual(num
, ERR_OTHER
)
1470 # invalid target DN syntax
1471 ldb
.rename("cn=ldaptestuser3,cn=users," + self
.base_dn
, ",cn=users," + self
.base_dn
)
1473 except LdbError
as e
:
1475 self
.assertEqual(num
, ERR_INVALID_DN_SYNTAX
)
1479 ldb
.rename("cn=ldaptestuser3,cn=users," + self
.base_dn
, "ou=ldaptestuser3,cn=users," + self
.base_dn
)
1481 except LdbError
as e
:
1483 self
.assertEqual(num
, ERR_UNWILLING_TO_PERFORM
)
1485 delete_force(self
.ldb
, "cn=ldaptestuser3,cn=users," + self
.base_dn
)
1487 # Performs some "systemFlags" testing
1489 # Move failing since no "SYSTEM_FLAG_CONFIG_ALLOW_MOVE"
1491 ldb
.rename("CN=DisplaySpecifiers," + self
.configuration_dn
, "CN=DisplaySpecifiers,CN=Services," + self
.configuration_dn
)
1493 except LdbError
as e
:
1495 self
.assertEqual(num
, ERR_UNWILLING_TO_PERFORM
)
1497 # Limited move failing since no "SYSTEM_FLAG_CONFIG_ALLOW_LIMITED_MOVE"
1499 ldb
.rename("CN=Directory Service,CN=Windows NT,CN=Services," + self
.configuration_dn
, "CN=Directory Service,CN=RRAS,CN=Services," + self
.configuration_dn
)
1501 except LdbError
as e
:
1503 self
.assertEqual(num
, ERR_UNWILLING_TO_PERFORM
)
1505 # Rename failing since no "SYSTEM_FLAG_CONFIG_ALLOW_RENAME"
1507 ldb
.rename("CN=DisplaySpecifiers," + self
.configuration_dn
, "CN=DisplaySpecifiers2," + self
.configuration_dn
)
1509 except LdbError
as e
:
1511 self
.assertEqual(num
, ERR_UNWILLING_TO_PERFORM
)
1513 # It's not really possible to test moves on the schema partition since
1514 # there don't exist subcontainers on it.
1516 # Rename failing since "SYSTEM_FLAG_SCHEMA_BASE_OBJECT"
1518 ldb
.rename("CN=Top," + self
.schema_dn
, "CN=Top2," + self
.schema_dn
)
1520 except LdbError
as e
:
1522 self
.assertEqual(num
, ERR_UNWILLING_TO_PERFORM
)
1524 # Move failing since "SYSTEM_FLAG_DOMAIN_DISALLOW_MOVE"
1526 ldb
.rename("CN=Users," + self
.base_dn
, "CN=Users,CN=Computers," + self
.base_dn
)
1528 except LdbError
as e
:
1530 self
.assertEqual(num
, ERR_UNWILLING_TO_PERFORM
)
1532 # Rename failing since "SYSTEM_FLAG_DOMAIN_DISALLOW_RENAME"
1534 ldb
.rename("CN=Users," + self
.base_dn
, "CN=Users2," + self
.base_dn
)
1536 except LdbError
as e
:
1538 self
.assertEqual(num
, ERR_UNWILLING_TO_PERFORM
)
1540 # Performs some other constraints testing
1543 ldb
.rename("CN=Policies,CN=System," + self
.base_dn
, "CN=Users2," + self
.base_dn
)
1545 except LdbError
as e
:
1547 self
.assertEqual(num
, ERR_OTHER
)
1549 def test_rename_twice(self
):
1550 """Tests the rename operation twice - this corresponds to a past bug"""
1552 "dn": "cn=ldaptestuser5,cn=users," + self
.base_dn
,
1553 "objectclass": "user"})
1555 ldb
.rename("cn=ldaptestuser5,cn=users," + self
.base_dn
, "cn=ldaptestUSER5,cn=users," + self
.base_dn
)
1556 delete_force(self
.ldb
, "cn=ldaptestuser5,cn=users," + self
.base_dn
)
1558 "dn": "cn=ldaptestuser5,cn=users," + self
.base_dn
,
1559 "objectclass": "user"})
1560 ldb
.rename("cn=ldaptestuser5,cn=Users," + self
.base_dn
, "cn=ldaptestUSER5,cn=users," + self
.base_dn
)
1561 res
= ldb
.search(expression
="cn=ldaptestuser5")
1562 self
.assertEqual(len(res
), 1, "Wrong number of hits for cn=ldaptestuser5")
1563 res
= ldb
.search(expression
="(&(cn=ldaptestuser5)(objectclass=user))")
1564 self
.assertEqual(len(res
), 1, "Wrong number of hits for (&(cn=ldaptestuser5)(objectclass=user))")
1565 delete_force(self
.ldb
, "cn=ldaptestuser5,cn=users," + self
.base_dn
)
1567 def test_objectGUID(self
):
1568 """Test objectGUID behaviour"""
1569 # The objectGUID cannot directly be set
1571 self
.ldb
.add_ldif("""
1572 dn: cn=ldaptestcontainer,""" + self
.base_dn
+ """
1573 objectClass: container
1574 objectGUID: bd3480c9-58af-4cd8-92df-bc4a18b6e44d
1577 except LdbError
as e
:
1579 self
.assertEqual(num
, ERR_UNWILLING_TO_PERFORM
)
1582 "dn": "cn=ldaptestcontainer," + self
.base_dn
,
1583 "objectClass": "container"})
1585 # The objectGUID cannot directly be changed
1587 self
.ldb
.modify_ldif("""
1588 dn: cn=ldaptestcontainer,""" + self
.base_dn
+ """
1591 objectGUID: bd3480c9-58af-4cd8-92df-bc4a18b6e44d
1594 except LdbError
as e
:
1596 self
.assertEqual(num
, ERR_CONSTRAINT_VIOLATION
)
1598 delete_force(self
.ldb
, "cn=ldaptestcontainer," + self
.base_dn
)
1600 def test_parentGUID(self
):
1601 """Test parentGUID behaviour"""
1603 "dn": "cn=parentguidtest,cn=users," + self
.base_dn
,
1604 "objectclass": "user",
1605 "samaccountname": "parentguidtest"})
1606 res1
= ldb
.search(base
="cn=parentguidtest,cn=users," + self
.base_dn
, scope
=SCOPE_BASE
,
1607 attrs
=["parentGUID", "samaccountname"])
1608 res2
= ldb
.search(base
="cn=users," + self
.base_dn
, scope
=SCOPE_BASE
,
1609 attrs
=["objectGUID"])
1610 res3
= ldb
.search(base
=self
.base_dn
, scope
=SCOPE_BASE
,
1611 attrs
=["parentGUID"])
1612 res4
= ldb
.search(base
=self
.configuration_dn
, scope
=SCOPE_BASE
,
1613 attrs
=["parentGUID"])
1614 res5
= ldb
.search(base
=self
.schema_dn
, scope
=SCOPE_BASE
,
1615 attrs
=["parentGUID"])
1617 """Check if the parentGUID is valid """
1618 self
.assertEqual(res1
[0]["parentGUID"], res2
[0]["objectGUID"])
1620 """Check if it returns nothing when there is no parent object - default NC"""
1621 has_parentGUID
= False
1622 for key
in res3
[0].keys():
1623 if key
== "parentGUID":
1624 has_parentGUID
= True
1626 self
.assertFalse(has_parentGUID
)
1628 """Check if it returns nothing when there is no parent object - configuration NC"""
1629 has_parentGUID
= False
1630 for key
in res4
[0].keys():
1631 if key
== "parentGUID":
1632 has_parentGUID
= True
1634 self
.assertFalse(has_parentGUID
)
1636 """Check if it returns nothing when there is no parent object - schema NC"""
1637 has_parentGUID
= False
1638 for key
in res5
[0].keys():
1639 if key
== "parentGUID":
1640 has_parentGUID
= True
1642 self
.assertFalse(has_parentGUID
)
1644 """Ensures that if you look for another object attribute after the constructed
1645 parentGUID, it will return correctly"""
1646 has_another_attribute
= False
1647 for key
in res1
[0].keys():
1648 if key
== "sAMAccountName":
1649 has_another_attribute
= True
1651 self
.assertTrue(has_another_attribute
)
1652 self
.assertTrue(len(res1
[0]["samaccountname"]) == 1)
1653 self
.assertEqual(str(res1
[0]["samaccountname"][0]), "parentguidtest")
1655 # Testing parentGUID behaviour on rename\
1658 "dn": "cn=testotherusers," + self
.base_dn
,
1659 "objectclass": "container"})
1660 res1
= ldb
.search(base
="cn=testotherusers," + self
.base_dn
, scope
=SCOPE_BASE
,
1661 attrs
=["objectGUID"])
1662 ldb
.rename("cn=parentguidtest,cn=users," + self
.base_dn
,
1663 "cn=parentguidtest,cn=testotherusers," + self
.base_dn
)
1664 res2
= ldb
.search(base
="cn=parentguidtest,cn=testotherusers," + self
.base_dn
,
1666 attrs
=["parentGUID"])
1667 self
.assertEqual(res1
[0]["objectGUID"], res2
[0]["parentGUID"])
1669 delete_force(self
.ldb
, "cn=parentguidtest,cn=testotherusers," + self
.base_dn
)
1670 delete_force(self
.ldb
, "cn=testotherusers," + self
.base_dn
)
1672 def test_usnChanged(self
):
1673 """Test usnChanged behaviour"""
1676 "dn": "cn=ldaptestcontainer," + self
.base_dn
,
1677 "objectClass": "container"})
1679 res
= ldb
.search("cn=ldaptestcontainer," + self
.base_dn
,
1681 attrs
=["objectGUID", "uSNCreated", "uSNChanged", "whenCreated", "whenChanged", "description"])
1682 self
.assertTrue(len(res
) == 1)
1683 self
.assertFalse("description" in res
[0])
1684 self
.assertTrue("objectGUID" in res
[0])
1685 self
.assertTrue("uSNCreated" in res
[0])
1686 self
.assertTrue("uSNChanged" in res
[0])
1687 self
.assertTrue("whenCreated" in res
[0])
1688 self
.assertTrue("whenChanged" in res
[0])
1690 delete_force(self
.ldb
, "cn=ldaptestcontainer," + self
.base_dn
)
1692 # All these attributes are specifiable on add operations
1694 "dn": "cn=ldaptestcontainer," + self
.base_dn
,
1695 "objectclass": "container",
1698 "whenCreated": timestring(int(time
.time())),
1699 "whenChanged": timestring(int(time
.time()))})
1701 res
= ldb
.search("cn=ldaptestcontainer," + self
.base_dn
,
1703 attrs
=["objectGUID", "uSNCreated", "uSNChanged", "whenCreated", "whenChanged", "description"])
1704 self
.assertTrue(len(res
) == 1)
1705 self
.assertFalse("description" in res
[0])
1706 self
.assertTrue("objectGUID" in res
[0])
1707 self
.assertTrue("uSNCreated" in res
[0])
1708 self
.assertFalse(res
[0]["uSNCreated"][0] == "1") # these are corrected
1709 self
.assertTrue("uSNChanged" in res
[0])
1710 self
.assertFalse(res
[0]["uSNChanged"][0] == "1") # these are corrected
1711 self
.assertTrue("whenCreated" in res
[0])
1712 self
.assertTrue("whenChanged" in res
[0])
1715 dn: cn=ldaptestcontainer,""" + self
.base_dn
+ """
1717 replace: description
1720 res2
= ldb
.search("cn=ldaptestcontainer," + self
.base_dn
,
1722 attrs
=["uSNCreated", "uSNChanged", "description"])
1723 self
.assertTrue(len(res
) == 1)
1724 self
.assertFalse("description" in res2
[0])
1725 self
.assertEqual(res
[0]["usnCreated"], res2
[0]["usnCreated"])
1726 self
.assertEqual(res
[0]["usnCreated"], res2
[0]["usnChanged"])
1727 self
.assertEqual(res
[0]["usnChanged"], res2
[0]["usnChanged"])
1730 dn: cn=ldaptestcontainer,""" + self
.base_dn
+ """
1732 replace: description
1736 res3
= ldb
.search("cn=ldaptestcontainer," + self
.base_dn
,
1738 attrs
=["uSNCreated", "uSNChanged", "description"])
1739 self
.assertTrue(len(res
) == 1)
1740 self
.assertTrue("description" in res3
[0])
1741 self
.assertEqual("test", str(res3
[0]["description"][0]))
1742 self
.assertEqual(res
[0]["usnCreated"], res3
[0]["usnCreated"])
1743 self
.assertNotEqual(res
[0]["usnCreated"], res3
[0]["usnChanged"])
1744 self
.assertNotEqual(res
[0]["usnChanged"], res3
[0]["usnChanged"])
1747 dn: cn=ldaptestcontainer,""" + self
.base_dn
+ """
1749 replace: description
1753 res4
= ldb
.search("cn=ldaptestcontainer," + self
.base_dn
,
1755 attrs
=["uSNCreated", "uSNChanged", "description"])
1756 self
.assertTrue(len(res
) == 1)
1757 self
.assertTrue("description" in res4
[0])
1758 self
.assertEqual("test", str(res4
[0]["description"][0]))
1759 self
.assertEqual(res
[0]["usnCreated"], res4
[0]["usnCreated"])
1760 self
.assertNotEqual(res3
[0]["usnCreated"], res4
[0]["usnChanged"])
1761 self
.assertEqual(res3
[0]["usnChanged"], res4
[0]["usnChanged"])
1764 dn: cn=ldaptestcontainer,""" + self
.base_dn
+ """
1766 replace: description
1770 res5
= ldb
.search("cn=ldaptestcontainer," + self
.base_dn
,
1772 attrs
=["uSNCreated", "uSNChanged", "description"])
1773 self
.assertTrue(len(res
) == 1)
1774 self
.assertTrue("description" in res5
[0])
1775 self
.assertEqual("test2", str(res5
[0]["description"][0]))
1776 self
.assertEqual(res
[0]["usnCreated"], res5
[0]["usnCreated"])
1777 self
.assertNotEqual(res3
[0]["usnChanged"], res5
[0]["usnChanged"])
1780 dn: cn=ldaptestcontainer,""" + self
.base_dn
+ """
1786 res6
= ldb
.search("cn=ldaptestcontainer," + self
.base_dn
,
1788 attrs
=["uSNCreated", "uSNChanged", "description"])
1789 self
.assertTrue(len(res
) == 1)
1790 self
.assertFalse("description" in res6
[0])
1791 self
.assertEqual(res
[0]["usnCreated"], res6
[0]["usnCreated"])
1792 self
.assertNotEqual(res5
[0]["usnChanged"], res6
[0]["usnChanged"])
1795 dn: cn=ldaptestcontainer,""" + self
.base_dn
+ """
1801 res7
= ldb
.search("cn=ldaptestcontainer," + self
.base_dn
,
1803 attrs
=["uSNCreated", "uSNChanged", "description"])
1804 self
.assertTrue(len(res
) == 1)
1805 self
.assertTrue("description" in res7
[0])
1806 self
.assertEqual("test3", str(res7
[0]["description"][0]))
1807 self
.assertEqual(res
[0]["usnCreated"], res7
[0]["usnCreated"])
1808 self
.assertNotEqual(res6
[0]["usnChanged"], res7
[0]["usnChanged"])
1811 dn: cn=ldaptestcontainer,""" + self
.base_dn
+ """
1816 res8
= ldb
.search("cn=ldaptestcontainer," + self
.base_dn
,
1818 attrs
=["uSNCreated", "uSNChanged", "description"])
1819 self
.assertTrue(len(res
) == 1)
1820 self
.assertFalse("description" in res8
[0])
1821 self
.assertEqual(res
[0]["usnCreated"], res8
[0]["usnCreated"])
1822 self
.assertNotEqual(res7
[0]["usnChanged"], res8
[0]["usnChanged"])
1824 delete_force(self
.ldb
, "cn=ldaptestcontainer," + self
.base_dn
)
1826 def test_groupType_int32(self
):
1827 """Test groupType (int32) behaviour (should appear to be cast to a 32 bit signed integer before comparison)"""
1829 res1
= ldb
.search(base
=self
.base_dn
, scope
=SCOPE_SUBTREE
,
1830 attrs
=["groupType"], expression
="groupType=2147483653")
1832 res2
= ldb
.search(base
=self
.base_dn
, scope
=SCOPE_SUBTREE
,
1833 attrs
=["groupType"], expression
="groupType=-2147483643")
1835 self
.assertEqual(len(res1
), len(res2
))
1837 self
.assertTrue(res1
.count
> 0)
1839 self
.assertEqual(str(res1
[0]["groupType"][0]), "-2147483643")
1841 def test_linked_attributes(self
):
1842 """This tests the linked attribute behaviour"""
1845 "dn": "cn=ldaptestgroup,cn=users," + self
.base_dn
,
1846 "objectclass": "group"})
1848 # This should not work since "memberOf" is linked to "member"
1851 "dn": "cn=ldaptestuser,cn=users," + self
.base_dn
,
1852 "objectclass": "user",
1853 "memberOf": "cn=ldaptestgroup,cn=users," + self
.base_dn
})
1854 except LdbError
as e
:
1856 self
.assertEqual(num
, ERR_UNWILLING_TO_PERFORM
)
1859 "dn": "cn=ldaptestuser,cn=users," + self
.base_dn
,
1860 "objectclass": "user"})
1863 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
1864 m
["memberOf"] = MessageElement("cn=ldaptestgroup,cn=users," + self
.base_dn
,
1865 FLAG_MOD_ADD
, "memberOf")
1869 except LdbError
as e
:
1871 self
.assertEqual(num
, ERR_UNWILLING_TO_PERFORM
)
1874 m
.dn
= Dn(ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
1875 m
["member"] = MessageElement("cn=ldaptestuser,cn=users," + self
.base_dn
,
1876 FLAG_MOD_ADD
, "member")
1880 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
1881 m
["memberOf"] = MessageElement("cn=ldaptestgroup,cn=users," + self
.base_dn
,
1882 FLAG_MOD_REPLACE
, "memberOf")
1886 except LdbError
as e
:
1888 self
.assertEqual(num
, ERR_UNWILLING_TO_PERFORM
)
1891 m
.dn
= Dn(ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
1892 m
["memberOf"] = MessageElement("cn=ldaptestgroup,cn=users," + self
.base_dn
,
1893 FLAG_MOD_DELETE
, "memberOf")
1897 except LdbError
as e
:
1899 self
.assertEqual(num
, ERR_UNWILLING_TO_PERFORM
)
1902 m
.dn
= Dn(ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
1903 m
["member"] = MessageElement("cn=ldaptestuser,cn=users," + self
.base_dn
,
1904 FLAG_MOD_DELETE
, "member")
1907 # This should yield no results since the member attribute for
1908 # "ldaptestuser" should have been deleted
1909 res1
= ldb
.search("cn=ldaptestgroup, cn=users," + self
.base_dn
,
1911 expression
="(member=cn=ldaptestuser,cn=users," + self
.base_dn
+ ")",
1913 self
.assertTrue(len(res1
) == 0)
1915 delete_force(self
.ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
1918 "dn": "cn=ldaptestgroup,cn=users," + self
.base_dn
,
1919 "objectclass": "group",
1920 "member": "cn=ldaptestuser,cn=users," + self
.base_dn
})
1922 delete_force(self
.ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
1924 # Make sure that the "member" attribute for "ldaptestuser" has been
1926 res
= ldb
.search("cn=ldaptestgroup,cn=users," + self
.base_dn
,
1927 scope
=SCOPE_BASE
, attrs
=["member"])
1928 self
.assertTrue(len(res
) == 1)
1929 self
.assertFalse("member" in res
[0])
1931 delete_force(self
.ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
1933 def test_wkguid(self
):
1934 """Test Well known GUID behaviours (including DN+Binary)"""
1936 res
= self
.ldb
.search(base
=("<WKGUID=ab1d30f3768811d1aded00c04fd8d5cd,%s>" % self
.base_dn
), scope
=SCOPE_BASE
, attrs
=[])
1937 self
.assertEqual(len(res
), 1)
1939 res2
= self
.ldb
.search(scope
=SCOPE_BASE
, attrs
=["wellKnownObjects"], expression
=("wellKnownObjects=B:32:ab1d30f3768811d1aded00c04fd8d5cd:%s" % res
[0].dn
))
1940 self
.assertEqual(len(res2
), 1)
1942 # Prove that the matching rule is over the whole DN+Binary
1943 res2
= self
.ldb
.search(scope
=SCOPE_BASE
, attrs
=["wellKnownObjects"], expression
=("wellKnownObjects=B:32:ab1d30f3768811d1aded00c04fd8d5cd"))
1944 self
.assertEqual(len(res2
), 0)
1945 # Prove that the matching rule is over the whole DN+Binary
1946 res2
= self
.ldb
.search(scope
=SCOPE_BASE
, attrs
=["wellKnownObjects"], expression
=("wellKnownObjects=%s") % res
[0].dn
)
1947 self
.assertEqual(len(res2
), 0)
1949 def test_subschemasubentry(self
):
1950 """Test subSchemaSubEntry appears when requested, but not when not requested"""
1952 res
= self
.ldb
.search(base
=self
.base_dn
, scope
=SCOPE_BASE
, attrs
=["subSchemaSubEntry"])
1953 self
.assertEqual(len(res
), 1)
1954 self
.assertEqual(str(res
[0]["subSchemaSubEntry"][0]), "CN=Aggregate," + self
.schema_dn
)
1956 res
= self
.ldb
.search(base
=self
.base_dn
, scope
=SCOPE_BASE
, attrs
=["*"])
1957 self
.assertEqual(len(res
), 1)
1958 self
.assertTrue("subScheamSubEntry" not in res
[0])
1966 "dn": "cn=ldaptestuser,cn=uSers," + self
.base_dn
,
1967 "objectclass": "user",
1968 "cN": "LDAPtestUSER",
1969 "givenname": "ldap",
1973 "dn": "cn=ldaptestgroup,cn=uSers," + self
.base_dn
,
1974 "objectclass": "group",
1975 "member": "cn=ldaptestuser,cn=useRs," + self
.base_dn
})
1978 "dn": "cn=ldaptestcomputer,cn=computers," + self
.base_dn
,
1979 "objectclass": "computer",
1980 "cN": "LDAPtestCOMPUTER"})
1982 ldb
.add({"dn": "cn=ldaptest2computer,cn=computers," + self
.base_dn
,
1983 "objectClass": "computer",
1984 "cn": "LDAPtest2COMPUTER",
1985 "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT
),
1986 "displayname": "ldap testy"})
1989 ldb
.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self
.base_dn
,
1990 "objectClass": "computer",
1991 "cn": "LDAPtest2COMPUTER"
1994 except LdbError
as e
:
1996 self
.assertEqual(num
, ERR_INVALID_DN_SYNTAX
)
1999 ldb
.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self
.base_dn
,
2000 "objectClass": "computer",
2001 "cn": "ldaptestcomputer3",
2002 "sAMAccountType": str(ATYPE_NORMAL_ACCOUNT
)
2005 except LdbError
as e
:
2007 self
.assertEqual(num
, ERR_UNWILLING_TO_PERFORM
)
2009 ldb
.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self
.base_dn
,
2010 "objectClass": "computer",
2011 "cn": "LDAPtestCOMPUTER3"
2014 # Testing ldb.search for (&(cn=ldaptestcomputer3)(objectClass=user))
2015 res
= ldb
.search(self
.base_dn
, expression
="(&(cn=ldaptestcomputer3)(objectClass=user))")
2016 self
.assertEqual(len(res
), 1, "Found only %d for (&(cn=ldaptestcomputer3)(objectClass=user))" % len(res
))
2018 self
.assertEqual(str(res
[0].dn
), ("CN=ldaptestcomputer3,CN=Computers," + self
.base_dn
))
2019 self
.assertEqual(str(res
[0]["cn"][0]), "ldaptestcomputer3")
2020 self
.assertEqual(str(res
[0]["name"][0]), "ldaptestcomputer3")
2021 self
.assertEqual(str(res
[0]["objectClass"][0]), "top")
2022 self
.assertEqual(str(res
[0]["objectClass"][1]), "person")
2023 self
.assertEqual(str(res
[0]["objectClass"][2]), "organizationalPerson")
2024 self
.assertEqual(str(res
[0]["objectClass"][3]), "user")
2025 self
.assertEqual(str(res
[0]["objectClass"][4]), "computer")
2026 self
.assertTrue("objectGUID" in res
[0])
2027 self
.assertTrue("whenCreated" in res
[0])
2028 self
.assertEqual(str(res
[0]["objectCategory"][0]), ("CN=Computer,%s" % ldb
.get_schema_basedn()))
2029 self
.assertEqual(int(res
[0]["primaryGroupID"][0]), DOMAIN_RID_DOMAIN_MEMBERS
)
2030 self
.assertEqual(int(res
[0]["sAMAccountType"][0]), ATYPE_WORKSTATION_TRUST
)
2031 self
.assertEqual(int(res
[0]["userAccountControl"][0]), UF_WORKSTATION_TRUST_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE
)
2033 delete_force(self
.ldb
, "cn=ldaptestcomputer3,cn=computers," + self
.base_dn
)
2035 # Testing attribute or value exists behaviour
2038 dn: cn=ldaptest2computer,cn=computers,""" + self
.base_dn
+ """
2040 replace: servicePrincipalName
2041 servicePrincipalName: host/ldaptest2computer
2042 servicePrincipalName: host/ldaptest2computer
2043 servicePrincipalName: cifs/ldaptest2computer
2046 except LdbError
as e
:
2048 self
.assertEqual(num
, ERR_ATTRIBUTE_OR_VALUE_EXISTS
)
2051 dn: cn=ldaptest2computer,cn=computers,""" + self
.base_dn
+ """
2053 replace: servicePrincipalName
2054 servicePrincipalName: host/ldaptest2computer
2055 servicePrincipalName: cifs/ldaptest2computer
2059 dn: cn=ldaptest2computer,cn=computers,""" + self
.base_dn
+ """
2061 add: servicePrincipalName
2062 servicePrincipalName: host/ldaptest2computer
2065 except LdbError
as e
:
2067 self
.assertEqual(num
, ERR_ATTRIBUTE_OR_VALUE_EXISTS
)
2069 # Testing ranged results
2071 dn: cn=ldaptest2computer,cn=computers,""" + self
.base_dn
+ """
2073 replace: servicePrincipalName
2077 dn: cn=ldaptest2computer,cn=computers,""" + self
.base_dn
+ """
2079 add: servicePrincipalName
2080 servicePrincipalName: host/ldaptest2computer0
2081 servicePrincipalName: host/ldaptest2computer1
2082 servicePrincipalName: host/ldaptest2computer2
2083 servicePrincipalName: host/ldaptest2computer3
2084 servicePrincipalName: host/ldaptest2computer4
2085 servicePrincipalName: host/ldaptest2computer5
2086 servicePrincipalName: host/ldaptest2computer6
2087 servicePrincipalName: host/ldaptest2computer7
2088 servicePrincipalName: host/ldaptest2computer8
2089 servicePrincipalName: host/ldaptest2computer9
2090 servicePrincipalName: host/ldaptest2computer10
2091 servicePrincipalName: host/ldaptest2computer11
2092 servicePrincipalName: host/ldaptest2computer12
2093 servicePrincipalName: host/ldaptest2computer13
2094 servicePrincipalName: host/ldaptest2computer14
2095 servicePrincipalName: host/ldaptest2computer15
2096 servicePrincipalName: host/ldaptest2computer16
2097 servicePrincipalName: host/ldaptest2computer17
2098 servicePrincipalName: host/ldaptest2computer18
2099 servicePrincipalName: host/ldaptest2computer19
2100 servicePrincipalName: host/ldaptest2computer20
2101 servicePrincipalName: host/ldaptest2computer21
2102 servicePrincipalName: host/ldaptest2computer22
2103 servicePrincipalName: host/ldaptest2computer23
2104 servicePrincipalName: host/ldaptest2computer24
2105 servicePrincipalName: host/ldaptest2computer25
2106 servicePrincipalName: host/ldaptest2computer26
2107 servicePrincipalName: host/ldaptest2computer27
2108 servicePrincipalName: host/ldaptest2computer28
2109 servicePrincipalName: host/ldaptest2computer29
2112 res
= ldb
.search(self
.base_dn
, expression
="(cn=ldaptest2computer))", scope
=SCOPE_SUBTREE
,
2113 attrs
=["servicePrincipalName;range=0-*"])
2114 self
.assertEqual(len(res
), 1, "Could not find (cn=ldaptest2computer)")
2115 self
.assertEqual(len(res
[0]["servicePrincipalName;range=0-*"]), 30)
2117 res
= ldb
.search(self
.base_dn
, expression
="(cn=ldaptest2computer))", scope
=SCOPE_SUBTREE
, attrs
=["servicePrincipalName;range=0-19"])
2118 self
.assertEqual(len(res
), 1, "Could not find (cn=ldaptest2computer)")
2119 self
.assertEqual(len(res
[0]["servicePrincipalName;range=0-19"]), 20)
2121 res
= ldb
.search(self
.base_dn
, expression
="(cn=ldaptest2computer))", scope
=SCOPE_SUBTREE
, attrs
=["servicePrincipalName;range=0-30"])
2122 self
.assertEqual(len(res
), 1, "Could not find (cn=ldaptest2computer)")
2123 self
.assertEqual(len(res
[0]["servicePrincipalName;range=0-*"]), 30)
2125 res
= ldb
.search(self
.base_dn
, expression
="(cn=ldaptest2computer))", scope
=SCOPE_SUBTREE
, attrs
=["servicePrincipalName;range=0-40"])
2126 self
.assertEqual(len(res
), 1, "Could not find (cn=ldaptest2computer)")
2127 self
.assertEqual(len(res
[0]["servicePrincipalName;range=0-*"]), 30)
2129 res
= ldb
.search(self
.base_dn
, expression
="(cn=ldaptest2computer))", scope
=SCOPE_SUBTREE
, attrs
=["servicePrincipalName;range=30-40"])
2130 self
.assertEqual(len(res
), 1, "Could not find (cn=ldaptest2computer)")
2131 self
.assertEqual(len(res
[0]["servicePrincipalName;range=30-*"]), 0)
2133 res
= ldb
.search(self
.base_dn
, expression
="(cn=ldaptest2computer))", scope
=SCOPE_SUBTREE
, attrs
=["servicePrincipalName;range=10-40"])
2134 self
.assertEqual(len(res
), 1, "Could not find (cn=ldaptest2computer)")
2135 self
.assertEqual(len(res
[0]["servicePrincipalName;range=10-*"]), 20)
2136 # pos_11 = res[0]["servicePrincipalName;range=10-*"][18]
2138 res
= ldb
.search(self
.base_dn
, expression
="(cn=ldaptest2computer))", scope
=SCOPE_SUBTREE
, attrs
=["servicePrincipalName;range=11-40"])
2139 self
.assertEqual(len(res
), 1, "Could not find (cn=ldaptest2computer)")
2140 self
.assertEqual(len(res
[0]["servicePrincipalName;range=11-*"]), 19)
2141 # self.assertEqual((res[0]["servicePrincipalName;range=11-*"][18]), pos_11)
2143 res
= ldb
.search(self
.base_dn
, expression
="(cn=ldaptest2computer))", scope
=SCOPE_SUBTREE
, attrs
=["servicePrincipalName;range=11-15"])
2144 self
.assertEqual(len(res
), 1, "Could not find (cn=ldaptest2computer)")
2145 self
.assertEqual(len(res
[0]["servicePrincipalName;range=11-15"]), 5)
2146 # self.assertEqual(res[0]["servicePrincipalName;range=11-15"][4], pos_11)
2148 res
= ldb
.search(self
.base_dn
, expression
="(cn=ldaptest2computer))", scope
=SCOPE_SUBTREE
, attrs
=["servicePrincipalName"])
2149 self
.assertEqual(len(res
), 1, "Could not find (cn=ldaptest2computer)")
2150 self
.assertEqual(len(res
[0]["servicePrincipalName"]), 30)
2151 # self.assertEqual(res[0]["servicePrincipalName"][18], pos_11)
2153 delete_force(self
.ldb
, "cn=ldaptestuser2,cn=users," + self
.base_dn
)
2155 "dn": "cn=ldaptestuser2,cn=useRs," + self
.base_dn
,
2156 "objectClass": "user",
2157 "cn": "LDAPtestUSER2",
2158 "givenname": "testy",
2159 "sn": "ldap user2"})
2161 # Testing Ambiguous Name Resolution
2162 # Testing ldb.search for (&(anr=ldap testy)(objectClass=user))
2163 res
= ldb
.search(expression
="(&(anr=ldap testy)(objectClass=user))")
2164 self
.assertEqual(len(res
), 3, "Found only %d of 3 for (&(anr=ldap testy)(objectClass=user))" % len(res
))
2166 # Testing ldb.search for (&(anr=testy ldap)(objectClass=user))
2167 res
= ldb
.search(expression
="(&(anr=testy ldap)(objectClass=user))")
2168 self
.assertEqual(len(res
), 2, "Found only %d of 2 for (&(anr=testy ldap)(objectClass=user))" % len(res
))
2170 # Testing ldb.search for (&(anr=ldap)(objectClass=user))
2171 res
= ldb
.search(expression
="(&(anr=ldap)(objectClass=user))")
2172 self
.assertEqual(len(res
), 4, "Found only %d of 4 for (&(anr=ldap)(objectClass=user))" % len(res
))
2174 # Testing ldb.search for (&(anr==ldap)(objectClass=user))
2175 res
= ldb
.search(expression
="(&(anr==ldap)(objectClass=user))")
2176 self
.assertEqual(len(res
), 1, "Could not find (&(anr==ldap)(objectClass=user)). Found only %d for (&(anr=ldap)(objectClass=user))" % len(res
))
2178 self
.assertEqual(str(res
[0].dn
), ("CN=ldaptestuser,CN=Users," + self
.base_dn
))
2179 self
.assertEqual(str(res
[0]["cn"][0]), "ldaptestuser")
2180 self
.assertEqual(str(res
[0]["name"]), "ldaptestuser")
2182 # Testing ldb.search for (&(anr=testy)(objectClass=user))
2183 res
= ldb
.search(expression
="(&(anr=testy)(objectClass=user))")
2184 self
.assertEqual(len(res
), 2, "Found only %d for (&(anr=testy)(objectClass=user))" % len(res
))
2186 # Testing ldb.search for (&(anr=testy ldap)(objectClass=user))
2187 res
= ldb
.search(expression
="(&(anr=testy ldap)(objectClass=user))")
2188 self
.assertEqual(len(res
), 2, "Found only %d for (&(anr=testy ldap)(objectClass=user))" % len(res
))
2190 # Testing ldb.search for (&(anr==testy ldap)(objectClass=user))
2191 # this test disabled for the moment, as anr with == tests are not understood
2192 # res = ldb.search(expression="(&(anr==testy ldap)(objectClass=user))")
2193 # self.assertEqual(len(res), 1, "Found only %d for (&(anr==testy ldap)(objectClass=user))" % len(res))
2195 # self.assertEqual(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
2196 # self.assertEqual(res[0]["cn"][0], "ldaptestuser")
2197 # self.assertEqual(res[0]["name"][0], "ldaptestuser")
2199 # Testing ldb.search for (&(anr==testy ldap)(objectClass=user))
2200 # res = ldb.search(expression="(&(anr==testy ldap)(objectClass=user))")
2201 # self.assertEqual(len(res), 1, "Could not find (&(anr==testy ldap)(objectClass=user))")
2203 # self.assertEqual(str(res[0].dn), ("CN=ldaptestuser,CN=Users," + self.base_dn))
2204 # self.assertEqual(res[0]["cn"][0], "ldaptestuser")
2205 # self.assertEqual(res[0]["name"][0], "ldaptestuser")
2207 # Testing ldb.search for (&(anr=testy ldap user)(objectClass=user))
2208 res
= ldb
.search(expression
="(&(anr=testy ldap user)(objectClass=user))")
2209 self
.assertEqual(len(res
), 1, "Could not find (&(anr=testy ldap user)(objectClass=user))")
2211 self
.assertEqual(str(res
[0].dn
), ("CN=ldaptestuser2,CN=Users," + self
.base_dn
))
2212 self
.assertEqual(str(res
[0]["cn"]), "ldaptestuser2")
2213 self
.assertEqual(str(res
[0]["name"]), "ldaptestuser2")
2215 # Testing ldb.search for (&(anr==testy ldap user2)(objectClass=user))
2216 # res = ldb.search(expression="(&(anr==testy ldap user2)(objectClass=user))")
2217 # self.assertEqual(len(res), 1, "Could not find (&(anr==testy ldap user2)(objectClass=user))")
2219 self
.assertEqual(str(res
[0].dn
), ("CN=ldaptestuser2,CN=Users," + self
.base_dn
))
2220 self
.assertEqual(str(res
[0]["cn"]), "ldaptestuser2")
2221 self
.assertEqual(str(res
[0]["name"]), "ldaptestuser2")
2223 # Testing ldb.search for (&(anr==ldap user2)(objectClass=user))
2224 # res = ldb.search(expression="(&(anr==ldap user2)(objectClass=user))")
2225 # self.assertEqual(len(res), 1, "Could not find (&(anr==ldap user2)(objectClass=user))")
2227 self
.assertEqual(str(res
[0].dn
), ("CN=ldaptestuser2,CN=Users," + self
.base_dn
))
2228 self
.assertEqual(str(res
[0]["cn"]), "ldaptestuser2")
2229 self
.assertEqual(str(res
[0]["name"]), "ldaptestuser2")
2231 # Testing ldb.search for (&(anr==not ldap user2)(objectClass=user))
2232 # res = ldb.search(expression="(&(anr==not ldap user2)(objectClass=user))")
2233 # self.assertEqual(len(res), 0, "Must not find (&(anr==not ldap user2)(objectClass=user))")
2235 # Testing ldb.search for (&(anr=not ldap user2)(objectClass=user))
2236 res
= ldb
.search(expression
="(&(anr=not ldap user2)(objectClass=user))")
2237 self
.assertEqual(len(res
), 0, "Must not find (&(anr=not ldap user2)(objectClass=user))")
2239 # Testing ldb.search for (&(anr="testy ldap")(objectClass=user)) (ie, with quotes)
2240 # res = ldb.search(expression="(&(anr==\"testy ldap\")(objectClass=user))")
2241 # self.assertEqual(len(res), 0, "Found (&(anr==\"testy ldap\")(objectClass=user))")
2245 attrs
= ["objectGUID", "objectSid"]
2246 # Testing ldb.search for (&(cn=ldaptestUSer2)(objectClass=user))
2247 res_user
= ldb
.search(self
.base_dn
, expression
="(&(cn=ldaptestUSer2)(objectClass=user))", scope
=SCOPE_SUBTREE
, attrs
=attrs
)
2248 self
.assertEqual(len(res_user
), 1, "Could not find (&(cn=ldaptestUSer2)(objectClass=user))")
2250 # Check rename works with extended/alternate DN forms
2251 ldb
.rename("<SID=" + get_string(ldb
.schema_format_value("objectSID", res_user
[0]["objectSID"][0])) + ">", "cn=ldaptestUSER3,cn=users," + self
.base_dn
)
2253 # Testing ldb.search for (&(cn=ldaptestuser3)(objectClass=user))
2254 res
= ldb
.search(expression
="(&(cn=ldaptestuser3)(objectClass=user))")
2255 self
.assertEqual(len(res
), 1, "Could not find (&(cn=ldaptestuser3)(objectClass=user))")
2257 self
.assertEqual(str(res
[0].dn
), ("CN=ldaptestUSER3,CN=Users," + self
.base_dn
))
2258 self
.assertEqual(str(res
[0]["cn"]), "ldaptestUSER3")
2259 self
.assertEqual(str(res
[0]["name"]), "ldaptestUSER3")
2261 #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))"
2262 res
= ldb
.search(expression
="(&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))")
2263 self
.assertEqual(len(res
), 1, "(&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))")
2265 self
.assertEqual(str(res
[0].dn
), ("CN=ldaptestUSER3,CN=Users," + self
.base_dn
))
2266 self
.assertEqual(str(res
[0]["cn"]), "ldaptestUSER3")
2267 self
.assertEqual(str(res
[0]["name"]), "ldaptestUSER3")
2269 #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))"
2270 res
= ldb
.search(expression
="(&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))")
2271 self
.assertEqual(len(res
), 1, "(&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))")
2273 self
.assertEqual(str(res
[0].dn
), ("CN=ldaptestUSER3,CN=Users," + self
.base_dn
))
2274 self
.assertEqual(str(res
[0]["cn"]), "ldaptestUSER3")
2275 self
.assertEqual(str(res
[0]["name"]), "ldaptestUSER3")
2277 #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))"
2278 res
= ldb
.search(expression
="(&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))")
2279 self
.assertEqual(len(res
), 0, "(&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))")
2281 # Testing ldb.search for (dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ") - should not work
2282 res
= ldb
.search(expression
="(dn=CN=ldaptestUSER3,CN=Users," + self
.base_dn
+ ")")
2283 self
.assertEqual(len(res
), 0, "Could find (dn=CN=ldaptestUSER3,CN=Users," + self
.base_dn
+ ")")
2285 # Testing ldb.search for (distinguishedName=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")
2286 res
= ldb
.search(expression
="(distinguishedName=CN=ldaptestUSER3,CN=Users," + self
.base_dn
+ ")")
2287 self
.assertEqual(len(res
), 1, "Could not find (distinguishedName=CN=ldaptestUSER3,CN=Users," + self
.base_dn
+ ")")
2288 self
.assertEqual(str(res
[0].dn
), ("CN=ldaptestUSER3,CN=Users," + self
.base_dn
))
2289 self
.assertEqual(str(res
[0]["cn"]), "ldaptestUSER3")
2290 self
.assertEqual(str(res
[0]["name"]), "ldaptestUSER3")
2292 # ensure we cannot add it again
2294 ldb
.add({"dn": "cn=ldaptestuser3,cn=userS," + self
.base_dn
,
2295 "objectClass": "user",
2296 "cn": "LDAPtestUSER3"})
2298 except LdbError
as e
:
2300 self
.assertEqual(num
, ERR_ENTRY_ALREADY_EXISTS
)
2303 ldb
.rename("cn=ldaptestuser3,cn=users," + self
.base_dn
, "cn=ldaptestuser2,cn=users," + self
.base_dn
)
2305 # ensure we cannot rename it twice
2307 ldb
.rename("cn=ldaptestuser3,cn=users," + self
.base_dn
,
2308 "cn=ldaptestuser2,cn=users," + self
.base_dn
)
2310 except LdbError
as e
:
2312 self
.assertEqual(num
, ERR_NO_SUCH_OBJECT
)
2314 # ensure can now use that name
2315 ldb
.add({"dn": "cn=ldaptestuser3,cn=users," + self
.base_dn
,
2316 "objectClass": "user",
2317 "cn": "LDAPtestUSER3"})
2319 # ensure we now cannot rename
2321 ldb
.rename("cn=ldaptestuser2,cn=users," + self
.base_dn
, "cn=ldaptestuser3,cn=users," + self
.base_dn
)
2323 except LdbError
as e
:
2325 self
.assertEqual(num
, ERR_ENTRY_ALREADY_EXISTS
)
2327 ldb
.rename("cn=ldaptestuser3,cn=users,%s" % self
.base_dn
, "cn=ldaptestuser3,%s" % ldb
.get_config_basedn())
2329 except LdbError
as e
:
2331 self
.assertTrue(num
in (71, 64))
2333 ldb
.rename("cn=ldaptestuser3,cn=users," + self
.base_dn
, "cn=ldaptestuser5,cn=users," + self
.base_dn
)
2335 ldb
.delete("cn=ldaptestuser5,cn=users," + self
.base_dn
)
2337 delete_force(ldb
, "cn=ldaptestgroup2,cn=users," + self
.base_dn
)
2339 ldb
.rename("cn=ldaptestgroup,cn=users," + self
.base_dn
, "cn=ldaptestgroup2,cn=users," + self
.base_dn
)
2341 # Testing subtree renames
2343 ldb
.add({"dn": "cn=ldaptestcontainer," + self
.base_dn
,
2344 "objectClass": "container"})
2346 ldb
.add({"dn": "CN=ldaptestuser4,CN=ldaptestcontainer," + self
.base_dn
,
2347 "objectClass": "user",
2348 "cn": "LDAPtestUSER4"})
2350 # Here we don't enforce these hard "description" constraints
2352 dn: cn=ldaptestcontainer,""" + self
.base_dn
+ """
2354 replace: description
2360 dn: cn=ldaptestgroup2,cn=users,""" + self
.base_dn
+ """
2363 member: cn=ldaptestuser4,cn=ldaptestcontainer,""" + self
.base_dn
+ """
2364 member: cn=ldaptestcomputer,cn=computers,""" + self
.base_dn
+ """
2365 member: cn=ldaptestuser2,cn=users,""" + self
.base_dn
+ """
2368 # Testing ldb.rename of cn=ldaptestcontainer," + self.base_dn + " to cn=ldaptestcontainer2," + self.base_dn
2369 ldb
.rename("CN=ldaptestcontainer," + self
.base_dn
, "CN=ldaptestcontainer2," + self
.base_dn
)
2371 # Testing ldb.search for (&(cn=ldaptestuser4)(objectClass=user))
2372 res
= ldb
.search(expression
="(&(cn=ldaptestuser4)(objectClass=user))")
2373 self
.assertEqual(len(res
), 1, "Could not find (&(cn=ldaptestuser4)(objectClass=user))")
2375 # Testing subtree ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in (just renamed from) cn=ldaptestcontainer," + self.base_dn
2377 res
= ldb
.search("cn=ldaptestcontainer," + self
.base_dn
,
2378 expression
="(&(cn=ldaptestuser4)(objectClass=user))",
2379 scope
=SCOPE_SUBTREE
)
2381 except LdbError
as e
:
2383 self
.assertEqual(num
, ERR_NO_SUCH_OBJECT
)
2385 # Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in (just renamed from) cn=ldaptestcontainer," + self.base_dn
2387 res
= ldb
.search("cn=ldaptestcontainer," + self
.base_dn
,
2388 expression
="(&(cn=ldaptestuser4)(objectClass=user))", scope
=SCOPE_ONELEVEL
)
2390 except LdbError
as e
:
2392 self
.assertEqual(num
, ERR_NO_SUCH_OBJECT
)
2394 # Testing ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in renamed container"
2395 res
= ldb
.search("cn=ldaptestcontainer2," + self
.base_dn
, expression
="(&(cn=ldaptestuser4)(objectClass=user))", scope
=SCOPE_SUBTREE
)
2396 self
.assertEqual(len(res
), 1, "Could not find (&(cn=ldaptestuser4)(objectClass=user)) under cn=ldaptestcontainer2," + self
.base_dn
)
2398 self
.assertEqual(str(res
[0].dn
), ("CN=ldaptestuser4,CN=ldaptestcontainer2," + self
.base_dn
))
2399 self
.assertEqual(str(res
[0]["memberOf"][0]).upper(), ("CN=ldaptestgroup2,CN=Users," + self
.base_dn
).upper())
2403 # Testing ldb.search for (&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn + ")(objectclass=group)) to check subtree renames and linked attributes"
2404 res
= ldb
.search(self
.base_dn
, expression
="(&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + self
.base_dn
+ ")(objectclass=group))", scope
=SCOPE_SUBTREE
)
2405 self
.assertEqual(len(res
), 1, "Could not find (&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + self
.base_dn
+ ")(objectclass=group)), perhaps linked attributes are not consistent with subtree renames?")
2407 # Testing ldb.rename (into itself) of cn=ldaptestcontainer2," + self.base_dn + " to cn=ldaptestcontainer,cn=ldaptestcontainer2," + self.base_dn
2409 ldb
.rename("cn=ldaptestcontainer2," + self
.base_dn
, "cn=ldaptestcontainer,cn=ldaptestcontainer2," + self
.base_dn
)
2411 except LdbError
as e
:
2413 self
.assertEqual(num
, ERR_UNWILLING_TO_PERFORM
)
2415 # Testing ldb.rename (into non-existent container) of cn=ldaptestcontainer2," + self.base_dn + " to cn=ldaptestcontainer,cn=ldaptestcontainer3," + self.base_dn
2417 ldb
.rename("cn=ldaptestcontainer2," + self
.base_dn
, "cn=ldaptestcontainer,cn=ldaptestcontainer3," + self
.base_dn
)
2419 except LdbError
as e
:
2421 self
.assertTrue(num
in (ERR_UNWILLING_TO_PERFORM
, ERR_OTHER
))
2423 # Testing delete (should fail, not a leaf node) of renamed cn=ldaptestcontainer2," + self.base_dn
2425 ldb
.delete("cn=ldaptestcontainer2," + self
.base_dn
)
2427 except LdbError
as e
:
2429 self
.assertEqual(num
, ERR_NOT_ALLOWED_ON_NON_LEAF
)
2431 # Testing base ldb.search for CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn
2432 res
= ldb
.search(expression
="(objectclass=*)", base
=("CN=ldaptestuser4,CN=ldaptestcontainer2," + self
.base_dn
), scope
=SCOPE_BASE
)
2433 self
.assertEqual(len(res
), 1)
2434 res
= ldb
.search(expression
="(cn=ldaptestuser40)", base
=("CN=ldaptestuser4,CN=ldaptestcontainer2," + self
.base_dn
), scope
=SCOPE_BASE
)
2435 self
.assertEqual(len(res
), 0)
2437 # Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in cn=ldaptestcontainer2," + self.base_dn
2438 res
= ldb
.search(expression
="(&(cn=ldaptestuser4)(objectClass=user))", base
=("cn=ldaptestcontainer2," + self
.base_dn
), scope
=SCOPE_ONELEVEL
)
2439 self
.assertEqual(len(res
), 1)
2441 # Testing one-level ldb.search for (&(cn=ldaptestuser4)(objectClass=user)) in cn=ldaptestcontainer2," + self.base_dn
2442 res
= ldb
.search(expression
="(&(cn=ldaptestuser4)(objectClass=user))", base
=("cn=ldaptestcontainer2," + self
.base_dn
), scope
=SCOPE_SUBTREE
)
2443 self
.assertEqual(len(res
), 1)
2445 # Testing delete of subtree renamed "+("CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn)
2446 ldb
.delete(("CN=ldaptestuser4,CN=ldaptestcontainer2," + self
.base_dn
))
2447 # Testing delete of renamed cn=ldaptestcontainer2," + self.base_dn
2448 ldb
.delete("cn=ldaptestcontainer2," + self
.base_dn
)
2450 ldb
.add({"dn": "cn=ldaptestutf8user èùéìòà,cn=users," + self
.base_dn
, "objectClass": "user"})
2452 ldb
.add({"dn": "cn=ldaptestutf8user2 èùéìòà,cn=users," + self
.base_dn
, "objectClass": "user"})
2454 # Testing ldb.search for (&(cn=ldaptestuser)(objectClass=user))"
2455 res
= ldb
.search(expression
="(&(cn=ldaptestuser)(objectClass=user))")
2456 self
.assertEqual(len(res
), 1, "Could not find (&(cn=ldaptestuser)(objectClass=user))")
2458 self
.assertEqual(str(res
[0].dn
), ("CN=ldaptestuser,CN=Users," + self
.base_dn
))
2459 self
.assertEqual(str(res
[0]["cn"]), "ldaptestuser")
2460 self
.assertEqual(str(res
[0]["name"]), "ldaptestuser")
2461 self
.assertEqual(set(res
[0]["objectClass"]), set([b
"top", b
"person", b
"organizationalPerson", b
"user"]))
2462 self
.assertTrue("objectGUID" in res
[0])
2463 self
.assertTrue("whenCreated" in res
[0])
2464 self
.assertEqual(str(res
[0]["objectCategory"]), ("CN=Person,%s" % ldb
.get_schema_basedn()))
2465 self
.assertEqual(int(res
[0]["sAMAccountType"][0]), ATYPE_NORMAL_ACCOUNT
)
2466 self
.assertEqual(int(res
[0]["userAccountControl"][0]), UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE
)
2467 self
.assertEqual(str(res
[0]["memberOf"][0]).upper(), ("CN=ldaptestgroup2,CN=Users," + self
.base_dn
).upper())
2468 self
.assertEqual(len(res
[0]["memberOf"]), 1)
2470 # Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=cn=person,%s))" % ldb.get_schema_basedn()
2471 res2
= ldb
.search(expression
="(&(cn=ldaptestuser)(objectCategory=cn=person,%s))" % ldb
.get_schema_basedn())
2472 self
.assertEqual(len(res2
), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=cn=person,%s))" % ldb
.get_schema_basedn())
2474 self
.assertEqual(res
[0].dn
, res2
[0].dn
)
2476 # Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon))"
2477 res3
= ldb
.search(expression
="(&(cn=ldaptestuser)(objectCategory=PerSon))")
2478 self
.assertEqual(len(res3
), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=PerSon)): matched %d" % len(res3
))
2480 self
.assertEqual(res
[0].dn
, res3
[0].dn
)
2482 if gc_ldb
is not None:
2483 # Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon)) in Global Catalog"
2484 res3gc
= gc_ldb
.search(expression
="(&(cn=ldaptestuser)(objectCategory=PerSon))")
2485 self
.assertEqual(len(res3gc
), 1)
2487 self
.assertEqual(res
[0].dn
, res3gc
[0].dn
)
2489 # Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon)) in with 'phantom root' control"
2491 if gc_ldb
is not None:
2492 res3control
= gc_ldb
.search(self
.base_dn
, expression
="(&(cn=ldaptestuser)(objectCategory=PerSon))", scope
=SCOPE_SUBTREE
, attrs
=["cn"], controls
=["search_options:1:2"])
2493 self
.assertEqual(len(res3control
), 1, "Could not find (&(cn=ldaptestuser)(objectCategory=PerSon)) in Global Catalog")
2495 self
.assertEqual(res
[0].dn
, res3control
[0].dn
)
2497 ldb
.delete(res
[0].dn
)
2499 # Testing ldb.search for (&(cn=ldaptestcomputer)(objectClass=user))"
2500 res
= ldb
.search(expression
="(&(cn=ldaptestcomputer)(objectClass=user))")
2501 self
.assertEqual(len(res
), 1, "Could not find (&(cn=ldaptestuser)(objectClass=user))")
2503 self
.assertEqual(str(res
[0].dn
), ("CN=ldaptestcomputer,CN=Computers," + self
.base_dn
))
2504 self
.assertEqual(str(res
[0]["cn"]), "ldaptestcomputer")
2505 self
.assertEqual(str(res
[0]["name"]), "ldaptestcomputer")
2506 self
.assertEqual(set(res
[0]["objectClass"]), set([b
"top", b
"person", b
"organizationalPerson", b
"user", b
"computer"]))
2507 self
.assertTrue("objectGUID" in res
[0])
2508 self
.assertTrue("whenCreated" in res
[0])
2509 self
.assertEqual(str(res
[0]["objectCategory"]), ("CN=Computer,%s" % ldb
.get_schema_basedn()))
2510 self
.assertEqual(int(res
[0]["primaryGroupID"][0]), DOMAIN_RID_DOMAIN_MEMBERS
)
2511 self
.assertEqual(int(res
[0]["sAMAccountType"][0]), ATYPE_WORKSTATION_TRUST
)
2512 self
.assertEqual(int(res
[0]["userAccountControl"][0]), UF_WORKSTATION_TRUST_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE
)
2513 self
.assertEqual(str(res
[0]["memberOf"][0]).upper(), ("CN=ldaptestgroup2,CN=Users," + self
.base_dn
).upper())
2514 self
.assertEqual(len(res
[0]["memberOf"]), 1)
2516 # Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=cn=computer,%s))" % ldb.get_schema_basedn()
2517 res2
= ldb
.search(expression
="(&(cn=ldaptestcomputer)(objectCategory=cn=computer,%s))" % ldb
.get_schema_basedn())
2518 self
.assertEqual(len(res2
), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=cn=computer,%s))" % ldb
.get_schema_basedn())
2520 self
.assertEqual(res
[0].dn
, res2
[0].dn
)
2522 if gc_ldb
is not None:
2523 # Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=cn=computer,%s)) in Global Catalog" % gc_ldb.get_schema_basedn()
2524 res2gc
= gc_ldb
.search(expression
="(&(cn=ldaptestcomputer)(objectCategory=cn=computer,%s))" % gc_ldb
.get_schema_basedn())
2525 self
.assertEqual(len(res2gc
), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=cn=computer,%s)) In Global Catalog" % gc_ldb
.get_schema_basedn())
2527 self
.assertEqual(res
[0].dn
, res2gc
[0].dn
)
2529 # Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=compuTER))"
2530 res3
= ldb
.search(expression
="(&(cn=ldaptestcomputer)(objectCategory=compuTER))")
2531 self
.assertEqual(len(res3
), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=compuTER))")
2533 self
.assertEqual(res
[0].dn
, res3
[0].dn
)
2535 if gc_ldb
is not None:
2536 # Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=compuTER)) in Global Catalog"
2537 res3gc
= gc_ldb
.search(expression
="(&(cn=ldaptestcomputer)(objectCategory=compuTER))")
2538 self
.assertEqual(len(res3gc
), 1, "Could not find (&(cn=ldaptestcomputer)(objectCategory=compuTER)) in Global Catalog")
2540 self
.assertEqual(res
[0].dn
, res3gc
[0].dn
)
2542 # Testing ldb.search for (&(cn=ldaptestcomp*r)(objectCategory=compuTER))"
2543 res4
= ldb
.search(expression
="(&(cn=ldaptestcomp*r)(objectCategory=compuTER))")
2544 self
.assertEqual(len(res4
), 1, "Could not find (&(cn=ldaptestcomp*r)(objectCategory=compuTER))")
2546 self
.assertEqual(res
[0].dn
, res4
[0].dn
)
2548 # Testing ldb.search for (&(cn=ldaptestcomput*)(objectCategory=compuTER))"
2549 res5
= ldb
.search(expression
="(&(cn=ldaptestcomput*)(objectCategory=compuTER))")
2550 self
.assertEqual(len(res5
), 1, "Could not find (&(cn=ldaptestcomput*)(objectCategory=compuTER))")
2552 self
.assertEqual(res
[0].dn
, res5
[0].dn
)
2554 # Testing ldb.search for (&(cn=*daptestcomputer)(objectCategory=compuTER))"
2555 res6
= ldb
.search(expression
="(&(cn=*daptestcomputer)(objectCategory=compuTER))")
2556 self
.assertEqual(len(res6
), 1, "Could not find (&(cn=*daptestcomputer)(objectCategory=compuTER))")
2558 self
.assertEqual(res
[0].dn
, res6
[0].dn
)
2560 ldb
.delete("<GUID=" + get_string(ldb
.schema_format_value("objectGUID", res
[0]["objectGUID"][0])) + ">")
2562 # Testing ldb.search for (&(cn=ldaptest2computer)(objectClass=user))"
2563 res
= ldb
.search(expression
="(&(cn=ldaptest2computer)(objectClass=user))")
2564 self
.assertEqual(len(res
), 1, "Could not find (&(cn=ldaptest2computer)(objectClass=user))")
2566 self
.assertEqual(str(res
[0].dn
), "CN=ldaptest2computer,CN=Computers," + self
.base_dn
)
2567 self
.assertEqual(str(res
[0]["cn"]), "ldaptest2computer")
2568 self
.assertEqual(str(res
[0]["name"]), "ldaptest2computer")
2569 self
.assertEqual(list(res
[0]["objectClass"]), [b
"top", b
"person", b
"organizationalPerson", b
"user", b
"computer"])
2570 self
.assertTrue("objectGUID" in res
[0])
2571 self
.assertTrue("whenCreated" in res
[0])
2572 self
.assertEqual(str(res
[0]["objectCategory"][0]), "CN=Computer,%s" % ldb
.get_schema_basedn())
2573 self
.assertEqual(int(res
[0]["sAMAccountType"][0]), ATYPE_WORKSTATION_TRUST
)
2574 self
.assertEqual(int(res
[0]["userAccountControl"][0]), UF_WORKSTATION_TRUST_ACCOUNT
)
2576 ldb
.delete("<SID=" + get_string(ldb
.schema_format_value("objectSID", res
[0]["objectSID"][0])) + ">")
2578 attrs
= ["cn", "name", "objectClass", "objectGUID", "objectSID", "whenCreated", "nTSecurityDescriptor", "memberOf", "allowedAttributes", "allowedAttributesEffective"]
2579 # Testing ldb.search for (&(cn=ldaptestUSer2)(objectClass=user))"
2580 res_user
= ldb
.search(self
.base_dn
, expression
="(&(cn=ldaptestUSer2)(objectClass=user))", scope
=SCOPE_SUBTREE
, attrs
=attrs
)
2581 self
.assertEqual(len(res_user
), 1, "Could not find (&(cn=ldaptestUSer2)(objectClass=user))")
2583 self
.assertEqual(str(res_user
[0].dn
), ("CN=ldaptestuser2,CN=Users," + self
.base_dn
))
2584 self
.assertEqual(str(res_user
[0]["cn"]), "ldaptestuser2")
2585 self
.assertEqual(str(res_user
[0]["name"]), "ldaptestuser2")
2586 self
.assertEqual(list(res_user
[0]["objectClass"]), [b
"top", b
"person", b
"organizationalPerson", b
"user"])
2587 self
.assertTrue("objectSid" in res_user
[0])
2588 self
.assertTrue("objectGUID" in res_user
[0])
2589 self
.assertTrue("whenCreated" in res_user
[0])
2590 self
.assertTrue("nTSecurityDescriptor" in res_user
[0])
2591 self
.assertTrue("allowedAttributes" in res_user
[0])
2592 self
.assertTrue("allowedAttributesEffective" in res_user
[0])
2593 self
.assertEqual(str(res_user
[0]["memberOf"][0]).upper(), ("CN=ldaptestgroup2,CN=Users," + self
.base_dn
).upper())
2595 ldaptestuser2_sid
= res_user
[0]["objectSid"][0]
2596 ldaptestuser2_guid
= res_user
[0]["objectGUID"][0]
2598 attrs
= ["cn", "name", "objectClass", "objectGUID", "objectSID", "whenCreated", "nTSecurityDescriptor", "member", "allowedAttributes", "allowedAttributesEffective"]
2599 # Testing ldb.search for (&(cn=ldaptestgroup2)(objectClass=group))"
2600 res
= ldb
.search(self
.base_dn
, expression
="(&(cn=ldaptestgroup2)(objectClass=group))", scope
=SCOPE_SUBTREE
, attrs
=attrs
)
2601 self
.assertEqual(len(res
), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))")
2603 self
.assertEqual(str(res
[0].dn
), ("CN=ldaptestgroup2,CN=Users," + self
.base_dn
))
2604 self
.assertEqual(str(res
[0]["cn"]), "ldaptestgroup2")
2605 self
.assertEqual(str(res
[0]["name"]), "ldaptestgroup2")
2606 self
.assertEqual(list(res
[0]["objectClass"]), [b
"top", b
"group"])
2607 self
.assertTrue("objectGUID" in res
[0])
2608 self
.assertTrue("objectSid" in res
[0])
2609 self
.assertTrue("whenCreated" in res
[0])
2610 self
.assertTrue("nTSecurityDescriptor" in res
[0])
2611 self
.assertTrue("allowedAttributes" in res
[0])
2612 self
.assertTrue("allowedAttributesEffective" in res
[0])
2614 for m
in res
[0]["member"]:
2615 memberUP
.append(str(m
).upper())
2616 self
.assertTrue(("CN=ldaptestuser2,CN=Users," + self
.base_dn
).upper() in memberUP
)
2618 res
= ldb
.search(self
.base_dn
, expression
="(&(cn=ldaptestgroup2)(objectClass=group))", scope
=SCOPE_SUBTREE
, attrs
=attrs
, controls
=["extended_dn:1:1"])
2619 self
.assertEqual(len(res
), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))")
2621 print(res
[0]["member"])
2623 for m
in res
[0]["member"]:
2624 memberUP
.append(str(m
).upper())
2625 print(("<GUID=" + get_string(ldb
.schema_format_value("objectGUID", ldaptestuser2_guid
)) + ">;<SID=" + get_string(ldb
.schema_format_value("objectSid", ldaptestuser2_sid
)) + ">;CN=ldaptestuser2,CN=Users," + self
.base_dn
).upper())
2627 self
.assertTrue(("<GUID=" + get_string(ldb
.schema_format_value("objectGUID", ldaptestuser2_guid
)) + ">;<SID=" + get_string(ldb
.schema_format_value("objectSid", ldaptestuser2_sid
)) + ">;CN=ldaptestuser2,CN=Users," + self
.base_dn
).upper() in memberUP
)
2629 # Quicktest for linked attributes"
2631 dn: cn=ldaptestgroup2,cn=users,""" + self
.base_dn
+ """
2634 member: CN=ldaptestuser2,CN=Users,""" + self
.base_dn
+ """
2635 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self
.base_dn
+ """
2639 dn: <GUID=""" + get_string(ldb
.schema_format_value("objectGUID", res
[0]["objectGUID"][0])) + """>
2642 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self
.base_dn
+ """
2646 dn: <SID=""" + get_string(ldb
.schema_format_value("objectSid", res
[0]["objectSid"][0])) + """>
2652 dn: cn=ldaptestgroup2,cn=users,""" + self
.base_dn
+ """
2655 member: <GUID=""" + get_string(ldb
.schema_format_value("objectGUID", res
[0]["objectGUID"][0])) + """>
2656 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self
.base_dn
+ """
2660 dn: cn=ldaptestgroup2,cn=users,""" + self
.base_dn
+ """
2666 dn: cn=ldaptestgroup2,cn=users,""" + self
.base_dn
+ """
2669 member: <SID=""" + get_string(ldb
.schema_format_value("objectSid", res_user
[0]["objectSid"][0])) + """>
2670 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self
.base_dn
+ """
2674 dn: cn=ldaptestgroup2,cn=users,""" + self
.base_dn
+ """
2677 member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self
.base_dn
+ """
2680 res
= ldb
.search(self
.base_dn
, expression
="(&(cn=ldaptestgroup2)(objectClass=group))", scope
=SCOPE_SUBTREE
, attrs
=attrs
)
2681 self
.assertEqual(len(res
), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))")
2683 self
.assertEqual(str(res
[0].dn
), ("CN=ldaptestgroup2,CN=Users," + self
.base_dn
))
2684 self
.assertEqual(str(res
[0]["member"][0]), ("CN=ldaptestuser2,CN=Users," + self
.base_dn
))
2685 self
.assertEqual(len(res
[0]["member"]), 1)
2687 ldb
.delete(("CN=ldaptestuser2,CN=Users," + self
.base_dn
))
2691 attrs
= ["cn", "name", "objectClass", "objectGUID", "whenCreated", "nTSecurityDescriptor", "member"]
2692 # Testing ldb.search for (&(cn=ldaptestgroup2)(objectClass=group)) to check linked delete"
2693 res
= ldb
.search(self
.base_dn
, expression
="(&(cn=ldaptestgroup2)(objectClass=group))", scope
=SCOPE_SUBTREE
, attrs
=attrs
)
2694 self
.assertEqual(len(res
), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group)) to check linked delete")
2696 self
.assertEqual(str(res
[0].dn
), ("CN=ldaptestgroup2,CN=Users," + self
.base_dn
))
2697 self
.assertTrue("member" not in res
[0])
2699 # Testing ldb.search for (&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))"
2700 res
= ldb
.search(expression
="(&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
2701 self
.assertEqual(len(res
), 1, "Could not find (&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
2702 res
= ldb
.search(expression
="(&(cn=ldaptestutf8user èùéìòà)(objectclass=user))")
2703 self
.assertEqual(len(res
), 1, "Could not find (&(cn=ldaptestutf8user ÈÙÉÌÒÀ)(objectClass=user))")
2705 self
.assertEqual(str(res
[0].dn
), ("CN=ldaptestutf8user èùéìòà,CN=Users," + self
.base_dn
))
2706 self
.assertEqual(str(res
[0]["cn"]), "ldaptestutf8user èùéìòà")
2707 self
.assertEqual(str(res
[0]["name"]), "ldaptestutf8user èùéìòà")
2708 self
.assertEqual(list(res
[0]["objectClass"]), [b
"top", b
"person", b
"organizationalPerson", b
"user"])
2709 self
.assertTrue("objectGUID" in res
[0])
2710 self
.assertTrue("whenCreated" in res
[0])
2712 # delete "ldaptestutf8user"
2713 ldb
.delete(res
[0].dn
)
2715 # Testing ldb.search for (&(cn=ldaptestutf8user2*)(objectClass=user))"
2716 res
= ldb
.search(expression
="(&(cn=ldaptestutf8user2*)(objectClass=user))")
2717 self
.assertEqual(len(res
), 1, "Could not find (&(cn=ldaptestutf8user2*)(objectClass=user))")
2719 # Testing ldb.search for (&(cn=ldaptestutf8user2 ÈÙÉÌÒÀ)(objectClass=user))"
2720 res
= ldb
.search(expression
="(&(cn=ldaptestutf8user2 ÈÙÉÌÒÀ)(objectClass=user))")
2721 self
.assertEqual(len(res
), 1, "Could not find (&(cn=ldaptestutf8user2 ÈÙÉÌÒÀ)(objectClass=user))")
2723 # delete "ldaptestutf8user2 "
2724 ldb
.delete(res
[0].dn
)
2726 ldb
.delete(("CN=ldaptestgroup2,CN=Users," + self
.base_dn
))
2728 # Testing that we can't get at the configuration DN from the main search base"
2729 res
= ldb
.search(self
.base_dn
, expression
="objectClass=crossRef", scope
=SCOPE_SUBTREE
, attrs
=["cn"])
2730 self
.assertEqual(len(res
), 0)
2732 # 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"
2733 res
= ldb
.search(self
.base_dn
, expression
="objectClass=crossRef", scope
=SCOPE_SUBTREE
, attrs
=["cn"], controls
=["search_options:1:2"])
2734 self
.assertTrue(len(res
) > 0)
2736 if gc_ldb
is not None:
2737 # Testing that we can get at the configuration DN from the main search base on the GC port with the search_options control == 0"
2739 res
= gc_ldb
.search(self
.base_dn
, expression
="objectClass=crossRef", scope
=SCOPE_SUBTREE
, attrs
=["cn"], controls
=["search_options:1:0"])
2740 self
.assertTrue(len(res
) > 0)
2742 # Testing that we do find configuration elements in the global catlog"
2743 res
= gc_ldb
.search(self
.base_dn
, expression
="objectClass=crossRef", scope
=SCOPE_SUBTREE
, attrs
=["cn"])
2744 self
.assertTrue(len(res
) > 0)
2746 # Testing that we do find configuration elements and user elements at the same time"
2747 res
= gc_ldb
.search(self
.base_dn
, expression
="(|(objectClass=crossRef)(objectClass=person))", scope
=SCOPE_SUBTREE
, attrs
=["cn"])
2748 self
.assertTrue(len(res
) > 0)
2750 # Testing that we do find configuration elements in the global catlog, with the configuration basedn"
2751 res
= gc_ldb
.search(self
.configuration_dn
, expression
="objectClass=crossRef", scope
=SCOPE_SUBTREE
, attrs
=["cn"])
2752 self
.assertTrue(len(res
) > 0)
2754 # Testing that we can get at the configuration DN on the main LDAP port"
2755 res
= ldb
.search(self
.configuration_dn
, expression
="objectClass=crossRef", scope
=SCOPE_SUBTREE
, attrs
=["cn"])
2756 self
.assertTrue(len(res
) > 0)
2758 # Testing objectCategory canonicalisation"
2759 res
= ldb
.search(self
.configuration_dn
, expression
="objectCategory=ntDsDSA", scope
=SCOPE_SUBTREE
, attrs
=["cn"])
2760 self
.assertTrue(len(res
) > 0, "Didn't find any records with objectCategory=ntDsDSA")
2761 self
.assertTrue(len(res
) != 0)
2763 res
= ldb
.search(self
.configuration_dn
, expression
="objectCategory=CN=ntDs-DSA," + self
.schema_dn
, scope
=SCOPE_SUBTREE
, attrs
=["cn"])
2764 self
.assertTrue(len(res
) > 0, "Didn't find any records with objectCategory=CN=ntDs-DSA," + self
.schema_dn
)
2765 self
.assertTrue(len(res
) != 0)
2767 # Testing objectClass attribute order on "+ self.base_dn
2768 res
= ldb
.search(expression
="objectClass=domain", base
=self
.base_dn
,
2769 scope
=SCOPE_BASE
, attrs
=["objectClass"])
2770 self
.assertEqual(len(res
), 1)
2772 self
.assertEqual(list(res
[0]["objectClass"]), [b
"top", b
"domain", b
"domainDNS"])
2776 # Testing ldb.search for objectCategory=person"
2777 res
= ldb
.search(self
.base_dn
, expression
="objectCategory=person", scope
=SCOPE_SUBTREE
, attrs
=["cn"])
2778 self
.assertTrue(len(res
) > 0)
2780 # Testing ldb.search for objectCategory=person with domain scope control"
2781 res
= ldb
.search(self
.base_dn
, expression
="objectCategory=person", scope
=SCOPE_SUBTREE
, attrs
=["cn"], controls
=["domain_scope:1"])
2782 self
.assertTrue(len(res
) > 0)
2784 # Testing ldb.search for objectCategory=user"
2785 res
= ldb
.search(self
.base_dn
, expression
="objectCategory=user", scope
=SCOPE_SUBTREE
, attrs
=["cn"])
2786 self
.assertTrue(len(res
) > 0)
2788 # Testing ldb.search for objectCategory=user with domain scope control"
2789 res
= ldb
.search(self
.base_dn
, expression
="objectCategory=user", scope
=SCOPE_SUBTREE
, attrs
=["cn"], controls
=["domain_scope:1"])
2790 self
.assertTrue(len(res
) > 0)
2792 # Testing ldb.search for objectCategory=group"
2793 res
= ldb
.search(self
.base_dn
, expression
="objectCategory=group", scope
=SCOPE_SUBTREE
, attrs
=["cn"])
2794 self
.assertTrue(len(res
) > 0)
2796 # Testing ldb.search for objectCategory=group with domain scope control"
2797 res
= ldb
.search(self
.base_dn
, expression
="objectCategory=group", scope
=SCOPE_SUBTREE
, attrs
=["cn"], controls
=["domain_scope:1"])
2798 self
.assertTrue(len(res
) > 0)
2800 # Testing creating a user with the posixAccount objectClass"
2801 self
.ldb
.add_ldif("""dn: cn=posixuser,CN=Users,%s
2804 objectClass: posixAccount
2806 objectClass: organizationalPerson
2812 homeDirectory: /home/posixuser
2813 loginShell: /bin/bash
2814 gecos: Posix User;;;
2815 description: A POSIX user""" % (self
.base_dn
))
2817 # Testing removing the posixAccount objectClass from an existing user"
2818 self
.ldb
.modify_ldif("""dn: cn=posixuser,CN=Users,%s
2821 objectClass: posixAccount""" % (self
.base_dn
))
2823 # Testing adding the posixAccount objectClass to an existing user"
2824 self
.ldb
.modify_ldif("""dn: cn=posixuser,CN=Users,%s
2827 objectClass: posixAccount""" % (self
.base_dn
))
2829 delete_force(self
.ldb
, "cn=posixuser,cn=users," + self
.base_dn
)
2830 delete_force(self
.ldb
, "cn=ldaptestuser,cn=users," + self
.base_dn
)
2831 delete_force(self
.ldb
, "cn=ldaptestuser2,cn=users," + self
.base_dn
)
2832 delete_force(self
.ldb
, "cn=ldaptestuser3,cn=users," + self
.base_dn
)
2833 delete_force(self
.ldb
, "cn=ldaptestuser4,cn=ldaptestcontainer," + self
.base_dn
)
2834 delete_force(self
.ldb
, "cn=ldaptestuser4,cn=ldaptestcontainer2," + self
.base_dn
)
2835 delete_force(self
.ldb
, "cn=ldaptestuser5,cn=users," + self
.base_dn
)
2836 delete_force(self
.ldb
, "cn=ldaptestgroup,cn=users," + self
.base_dn
)
2837 delete_force(self
.ldb
, "cn=ldaptestgroup2,cn=users," + self
.base_dn
)
2838 delete_force(self
.ldb
, "cn=ldaptestcomputer,cn=computers," + self
.base_dn
)
2839 delete_force(self
.ldb
, "cn=ldaptest2computer,cn=computers," + self
.base_dn
)
2840 delete_force(self
.ldb
, "cn=ldaptestcomputer3,cn=computers," + self
.base_dn
)
2841 delete_force(self
.ldb
, "cn=ldaptestutf8user èùéìòà,cn=users," + self
.base_dn
)
2842 delete_force(self
.ldb
, "cn=ldaptestutf8user2 èùéìòà,cn=users," + self
.base_dn
)
2843 delete_force(self
.ldb
, "cn=ldaptestcontainer," + self
.base_dn
)
2844 delete_force(self
.ldb
, "cn=ldaptestcontainer2," + self
.base_dn
)
2846 def test_security_descriptor_add(self
):
2847 """ Testing ldb.add_ldif() for nTSecurityDescriptor """
2848 user_name
= "testdescriptoruser1"
2849 user_dn
= "CN=%s,CN=Users,%s" % (user_name
, self
.base_dn
)
2851 # Test an empty security descriptor (naturally this shouldn't work)
2853 delete_force(self
.ldb
, user_dn
)
2855 self
.ldb
.add({"dn": user_dn
,
2856 "objectClass": "user",
2857 "sAMAccountName": user_name
,
2858 "nTSecurityDescriptor": []})
2860 except LdbError
as e
:
2862 self
.assertEqual(num
, ERR_CONSTRAINT_VIOLATION
)
2864 delete_force(self
.ldb
, user_dn
)
2866 # Test add_ldif() with SDDL security descriptor input
2869 sddl
= "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2870 self
.ldb
.add_ldif("""
2871 dn: """ + user_dn
+ """
2873 sAMAccountName: """ + user_name
+ """
2874 nTSecurityDescriptor: """ + sddl
)
2875 res
= self
.ldb
.search(base
=user_dn
, attrs
=["nTSecurityDescriptor"])
2876 desc
= res
[0]["nTSecurityDescriptor"][0]
2877 desc
= ndr_unpack(security
.descriptor
, desc
)
2878 desc_sddl
= desc
.as_sddl(self
.domain_sid
)
2879 self
.assertEqual(desc_sddl
, sddl
)
2881 delete_force(self
.ldb
, user_dn
)
2883 # Test add_ldif() with BASE64 security descriptor
2886 sddl
= "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
2887 desc
= security
.descriptor
.from_sddl(sddl
, self
.domain_sid
)
2888 desc_binary
= ndr_pack(desc
)
2889 desc_base64
= base64
.b64encode(desc_binary
).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 desc
= res
[0]["nTSecurityDescriptor"][0]
2897 desc
= ndr_unpack(security
.descriptor
, desc
)
2898 desc_sddl
= desc
.as_sddl(self
.domain_sid
)
2899 self
.assertEqual(desc_sddl
, sddl
)
2901 delete_force(self
.ldb
, user_dn
)
2903 def test_security_descriptor_add_neg(self
):
2904 """Test add_ldif() with BASE64 security descriptor input using WRONG domain SID
2907 user_name
= "testdescriptoruser1"
2908 user_dn
= "CN=%s,CN=Users,%s" % (user_name
, self
.base_dn
)
2909 delete_force(self
.ldb
, user_dn
)
2911 sddl
= "O:DUG:DUD:AI(A;;RPWP;;;AU)S:PAI"
2912 desc
= security
.descriptor
.from_sddl(sddl
, security
.dom_sid('S-1-5-21'))
2913 desc_base64
= base64
.b64encode(ndr_pack(desc
)).decode('utf8')
2914 self
.ldb
.add_ldif("""
2915 dn: """ + user_dn
+ """
2917 sAMAccountName: """ + user_name
+ """
2918 nTSecurityDescriptor:: """ + desc_base64
)
2919 res
= self
.ldb
.search(base
=user_dn
, attrs
=["nTSecurityDescriptor"])
2920 self
.assertTrue("nTSecurityDescriptor" in res
[0])
2921 desc
= res
[0]["nTSecurityDescriptor"][0]
2922 desc
= ndr_unpack(security
.descriptor
, desc
)
2923 desc_sddl
= desc
.as_sddl(self
.domain_sid
)
2924 self
.assertTrue("O:S-1-5-21-513G:S-1-5-21-513D:AI(A;;RPWP;;;AU)" in desc_sddl
)
2926 delete_force(self
.ldb
, user_dn
)
2928 def test_security_descriptor_modify(self
):
2929 """ Testing ldb.modify_ldif() for nTSecurityDescriptor """
2930 user_name
= "testdescriptoruser2"
2931 user_dn
= "CN=%s,CN=Users,%s" % (user_name
, self
.base_dn
)
2933 # Test an empty security descriptor (naturally this shouldn't work)
2935 delete_force(self
.ldb
, user_dn
)
2936 self
.ldb
.add({"dn": user_dn
,
2937 "objectClass": "user",
2938 "sAMAccountName": user_name
})
2941 m
.dn
= Dn(ldb
, user_dn
)
2942 m
["nTSecurityDescriptor"] = MessageElement([], FLAG_MOD_ADD
,
2943 "nTSecurityDescriptor")
2947 except LdbError
as e
:
2949 self
.assertEqual(num
, ERR_CONSTRAINT_VIOLATION
)
2952 m
.dn
= Dn(ldb
, user_dn
)
2953 m
["nTSecurityDescriptor"] = MessageElement([], FLAG_MOD_REPLACE
,
2954 "nTSecurityDescriptor")
2958 except LdbError
as e
:
2960 self
.assertEqual(num
, ERR_UNWILLING_TO_PERFORM
)
2963 m
.dn
= Dn(ldb
, user_dn
)
2964 m
["nTSecurityDescriptor"] = MessageElement([], FLAG_MOD_DELETE
,
2965 "nTSecurityDescriptor")
2969 except LdbError
as e
:
2971 self
.assertEqual(num
, ERR_UNWILLING_TO_PERFORM
)
2973 delete_force(self
.ldb
, user_dn
)
2975 # Test modify_ldif() with SDDL security descriptor input
2976 # Add ACE to the original descriptor test
2979 self
.ldb
.add_ldif("""
2980 dn: """ + user_dn
+ """
2982 sAMAccountName: """ + user_name
)
2984 res
= self
.ldb
.search(base
=user_dn
, attrs
=["nTSecurityDescriptor"])
2985 desc
= res
[0]["nTSecurityDescriptor"][0]
2986 desc
= ndr_unpack(security
.descriptor
, desc
)
2987 desc_sddl
= desc
.as_sddl(self
.domain_sid
)
2988 sddl
= desc_sddl
[:desc_sddl
.find("(")] + "(A;;RPWP;;;AU)" + desc_sddl
[desc_sddl
.find("("):]
2990 dn: """ + user_dn
+ """
2992 replace: nTSecurityDescriptor
2993 nTSecurityDescriptor: """ + sddl
2994 self
.ldb
.modify_ldif(mod
)
2995 # Read modified descriptor
2996 res
= self
.ldb
.search(base
=user_dn
, attrs
=["nTSecurityDescriptor"])
2997 desc
= res
[0]["nTSecurityDescriptor"][0]
2998 desc
= ndr_unpack(security
.descriptor
, desc
)
2999 desc_sddl
= desc
.as_sddl(self
.domain_sid
)
3000 self
.assertEqual(desc_sddl
, sddl
)
3002 delete_force(self
.ldb
, user_dn
)
3004 # Test modify_ldif() with SDDL security descriptor input
3005 # New descriptor test
3008 self
.ldb
.add_ldif("""
3009 dn: """ + user_dn
+ """
3011 sAMAccountName: """ + user_name
)
3013 sddl
= "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
3015 dn: """ + user_dn
+ """
3017 replace: nTSecurityDescriptor
3018 nTSecurityDescriptor: """ + sddl
3019 self
.ldb
.modify_ldif(mod
)
3020 # Read modified descriptor
3021 res
= self
.ldb
.search(base
=user_dn
, attrs
=["nTSecurityDescriptor"])
3022 desc
= res
[0]["nTSecurityDescriptor"][0]
3023 desc
= ndr_unpack(security
.descriptor
, desc
)
3024 desc_sddl
= desc
.as_sddl(self
.domain_sid
)
3025 self
.assertEqual(desc_sddl
, sddl
)
3027 delete_force(self
.ldb
, user_dn
)
3029 # Test modify_ldif() with BASE64 security descriptor input
3030 # Add ACE to the original descriptor test
3033 self
.ldb
.add_ldif("""
3034 dn: """ + user_dn
+ """
3036 sAMAccountName: """ + user_name
)
3038 res
= self
.ldb
.search(base
=user_dn
, attrs
=["nTSecurityDescriptor"])
3039 desc
= res
[0]["nTSecurityDescriptor"][0]
3040 desc
= ndr_unpack(security
.descriptor
, desc
)
3041 desc_sddl
= desc
.as_sddl(self
.domain_sid
)
3042 sddl
= desc_sddl
[:desc_sddl
.find("(")] + "(A;;RPWP;;;AU)" + desc_sddl
[desc_sddl
.find("("):]
3043 desc
= security
.descriptor
.from_sddl(sddl
, self
.domain_sid
)
3044 desc_base64
= base64
.b64encode(ndr_pack(desc
)).decode('utf8')
3046 dn: """ + user_dn
+ """
3048 replace: nTSecurityDescriptor
3049 nTSecurityDescriptor:: """ + desc_base64
3050 self
.ldb
.modify_ldif(mod
)
3051 # Read modified descriptor
3052 res
= self
.ldb
.search(base
=user_dn
, attrs
=["nTSecurityDescriptor"])
3053 desc
= res
[0]["nTSecurityDescriptor"][0]
3054 desc
= ndr_unpack(security
.descriptor
, desc
)
3055 desc_sddl
= desc
.as_sddl(self
.domain_sid
)
3056 self
.assertEqual(desc_sddl
, sddl
)
3058 delete_force(self
.ldb
, user_dn
)
3060 # Test modify_ldif() with BASE64 security descriptor input
3061 # New descriptor test
3064 delete_force(self
.ldb
, user_dn
)
3065 self
.ldb
.add_ldif("""
3066 dn: """ + user_dn
+ """
3068 sAMAccountName: """ + user_name
)
3070 sddl
= "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
3071 desc
= security
.descriptor
.from_sddl(sddl
, self
.domain_sid
)
3072 desc_base64
= base64
.b64encode(ndr_pack(desc
)).decode('utf8')
3074 dn: """ + user_dn
+ """
3076 replace: nTSecurityDescriptor
3077 nTSecurityDescriptor:: """ + desc_base64
3078 self
.ldb
.modify_ldif(mod
)
3079 # Read modified descriptor
3080 res
= self
.ldb
.search(base
=user_dn
, attrs
=["nTSecurityDescriptor"])
3081 desc
= res
[0]["nTSecurityDescriptor"][0]
3082 desc
= ndr_unpack(security
.descriptor
, desc
)
3083 desc_sddl
= desc
.as_sddl(self
.domain_sid
)
3084 self
.assertEqual(desc_sddl
, sddl
)
3086 delete_force(self
.ldb
, user_dn
)
3088 def test_dsheuristics(self
):
3089 """Tests the 'dSHeuristics' attribute"""
3090 # Tests the 'dSHeuristics' attribute"
3092 # Get the current value to restore it later
3093 dsheuristics
= self
.ldb
.get_dsheuristics()
3094 # Perform the length checks: for each decade (except the 0th) we need
3095 # the first index to be the number. This goes till the 9th one, beyond
3096 # there does not seem to be another limitation.
3099 for i
in range(1, 11):
3100 # This is in the range
3101 self
.ldb
.set_dsheuristics(dshstr
+ "x")
3102 self
.ldb
.set_dsheuristics(dshstr
+ "xxxxx")
3103 dshstr
= dshstr
+ "xxxxxxxxx"
3105 # Not anymore in the range, new decade specifier needed
3107 self
.ldb
.set_dsheuristics(dshstr
+ "x")
3109 except LdbError
as e
:
3111 self
.assertEqual(num
, ERR_CONSTRAINT_VIOLATION
)
3112 dshstr
= dshstr
+ str(i
)
3114 # There does not seem to be an upper limit
3115 self
.ldb
.set_dsheuristics(dshstr
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
3116 # apart from the above, all char values are accepted
3117 self
.ldb
.set_dsheuristics("123ABC-+!1asdfg@#^")
3118 self
.assertEqual(self
.ldb
.get_dsheuristics(), b
"123ABC-+!1asdfg@#^")
3121 self
.ldb
.set_dsheuristics(dsheuristics
)
3123 def test_ldapControlReturn(self
):
3124 """Testing that if we request a control that return a control it
3125 really return something"""
3126 res
= self
.ldb
.search(attrs
=["cn"],
3127 controls
=["paged_results:1:10"])
3128 self
.assertEqual(len(res
.controls
), 1)
3129 self
.assertEqual(res
.controls
[0].oid
, "1.2.840.113556.1.4.319")
3130 s
= str(res
.controls
[0])
3132 def test_operational(self
):
3133 """Tests operational attributes"""
3134 # Tests operational attributes"
3136 res
= self
.ldb
.search(self
.base_dn
, scope
=SCOPE_BASE
,
3137 attrs
=["createTimeStamp", "modifyTimeStamp",
3138 "structuralObjectClass", "whenCreated",
3140 self
.assertEqual(len(res
), 1)
3141 self
.assertTrue("createTimeStamp" in res
[0])
3142 self
.assertTrue("modifyTimeStamp" in res
[0])
3143 self
.assertTrue("structuralObjectClass" in res
[0])
3144 self
.assertTrue("whenCreated" in res
[0])
3145 self
.assertTrue("whenChanged" in res
[0])
3147 def test_timevalues1(self
):
3148 """Tests possible syntax of time attributes"""
3150 user_name
= "testtimevaluesuser1"
3151 user_dn
= "CN=%s,CN=Users,%s" % (user_name
, self
.base_dn
)
3153 delete_force(self
.ldb
, user_dn
)
3154 self
.ldb
.add({"dn": user_dn
,
3155 "objectClass": "user",
3156 "sAMAccountName": user_name
})
3159 # We check the following values:
3161 # 370101000000Z => 20370101000000.0Z
3162 # 20370102000000.*Z => 20370102000000.0Z
3164 ext
= ["Z", ".0Z", ".Z", ".000Z", ".RandomIgnoredCharacters...987654321Z"]
3165 for i
in range(0, len(ext
)):
3166 v_raw
= "203701%02d000000" % (i
+ 1)
3168 v_set
= v_raw
[2:] + ext
[i
]
3170 v_set
= v_raw
+ ext
[i
]
3171 v_get
= v_raw
+ ".0Z"
3174 m
.dn
= Dn(ldb
, user_dn
)
3175 m
["msTSExpireDate"] = MessageElement([v_set
],
3180 res
= self
.ldb
.search(base
=user_dn
, scope
=SCOPE_BASE
, attrs
=["msTSExpireDate"])
3181 self
.assertTrue(len(res
) == 1)
3182 self
.assertTrue("msTSExpireDate" in res
[0])
3183 self
.assertTrue(len(res
[0]["msTSExpireDate"]) == 1)
3184 self
.assertEqual(str(res
[0]["msTSExpireDate"][0]), v_get
)
3186 def test_ldapSearchNoAttributes(self
):
3187 """Testing ldap search with no attributes"""
3189 user_name
= "testemptyattributesuser"
3190 user_dn
= "CN=%s,%s" % (user_name
, self
.base_dn
)
3191 delete_force(self
.ldb
, user_dn
)
3193 self
.ldb
.add({"dn": user_dn
,
3194 "objectClass": "user",
3195 "sAMAccountName": user_name
})
3197 res
= self
.ldb
.search(user_dn
, scope
=SCOPE_BASE
, attrs
=[])
3198 delete_force(self
.ldb
, user_dn
)
3200 self
.assertEqual(len(res
), 1)
3201 self
.assertEqual(len(res
[0]), 0)
3204 class BaseDnTests(samba
.tests
.TestCase
):
3207 super(BaseDnTests
, self
).setUp()
3210 def test_rootdse_attrs(self
):
3211 """Testing for all rootDSE attributes"""
3212 res
= self
.ldb
.search("", scope
=SCOPE_BASE
, attrs
=[])
3213 self
.assertEqual(len(res
), 1)
3215 def test_highestcommittedusn(self
):
3216 """Testing for highestCommittedUSN"""
3217 res
= self
.ldb
.search("", scope
=SCOPE_BASE
, attrs
=["highestCommittedUSN"])
3218 self
.assertEqual(len(res
), 1)
3219 self
.assertTrue(int(res
[0]["highestCommittedUSN"][0]) != 0)
3221 def test_netlogon(self
):
3222 """Testing for netlogon via LDAP"""
3223 res
= self
.ldb
.search("", scope
=SCOPE_BASE
, attrs
=["netlogon"])
3224 self
.assertEqual(len(res
), 0)
3226 def test_netlogon_highestcommitted_usn(self
):
3227 """Testing for netlogon and highestCommittedUSN via LDAP"""
3228 res
= self
.ldb
.search("", scope
=SCOPE_BASE
,
3229 attrs
=["netlogon", "highestCommittedUSN"])
3230 self
.assertEqual(len(res
), 0)
3232 def test_namingContexts(self
):
3233 """Testing for namingContexts in rootDSE"""
3234 res
= self
.ldb
.search("", scope
=SCOPE_BASE
,
3235 attrs
=["namingContexts", "defaultNamingContext", "schemaNamingContext", "configurationNamingContext"])
3236 self
.assertEqual(len(res
), 1)
3239 for nc
in res
[0]["namingContexts"]:
3240 self
.assertTrue(nc
not in ncs
)
3243 self
.assertTrue(res
[0]["defaultNamingContext"][0] in ncs
)
3244 self
.assertTrue(res
[0]["configurationNamingContext"][0] in ncs
)
3245 self
.assertTrue(res
[0]["schemaNamingContext"][0] in ncs
)
3247 def test_serverPath(self
):
3248 """Testing the server paths in rootDSE"""
3249 res
= self
.ldb
.search("", scope
=SCOPE_BASE
,
3250 attrs
=["dsServiceName", "serverName"])
3251 self
.assertEqual(len(res
), 1)
3253 self
.assertTrue("CN=Servers" in str(res
[0]["dsServiceName"][0]))
3254 self
.assertTrue("CN=Sites" in str(res
[0]["dsServiceName"][0]))
3255 self
.assertTrue("CN=NTDS Settings" in str(res
[0]["dsServiceName"][0]))
3256 self
.assertTrue("CN=Servers" in str(res
[0]["serverName"][0]))
3257 self
.assertTrue("CN=Sites" in str(res
[0]["serverName"][0]))
3258 self
.assertFalse("CN=NTDS Settings" in str(res
[0]["serverName"][0]))
3260 def test_functionality(self
):
3261 """Testing the server paths in rootDSE"""
3262 res
= self
.ldb
.search("", scope
=SCOPE_BASE
,
3263 attrs
=["forestFunctionality", "domainFunctionality", "domainControllerFunctionality"])
3264 self
.assertEqual(len(res
), 1)
3265 self
.assertEqual(len(res
[0]["forestFunctionality"]), 1)
3266 self
.assertEqual(len(res
[0]["domainFunctionality"]), 1)
3267 self
.assertEqual(len(res
[0]["domainControllerFunctionality"]), 1)
3269 self
.assertTrue(int(res
[0]["forestFunctionality"][0]) <= int(res
[0]["domainFunctionality"][0]))
3270 self
.assertTrue(int(res
[0]["domainControllerFunctionality"][0]) >= int(res
[0]["domainFunctionality"][0]))
3272 res2
= self
.ldb
.search("", scope
=SCOPE_BASE
,
3273 attrs
=["dsServiceName", "serverName"])
3274 self
.assertEqual(len(res2
), 1)
3275 self
.assertEqual(len(res2
[0]["dsServiceName"]), 1)
3277 res3
= self
.ldb
.search(res2
[0]["dsServiceName"][0], scope
=SCOPE_BASE
, attrs
=["msDS-Behavior-Version"])
3278 self
.assertEqual(len(res3
), 1)
3279 self
.assertEqual(len(res3
[0]["msDS-Behavior-Version"]), 1)
3280 self
.assertEqual(int(res
[0]["domainControllerFunctionality"][0]), int(res3
[0]["msDS-Behavior-Version"][0]))
3282 res4
= self
.ldb
.search(ldb
.domain_dn(), scope
=SCOPE_BASE
, attrs
=["msDS-Behavior-Version"])
3283 self
.assertEqual(len(res4
), 1)
3284 self
.assertEqual(len(res4
[0]["msDS-Behavior-Version"]), 1)
3285 self
.assertEqual(int(res
[0]["domainFunctionality"][0]), int(res4
[0]["msDS-Behavior-Version"][0]))
3287 res5
= self
.ldb
.search("cn=partitions,%s" % ldb
.get_config_basedn(), scope
=SCOPE_BASE
, attrs
=["msDS-Behavior-Version"])
3288 self
.assertEqual(len(res5
), 1)
3289 self
.assertEqual(len(res5
[0]["msDS-Behavior-Version"]), 1)
3290 self
.assertEqual(int(res
[0]["forestFunctionality"][0]), int(res5
[0]["msDS-Behavior-Version"][0]))
3292 def test_dnsHostname(self
):
3293 """Testing the DNS hostname in rootDSE"""
3294 res
= self
.ldb
.search("", scope
=SCOPE_BASE
,
3295 attrs
=["dnsHostName", "serverName"])
3296 self
.assertEqual(len(res
), 1)
3298 res2
= self
.ldb
.search(res
[0]["serverName"][0], scope
=SCOPE_BASE
,
3299 attrs
=["dNSHostName"])
3300 self
.assertEqual(len(res2
), 1)
3302 self
.assertEqual(res
[0]["dnsHostName"][0], res2
[0]["dNSHostName"][0])
3304 def test_ldapServiceName(self
):
3305 """Testing the ldap service name in rootDSE"""
3306 res
= self
.ldb
.search("", scope
=SCOPE_BASE
,
3307 attrs
=["ldapServiceName", "dnsHostName"])
3308 self
.assertEqual(len(res
), 1)
3309 self
.assertTrue("ldapServiceName" in res
[0])
3310 self
.assertTrue("dnsHostName" in res
[0])
3312 (hostname
, _
, dns_domainname
) = str(res
[0]["dnsHostName"][0]).partition(".")
3314 given
= str(res
[0]["ldapServiceName"][0])
3315 expected
= "%s:%s$@%s" % (dns_domainname
.lower(), hostname
.lower(), dns_domainname
.upper())
3316 self
.assertEqual(given
, expected
)
3319 if "://" not in host
:
3320 if os
.path
.isfile(host
):
3321 host
= "tdb://%s" % host
3323 host
= "ldap://%s" % host
3325 ldb
= SamDB(host
, credentials
=creds
, session_info
=system_session(lp
), lp
=lp
)
3326 if "tdb://" not in host
:
3327 gc_ldb
= Ldb("%s:3268" % host
, credentials
=creds
,
3328 session_info
=system_session(lp
), lp
=lp
)
3332 TestProgram(module
=__name__
, opts
=subunitopts
)