~lefteris-nikoltsios/+junk/samba-lp1016895

« back to all changes in this revision

Viewing changes to source4/dsdb/tests/python/sam.py

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2011-12-21 13:18:04 UTC
  • mfrom: (0.39.21 sid)
  • Revision ID: package-import@ubuntu.com-20111221131804-xtlr39wx6njehxxr
Tags: 2:3.6.1-3ubuntu1
* Merge from Debian testing.  Remaining changes:
  + debian/patches/VERSION.patch:
    - set SAMBA_VERSION_SUFFIX to Ubuntu.
  + debian/patches/error-trans.fix-276472:
    - Add the translation of Unix Error code -ENOTSUP to NT Error Code
    - NT_STATUS_NOT_SUPPORTED to prevent the Permission denied error.
  + debian/smb.conf:
    - add "(Samba, Ubuntu)" to server string.
    - comment out the default [homes] share, and add a comment about
      "valid users = %S" to show users how to restrict access to
      \\server\username to only username.
    - Set 'usershare allow guests', so that usershare admins are 
      allowed to create public shares in addition to authenticated
      ones.
    - add map to guest = Bad user, maps bad username to guest access.
  + debian/samba-common.config:
    - Do not change priority to high if dhclient3 is installed.
    - Use priority medium instead of high for the workgroup question.
  + debian/control:
    - Don't build against or suggest ctdb.
    - Add dependency on samba-common-bin to samba.
  + Add ufw integration:
    - Created debian/samba.ufw.profile
    - debian/rules, debian/samba.dirs, debian/samba.files: install
      profile
    - debian/control: have samba suggest ufw
  + Add apport hook:
    - Created debian/source_samba.py.
    - debian/rules, debian/samba.dirs, debian/samba-common-bin.files: install
  + Switch to upstart:
    - Add debian/samba.{nmbd,smbd}.upstart.
  + debian/samba.logrotate, debian/samba-common.dhcp, debian/samba.if-up:
    - Make them upstart compatible
  + debian/samba.postinst: 
    - Avoid scary pdbedit warnings on first import.
  + debian/samba-common.postinst: Add more informative error message for
    the case where smb.conf was manually deleted
  + debian/patches/fix-debuglevel-name-conflict.patch: don't use 'debug_level'
    as a global variable name in an NSS module 
  + Dropped:
    - debian/patches/error-trans.fix-276472
    - debian/patches/fix-debuglevel-name-conflict.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python
 
2
# -*- coding: utf-8 -*-
 
3
# This is a port of the original in testprogs/ejs/ldap.js
 
4
 
 
5
import optparse
 
6
import sys
 
7
import os
 
8
 
 
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")
 
13
 
 
14
import samba.getopt as options
 
15
 
 
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, 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_DOMAIN_MEMBERS,
 
40
    DOMAIN_RID_DCS, DOMAIN_RID_READONLY_DCS)
 
41
 
 
42
from subunit.run import SubunitTestRunner
 
43
import unittest
 
44
 
 
45
from samba.dcerpc import security
 
46
from samba.tests import delete_force
 
47
 
 
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()
 
56
 
 
57
if len(args) < 1:
 
58
    parser.print_usage()
 
59
    sys.exit(1)
 
60
 
 
61
host = args[0]
 
62
 
 
63
lp = sambaopts.get_loadparm()
 
64
creds = credopts.get_credentials(lp)
 
65
 
 
66
class SamTests(unittest.TestCase):
 
67
 
 
68
    def setUp(self):
 
69
        super(SamTests, self).setUp()
 
70
        self.ldb = ldb
 
71
        self.base_dn = ldb.domain_dn()
 
72
 
 
73
        print "baseDN: %s\n" % self.base_dn
 
74
 
 
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)
 
81
 
 
82
    def test_users_groups(self):
 
83
        """This tests the SAM users and groups behaviour"""
 
84
        print "Testing users and groups behaviour\n"
 
85
 
 
86
        ldb.add({
 
87
            "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
 
88
            "objectclass": "group"})
 
89
 
 
90
        ldb.add({
 
91
            "dn": "cn=ldaptestgroup2,cn=users," + self.base_dn,
 
92
            "objectclass": "group"})
 
93
 
 
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]
 
99
 
 
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]
 
105
 
 
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)
 
116
 
 
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)
 
127
 
 
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)
 
138
 
 
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)
 
149
 
 
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)
 
161
 
 
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)
 
172
 
 
173
        # Test default primary groups on add operations
 
174
 
 
175
        ldb.add({
 
176
            "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
 
177
            "objectclass": "user"})
 
178
 
 
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))
 
183
 
 
184
        delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
 
185
 
 
186
        ldb.add({
 
187
            "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
 
188
            "objectclass": "user",
 
189
            "userAccountControl": str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD) })
 
190
 
 
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))
 
195
 
 
196
        delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
 
197
 
 
198
        # unfortunately the INTERDOMAIN_TRUST_ACCOUNT case cannot be tested
 
199
        # since such accounts aren't directly creatable (ACCESS_DENIED)
 
200
 
 
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) })
 
205
 
 
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))
 
210
 
 
211
        delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
 
212
 
 
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) })
 
217
 
 
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))
 
222
 
 
223
        delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
 
224
 
 
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) })
 
232
 
 
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))
 
238
 
 
239
        delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
 
240
 
 
241
        # Test default primary groups on modify operations
 
242
 
 
243
        ldb.add({
 
244
            "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
 
245
            "objectclass": "user"})
 
246
 
 
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)
 
252
 
 
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))
 
257
 
 
258
        # unfortunately the INTERDOMAIN_TRUST_ACCOUNT case cannot be tested
 
259
        # since such accounts aren't directly creatable (ACCESS_DENIED)
 
260
 
 
261
        delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
 
262
 
 
263
        ldb.add({
 
264
            "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
 
265
            "objectclass": "computer"})
 
266
 
 
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))
 
271
 
 
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)
 
277
 
 
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))
 
282
 
 
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)
 
288
 
 
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))
 
293
 
 
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)
 
302
 
 
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))
 
308
 
 
309
        delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
 
310
 
 
311
        # Recreate account for further tests
 
312
 
 
313
        ldb.add({
 
314
            "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
 
315
            "objectclass": "user"})
 
316
 
 
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)
 
327
 
 
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)
 
337
 
 
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)
 
344
 
 
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)
 
351
 
 
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)
 
362
 
 
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)
 
374
 
 
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)
 
381
 
 
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)
 
388
 
 
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)
 
395
 
 
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)
 
406
 
 
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)
 
418
 
 
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)
 
425
 
 
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)
 
432
 
 
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)
 
441
 
 
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())
 
450
 
 
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])
 
455
 
 
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)
 
466
 
 
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)
 
477
 
 
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)
 
487
 
 
488
        # Recreate user accounts
 
489
 
 
490
        delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
 
491
 
 
492
        ldb.add({
 
493
            "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
 
494
            "objectclass": "user"})
 
495
 
 
496
        ldb.add({
 
497
            "dn": "cn=ldaptestuser2,cn=users," + self.base_dn,
 
498
            "objectclass": "user"})
 
499
 
 
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)
 
505
 
 
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)
 
516
 
 
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()
 
523
 
 
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)
 
532
 
 
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)
 
543
 
 
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)
 
555
 
 
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)
 
568
 
 
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)
 
575
 
 
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)
 
580
 
 
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)
 
