PEP8: fix E128: continuation line under-indented for visual indent
[garming/samba-autobuild/.git] / lib / ldb-samba / tests / match_rules.py
1 #!/usr/bin/env python
2
3 import optparse
4 import sys
5 import os
6 import unittest
7 import samba
8 import samba.getopt as options
9
10 from samba.tests.subunitrun import SubunitOptions, TestProgram
11
12 from samba.tests import delete_force
13 from samba.dcerpc import security, misc
14 from samba.samdb import SamDB
15 from samba.auth import system_session
16 from samba.ndr import ndr_unpack
17 from ldb import Message, MessageElement, Dn, LdbError
18 from ldb import FLAG_MOD_ADD, FLAG_MOD_REPLACE, FLAG_MOD_DELETE
19 from ldb import SCOPE_BASE, SCOPE_SUBTREE, SCOPE_ONELEVEL
20
21 # TODO I'm ignoring case in these tests for now.
22 #       This should be fixed to work inline with Windows.
23 #       The literal strings are in the case Windows uses.
24 # Windows appear to preserve casing of the RDN and uppercase the other keys.
25 class MatchRulesTests(samba.tests.TestCase):
26     def setUp(self):
27         super(MatchRulesTests, self).setUp()
28         self.lp = lp
29         self.ldb = SamDB(host, credentials=creds, session_info=system_session(lp), lp=lp)
30         self.base_dn = self.ldb.domain_dn()
31         self.ou = "OU=matchrulestest,%s" % self.base_dn
32         self.ou_users = "OU=users,%s" % self.ou
33         self.ou_groups = "OU=groups,%s" % self.ou
34         self.ou_computers = "OU=computers,%s" % self.ou
35
36         # Add a organizational unit to create objects
37         self.ldb.add({
38             "dn": self.ou,
39             "objectclass": "organizationalUnit"})
40
41         # Add the following OU hierarchy and set otherWellKnownObjects,
42         # which has BinaryDN syntax:
43         #
44         # o1
45         # |--> o2
46         # |    |--> o3
47         # |    |    |-->o4
48
49         self.ldb.add({
50             "dn": "OU=o1,%s" % self.ou,
51             "objectclass": "organizationalUnit"})
52         self.ldb.add({
53             "dn": "OU=o2,OU=o1,%s" % self.ou,
54             "objectclass": "organizationalUnit"})
55         self.ldb.add({
56             "dn": "OU=o3,OU=o2,OU=o1,%s" % self.ou,
57             "objectclass": "organizationalUnit"})
58         self.ldb.add({
59             "dn": "OU=o4,OU=o3,OU=o2,OU=o1,%s" % self.ou,
60             "objectclass": "organizationalUnit"})
61
62         m = Message()
63         m.dn = Dn(self.ldb, self.ou)
64         m["otherWellKnownObjects"] = MessageElement("B:32:00000000000000000000000000000001:OU=o1,%s" % self.ou,
65                                                     FLAG_MOD_ADD, "otherWellKnownObjects")
66         self.ldb.modify(m)
67
68         m = Message()
69         m.dn = Dn(self.ldb, "OU=o1,%s" % self.ou)
70         m["otherWellKnownObjects"] = MessageElement("B:32:00000000000000000000000000000002:OU=o2,OU=o1,%s" % self.ou,
71                                                     FLAG_MOD_ADD, "otherWellKnownObjects")
72         self.ldb.modify(m)
73
74         m = Message()
75         m.dn = Dn(self.ldb, "OU=o2,OU=o1,%s" % self.ou)
76         m["otherWellKnownObjects"] = MessageElement("B:32:00000000000000000000000000000003:OU=o3,OU=o2,OU=o1,%s" % self.ou,
77                                                     FLAG_MOD_ADD, "otherWellKnownObjects")
78         self.ldb.modify(m)
79
80         m = Message()
81         m.dn = Dn(self.ldb, "OU=o3,OU=o2,OU=o1,%s" % self.ou)
82         m["otherWellKnownObjects"] = MessageElement("B:32:00000000000000000000000000000004:OU=o4,OU=o3,OU=o2,OU=o1,%s" % self.ou,
83                                                     FLAG_MOD_ADD, "otherWellKnownObjects")
84         self.ldb.modify(m)
85
86         # Create OU for users and groups
87         self.ldb.add({
88             "dn": self.ou_users,
89             "objectclass": "organizationalUnit"})
90         self.ldb.add({
91             "dn": self.ou_groups,
92             "objectclass": "organizationalUnit"})
93         self.ldb.add({
94             "dn": self.ou_computers,
95             "objectclass": "organizationalUnit"})
96
97         # Add four groups
98         self.ldb.add({
99             "dn": "cn=g1,%s" % self.ou_groups,
100             "objectclass": "group" })
101         self.ldb.add({
102             "dn": "cn=g2,%s" % self.ou_groups,
103             "objectclass": "group" })
104         self.ldb.add({
105             "dn": "cn=g4,%s" % self.ou_groups,
106             "objectclass": "group" })
107         self.ldb.add({
108             "dn": "cn=g3,%s" % self.ou_groups,
109             "objectclass": "group" })
110
111         # Add four users
112         self.ldb.add({
113             "dn": "cn=u1,%s" % self.ou_users,
114             "objectclass": "user"})
115         self.ldb.add({
116             "dn": "cn=u2,%s" % self.ou_users,
117             "objectclass": "user"})
118         self.ldb.add({
119             "dn": "cn=u3,%s" % self.ou_users,
120             "objectclass": "user"})
121         self.ldb.add({
122             "dn": "cn=u4,%s" % self.ou_users,
123             "objectclass": "user"})
124
125         # Add computers to test Object(DN-Binary) syntax
126         self.ldb.add({
127             "dn": "cn=c1,%s" % self.ou_computers,
128             "objectclass": "computer",
129             "dNSHostName": "c1.%s" % self.lp.get("realm").lower(),
130             "servicePrincipalName": ["HOST/c1"],
131             "sAMAccountName": "c1$",
132             "userAccountControl": "83890178"})
133
134         self.ldb.add({
135             "dn": "cn=c2,%s" % self.ou_computers,
136             "objectclass": "computer",
137             "dNSHostName": "c2.%s" % self.lp.get("realm").lower(),
138             "servicePrincipalName": ["HOST/c2"],
139             "sAMAccountName": "c2$",
140             "userAccountControl": "83890178"})
141
142         self.ldb.add({
143             "dn": "cn=c3,%s" % self.ou_computers,
144             "objectclass": "computer",
145             "dNSHostName": "c3.%s" % self.lp.get("realm").lower(),
146             "servicePrincipalName": ["HOST/c3"],
147             "sAMAccountName": "c3$",
148             "userAccountControl": "83890178"})
149
150         # Create the following hierarchy:
151         # g4
152         # |--> u4
153         # |--> g3
154         # |    |--> u3
155         # |    |--> g2
156         # |    |    |--> u2
157         # |    |    |--> g1
158         # |    |    |    |--> u1
159
160         # u1 member of g1
161         m = Message()
162         m.dn = Dn(self.ldb, "CN=g1,%s" % self.ou_groups)
163         m["member"] = MessageElement("CN=u1,%s" % self.ou_users,
164                                      FLAG_MOD_ADD, "member")
165         self.ldb.modify(m)
166
167         # u2 member of g2
168         m = Message()
169         m.dn = Dn(self.ldb, "CN=g2,%s" % self.ou_groups)
170         m["member"] = MessageElement("cn=u2,%s" % self.ou_users,
171                                      FLAG_MOD_ADD, "member")
172         self.ldb.modify(m)
173
174         # u3 member of g3
175         m = Message()
176         m.dn = Dn(self.ldb, "cn=g3,%s" % self.ou_groups)
177         m["member"] = MessageElement("CN=u3,%s" % self.ou_users,
178                                      FLAG_MOD_ADD, "member")
179         self.ldb.modify(m)
180
181         # u4 member of g4
182         m = Message()
183         m.dn = Dn(self.ldb, "cn=g4,%s" % self.ou_groups)
184         m["member"] = MessageElement("cn=u4,%s" % self.ou_users,
185                                      FLAG_MOD_ADD, "member")
186         self.ldb.modify(m)
187
188         # g3 member of g4
189         m = Message()
190         m.dn = Dn(self.ldb, "CN=g4,%s" % self.ou_groups)
191         m["member"] = MessageElement("cn=g3,%s" % self.ou_groups,
192                                      FLAG_MOD_ADD, "member")
193         self.ldb.modify(m)
194
195         # g2 member of g3
196         m = Message()
197         m.dn = Dn(self.ldb, "cn=g3,%s" % self.ou_groups)
198         m["member"] = MessageElement("CN=g2,%s" % self.ou_groups,
199                                      FLAG_MOD_ADD, "member")
200         self.ldb.modify(m)
201
202         # g1 member of g2
203         m = Message()
204         m.dn = Dn(self.ldb, "cn=g2,%s" % self.ou_groups)
205         m["member"] = MessageElement("cn=g1,%s" % self.ou_groups,
206                                      FLAG_MOD_ADD, "member")
207         self.ldb.modify(m)
208
209         # The msDS-RevealedUsers is owned by system and cannot be modified
210         # directly. Set the schemaUpgradeInProgress flag as workaround
211         # and create this hierarchy:
212         # ou=computers
213         # |-> c1
214         # |   |->c2
215         # |   |  |->u1
216
217         #
218         # While appropriate for this test, this is NOT a good practice
219         # in general.  This is only done here because the alternative
220         # is to make a schema modification.
221         #
222         # IF/WHEN Samba protects this attribute better, this
223         # particular part of the test can be removed, as the same code
224         # is covered by the addressBookRoots2 case well enough.
225         #
226         m = Message()
227         m.dn = Dn(self.ldb, "")
228         m["e1"] = MessageElement("1", FLAG_MOD_REPLACE, "schemaUpgradeInProgress")
229         self.ldb.modify(m)
230
231         m = Message()
232         m.dn = Dn(self.ldb, "cn=c2,%s" % self.ou_computers)
233         m["e1"] = MessageElement("B:8:01010101:cn=c3,%s" % self.ou_computers,
234                                  FLAG_MOD_ADD, "msDS-RevealedUsers")
235         self.ldb.modify(m)
236
237         m = Message()
238         m.dn = Dn(self.ldb, "cn=c1,%s" % self.ou_computers)
239         m["e1"] = MessageElement("B:8:01010101:cn=c2,%s" % self.ou_computers,
240                                  FLAG_MOD_ADD, "msDS-RevealedUsers")
241         self.ldb.modify(m)
242
243         m = Message()
244         m.dn = Dn(self.ldb, "")
245         m["e1"] = MessageElement("0", FLAG_MOD_REPLACE, "schemaUpgradeInProgress")
246         self.ldb.modify(m)
247
248         # Add a couple of ms-Exch-Configuration-Container to test forward-link
249         # attributes without backward link (addressBookRoots2)
250         # e1
251         # |--> e2
252         # |    |--> c1
253         self.ldb.add({
254             "dn": "cn=e1,%s" % self.ou,
255             "objectclass": "msExchConfigurationContainer"})
256         self.ldb.add({
257             "dn": "cn=e2,%s" % self.ou,
258             "objectclass": "msExchConfigurationContainer"})
259
260         m = Message()
261         m.dn = Dn(self.ldb, "cn=e2,%s" % self.ou)
262         m["e1"] = MessageElement("cn=c1,%s" % self.ou_computers,
263                                  FLAG_MOD_ADD, "addressBookRoots2")
264         self.ldb.modify(m)
265
266         m = Message()
267         m.dn = Dn(self.ldb, "cn=e1,%s" % self.ou)
268         m["e1"] = MessageElement("cn=e2,%s" % self.ou,
269                                  FLAG_MOD_ADD, "addressBookRoots2")
270         self.ldb.modify(m)
271
272     def tearDown(self):
273         super(MatchRulesTests, self).tearDown()
274         self.ldb.delete(self.ou, controls=['tree_delete:0'])
275
276     def test_u1_member_of_g4(self):
277         # Search without transitive match must return 0 results
278         res1 = self.ldb.search("cn=g4,%s" % self.ou_groups,
279                                scope=SCOPE_BASE,
280                                expression="member=cn=u1,%s" % self.ou_users)
281         self.assertEqual(len(res1), 0)
282
283         res1 = self.ldb.search("cn=u1,%s" % self.ou_users,
284                                scope=SCOPE_BASE,
285                                expression="memberOf=cn=g4,%s" % self.ou_groups)
286         self.assertEqual(len(res1), 0)
287
288         # Search with transitive match must return 1 results
289         res1 = self.ldb.search("cn=g4,%s" % self.ou_groups,
290                                scope=SCOPE_BASE,
291                                expression="member:1.2.840.113556.1.4.1941:=cn=u1,%s" % self.ou_users)
292         self.assertEqual(len(res1), 1)
293         self.assertEqual(str(res1[0].dn).lower(), ("CN=g4,%s" % self.ou_groups).lower())
294
295         res1 = self.ldb.search("cn=u1,%s" % self.ou_users,
296                                scope=SCOPE_BASE,
297                                expression="memberOf:1.2.840.113556.1.4.1941:=cn=g4,%s" % self.ou_groups)
298         self.assertEqual(len(res1), 1)
299         self.assertEqual(str(res1[0].dn).lower(), ("CN=u1,%s" % self.ou_users).lower())
300
301     def test_g1_member_of_g4(self):
302         # Search without transitive match must return 0 results
303         res1 = self.ldb.search("cn=g4,%s" % self.ou_groups,
304                                scope=SCOPE_BASE,
305                                expression="member=cn=g1,%s" % self.ou_groups)
306         self.assertEqual(len(res1), 0)
307
308         res1 = self.ldb.search("cn=g1,%s" % self.ou_groups,
309                                scope=SCOPE_BASE,
310                                expression="memberOf=cn=g4,%s" % self.ou_groups)
311         self.assertEqual(len(res1), 0)
312
313         # Search with transitive match must return 1 results
314         res1 = self.ldb.search("cn=g4,%s" % self.ou_groups,
315                                scope=SCOPE_BASE,
316                                expression="member:1.2.840.113556.1.4.1941:=cn=g1,%s" % self.ou_groups)
317         self.assertEqual(len(res1), 1)
318         self.assertEqual(str(res1[0].dn).lower(), ("CN=g4,%s" % self.ou_groups).lower())
319
320         res1 = self.ldb.search("cn=g1,%s" % self.ou_groups,
321                                scope=SCOPE_BASE,
322                                expression="memberOf:1.2.840.113556.1.4.1941:=cn=g4,%s" % self.ou_groups)
323         self.assertEqual(len(res1), 1)
324         self.assertEqual(str(res1[0].dn).lower(), ("CN=g1,%s" % self.ou_groups).lower())
325
326     def test_u1_groups(self):
327         res1 = self.ldb.search(self.ou_groups,
328                                scope=SCOPE_SUBTREE,
329                                expression="member=cn=u1,%s" % self.ou_users)
330         self.assertEqual(len(res1), 1)
331         self.assertEqual(str(res1[0].dn).lower(), ("CN=g1,%s" % self.ou_groups).lower())
332
333         res1 = self.ldb.search(self.ou_users,
334                                scope=SCOPE_SUBTREE,
335                                expression="member=cn=u1,%s" % self.ou_users)
336         self.assertEqual(len(res1), 0)
337
338         res1 = self.ldb.search(self.ou_groups,
339                                scope=SCOPE_SUBTREE,
340                                expression="member:1.2.840.113556.1.4.1941:=cn=u1,%s" % self.ou_users)
341         self.assertEqual(len(res1), 4)
342         dn_list = [str(res.dn).lower() for res in res1]
343         self.assertTrue(("CN=g1,%s" % self.ou_groups).lower() in dn_list)
344         self.assertTrue(("CN=g2,%s" % self.ou_groups).lower() in dn_list)
345         self.assertTrue(("CN=g3,%s" % self.ou_groups).lower() in dn_list)
346         self.assertTrue(("CN=g4,%s" % self.ou_groups).lower() in dn_list)
347
348         res1 = self.ldb.search(self.ou_users,
349                                scope=SCOPE_SUBTREE,
350                                expression="member:1.2.840.113556.1.4.1941:=cn=u1,%s" % self.ou_users)
351         self.assertEqual(len(res1), 0)
352
353     def test_u2_groups(self):
354         res1 = self.ldb.search(self.ou_groups,
355                                scope=SCOPE_SUBTREE,
356                                expression="member=cn=u2,%s" % self.ou_users)
357         self.assertEqual(len(res1), 1)
358         self.assertEqual(str(res1[0].dn).lower(), ("CN=g2,%s" % self.ou_groups).lower())
359
360         res1 = self.ldb.search(self.ou_users,
361                                scope=SCOPE_SUBTREE,
362                                expression="member=cn=u2,%s" % self.ou_users)
363         self.assertEqual(len(res1), 0)
364
365         res1 = self.ldb.search(self.ou_groups,
366                                scope=SCOPE_SUBTREE,
367                                expression="member:1.2.840.113556.1.4.1941:=cn=u2,%s" % self.ou_users)
368         self.assertEqual(len(res1), 3)
369         dn_list = [str(res.dn).lower() for res in res1]
370         self.assertTrue(("CN=g2,%s" % self.ou_groups).lower() in dn_list)
371         self.assertTrue(("CN=g3,%s" % self.ou_groups).lower() in dn_list)
372         self.assertTrue(("CN=g4,%s" % self.ou_groups).lower() in dn_list)
373
374         res1 = self.ldb.search(self.ou_users,
375                                scope=SCOPE_SUBTREE,
376                                expression="member:1.2.840.113556.1.4.1941:=cn=u2,%s" % self.ou_users)
377         self.assertEqual(len(res1), 0)
378
379     def test_u3_groups(self):
380         res1 = self.ldb.search(self.ou_groups,
381                                scope=SCOPE_SUBTREE,
382                                expression="member=cn=u3,%s" % self.ou_users)
383         self.assertEqual(len(res1), 1)
384         self.assertEqual(str(res1[0].dn).lower(), ("CN=g3,%s" % self.ou_groups).lower())
385
386         res1 = self.ldb.search(self.ou_users,
387                                scope=SCOPE_SUBTREE,
388                                expression="member=cn=u3,%s" % self.ou_users)
389         self.assertEqual(len(res1), 0)
390
391         res1 = self.ldb.search(self.ou_groups,
392                                scope=SCOPE_SUBTREE,
393                                expression="member:1.2.840.113556.1.4.1941:=cn=u3,%s" % self.ou_users)
394         self.assertEqual(len(res1), 2)
395         dn_list = [str(res.dn).lower() for res in res1]
396         self.assertTrue(("CN=g3,%s" % self.ou_groups).lower() in dn_list)
397         self.assertTrue(("CN=g4,%s" % self.ou_groups).lower() in dn_list)
398
399         res1 = self.ldb.search(self.ou_users,
400                                scope=SCOPE_SUBTREE,
401                                expression="member:1.2.840.113556.1.4.1941:=cn=u3,%s" % self.ou_users)
402         self.assertEqual(len(res1), 0)
403
404     def test_u4_groups(self):
405         res1 = self.ldb.search(self.ou_groups,
406                                scope=SCOPE_SUBTREE,
407                                expression="member=cn=u4,%s" % self.ou_users)
408         self.assertEqual(len(res1), 1)
409         self.assertEqual(str(res1[0].dn).lower(), ("CN=g4,%s" % self.ou_groups).lower())
410
411         res1 = self.ldb.search(self.ou_users,
412                                scope=SCOPE_SUBTREE,
413                                expression="member=cn=u4,%s" % self.ou_users)
414         self.assertEqual(len(res1), 0)
415
416         res1 = self.ldb.search(self.ou_groups,
417                                scope=SCOPE_SUBTREE,
418                                expression="member:1.2.840.113556.1.4.1941:=cn=u4,%s" % self.ou_users)
419         self.assertEqual(len(res1), 1)
420         self.assertEqual(str(res1[0].dn).lower(), ("CN=g4,%s" % self.ou_groups).lower())
421
422         res1 = self.ldb.search(self.ou_users,
423                                scope=SCOPE_SUBTREE,
424                                expression="member:1.2.840.113556.1.4.1941:=cn=u4,%s" % self.ou_users)
425         self.assertEqual(len(res1), 0)
426
427     def test_extended_dn_u1(self):
428         res1 = self.ldb.search("cn=u1,%s" % self.ou_users,
429                                scope=SCOPE_BASE,
430                                expression="objectClass=*",
431                                attrs=['objectSid', 'objectGUID'])
432         self.assertEqual(len(res1), 1)
433         self.assertEqual(str(res1[0].dn).lower(), ("cn=u1,%s" % self.ou_users).lower())
434
435         sid = self.ldb.schema_format_value("objectSid", res1[0]["objectSid"][0])
436         guid = self.ldb.schema_format_value("objectGUID", res1[0]['objectGUID'][0])
437
438         res1 = self.ldb.search(self.ou_groups,
439                                scope=SCOPE_SUBTREE,
440                                expression="member=<SID=%s>" % sid)
441         self.assertEqual(len(res1), 1)
442         self.assertEqual(str(res1[0].dn).lower(), ("CN=g1,%s" % self.ou_groups).lower())
443
444         res1 = self.ldb.search(self.ou_groups,
445                                scope=SCOPE_SUBTREE,
446                                expression="member=<GUID=%s>" % guid)
447         self.assertEqual(len(res1), 1)
448         self.assertEqual(str(res1[0].dn).lower(), ("CN=g1,%s" % self.ou_groups).lower())
449
450         res1 = self.ldb.search(self.ou_groups,
451                                scope=SCOPE_SUBTREE,
452                                expression="member:1.2.840.113556.1.4.1941:=<SID=%s>" % sid)
453         self.assertEqual(len(res1), 4)
454         dn_list = [str(res.dn).lower() for res in res1]
455         self.assertTrue(("CN=g1,%s" % self.ou_groups).lower() in dn_list)
456         self.assertTrue(("CN=g2,%s" % self.ou_groups).lower() in dn_list)
457         self.assertTrue(("CN=g3,%s" % self.ou_groups).lower() in dn_list)
458         self.assertTrue(("CN=g4,%s" % self.ou_groups).lower() in dn_list)
459
460         res1 = self.ldb.search(self.ou_groups,
461                                scope=SCOPE_ONELEVEL,
462                                expression="member:1.2.840.113556.1.4.1941:=<SID=%s>" % sid)
463         self.assertEqual(len(res1), 4)
464         dn_list = [str(res.dn).lower() for res in res1]
465         self.assertTrue(("CN=g1,%s" % self.ou_groups).lower() in dn_list)
466         self.assertTrue(("CN=g2,%s" % self.ou_groups).lower() in dn_list)
467         self.assertTrue(("CN=g3,%s" % self.ou_groups).lower() in dn_list)
468         self.assertTrue(("CN=g4,%s" % self.ou_groups).lower() in dn_list)
469
470         res1 = self.ldb.search(self.ou_groups,
471                                scope=SCOPE_SUBTREE,
472                                expression="member:1.2.840.113556.1.4.1941:=<GUID=%s>" % guid)
473         self.assertEqual(len(res1), 4)
474         dn_list = [str(res.dn).lower() for res in res1]
475         self.assertTrue(("CN=g1,%s" % self.ou_groups).lower() in dn_list)
476         self.assertTrue(("CN=g2,%s" % self.ou_groups).lower() in dn_list)
477         self.assertTrue(("CN=g3,%s" % self.ou_groups).lower() in dn_list)
478         self.assertTrue(("CN=g4,%s" % self.ou_groups).lower() in dn_list)
479
480         res1 = self.ldb.search(self.ou_groups,
481                                scope=SCOPE_ONELEVEL,
482                                expression="member:1.2.840.113556.1.4.1941:=<GUID=%s>" % guid)
483         self.assertEqual(len(res1), 4)
484         dn_list = [str(res.dn).lower() for res in res1]
485         self.assertTrue(("CN=g1,%s" % self.ou_groups).lower() in dn_list)
486         self.assertTrue(("CN=g2,%s" % self.ou_groups).lower() in dn_list)
487         self.assertTrue(("CN=g3,%s" % self.ou_groups).lower() in dn_list)
488         self.assertTrue(("CN=g4,%s" % self.ou_groups).lower() in dn_list)
489
490     def test_extended_dn_u2(self):
491         res1 = self.ldb.search("cn=u2,%s" % self.ou_users,
492                                scope=SCOPE_BASE,
493                                expression="objectClass=*",
494                                attrs=['objectSid', 'objectGUID'])
495         self.assertEqual(len(res1), 1)
496         self.assertEqual(str(res1[0].dn).lower(), ("cn=u2,%s" % self.ou_users).lower())
497
498         sid = self.ldb.schema_format_value("objectSid", res1[0]["objectSid"][0])
499         guid = self.ldb.schema_format_value("objectGUID", res1[0]['objectGUID'][0])
500
501         res1 = self.ldb.search(self.ou_groups,
502                                scope=SCOPE_SUBTREE,
503                                expression="member=<SID=%s>" % sid)
504         self.assertEqual(len(res1), 1)
505         self.assertEqual(str(res1[0].dn).lower(), ("CN=g2,%s" % self.ou_groups).lower())
506
507         res1 = self.ldb.search(self.ou_groups,
508                                scope=SCOPE_SUBTREE,
509                                expression="member=<GUID=%s>" % guid)
510         self.assertEqual(len(res1), 1)
511         self.assertEqual(str(res1[0].dn).lower(), ("CN=g2,%s" % self.ou_groups).lower())
512
513         res1 = self.ldb.search(self.ou_groups,
514                                scope=SCOPE_SUBTREE,
515                                expression="member:1.2.840.113556.1.4.1941:=<SID=%s>" % sid)
516         self.assertEqual(len(res1), 3)
517         dn_list = [str(res.dn).lower() for res in res1]
518         self.assertTrue(("CN=g2,%s" % self.ou_groups).lower() in dn_list)
519         self.assertTrue(("CN=g3,%s" % self.ou_groups).lower() in dn_list)
520         self.assertTrue(("CN=g4,%s" % self.ou_groups).lower() in dn_list)
521
522         res1 = self.ldb.search(self.ou_groups,
523                                scope=SCOPE_ONELEVEL,
524                                expression="member:1.2.840.113556.1.4.1941:=<SID=%s>" % sid)
525         self.assertEqual(len(res1), 3)
526         dn_list = [str(res.dn).lower() for res in res1]
527         self.assertTrue(("CN=g2,%s" % self.ou_groups).lower() in dn_list)
528         self.assertTrue(("CN=g3,%s" % self.ou_groups).lower() in dn_list)
529         self.assertTrue(("CN=g4,%s" % self.ou_groups).lower() in dn_list)
530
531         res1 = self.ldb.search(self.ou_groups,
532                                scope=SCOPE_SUBTREE,
533                                expression="member:1.2.840.113556.1.4.1941:=<GUID=%s>" % guid)
534         self.assertEqual(len(res1), 3)
535         dn_list = [str(res.dn).lower() for res in res1]
536         self.assertTrue(("CN=g2,%s" % self.ou_groups).lower() in dn_list)
537         self.assertTrue(("CN=g3,%s" % self.ou_groups).lower() in dn_list)
538         self.assertTrue(("CN=g4,%s" % self.ou_groups).lower() in dn_list)
539
540         res1 = self.ldb.search(self.ou_groups,
541                                scope=SCOPE_ONELEVEL,
542                                expression="member:1.2.840.113556.1.4.1941:=<GUID=%s>" % guid)
543         self.assertEqual(len(res1), 3)
544         dn_list = [str(res.dn).lower() for res in res1]
545         self.assertTrue(("CN=g2,%s" % self.ou_groups).lower() in dn_list)
546         self.assertTrue(("CN=g3,%s" % self.ou_groups).lower() in dn_list)
547         self.assertTrue(("CN=g4,%s" % self.ou_groups).lower() in dn_list)
548
549     def test_extended_dn_u3(self):
550         res1 = self.ldb.search("cn=u3,%s" % self.ou_users,
551                                scope=SCOPE_BASE,
552                                expression="objectClass=*",
553                                attrs=['objectSid', 'objectGUID'])
554         self.assertEqual(len(res1), 1)
555         self.assertEqual(str(res1[0].dn).lower(), ("cn=u3,%s" % self.ou_users).lower())
556
557         sid = self.ldb.schema_format_value("objectSid", res1[0]["objectSid"][0])
558         guid = self.ldb.schema_format_value("objectGUID", res1[0]['objectGUID'][0])
559
560         res1 = self.ldb.search(self.ou_groups,
561                                scope=SCOPE_SUBTREE,
562                                expression="member=<SID=%s>" % sid)
563         self.assertEqual(len(res1), 1)
564         self.assertEqual(str(res1[0].dn).lower(), ("CN=g3,%s" % self.ou_groups).lower())
565
566         res1 = self.ldb.search(self.ou_groups,
567                                scope=SCOPE_SUBTREE,
568                                expression="member=<GUID=%s>" % guid)
569         self.assertEqual(len(res1), 1)
570         self.assertEqual(str(res1[0].dn).lower(), ("CN=g3,%s" % self.ou_groups).lower())
571
572         res1 = self.ldb.search(self.ou_groups,
573                                scope=SCOPE_SUBTREE,
574                                expression="member:1.2.840.113556.1.4.1941:=<SID=%s>" % sid)
575         self.assertEqual(len(res1), 2)
576         dn_list = [str(res.dn).lower() for res in res1]
577         self.assertTrue(("CN=g3,%s" % self.ou_groups).lower() in dn_list)
578         self.assertTrue(("CN=g4,%s" % self.ou_groups).lower() in dn_list)
579
580         res1 = self.ldb.search(self.ou_groups,
581                                scope=SCOPE_ONELEVEL,
582                                expression="member:1.2.840.113556.1.4.1941:=<SID=%s>" % sid)
583         self.assertEqual(len(res1), 2)
584         dn_list = [str(res.dn).lower() for res in res1]
585         self.assertTrue(("CN=g3,%s" % self.ou_groups).lower() in dn_list)
586         self.assertTrue(("CN=g4,%s" % self.ou_groups).lower() in dn_list)
587
588         res1 = self.ldb.search(self.ou_groups,
589                                scope=SCOPE_SUBTREE,
590                                expression="member:1.2.840.113556.1.4.1941:=<GUID=%s>" % guid)
591         self.assertEqual(len(res1), 2)
592         dn_list = [str(res.dn).lower() for res in res1]
593         self.assertTrue(("CN=g3,%s" % self.ou_groups).lower() in dn_list)
594         self.assertTrue(("CN=g4,%s" % self.ou_groups).lower() in dn_list)
595
596         res1 = self.ldb.search(self.ou_groups,
597                                scope=SCOPE_ONELEVEL,
598                                expression="member:1.2.840.113556.1.4.1941:=<GUID=%s>" % guid)
599         self.assertEqual(len(res1), 2)
600         dn_list = [str(res.dn).lower() for res in res1]
601         self.assertTrue(("CN=g3,%s" % self.ou_groups).lower() in dn_list)
602         self.assertTrue(("CN=g4,%s" % self.ou_groups).lower() in dn_list)
603
604     def test_extended_dn_u4(self):
605         res1 = self.ldb.search("cn=u4,%s" % self.ou_users,
606                                scope=SCOPE_BASE,
607                                expression="objectClass=*",
608                                attrs=['objectSid', 'objectGUID'])
609         self.assertEqual(len(res1), 1)
610         self.assertEqual(str(res1[0].dn).lower(), ("cn=u4,%s" % self.ou_users).lower())
611
612         sid = self.ldb.schema_format_value("objectSid", res1[0]["objectSid"][0])
613         guid = self.ldb.schema_format_value("objectGUID", res1[0]['objectGUID'][0])
614
615         res1 = self.ldb.search(self.ou_groups,
616                                scope=SCOPE_SUBTREE,
617                                expression="member=<SID=%s>" % sid)
618         self.assertEqual(len(res1), 1)
619         self.assertEqual(str(res1[0].dn).lower(), ("CN=g4,%s" % self.ou_groups).lower())
620
621         res1 = self.ldb.search(self.ou_groups,
622                                scope=SCOPE_SUBTREE,
623                                expression="member=<GUID=%s>" % guid)
624         self.assertEqual(len(res1), 1)
625         self.assertEqual(str(res1[0].dn).lower(), ("CN=g4,%s" % self.ou_groups).lower())
626
627         res1 = self.ldb.search(self.ou_groups,
628                                scope=SCOPE_ONELEVEL,
629                                expression="member=<GUID=%s>" % guid)
630         self.assertEqual(len(res1), 1)
631         self.assertEqual(str(res1[0].dn).lower(), ("CN=g4,%s" % self.ou_groups).lower())
632
633         res1 = self.ldb.search(self.ou_groups,
634                                scope=SCOPE_SUBTREE,
635                                expression="member:1.2.840.113556.1.4.1941:=<SID=%s>" % sid)
636         self.assertEqual(len(res1), 1)
637         self.assertEqual(str(res1[0].dn).lower(), ("CN=g4,%s" % self.ou_groups).lower())
638
639         res1 = self.ldb.search(self.ou_groups,
640                                scope=SCOPE_ONELEVEL,
641                                expression="member:1.2.840.113556.1.4.1941:=<SID=%s>" % sid)
642         self.assertEqual(len(res1), 1)
643         self.assertEqual(str(res1[0].dn).lower(), ("CN=g4,%s" % self.ou_groups).lower())
644
645         res1 = self.ldb.search(self.ou_groups,
646                                scope=SCOPE_SUBTREE,
647                                expression="member:1.2.840.113556.1.4.1941:=<GUID=%s>" % guid)
648         self.assertEqual(len(res1), 1)
649         self.assertEqual(str(res1[0].dn).lower(), ("CN=g4,%s" % self.ou_groups).lower())
650
651         res1 = self.ldb.search(self.ou_groups,
652                                scope=SCOPE_ONELEVEL,
653                                expression="member:1.2.840.113556.1.4.1941:=<GUID=%s>" % guid)
654         self.assertEqual(len(res1), 1)
655         self.assertEqual(str(res1[0].dn).lower(), ("CN=g4,%s" % self.ou_groups).lower())
656
657     def test_object_dn_binary(self):
658         res1 = self.ldb.search(self.ou_computers,
659                                scope=SCOPE_SUBTREE,
660                                expression="msDS-RevealedUsers=B:8:01010101:cn=c3,%s" % self.ou_computers)
661         self.assertEqual(len(res1), 1)
662         self.assertEqual(str(res1[0].dn).lower(), ("CN=c2,%s" % self.ou_computers).lower())
663
664         res1 = self.ldb.search(self.ou_computers,
665                                scope=SCOPE_ONELEVEL,
666                                expression="msDS-RevealedUsers=B:8:01010101:cn=c3,%s" % self.ou_computers)
667         self.assertEqual(len(res1), 1)
668         self.assertEqual(str(res1[0].dn).lower(), ("CN=c2,%s" % self.ou_computers).lower())
669
670         res1 = self.ldb.search(self.ou_computers,
671                                scope=SCOPE_SUBTREE,
672                                expression="msDS-RevealedUsers:1.2.840.113556.1.4.1941:=B:8:01010101:cn=c3,%s" % self.ou_computers)
673         self.assertEqual(len(res1), 2)
674         dn_list = [str(res.dn).lower() for res in res1]
675         self.assertTrue(("CN=c1,%s" % self.ou_computers).lower() in dn_list)
676         self.assertTrue(("CN=c2,%s" % self.ou_computers).lower() in dn_list)
677
678         res1 = self.ldb.search(self.ou_computers,
679                                scope=SCOPE_ONELEVEL,
680                                expression="msDS-RevealedUsers:1.2.840.113556.1.4.1941:=B:8:01010101:cn=c3,%s" % self.ou_computers)
681         self.assertEqual(len(res1), 2)
682         dn_list = [str(res.dn).lower() for res in res1]
683         self.assertTrue(("CN=c1,%s" % self.ou_computers).lower() in dn_list)
684         self.assertTrue(("CN=c2,%s" % self.ou_computers).lower() in dn_list)
685
686     def test_one_way_links(self):
687         res1 = self.ldb.search(self.ou,
688                                scope=SCOPE_SUBTREE,
689                                expression="addressBookRoots2=cn=c1,%s" % self.ou_computers)
690         self.assertEqual(len(res1), 1)
691         self.assertEqual(str(res1[0].dn).lower(), ("CN=e2,%s" % self.ou).lower())
692
693         res1 = self.ldb.search(self.ou,
694                                scope=SCOPE_ONELEVEL,
695                                expression="addressBookRoots2=cn=c1,%s" % self.ou_computers)
696         self.assertEqual(len(res1), 1)
697         self.assertEqual(str(res1[0].dn).lower(), ("CN=e2,%s" % self.ou).lower())
698
699         res1 = self.ldb.search(self.ou,
700                                scope=SCOPE_SUBTREE,
701                                expression="addressBookRoots2:1.2.840.113556.1.4.1941:=cn=c1,%s" % self.ou_computers)
702         self.assertEqual(len(res1), 2)
703         dn_list = [str(res.dn).lower() for res in res1]
704         self.assertTrue(("CN=e1,%s" % self.ou).lower() in dn_list)
705         self.assertTrue(("CN=e2,%s" % self.ou).lower() in dn_list)
706
707         res1 = self.ldb.search(self.ou,
708                                scope=SCOPE_ONELEVEL,
709                                expression="addressBookRoots2:1.2.840.113556.1.4.1941:=cn=c1,%s" % self.ou_computers)
710         self.assertEqual(len(res1), 2)
711         dn_list = [str(res.dn).lower() for res in res1]
712         self.assertTrue(("CN=e1,%s" % self.ou).lower() in dn_list)
713         self.assertTrue(("CN=e2,%s" % self.ou).lower() in dn_list)
714
715     def test_not_linked_attrs(self):
716         res1 = self.ldb.search(self.base_dn,
717                                scope=SCOPE_BASE,
718                                expression="wellKnownObjects=B:32:aa312825768811d1aded00c04fd8d5cd:CN=computers,%s" % self.base_dn)
719         self.assertEqual(len(res1), 1)
720         self.assertEqual(str(res1[0].dn).lower(), self.base_dn.lower())
721
722     def test_invalid_basedn(self):
723         res1 = self.ldb.search(self.base_dn,
724                                scope=SCOPE_SUBTREE,
725                                expression="memberOf:1.2.840.113556.1.4.1941:=cn=c1,ou=computers,ou=matchrulestest,%sXX" % self.base_dn)
726         self.assertEqual(len(res1), 0)
727
728         res1 = self.ldb.search(self.base_dn,
729                                scope=SCOPE_SUBTREE,
730                                expression="memberOf:1.2.840.113556.1.4.1941:=cn=XX,ou=computers,ou=matchrulestest,%s" % self.base_dn)
731         self.assertEqual(len(res1), 0)
732
733     def test_subtree(self):
734         res1 = self.ldb.search(self.ou,
735                                scope=SCOPE_SUBTREE,
736                                expression="otherWellKnownObjects=B:32:00000000000000000000000000000004:OU=o4,OU=o3,OU=o2,OU=o1,%s" % self.ou)
737         self.assertEqual(len(res1), 1)
738         self.assertEqual(str(res1[0].dn).lower(), ("OU=o3,OU=o2,OU=o1,%s" % self.ou).lower())
739
740         res1 = self.ldb.search(self.ou,
741                                scope=SCOPE_ONELEVEL,
742                                expression="otherWellKnownObjects=B:32:00000000000000000000000000000004:OU=o4,OU=o3,OU=o2,OU=o1,%s" % self.ou)
743         self.assertEqual(len(res1), 0)
744
745         res1 = self.ldb.search(self.ou,
746                                scope=SCOPE_SUBTREE,
747                                expression="otherWellKnownObjects:1.2.840.113556.1.4.1941:=B:32:00000000000000000000000000000004:OU=o4,OU=o3,OU=o2,OU=o1,%s" % self.ou)
748         self.assertEqual(len(res1), 0)
749
750         res1 = self.ldb.search(self.ou,
751                                scope=SCOPE_ONELEVEL,
752                                expression="otherWellKnownObjects:1.2.840.113556.1.4.1941:=B:32:00000000000000000000000000000004:OU=o4,OU=o3,OU=o2,OU=o1,%s" % self.ou)
753         self.assertEqual(len(res1), 0)
754
755     def test_unknown_oid(self):
756         res1 = self.ldb.search("cn=g4,%s" % self.ou_groups,
757                                scope=SCOPE_BASE,
758                                expression="member:2.4.681.226012.2.8.3882:=cn=u1,%s" % self.ou_users)
759         self.assertEqual(len(res1), 0)
760
761         res1 = self.ldb.search("cn=g4,%s" % self.ou_groups,
762                                scope=SCOPE_BASE,
763                                expression="member:8.16.8720.1008448.8.32.15528:=cn=u1,%s" % self.ou_users)
764         self.assertEqual(len(res1), 0)
765
766         res1 = self.ldb.search("cn=g4,%s" % self.ou_groups,
767                                scope=SCOPE_BASE,
768                                expression="member:1.2.3.4:=cn=u1,%s" % self.ou_users)
769         self.assertEqual(len(res1), 0)
770
771     def test_nul_text(self):
772         self.assertRaises(TypeError,
773                           lambda: self.ldb.search("cn=g4,%s" % self.ou_groups,
774                                                   scope=SCOPE_BASE,
775                                                   expression="\00member:1.2.840.113556.1.4.1941:=cn=u1,%s" % self.ou_users))
776         self.assertRaises(TypeError,
777                           lambda: self.ldb.search("cn=g4,%s" % self.ou_groups,
778                                                   scope=SCOPE_BASE,
779                                                   expression="member:1.2.840\00.113556.1.4.1941:=cn=u1,%s" % self.ou_users))
780         self.assertRaises(TypeError,
781                           lambda: self.ldb.search("cn=g4,%s" % self.ou_groups,
782                                                   scope=SCOPE_BASE,
783                                                   expression="member:1.2.840.113556.1.4.1941:=cn=u1\00,%s" % self.ou_users))
784         self.assertRaises(LdbError,
785                           lambda: self.ldb.search("cn=\00g4,%s" % self.ou_groups,
786                                                   scope=SCOPE_BASE,
787                                                   expression="member:1.2.840.113556.1.4.1941:=cn=u1,%s" % self.ou_users))
788         self.assertRaises(LdbError,
789                           lambda: self.ldb.search("cn=g4,%s" % self.ou_groups,
790                                                   scope=SCOPE_BASE,
791                                                   expression="member:1.2.840.113556.1.4.1941:"))
792         res1 = self.ldb.search("cn=g4,%s" % self.ou_groups,
793                                scope=SCOPE_BASE,
794                                expression="member:1.2.840.113556.1.4.1941:=")
795         self.assertEqual(len(res1), 0)
796         res1 = self.ldb.search("cn=g4,%s" % self.ou_groups,
797                                scope=SCOPE_BASE,
798                                expression="member=")
799         self.assertEqual(len(res1), 0)
800         res1 = self.ldb.search("cn=g4,%s" % self.ou_groups,
801                                scope=SCOPE_BASE,
802                                expression="member:1.2.840.113556.1.4.1941:=nonexistent")
803         self.assertEqual(len(res1), 0)
804         res1 = self.ldb.search("cn=g4,%s" % self.ou_groups,
805                                scope=SCOPE_BASE,
806                                expression="member=nonexistent")
807         self.assertEqual(len(res1), 0)
808         self.assertRaises(LdbError,
809                           lambda: self.ldb.search("cn=\00g4,%s" % self.ou_groups,
810                                                   scope=SCOPE_BASE,
811                                                   expression="member:1.2.840.113556.1.4.1941:cn=u1,%s" % self.ou_users))
812         self.assertRaises(LdbError,
813                           lambda: self.ldb.search("cn=\00g4,%s" % self.ou_groups,
814                                                   scope=SCOPE_BASE,
815                                                   expression="member:1.2.840.113556.1.4.1941:=cn=u1"))
816         self.assertRaises(LdbError,
817                           lambda: self.ldb.search("cn=\00g4,%s" % self.ou_groups,
818                                                   scope=SCOPE_BASE,
819                                                   expression="member:1.2.840.113556.1.4.1941:=cn="))
820         self.assertRaises(LdbError,
821                           lambda: self.ldb.search("cn=\00g4,%s" % self.ou_groups,
822                                                   scope=SCOPE_BASE,
823                                                   expression="member::=cn=u1,%s" % self.ou_users))
824
825     def test_misc_matches(self):
826         res1 = self.ldb.search(self.ou_groups,
827                                scope=SCOPE_BASE,
828                                expression="member=cn=g1,%s" % self.ou_groups)
829         self.assertEqual(len(res1), 0)
830
831         res1 = self.ldb.search("cn=g1,%s" % self.ou_groups,
832                                scope=SCOPE_BASE,
833                                expression="member=cn=g1,%s" % self.ou_groups)
834         self.assertEqual(len(res1), 0)
835
836         res1 = self.ldb.search(self.ou_groups,
837                                scope=SCOPE_SUBTREE,
838                                expression="member=cn=g1,%s" % self.ou_groups)
839         self.assertEqual(len(res1), 1)
840         self.assertEqual(str(res1[0].dn), "CN=g2,%s" % self.ou_groups)
841
842         res1 = self.ldb.search(self.ou_groups,
843                                scope=SCOPE_ONELEVEL,
844                                expression="member=cn=g1,%s" % self.ou_groups)
845         self.assertEqual(len(res1), 1)
846         self.assertEqual(str(res1[0].dn), "CN=g2,%s" % self.ou_groups)
847
848         res1 = self.ldb.search(self.ou_groups,
849                                scope=SCOPE_BASE,
850                                expression="member:1.2.840.113556.1.4.1941:=cn=g1,%s" % self.ou_groups)
851         self.assertEqual(len(res1), 0)
852
853         res1 = self.ldb.search("cn=g1,%s" % self.ou_groups,
854                                scope=SCOPE_BASE,
855                                expression="member:1.2.840.113556.1.4.1941:=cn=g1,%s" % self.ou_groups)
856         self.assertEqual(len(res1), 0)
857
858         res1 = self.ldb.search(self.ou_groups,
859                                scope=SCOPE_SUBTREE,
860                                expression="member:1.2.840.113556.1.4.1941:=cn=g1,%s" % self.ou_groups)
861         self.assertEqual(len(res1), 3)
862         dn_list = [str(res.dn) for res in res1]
863         self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
864         self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
865         self.assertTrue("CN=g4,%s" % self.ou_groups in dn_list)
866
867         res1 = self.ldb.search(self.ou_groups,
868                                scope=SCOPE_ONELEVEL,
869                                expression="member:1.2.840.113556.1.4.1941:=cn=g1,%s" % self.ou_groups)
870         self.assertEqual(len(res1), 3)
871         dn_list = [str(res.dn) for res in res1]
872         self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
873         self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
874         self.assertTrue("CN=g4,%s" % self.ou_groups in dn_list)
875
876         res1 = self.ldb.search(self.ou_groups,
877                                scope=SCOPE_SUBTREE,
878                                expression="member:1.2.840.113556.1.4.1941:=cn=g4,%s" % self.ou_groups)
879         self.assertEqual(len(res1), 0)
880
881         res1 = self.ldb.search(self.ou_groups,
882                                scope=SCOPE_ONELEVEL,
883                                expression="member:1.2.840.113556.1.4.1941:=cn=g4,%s" % self.ou_groups)
884         self.assertEqual(len(res1), 0)
885
886         res1 = self.ldb.search(self.ou_groups,
887                                scope=SCOPE_BASE,
888                                expression="memberOf=cn=g4,%s" % self.ou_groups)
889         self.assertEqual(len(res1), 0)
890
891         res1 = self.ldb.search("cn=g4,%s" % self.ou_groups,
892                                scope=SCOPE_BASE,
893                                expression="memberOf=cn=g4,%s" % self.ou_groups)
894         self.assertEqual(len(res1), 0)
895
896         res1 = self.ldb.search(self.ou_groups,
897                                scope=SCOPE_SUBTREE,
898                                expression="memberOf=cn=g4,%s" % self.ou_groups)
899         self.assertEqual(len(res1), 1)
900         self.assertEqual(str(res1[0].dn), ("CN=g3,%s" % self.ou_groups))
901
902         res1 = self.ldb.search(self.ou_groups,
903                                scope=SCOPE_ONELEVEL,
904                                expression="memberOf=cn=g4,%s" % self.ou_groups)
905         self.assertEqual(len(res1), 1)
906         self.assertEqual(str(res1[0].dn), ("CN=g3,%s" % self.ou_groups))
907
908         res1 = self.ldb.search(self.ou_groups,
909                                scope=SCOPE_BASE,
910                                expression="memberOf:1.2.840.113556.1.4.1941:=cn=g4,%s" % self.ou_groups)
911         self.assertEqual(len(res1), 0)
912
913         res1 = self.ldb.search("cn=g4,%s" % self.ou_groups,
914                                scope=SCOPE_BASE,
915                                expression="memberOf:1.2.840.113556.1.4.1941:=cn=g4,%s" % self.ou_groups)
916         self.assertEqual(len(res1), 0)
917
918         res1 = self.ldb.search(self.ou_groups,
919                                scope=SCOPE_SUBTREE,
920                                expression="memberOf:1.2.840.113556.1.4.1941:=cn=g4,%s" % self.ou_groups)
921         self.assertEqual(len(res1), 3)
922         dn_list = [str(res.dn) for res in res1]
923         self.assertTrue("CN=g1,%s" % self.ou_groups in dn_list)
924         self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
925         self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
926
927         res1 = self.ldb.search(self.ou_groups,
928                                scope=SCOPE_ONELEVEL,
929                                expression="memberOf:1.2.840.113556.1.4.1941:=cn=g4,%s" % self.ou_groups)
930         self.assertEqual(len(res1), 3)
931         dn_list = [str(res.dn) for res in res1]
932         self.assertTrue("CN=g1,%s" % self.ou_groups in dn_list)
933         self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
934         self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
935
936         res1 = self.ldb.search(self.ou_groups,
937                                scope=SCOPE_SUBTREE,
938                                expression="memberOf:1.2.840.113556.1.4.1941:=cn=g1,%s" % self.ou_groups)
939         self.assertEqual(len(res1), 0)
940
941         res1 = self.ldb.search(self.ou_groups,
942                                scope=SCOPE_SUBTREE,
943                                expression="memberOf:1.2.840.113556.1.4.1941:=cn=g1,%s" % self.ou_groups)
944         self.assertEqual(len(res1), 0)
945
946 class MatchRuleConditionTests(samba.tests.TestCase):
947     def setUp(self):
948         super(MatchRuleConditionTests, self).setUp()
949         self.lp = lp
950         self.ldb = SamDB(host, credentials=creds, session_info=system_session(lp), lp=lp)
951         self.base_dn = self.ldb.domain_dn()
952         self.ou = "OU=matchruleconditiontests,%s" % self.base_dn
953         self.ou_users = "OU=users,%s" % self.ou
954         self.ou_groups = "OU=groups,%s" % self.ou
955         self.ou_computers = "OU=computers,%s" % self.ou
956
957         # Add a organizational unit to create objects
958         self.ldb.add({
959             "dn": self.ou,
960             "objectclass": "organizationalUnit"})
961
962         # Create users, groups, and computers
963         self.ldb.add({
964             "dn": self.ou_users,
965             "objectclass": "organizationalUnit"})
966         self.ldb.add({
967             "dn": self.ou_groups,
968             "objectclass": "organizationalUnit"})
969         self.ldb.add({
970             "dn": self.ou_computers,
971             "objectclass": "organizationalUnit"})
972
973         self.ldb.add({
974             "dn": "cn=g1,%s" % self.ou_groups,
975             "objectclass": "group" })
976         self.ldb.add({
977             "dn": "cn=g2,%s" % self.ou_groups,
978             "objectclass": "group" })
979         self.ldb.add({
980             "dn": "cn=g3,%s" % self.ou_groups,
981             "objectclass": "group" })
982         self.ldb.add({
983             "dn": "cn=g4,%s" % self.ou_groups,
984             "objectclass": "group" })
985
986         self.ldb.add({
987             "dn": "cn=u1,%s" % self.ou_users,
988             "objectclass": "group"})
989         self.ldb.add({
990             "dn": "cn=u2,%s" % self.ou_users,
991             "objectclass": "group"})
992         self.ldb.add({
993             "dn": "cn=u3,%s" % self.ou_users,
994             "objectclass": "group"})
995         self.ldb.add({
996             "dn": "cn=u4,%s" % self.ou_users,
997             "objectclass": "group"})
998
999         self.ldb.add({
1000             "dn": "cn=c1,%s" % self.ou_computers,
1001             "objectclass": "user"})
1002
1003         self.ldb.add({
1004             "dn": "cn=c2,%s" % self.ou_computers,
1005             "objectclass": "user"})
1006
1007         self.ldb.add({
1008             "dn": "cn=c3,%s" % self.ou_computers,
1009             "objectclass": "user"})
1010
1011         self.ldb.add({
1012             "dn": "cn=c4,%s" % self.ou_computers,
1013             "objectclass": "user"})
1014
1015         # Assign groups according to the following structure:
1016         #  g1-->g2---->g3   --g4
1017         #     \  |    / |  / / |
1018         #  u1- >u2-- | u3<- | u4
1019         #     \     \ \      \ |
1020         #  c1* >c2   ->c3     c4
1021         # *c1 is a member of u1, u2, u3, and u4
1022
1023         # u2 is a member of g1 and g2
1024         m = Message()
1025         m.dn = Dn(self.ldb, "CN=g1,%s" % self.ou_groups)
1026         m["member"] = MessageElement("CN=u2,%s" % self.ou_users,
1027                                      FLAG_MOD_ADD, "member")
1028         self.ldb.modify(m)
1029
1030         m = Message()
1031         m.dn = Dn(self.ldb, "CN=g2,%s" % self.ou_groups)
1032         m["member"] = MessageElement("CN=u2,%s" % self.ou_users,
1033                                      FLAG_MOD_ADD, "member")
1034         self.ldb.modify(m)
1035
1036         # g2 is a member of g1
1037         m = Message()
1038         m.dn = Dn(self.ldb, "CN=g1,%s" % self.ou_groups)
1039         m["member"] = MessageElement("CN=g2,%s" % self.ou_groups,
1040                                      FLAG_MOD_ADD, "member")
1041         self.ldb.modify(m)
1042
1043         # g3 is a member of g2
1044         m = Message()
1045         m.dn = Dn(self.ldb, "CN=g2,%s" % self.ou_groups)
1046         m["member"] = MessageElement("CN=g3,%s" % self.ou_groups,
1047                                      FLAG_MOD_ADD, "member")
1048         self.ldb.modify(m)
1049
1050         # u3 is a member of g3 and g4
1051         m = Message()
1052         m.dn = Dn(self.ldb, "CN=g3,%s" % self.ou_groups)
1053         m["member"] = MessageElement("CN=u3,%s" % self.ou_users,
1054                                      FLAG_MOD_ADD, "member")
1055         self.ldb.modify(m)
1056
1057         m = Message()
1058         m.dn = Dn(self.ldb, "CN=g4,%s" % self.ou_groups)
1059         m["member"] = MessageElement("CN=u3,%s" % self.ou_users,
1060                                      FLAG_MOD_ADD, "member")
1061         self.ldb.modify(m)
1062
1063         # u4 is a member of g4
1064         m = Message()
1065         m.dn = Dn(self.ldb, "CN=g4,%s" % self.ou_groups)
1066         m["member"] = MessageElement("CN=u4,%s" % self.ou_users,
1067                                      FLAG_MOD_ADD, "member")
1068         self.ldb.modify(m)
1069
1070         # c1 is a member of u1, u2, u3, and u4
1071         m = Message()
1072         m.dn = Dn(self.ldb, "CN=u1,%s" % self.ou_users)
1073         m["member"] = MessageElement("CN=c1,%s" % self.ou_computers,
1074                                      FLAG_MOD_ADD, "member")
1075         self.ldb.modify(m)
1076
1077         m = Message()
1078         m.dn = Dn(self.ldb, "CN=u2,%s" % self.ou_users)
1079         m["member"] = MessageElement("CN=c1,%s" % self.ou_computers,
1080                                      FLAG_MOD_ADD, "member")
1081         self.ldb.modify(m)
1082
1083         m = Message()
1084         m.dn = Dn(self.ldb, "CN=u3,%s" % self.ou_users)
1085         m["member"] = MessageElement("CN=c1,%s" % self.ou_computers,
1086                                      FLAG_MOD_ADD, "member")
1087         self.ldb.modify(m)
1088
1089         m = Message()
1090         m.dn = Dn(self.ldb, "CN=u4,%s" % self.ou_users)
1091         m["member"] = MessageElement("CN=c1,%s" % self.ou_computers,
1092                                      FLAG_MOD_ADD, "member")
1093         self.ldb.modify(m)
1094
1095         # c2 is a member of u1
1096         m = Message()
1097         m.dn = Dn(self.ldb, "CN=u1,%s" % self.ou_users)
1098         m["member"] = MessageElement("CN=c2,%s" % self.ou_computers,
1099                                      FLAG_MOD_ADD, "member")
1100         self.ldb.modify(m)
1101
1102         # c3 is a member of u2 and g3
1103         m = Message()
1104         m.dn = Dn(self.ldb, "CN=u2,%s" % self.ou_users)
1105         m["member"] = MessageElement("CN=c3,%s" % self.ou_computers,
1106                                      FLAG_MOD_ADD, "member")
1107         self.ldb.modify(m)
1108
1109         m = Message()
1110         m.dn = Dn(self.ldb, "CN=g3,%s" % self.ou_groups)
1111         m["member"] = MessageElement("CN=c3,%s" % self.ou_computers,
1112                                      FLAG_MOD_ADD, "member")
1113         self.ldb.modify(m)
1114
1115         # c4 is a member of u4 and g4
1116         m = Message()
1117         m.dn = Dn(self.ldb, "CN=u4,%s" % self.ou_users)
1118         m["member"] = MessageElement("CN=c4,%s" % self.ou_computers,
1119                                      FLAG_MOD_ADD, "member")
1120         self.ldb.modify(m)
1121
1122         m = Message()
1123         m.dn = Dn(self.ldb, "CN=g4,%s" % self.ou_groups)
1124         m["member"] = MessageElement("CN=c4,%s" % self.ou_computers,
1125                                      FLAG_MOD_ADD, "member")
1126         self.ldb.modify(m)
1127
1128         self.question = 6*(9-2)
1129         self.answer = 42
1130
1131     def tearDown(self):
1132         super(MatchRuleConditionTests, self).tearDown()
1133         self.ldb.delete(self.ou, controls=['tree_delete:0'])
1134
1135
1136     def test_g1_members(self):
1137         res1 = self.ldb.search(self.ou,
1138                                scope=SCOPE_SUBTREE,
1139                                expression="memberOf=cn=g1,%s" % self.ou_groups)
1140         self.assertEquals(len(res1), 2)
1141         dn_list = [str(res.dn) for res in res1]
1142         self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
1143         self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
1144
1145         res1 = self.ldb.search(self.ou,
1146                                scope=SCOPE_SUBTREE,
1147                                expression="memberOf:1.2.840.113556.1.4.1941:=cn=g1,%s" % self.ou_groups)
1148         self.assertEquals(len(res1), 6)
1149         dn_list = [str(res.dn) for res in res1]
1150         self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
1151         self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
1152         self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
1153         self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
1154         self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
1155         self.assertTrue("CN=c3,%s" % self.ou_computers in dn_list)
1156
1157         res1 = self.ldb.search(self.ou,
1158                                scope=SCOPE_SUBTREE,
1159                                expression="member=cn=g1,%s" % self.ou_groups)
1160         self.assertEquals(len(res1), 0)
1161
1162         res1 = self.ldb.search(self.ou,
1163                                scope=SCOPE_SUBTREE,
1164                                expression="member:1.2.840.113556.1.4.1941:=cn=g1,%s" % self.ou_groups)
1165         self.assertEquals(len(res1), 0)
1166
1167     def test_g2_members(self):
1168         res1 = self.ldb.search(self.ou,
1169                                scope=SCOPE_SUBTREE,
1170                                expression="memberOf=cn=g2,%s" % self.ou_groups)
1171         self.assertEquals(len(res1), 2)
1172         dn_list = [str(res.dn) for res in res1]
1173         self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
1174         self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
1175
1176         res1 = self.ldb.search(self.ou,
1177                                scope=SCOPE_SUBTREE,
1178                                expression="memberOf:1.2.840.113556.1.4.1941:=cn=g2,%s" % self.ou_groups)
1179         self.assertEquals(len(res1), 5)
1180         dn_list = [str(res.dn) for res in res1]
1181         self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
1182         self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
1183         self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
1184         self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
1185         self.assertTrue("CN=c3,%s" % self.ou_computers in dn_list)
1186
1187         res1 = self.ldb.search(self.ou,
1188                                scope=SCOPE_SUBTREE,
1189                                expression="member=cn=g2,%s" % self.ou_groups)
1190         self.assertEquals(len(res1), 1)
1191         self.assertEquals(str(res1[0].dn), "CN=g1,%s" % self.ou_groups)
1192
1193         res1 = self.ldb.search(self.ou,
1194                                scope=SCOPE_SUBTREE,
1195                                expression="member:1.2.840.113556.1.4.1941:=cn=g2,%s" % self.ou_groups)
1196         self.assertEquals(len(res1), 1)
1197         self.assertEquals(str(res1[0].dn), "CN=g1,%s" % self.ou_groups)
1198
1199     def test_g3_members(self):
1200         res1 = self.ldb.search(self.ou,
1201                                scope=SCOPE_SUBTREE,
1202                                expression="memberOf=cn=g3,%s" % self.ou_groups)
1203         self.assertEquals(len(res1), 2)
1204         dn_list = [str(res.dn) for res in res1]
1205         self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
1206         self.assertTrue("CN=c3,%s" % self.ou_computers in dn_list)
1207
1208         res1 = self.ldb.search(self.ou,
1209                                scope=SCOPE_SUBTREE,
1210                                expression="memberOf:1.2.840.113556.1.4.1941:=cn=g3,%s" % self.ou_groups)
1211         self.assertEquals(len(res1), 3)
1212         dn_list = [str(res.dn) for res in res1]
1213         self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
1214         self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
1215         self.assertTrue("CN=c3,%s" % self.ou_computers in dn_list)
1216
1217         res1 = self.ldb.search(self.ou,
1218                                scope=SCOPE_SUBTREE,
1219                                expression="member=cn=g3,%s" % self.ou_groups)
1220         self.assertEquals(len(res1), 1)
1221         self.assertEquals(str(res1[0].dn), "CN=g2,%s" % self.ou_groups)
1222
1223         res1 = self.ldb.search(self.ou,
1224                                scope=SCOPE_SUBTREE,
1225                                expression="member:1.2.840.113556.1.4.1941:=cn=g3,%s" % self.ou_groups)
1226         self.assertEquals(len(res1), 2)
1227         dn_list = [str(res.dn) for res in res1]
1228         self.assertTrue("CN=g1,%s" % self.ou_groups in dn_list)
1229         self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
1230
1231     def test_g4_members(self):
1232         res1 = self.ldb.search(self.ou,
1233                                scope=SCOPE_SUBTREE,
1234                                expression="memberOf=cn=g4,%s" % self.ou_groups)
1235         self.assertEquals(len(res1), 3)
1236         dn_list = [str(res.dn) for res in res1]
1237         self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
1238         self.assertTrue("CN=u4,%s" % self.ou_users in dn_list)
1239         self.assertTrue("CN=c4,%s" % self.ou_computers in dn_list)
1240
1241         res1 = self.ldb.search(self.ou,
1242                                scope=SCOPE_SUBTREE,
1243                                expression="memberOf:1.2.840.113556.1.4.1941:=cn=g4,%s" % self.ou_groups)
1244         self.assertEquals(len(res1), 4)
1245         dn_list = [str(res.dn) for res in res1]
1246         self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
1247         self.assertTrue("CN=u4,%s" % self.ou_users in dn_list)
1248         self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
1249         self.assertTrue("CN=c4,%s" % self.ou_computers in dn_list)
1250
1251         res1 = self.ldb.search(self.ou,
1252                                scope=SCOPE_SUBTREE,
1253                                expression="member=cn=g4,%s" % self.ou_groups)
1254         self.assertEquals(len(res1), 0)
1255
1256         res1 = self.ldb.search(self.ou,
1257                                scope=SCOPE_SUBTREE,
1258                                expression="member:1.2.840.113556.1.4.1941:=cn=g4,%s" % self.ou_groups)
1259         self.assertEquals(len(res1), 0)
1260
1261     def test_u1_members(self):
1262         res1 = self.ldb.search(self.ou,
1263                                scope=SCOPE_SUBTREE,
1264                                expression="memberOf=cn=u1,%s" % self.ou_users)
1265         self.assertEqual(len(res1), 2)
1266         dn_list = [str(res.dn) for res in res1]
1267         self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
1268         self.assertTrue("CN=c2,%s" % self.ou_computers in dn_list)
1269
1270         res1 = self.ldb.search(self.ou,
1271                                scope=SCOPE_SUBTREE,
1272                                expression="memberOf:1.2.840.113556.1.4.1941:=cn=u1,%s" % self.ou_users)
1273         self.assertEqual(len(res1), 2)
1274         dn_list = [str(res.dn) for res in res1]
1275         self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
1276         self.assertTrue("CN=c2,%s" % self.ou_computers in dn_list)
1277
1278         res1 = self.ldb.search(self.ou,
1279                                scope=SCOPE_SUBTREE,
1280                                expression="member=cn=u1,%s" % self.ou_users)
1281         self.assertEqual(len(res1), 0)
1282
1283         res1 = self.ldb.search(self.ou,
1284                                scope=SCOPE_SUBTREE,
1285                                expression="member:1.2.840.113556.1.4.1941:=cn=u1,%s" % self.ou_users)
1286         self.assertEqual(len(res1), 0)
1287
1288     def test_u2_members(self):
1289         res1 = self.ldb.search(self.ou,
1290                                scope=SCOPE_SUBTREE,
1291                                expression="memberOf=cn=u2,%s" % self.ou_users)
1292         self.assertEqual(len(res1), 2)
1293         dn_list = [str(res.dn) for res in res1]
1294         self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
1295         self.assertTrue("CN=c3,%s" % self.ou_computers in dn_list)
1296
1297         res1 = self.ldb.search(self.ou,
1298                                scope=SCOPE_SUBTREE,
1299                                expression="memberOf:1.2.840.113556.1.4.1941:=cn=u2,%s" % self.ou_users)
1300         self.assertEqual(len(res1), 2)
1301         dn_list = [str(res.dn) for res in res1]
1302         self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
1303         self.assertTrue("CN=c3,%s" % self.ou_computers in dn_list)
1304
1305         res1 = self.ldb.search(self.ou,
1306                                scope=SCOPE_SUBTREE,
1307                                expression="member=cn=u2,%s" % self.ou_users)
1308         self.assertEqual(len(res1), 2)
1309         dn_list = [str(res.dn) for res in res1]
1310         self.assertTrue("CN=g1,%s" % self.ou_groups in dn_list)
1311         self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
1312
1313         res1 = self.ldb.search(self.ou,
1314                                scope=SCOPE_SUBTREE,
1315                                expression="member:1.2.840.113556.1.4.1941:=cn=u2,%s" % self.ou_users)
1316         self.assertEqual(len(res1), 2)
1317         dn_list = [str(res.dn) for res in res1]
1318         self.assertTrue("CN=g1,%s" % self.ou_groups in dn_list)
1319         self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
1320
1321     def test_u3_members(self):
1322         res1 = self.ldb.search(self.ou,
1323                                scope=SCOPE_SUBTREE,
1324                                expression="member=cn=u3,%s" % self.ou_users)
1325         self.assertEqual(len(res1), 2)
1326         dn_list = [str(res.dn) for res in res1]
1327         self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
1328         self.assertTrue("CN=g4,%s" % self.ou_groups in dn_list)
1329
1330         res1 = self.ldb.search(self.ou,
1331                                scope=SCOPE_SUBTREE,
1332                                expression="member:1.2.840.113556.1.4.1941:=cn=u3,%s" % self.ou_users)
1333         self.assertEqual(len(res1), 4)
1334         dn_list = [str(res.dn) for res in res1]
1335         self.assertTrue("CN=g1,%s" % self.ou_groups in dn_list)
1336         self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
1337         self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
1338         self.assertTrue("CN=g4,%s" % self.ou_groups in dn_list)
1339
1340         res1 = self.ldb.search(self.ou,
1341                                scope=SCOPE_SUBTREE,
1342                                expression="memberOf=cn=u3,%s" % self.ou_users)
1343         self.assertEqual(len(res1), 1)
1344         self.assertEqual(str(res1[0].dn), "CN=c1,%s" % self.ou_computers)
1345
1346         res1 = self.ldb.search(self.ou,
1347                                scope=SCOPE_SUBTREE,
1348                                expression="memberOf:1.2.840.113556.1.4.1941:=cn=u3,%s" % self.ou_users)
1349         self.assertEqual(len(res1), 1)
1350         self.assertEqual(str(res1[0].dn), "CN=c1,%s" % self.ou_computers)
1351
1352     def test_u4_members(self):
1353         res1 = self.ldb.search(self.ou,
1354                                scope=SCOPE_SUBTREE,
1355                                expression="member=cn=u4,%s" % self.ou_users)
1356         self.assertEqual(len(res1), 1)
1357         self.assertEqual(str(res1[0].dn), "CN=g4,%s" % self.ou_groups)
1358
1359         res1 = self.ldb.search(self.ou,
1360                                scope=SCOPE_SUBTREE,
1361                                expression="member:1.2.840.113556.1.4.1941:=cn=u4,%s" % self.ou_users)
1362         self.assertEqual(len(res1), 1)
1363         self.assertEqual(str(res1[0].dn), "CN=g4,%s" % self.ou_groups)
1364
1365         res1 = self.ldb.search(self.ou,
1366                                scope=SCOPE_SUBTREE,
1367                                expression="memberOf=cn=u4,%s" % self.ou_users)
1368         self.assertEqual(len(res1), 2)
1369         dn_list = [str(res.dn) for res in res1]
1370         self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
1371         self.assertTrue("CN=c4,%s" % self.ou_computers in dn_list)
1372
1373         res1 = self.ldb.search(self.ou,
1374                                scope=SCOPE_SUBTREE,
1375                                expression="memberOf:1.2.840.113556.1.4.1941:=cn=u4,%s" % self.ou_users)
1376         self.assertEqual(len(res1), 2)
1377         dn_list = [str(res.dn) for res in res1]
1378         self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
1379         self.assertTrue("CN=c4,%s" % self.ou_computers in dn_list)
1380
1381     def test_c1_members(self):
1382         res1 = self.ldb.search(self.ou,
1383                                scope=SCOPE_SUBTREE,
1384                                expression="member=cn=c1,%s" % self.ou_computers)
1385         self.assertEqual(len(res1), 4)
1386         dn_list = [str(res.dn) for res in res1]
1387         self.assertTrue("CN=u1,%s" % self.ou_users in dn_list)
1388         self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
1389         self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
1390         self.assertTrue("CN=u4,%s" % self.ou_users in dn_list)
1391
1392         res1 = self.ldb.search(self.ou,
1393                                scope=SCOPE_SUBTREE,
1394                                expression="member:1.2.840.113556.1.4.1941:=cn=c1,%s" % self.ou_computers)
1395         self.assertEqual(len(res1), 8)
1396         dn_list = [str(res.dn) for res in res1]
1397         self.assertTrue("CN=u1,%s" % self.ou_users in dn_list)
1398         self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
1399         self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
1400         self.assertTrue("CN=u4,%s" % self.ou_users in dn_list)
1401         self.assertTrue("CN=g1,%s" % self.ou_groups in dn_list)
1402         self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
1403         self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
1404         self.assertTrue("CN=g4,%s" % self.ou_groups in dn_list)
1405
1406         res1 = self.ldb.search(self.ou,
1407                                scope=SCOPE_SUBTREE,
1408                                expression="memberOf=cn=c1,%s" % self.ou_computers)
1409         self.assertEqual(len(res1), 0)
1410
1411         res1 = self.ldb.search(self.ou,
1412                                scope=SCOPE_SUBTREE,
1413                                expression="memberOf:1.2.840.113556.1.4.1941:=cn=c1,%s" % self.ou_computers)
1414         self.assertEqual(len(res1), 0)
1415
1416     def test_c2_members(self):
1417         res1 = self.ldb.search(self.ou,
1418                                scope=SCOPE_SUBTREE,
1419                                expression="member=cn=c2,%s" % self.ou_computers)
1420         self.assertEqual(len(res1), 1)
1421         self.assertEqual(str(res1[0].dn), "CN=u1,%s" % self.ou_users)
1422
1423         res1 = self.ldb.search(self.ou,
1424                                scope=SCOPE_SUBTREE,
1425                                expression="member:1.2.840.113556.1.4.1941:=cn=c2,%s" % self.ou_computers)
1426         self.assertEqual(len(res1), 1)
1427         self.assertEqual(str(res1[0].dn), "CN=u1,%s" % self.ou_users)
1428
1429         res1 = self.ldb.search(self.ou,
1430                                scope=SCOPE_SUBTREE,
1431                                expression="memberOf=cn=c2,%s" % self.ou_computers)
1432         self.assertEqual(len(res1), 0)
1433
1434         res1 = self.ldb.search(self.ou,
1435                                scope=SCOPE_SUBTREE,
1436                                expression="memberOf:1.2.840.113556.1.4.1941:=cn=c2,%s" % self.ou_computers)
1437         self.assertEqual(len(res1), 0)
1438
1439     def test_c3_members(self):
1440         res1 = self.ldb.search(self.ou,
1441                                scope=SCOPE_SUBTREE,
1442                                expression="member=cn=c3,%s" % self.ou_computers)
1443         self.assertEqual(len(res1), 2)
1444         dn_list = [str(res.dn) for res in res1]
1445         self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
1446         self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
1447
1448         res1 = self.ldb.search(self.ou,
1449                                scope=SCOPE_SUBTREE,
1450                                expression="member:1.2.840.113556.1.4.1941:=cn=c3,%s" % self.ou_computers)
1451         self.assertEqual(len(res1), 4)
1452         dn_list = [str(res.dn) for res in res1]
1453         self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
1454         self.assertTrue("CN=g1,%s" % self.ou_groups in dn_list)
1455         self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
1456         self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
1457
1458         res1 = self.ldb.search(self.ou,
1459                                scope=SCOPE_SUBTREE,
1460                                expression="memberOf=cn=c3,%s" % self.ou_computers)
1461         self.assertEqual(len(res1), 0)
1462
1463         res1 = self.ldb.search(self.ou,
1464                                scope=SCOPE_SUBTREE,
1465                                expression="memberOf:1.2.840.113556.1.4.1941:=cn=c3,%s" % self.ou_computers)
1466         self.assertEqual(len(res1), 0)
1467
1468     def test_c4_members(self):
1469         res1 = self.ldb.search(self.ou,
1470                                scope=SCOPE_SUBTREE,
1471                                expression="member=cn=c4,%s" % self.ou_computers)
1472         self.assertEqual(len(res1), 2)
1473         dn_list = [str(res.dn) for res in res1]
1474         self.assertTrue("CN=g4,%s" % self.ou_groups in dn_list)
1475         self.assertTrue("CN=u4,%s" % self.ou_users in dn_list)
1476
1477         res1 = self.ldb.search(self.ou,
1478                                scope=SCOPE_SUBTREE,
1479                                expression="member:1.2.840.113556.1.4.1941:=cn=c4,%s" % self.ou_computers)
1480         self.assertEqual(len(res1), 2)
1481         dn_list = [str(res.dn) for res in res1]
1482         self.assertTrue("CN=u4,%s" % self.ou_users in dn_list)
1483         self.assertTrue("CN=g4,%s" % self.ou_groups in dn_list)
1484
1485         res1 = self.ldb.search(self.ou,
1486                                scope=SCOPE_SUBTREE,
1487                                expression="memberOf=cn=c4,%s" % self.ou_computers)
1488         self.assertEqual(len(res1), 0)
1489
1490         res1 = self.ldb.search(self.ou,
1491                                scope=SCOPE_SUBTREE,
1492                                expression="memberOf:1.2.840.113556.1.4.1941:=cn=c4,%s" % self.ou_computers)
1493         self.assertEqual(len(res1), 0)
1494
1495     def test_or_member_queries(self):
1496         res1 = self.ldb.search(self.ou,
1497                                scope=SCOPE_SUBTREE,
1498                                expression=("(|(member:1.2.840.113556.1.4.1941:=cn=c1,%s)"
1499                                            "(member:1.2.840.113556.1.4.1941:=cn=c2,%s))") % (
1500                                     self.ou_computers, self.ou_computers))
1501         self.assertEqual(len(res1), 8)
1502         dn_list = [str(res.dn) for res in res1]
1503         self.assertTrue("CN=u1,%s" % self.ou_users in dn_list)
1504         self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
1505         self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
1506         self.assertTrue("CN=u4,%s" % self.ou_users in dn_list)
1507         self.assertTrue("CN=g1,%s" % self.ou_groups in dn_list)
1508         self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
1509         self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
1510         self.assertTrue("CN=g4,%s" % self.ou_groups in dn_list)
1511
1512         res1 = self.ldb.search(self.ou,
1513                                scope=SCOPE_SUBTREE,
1514                                expression=("(|(member:1.2.840.113556.1.4.1941:=cn=c2,%s)"
1515                                            "(member:1.2.840.113556.1.4.1941:=cn=c3,%s))") % (
1516                                     self.ou_computers, self.ou_computers))
1517         self.assertEqual(len(res1), 5)
1518         dn_list = [str(res.dn) for res in res1]
1519         self.assertTrue("CN=u1,%s" % self.ou_users in dn_list)
1520         self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
1521         self.assertTrue("CN=g1,%s" % self.ou_groups in dn_list)
1522         self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
1523         self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
1524
1525         res1 = self.ldb.search(self.ou,
1526                                scope=SCOPE_SUBTREE,
1527                                expression=("(|(member:1.2.840.113556.1.4.1941:=cn=c2,%s)"
1528                                            "(member:1.2.840.113556.1.4.1941:=cn=c4,%s))") % (
1529                                     self.ou_computers, self.ou_computers))
1530         self.assertEqual(len(res1), 3)
1531         dn_list = [str(res.dn) for res in res1]
1532         self.assertTrue("CN=u1,%s" % self.ou_users in dn_list)
1533         self.assertTrue("CN=u4,%s" % self.ou_users in dn_list)
1534         self.assertTrue("CN=g4,%s" % self.ou_groups in dn_list)
1535
1536         res1 = self.ldb.search(self.ou,
1537                                scope=SCOPE_SUBTREE,
1538                                expression=("(|(member:1.2.840.113556.1.4.1941:=cn=c3,%s)"
1539                                            "(member:1.2.840.113556.1.4.1941:=cn=c4,%s))") % (
1540                                     self.ou_computers, self.ou_computers))
1541         self.assertEqual(len(res1), 6)
1542         dn_list = [str(res.dn) for res in res1]
1543         self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
1544         self.assertTrue("CN=u4,%s" % self.ou_users in dn_list)
1545         self.assertTrue("CN=g1,%s" % self.ou_groups in dn_list)
1546         self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
1547         self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
1548         self.assertTrue("CN=g4,%s" % self.ou_groups in dn_list)
1549
1550         res1 = self.ldb.search(self.ou,
1551                                scope=SCOPE_SUBTREE,
1552                                expression=("(|(member:1.2.840.113556.1.4.1941:=cn=u1,%s)"
1553                                            "(member:1.2.840.113556.1.4.1941:=cn=c4,%s))") % (
1554                                     self.ou_users, self.ou_computers))
1555         self.assertEqual(len(res1), 2)
1556         dn_list = [str(res.dn) for res in res1]
1557         self.assertTrue("CN=u4,%s" % self.ou_users in dn_list)
1558         self.assertTrue("CN=g4,%s" % self.ou_groups in dn_list)
1559
1560     def test_and_member_queries(self):
1561         res1 = self.ldb.search(self.ou,
1562                                scope=SCOPE_SUBTREE,
1563                                expression=("(&(member:1.2.840.113556.1.4.1941:=cn=c1,%s)"
1564                                            "(member:1.2.840.113556.1.4.1941:=cn=c2,%s))") % (
1565                                     self.ou_computers, self.ou_computers))
1566         self.assertEqual(len(res1), 1)
1567         self.assertEqual(str(res1[0].dn), "CN=u1,%s" % self.ou_users)
1568
1569         res1 = self.ldb.search(self.ou,
1570                                scope=SCOPE_SUBTREE,
1571                                expression=("(&(member:1.2.840.113556.1.4.1941:=cn=c2,%s)"
1572                                            "(member:1.2.840.113556.1.4.1941:=cn=c3,%s))") % (
1573                                     self.ou_computers, self.ou_computers))
1574         self.assertEqual(len(res1), 0)
1575
1576         res1 = self.ldb.search(self.ou,
1577                                scope=SCOPE_SUBTREE,
1578                                expression=("(&(member:1.2.840.113556.1.4.1941:=cn=c3,%s)"
1579                                            "(member:1.2.840.113556.1.4.1941:=cn=u3,%s))") % (
1580                                     self.ou_computers, self.ou_users))
1581         self.assertEqual(len(res1), 3)
1582         dn_list = [str(res.dn) for res in res1]
1583         self.assertTrue("CN=g1,%s" % self.ou_groups in dn_list)
1584         self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
1585         self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
1586
1587         res1 = self.ldb.search(self.ou,
1588                                scope=SCOPE_SUBTREE,
1589                                expression=("(&(member:1.2.840.113556.1.4.1941:=cn=c1,%s)"
1590                                            "(member:1.2.840.113556.1.4.1941:=cn=u4,%s))") % (
1591                                     self.ou_computers, self.ou_computers))
1592         self.assertEqual(len(res1), 0)
1593
1594     def test_or_memberOf_queries(self):
1595         res1 = self.ldb.search(self.ou,
1596                                scope=SCOPE_SUBTREE,
1597                                expression=("(|(memberOf:1.2.840.113556.1.4.1941:=cn=g1,%s)"
1598                                            "(memberOf:1.2.840.113556.1.4.1941:=cn=g2,%s))") % (
1599                                     self.ou_groups, self.ou_groups))
1600         self.assertEqual(len(res1), 6)
1601         dn_list = [str(res.dn) for res in res1]
1602         self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
1603         self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
1604         self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
1605         self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
1606         self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
1607         self.assertTrue("CN=c3,%s" % self.ou_computers in dn_list)
1608
1609         res1 = self.ldb.search(self.ou,
1610                                scope=SCOPE_SUBTREE,
1611                                expression=("(|(memberOf:1.2.840.113556.1.4.1941:=cn=g1,%s)"
1612                                            "(memberOf:1.2.840.113556.1.4.1941:=cn=g3,%s))") % (
1613                                     self.ou_groups, self.ou_groups))
1614         self.assertEqual(len(res1), 6)
1615         dn_list = [str(res.dn) for res in res1]
1616         self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
1617         self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
1618         self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
1619         self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
1620         self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
1621         self.assertTrue("CN=c3,%s" % self.ou_computers in dn_list)
1622
1623         res1 = self.ldb.search(self.ou,
1624                                scope=SCOPE_SUBTREE,
1625                                expression=("(|(memberOf:1.2.840.113556.1.4.1941:=cn=g1,%s)"
1626                                            "(memberOf:1.2.840.113556.1.4.1941:=cn=g4,%s))") % (
1627                                     self.ou_groups, self.ou_groups))
1628         self.assertEqual(len(res1), 8)
1629         dn_list = [str(res.dn) for res in res1]
1630         self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
1631         self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
1632         self.assertTrue("CN=u4,%s" % self.ou_users in dn_list)
1633         self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
1634         self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
1635         self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
1636         self.assertTrue("CN=c3,%s" % self.ou_computers in dn_list)
1637         self.assertTrue("CN=c4,%s" % self.ou_computers in dn_list)
1638
1639         res1 = self.ldb.search(self.ou,
1640                                scope=SCOPE_SUBTREE,
1641                                expression=("(|(memberOf:1.2.840.113556.1.4.1941:=cn=g2,%s)"
1642                                            "(memberOf:1.2.840.113556.1.4.1941:=cn=g3,%s))") %
1643                                (self.ou_groups, self.ou_groups))
1644         self.assertEqual(len(res1), 5)
1645         dn_list = [str(res.dn) for res in res1]
1646         self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
1647         self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
1648         self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
1649         self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
1650         self.assertTrue("CN=c3,%s" % self.ou_computers in dn_list)
1651
1652         res1 = self.ldb.search(self.ou,
1653                                scope=SCOPE_SUBTREE,
1654                                expression=("(|(memberOf:1.2.840.113556.1.4.1941:=cn=g2,%s)"
1655                                            "(memberOf:1.2.840.113556.1.4.1941:=cn=g4,%s))") % (
1656                                     self.ou_groups, self.ou_groups))
1657         self.assertEqual(len(res1), 7)
1658         dn_list = [str(res.dn) for res in res1]
1659         self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
1660         self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
1661         self.assertTrue("CN=u4,%s" % self.ou_users in dn_list)
1662         self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
1663         self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
1664         self.assertTrue("CN=c3,%s" % self.ou_computers in dn_list)
1665         self.assertTrue("CN=c4,%s" % self.ou_computers in dn_list)
1666
1667         res1 = self.ldb.search(self.ou,
1668                                scope=SCOPE_SUBTREE,
1669                                expression=("(|(memberOf:1.2.840.113556.1.4.1941:=cn=g3,%s)"
1670                                            "(memberOf:1.2.840.113556.1.4.1941:=cn=g4,%s))") % (
1671                                     self.ou_groups, self.ou_groups))
1672         self.assertEqual(len(res1), 5)
1673         dn_list = [str(res.dn) for res in res1]
1674         self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
1675         self.assertTrue("CN=u4,%s" % self.ou_users in dn_list)
1676         self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
1677         self.assertTrue("CN=c3,%s" % self.ou_computers in dn_list)
1678         self.assertTrue("CN=c4,%s" % self.ou_computers in dn_list)
1679
1680     def test_and_memberOf_queries(self):
1681         res1 = self.ldb.search(self.ou,
1682                                scope=SCOPE_SUBTREE,
1683                                expression=("(&(memberOf:1.2.840.113556.1.4.1941:=cn=g1,%s)"
1684                                            "(memberOf:1.2.840.113556.1.4.1941:=cn=g2,%s))") % (
1685                                     self.ou_groups, self.ou_groups))
1686         self.assertEqual(len(res1), 5)
1687         dn_list = [str(res.dn) for res in res1]
1688         self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
1689         self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
1690         self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
1691         self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
1692         self.assertTrue("CN=c3,%s" % self.ou_computers in dn_list)
1693
1694         res1 = self.ldb.search(self.ou,
1695                                scope=SCOPE_SUBTREE,
1696                                expression=("(&(memberOf:1.2.840.113556.1.4.1941:=cn=g1,%s)"
1697                                            "(memberOf:1.2.840.113556.1.4.1941:=cn=g3,%s))") % (
1698                                     self.ou_groups, self.ou_groups))
1699         self.assertEqual(len(res1), 3)
1700         dn_list = [str(res.dn) for res in res1]
1701         self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
1702         self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
1703         self.assertTrue("CN=c3,%s" % self.ou_computers in dn_list)
1704
1705         res1 = self.ldb.search(self.ou,
1706                                scope=SCOPE_SUBTREE,
1707                                expression=("(&(memberOf:1.2.840.113556.1.4.1941:=cn=g1,%s)"
1708                                            "(memberOf:1.2.840.113556.1.4.1941:=cn=g4,%s))") % (
1709                                     self.ou_groups, self.ou_groups))
1710         self.assertEqual(len(res1), 2)
1711         dn_list = [str(res.dn) for res in res1]
1712         self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
1713         self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
1714
1715         res1 = self.ldb.search(self.ou,
1716                                scope=SCOPE_SUBTREE,
1717                                expression=("(&(memberOf:1.2.840.113556.1.4.1941:=cn=g2,%s)"
1718                                            "(memberOf:1.2.840.113556.1.4.1941:=cn=g3,%s))") % (
1719                                     self.ou_groups, self.ou_groups))
1720         self.assertEqual(len(res1), 3)
1721         dn_list = [str(res.dn) for res in res1]
1722         self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
1723         self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
1724         self.assertTrue("CN=c3,%s" % self.ou_computers in dn_list)
1725
1726         res1 = self.ldb.search(self.ou,
1727                                scope=SCOPE_SUBTREE,
1728                                expression=("(&(memberOf:1.2.840.113556.1.4.1941:=cn=g2,%s)"
1729                                            "(memberOf:1.2.840.113556.1.4.1941:=cn=g4,%s))") % (
1730                                     self.ou_groups, self.ou_groups))
1731         self.assertEqual(len(res1), 2)
1732         dn_list = [str(res.dn) for res in res1]
1733         self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
1734         self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
1735
1736         res1 = self.ldb.search(self.ou,
1737                                scope=SCOPE_SUBTREE,
1738                                expression=("(&(memberOf:1.2.840.113556.1.4.1941:=cn=g3,%s)"
1739                                            "(memberOf:1.2.840.113556.1.4.1941:=cn=g4,%s))") % (
1740                                     self.ou_groups, self.ou_groups))
1741         self.assertEqual(len(res1), 2)
1742         dn_list = [str(res.dn) for res in res1]
1743         self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
1744         self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
1745
1746         res1 = self.ldb.search(self.ou,
1747                                scope=SCOPE_SUBTREE,
1748                                expression=("(&(memberOf:1.2.840.113556.1.4.1941:=cn=g1,%s)"
1749                                            "(memberOf:1.2.840.113556.1.4.1941:=cn=c1,%s))") % (
1750                                     self.ou_groups, self.ou_computers))
1751         self.assertEqual(len(res1), 0)
1752
1753 parser = optparse.OptionParser("match_rules.py [options] <host>")
1754 sambaopts = options.SambaOptions(parser)
1755 parser.add_option_group(sambaopts)
1756 parser.add_option_group(options.VersionOptions(parser))
1757
1758 # use command line creds if available
1759 credopts = options.CredentialsOptions(parser)
1760 parser.add_option_group(credopts)
1761 opts, args = parser.parse_args()
1762 subunitopts = SubunitOptions(parser)
1763 parser.add_option_group(subunitopts)
1764
1765 if len(args) < 1:
1766     parser.print_usage()
1767     sys.exit(1)
1768
1769 host = args[0]
1770
1771 lp = sambaopts.get_loadparm()
1772 creds = credopts.get_credentials(lp)
1773
1774 if not "://" in host:
1775     if os.path.isfile(host):
1776         host = "tdb://%s" % host
1777     else:
1778         host = "ldap://%s" % host
1779
1780 TestProgram(module=__name__, opts=subunitopts)