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