586
 
 
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"""
 
590
 
 
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"})
 
597
 
 
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)
 
607
 
 
608
        # Delete protection tests
 
609
 
 
610
        for attr in ["nTSecurityDescriptor", "objectSid", "sAMAccountType",
 
611
                     "sAMAccountName", "groupType"]:
 
612
 
 
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)
 
621
 
 
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)
 
630
 
 
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)
 
640
 
 
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)
 
650
 
 
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)
 
660
 
 
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)
 
670
 
 
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)
 
680
 
 
681
        # Delete protection tests
 
682
 
 
683
        for attr in ["nTSecurityDescriptor", "objectSid", "sAMAccountType",
 
684
                     "sAMAccountName", "primaryGroupID", "userAccountControl",
 
685
                     "accountExpires", "badPasswordTime", "badPwdCount",
 
686
                     "codePage", "countryCode", "lastLogoff", "lastLogon",
 
687
                     "logonCount", "pwdLastSet"]:
 
688
 
 
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)
 
697
 
 
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)
 
706
 
 
707
        delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
 
708
        delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
 
709
 
 
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"
 
713
 
 
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)
 
723
 
 
724
        ldb.add({
 
725
            "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
 
726
            "objectclass": "user"})
 
727
 
 
728
        ldb.add({
 
729
            "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
 
730
            "objectclass": "group"})
 
731
 
 
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])
 
740
 
 
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])
 
748
 
 
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])
 
753
 
 
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])
 
758
 
 
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])
 
763
 
 
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])
 
768
 
 
769
        rid = security.dom_sid(ldb.schema_format_value("objectSID", res1[0]["objectSID"][0])).split()[1]
 
770
        self.assertEquals(primary_group_token, rid)
 
771
 
 
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)
 
780
 
 
781
        delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
 
782
        delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
 
783
 
 
784
    def test_tokenGroups(self):
 
785
        """Test the tokenGroups behaviour (hidden-generated-readonly attribute on SAM objects)"""
 
786
        print "Testing tokenGroups behaviour\n"
 
787
 
 
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])
 
792
 
 
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])
 
800
 
 
801
        ldb.add({
 
802
            "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
 
803
            "objectclass": "user"})
 
804
 
 
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)
 
811
 
 
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
 
822
 
 
823
        self.assertTrue(domain_users_group_found)
 
824
        self.assertTrue(users_group_found)
 
825
 
 
826
        delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
 
827
 
 
828
    def test_groupType(self):
 
829
        """Test the groupType behaviour"""
 
830
        print "Testing groupType behaviour\n"
 
831
 
 
832
        # You can never create or change to a
 
833
        # "GTYPE_SECURITY_BUILTIN_LOCAL_GROUP"
 
834
 
 
835
        # Add operation
 
836
 
 
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)
 
847
 
 
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)
 
857
 
 
858
        ldb.add({
 
859
            "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
 
860
            "objectclass": "group",
 
861
            "groupType": str(GTYPE_SECURITY_GLOBAL_GROUP)})
 
862
 
 
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)
 
869
 
 
870
        ldb.add({
 
871
            "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
 
872
            "objectclass": "group",
 
873
            "groupType": str(GTYPE_SECURITY_UNIVERSAL_GROUP)})
 
874
 
 
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)
 
881
 
 
882
        ldb.add({
 
883
            "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
 
884
            "objectclass": "group",
 
885
            "groupType": str(GTYPE_SECURITY_DOMAIN_LOCAL_GROUP)})
 
886
 
 
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)
 
893
 
 
894
        ldb.add({
 
895
            "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
 
896
            "objectclass": "group",
 
897
            "groupType": str(GTYPE_DISTRIBUTION_GLOBAL_GROUP)})
 
898
 
 
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)
 
905
 
 
906
        ldb.add({
 
907
            "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
 
908
            "objectclass": "group",
 
909
            "groupType": str(GTYPE_DISTRIBUTION_UNIVERSAL_GROUP)})
 
910
 
 
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)
 
917
 
 
918
        ldb.add({
 
919
            "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
 
920
            "objectclass": "group",
 
921
            "groupType": str(GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP)})
 
922
 
 
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)
 
929
 
 
930
        # Modify operation
 
931
 
 
932
        ldb.add({
 
933
            "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
 
934
            "objectclass": "group"})
 
935
 
 
936
        # We can change in this direction: global <-> universal <-> local
 
937
        # On each step also the group type itself (security/distribution) is
 
938
        # variable.
 
939
 
 
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)
 
946
 
 
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)
 
957
 
 
958
        # Security groups
 
959
 
 
960
        # Default is "global group"
 
961
 
 
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)
 
968
 
 
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)
 
974
 
 
975
        # Change to "local" (shouldn't work)
 
976
 
 
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)
 
987
 
 
988
        # Change to "universal"
 
989
 
 
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)
 
996
 
 
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)
 
1002
 
 
1003
        # Change back to "global"
 
1004
 
 
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)
 
1011
 
 
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)
 
1017
 
 
1018
        # Change back to "universal"
 
1019
 
 
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)
 
1026
 
 
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)
 
1032
 
 
1033
        # Change to "local"
 
1034
 
 
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)
 
1041
 
 
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)
 
1047
 
 
1048
        # Change to "global" (shouldn't work)
 
1049
 
 
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)
 
1060
 
 
1061
        # Change to "builtin local" (shouldn't work)
 
1062
 
 
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)
 
1073
 
 
1074
        m = Message()
 
1075
        m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
 
1076
 
 
1077
        # Change back to "universal"
 
1078
 
 
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)
 
1085
 
 
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)
 
1091
 
 
1092
        # Change to "builtin local" (shouldn't work)
 
1093
 
 
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)
 
1104
 
 
1105
        # Change back to "global"
 
1106
 
 
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)
 
1113
 
 
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)
 
1119
 
 
1120
        # Change to "builtin local" (shouldn't work)
 
1121
 
 
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)
 
1132
 
 
1133
        # Distribution groups
 
1134
 
 
1135
        # Default is "global group"
 
1136
 
 
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)
 
1143
 
 
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)
 
1149
 
 
1150
        # Change to local (shouldn't work)
 
1151
 
 
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)
 
1162
 
 
1163
        # Change to "universal"
 
1164
 
 
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)
 
1171
 
 
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)
 
1177
 
 
1178
        # Change back to "global"
 
1179
 
 
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)
 
1186
 
 
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)
 
1192
 
 
1193
        # Change back to "universal"
 
1194
 
 
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)
 
1201
 
 
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)
 
1207
 
 
1208
        # Change to "local"
 
1209
 
 
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)
 
1216
 
 
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)
 
1222
 
 
1223
        # Change to "global" (shouldn't work)
 
1224
 
 
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)
 
1235
 
 
1236
        # Change back to "universal"
 
1237
 
 
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)
 
1249
 
 
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)
 
1257
 
 
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)
 
1263
 
 
1264
        # Change back to "global"
 
1265
 
 
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)
 
1272
 
 
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)
 
1278
 
 
1279
        # Both group types: this performs only random checks - all possibilities
 
1280
        # would require too much code.
 
1281
 
 
1282
        # Default is "global group"
 
1283
 
 
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)
 
1290
 
 
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)
 
1296
 
 
1297
        # Change to "local" (shouldn't work)
 
1298
 
 
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)
 
1309
 
 
1310
        # Change to "universal"
 
1311
 
 
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)
 
1318
 
 
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)
 
1324
 
 
1325
        # Change back to "global"
 
1326
 
 
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)
 
1333
 
 
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)
 
1339
 
 
1340
        # Change back to "universal"
 
1341
 
 
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)
 
1348
 
 
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)
 
1354
 
 
1355
        # Change to "local"
 
1356
 
 
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)
 
1363
 
 
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)
 
1369
 
 
1370
        # Change to "global" (shouldn't work)
 
1371
 
 
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)
 
1382
 
 
1383
        # Change back to "universal"
 
1384
 
 
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)
 
1391
 
 
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)
 
1397
 
 
1398
        # Change back to "global"
 
1399
 
 
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)
 
1406
 
 
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)
 
1412
 
 
1413
        delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
 
1414
 
 
1415
    def test_userAccountControl(self):
 
1416
        """Test the userAccountControl behaviour"""
 
1417
        print "Testing userAccountControl behaviour\n"
 
1418
 
 
1419
        # With a user object
 
1420
 
 
1421
        # Add operation
 
1422
 
 
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.
 
1427
 
 
1428
        # Invalid attribute
 
1429
        try:
 
1430
            ldb.add({
 
1431
                "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
 
1432
                "objectclass": "user",
 
1433
                "userAccountControl": "0"})
 
1434
            self.fail()
 
1435
        except LdbError, (num, _):
 
1436
            self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
 
1437
        delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
 
1438
 
 
1439
# This has to wait until s4 supports it (needs a password module change)
 
1440
#        try:
 
1441
#            ldb.add({
 
1442
#                "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
 
1443
#                "objectclass": "user",
 
1444
#                "userAccountControl": str(UF_NORMAL_ACCOUNT)})
 
1445
#            self.fail()
 
1446
#        except LdbError, (num, _):
 
1447
#            self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
 
1448
#        delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
 
1449
 
 
1450
        ldb.add({
 
1451
            "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
 
1452
            "objectclass": "user",
 
1453
            "userAccountControl": str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD)})
 
1454
 
 
1455
        res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
 
1456
                          scope=SCOPE_BASE,
 
1457
                          attrs=["sAMAccountType", "userAccountControl"])
 
1458
        self.assertTrue(len(res1) == 1)
 
1459
        self.assertEquals(int(res1[0]["sAMAccountType"][0]),
 
1460
          ATYPE_NORMAL_ACCOUNT)
 
1461
        self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_ACCOUNTDISABLE == 0)
 
1462
        delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
 
1463
 
 
1464
        try:
 
1465
            ldb.add({
 
1466
                "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
 
1467
                "objectclass": "user",
 
1468
                "userAccountControl": str(UF_TEMP_DUPLICATE_ACCOUNT)})
 
1469
            self.fail()
 
1470
        except LdbError, (num, _):
 
1471
            self.assertEquals(num, ERR_OTHER)
 
1472
        delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
 
1473
 
 
1474
# This isn't supported yet in s4
 
1475
#        try:
 
1476
#            ldb.add({
 
1477
#                "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
 
1478
#                "objectclass": "user",
 
1479
#                "userAccountControl": str(UF_SERVER_TRUST_ACCOUNT)})
 
1480
#            self.fail()
 
1481
#        except LdbError, (num, _):
 
1482
#            self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
 
1483
#        delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
 
1484
#
 
1485
#        try:
 
1486
#            ldb.add({
 
1487
#                "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
 
1488
#                "objectclass": "user",
 
1489
#                "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT)})
 
1490
#        except LdbError, (num, _):
 
1491
#            self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
 
1492
#        delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
 
1493
 
 
1494
# This isn't supported yet in s4 - needs ACL module adaption
 
1495
#        try:
 
1496
#            ldb.add({
 
1497
#                "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
 
1498
#                "objectclass": "user",
 
1499
#                "userAccountControl": str(UF_INTERDOMAIN_TRUST_ACCOUNT)})
 
1500
#            self.fail()
 
1501
#        except LdbError, (num, _):
 
1502
#            self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS)
 
1503
#        delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
 
1504
 
 
1505
        # Modify operation
 
1506
 
 
1507
        ldb.add({
 
1508
            "dn": "cn=ldaptestuser,cn=users," + self.base_dn,
 
1509
            "objectclass": "user"})
 
1510
 
 
1511
        # After creation we should have a normal account
 
1512
        res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
 
1513
                          scope=SCOPE_BASE,
 
1514
                          attrs=["sAMAccountType", "userAccountControl"])
 
1515
        self.assertTrue(len(res1) == 1)
 
1516
        self.assertEquals(int(res1[0]["sAMAccountType"][0]),
 
1517
          ATYPE_NORMAL_ACCOUNT)
 
1518
        self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_ACCOUNTDISABLE != 0)
 
1519
 
 
1520
        # As user you can only switch from a normal account to a workstation
 
1521
        # trust account and back.
 
1522
        # The UF_PASSWD_NOTREQD flag is needed since we haven't requested a
 
1523
        # password yet.
 
1524
        # With SYSTEM rights you can switch to a interdomain trust account.
 
1525
 
 
1526
        # Invalid attribute
 
1527
        try:
 
1528
            m = Message()
 
1529
            m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
 
1530
            m["userAccountControl"] = MessageElement("0",
 
1531
              FLAG_MOD_REPLACE, "userAccountControl")
 
1532
            ldb.modify(m)
 
1533
        except LdbError, (num, _):
 
1534
            self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
 
1535
 
 
1536
# This has to wait until s4 supports it (needs a password module change)
 
1537
#        try:
 
1538
#            m = Message()
 
1539
#            m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
 
1540
#            m["userAccountControl"] = MessageElement(
 
1541
#              str(UF_NORMAL_ACCOUNT),
 
1542
#              FLAG_MOD_REPLACE, "userAccountControl")
 
1543
#            ldb.modify(m)
 
1544
#        except LdbError, (num, _):
 
1545
#            self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
 
1546
 
 
1547
        m = Message()
 
1548
        m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
 
1549
        m["userAccountControl"] = MessageElement(
 
1550
          str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD),
 
1551
          FLAG_MOD_REPLACE, "userAccountControl")
 
1552
        ldb.modify(m)
 
1553
 
 
1554
        res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
 
1555
                          scope=SCOPE_BASE,
 
1556
                          attrs=["sAMAccountType", "userAccountControl"])
 
1557
        self.assertTrue(len(res1) == 1)
 
1558
        self.assertEquals(int(res1[0]["sAMAccountType"][0]),
 
1559
          ATYPE_NORMAL_ACCOUNT)
 
1560
        self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_ACCOUNTDISABLE == 0)
 
1561
 
 
1562
        try:
 
1563
            m = Message()
 
1564
            m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
 
1565
            m["userAccountControl"] = MessageElement(
 
1566
              str(UF_TEMP_DUPLICATE_ACCOUNT),
 
1567
              FLAG_MOD_REPLACE, "userAccountControl")
 
1568
            ldb.modify(m)
 
1569
            self.fail()
 
1570
        except LdbError, (num, _):
 
1571
            self.assertEquals(num, ERR_OTHER)
 
1572
 
 
1573
# This isn't supported yet in s4
 
1574
#        try:
 
1575
#            m = Message()
 
1576
#            m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
 
1577
#            m["userAccountControl"] = MessageElement(
 
1578
#              str(UF_SERVER_TRUST_ACCOUNT),
 
1579
#              FLAG_MOD_REPLACE, "userAccountControl")
 
1580
#            ldb.modify(m)
 
1581
#            self.fail()
 
1582
#        except LdbError, (num, _):
 
1583
#            self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
 
1584
 
 
1585
        m = Message()
 
1586
        m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
 
1587
        m["userAccountControl"] = MessageElement(
 
1588
          str(UF_WORKSTATION_TRUST_ACCOUNT),
 
1589
          FLAG_MOD_REPLACE, "userAccountControl")
 
1590
        ldb.modify(m)
 
1591
 
 
1592
        res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
 
1593
                          scope=SCOPE_BASE, attrs=["sAMAccountType"])
 
1594
        self.assertTrue(len(res1) == 1)
 
1595
        self.assertEquals(int(res1[0]["sAMAccountType"][0]),
 
1596
          ATYPE_WORKSTATION_TRUST)
 
1597
 
 
1598
        m = Message()
 
1599
        m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
 
1600
        m["userAccountControl"] = MessageElement(
 
1601
          str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD),
 
1602
          FLAG_MOD_REPLACE, "userAccountControl")
 
1603
        ldb.modify(m)
 
1604
 
 
1605
        res1 = ldb.search("cn=ldaptestuser,cn=users," + self.base_dn,
 
1606
                          scope=SCOPE_BASE, attrs=["sAMAccountType"])
 
1607
        self.assertTrue(len(res1) == 1)
 
1608
        self.assertEquals(int(res1[0]["sAMAccountType"][0]),
 
1609
          ATYPE_NORMAL_ACCOUNT)
 
1610
 
 
1611
# This isn't supported yet in s4 - needs ACL module adaption
 
1612
#        try:
 
1613
#            m = Message()
 
1614
#            m.dn = Dn(ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
 
1615
#            m["userAccountControl"] = MessageElement(
 
1616
#              str(UF_INTERDOMAIN_TRUST_ACCOUNT),
 
1617
#              FLAG_MOD_REPLACE, "userAccountControl")
 
1618
#            ldb.modify(m)
 
1619
#            self.fail()
 
1620
#        except LdbError, (num, _):
 
1621
#            self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS)
 
1622
 
 
1623
        # With a computer object
 
1624
 
 
1625
        # Add operation
 
1626
 
 
1627
        # As computer you can set a normal account and a server trust account.
 
1628
        # The UF_PASSWD_NOTREQD flag is needed since we haven't requested a
 
1629
        # password yet.
 
1630
        # With SYSTEM rights you can set a interdomain trust account.
 
1631
 
 
1632
        # Invalid attribute
 
1633
        try:
 
1634
            ldb.add({
 
1635
                "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
1636
                "objectclass": "computer",
 
1637
                "userAccountControl": "0"})
 
1638
            self.fail()
 
1639
        except LdbError, (num, _):
 
1640
            self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
 
1641
        delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
 
1642
 
 
1643
# This has to wait until s4 supports it (needs a password module change)
 
1644
#        try:
 
1645
#            ldb.add({
 
1646
#                "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
1647
#                "objectclass": "computer",
 
1648
#                "userAccountControl": str(UF_NORMAL_ACCOUNT)})
 
1649
#            self.fail()
 
1650
#        except LdbError, (num, _):
 
1651
#            self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
 
1652
#        delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
 
1653
 
 
1654
        ldb.add({
 
1655
            "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
1656
            "objectclass": "computer",
 
1657
            "userAccountControl": str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD)})
 
1658
 
 
1659
        res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
1660
                          scope=SCOPE_BASE,
 
1661
                          attrs=["sAMAccountType", "userAccountControl"])
 
1662
        self.assertTrue(len(res1) == 1)
 
1663
        self.assertEquals(int(res1[0]["sAMAccountType"][0]),
 
1664
          ATYPE_NORMAL_ACCOUNT)
 
1665
        self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_ACCOUNTDISABLE == 0)
 
1666
        delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
 
1667
 
 
1668
        try:
 
1669
            ldb.add({
 
1670
                "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
1671
                "objectclass": "computer",
 
1672
                "userAccountControl": str(UF_TEMP_DUPLICATE_ACCOUNT)})
 
1673
            self.fail()
 
1674
        except LdbError, (num, _):
 
1675
            self.assertEquals(num, ERR_OTHER)
 
1676
        delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
 
1677
 
 
1678
        ldb.add({
 
1679
            "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
1680
            "objectclass": "computer",
 
1681
            "userAccountControl": str(UF_SERVER_TRUST_ACCOUNT)})
 
1682
 
 
1683
        res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + 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_WORKSTATION_TRUST)
 
1688
        delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
 
1689
 
 
1690
        try:
 
1691
            ldb.add({
 
1692
                "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
1693
                "objectclass": "computer",
 
1694
                "userAccountControl": str(UF_WORKSTATION_TRUST_ACCOUNT)})
 
1695
        except LdbError, (num, _):
 
1696
            self.assertEquals(num, ERR_OBJECT_CLASS_VIOLATION)
 
1697
        delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
 
1698
 
 
1699
# This isn't supported yet in s4 - needs ACL module adaption
 
1700
#        try:
 
1701
#            ldb.add({
 
1702
#                "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
1703
#                "objectclass": "computer",
 
1704
#                "userAccountControl": str(UF_INTERDOMAIN_TRUST_ACCOUNT)})
 
1705
#            self.fail()
 
1706
#        except LdbError, (num, _):
 
1707
#            self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS)
 
1708
#        delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
 
1709
 
 
1710
        # Modify operation
 
1711
 
 
1712
        ldb.add({
 
1713
            "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
1714
            "objectclass": "computer"})
 
1715
 
 
1716
        # After creation we should have a normal account
 
1717
        res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
1718
                          scope=SCOPE_BASE,
 
1719
                          attrs=["sAMAccountType", "userAccountControl"])
 
1720
        self.assertTrue(len(res1) == 1)
 
1721
        self.assertEquals(int(res1[0]["sAMAccountType"][0]),
 
1722
          ATYPE_NORMAL_ACCOUNT)
 
1723
        self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_ACCOUNTDISABLE != 0)
 
1724
 
 
1725
        # As computer you can switch from a normal account to a workstation
 
1726
        # or server trust account and back (also swapping between trust
 
1727
        # accounts is allowed).
 
1728
        # The UF_PASSWD_NOTREQD flag is needed since we haven't requested a
 
1729
        # password yet.
 
1730
        # With SYSTEM rights you can switch to a interdomain trust account.
 
1731
 
 
1732
        # Invalid attribute
 
1733
        try:
 
1734
            m = Message()
 
1735
            m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
 
1736
            m["userAccountControl"] = MessageElement("0",
 
1737
              FLAG_MOD_REPLACE, "userAccountControl")
 
1738
            ldb.modify(m)
 
1739
        except LdbError, (num, _):
 
1740
            self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
 
1741
 
 
1742
# This has to wait until s4 supports it (needs a password module change)
 
1743
#        try:
 
1744
#            m = Message()
 
1745
#            m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
 
1746
#            m["userAccountControl"] = MessageElement(
 
1747
#              str(UF_NORMAL_ACCOUNT),
 
1748
#              FLAG_MOD_REPLACE, "userAccountControl")
 
1749
#            ldb.modify(m)
 
1750
#        except LdbError, (num, _):
 
1751
#            self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
 
1752
 
 
1753
        m = Message()
 
1754
        m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
 
1755
        m["userAccountControl"] = MessageElement(
 
1756
          str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD),
 
1757
          FLAG_MOD_REPLACE, "userAccountControl")
 
1758
        ldb.modify(m)
 
1759
 
 
1760
        res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
1761
                          scope=SCOPE_BASE,
 
1762
                          attrs=["sAMAccountType", "userAccountControl"])
 
1763
        self.assertTrue(len(res1) == 1)
 
1764
        self.assertEquals(int(res1[0]["sAMAccountType"][0]),
 
1765
          ATYPE_NORMAL_ACCOUNT)
 
1766
        self.assertTrue(int(res1[0]["userAccountControl"][0]) & UF_ACCOUNTDISABLE == 0)
 
1767
 
 
1768
        try:
 
1769
            m = Message()
 
1770
            m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
 
1771
            m["userAccountControl"] = MessageElement(
 
1772
              str(UF_TEMP_DUPLICATE_ACCOUNT),
 
1773
              FLAG_MOD_REPLACE, "userAccountControl")
 
1774
            ldb.modify(m)
 
1775
            self.fail()
 
1776
        except LdbError, (num, _):
 
1777
            self.assertEquals(num, ERR_OTHER)
 
1778
 
 
1779
        m = Message()
 
1780
        m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
 
1781
        m["userAccountControl"] = MessageElement(
 
1782
          str(UF_SERVER_TRUST_ACCOUNT),
 
1783
          FLAG_MOD_REPLACE, "userAccountControl")
 
1784
        ldb.modify(m)
 
1785
 
 
1786
        res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
1787
                          scope=SCOPE_BASE, attrs=["sAMAccountType"])
 
1788
        self.assertTrue(len(res1) == 1)
 
1789
        self.assertEquals(int(res1[0]["sAMAccountType"][0]),
 
1790
          ATYPE_WORKSTATION_TRUST)
 
1791
 
 
1792
        m = Message()
 
1793
        m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
 
1794
        m["userAccountControl"] = MessageElement(
 
1795
          str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD),
 
1796
          FLAG_MOD_REPLACE, "userAccountControl")
 
1797
        ldb.modify(m)
 
1798
 
 
1799
        res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
1800
                          scope=SCOPE_BASE, attrs=["sAMAccountType"])
 
1801
        self.assertTrue(len(res1) == 1)
 
1802
        self.assertEquals(int(res1[0]["sAMAccountType"][0]),
 
1803
          ATYPE_NORMAL_ACCOUNT)
 
1804
 
 
1805
        m = Message()
 
1806
        m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
 
1807
        m["userAccountControl"] = MessageElement(
 
1808
          str(UF_WORKSTATION_TRUST_ACCOUNT),
 
1809
          FLAG_MOD_REPLACE, "userAccountControl")
 
1810
        ldb.modify(m)
 
1811
 
 
1812
        res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
1813
                          scope=SCOPE_BASE, attrs=["sAMAccountType"])
 
1814
        self.assertTrue(len(res1) == 1)
 
1815
        self.assertEquals(int(res1[0]["sAMAccountType"][0]),
 
1816
          ATYPE_WORKSTATION_TRUST)
 
1817
 
 
1818
        m = Message()
 
1819
        m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
 
1820
        m["userAccountControl"] = MessageElement(
 
1821
          str(UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD),
 
1822
          FLAG_MOD_REPLACE, "userAccountControl")
 
1823
        ldb.modify(m)
 
1824
 
 
1825
        res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
1826
                          scope=SCOPE_BASE, attrs=["sAMAccountType"])
 
1827
        self.assertTrue(len(res1) == 1)
 
1828
        self.assertEquals(int(res1[0]["sAMAccountType"][0]),
 
1829
          ATYPE_NORMAL_ACCOUNT)
 
1830
 
 
1831
        m = Message()
 
1832
        m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
 
1833
        m["userAccountControl"] = MessageElement(
 
1834
          str(UF_SERVER_TRUST_ACCOUNT),
 
1835
          FLAG_MOD_REPLACE, "userAccountControl")
 
1836
        ldb.modify(m)
 
1837
 
 
1838
        res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
1839
                          scope=SCOPE_BASE, attrs=["sAMAccountType"])
 
1840
        self.assertTrue(len(res1) == 1)
 
1841
        self.assertEquals(int(res1[0]["sAMAccountType"][0]),
 
1842
          ATYPE_WORKSTATION_TRUST)
 
1843
 
 
1844
        m = Message()
 
1845
        m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
 
1846
        m["userAccountControl"] = MessageElement(
 
1847
          str(UF_WORKSTATION_TRUST_ACCOUNT),
 
1848
          FLAG_MOD_REPLACE, "userAccountControl")
 
1849
        ldb.modify(m)
 
1850
 
 
1851
        res1 = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
1852
                          scope=SCOPE_BASE, attrs=["sAMAccountType"])
 
1853
        self.assertTrue(len(res1) == 1)
 
1854
        self.assertEquals(int(res1[0]["sAMAccountType"][0]),
 
1855
          ATYPE_WORKSTATION_TRUST)
 
1856
 
 
1857
# This isn't supported yet in s4 - needs ACL module adaption
 
1858
#        try:
 
1859
#            m = Message()
 
1860
#            m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
 
1861
#            m["userAccountControl"] = MessageElement(
 
1862
#              str(UF_INTERDOMAIN_TRUST_ACCOUNT),
 
1863
#              FLAG_MOD_REPLACE, "userAccountControl")
 
1864
#            ldb.modify(m)
 
1865
#            self.fail()
 
1866
#        except LdbError, (num, _):
 
1867
#            self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS)
 
1868
 
 
1869
        delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn)
 
1870
        delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
 
1871
 
 
1872
    def test_service_principal_name_updates(self):
 
1873
        """Test the servicePrincipalNames update behaviour"""
 
1874
        print "Testing servicePrincipalNames update behaviour\n"
 
1875
 
 
1876
        ldb.add({
 
1877
            "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
1878
            "objectclass": "computer",
 
1879
            "dNSHostName": "testname.testdom"})
 
1880
 
 
1881
        res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
1882
                         scope=SCOPE_BASE, attrs=["servicePrincipalName"])
 
1883
        self.assertTrue(len(res) == 1)
 
1884
        self.assertFalse("servicePrincipalName" in res[0])
 
1885
 
 
1886
        delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
 
1887
 
 
1888
        ldb.add({
 
1889
            "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
1890
            "objectclass": "computer",
 
1891
            "servicePrincipalName": "HOST/testname.testdom"})
 
1892
 
 
1893
        res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
1894
                          scope=SCOPE_BASE, attrs=["dNSHostName"])
 
1895
        self.assertTrue(len(res) == 1)
 
1896
        self.assertFalse("dNSHostName" in res[0])
 
1897
 
 
1898
        delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
 
1899
 
 
1900
        ldb.add({
 
1901
            "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
1902
            "objectclass": "computer",
 
1903
            "dNSHostName": "testname2.testdom",
 
1904
            "servicePrincipalName": "HOST/testname.testdom"})
 
1905
 
 
1906
        res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
1907
                         scope=SCOPE_BASE, attrs=["dNSHostName"])
 
1908
        self.assertTrue(len(res) == 1)
 
1909
        self.assertEquals(res[0]["dNSHostName"][0], "testname2.testdom")
 
1910
 
 
1911
        res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
1912
                         scope=SCOPE_BASE, attrs=["servicePrincipalName"])
 
1913
        self.assertTrue(len(res) == 1)
 
1914
        self.assertEquals(res[0]["servicePrincipalName"][0],
 
1915
                          "HOST/testname.testdom")
 
1916
 
 
1917
        m = Message()
 
1918
        m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
 
1919
        m["dNSHostName"] = MessageElement("testname.testdoM",
 
1920
                                          FLAG_MOD_REPLACE, "dNSHostName")
 
1921
        ldb.modify(m)
 
1922
 
 
1923
        res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
1924
                         scope=SCOPE_BASE, attrs=["servicePrincipalName"])
 
1925
        self.assertTrue(len(res) == 1)
 
1926
        self.assertEquals(res[0]["servicePrincipalName"][0],
 
1927
                          "HOST/testname.testdom")
 
1928
 
 
1929
        m = Message()
 
1930
        m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
 
1931
        m["dNSHostName"] = MessageElement("testname2.testdom2",
 
1932
                                          FLAG_MOD_REPLACE, "dNSHostName")
 
1933
        ldb.modify(m)
 
1934
 
 
1935
        res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
1936
                         scope=SCOPE_BASE, attrs=["servicePrincipalName"])
 
1937
        self.assertTrue(len(res) == 1)
 
1938
        self.assertEquals(res[0]["servicePrincipalName"][0],
 
1939
                          "HOST/testname2.testdom2")
 
1940
 
 
1941
        m = Message()
 
1942
        m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
 
1943
        m["dNSHostName"] = MessageElement([],
 
1944
                                          FLAG_MOD_DELETE, "dNSHostName")
 
1945
        ldb.modify(m)
 
1946
 
 
1947
        res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
1948
                         scope=SCOPE_BASE, attrs=["servicePrincipalName"])
 
1949
        self.assertTrue(len(res) == 1)
 
1950
        self.assertEquals(res[0]["servicePrincipalName"][0],
 
1951
                          "HOST/testname2.testdom2")
 
1952
 
 
1953
        m = Message()
 
1954
        m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
 
1955
        m["dNSHostName"] = MessageElement("testname.testdom3",
 
1956
                                          FLAG_MOD_REPLACE, "dNSHostName")
 
1957
        ldb.modify(m)
 
1958
 
 
1959
        res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
1960
                         scope=SCOPE_BASE, attrs=["servicePrincipalName"])
 
1961
        self.assertTrue(len(res) == 1)
 
1962
        self.assertEquals(res[0]["servicePrincipalName"][0],
 
1963
                          "HOST/testname2.testdom2")
 
1964
 
 
1965
        m = Message()
 
1966
        m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
 
1967
        m["dNSHostName"] = MessageElement("testname2.testdom2",
 
1968
                                          FLAG_MOD_REPLACE, "dNSHostName")
 
1969
        ldb.modify(m)
 
1970
 
 
1971
        m = Message()
 
1972
        m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
 
1973
        m["dNSHostName"] = MessageElement("testname3.testdom3",
 
1974
                                          FLAG_MOD_REPLACE, "dNSHostName")
 
1975
        m["servicePrincipalName"] = MessageElement("HOST/testname2.testdom2",
 
1976
                                                   FLAG_MOD_REPLACE,
 
1977
                                                   "servicePrincipalName")
 
1978
        ldb.modify(m)
 
1979
 
 
1980
        res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
1981
                          scope=SCOPE_BASE, attrs=["servicePrincipalName"])
 
1982
        self.assertTrue(len(res) == 1)
 
1983
        self.assertEquals(res[0]["servicePrincipalName"][0],
 
1984
                          "HOST/testname3.testdom3")
 
1985
 
 
1986
        m = Message()
 
1987
        m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
 
1988
        m["servicePrincipalName"] = MessageElement("HOST/testname2.testdom2",
 
1989
                                                   FLAG_MOD_REPLACE,
 
1990
                                                   "servicePrincipalName")
 
1991
        m["dNSHostName"] = MessageElement("testname4.testdom4",
 
1992
                                          FLAG_MOD_REPLACE, "dNSHostName")
 
1993
        ldb.modify(m)
 
1994
 
 
1995
        res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
1996
                         scope=SCOPE_BASE, attrs=["servicePrincipalName"])
 
1997
        self.assertTrue(len(res) == 1)
 
1998
        self.assertEquals(res[0]["servicePrincipalName"][0],
 
1999
                          "HOST/testname2.testdom2")
 
2000
 
 
2001
        m = Message()
 
2002
        m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
 
2003
        m["servicePrincipalName"] = MessageElement([],
 
2004
                                                   FLAG_MOD_DELETE,
 
2005
                                                   "servicePrincipalName")
 
2006
        ldb.modify(m)
 
2007
 
 
2008
        m = Message()
 
2009
        m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
 
2010
        m["dNSHostName"] = MessageElement("testname2.testdom2",
 
2011
                                          FLAG_MOD_REPLACE, "dNSHostName")
 
2012
        ldb.modify(m)
 
2013
 
 
2014
        res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
2015
                         scope=SCOPE_BASE, attrs=["servicePrincipalName"])
 
2016
        self.assertTrue(len(res) == 1)
 
2017
        self.assertFalse("servicePrincipalName" in res[0])
 
2018
 
 
2019
        delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
 
2020
 
 
2021
        ldb.add({
 
2022
            "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
2023
            "objectclass": "computer",
 
2024
            "sAMAccountName": "testname$"})
 
2025
 
 
2026
        res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
2027
                         scope=SCOPE_BASE, attrs=["servicePrincipalName"])
 
2028
        self.assertTrue(len(res) == 1)
 
2029
        self.assertFalse("servicePrincipalName" in res[0])
 
2030
 
 
2031
        delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
 
2032
 
 
2033
        ldb.add({
 
2034
            "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
2035
            "objectclass": "computer",
 
2036
            "servicePrincipalName": "HOST/testname"})
 
2037
 
 
2038
        res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
2039
                         scope=SCOPE_BASE, attrs=["sAMAccountName"])
 
2040
        self.assertTrue(len(res) == 1)
 
2041
        self.assertTrue("sAMAccountName" in res[0])
 
2042
 
 
2043
        delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
 
2044
 
 
2045
        ldb.add({
 
2046
            "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
2047
            "objectclass": "computer",
 
2048
            "sAMAccountName": "testname$",
 
2049
            "servicePrincipalName": "HOST/testname"})
 
2050
 
 
2051
        res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
2052
                         scope=SCOPE_BASE, attrs=["sAMAccountName"])
 
2053
        self.assertTrue(len(res) == 1)
 
2054
        self.assertEquals(res[0]["sAMAccountName"][0], "testname$")
 
2055
 
 
2056
        res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
2057
                         scope=SCOPE_BASE, attrs=["servicePrincipalName"])
 
2058
        self.assertTrue(len(res) == 1)
 
2059
        self.assertEquals(res[0]["servicePrincipalName"][0],
 
2060
                          "HOST/testname")
 
2061
 
 
2062
        m = Message()
 
2063
        m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
 
2064
        m["sAMAccountName"] = MessageElement("testnamE$",
 
2065
                                             FLAG_MOD_REPLACE, "sAMAccountName")
 
2066
        ldb.modify(m)
 
2067
 
 
2068
        res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
2069
                         scope=SCOPE_BASE, attrs=["servicePrincipalName"])
 
2070
        self.assertTrue(len(res) == 1)
 
2071
        self.assertEquals(res[0]["servicePrincipalName"][0],
 
2072
                          "HOST/testname")
 
2073
 
 
2074
        m = Message()
 
2075
        m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
 
2076
        m["sAMAccountName"] = MessageElement("testname",
 
2077
                                             FLAG_MOD_REPLACE, "sAMAccountName")
 
2078
        ldb.modify(m)
 
2079
 
 
2080
        res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
2081
                         scope=SCOPE_BASE, attrs=["servicePrincipalName"])
 
2082
        self.assertTrue(len(res) == 1)
 
2083
        self.assertEquals(res[0]["servicePrincipalName"][0],
 
2084
                          "HOST/testname")
 
2085
 
 
2086
        m = Message()
 
2087
        m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
 
2088
        m["sAMAccountName"] = MessageElement("test$name$",
 
2089
                                             FLAG_MOD_REPLACE, "sAMAccountName")
 
2090
        ldb.modify(m)
 
2091
 
 
2092
        res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
2093
                         scope=SCOPE_BASE, attrs=["servicePrincipalName"])
 
2094
        self.assertTrue(len(res) == 1)
 
2095
        self.assertEquals(res[0]["servicePrincipalName"][0],
 
2096
                          "HOST/test$name")
 
2097
 
 
2098
        m = Message()
 
2099
        m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
 
2100
        m["sAMAccountName"] = MessageElement("testname2",
 
2101
                                             FLAG_MOD_REPLACE, "sAMAccountName")
 
2102
        ldb.modify(m)
 
2103
 
 
2104
        res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
2105
                         scope=SCOPE_BASE, attrs=["servicePrincipalName"])
 
2106
        self.assertTrue(len(res) == 1)
 
2107
        self.assertEquals(res[0]["servicePrincipalName"][0],
 
2108
                          "HOST/testname2")
 
2109
 
 
2110
        m = Message()
 
2111
        m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
 
2112
        m["sAMAccountName"] = MessageElement("testname3",
 
2113
                                             FLAG_MOD_REPLACE, "sAMAccountName")
 
2114
        m["servicePrincipalName"] = MessageElement("HOST/testname2",
 
2115
                                                   FLAG_MOD_REPLACE,
 
2116
                                                   "servicePrincipalName")
 
2117
        ldb.modify(m)
 
2118
 
 
2119
        res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
2120
                         scope=SCOPE_BASE, attrs=["servicePrincipalName"])
 
2121
        self.assertTrue(len(res) == 1)
 
2122
        self.assertEquals(res[0]["servicePrincipalName"][0],
 
2123
                          "HOST/testname3")
 
2124
 
 
2125
        m = Message()
 
2126
        m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
 
2127
        m["servicePrincipalName"] = MessageElement("HOST/testname2",
 
2128
                                                   FLAG_MOD_REPLACE,
 
2129
                                                   "servicePrincipalName")
 
2130
        m["sAMAccountName"] = MessageElement("testname4",
 
2131
                                             FLAG_MOD_REPLACE, "sAMAccountName")
 
2132
        ldb.modify(m)
 
2133
 
 
2134
        res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
2135
                         scope=SCOPE_BASE, attrs=["servicePrincipalName"])
 
2136
        self.assertTrue(len(res) == 1)
 
2137
        self.assertEquals(res[0]["servicePrincipalName"][0],
 
2138
                          "HOST/testname2")
 
2139
 
 
2140
        m = Message()
 
2141
        m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
 
2142
        m["servicePrincipalName"] = MessageElement([],
 
2143
                                                   FLAG_MOD_DELETE,
 
2144
                                                   "servicePrincipalName")
 
2145
        ldb.modify(m)
 
2146
 
 
2147
        m = Message()
 
2148
        m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
 
2149
        m["sAMAccountName"] = MessageElement("testname2",
 
2150
                                             FLAG_MOD_REPLACE, "sAMAccountName")
 
2151
        ldb.modify(m)
 
2152
 
 
2153
        res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
2154
                         scope=SCOPE_BASE, attrs=["servicePrincipalName"])
 
2155
        self.assertTrue(len(res) == 1)
 
2156
        self.assertFalse("servicePrincipalName" in res[0])
 
2157
 
 
2158
        delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
 
2159
 
 
2160
        ldb.add({
 
2161
            "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
2162
            "objectclass": "computer",
 
2163
            "dNSHostName": "testname.testdom",
 
2164
            "sAMAccountName": "testname$",
 
2165
            "servicePrincipalName": [ "HOST/testname.testdom", "HOST/testname" ]
 
2166
        })
 
2167
 
 
2168
        m = Message()
 
2169
        m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
 
2170
        m["dNSHostName"] = MessageElement("testname2.testdom",
 
2171
                                          FLAG_MOD_REPLACE, "dNSHostName")
 
2172
        m["sAMAccountName"] = MessageElement("testname2$",
 
2173
                                             FLAG_MOD_REPLACE, "sAMAccountName")
 
2174
        ldb.modify(m)
 
2175
 
 
2176
        res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
2177
                         scope=SCOPE_BASE, attrs=["dNSHostName", "sAMAccountName", "servicePrincipalName"])
 
2178
        self.assertTrue(len(res) == 1)
 
2179
        self.assertEquals(res[0]["dNSHostName"][0], "testname2.testdom")
 
2180
        self.assertEquals(res[0]["sAMAccountName"][0], "testname2$")
 
2181
        self.assertTrue(res[0]["servicePrincipalName"][0] == "HOST/testname2" or
 
2182
                        res[0]["servicePrincipalName"][1] == "HOST/testname2")
 
2183
        self.assertTrue(res[0]["servicePrincipalName"][0] == "HOST/testname2.testdom" or
 
2184
                        res[0]["servicePrincipalName"][1] == "HOST/testname2.testdom")
 
2185
 
 
2186
        delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
 
2187
 
 
2188
        ldb.add({
 
2189
            "dn": "cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
2190
            "objectclass": "computer",
 
2191
            "dNSHostName": "testname.testdom",
 
2192
            "sAMAccountName": "testname$",
 
2193
            "servicePrincipalName": [ "HOST/testname.testdom", "HOST/testname" ]
 
2194
        })
 
2195
 
 
2196
        m = Message()
 
2197
        m.dn = Dn(ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
 
2198
        m["sAMAccountName"] = MessageElement("testname2$",
 
2199
                                             FLAG_MOD_REPLACE, "sAMAccountName")
 
2200
        m["dNSHostName"] = MessageElement("testname2.testdom",
 
2201
                                          FLAG_MOD_REPLACE, "dNSHostName")
 
2202
        ldb.modify(m)
 
2203
 
 
2204
        res = ldb.search("cn=ldaptestcomputer,cn=computers," + self.base_dn,
 
2205
                         scope=SCOPE_BASE, attrs=["dNSHostName", "sAMAccountName", "servicePrincipalName"])
 
2206
        self.assertTrue(len(res) == 1)
 
2207
        self.assertEquals(res[0]["dNSHostName"][0], "testname2.testdom")
 
2208
        self.assertEquals(res[0]["sAMAccountName"][0], "testname2$")
 
2209
        self.assertTrue(res[0]["servicePrincipalName"][0] == "HOST/testname2" or
 
2210
                        res[0]["servicePrincipalName"][1] == "HOST/testname2")
 
2211
        self.assertTrue(res[0]["servicePrincipalName"][0] == "HOST/testname2.testdom" or
 
2212
                        res[0]["servicePrincipalName"][1] == "HOST/testname2.testdom")
 
2213
 
 
2214
        delete_force(self.ldb, "cn=ldaptestcomputer,cn=computers," + self.base_dn)
 
2215
 
 
2216
    def test_sam_description_attribute(self):
 
2217
        """Test SAM description attribute"""
 
2218
        print "Test SAM description attribute"""
 
