s4:samldb LDB module - MS-SAMR 3.1.1.8.10 "userAccountControl"
[Samba/bjacke.git] / source4 / dsdb / tests / python / sam.py
blob754096a0157dddc85603df92e3cb6fe711968c55
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 # This is a port of the original in testprogs/ejs/ldap.js
5 import optparse
6 import sys
7 import os
9 sys.path.insert(0, "bin/python")
10 import samba
11 samba.ensure_external_module("testtools", "testtools")
12 samba.ensure_external_module("subunit", "subunit/python")
14 import samba.getopt as options
16 from samba.auth import system_session
17 from ldb import SCOPE_BASE, LdbError
18 from ldb import ERR_NO_SUCH_OBJECT, ERR_ATTRIBUTE_OR_VALUE_EXISTS
19 from ldb import ERR_ENTRY_ALREADY_EXISTS, ERR_UNWILLING_TO_PERFORM
20 from ldb import ERR_OTHER, ERR_NO_SUCH_ATTRIBUTE
21 from ldb import ERR_OBJECT_CLASS_VIOLATION
22 from ldb import ERR_CONSTRAINT_VIOLATION
23 from ldb import ERR_UNDEFINED_ATTRIBUTE_TYPE
24 from ldb import Message, MessageElement, Dn
25 from ldb import FLAG_MOD_ADD, FLAG_MOD_REPLACE, FLAG_MOD_DELETE
26 from samba.samdb import SamDB
27 from samba.dsdb import (UF_NORMAL_ACCOUNT, UF_ACCOUNTDISABLE,
28 UF_WORKSTATION_TRUST_ACCOUNT, UF_SERVER_TRUST_ACCOUNT,
29 UF_PARTIAL_SECRETS_ACCOUNT, UF_TEMP_DUPLICATE_ACCOUNT,
30 UF_PASSWD_NOTREQD, UF_LOCKOUT, UF_PASSWORD_EXPIRED, ATYPE_NORMAL_ACCOUNT,
31 GTYPE_SECURITY_BUILTIN_LOCAL_GROUP, GTYPE_SECURITY_DOMAIN_LOCAL_GROUP,
32 GTYPE_SECURITY_GLOBAL_GROUP, GTYPE_SECURITY_UNIVERSAL_GROUP,
33 GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP, GTYPE_DISTRIBUTION_GLOBAL_GROUP,
34 GTYPE_DISTRIBUTION_UNIVERSAL_GROUP,
35 ATYPE_SECURITY_GLOBAL_GROUP, ATYPE_SECURITY_UNIVERSAL_GROUP,
36 ATYPE_SECURITY_LOCAL_GROUP, ATYPE_DISTRIBUTION_GLOBAL_GROUP,
37 ATYPE_DISTRIBUTION_UNIVERSAL_GROUP, ATYPE_DISTRIBUTION_LOCAL_GROUP,
38 ATYPE_WORKSTATION_TRUST)
39 from samba.dcerpc.security import (DOMAIN_RID_USERS, DOMAIN_RID_ADMINS,
40 DOMAIN_RID_DOMAIN_MEMBERS, DOMAIN_RID_DCS, DOMAIN_RID_READONLY_DCS)
42 from subunit.run import SubunitTestRunner
43 import unittest
45 from samba.dcerpc import security
46 from samba.tests import delete_force
48 parser = optparse.OptionParser("sam.py [options] <host>")
49 sambaopts = options.SambaOptions(parser)
50 parser.add_option_group(sambaopts)
51 parser.add_option_group(options.VersionOptions(parser))
52 # use command line creds if available
53 credopts = options.CredentialsOptions(parser)
54 parser.add_option_group(credopts)
55 opts, args = parser.parse_args()
57 if len(args) < 1:
58 parser.print_usage()
59 sys.exit(1)
61 host = args[0]
63 lp = sambaopts.get_loadparm()
64 creds = credopts.get_credentials(lp)
66 class SamTests(samba.tests.TestCase):
68 def setUp(self):
69 super(SamTests, self).setUp()
70 self.ldb = ldb
71 self.base_dn = ldb.domain_dn()
73 print "baseDN: %s\n" % self.base_dn
75 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
76 delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
77 delete_force(self.ldb, "cn=ldaptest\,specialuser,cn=users," + self.base_dn)
78 delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
79 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
80 delete_force(self.ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
82 def test_users_groups(self):
83 """This tests the SAM users and groups behaviour"""
84 print "Testing users and groups behaviour\n"
86 ldb.add({
87 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
88 "objectclass": "group"})
90 ldb.add({
91 "dn": "cn=ldaptestgroup2,cn=users," + self.base_dn,
92 "objectclass": "group"})
94 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
95 scope=SCOPE_BASE, attrs=["objectSID"])
96 self.assertTrue(len(res1) == 1)
97 group_rid_1 = security.dom_sid(ldb.schema_format_value("objectSID",
98 res1[0]["objectSID"][0])).split()[1]
100 res1 = ldb.search("cn=ldaptestgroup2,cn=users," + self.base_dn,
101 scope=SCOPE_BASE, attrs=["objectSID"])
102 self.assertTrue(len(res1) == 1)
103 group_rid_2 = security.dom_sid(ldb.schema_format_value("objectSID",
104 res1[0]["objectSID"][0])).split()[1]
106 # Try to create a user with an invalid account name
107 try:
108 ldb.add({
109 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
110 "objectclass": "user",
111 "sAMAccountName": "administrator"})
112 self.fail()
113 except LdbError, (num, _):
114 self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
115 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
117 # Try to create a user with an invalid account name
118 try:
119 ldb.add({
120 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
121 "objectclass": "user",
122 "sAMAccountName": []})
123 self.fail()
124 except LdbError, (num, _):
125 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
126 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
128 # Try to create a user with an invalid primary group
129 try:
130 ldb.add({
131 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
132 "objectclass": "user",
133 "primaryGroupID": "0"})
134 self.fail()
135 except LdbError, (num, _):
136 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
137 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
139 # Try to Create a user with a valid primary group
140 try:
141 ldb.add({
142 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
143 "objectclass": "user",
144 "primaryGroupID": str(group_rid_1)})
145 self.fail()
146 except LdbError, (num, _):
147 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
148 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
150 # Test to see how we should behave when the user account doesn't
151 # exist
152 m = Message()
153 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
154 m["primaryGroupID"] = MessageElement("0", FLAG_MOD_REPLACE,
155 "primaryGroupID")
156 try:
157 ldb.modify(m)
158 self.fail()
159 except LdbError, (num, _):
160 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
162 # Test to see how we should behave when the account isn't a user
163 m = Message()
164 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
165 m["primaryGroupID"] = MessageElement("0", FLAG_MOD_REPLACE,
166 "primaryGroupID")
167 try:
168 ldb.modify(m)
169 self.fail()
170 except LdbError, (num, _):
171 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
173 # Test default primary groups on add operations
175 ldb.add({
176 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
177 "objectclass": "user"})
179 res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
180 scope=SCOPE_BASE, attrs=["primaryGroupID"])
181 self.assertTrue(len(res1) == 1)
182 self.assertEquals(res1[0]["primaryGroupID"][0], str(DOMAIN_RID_USERS))
184 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
186 ldb.add({
187 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
188 "objectclass": "user",
189 "userAccountControl": str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD) })
191 res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
192 scope=SCOPE_BASE, attrs=["primaryGroupID"])
193 self.assertTrue(len(res1) == 1)
194 self.assertEquals(res1[0]["primaryGroupID"][0], str(DOMAIN_RID_USERS))
196 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
198 # unfortunately the INTERDOMAIN_TRUST_ACCOUNT case cannot be tested
199 # since such accounts aren't directly creatable (ACCESS_DENIED)
201 ldb.add({
202 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
203 "objectclass": "computer",
204 "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT | UF_PASSWD_NOTREQD) })
206 res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
207 scope=SCOPE_BASE, attrs=["primaryGroupID"])
208 self.assertTrue(len(res1) == 1)
209 self.assertEquals(res1[0]["primaryGroupID"][0], str(DOMAIN_RID_DOMAIN_MEMBERS))
211 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
213 ldb.add({
214 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
215 "objectclass": "computer",
216 "userAccountControl": str(UF_SERVER_TRUST_ACCOUNT | UF_PASSWD_NOTREQD) })
218 res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
219 scope=SCOPE_BASE, attrs=["primaryGroupID"])
220 self.assertTrue(len(res1) == 1)
221 self.assertEquals(res1[0]["primaryGroupID"][0], str(DOMAIN_RID_DCS))
223 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
225 # Read-only DC accounts are only creatable by
226 # UF_WORKSTATION_TRUST_ACCOUNT and work only on DCs >= 2008 (therefore
227 # we have a fallback in the assertion)
228 ldb.add({
229 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
230 "objectclass": "computer",
231 "userAccountControl": str(UF_PARTIAL_SECRETS_ACCOUNT | UF_WORKSTATION_TRUST_ACCOUNT | UF_PASSWD_NOTREQD) })
233 res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
234 scope=SCOPE_BASE, attrs=["primaryGroupID"])
235 self.assertTrue(len(res1) == 1)
236 self.assertTrue(res1[0]["primaryGroupID"][0] == str(DOMAIN_RID_READONLY_DCS) or
237 res1[0]["primaryGroupID"][0] == str(DOMAIN_RID_DOMAIN_MEMBERS))
239 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
241 # Test default primary groups on modify operations
243 ldb.add({
244 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
245 "objectclass": "user"})
247 m = Message()
248 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
249 m["userAccountControl"] = MessageElement(str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD), FLAG_MOD_REPLACE,
250 "userAccountControl")
251 ldb.modify(m)
253 res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
254 scope=SCOPE_BASE, attrs=["primaryGroupID"])
255 self.assertTrue(len(res1) == 1)
256 self.assertEquals(res1[0]["primaryGroupID"][0], str(DOMAIN_RID_USERS))
258 # unfortunately the INTERDOMAIN_TRUST_ACCOUNT case cannot be tested
259 # since such accounts aren't directly creatable (ACCESS_DENIED)
261 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
263 ldb.add({
264 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
265 "objectclass": "computer"})
267 res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
268 scope=SCOPE_BASE, attrs=["primaryGroupID"])
269 self.assertTrue(len(res1) == 1)
270 self.assertEquals(res1[0]["primaryGroupID"][0], str(DOMAIN_RID_USERS))
272 m = Message()
273 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
274 m["userAccountControl"] = MessageElement(str(UF_WORKSTATION_TRUST_ACCOUNT | UF_PASSWD_NOTREQD), FLAG_MOD_REPLACE,
275 "userAccountControl")
276 ldb.modify(m)
278 res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
279 scope=SCOPE_BASE, attrs=["primaryGroupID"])
280 self.assertTrue(len(res1) == 1)
281 self.assertEquals(res1[0]["primaryGroupID"][0], str(DOMAIN_RID_DOMAIN_MEMBERS))
283 m = Message()
284 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
285 m["userAccountControl"] = MessageElement(str(UF_SERVER_TRUST_ACCOUNT | UF_PASSWD_NOTREQD), FLAG_MOD_REPLACE,
286 "userAccountControl")
287 ldb.modify(m)
289 res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
290 scope=SCOPE_BASE, attrs=["primaryGroupID"])
291 self.assertTrue(len(res1) == 1)
292 self.assertEquals(res1[0]["primaryGroupID"][0], str(DOMAIN_RID_DCS))
294 # Read-only DC accounts are only creatable by
295 # UF_WORKSTATION_TRUST_ACCOUNT and work only on DCs >= 2008 (therefore
296 # we have a fallback in the assertion)
297 m = Message()
298 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
299 m["userAccountControl"] = MessageElement(str(UF_PARTIAL_SECRETS_ACCOUNT | UF_WORKSTATION_TRUST_ACCOUNT | UF_PASSWD_NOTREQD), FLAG_MOD_REPLACE,
300 "userAccountControl")
301 ldb.modify(m)
303 res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
304 scope=SCOPE_BASE, attrs=["primaryGroupID"])
305 self.assertTrue(len(res1) == 1)
306 self.assertTrue(res1[0]["primaryGroupID"][0] == str(DOMAIN_RID_READONLY_DCS) or
307 res1[0]["primaryGroupID"][0] == str(DOMAIN_RID_DOMAIN_MEMBERS))
309 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
311 # Recreate account for further tests
313 ldb.add({
314 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
315 "objectclass": "user"})
317 # Try to set an invalid account name
318 m = Message()
319 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
320 m["sAMAccountName"] = MessageElement("administrator", FLAG_MOD_REPLACE,
321 "sAMAccountName")
322 try:
323 ldb.modify(m)
324 self.fail()
325 except LdbError, (num, _):
326 self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
328 # But to reset the actual "sAMAccountName" should still be possible
329 res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
330 scope=SCOPE_BASE, attrs=["sAMAccountName"])
331 self.assertTrue(len(res1) == 1)
332 m = Message()
333 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
334 m["sAMAccountName"] = MessageElement(res1[0]["sAMAccountName"][0], FLAG_MOD_REPLACE,
335 "sAMAccountName")
336 ldb.modify(m)
338 # And another (free) name should be possible as well
339 m = Message()
340 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
341 m["sAMAccountName"] = MessageElement("xxx_ldaptestuser_xxx", FLAG_MOD_REPLACE,
342 "sAMAccountName")
343 ldb.modify(m)
345 # We should be able to reset our actual primary group
346 m = Message()
347 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
348 m["primaryGroupID"] = MessageElement(str(DOMAIN_RID_USERS), FLAG_MOD_REPLACE,
349 "primaryGroupID")
350 ldb.modify(m)
352 # Try to add invalid primary group
353 m = Message()
354 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
355 m["primaryGroupID"] = MessageElement("0", FLAG_MOD_REPLACE,
356 "primaryGroupID")
357 try:
358 ldb.modify(m)
359 self.fail()
360 except LdbError, (num, _):
361 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
363 # Try to make group 1 primary - should be denied since it is not yet
364 # secondary
365 m = Message()
366 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
367 m["primaryGroupID"] = MessageElement(str(group_rid_1),
368 FLAG_MOD_REPLACE, "primaryGroupID")
369 try:
370 ldb.modify(m)
371 self.fail()
372 except LdbError, (num, _):
373 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
375 # Make group 1 secondary
376 m = Message()
377 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
378 m["member"] = MessageElement("cn=ldaptestuser,cn=users," + self.base_dn,
379 FLAG_MOD_REPLACE, "member")
380 ldb.modify(m)
382 # Make group 1 primary
383 m = Message()
384 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
385 m["primaryGroupID"] = MessageElement(str(group_rid_1),
386 FLAG_MOD_REPLACE, "primaryGroupID")
387 ldb.modify(m)
389 # Try to delete group 1 - should be denied
390 try:
391 ldb.delete("cn=ldaptestgroup,cn=users," + self.base_dn)
392 self.fail()
393 except LdbError, (num, _):
394 self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
396 # Try to add group 1 also as secondary - should be denied
397 m = Message()
398 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
399 m["member"] = MessageElement("cn=ldaptestuser,cn=users," + self.base_dn,
400 FLAG_MOD_ADD, "member")
401 try:
402 ldb.modify(m)
403 self.fail()
404 except LdbError, (num, _):
405 self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
407 # Try to add invalid member to group 1 - should be denied
408 m = Message()
409 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
410 m["member"] = MessageElement(
411 "cn=ldaptestuser3,cn=users," + self.base_dn,
412 FLAG_MOD_ADD, "member")
413 try:
414 ldb.modify(m)
415 self.fail()
416 except LdbError, (num, _):
417 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
419 # Make group 2 secondary
420 m = Message()
421 m.dn = Dn(ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
422 m["member"] = MessageElement("cn=ldaptestuser,cn=users," + self.base_dn,
423 FLAG_MOD_ADD, "member")
424 ldb.modify(m)
426 # Swap the groups
427 m = Message()
428 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
429 m["primaryGroupID"] = MessageElement(str(group_rid_2),
430 FLAG_MOD_REPLACE, "primaryGroupID")
431 ldb.modify(m)
433 # Swap the groups (does not really make sense but does the same)
434 m = Message()
435 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
436 m["primaryGroupID"] = MessageElement(str(group_rid_1),
437 FLAG_MOD_REPLACE, "primaryGroupID")
438 m["primaryGroupID"] = MessageElement(str(group_rid_2),
439 FLAG_MOD_REPLACE, "primaryGroupID")
440 ldb.modify(m)
442 # Old primary group should contain a "member" attribute for the user,
443 # the new shouldn't contain anymore one
444 res1 = ldb.search("cn=ldaptestgroup, cn=users," + self.base_dn,
445 scope=SCOPE_BASE, attrs=["member"])
446 self.assertTrue(len(res1) == 1)
447 self.assertTrue(len(res1[0]["member"]) == 1)
448 self.assertEquals(res1[0]["member"][0].lower(),
449 ("cn=ldaptestuser,cn=users," + self.base_dn).lower())
451 res1 = ldb.search("cn=ldaptestgroup2, cn=users," + self.base_dn,
452 scope=SCOPE_BASE, attrs=["member"])
453 self.assertTrue(len(res1) == 1)
454 self.assertFalse("member" in res1[0])
456 # Primary group member
457 m = Message()
458 m.dn = Dn(ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
459 m["member"] = MessageElement("cn=ldaptestuser,cn=users," + self.base_dn,
460 FLAG_MOD_DELETE, "member")
461 try:
462 ldb.modify(m)
463 self.fail()
464 except LdbError, (num, _):
465 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
467 # Delete invalid group member
468 m = Message()
469 m.dn = Dn(ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
470 m["member"] = MessageElement("cn=ldaptestuser1,cn=users," + self.base_dn,
471 FLAG_MOD_DELETE, "member")
472 try:
473 ldb.modify(m)
474 self.fail()
475 except LdbError, (num, _):
476 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
478 # Also this should be denied
479 try:
480 ldb.add({
481 "dn": "cn=ldaptestuser2,cn=users," + self.base_dn,
482 "objectclass": "user",
483 "primaryGroupID": "0"})
484 self.fail()
485 except LdbError, (num, _):
486 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
488 # Recreate user accounts
490 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
492 ldb.add({
493 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
494 "objectclass": "user"})
496 ldb.add({
497 "dn": "cn=ldaptestuser2,cn=users," + self.base_dn,
498 "objectclass": "user"})
500 m = Message()
501 m.dn = Dn(ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
502 m["member"] = MessageElement("cn=ldaptestuser,cn=users," + self.base_dn,
503 FLAG_MOD_ADD, "member")
504 ldb.modify(m)
506 # Already added
507 m = Message()
508 m.dn = Dn(ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
509 m["member"] = MessageElement("cn=ldaptestuser,cn=users," + self.base_dn,
510 FLAG_MOD_ADD, "member")
511 try:
512 ldb.modify(m)
513 self.fail()
514 except LdbError, (num, _):
515 self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
517 # Already added, but as <SID=...>
518 res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
519 scope=SCOPE_BASE, attrs=["objectSid"])
520 self.assertTrue(len(res1) == 1)
521 sid_bin = res1[0]["objectSid"][0]
522 sid_str = ("<SID=" + ldb.schema_format_value("objectSid", sid_bin) + ">").upper()
524 m = Message()
525 m.dn = Dn(ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
526 m["member"] = MessageElement(sid_str, FLAG_MOD_ADD, "member")
527 try:
528 ldb.modify(m)
529 self.fail()
530 except LdbError, (num, _):
531 self.assertEquals(num, ERR_ENTRY_ALREADY_EXISTS)
533 # Invalid member
534 m = Message()
535 m.dn = Dn(ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
536 m["member"] = MessageElement("cn=ldaptestuser1,cn=users," + self.base_dn,
537 FLAG_MOD_REPLACE, "member")
538 try:
539 ldb.modify(m)
540 self.fail()
541 except LdbError, (num, _):
542 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
544 # Invalid member
545 m = Message()
546 m.dn = Dn(ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
547 m["member"] = MessageElement(["cn=ldaptestuser,cn=users," + self.base_dn,
548 "cn=ldaptestuser1,cn=users," + self.base_dn],
549 FLAG_MOD_REPLACE, "member")
550 try:
551 ldb.modify(m)
552 self.fail()
553 except LdbError, (num, _):
554 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
556 # Invalid member
557 m = Message()
558 m.dn = Dn(ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
559 m["member"] = MessageElement("cn=ldaptestuser,cn=users," + self.base_dn,
560 FLAG_MOD_REPLACE, "member")
561 m["member"] = MessageElement("cn=ldaptestuser1,cn=users," + self.base_dn,
562 FLAG_MOD_ADD, "member")
563 try:
564 ldb.modify(m)
565 self.fail()
566 except LdbError, (num, _):
567 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
569 m = Message()
570 m.dn = Dn(ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
571 m["member"] = MessageElement(["cn=ldaptestuser,cn=users," + self.base_dn,
572 "cn=ldaptestuser2,cn=users," + self.base_dn],
573 FLAG_MOD_REPLACE, "member")
574 ldb.modify(m)
576 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
577 delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
578 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
579 delete_force(self.ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn)
581 # Make also a small test for accounts with special DNs ("," in this case)
582 ldb.add({
583 "dn": "cn=ldaptest\,specialuser,cn=users," + self.base_dn,
584 "objectclass": "user"})
585 delete_force(self.ldb, "cn=ldaptest\,specialuser,cn=users," + self.base_dn)
587 def test_sam_attributes(self):
588 """Test the behaviour of special attributes of SAM objects"""
589 print "Testing the behaviour of special attributes of SAM objects\n"""
591 ldb.add({
592 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
593 "objectclass": "user"})
594 ldb.add({
595 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
596 "objectclass": "group"})
598 m = Message()
599 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
600 m["groupType"] = MessageElement(str(GTYPE_SECURITY_GLOBAL_GROUP), FLAG_MOD_ADD,
601 "groupType")
602 try:
603 ldb.modify(m)
604 self.fail()
605 except LdbError, (num, _):
606 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
608 # Delete protection tests
610 for attr in ["nTSecurityDescriptor", "objectSid", "sAMAccountType",
611 "sAMAccountName", "groupType"]:
613 m = Message()
614 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
615 m[attr] = MessageElement([], FLAG_MOD_REPLACE, attr)
616 try:
617 ldb.modify(m)
618 self.fail()
619 except LdbError, (num, _):
620 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
622 m = Message()
623 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
624 m[attr] = MessageElement([], FLAG_MOD_DELETE, attr)
625 try:
626 ldb.modify(m)
627 self.fail()
628 except LdbError, (num, _):
629 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
631 m = Message()
632 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
633 m["primaryGroupID"] = MessageElement("513", FLAG_MOD_ADD,
634 "primaryGroupID")
635 try:
636 ldb.modify(m)
637 self.fail()
638 except LdbError, (num, _):
639 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
641 m = Message()
642 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
643 m["userAccountControl"] = MessageElement(str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD), FLAG_MOD_ADD,
644 "userAccountControl")
645 try:
646 ldb.modify(m)
647 self.fail()
648 except LdbError, (num, _):
649 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
651 m = Message()
652 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
653 m["objectSid"] = MessageElement("xxxxxxxxxxxxxxxx", FLAG_MOD_ADD,
654 "objectSid")
655 try:
656 ldb.modify(m)
657 self.fail()
658 except LdbError, (num, _):
659 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
661 m = Message()
662 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
663 m["sAMAccountType"] = MessageElement("0", FLAG_MOD_ADD,
664 "sAMAccountType")
665 try:
666 ldb.modify(m)
667 self.fail()
668 except LdbError, (num, _):
669 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
671 m = Message()
672 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
673 m["sAMAccountName"] = MessageElement("test", FLAG_MOD_ADD,
674 "sAMAccountName")
675 try:
676 ldb.modify(m)
677 self.fail()
678 except LdbError, (num, _):
679 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
681 # Delete protection tests
683 for attr in ["nTSecurityDescriptor", "objectSid", "sAMAccountType",
684 "sAMAccountName", "primaryGroupID", "userAccountControl",
685 "accountExpires", "badPasswordTime", "badPwdCount",
686 "codePage", "countryCode", "lastLogoff", "lastLogon",
687 "logonCount", "pwdLastSet"]:
689 m = Message()
690 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
691 m[attr] = MessageElement([], FLAG_MOD_REPLACE, attr)
692 try:
693 ldb.modify(m)
694 self.fail()
695 except LdbError, (num, _):
696 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
698 m = Message()
699 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
700 m[attr] = MessageElement([], FLAG_MOD_DELETE, attr)
701 try:
702 ldb.modify(m)
703 self.fail()
704 except LdbError, (num, _):
705 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
707 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
708 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
710 def test_primary_group_token_constructed(self):
711 """Test the primary group token behaviour (hidden-generated-readonly attribute on groups) and some other constructed attributes"""
712 print "Testing primary group token behaviour and other constructed attributes\n"
714 try:
715 ldb.add({
716 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
717 "objectclass": "group",
718 "primaryGroupToken": "100"})
719 self.fail()
720 except LdbError, (num, _):
721 self.assertEquals(num, ERR_UNDEFINED_ATTRIBUTE_TYPE)
722 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
724 ldb.add({
725 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
726 "objectclass": "user"})
728 ldb.add({
729 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
730 "objectclass": "group"})
732 # Testing for one invalid, and one valid operational attribute, but also the things they are built from
733 res1 = ldb.search(self.base_dn,
734 scope=SCOPE_BASE, attrs=["primaryGroupToken", "canonicalName", "objectClass", "objectSid"])
735 self.assertTrue(len(res1) == 1)
736 self.assertFalse("primaryGroupToken" in res1[0])
737 self.assertTrue("canonicalName" in res1[0])
738 self.assertTrue("objectClass" in res1[0])
739 self.assertTrue("objectSid" in res1[0])
741 res1 = ldb.search(self.base_dn,
742 scope=SCOPE_BASE, attrs=["primaryGroupToken", "canonicalName"])
743 self.assertTrue(len(res1) == 1)
744 self.assertFalse("primaryGroupToken" in res1[0])
745 self.assertFalse("objectSid" in res1[0])
746 self.assertFalse("objectClass" in res1[0])
747 self.assertTrue("canonicalName" in res1[0])
749 res1 = ldb.search("cn=users," + self.base_dn,
750 scope=SCOPE_BASE, attrs=["primaryGroupToken"])
751 self.assertTrue(len(res1) == 1)
752 self.assertFalse("primaryGroupToken" in res1[0])
754 res1 = ldb.search("cn=ldaptestuser, cn=users," + self.base_dn,
755 scope=SCOPE_BASE, attrs=["primaryGroupToken"])
756 self.assertTrue(len(res1) == 1)
757 self.assertFalse("primaryGroupToken" in res1[0])
759 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
760 scope=SCOPE_BASE)
761 self.assertTrue(len(res1) == 1)
762 self.assertFalse("primaryGroupToken" in res1[0])
764 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
765 scope=SCOPE_BASE, attrs=["primaryGroupToken", "objectSID"])
766 self.assertTrue(len(res1) == 1)
767 primary_group_token = int(res1[0]["primaryGroupToken"][0])
769 rid = security.dom_sid(ldb.schema_format_value("objectSID", res1[0]["objectSID"][0])).split()[1]
770 self.assertEquals(primary_group_token, rid)
772 m = Message()
773 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
774 m["primaryGroupToken"] = "100"
775 try:
776 ldb.modify(m)
777 self.fail()
778 except LdbError, (num, _):
779 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
781 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
782 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
784 def test_tokenGroups(self):
785 """Test the tokenGroups behaviour (hidden-generated-readonly attribute on SAM objects)"""
786 print "Testing tokenGroups behaviour\n"
788 # The domain object shouldn't contain any "tokenGroups" entry
789 res = ldb.search(self.base_dn, scope=SCOPE_BASE, attrs=["tokenGroups"])
790 self.assertTrue(len(res) == 1)
791 self.assertFalse("tokenGroups" in res[0])
793 # The domain administrator should contain "tokenGroups" entries
794 # (the exact number depends on the domain/forest function level and the
795 # DC software versions)
796 res = ldb.search("cn=Administrator,cn=Users," + self.base_dn,
797 scope=SCOPE_BASE, attrs=["tokenGroups"])
798 self.assertTrue(len(res) == 1)
799 self.assertTrue("tokenGroups" in res[0])
801 ldb.add({
802 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
803 "objectclass": "user"})
805 # This testuser should contain at least two "tokenGroups" entries
806 # (exactly two on an unmodified "Domain Users" and "Users" group)
807 res = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
808 scope=SCOPE_BASE, attrs=["tokenGroups"])
809 self.assertTrue(len(res) == 1)
810 self.assertTrue(len(res[0]["tokenGroups"]) >= 2)
812 # one entry which we need to find should point to domains "Domain Users"
813 # group and another entry should point to the builtin "Users"group
814 domain_users_group_found = False
815 users_group_found = False
816 for sid in res[0]["tokenGroups"]:
817 rid = security.dom_sid(ldb.schema_format_value("objectSID", sid)).split()[1]
818 if rid == 513:
819 domain_users_group_found = True
820 if rid == 545:
821 users_group_found = True
823 self.assertTrue(domain_users_group_found)
824 self.assertTrue(users_group_found)
826 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
828 def test_groupType(self):
829 """Test the groupType behaviour"""
830 print "Testing groupType behaviour\n"
832 # You can never create or change to a
833 # "GTYPE_SECURITY_BUILTIN_LOCAL_GROUP"
835 # Add operation
837 # Invalid attribute
838 try:
839 ldb.add({
840 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
841 "objectclass": "group",
842 "groupType": "0"})
843 self.fail()
844 except LdbError, (num, _):
845 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
846 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
848 try:
849 ldb.add({
850 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
851 "objectclass": "group",
852 "groupType": str(GTYPE_SECURITY_BUILTIN_LOCAL_GROUP)})
853 self.fail()
854 except LdbError, (num, _):
855 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
856 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
858 ldb.add({
859 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
860 "objectclass": "group",
861 "groupType": str(GTYPE_SECURITY_GLOBAL_GROUP)})
863 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
864 scope=SCOPE_BASE, attrs=["sAMAccountType"])
865 self.assertTrue(len(res1) == 1)
866 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
867 ATYPE_SECURITY_GLOBAL_GROUP)
868 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
870 ldb.add({
871 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
872 "objectclass": "group",
873 "groupType": str(GTYPE_SECURITY_UNIVERSAL_GROUP)})
875 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
876 scope=SCOPE_BASE, attrs=["sAMAccountType"])
877 self.assertTrue(len(res1) == 1)
878 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
879 ATYPE_SECURITY_UNIVERSAL_GROUP)
880 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
882 ldb.add({
883 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
884 "objectclass": "group",
885 "groupType": str(GTYPE_SECURITY_DOMAIN_LOCAL_GROUP)})
887 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
888 scope=SCOPE_BASE, attrs=["sAMAccountType"])
889 self.assertTrue(len(res1) == 1)
890 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
891 ATYPE_SECURITY_LOCAL_GROUP)
892 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
894 ldb.add({
895 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
896 "objectclass": "group",
897 "groupType": str(GTYPE_DISTRIBUTION_GLOBAL_GROUP)})
899 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
900 scope=SCOPE_BASE, attrs=["sAMAccountType"])
901 self.assertTrue(len(res1) == 1)
902 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
903 ATYPE_DISTRIBUTION_GLOBAL_GROUP)
904 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
906 ldb.add({
907 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
908 "objectclass": "group",
909 "groupType": str(GTYPE_DISTRIBUTION_UNIVERSAL_GROUP)})
911 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
912 scope=SCOPE_BASE, attrs=["sAMAccountType"])
913 self.assertTrue(len(res1) == 1)
914 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
915 ATYPE_DISTRIBUTION_UNIVERSAL_GROUP)
916 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
918 ldb.add({
919 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
920 "objectclass": "group",
921 "groupType": str(GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP)})
923 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
924 scope=SCOPE_BASE, attrs=["sAMAccountType"])
925 self.assertTrue(len(res1) == 1)
926 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
927 ATYPE_DISTRIBUTION_LOCAL_GROUP)
928 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
930 # Modify operation
932 ldb.add({
933 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
934 "objectclass": "group"})
936 # We can change in this direction: global <-> universal <-> local
937 # On each step also the group type itself (security/distribution) is
938 # variable.
940 # After creation we should have a "security global group"
941 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
942 scope=SCOPE_BASE, attrs=["sAMAccountType"])
943 self.assertTrue(len(res1) == 1)
944 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
945 ATYPE_SECURITY_GLOBAL_GROUP)
947 # Invalid attribute
948 try:
949 m = Message()
950 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
951 m["groupType"] = MessageElement("0",
952 FLAG_MOD_REPLACE, "groupType")
953 ldb.modify(m)
954 self.fail()
955 except LdbError, (num, _):
956 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
958 # Security groups
960 # Default is "global group"
962 m = Message()
963 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
964 m["groupType"] = MessageElement(
965 str(GTYPE_SECURITY_GLOBAL_GROUP),
966 FLAG_MOD_REPLACE, "groupType")
967 ldb.modify(m)
969 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
970 scope=SCOPE_BASE, attrs=["sAMAccountType"])
971 self.assertTrue(len(res1) == 1)
972 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
973 ATYPE_SECURITY_GLOBAL_GROUP)
975 # Change to "local" (shouldn't work)
977 try:
978 m = Message()
979 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
980 m["groupType"] = MessageElement(
981 str(GTYPE_SECURITY_DOMAIN_LOCAL_GROUP),
982 FLAG_MOD_REPLACE, "groupType")
983 ldb.modify(m)
984 self.fail()
985 except LdbError, (num, _):
986 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
988 # Change to "universal"
990 m = Message()
991 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
992 m["groupType"] = MessageElement(
993 str(GTYPE_SECURITY_UNIVERSAL_GROUP),
994 FLAG_MOD_REPLACE, "groupType")
995 ldb.modify(m)
997 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
998 scope=SCOPE_BASE, attrs=["sAMAccountType"])
999 self.assertTrue(len(res1) == 1)
1000 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
1001 ATYPE_SECURITY_UNIVERSAL_GROUP)
1003 # Change back to "global"
1005 m = Message()
1006 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1007 m["groupType"] = MessageElement(
1008 str(GTYPE_SECURITY_GLOBAL_GROUP),
1009 FLAG_MOD_REPLACE, "groupType")
1010 ldb.modify(m)
1012 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
1013 scope=SCOPE_BASE, attrs=["sAMAccountType"])
1014 self.assertTrue(len(res1) == 1)
1015 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
1016 ATYPE_SECURITY_GLOBAL_GROUP)
1018 # Change back to "universal"
1020 m = Message()
1021 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1022 m["groupType"] = MessageElement(
1023 str(GTYPE_SECURITY_UNIVERSAL_GROUP),
1024 FLAG_MOD_REPLACE, "groupType")
1025 ldb.modify(m)
1027 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
1028 scope=SCOPE_BASE, attrs=["sAMAccountType"])
1029 self.assertTrue(len(res1) == 1)
1030 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
1031 ATYPE_SECURITY_UNIVERSAL_GROUP)
1033 # Change to "local"
1035 m = Message()
1036 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1037 m["groupType"] = MessageElement(
1038 str(GTYPE_SECURITY_DOMAIN_LOCAL_GROUP),
1039 FLAG_MOD_REPLACE, "groupType")
1040 ldb.modify(m)
1042 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
1043 scope=SCOPE_BASE, attrs=["sAMAccountType"])
1044 self.assertTrue(len(res1) == 1)
1045 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
1046 ATYPE_SECURITY_LOCAL_GROUP)
1048 # Change to "global" (shouldn't work)
1050 try:
1051 m = Message()
1052 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1053 m["groupType"] = MessageElement(
1054 str(GTYPE_SECURITY_GLOBAL_GROUP),
1055 FLAG_MOD_REPLACE, "groupType")
1056 ldb.modify(m)
1057 self.fail()
1058 except LdbError, (num, _):
1059 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1061 # Change to "builtin local" (shouldn't work)
1063 try:
1064 m = Message()
1065 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1066 m["groupType"] = MessageElement(
1067 str(GTYPE_SECURITY_BUILTIN_LOCAL_GROUP),
1068 FLAG_MOD_REPLACE, "groupType")
1069 ldb.modify(m)
1070 self.fail()
1071 except LdbError, (num, _):
1072 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1074 m = Message()
1075 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1077 # Change back to "universal"
1079 m = Message()
1080 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1081 m["groupType"] = MessageElement(
1082 str(GTYPE_SECURITY_UNIVERSAL_GROUP),
1083 FLAG_MOD_REPLACE, "groupType")
1084 ldb.modify(m)
1086 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
1087 scope=SCOPE_BASE, attrs=["sAMAccountType"])
1088 self.assertTrue(len(res1) == 1)
1089 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
1090 ATYPE_SECURITY_UNIVERSAL_GROUP)
1092 # Change to "builtin local" (shouldn't work)
1094 try:
1095 m = Message()
1096 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1097 m["groupType"] = MessageElement(
1098 str(GTYPE_SECURITY_BUILTIN_LOCAL_GROUP),
1099 FLAG_MOD_REPLACE, "groupType")
1100 ldb.modify(m)
1101 self.fail()
1102 except LdbError, (num, _):
1103 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1105 # Change back to "global"
1107 m = Message()
1108 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1109 m["groupType"] = MessageElement(
1110 str(GTYPE_SECURITY_GLOBAL_GROUP),
1111 FLAG_MOD_REPLACE, "groupType")
1112 ldb.modify(m)
1114 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
1115 scope=SCOPE_BASE, attrs=["sAMAccountType"])
1116 self.assertTrue(len(res1) == 1)
1117 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
1118 ATYPE_SECURITY_GLOBAL_GROUP)
1120 # Change to "builtin local" (shouldn't work)
1122 try:
1123 m = Message()
1124 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1125 m["groupType"] = MessageElement(
1126 str(GTYPE_SECURITY_BUILTIN_LOCAL_GROUP),
1127 FLAG_MOD_REPLACE, "groupType")
1128 ldb.modify(m)
1129 self.fail()
1130 except LdbError, (num, _):
1131 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1133 # Distribution groups
1135 # Default is "global group"
1137 m = Message()
1138 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1139 m["groupType"] = MessageElement(
1140 str(GTYPE_DISTRIBUTION_GLOBAL_GROUP),
1141 FLAG_MOD_REPLACE, "groupType")
1142 ldb.modify(m)
1144 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
1145 scope=SCOPE_BASE, attrs=["sAMAccountType"])
1146 self.assertTrue(len(res1) == 1)
1147 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
1148 ATYPE_DISTRIBUTION_GLOBAL_GROUP)
1150 # Change to local (shouldn't work)
1152 try:
1153 m = Message()
1154 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1155 m["groupType"] = MessageElement(
1156 str(GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP),
1157 FLAG_MOD_REPLACE, "groupType")
1158 ldb.modify(m)
1159 self.fail()
1160 except LdbError, (num, _):
1161 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1163 # Change to "universal"
1165 m = Message()
1166 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1167 m["groupType"] = MessageElement(
1168 str(GTYPE_DISTRIBUTION_UNIVERSAL_GROUP),
1169 FLAG_MOD_REPLACE, "groupType")
1170 ldb.modify(m)
1172 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
1173 scope=SCOPE_BASE, attrs=["sAMAccountType"])
1174 self.assertTrue(len(res1) == 1)
1175 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
1176 ATYPE_DISTRIBUTION_UNIVERSAL_GROUP)
1178 # Change back to "global"
1180 m = Message()
1181 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1182 m["groupType"] = MessageElement(
1183 str(GTYPE_DISTRIBUTION_GLOBAL_GROUP),
1184 FLAG_MOD_REPLACE, "groupType")
1185 ldb.modify(m)
1187 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
1188 scope=SCOPE_BASE, attrs=["sAMAccountType"])
1189 self.assertTrue(len(res1) == 1)
1190 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
1191 ATYPE_DISTRIBUTION_GLOBAL_GROUP)
1193 # Change back to "universal"
1195 m = Message()
1196 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1197 m["groupType"] = MessageElement(
1198 str(GTYPE_DISTRIBUTION_UNIVERSAL_GROUP),
1199 FLAG_MOD_REPLACE, "groupType")
1200 ldb.modify(m)
1202 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
1203 scope=SCOPE_BASE, attrs=["sAMAccountType"])
1204 self.assertTrue(len(res1) == 1)
1205 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
1206 ATYPE_DISTRIBUTION_UNIVERSAL_GROUP)
1208 # Change to "local"
1210 m = Message()
1211 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1212 m["groupType"] = MessageElement(
1213 str(GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP),
1214 FLAG_MOD_REPLACE, "groupType")
1215 ldb.modify(m)
1217 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
1218 scope=SCOPE_BASE, attrs=["sAMAccountType"])
1219 self.assertTrue(len(res1) == 1)
1220 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
1221 ATYPE_DISTRIBUTION_LOCAL_GROUP)
1223 # Change to "global" (shouldn't work)
1225 try:
1226 m = Message()
1227 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1228 m["groupType"] = MessageElement(
1229 str(GTYPE_DISTRIBUTION_GLOBAL_GROUP),
1230 FLAG_MOD_REPLACE, "groupType")
1231 ldb.modify(m)
1232 self.fail()
1233 except LdbError, (num, _):
1234 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1236 # Change back to "universal"
1238 # Try to add invalid member to group 1 - should be denied
1239 m = Message()
1240 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1241 m["member"] = MessageElement(
1242 "cn=ldaptestuser3,cn=users," + self.base_dn,
1243 FLAG_MOD_ADD, "member")
1244 try:
1245 ldb.modify(m)
1246 self.fail()
1247 except LdbError, (num, _):
1248 self.assertEquals(num, ERR_NO_SUCH_OBJECT)
1250 # Make group 2 secondary
1251 m = Message()
1252 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1253 m["groupType"] = MessageElement(
1254 str(GTYPE_DISTRIBUTION_UNIVERSAL_GROUP),
1255 FLAG_MOD_REPLACE, "groupType")
1256 ldb.modify(m)
1258 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
1259 scope=SCOPE_BASE, attrs=["sAMAccountType"])
1260 self.assertTrue(len(res1) == 1)
1261 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
1262 ATYPE_DISTRIBUTION_UNIVERSAL_GROUP)
1264 # Change back to "global"
1266 m = Message()
1267 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1268 m["groupType"] = MessageElement(
1269 str(GTYPE_DISTRIBUTION_GLOBAL_GROUP),
1270 FLAG_MOD_REPLACE, "groupType")
1271 ldb.modify(m)
1273 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
1274 scope=SCOPE_BASE, attrs=["sAMAccountType"])
1275 self.assertTrue(len(res1) == 1)
1276 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
1277 ATYPE_DISTRIBUTION_GLOBAL_GROUP)
1279 # Both group types: this performs only random checks - all possibilities
1280 # would require too much code.
1282 # Default is "global group"
1284 m = Message()
1285 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1286 m["groupType"] = MessageElement(
1287 str(GTYPE_SECURITY_GLOBAL_GROUP),
1288 FLAG_MOD_REPLACE, "groupType")
1289 ldb.modify(m)
1291 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
1292 scope=SCOPE_BASE, attrs=["sAMAccountType"])
1293 self.assertTrue(len(res1) == 1)
1294 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
1295 ATYPE_SECURITY_GLOBAL_GROUP)
1297 # Change to "local" (shouldn't work)
1299 try:
1300 m = Message()
1301 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1302 m["groupType"] = MessageElement(
1303 str(GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP),
1304 FLAG_MOD_REPLACE, "groupType")
1305 ldb.modify(m)
1306 self.fail()
1307 except LdbError, (num, _):
1308 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1310 # Change to "universal"
1312 m = Message()
1313 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1314 m["groupType"] = MessageElement(
1315 str(GTYPE_DISTRIBUTION_UNIVERSAL_GROUP),
1316 FLAG_MOD_REPLACE, "groupType")
1317 ldb.modify(m)
1319 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
1320 scope=SCOPE_BASE, attrs=["sAMAccountType"])
1321 self.assertTrue(len(res1) == 1)
1322 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
1323 ATYPE_DISTRIBUTION_UNIVERSAL_GROUP)
1325 # Change back to "global"
1327 m = Message()
1328 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1329 m["groupType"] = MessageElement(
1330 str(GTYPE_SECURITY_GLOBAL_GROUP),
1331 FLAG_MOD_REPLACE, "groupType")
1332 ldb.modify(m)
1334 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
1335 scope=SCOPE_BASE, attrs=["sAMAccountType"])
1336 self.assertTrue(len(res1) == 1)
1337 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
1338 ATYPE_SECURITY_GLOBAL_GROUP)
1340 # Change back to "universal"
1342 m = Message()
1343 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1344 m["groupType"] = MessageElement(
1345 str(GTYPE_SECURITY_UNIVERSAL_GROUP),
1346 FLAG_MOD_REPLACE, "groupType")
1347 ldb.modify(m)
1349 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
1350 scope=SCOPE_BASE, attrs=["sAMAccountType"])
1351 self.assertTrue(len(res1) == 1)
1352 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
1353 ATYPE_SECURITY_UNIVERSAL_GROUP)
1355 # Change to "local"
1357 m = Message()
1358 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1359 m["groupType"] = MessageElement(
1360 str(GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP),
1361 FLAG_MOD_REPLACE, "groupType")
1362 ldb.modify(m)
1364 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
1365 scope=SCOPE_BASE, attrs=["sAMAccountType"])
1366 self.assertTrue(len(res1) == 1)
1367 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
1368 ATYPE_DISTRIBUTION_LOCAL_GROUP)
1370 # Change to "global" (shouldn't work)
1372 try:
1373 m = Message()
1374 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1375 m["groupType"] = MessageElement(
1376 str(GTYPE_DISTRIBUTION_GLOBAL_GROUP),
1377 FLAG_MOD_REPLACE, "groupType")
1378 ldb.modify(m)
1379 self.fail()
1380 except LdbError, (num, _):
1381 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1383 # Change back to "universal"
1385 m = Message()
1386 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1387 m["groupType"] = MessageElement(
1388 str(GTYPE_SECURITY_UNIVERSAL_GROUP),
1389 FLAG_MOD_REPLACE, "groupType")
1390 ldb.modify(m)
1392 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
1393 scope=SCOPE_BASE, attrs=["sAMAccountType"])
1394 self.assertTrue(len(res1) == 1)
1395 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
1396 ATYPE_SECURITY_UNIVERSAL_GROUP)
1398 # Change back to "global"
1400 m = Message()
1401 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1402 m["groupType"] = MessageElement(
1403 str(GTYPE_SECURITY_GLOBAL_GROUP),
1404 FLAG_MOD_REPLACE, "groupType")
1405 ldb.modify(m)
1407 res1 = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
1408 scope=SCOPE_BASE, attrs=["sAMAccountType"])
1409 self.assertTrue(len(res1) == 1)
1410 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
1411 ATYPE_SECURITY_GLOBAL_GROUP)
1413 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
1415 def test_userAccountControl(self):
1416 """Test the userAccountControl behaviour"""
1417 print "Testing userAccountControl behaviour\n"
1419 # With a user object
1421 # Add operation
1423 # As user you can only set a normal account.
1424 # The UF_PASSWD_NOTREQD flag is needed since we haven't requested a
1425 # password yet.
1426 # With SYSTEM rights you can set a interdomain trust account.
1428 ldb.add({
1429 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1430 "objectclass": "user",
1431 "userAccountControl": "0"})
1433 res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
1434 scope=SCOPE_BASE,
1435 attrs=["sAMAccountType", "userAccountControl"])
1436 self.assertTrue(len(res1) == 1)
1437 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
1438 ATYPE_NORMAL_ACCOUNT)
1439 self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_ACCOUNTDISABLE == 0)
1440 self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_PASSWD_NOTREQD == 0)
1441 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1443 # This has to wait until s4 supports it (needs a password module change)
1444 # try:
1445 # ldb.add({
1446 # "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1447 # "objectclass": "user",
1448 # "userAccountControl": str(UF_NORMAL_ACCOUNT)})
1449 # self.fail()
1450 # except LdbError, (num, _):
1451 # self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1452 # delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1454 ldb.add({
1455 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1456 "objectclass": "user",
1457 "userAccountControl": str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD)})
1459 res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
1460 scope=SCOPE_BASE,
1461 attrs=["sAMAccountType", "userAccountControl"])
1462 self.assertTrue(len(res1) == 1)
1463 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
1464 ATYPE_NORMAL_ACCOUNT)
1465 self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_ACCOUNTDISABLE == 0)
1466 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1468 ldb.add({
1469 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1470 "objectclass": "user",
1471 "userAccountControl": str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_LOCKOUT | UF_PASSWORD_EXPIRED)})
1473 res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
1474 scope=SCOPE_BASE,
1475 attrs=["sAMAccountType", "userAccountControl", "lockoutTime", "pwdLastSet"])
1476 self.assertTrue(len(res1) == 1)
1477 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
1478 ATYPE_NORMAL_ACCOUNT)
1479 self.assertTrue(int(res1[0]["userAccountControl"][0]) & (UF_LOCKOUT | UF_PASSWORD_EXPIRED) == 0)
1480 self.assertFalse("lockoutTime" in res1[0])
1481 self.assertTrue(int(res1[0]["pwdLastSet"][0]) == 0)
1482 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1484 try:
1485 ldb.add({
1486 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1487 "objectclass": "user",
1488 "userAccountControl": str(UF_TEMP_DUPLICATE_ACCOUNT)})
1489 self.fail()
1490 except LdbError, (num, _):
1491 self.assertEquals(num, ERR_OTHER)
1492 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1494 try:
1495 ldb.add({
1496 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1497 "objectclass": "user",
1498 "userAccountControl": str(UF_SERVER_TRUST_ACCOUNT)})
1499 self.fail()
1500 except LdbError, (num, _):
1501 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
1502 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1504 try:
1505 ldb.add({
1506 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1507 "objectclass": "user",
1508 "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT)})
1509 except LdbError, (num, _):
1510 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
1511 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1513 try:
1514 ldb.add({
1515 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1516 "objectclass": "user",
1517 "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT | UF_PARTIAL_SECRETS_ACCOUNT)})
1518 except LdbError, (num, _):
1519 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
1520 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1522 # This isn't supported yet in s4 - needs ACL module adaption
1523 # try:
1524 # ldb.add({
1525 # "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1526 # "objectclass": "user",
1527 # "userAccountControl": str(UF_INTERDOMAIN_TRUST_ACCOUNT)})
1528 # self.fail()
1529 # except LdbError, (num, _):
1530 # self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS)
1531 # delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1533 # Modify operation
1535 ldb.add({
1536 "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
1537 "objectclass": "user"})
1539 # After creation we should have a normal account
1540 res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
1541 scope=SCOPE_BASE,
1542 attrs=["sAMAccountType", "userAccountControl"])
1543 self.assertTrue(len(res1) == 1)
1544 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
1545 ATYPE_NORMAL_ACCOUNT)
1546 self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_ACCOUNTDISABLE != 0)
1548 # As user you can only switch from a normal account to a workstation
1549 # trust account and back.
1550 # The UF_PASSWD_NOTREQD flag is needed since we haven't requested a
1551 # password yet.
1552 # With SYSTEM rights you can switch to a interdomain trust account.
1554 # Invalid attribute
1555 try:
1556 m = Message()
1557 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1558 m["userAccountControl"] = MessageElement("0",
1559 FLAG_MOD_REPLACE, "userAccountControl")
1560 ldb.modify(m)
1561 except LdbError, (num, _):
1562 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1564 # This has to wait until s4 supports it (needs a password module change)
1565 # try:
1566 # m = Message()
1567 # m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1568 # m["userAccountControl"] = MessageElement(
1569 # str(UF_NORMAL_ACCOUNT),
1570 # FLAG_MOD_REPLACE, "userAccountControl")
1571 # ldb.modify(m)
1572 # except LdbError, (num, _):
1573 # self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1575 m = Message()
1576 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1577 m["userAccountControl"] = MessageElement(
1578 str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD),
1579 FLAG_MOD_REPLACE, "userAccountControl")
1580 ldb.modify(m)
1582 res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
1583 scope=SCOPE_BASE,
1584 attrs=["sAMAccountType", "userAccountControl"])
1585 self.assertTrue(len(res1) == 1)
1586 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
1587 ATYPE_NORMAL_ACCOUNT)
1588 self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_ACCOUNTDISABLE == 0)
1590 m = Message()
1591 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1592 m["userAccountControl"] = MessageElement(
1593 str(UF_ACCOUNTDISABLE),
1594 FLAG_MOD_REPLACE, "userAccountControl")
1595 ldb.modify(m)
1597 res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
1598 scope=SCOPE_BASE,
1599 attrs=["sAMAccountType", "userAccountControl"])
1600 self.assertTrue(len(res1) == 1)
1601 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
1602 ATYPE_NORMAL_ACCOUNT)
1603 self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_NORMAL_ACCOUNT != 0)
1604 self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_ACCOUNTDISABLE != 0)
1606 m = Message()
1607 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1608 m["lockoutTime"] = MessageElement(str(samba.unix2nttime(0)), FLAG_MOD_REPLACE, "lockoutTime")
1609 m["pwdLastSet"] = MessageElement(str(samba.unix2nttime(0)), FLAG_MOD_REPLACE, "pwdLastSet")
1610 ldb.modify(m)
1612 m = Message()
1613 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1614 m["userAccountControl"] = MessageElement(
1615 str(UF_LOCKOUT | UF_PASSWORD_EXPIRED),
1616 FLAG_MOD_REPLACE, "userAccountControl")
1617 ldb.modify(m)
1619 res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
1620 scope=SCOPE_BASE,
1621 attrs=["sAMAccountType", "userAccountControl", "lockoutTime", "pwdLastSet"])
1622 self.assertTrue(len(res1) == 1)
1623 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
1624 ATYPE_NORMAL_ACCOUNT)
1625 self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_NORMAL_ACCOUNT != 0)
1626 self.assertTrue(int(res1[0]["userAccountControl"][0]) & (UF_LOCKOUT | UF_PASSWORD_EXPIRED) == 0)
1627 self.assertTrue(int(res1[0]["lockoutTime"][0]) == 0)
1628 self.assertTrue(int(res1[0]["pwdLastSet"][0]) == 0)
1630 try:
1631 m = Message()
1632 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1633 m["userAccountControl"] = MessageElement(
1634 str(UF_TEMP_DUPLICATE_ACCOUNT),
1635 FLAG_MOD_REPLACE, "userAccountControl")
1636 ldb.modify(m)
1637 self.fail()
1638 except LdbError, (num, _):
1639 self.assertEquals(num, ERR_OTHER)
1641 try:
1642 m = Message()
1643 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1644 m["userAccountControl"] = MessageElement(
1645 str(UF_SERVER_TRUST_ACCOUNT),
1646 FLAG_MOD_REPLACE, "userAccountControl")
1647 ldb.modify(m)
1648 self.fail()
1649 except LdbError, (num, _):
1650 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1652 m = Message()
1653 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1654 m["userAccountControl"] = MessageElement(
1655 str(UF_WORKSTATION_TRUST_ACCOUNT),
1656 FLAG_MOD_REPLACE, "userAccountControl")
1657 ldb.modify(m)
1659 try:
1660 m = Message()
1661 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1662 m["userAccountControl"] = MessageElement(
1663 str(UF_WORKSTATION_TRUST_ACCOUNT | UF_PARTIAL_SECRETS_ACCOUNT),
1664 FLAG_MOD_REPLACE, "userAccountControl")
1665 ldb.modify(m)
1666 self.fail()
1667 except LdbError, (num, _):
1668 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1670 res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
1671 scope=SCOPE_BASE, attrs=["sAMAccountType"])
1672 self.assertTrue(len(res1) == 1)
1673 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
1674 ATYPE_WORKSTATION_TRUST)
1676 m = Message()
1677 m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1678 m["userAccountControl"] = MessageElement(
1679 str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD),
1680 FLAG_MOD_REPLACE, "userAccountControl")
1681 ldb.modify(m)
1683 res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
1684 scope=SCOPE_BASE, attrs=["sAMAccountType"])
1685 self.assertTrue(len(res1) == 1)
1686 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
1687 ATYPE_NORMAL_ACCOUNT)
1689 # This isn't supported yet in s4 - needs ACL module adaption
1690 # try:
1691 # m = Message()
1692 # m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
1693 # m["userAccountControl"] = MessageElement(
1694 # str(UF_INTERDOMAIN_TRUST_ACCOUNT),
1695 # FLAG_MOD_REPLACE, "userAccountControl")
1696 # ldb.modify(m)
1697 # self.fail()
1698 # except LdbError, (num, _):
1699 # self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS)
1701 # With a computer object
1703 # Add operation
1705 # As computer you can set a normal account and a server trust account.
1706 # The UF_PASSWD_NOTREQD flag is needed since we haven't requested a
1707 # password yet.
1708 # With SYSTEM rights you can set a interdomain trust account.
1710 ldb.add({
1711 "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
1712 "objectclass": "computer",
1713 "userAccountControl": "0"})
1715 res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
1716 scope=SCOPE_BASE,
1717 attrs=["sAMAccountType", "userAccountControl"])
1718 self.assertTrue(len(res1) == 1)
1719 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
1720 ATYPE_NORMAL_ACCOUNT)
1721 self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_ACCOUNTDISABLE == 0)
1722 self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_PASSWD_NOTREQD == 0)
1723 delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
1725 # This has to wait until s4 supports it (needs a password module change)
1726 # try:
1727 # ldb.add({
1728 # "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
1729 # "objectclass": "computer",
1730 # "userAccountControl": str(UF_NORMAL_ACCOUNT)})
1731 # self.fail()
1732 # except LdbError, (num, _):
1733 # self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1734 # delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
1736 ldb.add({
1737 "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
1738 "objectclass": "computer",
1739 "userAccountControl": str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD)})
1741 res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
1742 scope=SCOPE_BASE,
1743 attrs=["sAMAccountType", "userAccountControl"])
1744 self.assertTrue(len(res1) == 1)
1745 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
1746 ATYPE_NORMAL_ACCOUNT)
1747 self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_ACCOUNTDISABLE == 0)
1748 delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
1750 ldb.add({
1751 "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
1752 "objectclass": "computer",
1753 "userAccountControl": str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_LOCKOUT | UF_PASSWORD_EXPIRED)})
1755 res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
1756 scope=SCOPE_BASE,
1757 attrs=["sAMAccountType", "userAccountControl", "lockoutTime", "pwdLastSet"])
1758 self.assertTrue(len(res1) == 1)
1759 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
1760 ATYPE_NORMAL_ACCOUNT)
1761 self.assertTrue(int(res1[0]["userAccountControl"][0]) & (UF_LOCKOUT | UF_PASSWORD_EXPIRED) == 0)
1762 self.assertFalse("lockoutTime" in res1[0])
1763 self.assertTrue(int(res1[0]["pwdLastSet"][0]) == 0)
1764 delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
1766 try:
1767 ldb.add({
1768 "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
1769 "objectclass": "computer",
1770 "userAccountControl": str(UF_TEMP_DUPLICATE_ACCOUNT)})
1771 self.fail()
1772 except LdbError, (num, _):
1773 self.assertEquals(num, ERR_OTHER)
1774 delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
1776 ldb.add({
1777 "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
1778 "objectclass": "computer",
1779 "userAccountControl": str(UF_SERVER_TRUST_ACCOUNT)})
1781 res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
1782 scope=SCOPE_BASE, attrs=["sAMAccountType"])
1783 self.assertTrue(len(res1) == 1)
1784 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
1785 ATYPE_WORKSTATION_TRUST)
1786 delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
1788 try:
1789 ldb.add({
1790 "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
1791 "objectclass": "computer",
1792 "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT)})
1793 except LdbError, (num, _):
1794 self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
1795 delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
1797 # This isn't supported yet in s4 - needs ACL module adaption
1798 # try:
1799 # ldb.add({
1800 # "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
1801 # "objectclass": "computer",
1802 # "userAccountControl": str(UF_INTERDOMAIN_TRUST_ACCOUNT)})
1803 # self.fail()
1804 # except LdbError, (num, _):
1805 # self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS)
1806 # delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
1808 # Modify operation
1810 ldb.add({
1811 "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
1812 "objectclass": "computer"})
1814 # After creation we should have a normal account
1815 res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
1816 scope=SCOPE_BASE,
1817 attrs=["sAMAccountType", "userAccountControl"])
1818 self.assertTrue(len(res1) == 1)
1819 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
1820 ATYPE_NORMAL_ACCOUNT)
1821 self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_ACCOUNTDISABLE != 0)
1823 # As computer you can switch from a normal account to a workstation
1824 # or server trust account and back (also swapping between trust
1825 # accounts is allowed).
1826 # The UF_PASSWD_NOTREQD flag is needed since we haven't requested a
1827 # password yet.
1828 # With SYSTEM rights you can switch to a interdomain trust account.
1830 # Invalid attribute
1831 try:
1832 m = Message()
1833 m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
1834 m["userAccountControl"] = MessageElement("0",
1835 FLAG_MOD_REPLACE, "userAccountControl")
1836 ldb.modify(m)
1837 except LdbError, (num, _):
1838 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1840 # This has to wait until s4 supports it (needs a password module change)
1841 # try:
1842 # m = Message()
1843 # m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
1844 # m["userAccountControl"] = MessageElement(
1845 # str(UF_NORMAL_ACCOUNT),
1846 # FLAG_MOD_REPLACE, "userAccountControl")
1847 # ldb.modify(m)
1848 # except LdbError, (num, _):
1849 # self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
1851 m = Message()
1852 m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
1853 m["userAccountControl"] = MessageElement(
1854 str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD),
1855 FLAG_MOD_REPLACE, "userAccountControl")
1856 ldb.modify(m)
1858 res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
1859 scope=SCOPE_BASE,
1860 attrs=["sAMAccountType", "userAccountControl"])
1861 self.assertTrue(len(res1) == 1)
1862 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
1863 ATYPE_NORMAL_ACCOUNT)
1864 self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_ACCOUNTDISABLE == 0)
1866 m = Message()
1867 m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
1868 m["userAccountControl"] = MessageElement(
1869 str(UF_ACCOUNTDISABLE),
1870 FLAG_MOD_REPLACE, "userAccountControl")
1871 ldb.modify(m)
1873 res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
1874 scope=SCOPE_BASE,
1875 attrs=["sAMAccountType", "userAccountControl"])
1876 self.assertTrue(len(res1) == 1)
1877 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
1878 ATYPE_NORMAL_ACCOUNT)
1879 self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_NORMAL_ACCOUNT != 0)
1880 self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_ACCOUNTDISABLE != 0)
1882 m = Message()
1883 m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
1884 m["lockoutTime"] = MessageElement(str(samba.unix2nttime(0)), FLAG_MOD_REPLACE, "lockoutTime")
1885 m["pwdLastSet"] = MessageElement(str(samba.unix2nttime(0)), FLAG_MOD_REPLACE, "pwdLastSet")
1886 ldb.modify(m)
1888 m = Message()
1889 m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
1890 m["userAccountControl"] = MessageElement(
1891 str(UF_LOCKOUT | UF_PASSWORD_EXPIRED),
1892 FLAG_MOD_REPLACE, "userAccountControl")
1893 ldb.modify(m)
1895 res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
1896 scope=SCOPE_BASE,
1897 attrs=["sAMAccountType", "userAccountControl", "lockoutTime", "pwdLastSet"])
1898 self.assertTrue(len(res1) == 1)
1899 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
1900 ATYPE_NORMAL_ACCOUNT)
1901 self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_NORMAL_ACCOUNT != 0)
1902 self.assertTrue(int(res1[0]["userAccountControl"][0]) & (UF_LOCKOUT | UF_PASSWORD_EXPIRED) == 0)
1903 self.assertTrue(int(res1[0]["lockoutTime"][0]) == 0)
1904 self.assertTrue(int(res1[0]["pwdLastSet"][0]) == 0)
1906 try:
1907 m = Message()
1908 m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
1909 m["userAccountControl"] = MessageElement(
1910 str(UF_TEMP_DUPLICATE_ACCOUNT),
1911 FLAG_MOD_REPLACE, "userAccountControl")
1912 ldb.modify(m)
1913 self.fail()
1914 except LdbError, (num, _):
1915 self.assertEquals(num, ERR_OTHER)
1917 m = Message()
1918 m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
1919 m["userAccountControl"] = MessageElement(
1920 str(UF_SERVER_TRUST_ACCOUNT),
1921 FLAG_MOD_REPLACE, "userAccountControl")
1922 ldb.modify(m)
1924 res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
1925 scope=SCOPE_BASE, attrs=["sAMAccountType"])
1926 self.assertTrue(len(res1) == 1)
1927 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
1928 ATYPE_WORKSTATION_TRUST)
1930 m = Message()
1931 m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
1932 m["userAccountControl"] = MessageElement(
1933 str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD),
1934 FLAG_MOD_REPLACE, "userAccountControl")
1935 ldb.modify(m)
1937 res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
1938 scope=SCOPE_BASE, attrs=["sAMAccountType"])
1939 self.assertTrue(len(res1) == 1)
1940 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
1941 ATYPE_NORMAL_ACCOUNT)
1943 m = Message()
1944 m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
1945 m["userAccountControl"] = MessageElement(
1946 str(UF_WORKSTATION_TRUST_ACCOUNT),
1947 FLAG_MOD_REPLACE, "userAccountControl")
1948 ldb.modify(m)
1950 res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
1951 scope=SCOPE_BASE, attrs=["sAMAccountType"])
1952 self.assertTrue(len(res1) == 1)
1953 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
1954 ATYPE_WORKSTATION_TRUST)
1956 m = Message()
1957 m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
1958 m["userAccountControl"] = MessageElement(
1959 str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD),
1960 FLAG_MOD_REPLACE, "userAccountControl")
1961 ldb.modify(m)
1963 res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
1964 scope=SCOPE_BASE, attrs=["sAMAccountType"])
1965 self.assertTrue(len(res1) == 1)
1966 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
1967 ATYPE_NORMAL_ACCOUNT)
1969 m = Message()
1970 m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
1971 m["userAccountControl"] = MessageElement(
1972 str(UF_SERVER_TRUST_ACCOUNT),
1973 FLAG_MOD_REPLACE, "userAccountControl")
1974 ldb.modify(m)
1976 res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
1977 scope=SCOPE_BASE, attrs=["sAMAccountType"])
1978 self.assertTrue(len(res1) == 1)
1979 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
1980 ATYPE_WORKSTATION_TRUST)
1982 m = Message()
1983 m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
1984 m["userAccountControl"] = MessageElement(
1985 str(UF_WORKSTATION_TRUST_ACCOUNT),
1986 FLAG_MOD_REPLACE, "userAccountControl")
1987 ldb.modify(m)
1989 res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
1990 scope=SCOPE_BASE, attrs=["sAMAccountType"])
1991 self.assertTrue(len(res1) == 1)
1992 self.assertEquals(int(res1[0]["sAMAccountType"][0]),
1993 ATYPE_WORKSTATION_TRUST)
1995 # This isn't supported yet in s4 - needs ACL module adaption
1996 # try:
1997 # m = Message()
1998 # m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
1999 # m["userAccountControl"] = MessageElement(
2000 # str(UF_INTERDOMAIN_TRUST_ACCOUNT),
2001 # FLAG_MOD_REPLACE, "userAccountControl")
2002 # ldb.modify(m)
2003 # self.fail()
2004 # except LdbError, (num, _):
2005 # self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS)
2007 # "primaryGroupID" does not change if account type remains the same
2009 # For a user account
2011 ldb.add({
2012 "dn": "cn=ldaptestuser2,cn=users," + self.base_dn,
2013 "objectclass": "user",
2014 "userAccountControl": str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE)})
2016 res1 = ldb.search("cn=ldaptestuser2,cn=users," + self.base_dn,
2017 scope=SCOPE_BASE,
2018 attrs=["userAccountControl"])
2019 self.assertTrue(len(res1) == 1)
2020 self.assertEquals(int(res1[0]["userAccountControl"][0]),
2021 UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD | UF_ACCOUNTDISABLE)
2023 m = Message()
2024 m.dn = Dn(ldb, "<SID=" + ldb.get_domain_sid() + "-" + str(DOMAIN_RID_ADMINS) + ">")
2025 m["member"] = MessageElement(
2026 "cn=ldaptestuser2,cn=users," + self.base_dn, FLAG_MOD_ADD, "member")
2027 ldb.modify(m)
2029 m = Message()
2030 m.dn = Dn(ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
2031 m["primaryGroupID"] = MessageElement(str(DOMAIN_RID_ADMINS),
2032 FLAG_MOD_REPLACE, "primaryGroupID")
2033 ldb.modify(m)
2035 m = Message()
2036 m.dn = Dn(ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
2037 m["userAccountControl"] = MessageElement(
2038 str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD),
2039 FLAG_MOD_REPLACE, "userAccountControl")
2040 ldb.modify(m)
2042 res1 = ldb.search("cn=ldaptestuser2,cn=users," + self.base_dn,
2043 scope=SCOPE_BASE,
2044 attrs=["userAccountControl", "primaryGroupID"])
2045 self.assertTrue(len(res1) == 1)
2046 self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_ACCOUNTDISABLE == 0)
2047 self.assertEquals(int(res1[0]["primaryGroupID"][0]), DOMAIN_RID_ADMINS)
2049 # For a workstation account
2051 res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
2052 scope=SCOPE_BASE,
2053 attrs=["primaryGroupID"])
2054 self.assertTrue(len(res1) == 1)
2055 self.assertEquals(int(res1[0]["primaryGroupID"][0]), DOMAIN_RID_DOMAIN_MEMBERS)
2057 m = Message()
2058 m.dn = Dn(ldb, "<SID=" + ldb.get_domain_sid() + "-" + str(DOMAIN_RID_USERS) + ">")
2059 m["member"] = MessageElement(
2060 "cn=ldaptestcomputer,cn=computers," + self.base_dn, FLAG_MOD_ADD, "member")
2061 ldb.modify(m)
2063 m = Message()
2064 m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2065 m["primaryGroupID"] = MessageElement(str(DOMAIN_RID_USERS),
2066 FLAG_MOD_REPLACE, "primaryGroupID")
2067 ldb.modify(m)
2069 m = Message()
2070 m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2071 m["userAccountControl"] = MessageElement(
2072 str(UF_WORKSTATION_TRUST_ACCOUNT),
2073 FLAG_MOD_REPLACE, "userAccountControl")
2074 ldb.modify(m)
2076 res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
2077 scope=SCOPE_BASE,
2078 attrs=["primaryGroupID"])
2079 self.assertTrue(len(res1) == 1)
2080 self.assertEquals(int(res1[0]["primaryGroupID"][0]), DOMAIN_RID_USERS)
2082 delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
2083 delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
2084 delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2086 def test_isCriticalSystemObject(self):
2087 """Test the isCriticalSystemObject behaviour"""
2088 print "Testing isCriticalSystemObject behaviour\n"
2090 # Add tests
2092 ldb.add({
2093 "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
2094 "objectclass": "computer"})
2096 res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
2097 scope=SCOPE_BASE,
2098 attrs=["isCriticalSystemObject"])
2099 self.assertTrue(len(res1) == 1)
2100 self.assertTrue("isCriticalSystemObject" not in res1[0])
2102 delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2104 ldb.add({
2105 "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
2106 "objectclass": "computer",
2107 "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT)})
2109 res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
2110 scope=SCOPE_BASE,
2111 attrs=["isCriticalSystemObject"])
2112 self.assertTrue(len(res1) == 1)
2113 self.assertEquals(res1[0]["isCriticalSystemObject"][0], "FALSE")
2115 delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2117 ldb.add({
2118 "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
2119 "objectclass": "computer",
2120 "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT | UF_PARTIAL_SECRETS_ACCOUNT)})
2122 res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
2123 scope=SCOPE_BASE,
2124 attrs=["isCriticalSystemObject"])
2125 self.assertTrue(len(res1) == 1)
2126 self.assertEquals(res1[0]["isCriticalSystemObject"][0], "TRUE")
2128 delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2130 ldb.add({
2131 "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
2132 "objectclass": "computer",
2133 "userAccountControl": str(UF_SERVER_TRUST_ACCOUNT)})
2135 res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
2136 scope=SCOPE_BASE,
2137 attrs=["isCriticalSystemObject"])
2138 self.assertTrue(len(res1) == 1)
2139 self.assertEquals(res1[0]["isCriticalSystemObject"][0], "TRUE")
2141 # Modification tests
2143 m = Message()
2144 m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2145 m["userAccountControl"] = MessageElement(str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD),
2146 FLAG_MOD_REPLACE, "userAccountControl")
2147 ldb.modify(m)
2149 res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
2150 scope=SCOPE_BASE,
2151 attrs=["isCriticalSystemObject"])
2152 self.assertTrue(len(res1) == 1)
2153 self.assertEquals(res1[0]["isCriticalSystemObject"][0], "TRUE")
2155 m = Message()
2156 m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2157 m["userAccountControl"] = MessageElement(str(UF_WORKSTATION_TRUST_ACCOUNT),
2158 FLAG_MOD_REPLACE, "userAccountControl")
2159 ldb.modify(m)
2161 res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
2162 scope=SCOPE_BASE,
2163 attrs=["isCriticalSystemObject"])
2164 self.assertTrue(len(res1) == 1)
2165 self.assertEquals(res1[0]["isCriticalSystemObject"][0], "FALSE")
2167 m = Message()
2168 m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2169 m["userAccountControl"] = MessageElement(
2170 str(UF_WORKSTATION_TRUST_ACCOUNT | UF_PARTIAL_SECRETS_ACCOUNT),
2171 FLAG_MOD_REPLACE, "userAccountControl")
2172 ldb.modify(m)
2174 res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
2175 scope=SCOPE_BASE,
2176 attrs=["isCriticalSystemObject"])
2177 self.assertTrue(len(res1) == 1)
2178 self.assertEquals(res1[0]["isCriticalSystemObject"][0], "TRUE")
2180 m = Message()
2181 m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2182 m["userAccountControl"] = MessageElement(str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD),
2183 FLAG_MOD_REPLACE, "userAccountControl")
2184 ldb.modify(m)
2186 res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
2187 scope=SCOPE_BASE,
2188 attrs=["isCriticalSystemObject"])
2189 self.assertTrue(len(res1) == 1)
2190 self.assertEquals(res1[0]["isCriticalSystemObject"][0], "TRUE")
2192 m = Message()
2193 m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2194 m["userAccountControl"] = MessageElement(str(UF_SERVER_TRUST_ACCOUNT),
2195 FLAG_MOD_REPLACE, "userAccountControl")
2196 ldb.modify(m)
2198 res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
2199 scope=SCOPE_BASE,
2200 attrs=["isCriticalSystemObject"])
2201 self.assertTrue(len(res1) == 1)
2202 self.assertEquals(res1[0]["isCriticalSystemObject"][0], "TRUE")
2204 m = Message()
2205 m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2206 m["userAccountControl"] = MessageElement(str(UF_WORKSTATION_TRUST_ACCOUNT),
2207 FLAG_MOD_REPLACE, "userAccountControl")
2208 ldb.modify(m)
2210 res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
2211 scope=SCOPE_BASE,
2212 attrs=["isCriticalSystemObject"])
2213 self.assertTrue(len(res1) == 1)
2214 self.assertEquals(res1[0]["isCriticalSystemObject"][0], "FALSE")
2216 delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2218 def test_service_principal_name_updates(self):
2219 """Test the servicePrincipalNames update behaviour"""
2220 print "Testing servicePrincipalNames update behaviour\n"
2222 ldb.add({
2223 "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
2224 "objectclass": "computer",
2225 "dNSHostName": "testname.testdom"})
2227 res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
2228 scope=SCOPE_BASE, attrs=["servicePrincipalName"])
2229 self.assertTrue(len(res) == 1)
2230 self.assertFalse("servicePrincipalName" in res[0])
2232 delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2234 ldb.add({
2235 "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
2236 "objectclass": "computer",
2237 "servicePrincipalName": "HOST/testname.testdom"})
2239 res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
2240 scope=SCOPE_BASE, attrs=["dNSHostName"])
2241 self.assertTrue(len(res) == 1)
2242 self.assertFalse("dNSHostName" in res[0])
2244 delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2246 ldb.add({
2247 "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
2248 "objectclass": "computer",
2249 "dNSHostName": "testname2.testdom",
2250 "servicePrincipalName": "HOST/testname.testdom"})
2252 res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
2253 scope=SCOPE_BASE, attrs=["dNSHostName"])
2254 self.assertTrue(len(res) == 1)
2255 self.assertEquals(res[0]["dNSHostName"][0], "testname2.testdom")
2257 res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
2258 scope=SCOPE_BASE, attrs=["servicePrincipalName"])
2259 self.assertTrue(len(res) == 1)
2260 self.assertEquals(res[0]["servicePrincipalName"][0],
2261 "HOST/testname.testdom")
2263 m = Message()
2264 m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2265 m["dNSHostName"] = MessageElement("testname.testdoM",
2266 FLAG_MOD_REPLACE, "dNSHostName")
2267 ldb.modify(m)
2269 res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
2270 scope=SCOPE_BASE, attrs=["servicePrincipalName"])
2271 self.assertTrue(len(res) == 1)
2272 self.assertEquals(res[0]["servicePrincipalName"][0],
2273 "HOST/testname.testdom")
2275 m = Message()
2276 m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2277 m["dNSHostName"] = MessageElement("testname2.testdom2",
2278 FLAG_MOD_REPLACE, "dNSHostName")
2279 ldb.modify(m)
2281 res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
2282 scope=SCOPE_BASE, attrs=["servicePrincipalName"])
2283 self.assertTrue(len(res) == 1)
2284 self.assertEquals(res[0]["servicePrincipalName"][0],
2285 "HOST/testname2.testdom2")
2287 m = Message()
2288 m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2289 m["dNSHostName"] = MessageElement([],
2290 FLAG_MOD_DELETE, "dNSHostName")
2291 ldb.modify(m)
2293 res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
2294 scope=SCOPE_BASE, attrs=["servicePrincipalName"])
2295 self.assertTrue(len(res) == 1)
2296 self.assertEquals(res[0]["servicePrincipalName"][0],
2297 "HOST/testname2.testdom2")
2299 m = Message()
2300 m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2301 m["dNSHostName"] = MessageElement("testname.testdom3",
2302 FLAG_MOD_REPLACE, "dNSHostName")
2303 ldb.modify(m)
2305 res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
2306 scope=SCOPE_BASE, attrs=["servicePrincipalName"])
2307 self.assertTrue(len(res) == 1)
2308 self.assertEquals(res[0]["servicePrincipalName"][0],
2309 "HOST/testname2.testdom2")
2311 m = Message()
2312 m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2313 m["dNSHostName"] = MessageElement("testname2.testdom2",
2314 FLAG_MOD_REPLACE, "dNSHostName")
2315 ldb.modify(m)
2317 m = Message()
2318 m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2319 m["dNSHostName"] = MessageElement("testname3.testdom3",
2320 FLAG_MOD_REPLACE, "dNSHostName")
2321 m["servicePrincipalName"] = MessageElement("HOST/testname2.testdom2",
2322 FLAG_MOD_REPLACE,
2323 "servicePrincipalName")
2324 ldb.modify(m)
2326 res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
2327 scope=SCOPE_BASE, attrs=["servicePrincipalName"])
2328 self.assertTrue(len(res) == 1)
2329 self.assertEquals(res[0]["servicePrincipalName"][0],
2330 "HOST/testname3.testdom3")
2332 m = Message()
2333 m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2334 m["servicePrincipalName"] = MessageElement("HOST/testname2.testdom2",
2335 FLAG_MOD_REPLACE,
2336 "servicePrincipalName")
2337 m["dNSHostName"] = MessageElement("testname4.testdom4",
2338 FLAG_MOD_REPLACE, "dNSHostName")
2339 ldb.modify(m)
2341 res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
2342 scope=SCOPE_BASE, attrs=["servicePrincipalName"])
2343 self.assertTrue(len(res) == 1)
2344 self.assertEquals(res[0]["servicePrincipalName"][0],
2345 "HOST/testname2.testdom2")
2347 m = Message()
2348 m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2349 m["servicePrincipalName"] = MessageElement([],
2350 FLAG_MOD_DELETE,
2351 "servicePrincipalName")
2352 ldb.modify(m)
2354 m = Message()
2355 m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2356 m["dNSHostName"] = MessageElement("testname2.testdom2",
2357 FLAG_MOD_REPLACE, "dNSHostName")
2358 ldb.modify(m)
2360 res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
2361 scope=SCOPE_BASE, attrs=["servicePrincipalName"])
2362 self.assertTrue(len(res) == 1)
2363 self.assertFalse("servicePrincipalName" in res[0])
2365 delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2367 ldb.add({
2368 "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
2369 "objectclass": "computer",
2370 "sAMAccountName": "testname$"})
2372 res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
2373 scope=SCOPE_BASE, attrs=["servicePrincipalName"])
2374 self.assertTrue(len(res) == 1)
2375 self.assertFalse("servicePrincipalName" in res[0])
2377 delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2379 ldb.add({
2380 "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
2381 "objectclass": "computer",
2382 "servicePrincipalName": "HOST/testname"})
2384 res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
2385 scope=SCOPE_BASE, attrs=["sAMAccountName"])
2386 self.assertTrue(len(res) == 1)
2387 self.assertTrue("sAMAccountName" in res[0])
2389 delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2391 ldb.add({
2392 "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
2393 "objectclass": "computer",
2394 "sAMAccountName": "testname$",
2395 "servicePrincipalName": "HOST/testname"})
2397 res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
2398 scope=SCOPE_BASE, attrs=["sAMAccountName"])
2399 self.assertTrue(len(res) == 1)
2400 self.assertEquals(res[0]["sAMAccountName"][0], "testname$")
2402 res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
2403 scope=SCOPE_BASE, attrs=["servicePrincipalName"])
2404 self.assertTrue(len(res) == 1)
2405 self.assertEquals(res[0]["servicePrincipalName"][0],
2406 "HOST/testname")
2408 m = Message()
2409 m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2410 m["sAMAccountName"] = MessageElement("testnamE$",
2411 FLAG_MOD_REPLACE, "sAMAccountName")
2412 ldb.modify(m)
2414 res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
2415 scope=SCOPE_BASE, attrs=["servicePrincipalName"])
2416 self.assertTrue(len(res) == 1)
2417 self.assertEquals(res[0]["servicePrincipalName"][0],
2418 "HOST/testname")
2420 m = Message()
2421 m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2422 m["sAMAccountName"] = MessageElement("testname",
2423 FLAG_MOD_REPLACE, "sAMAccountName")
2424 ldb.modify(m)
2426 res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
2427 scope=SCOPE_BASE, attrs=["servicePrincipalName"])
2428 self.assertTrue(len(res) == 1)
2429 self.assertEquals(res[0]["servicePrincipalName"][0],
2430 "HOST/testname")
2432 m = Message()
2433 m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2434 m["sAMAccountName"] = MessageElement("test$name$",
2435 FLAG_MOD_REPLACE, "sAMAccountName")
2436 ldb.modify(m)
2438 res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
2439 scope=SCOPE_BASE, attrs=["servicePrincipalName"])
2440 self.assertTrue(len(res) == 1)
2441 self.assertEquals(res[0]["servicePrincipalName"][0],
2442 "HOST/test$name")
2444 m = Message()
2445 m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2446 m["sAMAccountName"] = MessageElement("testname2",
2447 FLAG_MOD_REPLACE, "sAMAccountName")
2448 ldb.modify(m)
2450 res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
2451 scope=SCOPE_BASE, attrs=["servicePrincipalName"])
2452 self.assertTrue(len(res) == 1)
2453 self.assertEquals(res[0]["servicePrincipalName"][0],
2454 "HOST/testname2")
2456 m = Message()
2457 m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2458 m["sAMAccountName"] = MessageElement("testname3",
2459 FLAG_MOD_REPLACE, "sAMAccountName")
2460 m["servicePrincipalName"] = MessageElement("HOST/testname2",
2461 FLAG_MOD_REPLACE,
2462 "servicePrincipalName")
2463 ldb.modify(m)
2465 res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
2466 scope=SCOPE_BASE, attrs=["servicePrincipalName"])
2467 self.assertTrue(len(res) == 1)
2468 self.assertEquals(res[0]["servicePrincipalName"][0],
2469 "HOST/testname3")
2471 m = Message()
2472 m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2473 m["servicePrincipalName"] = MessageElement("HOST/testname2",
2474 FLAG_MOD_REPLACE,
2475 "servicePrincipalName")
2476 m["sAMAccountName"] = MessageElement("testname4",
2477 FLAG_MOD_REPLACE, "sAMAccountName")
2478 ldb.modify(m)
2480 res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
2481 scope=SCOPE_BASE, attrs=["servicePrincipalName"])
2482 self.assertTrue(len(res) == 1)
2483 self.assertEquals(res[0]["servicePrincipalName"][0],
2484 "HOST/testname2")
2486 m = Message()
2487 m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2488 m["servicePrincipalName"] = MessageElement([],
2489 FLAG_MOD_DELETE,
2490 "servicePrincipalName")
2491 ldb.modify(m)
2493 m = Message()
2494 m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2495 m["sAMAccountName"] = MessageElement("testname2",
2496 FLAG_MOD_REPLACE, "sAMAccountName")
2497 ldb.modify(m)
2499 res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
2500 scope=SCOPE_BASE, attrs=["servicePrincipalName"])
2501 self.assertTrue(len(res) == 1)
2502 self.assertFalse("servicePrincipalName" in res[0])
2504 delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2506 ldb.add({
2507 "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
2508 "objectclass": "computer",
2509 "dNSHostName": "testname.testdom",
2510 "sAMAccountName": "testname$",
2511 "servicePrincipalName": [ "HOST/testname.testdom", "HOST/testname" ]
2514 m = Message()
2515 m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2516 m["dNSHostName"] = MessageElement("testname2.testdom",
2517 FLAG_MOD_REPLACE, "dNSHostName")
2518 m["sAMAccountName"] = MessageElement("testname2$",
2519 FLAG_MOD_REPLACE, "sAMAccountName")
2520 ldb.modify(m)
2522 res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
2523 scope=SCOPE_BASE, attrs=["dNSHostName", "sAMAccountName", "servicePrincipalName"])
2524 self.assertTrue(len(res) == 1)
2525 self.assertEquals(res[0]["dNSHostName"][0], "testname2.testdom")
2526 self.assertEquals(res[0]["sAMAccountName"][0], "testname2$")
2527 self.assertTrue(res[0]["servicePrincipalName"][0] == "HOST/testname2" or
2528 res[0]["servicePrincipalName"][1] == "HOST/testname2")
2529 self.assertTrue(res[0]["servicePrincipalName"][0] == "HOST/testname2.testdom" or
2530 res[0]["servicePrincipalName"][1] == "HOST/testname2.testdom")
2532 delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2534 ldb.add({
2535 "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
2536 "objectclass": "computer",
2537 "dNSHostName": "testname.testdom",
2538 "sAMAccountName": "testname$",
2539 "servicePrincipalName": [ "HOST/testname.testdom", "HOST/testname" ]
2542 m = Message()
2543 m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2544 m["sAMAccountName"] = MessageElement("testname2$",
2545 FLAG_MOD_REPLACE, "sAMAccountName")
2546 m["dNSHostName"] = MessageElement("testname2.testdom",
2547 FLAG_MOD_REPLACE, "dNSHostName")
2548 ldb.modify(m)
2550 res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
2551 scope=SCOPE_BASE, attrs=["dNSHostName", "sAMAccountName", "servicePrincipalName"])
2552 self.assertTrue(len(res) == 1)
2553 self.assertEquals(res[0]["dNSHostName"][0], "testname2.testdom")
2554 self.assertEquals(res[0]["sAMAccountName"][0], "testname2$")
2555 self.assertTrue(len(res[0]["servicePrincipalName"]) == 2)
2556 self.assertTrue("HOST/testname2" in res[0]["servicePrincipalName"])
2557 self.assertTrue("HOST/testname2.testdom" in res[0]["servicePrincipalName"])
2559 m = Message()
2560 m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2561 m["servicePrincipalName"] = MessageElement("HOST/testname2.testdom",
2562 FLAG_MOD_ADD, "servicePrincipalName")
2563 try:
2564 ldb.modify(m)
2565 self.fail()
2566 except LdbError, (num, _):
2567 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
2569 m = Message()
2570 m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2571 m["servicePrincipalName"] = MessageElement("HOST/testname3",
2572 FLAG_MOD_ADD, "servicePrincipalName")
2573 ldb.modify(m)
2575 res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
2576 scope=SCOPE_BASE, attrs=["dNSHostName", "sAMAccountName", "servicePrincipalName"])
2577 self.assertTrue(len(res) == 1)
2578 self.assertEquals(res[0]["dNSHostName"][0], "testname2.testdom")
2579 self.assertEquals(res[0]["sAMAccountName"][0], "testname2$")
2580 self.assertTrue(len(res[0]["servicePrincipalName"]) == 3)
2581 self.assertTrue("HOST/testname2" in res[0]["servicePrincipalName"])
2582 self.assertTrue("HOST/testname3" in res[0]["servicePrincipalName"])
2583 self.assertTrue("HOST/testname2.testdom" in res[0]["servicePrincipalName"])
2585 m = Message()
2586 m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2587 m["dNSHostName"] = MessageElement("testname3.testdom",
2588 FLAG_MOD_REPLACE, "dNSHostName")
2589 m["servicePrincipalName"] = MessageElement("HOST/testname3.testdom",
2590 FLAG_MOD_ADD, "servicePrincipalName")
2591 ldb.modify(m)
2593 res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
2594 scope=SCOPE_BASE, attrs=["dNSHostName", "sAMAccountName", "servicePrincipalName"])
2595 self.assertTrue(len(res) == 1)
2596 self.assertEquals(res[0]["dNSHostName"][0], "testname3.testdom")
2597 self.assertEquals(res[0]["sAMAccountName"][0], "testname2$")
2598 self.assertTrue(len(res[0]["servicePrincipalName"]) == 3)
2599 self.assertTrue("HOST/testname2" in res[0]["servicePrincipalName"])
2600 self.assertTrue("HOST/testname3" in res[0]["servicePrincipalName"])
2601 self.assertTrue("HOST/testname3.testdom" in res[0]["servicePrincipalName"])
2603 delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
2605 def test_sam_description_attribute(self):
2606 """Test SAM description attribute"""
2607 print "Test SAM description attribute"""
2609 self.ldb.add({
2610 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
2611 "description": "desc2",
2612 "objectclass": "group",
2613 "description": "desc1"})
2615 res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
2616 scope=SCOPE_BASE, attrs=["description"])
2617 self.assertTrue(len(res) == 1)
2618 self.assertTrue("description" in res[0])
2619 self.assertTrue(len(res[0]["description"]) == 1)
2620 self.assertEquals(res[0]["description"][0], "desc1")
2622 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
2624 self.ldb.add({
2625 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
2626 "objectclass": "group",
2627 "description": ["desc1", "desc2"]})
2629 res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
2630 scope=SCOPE_BASE, attrs=["description"])
2631 self.assertTrue(len(res) == 1)
2632 self.assertTrue("description" in res[0])
2633 self.assertTrue(len(res[0]["description"]) == 2)
2634 self.assertTrue(res[0]["description"][0] == "desc1" or
2635 res[0]["description"][1] == "desc1")
2636 self.assertTrue(res[0]["description"][0] == "desc2" or
2637 res[0]["description"][1] == "desc2")
2639 m = Message()
2640 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
2641 m["description"] = MessageElement(["desc1","desc2"], FLAG_MOD_REPLACE,
2642 "description")
2643 try:
2644 ldb.modify(m)
2645 self.fail()
2646 except LdbError, (num, _):
2647 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
2649 m = Message()
2650 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
2651 m["description"] = MessageElement(["desc1","desc2"], FLAG_MOD_DELETE,
2652 "description")
2653 ldb.modify(m)
2655 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
2657 self.ldb.add({
2658 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
2659 "objectclass": "group" })
2661 m = Message()
2662 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
2663 m["description"] = MessageElement("desc1", FLAG_MOD_REPLACE,
2664 "description")
2665 ldb.modify(m)
2667 res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
2668 scope=SCOPE_BASE, attrs=["description"])
2669 self.assertTrue(len(res) == 1)
2670 self.assertTrue("description" in res[0])
2671 self.assertTrue(len(res[0]["description"]) == 1)
2672 self.assertEquals(res[0]["description"][0], "desc1")
2674 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
2676 self.ldb.add({
2677 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
2678 "objectclass": "group",
2679 "description": ["desc1", "desc2"]})
2681 m = Message()
2682 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
2683 m["description"] = MessageElement("desc1", FLAG_MOD_REPLACE,
2684 "description")
2685 ldb.modify(m)
2687 res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
2688 scope=SCOPE_BASE, attrs=["description"])
2689 self.assertTrue(len(res) == 1)
2690 self.assertTrue("description" in res[0])
2691 self.assertTrue(len(res[0]["description"]) == 1)
2692 self.assertEquals(res[0]["description"][0], "desc1")
2694 m = Message()
2695 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
2696 m["description"] = MessageElement("desc3", FLAG_MOD_ADD,
2697 "description")
2698 try:
2699 ldb.modify(m)
2700 self.fail()
2701 except LdbError, (num, _):
2702 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
2704 m = Message()
2705 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
2706 m["description"] = MessageElement(["desc1","desc2"], FLAG_MOD_DELETE,
2707 "description")
2708 try:
2709 ldb.modify(m)
2710 self.fail()
2711 except LdbError, (num, _):
2712 self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
2714 m = Message()
2715 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
2716 m["description"] = MessageElement("desc1", FLAG_MOD_DELETE,
2717 "description")
2718 ldb.modify(m)
2719 res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
2720 scope=SCOPE_BASE, attrs=["description"])
2721 self.assertTrue(len(res) == 1)
2722 self.assertFalse("description" in res[0])
2724 m = Message()
2725 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
2726 m["description"] = MessageElement(["desc1","desc2"], FLAG_MOD_REPLACE,
2727 "description")
2728 try:
2729 ldb.modify(m)
2730 self.fail()
2731 except LdbError, (num, _):
2732 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
2734 m = Message()
2735 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
2736 m["description"] = MessageElement(["desc3", "desc4"], FLAG_MOD_ADD,
2737 "description")
2738 try:
2739 ldb.modify(m)
2740 self.fail()
2741 except LdbError, (num, _):
2742 self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
2744 m = Message()
2745 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
2746 m["description"] = MessageElement("desc1", FLAG_MOD_ADD,
2747 "description")
2748 ldb.modify(m)
2750 res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
2751 scope=SCOPE_BASE, attrs=["description"])
2752 self.assertTrue(len(res) == 1)
2753 self.assertTrue("description" in res[0])
2754 self.assertTrue(len(res[0]["description"]) == 1)
2755 self.assertEquals(res[0]["description"][0], "desc1")
2757 m = Message()
2758 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
2759 m.add(MessageElement("desc1", FLAG_MOD_DELETE, "description"))
2760 m.add(MessageElement("desc2", FLAG_MOD_ADD, "description"))
2761 ldb.modify(m)
2763 res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
2764 scope=SCOPE_BASE, attrs=["description"])
2765 self.assertTrue(len(res) == 1)
2766 self.assertTrue("description" in res[0])
2767 self.assertTrue(len(res[0]["description"]) == 1)
2768 self.assertEquals(res[0]["description"][0], "desc2")
2770 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
2773 def test_fSMORoleOwner_attribute(self):
2774 """Test fSMORoleOwner attribute"""
2775 print "Test fSMORoleOwner attribute"""
2777 ds_service_name = self.ldb.get_dsServiceName()
2779 # The "fSMORoleOwner" attribute can only be set to "nTDSDSA" entries,
2780 # invalid DNs return ERR_UNWILLING_TO_PERFORM
2782 try:
2783 self.ldb.add({
2784 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
2785 "objectclass": "group",
2786 "fSMORoleOwner": self.base_dn})
2787 self.fail()
2788 except LdbError, (num, _):
2789 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
2791 try:
2792 self.ldb.add({
2793 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
2794 "objectclass": "group",
2795 "fSMORoleOwner": [] })
2796 self.fail()
2797 except LdbError, (num, _):
2798 self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
2800 # We are able to set it to a valid "nTDSDSA" entry if the server is
2801 # capable of handling the role
2803 self.ldb.add({
2804 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
2805 "objectclass": "group",
2806 "fSMORoleOwner": ds_service_name })
2808 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
2810 self.ldb.add({
2811 "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
2812 "objectclass": "group" })
2814 m = Message()
2815 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
2816 m.add(MessageElement(self.base_dn, FLAG_MOD_REPLACE, "fSMORoleOwner"))
2817 try:
2818 ldb.modify(m)
2819 self.fail()
2820 except LdbError, (num, _):
2821 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
2823 m = Message()
2824 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
2825 m.add(MessageElement([], FLAG_MOD_REPLACE, "fSMORoleOwner"))
2826 try:
2827 ldb.modify(m)
2828 self.fail()
2829 except LdbError, (num, _):
2830 self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
2832 # We are able to set it to a valid "nTDSDSA" entry if the server is
2833 # capable of handling the role
2835 m = Message()
2836 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
2837 m.add(MessageElement(ds_service_name, FLAG_MOD_REPLACE, "fSMORoleOwner"))
2838 ldb.modify(m)
2840 # A clean-out works on plain entries, not master (schema, PDC...) DNs
2842 m = Message()
2843 m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
2844 m.add(MessageElement([], FLAG_MOD_DELETE, "fSMORoleOwner"))
2845 ldb.modify(m)
2847 delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
2850 if not "://" in host:
2851 if os.path.isfile(host):
2852 host = "tdb://%s" % host
2853 else:
2854 host = "ldap://%s" % host
2856 ldb = SamDB(host, credentials=creds, session_info=system_session(lp), lp=lp)
2858 runner = SubunitTestRunner()
2859 rc = 0
2860 if not runner.run(unittest.makeSuite(SamTests)).wasSuccessful():
2861 rc = 1
2862 sys.exit(rc)