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