2219
 
 
2220
        self.ldb.add({
 
2221
            "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
 
2222
            "description": "desc2",
 
2223
            "objectclass": "group",
 
2224
            "description": "desc1"})
 
2225
 
 
2226
        res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
 
2227
                         scope=SCOPE_BASE, attrs=["description"])
 
2228
        self.assertTrue(len(res) == 1)
 
2229
        self.assertTrue("description" in res[0])
 
2230
        self.assertTrue(len(res[0]["description"]) == 1)
 
2231
        self.assertEquals(res[0]["description"][0], "desc1")
 
2232
 
 
2233
        delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
 
2234
 
 
2235
        self.ldb.add({
 
2236
            "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
 
2237
            "objectclass": "group",
 
2238
            "description": ["desc1", "desc2"]})
 
2239
 
 
2240
        res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
 
2241
                         scope=SCOPE_BASE, attrs=["description"])
 
2242
        self.assertTrue(len(res) == 1)
 
2243
        self.assertTrue("description" in res[0])
 
2244
        self.assertTrue(len(res[0]["description"]) == 2)
 
2245
        self.assertTrue(res[0]["description"][0] == "desc1" or
 
2246
                        res[0]["description"][1] == "desc1")
 
2247
        self.assertTrue(res[0]["description"][0] == "desc2" or
 
2248
                        res[0]["description"][1] == "desc2")
 
