ldb-samba: Expand testing of recursive search
[obnox/samba/samba-obnox.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         delete_force(self.ldb, "cn=u4,%s" % self.ou_users)
275         delete_force(self.ldb, "cn=u3,%s" % self.ou_users)
276         delete_force(self.ldb, "cn=u2,%s" % self.ou_users)
277         delete_force(self.ldb, "cn=u1,%s" % self.ou_users)
278         delete_force(self.ldb, "cn=g4,%s" % self.ou_groups)
279         delete_force(self.ldb, "cn=g3,%s" % self.ou_groups)
280         delete_force(self.ldb, "cn=g2,%s" % self.ou_groups)
281         delete_force(self.ldb, "cn=g1,%s" % self.ou_groups)
282         delete_force(self.ldb, "cn=c1,%s" % self.ou_computers)
283         delete_force(self.ldb, "cn=c2,%s" % self.ou_computers)
284         delete_force(self.ldb, "cn=c3,%s" % self.ou_computers)
285         delete_force(self.ldb, self.ou_users)
286         delete_force(self.ldb, self.ou_groups)
287         delete_force(self.ldb, self.ou_computers)
288         delete_force(self.ldb, "OU=o4,OU=o3,OU=o2,OU=o1,%s" % self.ou)
289         delete_force(self.ldb, "OU=o3,OU=o2,OU=o1,%s" % self.ou)
290         delete_force(self.ldb, "OU=o2,OU=o1,%s" % self.ou)
291         delete_force(self.ldb, "OU=o1,%s" % self.ou)
292         delete_force(self.ldb, "CN=e2,%s" % self.ou)
293         delete_force(self.ldb, "CN=e1,%s" % self.ou)
294         delete_force(self.ldb, self.ou)
295
296     def test_u1_member_of_g4(self):
297         # Search without transitive match must return 0 results
298         res1 = self.ldb.search("cn=g4,%s" % self.ou_groups,
299                         scope=SCOPE_BASE,
300                         expression="member=cn=u1,%s" % self.ou_users)
301         self.assertEqual(len(res1), 0)
302
303         res1 = self.ldb.search("cn=u1,%s" % self.ou_users,
304                         scope=SCOPE_BASE,
305                         expression="memberOf=cn=g4,%s" % self.ou_groups)
306         self.assertEqual(len(res1), 0)
307
308         # Search with transitive match must return 1 results
309         res1 = self.ldb.search("cn=g4,%s" % self.ou_groups,
310                         scope=SCOPE_BASE,
311                         expression="member:1.2.840.113556.1.4.1941:=cn=u1,%s" % self.ou_users)
312         self.assertEqual(len(res1), 1)
313         self.assertEqual(str(res1[0].dn).lower(), ("CN=g4,%s" % self.ou_groups).lower())
314
315         res1 = self.ldb.search("cn=u1,%s" % self.ou_users,
316                         scope=SCOPE_BASE,
317                         expression="memberOf:1.2.840.113556.1.4.1941:=cn=g4,%s" % self.ou_groups)
318         self.assertEqual(len(res1), 1)
319         self.assertEqual(str(res1[0].dn).lower(), ("CN=u1,%s" % self.ou_users).lower())
320
321     def test_g1_member_of_g4(self):
322         # Search without transitive match must return 0 results
323         res1 = self.ldb.search("cn=g4,%s" % self.ou_groups,
324                         scope=SCOPE_BASE,
325                         expression="member=cn=g1,%s" % self.ou_groups)
326         self.assertEqual(len(res1), 0)
327
328         res1 = self.ldb.search("cn=g1,%s" % self.ou_groups,
329                         scope=SCOPE_BASE,
330                         expression="memberOf=cn=g4,%s" % self.ou_groups)
331         self.assertEqual(len(res1), 0)
332
333         # Search with transitive match must return 1 results
334         res1 = self.ldb.search("cn=g4,%s" % self.ou_groups,
335                         scope=SCOPE_BASE,
336                         expression="member:1.2.840.113556.1.4.1941:=cn=g1,%s" % self.ou_groups)
337         self.assertEqual(len(res1), 1)
338         self.assertEqual(str(res1[0].dn).lower(), ("CN=g4,%s" % self.ou_groups).lower())
339
340         res1 = self.ldb.search("cn=g1,%s" % self.ou_groups,
341                         scope=SCOPE_BASE,
342                         expression="memberOf:1.2.840.113556.1.4.1941:=cn=g4,%s" % self.ou_groups)
343         self.assertEqual(len(res1), 1)
344         self.assertEqual(str(res1[0].dn).lower(), ("CN=g1,%s" % self.ou_groups).lower())
345
346     def test_u1_groups(self):
347         res1 = self.ldb.search(self.ou_groups,
348                         scope=SCOPE_SUBTREE,
349                         expression="member=cn=u1,%s" % self.ou_users)
350         self.assertEqual(len(res1), 1)
351         self.assertEqual(str(res1[0].dn).lower(), ("CN=g1,%s" % self.ou_groups).lower())
352
353         res1 = self.ldb.search(self.ou_users,
354                         scope=SCOPE_SUBTREE,
355                         expression="member=cn=u1,%s" % self.ou_users)
356         self.assertEqual(len(res1), 0)
357
358         res1 = self.ldb.search(self.ou_groups,
359                         scope=SCOPE_SUBTREE,
360                         expression="member:1.2.840.113556.1.4.1941:=cn=u1,%s" % self.ou_users)
361         self.assertEqual(len(res1), 4)
362         dn_list = [str(res.dn).lower() for res in res1]
363         self.assertTrue(("CN=g1,%s" % self.ou_groups).lower() in dn_list)
364         self.assertTrue(("CN=g2,%s" % self.ou_groups).lower() in dn_list)
365         self.assertTrue(("CN=g3,%s" % self.ou_groups).lower() in dn_list)
366         self.assertTrue(("CN=g4,%s" % self.ou_groups).lower() in dn_list)
367
368         res1 = self.ldb.search(self.ou_users,
369                         scope=SCOPE_SUBTREE,
370                         expression="member:1.2.840.113556.1.4.1941:=cn=u1,%s" % self.ou_users)
371         self.assertEqual(len(res1), 0)
372
373     def test_u2_groups(self):
374         res1 = self.ldb.search(self.ou_groups,
375                         scope=SCOPE_SUBTREE,
376                         expression="member=cn=u2,%s" % self.ou_users)
377         self.assertEqual(len(res1), 1)
378         self.assertEqual(str(res1[0].dn).lower(), ("CN=g2,%s" % self.ou_groups).lower())
379
380         res1 = self.ldb.search(self.ou_users,
381                         scope=SCOPE_SUBTREE,
382                         expression="member=cn=u2,%s" % self.ou_users)
383         self.assertEqual(len(res1), 0)
384
385         res1 = self.ldb.search(self.ou_groups,
386                         scope=SCOPE_SUBTREE,
387                         expression="member:1.2.840.113556.1.4.1941:=cn=u2,%s" % self.ou_users)
388         self.assertEqual(len(res1), 3)
389         dn_list = [str(res.dn).lower() for res in res1]
390         self.assertTrue(("CN=g2,%s" % self.ou_groups).lower() in dn_list)
391         self.assertTrue(("CN=g3,%s" % self.ou_groups).lower() in dn_list)
392         self.assertTrue(("CN=g4,%s" % self.ou_groups).lower() in dn_list)
393
394         res1 = self.ldb.search(self.ou_users,
395                         scope=SCOPE_SUBTREE,
396                         expression="member:1.2.840.113556.1.4.1941:=cn=u2,%s" % self.ou_users)
397         self.assertEqual(len(res1), 0)
398
399     def test_u3_groups(self):
400         res1 = self.ldb.search(self.ou_groups,
401                         scope=SCOPE_SUBTREE,
402                         expression="member=cn=u3,%s" % self.ou_users)
403         self.assertEqual(len(res1), 1)
404         self.assertEqual(str(res1[0].dn).lower(), ("CN=g3,%s" % self.ou_groups).lower())
405
406         res1 = self.ldb.search(self.ou_users,
407                         scope=SCOPE_SUBTREE,
408                         expression="member=cn=u3,%s" % self.ou_users)
409         self.assertEqual(len(res1), 0)
410
411         res1 = self.ldb.search(self.ou_groups,
412                         scope=SCOPE_SUBTREE,
413                         expression="member:1.2.840.113556.1.4.1941:=cn=u3,%s" % self.ou_users)
414         self.assertEqual(len(res1), 2)
415         dn_list = [str(res.dn).lower() for res in res1]
416         self.assertTrue(("CN=g3,%s" % self.ou_groups).lower() in dn_list)
417         self.assertTrue(("CN=g4,%s" % self.ou_groups).lower() in dn_list)
418
419         res1 = self.ldb.search(self.ou_users,
420                         scope=SCOPE_SUBTREE,
421                         expression="member:1.2.840.113556.1.4.1941:=cn=u3,%s" % self.ou_users)
422         self.assertEqual(len(res1), 0)
423
424     def test_u4_groups(self):
425         res1 = self.ldb.search(self.ou_groups,
426                         scope=SCOPE_SUBTREE,
427                         expression="member=cn=u4,%s" % self.ou_users)
428         self.assertEqual(len(res1), 1)
429         self.assertEqual(str(res1[0].dn).lower(), ("CN=g4,%s" % self.ou_groups).lower())
430
431         res1 = self.ldb.search(self.ou_users,
432                         scope=SCOPE_SUBTREE,
433                         expression="member=cn=u4,%s" % self.ou_users)
434         self.assertEqual(len(res1), 0)
435
436         res1 = self.ldb.search(self.ou_groups,
437                         scope=SCOPE_SUBTREE,
438                         expression="member:1.2.840.113556.1.4.1941:=cn=u4,%s" % self.ou_users)
439         self.assertEqual(len(res1), 1)
440         self.assertEqual(str(res1[0].dn).lower(), ("CN=g4,%s" % self.ou_groups).lower())
441
442         res1 = self.ldb.search(self.ou_users,
443                         scope=SCOPE_SUBTREE,
444                         expression="member:1.2.840.113556.1.4.1941:=cn=u4,%s" % self.ou_users)
445         self.assertEqual(len(res1), 0)
446
447     def test_extended_dn_u1(self):
448         res1 = self.ldb.search("cn=u1,%s" % self.ou_users,
449                         scope=SCOPE_BASE,
450                         expression="objectClass=*",
451                         attrs=['objectSid', 'objectGUID'])
452         self.assertEqual(len(res1), 1)
453         self.assertEqual(str(res1[0].dn).lower(), ("cn=u1,%s" % self.ou_users).lower())
454
455         sid = self.ldb.schema_format_value("objectSid", res1[0]["objectSid"][0])
456         guid = self.ldb.schema_format_value("objectGUID", res1[0]['objectGUID'][0])
457
458         res1 = self.ldb.search(self.ou_groups,
459                         scope=SCOPE_SUBTREE,
460                         expression="member=<SID=%s>" % sid)
461         self.assertEqual(len(res1), 1)
462         self.assertEqual(str(res1[0].dn).lower(), ("CN=g1,%s" % self.ou_groups).lower())
463
464         res1 = self.ldb.search(self.ou_groups,
465                         scope=SCOPE_SUBTREE,
466                         expression="member=<GUID=%s>" % guid)
467         self.assertEqual(len(res1), 1)
468         self.assertEqual(str(res1[0].dn).lower(), ("CN=g1,%s" % self.ou_groups).lower())
469
470         res1 = self.ldb.search(self.ou_groups,
471                         scope=SCOPE_SUBTREE,
472                         expression="member:1.2.840.113556.1.4.1941:=<SID=%s>" % sid)
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:=<SID=%s>" % sid)
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         res1 = self.ldb.search(self.ou_groups,
491                         scope=SCOPE_SUBTREE,
492                         expression="member:1.2.840.113556.1.4.1941:=<GUID=%s>" % guid)
493         self.assertEqual(len(res1), 4)
494         dn_list = [str(res.dn).lower() for res in res1]
495         self.assertTrue(("CN=g1,%s" % self.ou_groups).lower() in dn_list)
496         self.assertTrue(("CN=g2,%s" % self.ou_groups).lower() in dn_list)
497         self.assertTrue(("CN=g3,%s" % self.ou_groups).lower() in dn_list)
498         self.assertTrue(("CN=g4,%s" % self.ou_groups).lower() in dn_list)
499
500         res1 = self.ldb.search(self.ou_groups,
501                         scope=SCOPE_ONELEVEL,
502                         expression="member:1.2.840.113556.1.4.1941:=<GUID=%s>" % guid)
503         self.assertEqual(len(res1), 4)
504         dn_list = [str(res.dn).lower() for res in res1]
505         self.assertTrue(("CN=g1,%s" % self.ou_groups).lower() in dn_list)
506         self.assertTrue(("CN=g2,%s" % self.ou_groups).lower() in dn_list)
507         self.assertTrue(("CN=g3,%s" % self.ou_groups).lower() in dn_list)
508         self.assertTrue(("CN=g4,%s" % self.ou_groups).lower() in dn_list)
509
510     def test_extended_dn_u2(self):
511         res1 = self.ldb.search("cn=u2,%s" % self.ou_users,
512                         scope=SCOPE_BASE,
513                         expression="objectClass=*",
514                         attrs=['objectSid', 'objectGUID'])
515         self.assertEqual(len(res1), 1)
516         self.assertEqual(str(res1[0].dn).lower(), ("cn=u2,%s" % self.ou_users).lower())
517
518         sid = self.ldb.schema_format_value("objectSid", res1[0]["objectSid"][0])
519         guid = self.ldb.schema_format_value("objectGUID", res1[0]['objectGUID'][0])
520
521         res1 = self.ldb.search(self.ou_groups,
522                         scope=SCOPE_SUBTREE,
523                         expression="member=<SID=%s>" % sid)
524         self.assertEqual(len(res1), 1)
525         self.assertEqual(str(res1[0].dn).lower(), ("CN=g2,%s" % self.ou_groups).lower())
526
527         res1 = self.ldb.search(self.ou_groups,
528                         scope=SCOPE_SUBTREE,
529                         expression="member=<GUID=%s>" % guid)
530         self.assertEqual(len(res1), 1)
531         self.assertEqual(str(res1[0].dn).lower(), ("CN=g2,%s" % self.ou_groups).lower())
532
533         res1 = self.ldb.search(self.ou_groups,
534                         scope=SCOPE_SUBTREE,
535                         expression="member:1.2.840.113556.1.4.1941:=<SID=%s>" % sid)
536         self.assertEqual(len(res1), 3)
537         dn_list = [str(res.dn).lower() for res in res1]
538         self.assertTrue(("CN=g2,%s" % self.ou_groups).lower() in dn_list)
539         self.assertTrue(("CN=g3,%s" % self.ou_groups).lower() in dn_list)
540         self.assertTrue(("CN=g4,%s" % self.ou_groups).lower() in dn_list)
541
542         res1 = self.ldb.search(self.ou_groups,
543                         scope=SCOPE_ONELEVEL,
544                         expression="member:1.2.840.113556.1.4.1941:=<SID=%s>" % sid)
545         self.assertEqual(len(res1), 3)
546         dn_list = [str(res.dn).lower() for res in res1]
547         self.assertTrue(("CN=g2,%s" % self.ou_groups).lower() in dn_list)
548         self.assertTrue(("CN=g3,%s" % self.ou_groups).lower() in dn_list)
549         self.assertTrue(("CN=g4,%s" % self.ou_groups).lower() in dn_list)
550
551         res1 = self.ldb.search(self.ou_groups,
552                         scope=SCOPE_SUBTREE,
553                         expression="member:1.2.840.113556.1.4.1941:=<GUID=%s>" % guid)
554         self.assertEqual(len(res1), 3)
555         dn_list = [str(res.dn).lower() for res in res1]
556         self.assertTrue(("CN=g2,%s" % self.ou_groups).lower() in dn_list)
557         self.assertTrue(("CN=g3,%s" % self.ou_groups).lower() in dn_list)
558         self.assertTrue(("CN=g4,%s" % self.ou_groups).lower() in dn_list)
559
560         res1 = self.ldb.search(self.ou_groups,
561                         scope=SCOPE_ONELEVEL,
562                         expression="member:1.2.840.113556.1.4.1941:=<GUID=%s>" % guid)
563         self.assertEqual(len(res1), 3)
564         dn_list = [str(res.dn).lower() for res in res1]
565         self.assertTrue(("CN=g2,%s" % self.ou_groups).lower() in dn_list)
566         self.assertTrue(("CN=g3,%s" % self.ou_groups).lower() in dn_list)
567         self.assertTrue(("CN=g4,%s" % self.ou_groups).lower() in dn_list)
568
569     def test_extended_dn_u3(self):
570         res1 = self.ldb.search("cn=u3,%s" % self.ou_users,
571                         scope=SCOPE_BASE,
572                         expression="objectClass=*",
573                         attrs=['objectSid', 'objectGUID'])
574         self.assertEqual(len(res1), 1)
575         self.assertEqual(str(res1[0].dn).lower(), ("cn=u3,%s" % self.ou_users).lower())
576
577         sid = self.ldb.schema_format_value("objectSid", res1[0]["objectSid"][0])
578         guid = self.ldb.schema_format_value("objectGUID", res1[0]['objectGUID'][0])
579
580         res1 = self.ldb.search(self.ou_groups,
581                         scope=SCOPE_SUBTREE,
582                         expression="member=<SID=%s>" % sid)
583         self.assertEqual(len(res1), 1)
584         self.assertEqual(str(res1[0].dn).lower(), ("CN=g3,%s" % self.ou_groups).lower())
585
586         res1 = self.ldb.search(self.ou_groups,
587                         scope=SCOPE_SUBTREE,
588                         expression="member=<GUID=%s>" % guid)
589         self.assertEqual(len(res1), 1)
590         self.assertEqual(str(res1[0].dn).lower(), ("CN=g3,%s" % self.ou_groups).lower())
591
592         res1 = self.ldb.search(self.ou_groups,
593                                 scope=SCOPE_SUBTREE,
594                                 expression="member:1.2.840.113556.1.4.1941:=<SID=%s>" % sid)
595         self.assertEqual(len(res1), 2)
596         dn_list = [str(res.dn).lower() for res in res1]
597         self.assertTrue(("CN=g3,%s" % self.ou_groups).lower() in dn_list)
598         self.assertTrue(("CN=g4,%s" % self.ou_groups).lower() in dn_list)
599
600         res1 = self.ldb.search(self.ou_groups,
601                                 scope=SCOPE_ONELEVEL,
602                                 expression="member:1.2.840.113556.1.4.1941:=<SID=%s>" % sid)
603         self.assertEqual(len(res1), 2)
604         dn_list = [str(res.dn).lower() for res in res1]
605         self.assertTrue(("CN=g3,%s" % self.ou_groups).lower() in dn_list)
606         self.assertTrue(("CN=g4,%s" % self.ou_groups).lower() in dn_list)
607
608         res1 = self.ldb.search(self.ou_groups,
609                         scope=SCOPE_SUBTREE,
610                         expression="member:1.2.840.113556.1.4.1941:=<GUID=%s>" % guid)
611         self.assertEqual(len(res1), 2)
612         dn_list = [str(res.dn).lower() for res in res1]
613         self.assertTrue(("CN=g3,%s" % self.ou_groups).lower() in dn_list)
614         self.assertTrue(("CN=g4,%s" % self.ou_groups).lower() in dn_list)
615
616         res1 = self.ldb.search(self.ou_groups,
617                         scope=SCOPE_ONELEVEL,
618                         expression="member:1.2.840.113556.1.4.1941:=<GUID=%s>" % guid)
619         self.assertEqual(len(res1), 2)
620         dn_list = [str(res.dn).lower() for res in res1]
621         self.assertTrue(("CN=g3,%s" % self.ou_groups).lower() in dn_list)
622         self.assertTrue(("CN=g4,%s" % self.ou_groups).lower() in dn_list)
623
624     def test_extended_dn_u4(self):
625         res1 = self.ldb.search("cn=u4,%s" % self.ou_users,
626                                 scope=SCOPE_BASE,
627                                 expression="objectClass=*",
628                                 attrs=['objectSid', 'objectGUID'])
629         self.assertEqual(len(res1), 1)
630         self.assertEqual(str(res1[0].dn).lower(), ("cn=u4,%s" % self.ou_users).lower())
631
632         sid = self.ldb.schema_format_value("objectSid", res1[0]["objectSid"][0])
633         guid = self.ldb.schema_format_value("objectGUID", res1[0]['objectGUID'][0])
634
635         res1 = self.ldb.search(self.ou_groups,
636                                 scope=SCOPE_SUBTREE,
637                                 expression="member=<SID=%s>" % sid)
638         self.assertEqual(len(res1), 1)
639         self.assertEqual(str(res1[0].dn).lower(), ("CN=g4,%s" % self.ou_groups).lower())
640
641         res1 = self.ldb.search(self.ou_groups,
642                                 scope=SCOPE_SUBTREE,
643                                 expression="member=<GUID=%s>" % guid)
644         self.assertEqual(len(res1), 1)
645         self.assertEqual(str(res1[0].dn).lower(), ("CN=g4,%s" % self.ou_groups).lower())
646
647         res1 = self.ldb.search(self.ou_groups,
648                                 scope=SCOPE_ONELEVEL,
649                                 expression="member=<GUID=%s>" % guid)
650         self.assertEqual(len(res1), 1)
651         self.assertEqual(str(res1[0].dn).lower(), ("CN=g4,%s" % self.ou_groups).lower())
652
653         res1 = self.ldb.search(self.ou_groups,
654                                 scope=SCOPE_SUBTREE,
655                                 expression="member:1.2.840.113556.1.4.1941:=<SID=%s>" % sid)
656         self.assertEqual(len(res1), 1)
657         self.assertEqual(str(res1[0].dn).lower(), ("CN=g4,%s" % self.ou_groups).lower())
658
659         res1 = self.ldb.search(self.ou_groups,
660                                 scope=SCOPE_ONELEVEL,
661                                 expression="member:1.2.840.113556.1.4.1941:=<SID=%s>" % sid)
662         self.assertEqual(len(res1), 1)
663         self.assertEqual(str(res1[0].dn).lower(), ("CN=g4,%s" % self.ou_groups).lower())
664
665         res1 = self.ldb.search(self.ou_groups,
666                                 scope=SCOPE_SUBTREE,
667                                 expression="member:1.2.840.113556.1.4.1941:=<GUID=%s>" % guid)
668         self.assertEqual(len(res1), 1)
669         self.assertEqual(str(res1[0].dn).lower(), ("CN=g4,%s" % self.ou_groups).lower())
670
671         res1 = self.ldb.search(self.ou_groups,
672                                 scope=SCOPE_ONELEVEL,
673                                 expression="member:1.2.840.113556.1.4.1941:=<GUID=%s>" % guid)
674         self.assertEqual(len(res1), 1)
675         self.assertEqual(str(res1[0].dn).lower(), ("CN=g4,%s" % self.ou_groups).lower())
676
677     def test_object_dn_binary(self):
678         res1 = self.ldb.search(self.ou_computers,
679                         scope=SCOPE_SUBTREE,
680                         expression="msDS-RevealedUsers=B:8:01010101:cn=c3,%s" % self.ou_computers)
681         self.assertEqual(len(res1), 1)
682         self.assertEqual(str(res1[0].dn).lower(), ("CN=c2,%s" % self.ou_computers).lower())
683
684         res1 = self.ldb.search(self.ou_computers,
685                         scope=SCOPE_ONELEVEL,
686                         expression="msDS-RevealedUsers=B:8:01010101:cn=c3,%s" % self.ou_computers)
687         self.assertEqual(len(res1), 1)
688         self.assertEqual(str(res1[0].dn).lower(), ("CN=c2,%s" % self.ou_computers).lower())
689
690         res1 = self.ldb.search(self.ou_computers,
691                         scope=SCOPE_SUBTREE,
692                         expression="msDS-RevealedUsers:1.2.840.113556.1.4.1941:=B:8:01010101:cn=c3,%s" % self.ou_computers)
693         self.assertEqual(len(res1), 2)
694         dn_list = [str(res.dn).lower() for res in res1]
695         self.assertTrue(("CN=c1,%s" % self.ou_computers).lower() in dn_list)
696         self.assertTrue(("CN=c2,%s" % self.ou_computers).lower() in dn_list)
697
698         res1 = self.ldb.search(self.ou_computers,
699                         scope=SCOPE_ONELEVEL,
700                         expression="msDS-RevealedUsers:1.2.840.113556.1.4.1941:=B:8:01010101:cn=c3,%s" % self.ou_computers)
701         self.assertEqual(len(res1), 2)
702         dn_list = [str(res.dn).lower() for res in res1]
703         self.assertTrue(("CN=c1,%s" % self.ou_computers).lower() in dn_list)
704         self.assertTrue(("CN=c2,%s" % self.ou_computers).lower() in dn_list)
705
706     def test_one_way_links(self):
707         res1 = self.ldb.search(self.ou,
708                         scope=SCOPE_SUBTREE,
709                         expression="addressBookRoots2=cn=c1,%s" % self.ou_computers)
710         self.assertEqual(len(res1), 1)
711         self.assertEqual(str(res1[0].dn).lower(), ("CN=e2,%s" % self.ou).lower())
712
713         res1 = self.ldb.search(self.ou,
714                         scope=SCOPE_ONELEVEL,
715                         expression="addressBookRoots2=cn=c1,%s" % self.ou_computers)
716         self.assertEqual(len(res1), 1)
717         self.assertEqual(str(res1[0].dn).lower(), ("CN=e2,%s" % self.ou).lower())
718
719         res1 = self.ldb.search(self.ou,
720                         scope=SCOPE_SUBTREE,
721                         expression="addressBookRoots2:1.2.840.113556.1.4.1941:=cn=c1,%s" % self.ou_computers)
722         self.assertEqual(len(res1), 2)
723         dn_list = [str(res.dn).lower() for res in res1]
724         self.assertTrue(("CN=e1,%s" % self.ou).lower() in dn_list)
725         self.assertTrue(("CN=e1,%s" % self.ou).lower() in dn_list)
726
727         res1 = self.ldb.search(self.ou,
728                         scope=SCOPE_ONELEVEL,
729                         expression="addressBookRoots2:1.2.840.113556.1.4.1941:=cn=c1,%s" % self.ou_computers)
730         self.assertEqual(len(res1), 2)
731         dn_list = [str(res.dn).lower() for res in res1]
732         self.assertTrue(("CN=e1,%s" % self.ou).lower() in dn_list)
733         self.assertTrue(("CN=e1,%s" % self.ou).lower() in dn_list)
734
735     def test_not_linked_attrs(self):
736         res1 = self.ldb.search(self.base_dn,
737                         scope=SCOPE_BASE,
738                         expression="wellKnownObjects=B:32:aa312825768811d1aded00c04fd8d5cd:CN=computers,%s" % self.base_dn)
739         self.assertEqual(len(res1), 1)
740         self.assertEqual(str(res1[0].dn).lower(), self.base_dn.lower())
741
742     def test_invalid_basedn(self):
743         res1 = self.ldb.search(self.base_dn,
744                                 scope=SCOPE_SUBTREE,
745                                 expression="memberOf:1.2.840.113556.1.4.1941:=cn=c1,ou=computers,ou=matchrulestest,%sXX" % self.base_dn)
746         self.assertEqual(len(res1), 0)
747
748         res1 = self.ldb.search(self.base_dn,
749                                 scope=SCOPE_SUBTREE,
750                                 expression="memberOf:1.2.840.113556.1.4.1941:=cn=XX,ou=computers,ou=matchrulestest,%s" % self.base_dn)
751         self.assertEqual(len(res1), 0)
752
753     def test_subtree(self):
754             res1 = self.ldb.search(self.ou,
755                             scope=SCOPE_SUBTREE,
756                             expression="otherWellKnownObjects=B:32:00000000000000000000000000000004:OU=o4,OU=o3,OU=o2,OU=o1,%s" % self.ou)
757             self.assertEqual(len(res1), 1)
758             self.assertEqual(str(res1[0].dn).lower(), ("OU=o3,OU=o2,OU=o1,%s" % self.ou).lower())
759
760             res1 = self.ldb.search(self.ou,
761                             scope=SCOPE_ONELEVEL,
762                             expression="otherWellKnownObjects=B:32:00000000000000000000000000000004:OU=o4,OU=o3,OU=o2,OU=o1,%s" % self.ou)
763             self.assertEqual(len(res1), 0)
764
765             res1 = self.ldb.search(self.ou,
766                             scope=SCOPE_SUBTREE,
767                             expression="otherWellKnownObjects:1.2.840.113556.1.4.1941:=B:32:00000000000000000000000000000004:OU=o4,OU=o3,OU=o2,OU=o1,%s" % self.ou)
768             self.assertEqual(len(res1), 0)
769
770             res1 = self.ldb.search(self.ou,
771                             scope=SCOPE_ONELEVEL,
772                             expression="otherWellKnownObjects:1.2.840.113556.1.4.1941:=B:32:00000000000000000000000000000004:OU=o4,OU=o3,OU=o2,OU=o1,%s" % self.ou)
773             self.assertEqual(len(res1), 0)
774
775     def test_unknown_oid(self):
776         res1 = self.ldb.search("cn=g4,%s" % self.ou_groups,
777                                 scope=SCOPE_BASE,
778                                 expression="member:2.4.681.226012.2.8.3882:=cn=u1,%s" % self.ou_users)
779         self.assertEqual(len(res1), 0)
780
781         res1 = self.ldb.search("cn=g4,%s" % self.ou_groups,
782                                 scope=SCOPE_BASE,
783                                 expression="member:8.16.8720.1008448.8.32.15528:=cn=u1,%s" % self.ou_users)
784         self.assertEqual(len(res1), 0)
785
786         res1 = self.ldb.search("cn=g4,%s" % self.ou_groups,
787                                 scope=SCOPE_BASE,
788                                 expression="member:1.2.3.4:=cn=u1,%s" % self.ou_users)
789         self.assertEqual(len(res1), 0)
790
791     def test_nul_text(self):
792         self.assertRaises(TypeError, lambda: self.ldb.search("cn=g4,%s" % self.ou_groups,
793                             scope=SCOPE_BASE,
794                             expression="\00member:1.2.840.113556.1.4.1941:=cn=u1,%s" % self.ou_users))
795         self.assertRaises(TypeError, lambda: self.ldb.search("cn=g4,%s" % self.ou_groups,
796                             scope=SCOPE_BASE,
797                             expression="member:1.2.840\00.113556.1.4.1941:=cn=u1,%s" % self.ou_users))
798         self.assertRaises(TypeError, lambda: self.ldb.search("cn=g4,%s" % self.ou_groups,
799                             scope=SCOPE_BASE,
800                             expression="member:1.2.840.113556.1.4.1941:=cn=u1\00,%s" % self.ou_users))
801         self.assertRaises(LdbError, lambda: self.ldb.search("cn=\00g4,%s" % self.ou_groups,
802                             scope=SCOPE_BASE,
803                             expression="member:1.2.840.113556.1.4.1941:=cn=u1,%s" % self.ou_users))
804         self.assertRaises(LdbError, lambda: self.ldb.search("cn=g4,%s" % self.ou_groups,
805                             scope=SCOPE_BASE,
806                             expression="member:1.2.840.113556.1.4.1941:"))
807         res1 = self.ldb.search("cn=g4,%s" % self.ou_groups,
808                             scope=SCOPE_BASE,
809                             expression="member:1.2.840.113556.1.4.1941:=")
810         self.assertEqual(len(res1), 0)
811         res1 = self.ldb.search("cn=g4,%s" % self.ou_groups,
812                             scope=SCOPE_BASE,
813                             expression="member=")
814         self.assertEqual(len(res1), 0)
815         res1 = self.ldb.search("cn=g4,%s" % self.ou_groups,
816                             scope=SCOPE_BASE,
817                             expression="member:1.2.840.113556.1.4.1941:=nonexistent")
818         self.assertEqual(len(res1), 0)
819         res1 = self.ldb.search("cn=g4,%s" % self.ou_groups,
820                             scope=SCOPE_BASE,
821                             expression="member=nonexistent")
822         self.assertEqual(len(res1), 0)
823         self.assertRaises(LdbError, lambda: self.ldb.search("cn=\00g4,%s" % self.ou_groups,
824                             scope=SCOPE_BASE,
825                             expression="member:1.2.840.113556.1.4.1941:cn=u1,%s" % self.ou_users))
826         self.assertRaises(LdbError, lambda: self.ldb.search("cn=\00g4,%s" % self.ou_groups,
827                             scope=SCOPE_BASE,
828                             expression="member:1.2.840.113556.1.4.1941:=cn=u1"))
829         self.assertRaises(LdbError, lambda: self.ldb.search("cn=\00g4,%s" % self.ou_groups,
830                             scope=SCOPE_BASE,
831                             expression="member:1.2.840.113556.1.4.1941:=cn="))
832         self.assertRaises(LdbError, lambda: self.ldb.search("cn=\00g4,%s" % self.ou_groups,
833                             scope=SCOPE_BASE,
834                             expression="member::=cn=u1,%s" % self.ou_users))
835
836     def test_misc_matches(self):
837         res1 = self.ldb.search(self.ou_groups,
838                                 scope=SCOPE_BASE,
839                                 expression="member=cn=g1,%s" % self.ou_groups)
840         self.assertEqual(len(res1), 0)
841
842         res1 = self.ldb.search("cn=g1,%s" % self.ou_groups,
843                                 scope=SCOPE_BASE,
844                                 expression="member=cn=g1,%s" % self.ou_groups)
845         self.assertEqual(len(res1), 0)
846
847         res1 = self.ldb.search(self.ou_groups,
848                                 scope=SCOPE_SUBTREE,
849                                 expression="member=cn=g1,%s" % self.ou_groups)
850         self.assertEqual(len(res1), 1)
851         self.assertEqual(str(res1[0].dn), "CN=g2,%s" % self.ou_groups)
852
853         res1 = self.ldb.search(self.ou_groups,
854                                 scope=SCOPE_ONELEVEL,
855                                 expression="member=cn=g1,%s" % self.ou_groups)
856         self.assertEqual(len(res1), 1)
857         self.assertEqual(str(res1[0].dn), "CN=g2,%s" % self.ou_groups)
858
859         res1 = self.ldb.search(self.ou_groups,
860                                 scope=SCOPE_BASE,
861                                 expression="member:1.2.840.113556.1.4.1941:=cn=g1,%s" % self.ou_groups)
862         self.assertEqual(len(res1), 0)
863
864         res1 = self.ldb.search("cn=g1,%s" % self.ou_groups,
865                                 scope=SCOPE_BASE,
866                                 expression="member:1.2.840.113556.1.4.1941:=cn=g1,%s" % self.ou_groups)
867         self.assertEqual(len(res1), 0)
868
869         res1 = self.ldb.search(self.ou_groups,
870                                 scope=SCOPE_SUBTREE,
871                                 expression="member:1.2.840.113556.1.4.1941:=cn=g1,%s" % self.ou_groups)
872         self.assertEqual(len(res1), 3)
873         dn_list = [str(res.dn) for res in res1]
874         self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
875         self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
876         self.assertTrue("CN=g4,%s" % self.ou_groups in dn_list)
877
878         res1 = self.ldb.search(self.ou_groups,
879                                 scope=SCOPE_ONELEVEL,
880                                 expression="member:1.2.840.113556.1.4.1941:=cn=g1,%s" % self.ou_groups)
881         self.assertEqual(len(res1), 3)
882         dn_list = [str(res.dn) for res in res1]
883         self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
884         self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
885         self.assertTrue("CN=g4,%s" % self.ou_groups in dn_list)
886
887         res1 = self.ldb.search(self.ou_groups,
888                                 scope=SCOPE_SUBTREE,
889                                 expression="member:1.2.840.113556.1.4.1941:=cn=g4,%s" % self.ou_groups)
890         self.assertEqual(len(res1), 0)
891
892         res1 = self.ldb.search(self.ou_groups,
893                                 scope=SCOPE_ONELEVEL,
894                                 expression="member:1.2.840.113556.1.4.1941:=cn=g4,%s" % self.ou_groups)
895         self.assertEqual(len(res1), 0)
896
897         res1 = self.ldb.search(self.ou_groups,
898                                 scope=SCOPE_BASE,
899                                 expression="memberOf=cn=g4,%s" % self.ou_groups)
900         self.assertEqual(len(res1), 0)
901
902         res1 = self.ldb.search("cn=g4,%s" % self.ou_groups,
903                                 scope=SCOPE_BASE,
904                                 expression="memberOf=cn=g4,%s" % self.ou_groups)
905         self.assertEqual(len(res1), 0)
906
907         res1 = self.ldb.search(self.ou_groups,
908                                 scope=SCOPE_SUBTREE,
909                                 expression="memberOf=cn=g4,%s" % self.ou_groups)
910         self.assertEqual(len(res1), 1)
911         self.assertEqual(str(res1[0].dn), ("CN=g3,%s" % self.ou_groups))
912
913         res1 = self.ldb.search(self.ou_groups,
914                                 scope=SCOPE_ONELEVEL,
915                                 expression="memberOf=cn=g4,%s" % self.ou_groups)
916         self.assertEqual(len(res1), 1)
917         self.assertEqual(str(res1[0].dn), ("CN=g3,%s" % self.ou_groups))
918
919         res1 = self.ldb.search(self.ou_groups,
920                                 scope=SCOPE_BASE,
921                                 expression="memberOf:1.2.840.113556.1.4.1941:=cn=g4,%s" % self.ou_groups)
922         self.assertEqual(len(res1), 0)
923
924         res1 = self.ldb.search("cn=g4,%s" % self.ou_groups,
925                                 scope=SCOPE_BASE,
926                                 expression="memberOf:1.2.840.113556.1.4.1941:=cn=g4,%s" % self.ou_groups)
927         self.assertEqual(len(res1), 0)
928
929         res1 = self.ldb.search(self.ou_groups,
930                                 scope=SCOPE_SUBTREE,
931                                 expression="memberOf:1.2.840.113556.1.4.1941:=cn=g4,%s" % self.ou_groups)
932         self.assertEqual(len(res1), 3)
933         dn_list = [str(res.dn) for res in res1]
934         self.assertTrue("CN=g1,%s" % self.ou_groups in dn_list)
935         self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
936         self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
937
938         res1 = self.ldb.search(self.ou_groups,
939                                 scope=SCOPE_ONELEVEL,
940                                 expression="memberOf:1.2.840.113556.1.4.1941:=cn=g4,%s" % self.ou_groups)
941         self.assertEqual(len(res1), 3)
942         dn_list = [str(res.dn) for res in res1]
943         self.assertTrue("CN=g1,%s" % self.ou_groups in dn_list)
944         self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
945         self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
946
947         res1 = self.ldb.search(self.ou_groups,
948                                 scope=SCOPE_SUBTREE,
949                                 expression="memberOf:1.2.840.113556.1.4.1941:=cn=g1,%s" % self.ou_groups)
950         self.assertEqual(len(res1), 0)
951
952         res1 = self.ldb.search(self.ou_groups,
953                                 scope=SCOPE_SUBTREE,
954                                 expression="memberOf:1.2.840.113556.1.4.1941:=cn=g1,%s" % self.ou_groups)
955         self.assertEqual(len(res1), 0)
956
957 class MatchRuleConditionTests(samba.tests.TestCase):
958     def setUp(self):
959         super(MatchRuleConditionTests, self).setUp()
960         self.lp = lp
961         self.ldb = SamDB(host, credentials=creds, session_info=system_session(lp), lp=lp)
962         self.base_dn = self.ldb.domain_dn()
963         self.ou = "OU=matchruleconditiontests,%s" % self.base_dn
964         self.ou_users = "OU=users,%s" % self.ou
965         self.ou_groups = "OU=groups,%s" % self.ou
966         self.ou_computers = "OU=computers,%s" % self.ou
967
968         # Add a organizational unit to create objects
969         self.ldb.add({
970             "dn": self.ou,
971             "objectclass": "organizationalUnit"})
972
973         # Create users, groups, and computers
974         self.ldb.add({
975             "dn": self.ou_users,
976             "objectclass": "organizationalUnit"})
977         self.ldb.add({
978             "dn": self.ou_groups,
979             "objectclass": "organizationalUnit"})
980         self.ldb.add({
981             "dn": self.ou_computers,
982             "objectclass": "organizationalUnit"})
983
984         self.ldb.add({
985             "dn": "cn=g1,%s" % self.ou_groups,
986             "objectclass": "group" })
987         self.ldb.add({
988             "dn": "cn=g2,%s" % self.ou_groups,
989             "objectclass": "group" })
990         self.ldb.add({
991             "dn": "cn=g3,%s" % self.ou_groups,
992             "objectclass": "group" })
993         self.ldb.add({
994             "dn": "cn=g4,%s" % self.ou_groups,
995             "objectclass": "group" })
996
997         self.ldb.add({
998             "dn": "cn=u1,%s" % self.ou_users,
999             "objectclass": "group"})
1000         self.ldb.add({
1001             "dn": "cn=u2,%s" % self.ou_users,
1002             "objectclass": "group"})
1003         self.ldb.add({
1004             "dn": "cn=u3,%s" % self.ou_users,
1005             "objectclass": "group"})
1006         self.ldb.add({
1007             "dn": "cn=u4,%s" % self.ou_users,
1008             "objectclass": "group"})
1009
1010         self.ldb.add({
1011             "dn": "cn=c1,%s" % self.ou_computers,
1012             "objectclass": "user"})
1013
1014         self.ldb.add({
1015             "dn": "cn=c2,%s" % self.ou_computers,
1016             "objectclass": "user"})
1017
1018         self.ldb.add({
1019             "dn": "cn=c3,%s" % self.ou_computers,
1020             "objectclass": "user"})
1021
1022         self.ldb.add({
1023             "dn": "cn=c4,%s" % self.ou_computers,
1024             "objectclass": "user"})
1025
1026         # Assign groups according to the following structure:
1027         #  g1-->g2---->g3   --g4
1028         #     \  |    / |  / / |
1029         #  u1- >u2-- | u3<- | u4
1030         #     \     \ \      \ |
1031         #  c1* >c2   ->c3     c4
1032         # *c1 is a member of u1, u2, u3, and u4
1033
1034         # u2 is a member of g1 and g2
1035         m = Message()
1036         m.dn = Dn(self.ldb, "CN=g1,%s" % self.ou_groups)
1037         m["member"] = MessageElement("CN=u2,%s" % self.ou_users,
1038                                      FLAG_MOD_ADD, "member")
1039         self.ldb.modify(m)
1040
1041         m = Message()
1042         m.dn = Dn(self.ldb, "CN=g2,%s" % self.ou_groups)
1043         m["member"] = MessageElement("CN=u2,%s" % self.ou_users,
1044                                      FLAG_MOD_ADD, "member")
1045         self.ldb.modify(m)
1046
1047         # g2 is a member of g1
1048         m = Message()
1049         m.dn = Dn(self.ldb, "CN=g1,%s" % self.ou_groups)
1050         m["member"] = MessageElement("CN=g2,%s" % self.ou_groups,
1051                                      FLAG_MOD_ADD, "member")
1052         self.ldb.modify(m)
1053
1054         # g3 is a member of g2
1055         m = Message()
1056         m.dn = Dn(self.ldb, "CN=g2,%s" % self.ou_groups)
1057         m["member"] = MessageElement("CN=g3,%s" % self.ou_groups,
1058                                      FLAG_MOD_ADD, "member")
1059         self.ldb.modify(m)
1060
1061         # u3 is a member of g3 and g4
1062         m = Message()
1063         m.dn = Dn(self.ldb, "CN=g3,%s" % self.ou_groups)
1064         m["member"] = MessageElement("CN=u3,%s" % self.ou_users,
1065                                      FLAG_MOD_ADD, "member")
1066         self.ldb.modify(m)
1067
1068         m = Message()
1069         m.dn = Dn(self.ldb, "CN=g4,%s" % self.ou_groups)
1070         m["member"] = MessageElement("CN=u3,%s" % self.ou_users,
1071                                      FLAG_MOD_ADD, "member")
1072         self.ldb.modify(m)
1073
1074         # u4 is a member of g4
1075         m = Message()
1076         m.dn = Dn(self.ldb, "CN=g4,%s" % self.ou_groups)
1077         m["member"] = MessageElement("CN=u4,%s" % self.ou_users,
1078                                      FLAG_MOD_ADD, "member")
1079         self.ldb.modify(m)
1080
1081         # c1 is a member of u1, u2, u3, and u4
1082         m = Message()
1083         m.dn = Dn(self.ldb, "CN=u1,%s" % self.ou_users)
1084         m["member"] = MessageElement("CN=c1,%s" % self.ou_computers,
1085                                      FLAG_MOD_ADD, "member")
1086         self.ldb.modify(m)
1087
1088         m = Message()
1089         m.dn = Dn(self.ldb, "CN=u2,%s" % self.ou_users)
1090         m["member"] = MessageElement("CN=c1,%s" % self.ou_computers,
1091                                      FLAG_MOD_ADD, "member")
1092         self.ldb.modify(m)
1093
1094         m = Message()
1095         m.dn = Dn(self.ldb, "CN=u3,%s" % self.ou_users)
1096         m["member"] = MessageElement("CN=c1,%s" % self.ou_computers,
1097                                      FLAG_MOD_ADD, "member")
1098         self.ldb.modify(m)
1099
1100         m = Message()
1101         m.dn = Dn(self.ldb, "CN=u4,%s" % self.ou_users)
1102         m["member"] = MessageElement("CN=c1,%s" % self.ou_computers,
1103                                      FLAG_MOD_ADD, "member")
1104         self.ldb.modify(m)
1105
1106         # c2 is a member of u1
1107         m = Message()
1108         m.dn = Dn(self.ldb, "CN=u1,%s" % self.ou_users)
1109         m["member"] = MessageElement("CN=c2,%s" % self.ou_computers,
1110                                      FLAG_MOD_ADD, "member")
1111         self.ldb.modify(m)
1112
1113         # c3 is a member of u2 and g3
1114         m = Message()
1115         m.dn = Dn(self.ldb, "CN=u2,%s" % self.ou_users)
1116         m["member"] = MessageElement("CN=c3,%s" % self.ou_computers,
1117                                      FLAG_MOD_ADD, "member")
1118         self.ldb.modify(m)
1119
1120         m = Message()
1121         m.dn = Dn(self.ldb, "CN=g3,%s" % self.ou_groups)
1122         m["member"] = MessageElement("CN=c3,%s" % self.ou_computers,
1123                                      FLAG_MOD_ADD, "member")
1124         self.ldb.modify(m)
1125
1126         # c4 is a member of u4 and g4
1127         m = Message()
1128         m.dn = Dn(self.ldb, "CN=u4,%s" % self.ou_users)
1129         m["member"] = MessageElement("CN=c4,%s" % self.ou_computers,
1130                                      FLAG_MOD_ADD, "member")
1131         self.ldb.modify(m)
1132
1133         m = Message()
1134         m.dn = Dn(self.ldb, "CN=g4,%s" % self.ou_groups)
1135         m["member"] = MessageElement("CN=c4,%s" % self.ou_computers,
1136                                      FLAG_MOD_ADD, "member")
1137         self.ldb.modify(m)
1138
1139         self.question = 6*(9-2)
1140         self.answer = 42
1141
1142     def tearDown(self):
1143         super(MatchRuleConditionTests, self).tearDown()
1144         delete_force(self.ldb, "cn=u4,%s" % self.ou_users)
1145         delete_force(self.ldb, "cn=u3,%s" % self.ou_users)
1146         delete_force(self.ldb, "cn=u2,%s" % self.ou_users)
1147         delete_force(self.ldb, "cn=u1,%s" % self.ou_users)
1148         delete_force(self.ldb, "cn=g4,%s" % self.ou_groups)
1149         delete_force(self.ldb, "cn=g3,%s" % self.ou_groups)
1150         delete_force(self.ldb, "cn=g2,%s" % self.ou_groups)
1151         delete_force(self.ldb, "cn=g1,%s" % self.ou_groups)
1152         delete_force(self.ldb, "cn=c1,%s" % self.ou_computers)
1153         delete_force(self.ldb, "cn=c2,%s" % self.ou_computers)
1154         delete_force(self.ldb, "cn=c3,%s" % self.ou_computers)
1155         delete_force(self.ldb, "cn=c4,%s" % self.ou_computers)
1156         delete_force(self.ldb, self.ou_users)
1157         delete_force(self.ldb, self.ou_groups)
1158         delete_force(self.ldb, self.ou_computers)
1159         delete_force(self.ldb, self.ou)
1160
1161
1162     def test_g1_members(self):
1163         res1 = self.ldb.search(self.ou,
1164                                 scope=SCOPE_SUBTREE,
1165                                 expression="memberOf=cn=g1,%s" % self.ou_groups)
1166         self.assertEquals(len(res1), 2)
1167         dn_list = [str(res.dn) for res in res1]
1168         self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
1169         self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
1170
1171         res1 = self.ldb.search(self.ou,
1172                                 scope=SCOPE_SUBTREE,
1173                                 expression="memberOf:1.2.840.113556.1.4.1941:=cn=g1,%s" % self.ou_groups)
1174         self.assertEquals(len(res1), 6)
1175         dn_list = [str(res.dn) for res in res1]
1176         self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
1177         self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
1178         self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
1179         self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
1180         self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
1181         self.assertTrue("CN=c3,%s" % self.ou_computers in dn_list)
1182
1183         res1 = self.ldb.search(self.ou,
1184                                 scope=SCOPE_SUBTREE,
1185                                 expression="member=cn=g1,%s" % self.ou_groups)
1186         self.assertEquals(len(res1), 0)
1187
1188         res1 = self.ldb.search(self.ou,
1189                                 scope=SCOPE_SUBTREE,
1190                                 expression="member:1.2.840.113556.1.4.1941:=cn=g1,%s" % self.ou_groups)
1191         self.assertEquals(len(res1), 0)
1192
1193     def test_g2_members(self):
1194         res1 = self.ldb.search(self.ou,
1195                                 scope=SCOPE_SUBTREE,
1196                                 expression="memberOf=cn=g2,%s" % self.ou_groups)
1197         self.assertEquals(len(res1), 2)
1198         dn_list = [str(res.dn) for res in res1]
1199         self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
1200         self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
1201
1202         res1 = self.ldb.search(self.ou,
1203                                 scope=SCOPE_SUBTREE,
1204                                 expression="memberOf:1.2.840.113556.1.4.1941:=cn=g2,%s" % self.ou_groups)
1205         self.assertEquals(len(res1), 5)
1206         dn_list = [str(res.dn) for res in res1]
1207         self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
1208         self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
1209         self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
1210         self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
1211         self.assertTrue("CN=c3,%s" % self.ou_computers in dn_list)
1212
1213         res1 = self.ldb.search(self.ou,
1214                                 scope=SCOPE_SUBTREE,
1215                                 expression="member=cn=g2,%s" % self.ou_groups)
1216         self.assertEquals(len(res1), 1)
1217         self.assertEquals(str(res1[0].dn), "CN=g1,%s" % self.ou_groups)
1218
1219         res1 = self.ldb.search(self.ou,
1220                                 scope=SCOPE_SUBTREE,
1221                                 expression="member:1.2.840.113556.1.4.1941:=cn=g2,%s" % self.ou_groups)
1222         self.assertEquals(len(res1), 1)
1223         self.assertEquals(str(res1[0].dn), "CN=g1,%s" % self.ou_groups)
1224
1225     def test_g3_members(self):
1226         res1 = self.ldb.search(self.ou,
1227                                 scope=SCOPE_SUBTREE,
1228                                 expression="memberOf=cn=g3,%s" % self.ou_groups)
1229         self.assertEquals(len(res1), 2)
1230         dn_list = [str(res.dn) for res in res1]
1231         self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
1232         self.assertTrue("CN=c3,%s" % self.ou_computers in dn_list)
1233
1234         res1 = self.ldb.search(self.ou,
1235                                 scope=SCOPE_SUBTREE,
1236                                 expression="memberOf:1.2.840.113556.1.4.1941:=cn=g3,%s" % self.ou_groups)
1237         self.assertEquals(len(res1), 3)
1238         dn_list = [str(res.dn) for res in res1]
1239         self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
1240         self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
1241         self.assertTrue("CN=c3,%s" % self.ou_computers in dn_list)
1242
1243         res1 = self.ldb.search(self.ou,
1244                                 scope=SCOPE_SUBTREE,
1245                                 expression="member=cn=g3,%s" % self.ou_groups)
1246         self.assertEquals(len(res1), 1)
1247         self.assertEquals(str(res1[0].dn), "CN=g2,%s" % self.ou_groups)
1248
1249         res1 = self.ldb.search(self.ou,
1250                                 scope=SCOPE_SUBTREE,
1251                                 expression="member:1.2.840.113556.1.4.1941:=cn=g3,%s" % self.ou_groups)
1252         self.assertEquals(len(res1), 2)
1253         dn_list = [str(res.dn) for res in res1]
1254         self.assertTrue("CN=g1,%s" % self.ou_groups in dn_list)
1255         self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
1256
1257     def test_g4_members(self):
1258         res1 = self.ldb.search(self.ou,
1259                                 scope=SCOPE_SUBTREE,
1260                                 expression="memberOf=cn=g4,%s" % self.ou_groups)
1261         self.assertEquals(len(res1), 3)
1262         dn_list = [str(res.dn) for res in res1]
1263         self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
1264         self.assertTrue("CN=u4,%s" % self.ou_users in dn_list)
1265         self.assertTrue("CN=c4,%s" % self.ou_computers in dn_list)
1266
1267         res1 = self.ldb.search(self.ou,
1268                                 scope=SCOPE_SUBTREE,
1269                                 expression="memberOf:1.2.840.113556.1.4.1941:=cn=g4,%s" % self.ou_groups)
1270         self.assertEquals(len(res1), 4)
1271         dn_list = [str(res.dn) for res in res1]
1272         self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
1273         self.assertTrue("CN=u4,%s" % self.ou_users in dn_list)
1274         self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
1275         self.assertTrue("CN=c4,%s" % self.ou_computers in dn_list)
1276
1277         res1 = self.ldb.search(self.ou,
1278                                 scope=SCOPE_SUBTREE,
1279                                 expression="member=cn=g4,%s" % self.ou_groups)
1280         self.assertEquals(len(res1), 0)
1281
1282         res1 = self.ldb.search(self.ou,
1283                                 scope=SCOPE_SUBTREE,
1284                                 expression="member:1.2.840.113556.1.4.1941:=cn=g4,%s" % self.ou_groups)
1285         self.assertEquals(len(res1), 0)
1286
1287     def test_u1_members(self):
1288         res1 = self.ldb.search(self.ou,
1289                                 scope=SCOPE_SUBTREE,
1290                                 expression="memberOf=cn=u1,%s" % self.ou_users)
1291         self.assertEqual(len(res1), 2)
1292         dn_list = [str(res.dn) for res in res1]
1293         self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
1294         self.assertTrue("CN=c2,%s" % self.ou_computers in dn_list)
1295
1296         res1 = self.ldb.search(self.ou,
1297                                 scope=SCOPE_SUBTREE,
1298                                 expression="memberOf:1.2.840.113556.1.4.1941:=cn=u1,%s" % self.ou_users)
1299         self.assertEqual(len(res1), 2)
1300         dn_list = [str(res.dn) for res in res1]
1301         self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
1302         self.assertTrue("CN=c2,%s" % self.ou_computers in dn_list)
1303
1304         res1 = self.ldb.search(self.ou,
1305                                 scope=SCOPE_SUBTREE,
1306                                 expression="member=cn=u1,%s" % self.ou_users)
1307         self.assertEqual(len(res1), 0)
1308
1309         res1 = self.ldb.search(self.ou,
1310                                 scope=SCOPE_SUBTREE,
1311                                 expression="member:1.2.840.113556.1.4.1941:=cn=u1,%s" % self.ou_users)
1312         self.assertEqual(len(res1), 0)
1313
1314     def test_u2_members(self):
1315         res1 = self.ldb.search(self.ou,
1316                                 scope=SCOPE_SUBTREE,
1317                                 expression="memberOf=cn=u2,%s" % self.ou_users)
1318         self.assertEqual(len(res1), 2)
1319         dn_list = [str(res.dn) for res in res1]
1320         self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
1321         self.assertTrue("CN=c3,%s" % self.ou_computers in dn_list)
1322
1323         res1 = self.ldb.search(self.ou,
1324                                 scope=SCOPE_SUBTREE,
1325                                 expression="memberOf:1.2.840.113556.1.4.1941:=cn=u2,%s" % self.ou_users)
1326         self.assertEqual(len(res1), 2)
1327         dn_list = [str(res.dn) for res in res1]
1328         self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
1329         self.assertTrue("CN=c3,%s" % self.ou_computers in dn_list)
1330
1331         res1 = self.ldb.search(self.ou,
1332                                 scope=SCOPE_SUBTREE,
1333                                 expression="member=cn=u2,%s" % self.ou_users)
1334         self.assertEqual(len(res1), 2)
1335         dn_list = [str(res.dn) for res in res1]
1336         self.assertTrue("CN=g1,%s" % self.ou_groups in dn_list)
1337         self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
1338
1339         res1 = self.ldb.search(self.ou,
1340                                 scope=SCOPE_SUBTREE,
1341                                 expression="member:1.2.840.113556.1.4.1941:=cn=u2,%s" % self.ou_users)
1342         self.assertEqual(len(res1), 2)
1343         dn_list = [str(res.dn) for res in res1]
1344         self.assertTrue("CN=g1,%s" % self.ou_groups in dn_list)
1345         self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
1346
1347     def test_u3_members(self):
1348         res1 = self.ldb.search(self.ou,
1349                                 scope=SCOPE_SUBTREE,
1350                                 expression="member=cn=u3,%s" % self.ou_users)
1351         self.assertEqual(len(res1), 2)
1352         dn_list = [str(res.dn) for res in res1]
1353         self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
1354         self.assertTrue("CN=g4,%s" % self.ou_groups in dn_list)
1355
1356         res1 = self.ldb.search(self.ou,
1357                                 scope=SCOPE_SUBTREE,
1358                                 expression="member:1.2.840.113556.1.4.1941:=cn=u3,%s" % self.ou_users)
1359         self.assertEqual(len(res1), 4)
1360         dn_list = [str(res.dn) for res in res1]
1361         self.assertTrue("CN=g1,%s" % self.ou_groups in dn_list)
1362         self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
1363         self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
1364         self.assertTrue("CN=g4,%s" % self.ou_groups in dn_list)
1365
1366         res1 = self.ldb.search(self.ou,
1367                                 scope=SCOPE_SUBTREE,
1368                                 expression="memberOf=cn=u3,%s" % self.ou_users)
1369         self.assertEqual(len(res1), 1)
1370         self.assertEqual(str(res1[0].dn), "CN=c1,%s" % self.ou_computers)
1371
1372         res1 = self.ldb.search(self.ou,
1373                                 scope=SCOPE_SUBTREE,
1374                                 expression="memberOf:1.2.840.113556.1.4.1941:=cn=u3,%s" % self.ou_users)
1375         self.assertEqual(len(res1), 1)
1376         self.assertEqual(str(res1[0].dn), "CN=c1,%s" % self.ou_computers)
1377
1378     def test_u4_members(self):
1379         res1 = self.ldb.search(self.ou,
1380                                 scope=SCOPE_SUBTREE,
1381                                 expression="member=cn=u4,%s" % self.ou_users)
1382         self.assertEqual(len(res1), 1)
1383         self.assertEqual(str(res1[0].dn), "CN=g4,%s" % self.ou_groups)
1384
1385         res1 = self.ldb.search(self.ou,
1386                                 scope=SCOPE_SUBTREE,
1387                                 expression="member:1.2.840.113556.1.4.1941:=cn=u4,%s" % self.ou_users)
1388         self.assertEqual(len(res1), 1)
1389         self.assertEqual(str(res1[0].dn), "CN=g4,%s" % self.ou_groups)
1390
1391         res1 = self.ldb.search(self.ou,
1392                                 scope=SCOPE_SUBTREE,
1393                                 expression="memberOf=cn=u4,%s" % self.ou_users)
1394         self.assertEqual(len(res1), 2)
1395         dn_list = [str(res.dn) for res in res1]
1396         self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
1397         self.assertTrue("CN=c4,%s" % self.ou_computers in dn_list)
1398
1399         res1 = self.ldb.search(self.ou,
1400                                 scope=SCOPE_SUBTREE,
1401                                 expression="memberOf:1.2.840.113556.1.4.1941:=cn=u4,%s" % self.ou_users)
1402         self.assertEqual(len(res1), 2)
1403         dn_list = [str(res.dn) for res in res1]
1404         self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
1405         self.assertTrue("CN=c4,%s" % self.ou_computers in dn_list)
1406
1407     def test_c1_members(self):
1408         res1 = self.ldb.search(self.ou,
1409                                 scope=SCOPE_SUBTREE,
1410                                 expression="member=cn=c1,%s" % self.ou_computers)
1411         self.assertEqual(len(res1), 4)
1412         dn_list = [str(res.dn) for res in res1]
1413         self.assertTrue("CN=u1,%s" % self.ou_users in dn_list)
1414         self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
1415         self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
1416         self.assertTrue("CN=u4,%s" % self.ou_users in dn_list)
1417
1418         res1 = self.ldb.search(self.ou,
1419                                 scope=SCOPE_SUBTREE,
1420                                 expression="member:1.2.840.113556.1.4.1941:=cn=c1,%s" % self.ou_computers)
1421         self.assertEqual(len(res1), 8)
1422         dn_list = [str(res.dn) for res in res1]
1423         self.assertTrue("CN=u1,%s" % self.ou_users in dn_list)
1424         self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
1425         self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
1426         self.assertTrue("CN=u4,%s" % self.ou_users in dn_list)
1427         self.assertTrue("CN=g1,%s" % self.ou_groups in dn_list)
1428         self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
1429         self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
1430         self.assertTrue("CN=g4,%s" % self.ou_groups in dn_list)
1431
1432         res1 = self.ldb.search(self.ou,
1433                                 scope=SCOPE_SUBTREE,
1434                                 expression="memberOf=cn=c1,%s" % self.ou_computers)
1435         self.assertEqual(len(res1), 0)
1436
1437         res1 = self.ldb.search(self.ou,
1438                                 scope=SCOPE_SUBTREE,
1439                                 expression="memberOf:1.2.840.113556.1.4.1941:=cn=c1,%s" % self.ou_computers)
1440         self.assertEqual(len(res1), 0)
1441
1442     def test_c2_members(self):
1443         res1 = self.ldb.search(self.ou,
1444                                 scope=SCOPE_SUBTREE,
1445                                 expression="member=cn=c2,%s" % self.ou_computers)
1446         self.assertEqual(len(res1), 1)
1447         self.assertEqual(str(res1[0].dn), "CN=u1,%s" % self.ou_users)
1448
1449         res1 = self.ldb.search(self.ou,
1450                                 scope=SCOPE_SUBTREE,
1451                                 expression="member:1.2.840.113556.1.4.1941:=cn=c2,%s" % self.ou_computers)
1452         self.assertEqual(len(res1), 1)
1453         self.assertEqual(str(res1[0].dn), "CN=u1,%s" % self.ou_users)
1454
1455         res1 = self.ldb.search(self.ou,
1456                                 scope=SCOPE_SUBTREE,
1457                                 expression="memberOf=cn=c2,%s" % self.ou_computers)
1458         self.assertEqual(len(res1), 0)
1459
1460         res1 = self.ldb.search(self.ou,
1461                                 scope=SCOPE_SUBTREE,
1462                                 expression="memberOf:1.2.840.113556.1.4.1941:=cn=c2,%s" % self.ou_computers)
1463         self.assertEqual(len(res1), 0)
1464
1465     def test_c3_members(self):
1466         res1 = self.ldb.search(self.ou,
1467                                 scope=SCOPE_SUBTREE,
1468                                 expression="member=cn=c3,%s" % self.ou_computers)
1469         self.assertEqual(len(res1), 2)
1470         dn_list = [str(res.dn) for res in res1]
1471         self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
1472         self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
1473
1474         res1 = self.ldb.search(self.ou,
1475                                 scope=SCOPE_SUBTREE,
1476                                 expression="member:1.2.840.113556.1.4.1941:=cn=c3,%s" % self.ou_computers)
1477         self.assertEqual(len(res1), 4)
1478         dn_list = [str(res.dn) for res in res1]
1479         self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
1480         self.assertTrue("CN=g1,%s" % self.ou_groups in dn_list)
1481         self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
1482         self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
1483
1484         res1 = self.ldb.search(self.ou,
1485                                 scope=SCOPE_SUBTREE,
1486                                 expression="memberOf=cn=c3,%s" % self.ou_computers)
1487         self.assertEqual(len(res1), 0)
1488
1489         res1 = self.ldb.search(self.ou,
1490                                 scope=SCOPE_SUBTREE,
1491                                 expression="memberOf:1.2.840.113556.1.4.1941:=cn=c3,%s" % self.ou_computers)
1492         self.assertEqual(len(res1), 0)
1493
1494     def test_c4_members(self):
1495         res1 = self.ldb.search(self.ou,
1496                                 scope=SCOPE_SUBTREE,
1497                                 expression="member=cn=c4,%s" % self.ou_computers)
1498         self.assertEqual(len(res1), 2)
1499         dn_list = [str(res.dn) for res in res1]
1500         self.assertTrue("CN=g4,%s" % self.ou_groups in dn_list)
1501         self.assertTrue("CN=u4,%s" % self.ou_users in dn_list)
1502
1503         res1 = self.ldb.search(self.ou,
1504                                 scope=SCOPE_SUBTREE,
1505                                 expression="member:1.2.840.113556.1.4.1941:=cn=c4,%s" % self.ou_computers)
1506         self.assertEqual(len(res1), 2)
1507         dn_list = [str(res.dn) for res in res1]
1508         self.assertTrue("CN=u4,%s" % self.ou_users in dn_list)
1509         self.assertTrue("CN=g4,%s" % self.ou_groups in dn_list)
1510
1511         res1 = self.ldb.search(self.ou,
1512                                 scope=SCOPE_SUBTREE,
1513                                 expression="memberOf=cn=c4,%s" % self.ou_computers)
1514         self.assertEqual(len(res1), 0)
1515
1516         res1 = self.ldb.search(self.ou,
1517                                 scope=SCOPE_SUBTREE,
1518                                 expression="memberOf:1.2.840.113556.1.4.1941:=cn=c4,%s" % self.ou_computers)
1519         self.assertEqual(len(res1), 0)
1520
1521     def test_or_member_queries(self):
1522         res1 = self.ldb.search(self.ou,
1523                                 scope=SCOPE_SUBTREE,
1524                                 expression=("(|(member:1.2.840.113556.1.4.1941:=cn=c1,%s)"
1525                                             "(member:1.2.840.113556.1.4.1941:=cn=c2,%s))") % (
1526                                             self.ou_computers, self.ou_computers))
1527         self.assertEqual(len(res1), 8)
1528         dn_list = [str(res.dn) for res in res1]
1529         self.assertTrue("CN=u1,%s" % self.ou_users in dn_list)
1530         self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
1531         self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
1532         self.assertTrue("CN=u4,%s" % self.ou_users in dn_list)
1533         self.assertTrue("CN=g1,%s" % self.ou_groups in dn_list)
1534         self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
1535         self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
1536         self.assertTrue("CN=g4,%s" % self.ou_groups in dn_list)
1537
1538         res1 = self.ldb.search(self.ou,
1539                                 scope=SCOPE_SUBTREE,
1540                                 expression=("(|(member:1.2.840.113556.1.4.1941:=cn=c2,%s)"
1541                                             "(member:1.2.840.113556.1.4.1941:=cn=c3,%s))") % (
1542                                             self.ou_computers, self.ou_computers))
1543         self.assertEqual(len(res1), 5)
1544         dn_list = [str(res.dn) for res in res1]
1545         self.assertTrue("CN=u1,%s" % self.ou_users in dn_list)
1546         self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
1547         self.assertTrue("CN=g1,%s" % self.ou_groups in dn_list)
1548         self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
1549         self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
1550
1551         res1 = self.ldb.search(self.ou,
1552                                 scope=SCOPE_SUBTREE,
1553                                 expression=("(|(member:1.2.840.113556.1.4.1941:=cn=c2,%s)"
1554                                             "(member:1.2.840.113556.1.4.1941:=cn=c4,%s))") % (
1555                                             self.ou_computers, self.ou_computers))
1556         self.assertEqual(len(res1), 3)
1557         dn_list = [str(res.dn) for res in res1]
1558         self.assertTrue("CN=u1,%s" % self.ou_users in dn_list)
1559         self.assertTrue("CN=u4,%s" % self.ou_users in dn_list)
1560         self.assertTrue("CN=g4,%s" % self.ou_groups in dn_list)
1561
1562         res1 = self.ldb.search(self.ou,
1563                                 scope=SCOPE_SUBTREE,
1564                                 expression=("(|(member:1.2.840.113556.1.4.1941:=cn=c3,%s)"
1565                                             "(member:1.2.840.113556.1.4.1941:=cn=c4,%s))") % (
1566                                             self.ou_computers, self.ou_computers))
1567         self.assertEqual(len(res1), 6)
1568         dn_list = [str(res.dn) for res in res1]
1569         self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
1570         self.assertTrue("CN=u4,%s" % self.ou_users in dn_list)
1571         self.assertTrue("CN=g1,%s" % self.ou_groups in dn_list)
1572         self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
1573         self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
1574         self.assertTrue("CN=g4,%s" % self.ou_groups in dn_list)
1575
1576         res1 = self.ldb.search(self.ou,
1577                                 scope=SCOPE_SUBTREE,
1578                                 expression=("(|(member:1.2.840.113556.1.4.1941:=cn=u1,%s)"
1579                                             "(member:1.2.840.113556.1.4.1941:=cn=c4,%s))") % (
1580                                             self.ou_users, self.ou_computers))
1581         self.assertEqual(len(res1), 2)
1582         dn_list = [str(res.dn) for res in res1]
1583         self.assertTrue("CN=u4,%s" % self.ou_users in dn_list)
1584         self.assertTrue("CN=g4,%s" % self.ou_groups in dn_list)
1585
1586     def test_and_member_queries(self):
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=c2,%s))") % (
1591                                             self.ou_computers, self.ou_computers))
1592         self.assertEqual(len(res1), 1)
1593         self.assertEqual(str(res1[0].dn), "CN=u1,%s" % self.ou_users)
1594
1595         res1 = self.ldb.search(self.ou,
1596                                 scope=SCOPE_SUBTREE,
1597                                 expression=("(&(member:1.2.840.113556.1.4.1941:=cn=c2,%s)"
1598                                             "(member:1.2.840.113556.1.4.1941:=cn=c3,%s))") % (
1599                                             self.ou_computers, self.ou_computers))
1600         self.assertEqual(len(res1), 0)
1601
1602         res1 = self.ldb.search(self.ou,
1603                                 scope=SCOPE_SUBTREE,
1604                                 expression=("(&(member:1.2.840.113556.1.4.1941:=cn=c3,%s)"
1605                                             "(member:1.2.840.113556.1.4.1941:=cn=u3,%s))") % (
1606                                             self.ou_computers, self.ou_users))
1607         self.assertEqual(len(res1), 3)
1608         dn_list = [str(res.dn) for res in res1]
1609         self.assertTrue("CN=g1,%s" % self.ou_groups in dn_list)
1610         self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
1611         self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
1612
1613         res1 = self.ldb.search(self.ou,
1614                                 scope=SCOPE_SUBTREE,
1615                                 expression=("(&(member:1.2.840.113556.1.4.1941:=cn=c1,%s)"
1616                                             "(member:1.2.840.113556.1.4.1941:=cn=u4,%s))") % (
1617                                             self.ou_computers, self.ou_computers))
1618         self.assertEqual(len(res1), 0)
1619
1620     def test_or_memberOf_queries(self):
1621         res1 = self.ldb.search(self.ou,
1622                                 scope=SCOPE_SUBTREE,
1623                                 expression=("(|(memberOf:1.2.840.113556.1.4.1941:=cn=g1,%s)"
1624                                             "(memberOf:1.2.840.113556.1.4.1941:=cn=g2,%s))") % (
1625                                             self.ou_groups, self.ou_groups))
1626         self.assertEqual(len(res1), 6)
1627         dn_list = [str(res.dn) for res in res1]
1628         self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
1629         self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
1630         self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
1631         self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
1632         self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
1633         self.assertTrue("CN=c3,%s" % self.ou_computers in dn_list)
1634
1635         res1 = self.ldb.search(self.ou,
1636                                 scope=SCOPE_SUBTREE,
1637                                 expression=("(|(memberOf:1.2.840.113556.1.4.1941:=cn=g1,%s)"
1638                                             "(memberOf:1.2.840.113556.1.4.1941:=cn=g3,%s))") % (
1639                                             self.ou_groups, self.ou_groups))
1640         self.assertEqual(len(res1), 6)
1641         dn_list = [str(res.dn) for res in res1]
1642         self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
1643         self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
1644         self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
1645         self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
1646         self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
1647         self.assertTrue("CN=c3,%s" % self.ou_computers in dn_list)
1648
1649         res1 = self.ldb.search(self.ou,
1650                                 scope=SCOPE_SUBTREE,
1651                                 expression=("(|(memberOf:1.2.840.113556.1.4.1941:=cn=g1,%s)"
1652                                             "(memberOf:1.2.840.113556.1.4.1941:=cn=g4,%s))") % (
1653                                             self.ou_groups, self.ou_groups))
1654         self.assertEqual(len(res1), 8)
1655         dn_list = [str(res.dn) for res in res1]
1656         self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
1657         self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
1658         self.assertTrue("CN=u4,%s" % self.ou_users in dn_list)
1659         self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
1660         self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
1661         self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
1662         self.assertTrue("CN=c3,%s" % self.ou_computers in dn_list)
1663         self.assertTrue("CN=c4,%s" % self.ou_computers in dn_list)
1664
1665         res1 = self.ldb.search(self.ou,
1666                                 scope=SCOPE_SUBTREE,
1667                                 expression=("(|(memberOf:1.2.840.113556.1.4.1941:=cn=g2,%s)"
1668                                             "(memberOf:1.2.840.113556.1.4.1941:=cn=g3,%s))") %
1669                                             (self.ou_groups, self.ou_groups))
1670         self.assertEqual(len(res1), 5)
1671         dn_list = [str(res.dn) for res in res1]
1672         self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
1673         self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
1674         self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
1675         self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
1676         self.assertTrue("CN=c3,%s" % self.ou_computers in dn_list)
1677
1678         res1 = self.ldb.search(self.ou,
1679                                 scope=SCOPE_SUBTREE,
1680                                 expression=("(|(memberOf:1.2.840.113556.1.4.1941:=cn=g2,%s)"
1681                                             "(memberOf:1.2.840.113556.1.4.1941:=cn=g4,%s))") % (
1682                                             self.ou_groups, self.ou_groups))
1683         self.assertEqual(len(res1), 7)
1684         dn_list = [str(res.dn) for res in res1]
1685         self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
1686         self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
1687         self.assertTrue("CN=u4,%s" % self.ou_users in dn_list)
1688         self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
1689         self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
1690         self.assertTrue("CN=c3,%s" % self.ou_computers in dn_list)
1691         self.assertTrue("CN=c4,%s" % self.ou_computers in dn_list)
1692
1693         res1 = self.ldb.search(self.ou,
1694                                 scope=SCOPE_SUBTREE,
1695                                 expression=("(|(memberOf:1.2.840.113556.1.4.1941:=cn=g3,%s)"
1696                                             "(memberOf:1.2.840.113556.1.4.1941:=cn=g4,%s))") % (
1697                                             self.ou_groups, self.ou_groups))
1698         self.assertEqual(len(res1), 5)
1699         dn_list = [str(res.dn) for res in res1]
1700         self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
1701         self.assertTrue("CN=u4,%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         self.assertTrue("CN=c4,%s" % self.ou_computers in dn_list)
1705
1706     def test_and_memberOf_queries(self):
1707         res1 = self.ldb.search(self.ou,
1708                                 scope=SCOPE_SUBTREE,
1709                                 expression=("(&(memberOf:1.2.840.113556.1.4.1941:=cn=g1,%s)"
1710                                             "(memberOf:1.2.840.113556.1.4.1941:=cn=g2,%s))") % (
1711                                             self.ou_groups, self.ou_groups))
1712         self.assertEqual(len(res1), 5)
1713         dn_list = [str(res.dn) for res in res1]
1714         self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
1715         self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
1716         self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
1717         self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
1718         self.assertTrue("CN=c3,%s" % self.ou_computers in dn_list)
1719
1720         res1 = self.ldb.search(self.ou,
1721                                 scope=SCOPE_SUBTREE,
1722                                 expression=("(&(memberOf:1.2.840.113556.1.4.1941:=cn=g1,%s)"
1723                                             "(memberOf:1.2.840.113556.1.4.1941:=cn=g3,%s))") % (
1724                                             self.ou_groups, self.ou_groups))
1725         self.assertEqual(len(res1), 3)
1726         dn_list = [str(res.dn) for res in res1]
1727         self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
1728         self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
1729         self.assertTrue("CN=c3,%s" % self.ou_computers in dn_list)
1730
1731         res1 = self.ldb.search(self.ou,
1732                                 scope=SCOPE_SUBTREE,
1733                                 expression=("(&(memberOf:1.2.840.113556.1.4.1941:=cn=g1,%s)"
1734                                             "(memberOf:1.2.840.113556.1.4.1941:=cn=g4,%s))") % (
1735                                             self.ou_groups, self.ou_groups))
1736         self.assertEqual(len(res1), 2)
1737         dn_list = [str(res.dn) for res in res1]
1738         self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
1739         self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
1740
1741         res1 = self.ldb.search(self.ou,
1742                                 scope=SCOPE_SUBTREE,
1743                                 expression=("(&(memberOf:1.2.840.113556.1.4.1941:=cn=g2,%s)"
1744                                             "(memberOf:1.2.840.113556.1.4.1941:=cn=g3,%s))") % (
1745                                             self.ou_groups, self.ou_groups))
1746         self.assertEqual(len(res1), 3)
1747         dn_list = [str(res.dn) for res in res1]
1748         self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
1749         self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
1750         self.assertTrue("CN=c3,%s" % self.ou_computers in dn_list)
1751
1752         res1 = self.ldb.search(self.ou,
1753                                 scope=SCOPE_SUBTREE,
1754                                 expression=("(&(memberOf:1.2.840.113556.1.4.1941:=cn=g2,%s)"
1755                                             "(memberOf:1.2.840.113556.1.4.1941:=cn=g4,%s))") % (
1756                                             self.ou_groups, self.ou_groups))
1757         self.assertEqual(len(res1), 2)
1758         dn_list = [str(res.dn) for res in res1]
1759         self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
1760         self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
1761
1762         res1 = self.ldb.search(self.ou,
1763                                 scope=SCOPE_SUBTREE,
1764                                 expression=("(&(memberOf:1.2.840.113556.1.4.1941:=cn=g3,%s)"
1765                                             "(memberOf:1.2.840.113556.1.4.1941:=cn=g4,%s))") % (
1766                                             self.ou_groups, self.ou_groups))
1767         self.assertEqual(len(res1), 2)
1768         dn_list = [str(res.dn) for res in res1]
1769         self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
1770         self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
1771
1772         res1 = self.ldb.search(self.ou,
1773                                 scope=SCOPE_SUBTREE,
1774                                 expression=("(&(memberOf:1.2.840.113556.1.4.1941:=cn=g1,%s)"
1775                                             "(memberOf:1.2.840.113556.1.4.1941:=cn=c1,%s))") % (
1776                                             self.ou_groups, self.ou_computers))
1777         self.assertEqual(len(res1), 0)
1778
1779 parser = optparse.OptionParser("match_rules.py [options] <host>")
1780 sambaopts = options.SambaOptions(parser)
1781 parser.add_option_group(sambaopts)
1782 parser.add_option_group(options.VersionOptions(parser))
1783
1784 # use command line creds if available
1785 credopts = options.CredentialsOptions(parser)
1786 parser.add_option_group(credopts)
1787 opts, args = parser.parse_args()
1788 subunitopts = SubunitOptions(parser)
1789 parser.add_option_group(subunitopts)
1790
1791 if len(args) < 1:
1792     parser.print_usage()
1793     sys.exit(1)
1794
1795 host = args[0]
1796
1797 lp = sambaopts.get_loadparm()
1798 creds = credopts.get_credentials(lp)
1799
1800 if not "://" in host:
1801     if os.path.isfile(host):
1802         host = "tdb://%s" % host
1803     else:
1804         host = "ldap://%s" % host
1805
1806 TestProgram(module=__name__, opts=subunitopts)