2249
 
 
2250
        m = Message()
 
2251
        m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
 
2252
        m["description"] = MessageElement(["desc1","desc2"], FLAG_MOD_REPLACE,
 
2253
          "description")
 
2254
        try:
 
2255
            ldb.modify(m)
 
2256
            self.fail()
 
2257
        except LdbError, (num, _):
 
2258
            self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
 
2259
 
 
2260
        m = Message()
 
2261
        m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
 
2262
        m["description"] = MessageElement(["desc1","desc2"], FLAG_MOD_DELETE,
 
2263
          "description")
 
2264
        ldb.modify(m)
 
2265
 
 
2266
        delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
 
2267
 
 
2268
        self.ldb.add({
 
2269
            "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
 
2270
            "objectclass": "group" })
 
2271
 
 
2272
        m = Message()
 
2273
        m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
 
2274
        m["description"] = MessageElement("desc1", FLAG_MOD_REPLACE,
 
2275
          "description")
 
2276
        ldb.modify(m)
 
2277
 
 
2278
        res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
 
2279
                         scope=SCOPE_BASE, attrs=["description"])
 
2280
        self.assertTrue(len(res) == 1)
 
2281
        self.assertTrue("description" in res[0])
 
2282
        self.assertTrue(len(res[0]["description"]) == 1)
 
2283
        self.assertEquals(res[0]["description"][0], "desc1")
 
2284
 
 
2285
        delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
 
2286
 
 
2287
        self.ldb.add({
 
2288
            "dn": "cn=ldaptestgroup,cn=users," + self.base_dn,
 
2289
            "objectclass": "group",
 
2290
            "description": ["desc1", "desc2"]})
 
2291
 
 
2292
        m = Message()
 
2293
        m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
 
2294
        m["description"] = MessageElement("desc1", FLAG_MOD_REPLACE,
 
2295
          "description")
 
2296
        ldb.modify(m)
 
2297
 
 
2298
        res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
 
2299
                         scope=SCOPE_BASE, attrs=["description"])
 
2300
        self.assertTrue(len(res) == 1)
 
2301
        self.assertTrue("description" in res[0])
 
2302
        self.assertTrue(len(res[0]["description"]) == 1)
 
2303
        self.assertEquals(res[0]["description"][0], "desc1")
 
2304
 
 
2305
        m = Message()
 
2306
        m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
 
2307
        m["description"] = MessageElement("desc3", FLAG_MOD_ADD,
 
2308
          "description")
 
2309
        try:
 
2310
            ldb.modify(m)
 
2311
            self.fail()
 
2312
        except LdbError, (num, _):
 
2313
            self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
 
2314
 
 
2315
        m = Message()
 
2316
        m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
 
2317
        m["description"] = MessageElement(["desc1","desc2"], FLAG_MOD_DELETE,
 
2318
          "description")
 
2319
        try:
 
2320
            ldb.modify(m)
 
2321
            self.fail()
 
2322
        except LdbError, (num, _):
 
2323
            self.assertEquals(num, ERR_NO_SUCH_ATTRIBUTE)
 
2324
 
 
2325
        m = Message()
 
2326
        m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
 
2327
        m["description"] = MessageElement("desc1", FLAG_MOD_DELETE,
 
2328
          "description")
 
2329
        ldb.modify(m)
 
2330
        res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
 
2331
                         scope=SCOPE_BASE, attrs=["description"])
 
2332
        self.assertTrue(len(res) == 1)
 
2333
        self.assertFalse("description" in res[0])
 
2334
 
 
2335
        m = Message()
 
2336
        m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
 
2337
        m["description"] = MessageElement(["desc1","desc2"], FLAG_MOD_REPLACE,
 
2338
          "description")
 
2339
        try:
 
2340
            ldb.modify(m)
 
2341
            self.fail()
 
2342
        except LdbError, (num, _):
 
2343
            self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
 
2344
 
 
2345
        m = Message()
 
2346
        m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
 
2347
        m["description"] = MessageElement(["desc3", "desc4"], FLAG_MOD_ADD,
 
2348
          "description")
 
2349
        try:
 
2350
            ldb.modify(m)
 
2351
            self.fail()
 
2352
        except LdbError, (num, _):
 
2353
            self.assertEquals(num, ERR_ATTRIBUTE_OR_VALUE_EXISTS)
 
2354
 
 
2355
        m = Message()
 
2356
        m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
 
2357
        m["description"] = MessageElement("desc1", FLAG_MOD_ADD,
 
2358
          "description")
 
2359
        ldb.modify(m)
 
2360
 
 
2361
        res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
 
2362
                         scope=SCOPE_BASE, attrs=["description"])
 
2363
        self.assertTrue(len(res) == 1)
 
2364
        self.assertTrue("description" in res[0])
 
2365
        self.assertTrue(len(res[0]["description"]) == 1)
 
2366
        self.assertEquals(res[0]["description"][0], "desc1")
 
2367
 
 
2368
        m = Message()
 
2369
        m.dn = Dn(ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
 
2370
        m.add(MessageElement("desc1", FLAG_MOD_DELETE, "description"))
 
2371
        m.add(MessageElement("desc2", FLAG_MOD_ADD, "description"))
 
2372
        ldb.modify(m)
 
2373
 
 
2374
        res = ldb.search("cn=ldaptestgroup,cn=users," + self.base_dn,
 
2375
                         scope=SCOPE_BASE, attrs=["description"])
 
2376
        self.assertTrue(len(res) == 1)
 
2377
        self.assertTrue("description" in res[0])
 
2378
        self.assertTrue(len(res[0]["description"]) == 1)
 
2379
        self.assertEquals(res[0]["description"][0], "desc2")
 
2380
 
 
2381
        delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn)
 
2382
 
 
2383
 
 
2384
if not "://" in host:
 
2385
    if os.path.isfile(host):
 
2386
        host = "tdb://%s" % host
 
2387
    else:
 
2388
        host = "ldap://%s" % host
 
2389
 
 
2390
ldb = SamDB(host, credentials=creds, session_info=system_session(lp), lp=lp)
 
2391
 
 
2392
runner = SubunitTestRunner()
 
2393
rc = 0
 
2394
if not runner.run(unittest.makeSuite(SamTests)).wasSuccessful():
 
2395
    rc = 1
 
2396
sys.exit(rc)