PEP8: fix E305: expected 2 blank lines after class or function definition, found 1
[garming/samba-autobuild/.git] / lib / ldb-samba / tests / match_rules.py
index 1b30e9fbb79737db062f1a2b62d1fc00e9b81238..aaa9675c1960bf19f14696efefee0352505a9e38 100755 (executable)
@@ -16,7 +16,13 @@ from samba.auth import system_session
 from samba.ndr import ndr_unpack
 from ldb import Message, MessageElement, Dn, LdbError
 from ldb import FLAG_MOD_ADD, FLAG_MOD_REPLACE, FLAG_MOD_DELETE
-from ldb import SCOPE_BASE, SCOPE_SUBTREE
+from ldb import SCOPE_BASE, SCOPE_SUBTREE, SCOPE_ONELEVEL
+
+# TODO I'm ignoring case in these tests for now.
+#       This should be fixed to work inline with Windows.
+#       The literal strings are in the case Windows uses.
+# Windows appear to preserve casing of the RDN and uppercase the other keys.
+
 
 class MatchRulesTests(samba.tests.TestCase):
     def setUp(self):
@@ -24,62 +30,62 @@ class MatchRulesTests(samba.tests.TestCase):
         self.lp = lp
         self.ldb = SamDB(host, credentials=creds, session_info=system_session(lp), lp=lp)
         self.base_dn = self.ldb.domain_dn()
-        self.ou = "ou=matchrulestest,%s" % self.base_dn
-        self.ou_users = "ou=users,%s" % self.ou
-        self.ou_groups = "ou=groups,%s" % self.ou
-        self.ou_computers = "ou=computers,%s" % self.ou
+        self.ou = "OU=matchrulestest,%s" % self.base_dn
+        self.ou_users = "OU=users,%s" % self.ou
+        self.ou_groups = "OU=groups,%s" % self.ou
+        self.ou_computers = "OU=computers,%s" % self.ou
 
         # Add a organizational unit to create objects
         self.ldb.add({
             "dn": self.ou,
             "objectclass": "organizationalUnit"})
 
-       # Add the following OU hierarchy and set otherWellKnownObjects,
-       # which has BinaryDN syntax:
-       #
-       # o1
-       # |--> o2
-       # |    |--> o3
-       # |    |    |-->o4
+        # Add the following OU hierarchy and set otherWellKnownObjects,
+        # which has BinaryDN syntax:
+        #
+        # o1
+        # |--> o2
+        # |    |--> o3
+        # |    |    |-->o4
 
-       self.ldb.add({
-           "dn": "OU=o1,%s" % self.ou,
+        self.ldb.add({
+            "dn": "OU=o1,%s" % self.ou,
             "objectclass": "organizationalUnit"})
-       self.ldb.add({
-           "dn": "OU=o2,OU=o1,%s" % self.ou,
+        self.ldb.add({
+            "dn": "OU=o2,OU=o1,%s" % self.ou,
             "objectclass": "organizationalUnit"})
-       self.ldb.add({
-           "dn": "OU=o3,OU=o2,OU=o1,%s" % self.ou,
+        self.ldb.add({
+            "dn": "OU=o3,OU=o2,OU=o1,%s" % self.ou,
             "objectclass": "organizationalUnit"})
-       self.ldb.add({
-           "dn": "OU=o4,OU=o3,OU=o2,OU=o1,%s" % self.ou,
+        self.ldb.add({
+            "dn": "OU=o4,OU=o3,OU=o2,OU=o1,%s" % self.ou,
             "objectclass": "organizationalUnit"})
 
         m = Message()
         m.dn = Dn(self.ldb, self.ou)
         m["otherWellKnownObjects"] = MessageElement("B:32:00000000000000000000000000000001:OU=o1,%s" % self.ou,
-                                     FLAG_MOD_ADD, "otherWellKnownObjects")
+                                                    FLAG_MOD_ADD, "otherWellKnownObjects")
         self.ldb.modify(m)
 
         m = Message()
         m.dn = Dn(self.ldb, "OU=o1,%s" % self.ou)
         m["otherWellKnownObjects"] = MessageElement("B:32:00000000000000000000000000000002:OU=o2,OU=o1,%s" % self.ou,
-                                     FLAG_MOD_ADD, "otherWellKnownObjects")
+                                                    FLAG_MOD_ADD, "otherWellKnownObjects")
         self.ldb.modify(m)
 
         m = Message()
         m.dn = Dn(self.ldb, "OU=o2,OU=o1,%s" % self.ou)
         m["otherWellKnownObjects"] = MessageElement("B:32:00000000000000000000000000000003:OU=o3,OU=o2,OU=o1,%s" % self.ou,
-                                     FLAG_MOD_ADD, "otherWellKnownObjects")
+                                                    FLAG_MOD_ADD, "otherWellKnownObjects")
         self.ldb.modify(m)
 
         m = Message()
         m.dn = Dn(self.ldb, "OU=o3,OU=o2,OU=o1,%s" % self.ou)
         m["otherWellKnownObjects"] = MessageElement("B:32:00000000000000000000000000000004:OU=o4,OU=o3,OU=o2,OU=o1,%s" % self.ou,
-                                     FLAG_MOD_ADD, "otherWellKnownObjects")
+                                                    FLAG_MOD_ADD, "otherWellKnownObjects")
         self.ldb.modify(m)
 
-       # Create OU for users and groups
+        # Create OU for users and groups
         self.ldb.add({
             "dn": self.ou_users,
             "objectclass": "organizationalUnit"})
@@ -93,16 +99,16 @@ class MatchRulesTests(samba.tests.TestCase):
         # Add four groups
         self.ldb.add({
             "dn": "cn=g1,%s" % self.ou_groups,
-            "objectclass": "group" })
+            "objectclass": "group"})
         self.ldb.add({
             "dn": "cn=g2,%s" % self.ou_groups,
-            "objectclass": "group" })
-        self.ldb.add({
-            "dn": "cn=g3,%s" % self.ou_groups,
-            "objectclass": "group" })
+            "objectclass": "group"})
         self.ldb.add({
             "dn": "cn=g4,%s" % self.ou_groups,
-            "objectclass": "group" })
+            "objectclass": "group"})
+        self.ldb.add({
+            "dn": "cn=g3,%s" % self.ou_groups,
+            "objectclass": "group"})
 
         # Add four users
         self.ldb.add({
@@ -155,14 +161,14 @@ class MatchRulesTests(samba.tests.TestCase):
 
         # u1 member of g1
         m = Message()
-        m.dn = Dn(self.ldb, "cn=g1,%s" % self.ou_groups)
-        m["member"] = MessageElement("cn=u1,%s" % self.ou_users,
+        m.dn = Dn(self.ldb, "CN=g1,%s" % self.ou_groups)
+        m["member"] = MessageElement("CN=u1,%s" % self.ou_users,
                                      FLAG_MOD_ADD, "member")
         self.ldb.modify(m)
 
         # u2 member of g2
         m = Message()
-        m.dn = Dn(self.ldb, "cn=g2,%s" % self.ou_groups)
+        m.dn = Dn(self.ldb, "CN=g2,%s" % self.ou_groups)
         m["member"] = MessageElement("cn=u2,%s" % self.ou_users,
                                      FLAG_MOD_ADD, "member")
         self.ldb.modify(m)
@@ -170,7 +176,7 @@ class MatchRulesTests(samba.tests.TestCase):
         # u3 member of g3
         m = Message()
         m.dn = Dn(self.ldb, "cn=g3,%s" % self.ou_groups)
-        m["member"] = MessageElement("cn=u3,%s" % self.ou_users,
+        m["member"] = MessageElement("CN=u3,%s" % self.ou_users,
                                      FLAG_MOD_ADD, "member")
         self.ldb.modify(m)
 
@@ -183,7 +189,7 @@ class MatchRulesTests(samba.tests.TestCase):
 
         # g3 member of g4
         m = Message()
-        m.dn = Dn(self.ldb, "cn=g4,%s" % self.ou_groups)
+        m.dn = Dn(self.ldb, "CN=g4,%s" % self.ou_groups)
         m["member"] = MessageElement("cn=g3,%s" % self.ou_groups,
                                      FLAG_MOD_ADD, "member")
         self.ldb.modify(m)
@@ -191,7 +197,7 @@ class MatchRulesTests(samba.tests.TestCase):
         # g2 member of g3
         m = Message()
         m.dn = Dn(self.ldb, "cn=g3,%s" % self.ou_groups)
-        m["member"] = MessageElement("cn=g2,%s" % self.ou_groups,
+        m["member"] = MessageElement("CN=g2,%s" % self.ou_groups,
                                      FLAG_MOD_ADD, "member")
         self.ldb.modify(m)
 
@@ -267,221 +273,1485 @@ class MatchRulesTests(samba.tests.TestCase):
 
     def tearDown(self):
         super(MatchRulesTests, self).tearDown()
-        delete_force(self.ldb, "cn=u4,%s" % self.ou_users)
-        delete_force(self.ldb, "cn=u3,%s" % self.ou_users)
-        delete_force(self.ldb, "cn=u2,%s" % self.ou_users)
-        delete_force(self.ldb, "cn=u1,%s" % self.ou_users)
-        delete_force(self.ldb, "cn=g4,%s" % self.ou_groups)
-        delete_force(self.ldb, "cn=g3,%s" % self.ou_groups)
-        delete_force(self.ldb, "cn=g2,%s" % self.ou_groups)
-        delete_force(self.ldb, "cn=g1,%s" % self.ou_groups)
-        delete_force(self.ldb, "cn=c1,%s" % self.ou_computers)
-        delete_force(self.ldb, "cn=c2,%s" % self.ou_computers)
-        delete_force(self.ldb, "cn=c3,%s" % self.ou_computers)
-        delete_force(self.ldb, self.ou_users)
-        delete_force(self.ldb, self.ou_groups)
-        delete_force(self.ldb, self.ou_computers)
-        delete_force(self.ldb, "OU=o4,OU=o3,OU=o2,OU=o1,%s" % self.ou)
-        delete_force(self.ldb, "OU=o3,OU=o2,OU=o1,%s" % self.ou)
-        delete_force(self.ldb, "OU=o2,OU=o1,%s" % self.ou)
-        delete_force(self.ldb, "OU=o1,%s" % self.ou)
-        delete_force(self.ldb, "CN=e2,%s" % self.ou)
-        delete_force(self.ldb, "CN=e1,%s" % self.ou)
-        delete_force(self.ldb, self.ou)
+        self.ldb.delete(self.ou, controls=['tree_delete:0'])
 
     def test_u1_member_of_g4(self):
         # Search without transitive match must return 0 results
         res1 = self.ldb.search("cn=g4,%s" % self.ou_groups,
-                        scope=SCOPE_BASE,
-                        expression="member=cn=u1,%s" % self.ou_users)
-        self.assertTrue(len(res1) == 0)
+                               scope=SCOPE_BASE,
+                               expression="member=cn=u1,%s" % self.ou_users)
+        self.assertEqual(len(res1), 0)
 
         res1 = self.ldb.search("cn=u1,%s" % self.ou_users,
-                        scope=SCOPE_BASE,
-                        expression="memberOf=cn=g4,%s" % self.ou_groups)
-        self.assertTrue(len(res1) == 0)
-
-        try:
-            # Search with transitive match must return 1 results
-            res1 = self.ldb.search("cn=g4,%s" % self.ou_groups,
-                            scope=SCOPE_BASE,
-                            expression="member:1.2.840.113556.1.4.1941:=cn=u1,%s" % self.ou_users)
-            self.assertTrue(len(res1) == 1)
-        except LdbError, err:
-            self.fail(str(err))
+                               scope=SCOPE_BASE,
+                               expression="memberOf=cn=g4,%s" % self.ou_groups)
+        self.assertEqual(len(res1), 0)
+
+        # Search with transitive match must return 1 results
+        res1 = self.ldb.search("cn=g4,%s" % self.ou_groups,
+                               scope=SCOPE_BASE,
+                               expression="member:1.2.840.113556.1.4.1941:=cn=u1,%s" % self.ou_users)
+        self.assertEqual(len(res1), 1)
+        self.assertEqual(str(res1[0].dn).lower(), ("CN=g4,%s" % self.ou_groups).lower())
 
         res1 = self.ldb.search("cn=u1,%s" % self.ou_users,
-                        scope=SCOPE_BASE,
-                        expression="memberOf:1.2.840.113556.1.4.1941:=cn=g4,%s" % self.ou_groups)
-        self.assertTrue(len(res1) == 1)
+                               scope=SCOPE_BASE,
+                               expression="memberOf:1.2.840.113556.1.4.1941:=cn=g4,%s" % self.ou_groups)
+        self.assertEqual(len(res1), 1)
+        self.assertEqual(str(res1[0].dn).lower(), ("CN=u1,%s" % self.ou_users).lower())
 
     def test_g1_member_of_g4(self):
         # Search without transitive match must return 0 results
         res1 = self.ldb.search("cn=g4,%s" % self.ou_groups,
-                        scope=SCOPE_BASE,
-                        expression="member=cn=g1,%s" % self.ou_groups)
-        self.assertTrue(len(res1) == 0)
+                               scope=SCOPE_BASE,
+                               expression="member=cn=g1,%s" % self.ou_groups)
+        self.assertEqual(len(res1), 0)
 
         res1 = self.ldb.search("cn=g1,%s" % self.ou_groups,
-                        scope=SCOPE_BASE,
-                        expression="memberOf=cn=g4,%s" % self.ou_groups)
-        self.assertTrue(len(res1) == 0)
-
-        try:
-            # Search with transitive match must return 1 results
-            res1 = self.ldb.search("cn=g4,%s" % self.ou_groups,
-                            scope=SCOPE_BASE,
-                            expression="member:1.2.840.113556.1.4.1941:=cn=g1,%s" % self.ou_groups)
-            self.assertTrue(len(res1) == 1)
-        except LdbError, err:
-            self.fail(str(err))
+                               scope=SCOPE_BASE,
+                               expression="memberOf=cn=g4,%s" % self.ou_groups)
+        self.assertEqual(len(res1), 0)
+
+        # Search with transitive match must return 1 results
+        res1 = self.ldb.search("cn=g4,%s" % self.ou_groups,
+                               scope=SCOPE_BASE,
+                               expression="member:1.2.840.113556.1.4.1941:=cn=g1,%s" % self.ou_groups)
+        self.assertEqual(len(res1), 1)
+        self.assertEqual(str(res1[0].dn).lower(), ("CN=g4,%s" % self.ou_groups).lower())
 
         res1 = self.ldb.search("cn=g1,%s" % self.ou_groups,
-                        scope=SCOPE_BASE,
-                        expression="memberOf:1.2.840.113556.1.4.1941:=cn=g4,%s" % self.ou_groups)
-        self.assertTrue(len(res1) == 1)
+                               scope=SCOPE_BASE,
+                               expression="memberOf:1.2.840.113556.1.4.1941:=cn=g4,%s" % self.ou_groups)
+        self.assertEqual(len(res1), 1)
+        self.assertEqual(str(res1[0].dn).lower(), ("CN=g1,%s" % self.ou_groups).lower())
 
     def test_u1_groups(self):
         res1 = self.ldb.search(self.ou_groups,
-                        scope=SCOPE_SUBTREE,
-                        expression="member=cn=u1,%s" % self.ou_users)
-        self.assertTrue(len(res1) == 1)
+                               scope=SCOPE_SUBTREE,
+                               expression="member=cn=u1,%s" % self.ou_users)
+        self.assertEqual(len(res1), 1)
+        self.assertEqual(str(res1[0].dn).lower(), ("CN=g1,%s" % self.ou_groups).lower())
 
-        try:
-            res1 = self.ldb.search(self.ou_groups,
-                            scope=SCOPE_SUBTREE,
-                            expression="member:1.2.840.113556.1.4.1941:=cn=u1,%s" % self.ou_users)
-            self.assertTrue(len(res1) == 4)
-        except LdbError, err:
-            self.fail(str(err))
+        res1 = self.ldb.search(self.ou_users,
+                               scope=SCOPE_SUBTREE,
+                               expression="member=cn=u1,%s" % self.ou_users)
+        self.assertEqual(len(res1), 0)
+
+        res1 = self.ldb.search(self.ou_groups,
+                               scope=SCOPE_SUBTREE,
+                               expression="member:1.2.840.113556.1.4.1941:=cn=u1,%s" % self.ou_users)
+        self.assertEqual(len(res1), 4)
+        dn_list = [str(res.dn).lower() for res in res1]
+        self.assertTrue(("CN=g1,%s" % self.ou_groups).lower() in dn_list)
+        self.assertTrue(("CN=g2,%s" % self.ou_groups).lower() in dn_list)
+        self.assertTrue(("CN=g3,%s" % self.ou_groups).lower() in dn_list)
+        self.assertTrue(("CN=g4,%s" % self.ou_groups).lower() in dn_list)
+
+        res1 = self.ldb.search(self.ou_users,
+                               scope=SCOPE_SUBTREE,
+                               expression="member:1.2.840.113556.1.4.1941:=cn=u1,%s" % self.ou_users)
+        self.assertEqual(len(res1), 0)
 
     def test_u2_groups(self):
         res1 = self.ldb.search(self.ou_groups,
-                        scope=SCOPE_SUBTREE,
-                        expression="member=cn=u2,%s" % self.ou_users)
-        self.assertTrue(len(res1) == 1)
+                               scope=SCOPE_SUBTREE,
+                               expression="member=cn=u2,%s" % self.ou_users)
+        self.assertEqual(len(res1), 1)
+        self.assertEqual(str(res1[0].dn).lower(), ("CN=g2,%s" % self.ou_groups).lower())
 
-        try:
-            res1 = self.ldb.search(self.ou_groups,
-                            scope=SCOPE_SUBTREE,
-                            expression="member:1.2.840.113556.1.4.1941:=cn=u2,%s" % self.ou_users)
-            self.assertTrue(len(res1) == 3)
-        except LdbError, err:
-            self.fail(str(err))
+        res1 = self.ldb.search(self.ou_users,
+                               scope=SCOPE_SUBTREE,
+                               expression="member=cn=u2,%s" % self.ou_users)
+        self.assertEqual(len(res1), 0)
+
+        res1 = self.ldb.search(self.ou_groups,
+                               scope=SCOPE_SUBTREE,
+                               expression="member:1.2.840.113556.1.4.1941:=cn=u2,%s" % self.ou_users)
+        self.assertEqual(len(res1), 3)
+        dn_list = [str(res.dn).lower() for res in res1]
+        self.assertTrue(("CN=g2,%s" % self.ou_groups).lower() in dn_list)
+        self.assertTrue(("CN=g3,%s" % self.ou_groups).lower() in dn_list)
+        self.assertTrue(("CN=g4,%s" % self.ou_groups).lower() in dn_list)
+
+        res1 = self.ldb.search(self.ou_users,
+                               scope=SCOPE_SUBTREE,
+                               expression="member:1.2.840.113556.1.4.1941:=cn=u2,%s" % self.ou_users)
+        self.assertEqual(len(res1), 0)
 
     def test_u3_groups(self):
         res1 = self.ldb.search(self.ou_groups,
-                        scope=SCOPE_SUBTREE,
-                        expression="member=cn=u3,%s" % self.ou_users)
-        self.assertTrue(len(res1) == 1)
+                               scope=SCOPE_SUBTREE,
+                               expression="member=cn=u3,%s" % self.ou_users)
+        self.assertEqual(len(res1), 1)
+        self.assertEqual(str(res1[0].dn).lower(), ("CN=g3,%s" % self.ou_groups).lower())
+
+        res1 = self.ldb.search(self.ou_users,
+                               scope=SCOPE_SUBTREE,
+                               expression="member=cn=u3,%s" % self.ou_users)
+        self.assertEqual(len(res1), 0)
 
-        try:
-            res1 = self.ldb.search(self.ou_groups,
-                            scope=SCOPE_SUBTREE,
-                            expression="member:1.2.840.113556.1.4.1941:=cn=u3,%s" % self.ou_users)
-            self.assertTrue(len(res1) == 2)
-        except LdbError, err:
-            self.fail(str(err))
+        res1 = self.ldb.search(self.ou_groups,
+                               scope=SCOPE_SUBTREE,
+                               expression="member:1.2.840.113556.1.4.1941:=cn=u3,%s" % self.ou_users)
+        self.assertEqual(len(res1), 2)
+        dn_list = [str(res.dn).lower() for res in res1]
+        self.assertTrue(("CN=g3,%s" % self.ou_groups).lower() in dn_list)
+        self.assertTrue(("CN=g4,%s" % self.ou_groups).lower() in dn_list)
+
+        res1 = self.ldb.search(self.ou_users,
+                               scope=SCOPE_SUBTREE,
+                               expression="member:1.2.840.113556.1.4.1941:=cn=u3,%s" % self.ou_users)
+        self.assertEqual(len(res1), 0)
 
     def test_u4_groups(self):
         res1 = self.ldb.search(self.ou_groups,
-                        scope=SCOPE_SUBTREE,
-                        expression="member=cn=u4,%s" % self.ou_users)
-        self.assertTrue(len(res1) == 1)
+                               scope=SCOPE_SUBTREE,
+                               expression="member=cn=u4,%s" % self.ou_users)
+        self.assertEqual(len(res1), 1)
+        self.assertEqual(str(res1[0].dn).lower(), ("CN=g4,%s" % self.ou_groups).lower())
+
+        res1 = self.ldb.search(self.ou_users,
+                               scope=SCOPE_SUBTREE,
+                               expression="member=cn=u4,%s" % self.ou_users)
+        self.assertEqual(len(res1), 0)
+
+        res1 = self.ldb.search(self.ou_groups,
+                               scope=SCOPE_SUBTREE,
+                               expression="member:1.2.840.113556.1.4.1941:=cn=u4,%s" % self.ou_users)
+        self.assertEqual(len(res1), 1)
+        self.assertEqual(str(res1[0].dn).lower(), ("CN=g4,%s" % self.ou_groups).lower())
 
-        try:
-            res1 = self.ldb.search(self.ou_groups,
-                            scope=SCOPE_SUBTREE,
-                            expression="member:1.2.840.113556.1.4.1941:=cn=u4,%s" % self.ou_users)
-            self.assertTrue(len(res1) == 1)
-        except LdbError, err:
-            self.fail(str(err))
+        res1 = self.ldb.search(self.ou_users,
+                               scope=SCOPE_SUBTREE,
+                               expression="member:1.2.840.113556.1.4.1941:=cn=u4,%s" % self.ou_users)
+        self.assertEqual(len(res1), 0)
 
-    def test_extended_dn(self):
+    def test_extended_dn_u1(self):
         res1 = self.ldb.search("cn=u1,%s" % self.ou_users,
-                        scope=SCOPE_BASE,
-                        expression="objectClass=*",
-                        attrs=['objectSid', 'objectGUID'])
-        self.assertTrue(len(res1) == 1)
+                               scope=SCOPE_BASE,
+                               expression="objectClass=*",
+                               attrs=['objectSid', 'objectGUID'])
+        self.assertEqual(len(res1), 1)
+        self.assertEqual(str(res1[0].dn).lower(), ("cn=u1,%s" % self.ou_users).lower())
+
+        sid = self.ldb.schema_format_value("objectSid", res1[0]["objectSid"][0])
+        guid = self.ldb.schema_format_value("objectGUID", res1[0]['objectGUID'][0])
+
+        res1 = self.ldb.search(self.ou_groups,
+                               scope=SCOPE_SUBTREE,
+                               expression="member=<SID=%s>" % sid)
+        self.assertEqual(len(res1), 1)
+        self.assertEqual(str(res1[0].dn).lower(), ("CN=g1,%s" % self.ou_groups).lower())
+
+        res1 = self.ldb.search(self.ou_groups,
+                               scope=SCOPE_SUBTREE,
+                               expression="member=<GUID=%s>" % guid)
+        self.assertEqual(len(res1), 1)
+        self.assertEqual(str(res1[0].dn).lower(), ("CN=g1,%s" % self.ou_groups).lower())
+
+        res1 = self.ldb.search(self.ou_groups,
+                               scope=SCOPE_SUBTREE,
+                               expression="member:1.2.840.113556.1.4.1941:=<SID=%s>" % sid)
+        self.assertEqual(len(res1), 4)
+        dn_list = [str(res.dn).lower() for res in res1]
+        self.assertTrue(("CN=g1,%s" % self.ou_groups).lower() in dn_list)
+        self.assertTrue(("CN=g2,%s" % self.ou_groups).lower() in dn_list)
+        self.assertTrue(("CN=g3,%s" % self.ou_groups).lower() in dn_list)
+        self.assertTrue(("CN=g4,%s" % self.ou_groups).lower() in dn_list)
+
+        res1 = self.ldb.search(self.ou_groups,
+                               scope=SCOPE_ONELEVEL,
+                               expression="member:1.2.840.113556.1.4.1941:=<SID=%s>" % sid)
+        self.assertEqual(len(res1), 4)
+        dn_list = [str(res.dn).lower() for res in res1]
+        self.assertTrue(("CN=g1,%s" % self.ou_groups).lower() in dn_list)
+        self.assertTrue(("CN=g2,%s" % self.ou_groups).lower() in dn_list)
+        self.assertTrue(("CN=g3,%s" % self.ou_groups).lower() in dn_list)
+        self.assertTrue(("CN=g4,%s" % self.ou_groups).lower() in dn_list)
+
+        res1 = self.ldb.search(self.ou_groups,
+                               scope=SCOPE_SUBTREE,
+                               expression="member:1.2.840.113556.1.4.1941:=<GUID=%s>" % guid)
+        self.assertEqual(len(res1), 4)
+        dn_list = [str(res.dn).lower() for res in res1]
+        self.assertTrue(("CN=g1,%s" % self.ou_groups).lower() in dn_list)
+        self.assertTrue(("CN=g2,%s" % self.ou_groups).lower() in dn_list)
+        self.assertTrue(("CN=g3,%s" % self.ou_groups).lower() in dn_list)
+        self.assertTrue(("CN=g4,%s" % self.ou_groups).lower() in dn_list)
+
+        res1 = self.ldb.search(self.ou_groups,
+                               scope=SCOPE_ONELEVEL,
+                               expression="member:1.2.840.113556.1.4.1941:=<GUID=%s>" % guid)
+        self.assertEqual(len(res1), 4)
+        dn_list = [str(res.dn).lower() for res in res1]
+        self.assertTrue(("CN=g1,%s" % self.ou_groups).lower() in dn_list)
+        self.assertTrue(("CN=g2,%s" % self.ou_groups).lower() in dn_list)
+        self.assertTrue(("CN=g3,%s" % self.ou_groups).lower() in dn_list)
+        self.assertTrue(("CN=g4,%s" % self.ou_groups).lower() in dn_list)
+
+    def test_extended_dn_u2(self):
+        res1 = self.ldb.search("cn=u2,%s" % self.ou_users,
+                               scope=SCOPE_BASE,
+                               expression="objectClass=*",
+                               attrs=['objectSid', 'objectGUID'])
+        self.assertEqual(len(res1), 1)
+        self.assertEqual(str(res1[0].dn).lower(), ("cn=u2,%s" % self.ou_users).lower())
+
+        sid = self.ldb.schema_format_value("objectSid", res1[0]["objectSid"][0])
+        guid = self.ldb.schema_format_value("objectGUID", res1[0]['objectGUID'][0])
+
+        res1 = self.ldb.search(self.ou_groups,
+                               scope=SCOPE_SUBTREE,
+                               expression="member=<SID=%s>" % sid)
+        self.assertEqual(len(res1), 1)
+        self.assertEqual(str(res1[0].dn).lower(), ("CN=g2,%s" % self.ou_groups).lower())
+
+        res1 = self.ldb.search(self.ou_groups,
+                               scope=SCOPE_SUBTREE,
+                               expression="member=<GUID=%s>" % guid)
+        self.assertEqual(len(res1), 1)
+        self.assertEqual(str(res1[0].dn).lower(), ("CN=g2,%s" % self.ou_groups).lower())
+
+        res1 = self.ldb.search(self.ou_groups,
+                               scope=SCOPE_SUBTREE,
+                               expression="member:1.2.840.113556.1.4.1941:=<SID=%s>" % sid)
+        self.assertEqual(len(res1), 3)
+        dn_list = [str(res.dn).lower() for res in res1]
+        self.assertTrue(("CN=g2,%s" % self.ou_groups).lower() in dn_list)
+        self.assertTrue(("CN=g3,%s" % self.ou_groups).lower() in dn_list)
+        self.assertTrue(("CN=g4,%s" % self.ou_groups).lower() in dn_list)
+
+        res1 = self.ldb.search(self.ou_groups,
+                               scope=SCOPE_ONELEVEL,
+                               expression="member:1.2.840.113556.1.4.1941:=<SID=%s>" % sid)
+        self.assertEqual(len(res1), 3)
+        dn_list = [str(res.dn).lower() for res in res1]
+        self.assertTrue(("CN=g2,%s" % self.ou_groups).lower() in dn_list)
+        self.assertTrue(("CN=g3,%s" % self.ou_groups).lower() in dn_list)
+        self.assertTrue(("CN=g4,%s" % self.ou_groups).lower() in dn_list)
+
+        res1 = self.ldb.search(self.ou_groups,
+                               scope=SCOPE_SUBTREE,
+                               expression="member:1.2.840.113556.1.4.1941:=<GUID=%s>" % guid)
+        self.assertEqual(len(res1), 3)
+        dn_list = [str(res.dn).lower() for res in res1]
+        self.assertTrue(("CN=g2,%s" % self.ou_groups).lower() in dn_list)
+        self.assertTrue(("CN=g3,%s" % self.ou_groups).lower() in dn_list)
+        self.assertTrue(("CN=g4,%s" % self.ou_groups).lower() in dn_list)
+
+        res1 = self.ldb.search(self.ou_groups,
+                               scope=SCOPE_ONELEVEL,
+                               expression="member:1.2.840.113556.1.4.1941:=<GUID=%s>" % guid)
+        self.assertEqual(len(res1), 3)
+        dn_list = [str(res.dn).lower() for res in res1]
+        self.assertTrue(("CN=g2,%s" % self.ou_groups).lower() in dn_list)
+        self.assertTrue(("CN=g3,%s" % self.ou_groups).lower() in dn_list)
+        self.assertTrue(("CN=g4,%s" % self.ou_groups).lower() in dn_list)
+
+    def test_extended_dn_u3(self):
+        res1 = self.ldb.search("cn=u3,%s" % self.ou_users,
+                               scope=SCOPE_BASE,
+                               expression="objectClass=*",
+                               attrs=['objectSid', 'objectGUID'])
+        self.assertEqual(len(res1), 1)
+        self.assertEqual(str(res1[0].dn).lower(), ("cn=u3,%s" % self.ou_users).lower())
+
+        sid = self.ldb.schema_format_value("objectSid", res1[0]["objectSid"][0])
+        guid = self.ldb.schema_format_value("objectGUID", res1[0]['objectGUID'][0])
+
+        res1 = self.ldb.search(self.ou_groups,
+                               scope=SCOPE_SUBTREE,
+                               expression="member=<SID=%s>" % sid)
+        self.assertEqual(len(res1), 1)
+        self.assertEqual(str(res1[0].dn).lower(), ("CN=g3,%s" % self.ou_groups).lower())
+
+        res1 = self.ldb.search(self.ou_groups,
+                               scope=SCOPE_SUBTREE,
+                               expression="member=<GUID=%s>" % guid)
+        self.assertEqual(len(res1), 1)
+        self.assertEqual(str(res1[0].dn).lower(), ("CN=g3,%s" % self.ou_groups).lower())
+
+        res1 = self.ldb.search(self.ou_groups,
+                               scope=SCOPE_SUBTREE,
+                               expression="member:1.2.840.113556.1.4.1941:=<SID=%s>" % sid)
+        self.assertEqual(len(res1), 2)
+        dn_list = [str(res.dn).lower() for res in res1]
+        self.assertTrue(("CN=g3,%s" % self.ou_groups).lower() in dn_list)
+        self.assertTrue(("CN=g4,%s" % self.ou_groups).lower() in dn_list)
+
+        res1 = self.ldb.search(self.ou_groups,
+                               scope=SCOPE_ONELEVEL,
+                               expression="member:1.2.840.113556.1.4.1941:=<SID=%s>" % sid)
+        self.assertEqual(len(res1), 2)
+        dn_list = [str(res.dn).lower() for res in res1]
+        self.assertTrue(("CN=g3,%s" % self.ou_groups).lower() in dn_list)
+        self.assertTrue(("CN=g4,%s" % self.ou_groups).lower() in dn_list)
+
+        res1 = self.ldb.search(self.ou_groups,
+                               scope=SCOPE_SUBTREE,
+                               expression="member:1.2.840.113556.1.4.1941:=<GUID=%s>" % guid)
+        self.assertEqual(len(res1), 2)
+        dn_list = [str(res.dn).lower() for res in res1]
+        self.assertTrue(("CN=g3,%s" % self.ou_groups).lower() in dn_list)
+        self.assertTrue(("CN=g4,%s" % self.ou_groups).lower() in dn_list)
+
+        res1 = self.ldb.search(self.ou_groups,
+                               scope=SCOPE_ONELEVEL,
+                               expression="member:1.2.840.113556.1.4.1941:=<GUID=%s>" % guid)
+        self.assertEqual(len(res1), 2)
+        dn_list = [str(res.dn).lower() for res in res1]
+        self.assertTrue(("CN=g3,%s" % self.ou_groups).lower() in dn_list)
+        self.assertTrue(("CN=g4,%s" % self.ou_groups).lower() in dn_list)
+
+    def test_extended_dn_u4(self):
+        res1 = self.ldb.search("cn=u4,%s" % self.ou_users,
+                               scope=SCOPE_BASE,
+                               expression="objectClass=*",
+                               attrs=['objectSid', 'objectGUID'])
+        self.assertEqual(len(res1), 1)
+        self.assertEqual(str(res1[0].dn).lower(), ("cn=u4,%s" % self.ou_users).lower())
 
         sid = self.ldb.schema_format_value("objectSid", res1[0]["objectSid"][0])
         guid = self.ldb.schema_format_value("objectGUID", res1[0]['objectGUID'][0])
 
         res1 = self.ldb.search(self.ou_groups,
-                        scope=SCOPE_SUBTREE,
-                        expression="member=<SID=%s>" % sid)
-        self.assertTrue(len(res1) == 1)
+                               scope=SCOPE_SUBTREE,
+                               expression="member=<SID=%s>" % sid)
+        self.assertEqual(len(res1), 1)
+        self.assertEqual(str(res1[0].dn).lower(), ("CN=g4,%s" % self.ou_groups).lower())
 
         res1 = self.ldb.search(self.ou_groups,
-                        scope=SCOPE_SUBTREE,
-                        expression="member=<GUID=%s>" % guid)
-        self.assertTrue(len(res1) == 1)
+                               scope=SCOPE_SUBTREE,
+                               expression="member=<GUID=%s>" % guid)
+        self.assertEqual(len(res1), 1)
+        self.assertEqual(str(res1[0].dn).lower(), ("CN=g4,%s" % self.ou_groups).lower())
 
-        try:
-            res1 = self.ldb.search(self.ou_groups,
-                            scope=SCOPE_SUBTREE,
-                            expression="member:1.2.840.113556.1.4.1941:=<SID=%s>" % sid)
-            self.assertTrue(len(res1) == 4)
-        except LdbError, err:
-            self.fail(str(err))
+        res1 = self.ldb.search(self.ou_groups,
+                               scope=SCOPE_ONELEVEL,
+                               expression="member=<GUID=%s>" % guid)
+        self.assertEqual(len(res1), 1)
+        self.assertEqual(str(res1[0].dn).lower(), ("CN=g4,%s" % self.ou_groups).lower())
+
+        res1 = self.ldb.search(self.ou_groups,
+                               scope=SCOPE_SUBTREE,
+                               expression="member:1.2.840.113556.1.4.1941:=<SID=%s>" % sid)
+        self.assertEqual(len(res1), 1)
+        self.assertEqual(str(res1[0].dn).lower(), ("CN=g4,%s" % self.ou_groups).lower())
 
         res1 = self.ldb.search(self.ou_groups,
-                        scope=SCOPE_SUBTREE,
-                        expression="member:1.2.840.113556.1.4.1941:=<GUID=%s>" % guid)
-        self.assertTrue(len(res1) == 4)
+                               scope=SCOPE_ONELEVEL,
+                               expression="member:1.2.840.113556.1.4.1941:=<SID=%s>" % sid)
+        self.assertEqual(len(res1), 1)
+        self.assertEqual(str(res1[0].dn).lower(), ("CN=g4,%s" % self.ou_groups).lower())
+
+        res1 = self.ldb.search(self.ou_groups,
+                               scope=SCOPE_SUBTREE,
+                               expression="member:1.2.840.113556.1.4.1941:=<GUID=%s>" % guid)
+        self.assertEqual(len(res1), 1)
+        self.assertEqual(str(res1[0].dn).lower(), ("CN=g4,%s" % self.ou_groups).lower())
+
+        res1 = self.ldb.search(self.ou_groups,
+                               scope=SCOPE_ONELEVEL,
+                               expression="member:1.2.840.113556.1.4.1941:=<GUID=%s>" % guid)
+        self.assertEqual(len(res1), 1)
+        self.assertEqual(str(res1[0].dn).lower(), ("CN=g4,%s" % self.ou_groups).lower())
 
     def test_object_dn_binary(self):
         res1 = self.ldb.search(self.ou_computers,
-                        scope=SCOPE_SUBTREE,
-                        expression="msDS-RevealedUsers=B:8:01010101:cn=c3,%s" % self.ou_computers)
-        self.assertTrue(len(res1) == 1)
-
-        try:
-            res1 = self.ldb.search(self.ou_computers,
-                            scope=SCOPE_SUBTREE,
-                            expression="msDS-RevealedUsers:1.2.840.113556.1.4.1941:=B:8:01010101:cn=c3,%s" % self.ou_computers)
-            self.assertTrue(len(res1) == 2)
-        except LdbError, err:
-            self.fail(str(err))
+                               scope=SCOPE_SUBTREE,
+                               expression="msDS-RevealedUsers=B:8:01010101:cn=c3,%s" % self.ou_computers)
+        self.assertEqual(len(res1), 1)
+        self.assertEqual(str(res1[0].dn).lower(), ("CN=c2,%s" % self.ou_computers).lower())
+
+        res1 = self.ldb.search(self.ou_computers,
+                               scope=SCOPE_ONELEVEL,
+                               expression="msDS-RevealedUsers=B:8:01010101:cn=c3,%s" % self.ou_computers)
+        self.assertEqual(len(res1), 1)
+        self.assertEqual(str(res1[0].dn).lower(), ("CN=c2,%s" % self.ou_computers).lower())
+
+        res1 = self.ldb.search(self.ou_computers,
+                               scope=SCOPE_SUBTREE,
+                               expression="msDS-RevealedUsers:1.2.840.113556.1.4.1941:=B:8:01010101:cn=c3,%s" % self.ou_computers)
+        self.assertEqual(len(res1), 2)
+        dn_list = [str(res.dn).lower() for res in res1]
+        self.assertTrue(("CN=c1,%s" % self.ou_computers).lower() in dn_list)
+        self.assertTrue(("CN=c2,%s" % self.ou_computers).lower() in dn_list)
+
+        res1 = self.ldb.search(self.ou_computers,
+                               scope=SCOPE_ONELEVEL,
+                               expression="msDS-RevealedUsers:1.2.840.113556.1.4.1941:=B:8:01010101:cn=c3,%s" % self.ou_computers)
+        self.assertEqual(len(res1), 2)
+        dn_list = [str(res.dn).lower() for res in res1]
+        self.assertTrue(("CN=c1,%s" % self.ou_computers).lower() in dn_list)
+        self.assertTrue(("CN=c2,%s" % self.ou_computers).lower() in dn_list)
 
     def test_one_way_links(self):
         res1 = self.ldb.search(self.ou,
-                        scope=SCOPE_SUBTREE,
-                        expression="addressBookRoots2=cn=c1,%s" % self.ou_computers)
-        self.assertTrue(len(res1) == 1)
+                               scope=SCOPE_SUBTREE,
+                               expression="addressBookRoots2=cn=c1,%s" % self.ou_computers)
+        self.assertEqual(len(res1), 1)
+        self.assertEqual(str(res1[0].dn).lower(), ("CN=e2,%s" % self.ou).lower())
 
-        try:
-            res1 = self.ldb.search(self.ou,
-                            scope=SCOPE_SUBTREE,
-                            expression="addressBookRoots2:1.2.840.113556.1.4.1941:=cn=c1,%s" % self.ou_computers)
-            self.assertTrue(len(res1) == 2)
-        except LdbError, err:
-            self.fail(str(err))
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_ONELEVEL,
+                               expression="addressBookRoots2=cn=c1,%s" % self.ou_computers)
+        self.assertEqual(len(res1), 1)
+        self.assertEqual(str(res1[0].dn).lower(), ("CN=e2,%s" % self.ou).lower())
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="addressBookRoots2:1.2.840.113556.1.4.1941:=cn=c1,%s" % self.ou_computers)
+        self.assertEqual(len(res1), 2)
+        dn_list = [str(res.dn).lower() for res in res1]
+        self.assertTrue(("CN=e1,%s" % self.ou).lower() in dn_list)
+        self.assertTrue(("CN=e2,%s" % self.ou).lower() in dn_list)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_ONELEVEL,
+                               expression="addressBookRoots2:1.2.840.113556.1.4.1941:=cn=c1,%s" % self.ou_computers)
+        self.assertEqual(len(res1), 2)
+        dn_list = [str(res.dn).lower() for res in res1]
+        self.assertTrue(("CN=e1,%s" % self.ou).lower() in dn_list)
+        self.assertTrue(("CN=e2,%s" % self.ou).lower() in dn_list)
 
     def test_not_linked_attrs(self):
         res1 = self.ldb.search(self.base_dn,
-                        scope=SCOPE_BASE,
-                        expression="wellKnownObjects=B:32:aa312825768811d1aded00c04fd8d5cd:CN=computers,%s" % self.base_dn)
-        self.assertTrue(len(res1) == 1)
-
-        try:
-            res1 = self.ldb.search(self.base_dn,
-                            scope=SCOPE_BASE,
-                            expression="wellKnownObjects:1.2.840.113556.1.4.1941:=B:32:aa312825768811d1aded00c04fd8d5cd:CN=computers,%s" % self.base_dn)
-            self.assertTrue(len(res1) == 0)
-        except LdbError, err:
-            self.fail(str(err))
-
-
-       res1 = self.ldb.search(self.ou,
-                       scope=SCOPE_SUBTREE,
-                       expression="otherWellKnownObjects=B:32:00000000000000000000000000000004:OU=o4,OU=o3,OU=o2,OU=o1,%s" % self.ou)
-       self.assertTrue(len(res1) == 1)
-
-       res1 = self.ldb.search(self.ou,
-                       scope=SCOPE_SUBTREE,
-                       expression="otherWellKnownObjects:1.2.840.113556.1.4.1941:=B:32:00000000000000000000000000000004:OU=o4,OU=o3,OU=o2,OU=o1,%s" % self.ou)
-       self.assertTrue(len(res1) == 0)
+                               scope=SCOPE_BASE,
+                               expression="wellKnownObjects=B:32:aa312825768811d1aded00c04fd8d5cd:CN=computers,%s" % self.base_dn)
+        self.assertEqual(len(res1), 1)
+        self.assertEqual(str(res1[0].dn).lower(), self.base_dn.lower())
+
+    def test_invalid_basedn(self):
+        res1 = self.ldb.search(self.base_dn,
+                               scope=SCOPE_SUBTREE,
+                               expression="memberOf:1.2.840.113556.1.4.1941:=cn=c1,ou=computers,ou=matchrulestest,%sXX" % self.base_dn)
+        self.assertEqual(len(res1), 0)
+
+        res1 = self.ldb.search(self.base_dn,
+                               scope=SCOPE_SUBTREE,
+                               expression="memberOf:1.2.840.113556.1.4.1941:=cn=XX,ou=computers,ou=matchrulestest,%s" % self.base_dn)
+        self.assertEqual(len(res1), 0)
+
+    def test_subtree(self):
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="otherWellKnownObjects=B:32:00000000000000000000000000000004:OU=o4,OU=o3,OU=o2,OU=o1,%s" % self.ou)
+        self.assertEqual(len(res1), 1)
+        self.assertEqual(str(res1[0].dn).lower(), ("OU=o3,OU=o2,OU=o1,%s" % self.ou).lower())
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_ONELEVEL,
+                               expression="otherWellKnownObjects=B:32:00000000000000000000000000000004:OU=o4,OU=o3,OU=o2,OU=o1,%s" % self.ou)
+        self.assertEqual(len(res1), 0)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="otherWellKnownObjects:1.2.840.113556.1.4.1941:=B:32:00000000000000000000000000000004:OU=o4,OU=o3,OU=o2,OU=o1,%s" % self.ou)
+        self.assertEqual(len(res1), 0)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_ONELEVEL,
+                               expression="otherWellKnownObjects:1.2.840.113556.1.4.1941:=B:32:00000000000000000000000000000004:OU=o4,OU=o3,OU=o2,OU=o1,%s" % self.ou)
+        self.assertEqual(len(res1), 0)
+
+    def test_unknown_oid(self):
+        res1 = self.ldb.search("cn=g4,%s" % self.ou_groups,
+                               scope=SCOPE_BASE,
+                               expression="member:2.4.681.226012.2.8.3882:=cn=u1,%s" % self.ou_users)
+        self.assertEqual(len(res1), 0)
+
+        res1 = self.ldb.search("cn=g4,%s" % self.ou_groups,
+                               scope=SCOPE_BASE,
+                               expression="member:8.16.8720.1008448.8.32.15528:=cn=u1,%s" % self.ou_users)
+        self.assertEqual(len(res1), 0)
+
+        res1 = self.ldb.search("cn=g4,%s" % self.ou_groups,
+                               scope=SCOPE_BASE,
+                               expression="member:1.2.3.4:=cn=u1,%s" % self.ou_users)
+        self.assertEqual(len(res1), 0)
+
+    def test_nul_text(self):
+        self.assertRaises(TypeError,
+                          lambda: self.ldb.search("cn=g4,%s" % self.ou_groups,
+                                                  scope=SCOPE_BASE,
+                                                  expression="\00member:1.2.840.113556.1.4.1941:=cn=u1,%s" % self.ou_users))
+        self.assertRaises(TypeError,
+                          lambda: self.ldb.search("cn=g4,%s" % self.ou_groups,
+                                                  scope=SCOPE_BASE,
+                                                  expression="member:1.2.840\00.113556.1.4.1941:=cn=u1,%s" % self.ou_users))
+        self.assertRaises(TypeError,
+                          lambda: self.ldb.search("cn=g4,%s" % self.ou_groups,
+                                                  scope=SCOPE_BASE,
+                                                  expression="member:1.2.840.113556.1.4.1941:=cn=u1\00,%s" % self.ou_users))
+        self.assertRaises(LdbError,
+                          lambda: self.ldb.search("cn=\00g4,%s" % self.ou_groups,
+                                                  scope=SCOPE_BASE,
+                                                  expression="member:1.2.840.113556.1.4.1941:=cn=u1,%s" % self.ou_users))
+        self.assertRaises(LdbError,
+                          lambda: self.ldb.search("cn=g4,%s" % self.ou_groups,
+                                                  scope=SCOPE_BASE,
+                                                  expression="member:1.2.840.113556.1.4.1941:"))
+        res1 = self.ldb.search("cn=g4,%s" % self.ou_groups,
+                               scope=SCOPE_BASE,
+                               expression="member:1.2.840.113556.1.4.1941:=")
+        self.assertEqual(len(res1), 0)
+        res1 = self.ldb.search("cn=g4,%s" % self.ou_groups,
+                               scope=SCOPE_BASE,
+                               expression="member=")
+        self.assertEqual(len(res1), 0)
+        res1 = self.ldb.search("cn=g4,%s" % self.ou_groups,
+                               scope=SCOPE_BASE,
+                               expression="member:1.2.840.113556.1.4.1941:=nonexistent")
+        self.assertEqual(len(res1), 0)
+        res1 = self.ldb.search("cn=g4,%s" % self.ou_groups,
+                               scope=SCOPE_BASE,
+                               expression="member=nonexistent")
+        self.assertEqual(len(res1), 0)
+        self.assertRaises(LdbError,
+                          lambda: self.ldb.search("cn=\00g4,%s" % self.ou_groups,
+                                                  scope=SCOPE_BASE,
+                                                  expression="member:1.2.840.113556.1.4.1941:cn=u1,%s" % self.ou_users))
+        self.assertRaises(LdbError,
+                          lambda: self.ldb.search("cn=\00g4,%s" % self.ou_groups,
+                                                  scope=SCOPE_BASE,
+                                                  expression="member:1.2.840.113556.1.4.1941:=cn=u1"))
+        self.assertRaises(LdbError,
+                          lambda: self.ldb.search("cn=\00g4,%s" % self.ou_groups,
+                                                  scope=SCOPE_BASE,
+                                                  expression="member:1.2.840.113556.1.4.1941:=cn="))
+        self.assertRaises(LdbError,
+                          lambda: self.ldb.search("cn=\00g4,%s" % self.ou_groups,
+                                                  scope=SCOPE_BASE,
+                                                  expression="member::=cn=u1,%s" % self.ou_users))
+
+    def test_misc_matches(self):
+        res1 = self.ldb.search(self.ou_groups,
+                               scope=SCOPE_BASE,
+                               expression="member=cn=g1,%s" % self.ou_groups)
+        self.assertEqual(len(res1), 0)
+
+        res1 = self.ldb.search("cn=g1,%s" % self.ou_groups,
+                               scope=SCOPE_BASE,
+                               expression="member=cn=g1,%s" % self.ou_groups)
+        self.assertEqual(len(res1), 0)
+
+        res1 = self.ldb.search(self.ou_groups,
+                               scope=SCOPE_SUBTREE,
+                               expression="member=cn=g1,%s" % self.ou_groups)
+        self.assertEqual(len(res1), 1)
+        self.assertEqual(str(res1[0].dn), "CN=g2,%s" % self.ou_groups)
+
+        res1 = self.ldb.search(self.ou_groups,
+                               scope=SCOPE_ONELEVEL,
+                               expression="member=cn=g1,%s" % self.ou_groups)
+        self.assertEqual(len(res1), 1)
+        self.assertEqual(str(res1[0].dn), "CN=g2,%s" % self.ou_groups)
+
+        res1 = self.ldb.search(self.ou_groups,
+                               scope=SCOPE_BASE,
+                               expression="member:1.2.840.113556.1.4.1941:=cn=g1,%s" % self.ou_groups)
+        self.assertEqual(len(res1), 0)
+
+        res1 = self.ldb.search("cn=g1,%s" % self.ou_groups,
+                               scope=SCOPE_BASE,
+                               expression="member:1.2.840.113556.1.4.1941:=cn=g1,%s" % self.ou_groups)
+        self.assertEqual(len(res1), 0)
+
+        res1 = self.ldb.search(self.ou_groups,
+                               scope=SCOPE_SUBTREE,
+                               expression="member:1.2.840.113556.1.4.1941:=cn=g1,%s" % self.ou_groups)
+        self.assertEqual(len(res1), 3)
+        dn_list = [str(res.dn) for res in res1]
+        self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
+        self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
+        self.assertTrue("CN=g4,%s" % self.ou_groups in dn_list)
+
+        res1 = self.ldb.search(self.ou_groups,
+                               scope=SCOPE_ONELEVEL,
+                               expression="member:1.2.840.113556.1.4.1941:=cn=g1,%s" % self.ou_groups)
+        self.assertEqual(len(res1), 3)
+        dn_list = [str(res.dn) for res in res1]
+        self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
+        self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
+        self.assertTrue("CN=g4,%s" % self.ou_groups in dn_list)
+
+        res1 = self.ldb.search(self.ou_groups,
+                               scope=SCOPE_SUBTREE,
+                               expression="member:1.2.840.113556.1.4.1941:=cn=g4,%s" % self.ou_groups)
+        self.assertEqual(len(res1), 0)
+
+        res1 = self.ldb.search(self.ou_groups,
+                               scope=SCOPE_ONELEVEL,
+                               expression="member:1.2.840.113556.1.4.1941:=cn=g4,%s" % self.ou_groups)
+        self.assertEqual(len(res1), 0)
+
+        res1 = self.ldb.search(self.ou_groups,
+                               scope=SCOPE_BASE,
+                               expression="memberOf=cn=g4,%s" % self.ou_groups)
+        self.assertEqual(len(res1), 0)
+
+        res1 = self.ldb.search("cn=g4,%s" % self.ou_groups,
+                               scope=SCOPE_BASE,
+                               expression="memberOf=cn=g4,%s" % self.ou_groups)
+        self.assertEqual(len(res1), 0)
+
+        res1 = self.ldb.search(self.ou_groups,
+                               scope=SCOPE_SUBTREE,
+                               expression="memberOf=cn=g4,%s" % self.ou_groups)
+        self.assertEqual(len(res1), 1)
+        self.assertEqual(str(res1[0].dn), ("CN=g3,%s" % self.ou_groups))
+
+        res1 = self.ldb.search(self.ou_groups,
+                               scope=SCOPE_ONELEVEL,
+                               expression="memberOf=cn=g4,%s" % self.ou_groups)
+        self.assertEqual(len(res1), 1)
+        self.assertEqual(str(res1[0].dn), ("CN=g3,%s" % self.ou_groups))
+
+        res1 = self.ldb.search(self.ou_groups,
+                               scope=SCOPE_BASE,
+                               expression="memberOf:1.2.840.113556.1.4.1941:=cn=g4,%s" % self.ou_groups)
+        self.assertEqual(len(res1), 0)
+
+        res1 = self.ldb.search("cn=g4,%s" % self.ou_groups,
+                               scope=SCOPE_BASE,
+                               expression="memberOf:1.2.840.113556.1.4.1941:=cn=g4,%s" % self.ou_groups)
+        self.assertEqual(len(res1), 0)
+
+        res1 = self.ldb.search(self.ou_groups,
+                               scope=SCOPE_SUBTREE,
+                               expression="memberOf:1.2.840.113556.1.4.1941:=cn=g4,%s" % self.ou_groups)
+        self.assertEqual(len(res1), 3)
+        dn_list = [str(res.dn) for res in res1]
+        self.assertTrue("CN=g1,%s" % self.ou_groups in dn_list)
+        self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
+        self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
+
+        res1 = self.ldb.search(self.ou_groups,
+                               scope=SCOPE_ONELEVEL,
+                               expression="memberOf:1.2.840.113556.1.4.1941:=cn=g4,%s" % self.ou_groups)
+        self.assertEqual(len(res1), 3)
+        dn_list = [str(res.dn) for res in res1]
+        self.assertTrue("CN=g1,%s" % self.ou_groups in dn_list)
+        self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
+        self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
+
+        res1 = self.ldb.search(self.ou_groups,
+                               scope=SCOPE_SUBTREE,
+                               expression="memberOf:1.2.840.113556.1.4.1941:=cn=g1,%s" % self.ou_groups)
+        self.assertEqual(len(res1), 0)
+
+        res1 = self.ldb.search(self.ou_groups,
+                               scope=SCOPE_SUBTREE,
+                               expression="memberOf:1.2.840.113556.1.4.1941:=cn=g1,%s" % self.ou_groups)
+        self.assertEqual(len(res1), 0)
+
+
+class MatchRuleConditionTests(samba.tests.TestCase):
+    def setUp(self):
+        super(MatchRuleConditionTests, self).setUp()
+        self.lp = lp
+        self.ldb = SamDB(host, credentials=creds, session_info=system_session(lp), lp=lp)
+        self.base_dn = self.ldb.domain_dn()
+        self.ou = "OU=matchruleconditiontests,%s" % self.base_dn
+        self.ou_users = "OU=users,%s" % self.ou
+        self.ou_groups = "OU=groups,%s" % self.ou
+        self.ou_computers = "OU=computers,%s" % self.ou
+
+        # Add a organizational unit to create objects
+        self.ldb.add({
+            "dn": self.ou,
+            "objectclass": "organizationalUnit"})
+
+        # Create users, groups, and computers
+        self.ldb.add({
+            "dn": self.ou_users,
+            "objectclass": "organizationalUnit"})
+        self.ldb.add({
+            "dn": self.ou_groups,
+            "objectclass": "organizationalUnit"})
+        self.ldb.add({
+            "dn": self.ou_computers,
+            "objectclass": "organizationalUnit"})
+
+        self.ldb.add({
+            "dn": "cn=g1,%s" % self.ou_groups,
+            "objectclass": "group"})
+        self.ldb.add({
+            "dn": "cn=g2,%s" % self.ou_groups,
+            "objectclass": "group"})
+        self.ldb.add({
+            "dn": "cn=g3,%s" % self.ou_groups,
+            "objectclass": "group"})
+        self.ldb.add({
+            "dn": "cn=g4,%s" % self.ou_groups,
+            "objectclass": "group"})
+
+        self.ldb.add({
+            "dn": "cn=u1,%s" % self.ou_users,
+            "objectclass": "group"})
+        self.ldb.add({
+            "dn": "cn=u2,%s" % self.ou_users,
+            "objectclass": "group"})
+        self.ldb.add({
+            "dn": "cn=u3,%s" % self.ou_users,
+            "objectclass": "group"})
+        self.ldb.add({
+            "dn": "cn=u4,%s" % self.ou_users,
+            "objectclass": "group"})
+
+        self.ldb.add({
+            "dn": "cn=c1,%s" % self.ou_computers,
+            "objectclass": "user"})
+
+        self.ldb.add({
+            "dn": "cn=c2,%s" % self.ou_computers,
+            "objectclass": "user"})
+
+        self.ldb.add({
+            "dn": "cn=c3,%s" % self.ou_computers,
+            "objectclass": "user"})
+
+        self.ldb.add({
+            "dn": "cn=c4,%s" % self.ou_computers,
+            "objectclass": "user"})
+
+        # Assign groups according to the following structure:
+        #  g1-->g2---->g3   --g4
+        #     \  |    / |  / / |
+        #  u1- >u2-- | u3<- | u4
+        #     \     \ \      \ |
+        #  c1* >c2   ->c3     c4
+        # *c1 is a member of u1, u2, u3, and u4
+
+        # u2 is a member of g1 and g2
+        m = Message()
+        m.dn = Dn(self.ldb, "CN=g1,%s" % self.ou_groups)
+        m["member"] = MessageElement("CN=u2,%s" % self.ou_users,
+                                     FLAG_MOD_ADD, "member")
+        self.ldb.modify(m)
+
+        m = Message()
+        m.dn = Dn(self.ldb, "CN=g2,%s" % self.ou_groups)
+        m["member"] = MessageElement("CN=u2,%s" % self.ou_users,
+                                     FLAG_MOD_ADD, "member")
+        self.ldb.modify(m)
+
+        # g2 is a member of g1
+        m = Message()
+        m.dn = Dn(self.ldb, "CN=g1,%s" % self.ou_groups)
+        m["member"] = MessageElement("CN=g2,%s" % self.ou_groups,
+                                     FLAG_MOD_ADD, "member")
+        self.ldb.modify(m)
+
+        # g3 is a member of g2
+        m = Message()
+        m.dn = Dn(self.ldb, "CN=g2,%s" % self.ou_groups)
+        m["member"] = MessageElement("CN=g3,%s" % self.ou_groups,
+                                     FLAG_MOD_ADD, "member")
+        self.ldb.modify(m)
+
+        # u3 is a member of g3 and g4
+        m = Message()
+        m.dn = Dn(self.ldb, "CN=g3,%s" % self.ou_groups)
+        m["member"] = MessageElement("CN=u3,%s" % self.ou_users,
+                                     FLAG_MOD_ADD, "member")
+        self.ldb.modify(m)
+
+        m = Message()
+        m.dn = Dn(self.ldb, "CN=g4,%s" % self.ou_groups)
+        m["member"] = MessageElement("CN=u3,%s" % self.ou_users,
+                                     FLAG_MOD_ADD, "member")
+        self.ldb.modify(m)
+
+        # u4 is a member of g4
+        m = Message()
+        m.dn = Dn(self.ldb, "CN=g4,%s" % self.ou_groups)
+        m["member"] = MessageElement("CN=u4,%s" % self.ou_users,
+                                     FLAG_MOD_ADD, "member")
+        self.ldb.modify(m)
+
+        # c1 is a member of u1, u2, u3, and u4
+        m = Message()
+        m.dn = Dn(self.ldb, "CN=u1,%s" % self.ou_users)
+        m["member"] = MessageElement("CN=c1,%s" % self.ou_computers,
+                                     FLAG_MOD_ADD, "member")
+        self.ldb.modify(m)
+
+        m = Message()
+        m.dn = Dn(self.ldb, "CN=u2,%s" % self.ou_users)
+        m["member"] = MessageElement("CN=c1,%s" % self.ou_computers,
+                                     FLAG_MOD_ADD, "member")
+        self.ldb.modify(m)
+
+        m = Message()
+        m.dn = Dn(self.ldb, "CN=u3,%s" % self.ou_users)
+        m["member"] = MessageElement("CN=c1,%s" % self.ou_computers,
+                                     FLAG_MOD_ADD, "member")
+        self.ldb.modify(m)
+
+        m = Message()
+        m.dn = Dn(self.ldb, "CN=u4,%s" % self.ou_users)
+        m["member"] = MessageElement("CN=c1,%s" % self.ou_computers,
+                                     FLAG_MOD_ADD, "member")
+        self.ldb.modify(m)
+
+        # c2 is a member of u1
+        m = Message()
+        m.dn = Dn(self.ldb, "CN=u1,%s" % self.ou_users)
+        m["member"] = MessageElement("CN=c2,%s" % self.ou_computers,
+                                     FLAG_MOD_ADD, "member")
+        self.ldb.modify(m)
+
+        # c3 is a member of u2 and g3
+        m = Message()
+        m.dn = Dn(self.ldb, "CN=u2,%s" % self.ou_users)
+        m["member"] = MessageElement("CN=c3,%s" % self.ou_computers,
+                                     FLAG_MOD_ADD, "member")
+        self.ldb.modify(m)
+
+        m = Message()
+        m.dn = Dn(self.ldb, "CN=g3,%s" % self.ou_groups)
+        m["member"] = MessageElement("CN=c3,%s" % self.ou_computers,
+                                     FLAG_MOD_ADD, "member")
+        self.ldb.modify(m)
+
+        # c4 is a member of u4 and g4
+        m = Message()
+        m.dn = Dn(self.ldb, "CN=u4,%s" % self.ou_users)
+        m["member"] = MessageElement("CN=c4,%s" % self.ou_computers,
+                                     FLAG_MOD_ADD, "member")
+        self.ldb.modify(m)
+
+        m = Message()
+        m.dn = Dn(self.ldb, "CN=g4,%s" % self.ou_groups)
+        m["member"] = MessageElement("CN=c4,%s" % self.ou_computers,
+                                     FLAG_MOD_ADD, "member")
+        self.ldb.modify(m)
+
+        self.question = 6 * (9 -2)
+        self.answer = 42
+
+    def tearDown(self):
+        super(MatchRuleConditionTests, self).tearDown()
+        self.ldb.delete(self.ou, controls=['tree_delete:0'])
+
+    def test_g1_members(self):
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="memberOf=cn=g1,%s" % self.ou_groups)
+        self.assertEquals(len(res1), 2)
+        dn_list = [str(res.dn) for res in res1]
+        self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
+        self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="memberOf:1.2.840.113556.1.4.1941:=cn=g1,%s" % self.ou_groups)
+        self.assertEquals(len(res1), 6)
+        dn_list = [str(res.dn) for res in res1]
+        self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
+        self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
+        self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
+        self.assertTrue("CN=c3,%s" % self.ou_computers in dn_list)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="member=cn=g1,%s" % self.ou_groups)
+        self.assertEquals(len(res1), 0)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="member:1.2.840.113556.1.4.1941:=cn=g1,%s" % self.ou_groups)
+        self.assertEquals(len(res1), 0)
+
+    def test_g2_members(self):
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="memberOf=cn=g2,%s" % self.ou_groups)
+        self.assertEquals(len(res1), 2)
+        dn_list = [str(res.dn) for res in res1]
+        self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
+        self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="memberOf:1.2.840.113556.1.4.1941:=cn=g2,%s" % self.ou_groups)
+        self.assertEquals(len(res1), 5)
+        dn_list = [str(res.dn) for res in res1]
+        self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
+        self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
+        self.assertTrue("CN=c3,%s" % self.ou_computers in dn_list)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="member=cn=g2,%s" % self.ou_groups)
+        self.assertEquals(len(res1), 1)
+        self.assertEquals(str(res1[0].dn), "CN=g1,%s" % self.ou_groups)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="member:1.2.840.113556.1.4.1941:=cn=g2,%s" % self.ou_groups)
+        self.assertEquals(len(res1), 1)
+        self.assertEquals(str(res1[0].dn), "CN=g1,%s" % self.ou_groups)
+
+    def test_g3_members(self):
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="memberOf=cn=g3,%s" % self.ou_groups)
+        self.assertEquals(len(res1), 2)
+        dn_list = [str(res.dn) for res in res1]
+        self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=c3,%s" % self.ou_computers in dn_list)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="memberOf:1.2.840.113556.1.4.1941:=cn=g3,%s" % self.ou_groups)
+        self.assertEquals(len(res1), 3)
+        dn_list = [str(res.dn) for res in res1]
+        self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
+        self.assertTrue("CN=c3,%s" % self.ou_computers in dn_list)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="member=cn=g3,%s" % self.ou_groups)
+        self.assertEquals(len(res1), 1)
+        self.assertEquals(str(res1[0].dn), "CN=g2,%s" % self.ou_groups)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="member:1.2.840.113556.1.4.1941:=cn=g3,%s" % self.ou_groups)
+        self.assertEquals(len(res1), 2)
+        dn_list = [str(res.dn) for res in res1]
+        self.assertTrue("CN=g1,%s" % self.ou_groups in dn_list)
+        self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
+
+    def test_g4_members(self):
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="memberOf=cn=g4,%s" % self.ou_groups)
+        self.assertEquals(len(res1), 3)
+        dn_list = [str(res.dn) for res in res1]
+        self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=u4,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=c4,%s" % self.ou_computers in dn_list)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="memberOf:1.2.840.113556.1.4.1941:=cn=g4,%s" % self.ou_groups)
+        self.assertEquals(len(res1), 4)
+        dn_list = [str(res.dn) for res in res1]
+        self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=u4,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
+        self.assertTrue("CN=c4,%s" % self.ou_computers in dn_list)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="member=cn=g4,%s" % self.ou_groups)
+        self.assertEquals(len(res1), 0)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="member:1.2.840.113556.1.4.1941:=cn=g4,%s" % self.ou_groups)
+        self.assertEquals(len(res1), 0)
+
+    def test_u1_members(self):
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="memberOf=cn=u1,%s" % self.ou_users)
+        self.assertEqual(len(res1), 2)
+        dn_list = [str(res.dn) for res in res1]
+        self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
+        self.assertTrue("CN=c2,%s" % self.ou_computers in dn_list)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="memberOf:1.2.840.113556.1.4.1941:=cn=u1,%s" % self.ou_users)
+        self.assertEqual(len(res1), 2)
+        dn_list = [str(res.dn) for res in res1]
+        self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
+        self.assertTrue("CN=c2,%s" % self.ou_computers in dn_list)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="member=cn=u1,%s" % self.ou_users)
+        self.assertEqual(len(res1), 0)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="member:1.2.840.113556.1.4.1941:=cn=u1,%s" % self.ou_users)
+        self.assertEqual(len(res1), 0)
+
+    def test_u2_members(self):
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="memberOf=cn=u2,%s" % self.ou_users)
+        self.assertEqual(len(res1), 2)
+        dn_list = [str(res.dn) for res in res1]
+        self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
+        self.assertTrue("CN=c3,%s" % self.ou_computers in dn_list)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="memberOf:1.2.840.113556.1.4.1941:=cn=u2,%s" % self.ou_users)
+        self.assertEqual(len(res1), 2)
+        dn_list = [str(res.dn) for res in res1]
+        self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
+        self.assertTrue("CN=c3,%s" % self.ou_computers in dn_list)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="member=cn=u2,%s" % self.ou_users)
+        self.assertEqual(len(res1), 2)
+        dn_list = [str(res.dn) for res in res1]
+        self.assertTrue("CN=g1,%s" % self.ou_groups in dn_list)
+        self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="member:1.2.840.113556.1.4.1941:=cn=u2,%s" % self.ou_users)
+        self.assertEqual(len(res1), 2)
+        dn_list = [str(res.dn) for res in res1]
+        self.assertTrue("CN=g1,%s" % self.ou_groups in dn_list)
+        self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
+
+    def test_u3_members(self):
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="member=cn=u3,%s" % self.ou_users)
+        self.assertEqual(len(res1), 2)
+        dn_list = [str(res.dn) for res in res1]
+        self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
+        self.assertTrue("CN=g4,%s" % self.ou_groups in dn_list)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="member:1.2.840.113556.1.4.1941:=cn=u3,%s" % self.ou_users)
+        self.assertEqual(len(res1), 4)
+        dn_list = [str(res.dn) for res in res1]
+        self.assertTrue("CN=g1,%s" % self.ou_groups in dn_list)
+        self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
+        self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
+        self.assertTrue("CN=g4,%s" % self.ou_groups in dn_list)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="memberOf=cn=u3,%s" % self.ou_users)
+        self.assertEqual(len(res1), 1)
+        self.assertEqual(str(res1[0].dn), "CN=c1,%s" % self.ou_computers)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="memberOf:1.2.840.113556.1.4.1941:=cn=u3,%s" % self.ou_users)
+        self.assertEqual(len(res1), 1)
+        self.assertEqual(str(res1[0].dn), "CN=c1,%s" % self.ou_computers)
+
+    def test_u4_members(self):
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="member=cn=u4,%s" % self.ou_users)
+        self.assertEqual(len(res1), 1)
+        self.assertEqual(str(res1[0].dn), "CN=g4,%s" % self.ou_groups)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="member:1.2.840.113556.1.4.1941:=cn=u4,%s" % self.ou_users)
+        self.assertEqual(len(res1), 1)
+        self.assertEqual(str(res1[0].dn), "CN=g4,%s" % self.ou_groups)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="memberOf=cn=u4,%s" % self.ou_users)
+        self.assertEqual(len(res1), 2)
+        dn_list = [str(res.dn) for res in res1]
+        self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
+        self.assertTrue("CN=c4,%s" % self.ou_computers in dn_list)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="memberOf:1.2.840.113556.1.4.1941:=cn=u4,%s" % self.ou_users)
+        self.assertEqual(len(res1), 2)
+        dn_list = [str(res.dn) for res in res1]
+        self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
+        self.assertTrue("CN=c4,%s" % self.ou_computers in dn_list)
+
+    def test_c1_members(self):
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="member=cn=c1,%s" % self.ou_computers)
+        self.assertEqual(len(res1), 4)
+        dn_list = [str(res.dn) for res in res1]
+        self.assertTrue("CN=u1,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=u4,%s" % self.ou_users in dn_list)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="member:1.2.840.113556.1.4.1941:=cn=c1,%s" % self.ou_computers)
+        self.assertEqual(len(res1), 8)
+        dn_list = [str(res.dn) for res in res1]
+        self.assertTrue("CN=u1,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=u4,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=g1,%s" % self.ou_groups in dn_list)
+        self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
+        self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
+        self.assertTrue("CN=g4,%s" % self.ou_groups in dn_list)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="memberOf=cn=c1,%s" % self.ou_computers)
+        self.assertEqual(len(res1), 0)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="memberOf:1.2.840.113556.1.4.1941:=cn=c1,%s" % self.ou_computers)
+        self.assertEqual(len(res1), 0)
+
+    def test_c2_members(self):
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="member=cn=c2,%s" % self.ou_computers)
+        self.assertEqual(len(res1), 1)
+        self.assertEqual(str(res1[0].dn), "CN=u1,%s" % self.ou_users)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="member:1.2.840.113556.1.4.1941:=cn=c2,%s" % self.ou_computers)
+        self.assertEqual(len(res1), 1)
+        self.assertEqual(str(res1[0].dn), "CN=u1,%s" % self.ou_users)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="memberOf=cn=c2,%s" % self.ou_computers)
+        self.assertEqual(len(res1), 0)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="memberOf:1.2.840.113556.1.4.1941:=cn=c2,%s" % self.ou_computers)
+        self.assertEqual(len(res1), 0)
+
+    def test_c3_members(self):
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="member=cn=c3,%s" % self.ou_computers)
+        self.assertEqual(len(res1), 2)
+        dn_list = [str(res.dn) for res in res1]
+        self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
+        self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="member:1.2.840.113556.1.4.1941:=cn=c3,%s" % self.ou_computers)
+        self.assertEqual(len(res1), 4)
+        dn_list = [str(res.dn) for res in res1]
+        self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=g1,%s" % self.ou_groups in dn_list)
+        self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
+        self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="memberOf=cn=c3,%s" % self.ou_computers)
+        self.assertEqual(len(res1), 0)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="memberOf:1.2.840.113556.1.4.1941:=cn=c3,%s" % self.ou_computers)
+        self.assertEqual(len(res1), 0)
+
+    def test_c4_members(self):
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="member=cn=c4,%s" % self.ou_computers)
+        self.assertEqual(len(res1), 2)
+        dn_list = [str(res.dn) for res in res1]
+        self.assertTrue("CN=g4,%s" % self.ou_groups in dn_list)
+        self.assertTrue("CN=u4,%s" % self.ou_users in dn_list)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="member:1.2.840.113556.1.4.1941:=cn=c4,%s" % self.ou_computers)
+        self.assertEqual(len(res1), 2)
+        dn_list = [str(res.dn) for res in res1]
+        self.assertTrue("CN=u4,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=g4,%s" % self.ou_groups in dn_list)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="memberOf=cn=c4,%s" % self.ou_computers)
+        self.assertEqual(len(res1), 0)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression="memberOf:1.2.840.113556.1.4.1941:=cn=c4,%s" % self.ou_computers)
+        self.assertEqual(len(res1), 0)
+
+    def test_or_member_queries(self):
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression=("(|(member:1.2.840.113556.1.4.1941:=cn=c1,%s)"
+                                           "(member:1.2.840.113556.1.4.1941:=cn=c2,%s))") % (
+                                    self.ou_computers, self.ou_computers))
+        self.assertEqual(len(res1), 8)
+        dn_list = [str(res.dn) for res in res1]
+        self.assertTrue("CN=u1,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=u4,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=g1,%s" % self.ou_groups in dn_list)
+        self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
+        self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
+        self.assertTrue("CN=g4,%s" % self.ou_groups in dn_list)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression=("(|(member:1.2.840.113556.1.4.1941:=cn=c2,%s)"
+                                           "(member:1.2.840.113556.1.4.1941:=cn=c3,%s))") % (
+                                    self.ou_computers, self.ou_computers))
+        self.assertEqual(len(res1), 5)
+        dn_list = [str(res.dn) for res in res1]
+        self.assertTrue("CN=u1,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=g1,%s" % self.ou_groups in dn_list)
+        self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
+        self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression=("(|(member:1.2.840.113556.1.4.1941:=cn=c2,%s)"
+                                           "(member:1.2.840.113556.1.4.1941:=cn=c4,%s))") % (
+                                    self.ou_computers, self.ou_computers))
+        self.assertEqual(len(res1), 3)
+        dn_list = [str(res.dn) for res in res1]
+        self.assertTrue("CN=u1,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=u4,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=g4,%s" % self.ou_groups in dn_list)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression=("(|(member:1.2.840.113556.1.4.1941:=cn=c3,%s)"
+                                           "(member:1.2.840.113556.1.4.1941:=cn=c4,%s))") % (
+                                    self.ou_computers, self.ou_computers))
+        self.assertEqual(len(res1), 6)
+        dn_list = [str(res.dn) for res in res1]
+        self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=u4,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=g1,%s" % self.ou_groups in dn_list)
+        self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
+        self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
+        self.assertTrue("CN=g4,%s" % self.ou_groups in dn_list)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression=("(|(member:1.2.840.113556.1.4.1941:=cn=u1,%s)"
+                                           "(member:1.2.840.113556.1.4.1941:=cn=c4,%s))") % (
+                                    self.ou_users, self.ou_computers))
+        self.assertEqual(len(res1), 2)
+        dn_list = [str(res.dn) for res in res1]
+        self.assertTrue("CN=u4,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=g4,%s" % self.ou_groups in dn_list)
+
+    def test_and_member_queries(self):
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression=("(&(member:1.2.840.113556.1.4.1941:=cn=c1,%s)"
+                                           "(member:1.2.840.113556.1.4.1941:=cn=c2,%s))") % (
+                                    self.ou_computers, self.ou_computers))
+        self.assertEqual(len(res1), 1)
+        self.assertEqual(str(res1[0].dn), "CN=u1,%s" % self.ou_users)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression=("(&(member:1.2.840.113556.1.4.1941:=cn=c2,%s)"
+                                           "(member:1.2.840.113556.1.4.1941:=cn=c3,%s))") % (
+                                    self.ou_computers, self.ou_computers))
+        self.assertEqual(len(res1), 0)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression=("(&(member:1.2.840.113556.1.4.1941:=cn=c3,%s)"
+                                           "(member:1.2.840.113556.1.4.1941:=cn=u3,%s))") % (
+                                    self.ou_computers, self.ou_users))
+        self.assertEqual(len(res1), 3)
+        dn_list = [str(res.dn) for res in res1]
+        self.assertTrue("CN=g1,%s" % self.ou_groups in dn_list)
+        self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
+        self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression=("(&(member:1.2.840.113556.1.4.1941:=cn=c1,%s)"
+                                           "(member:1.2.840.113556.1.4.1941:=cn=u4,%s))") % (
+                                    self.ou_computers, self.ou_computers))
+        self.assertEqual(len(res1), 0)
+
+    def test_or_memberOf_queries(self):
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression=("(|(memberOf:1.2.840.113556.1.4.1941:=cn=g1,%s)"
+                                           "(memberOf:1.2.840.113556.1.4.1941:=cn=g2,%s))") % (
+                                    self.ou_groups, self.ou_groups))
+        self.assertEqual(len(res1), 6)
+        dn_list = [str(res.dn) for res in res1]
+        self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
+        self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
+        self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
+        self.assertTrue("CN=c3,%s" % self.ou_computers in dn_list)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression=("(|(memberOf:1.2.840.113556.1.4.1941:=cn=g1,%s)"
+                                           "(memberOf:1.2.840.113556.1.4.1941:=cn=g3,%s))") % (
+                                    self.ou_groups, self.ou_groups))
+        self.assertEqual(len(res1), 6)
+        dn_list = [str(res.dn) for res in res1]
+        self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
+        self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
+        self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
+        self.assertTrue("CN=c3,%s" % self.ou_computers in dn_list)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression=("(|(memberOf:1.2.840.113556.1.4.1941:=cn=g1,%s)"
+                                           "(memberOf:1.2.840.113556.1.4.1941:=cn=g4,%s))") % (
+                                    self.ou_groups, self.ou_groups))
+        self.assertEqual(len(res1), 8)
+        dn_list = [str(res.dn) for res in res1]
+        self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=u4,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=g2,%s" % self.ou_groups in dn_list)
+        self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
+        self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
+        self.assertTrue("CN=c3,%s" % self.ou_computers in dn_list)
+        self.assertTrue("CN=c4,%s" % self.ou_computers in dn_list)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression=("(|(memberOf:1.2.840.113556.1.4.1941:=cn=g2,%s)"
+                                           "(memberOf:1.2.840.113556.1.4.1941:=cn=g3,%s))") %
+                               (self.ou_groups, self.ou_groups))
+        self.assertEqual(len(res1), 5)
+        dn_list = [str(res.dn) for res in res1]
+        self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
+        self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
+        self.assertTrue("CN=c3,%s" % self.ou_computers in dn_list)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression=("(|(memberOf:1.2.840.113556.1.4.1941:=cn=g2,%s)"
+                                           "(memberOf:1.2.840.113556.1.4.1941:=cn=g4,%s))") % (
+                                    self.ou_groups, self.ou_groups))
+        self.assertEqual(len(res1), 7)
+        dn_list = [str(res.dn) for res in res1]
+        self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=u4,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
+        self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
+        self.assertTrue("CN=c3,%s" % self.ou_computers in dn_list)
+        self.assertTrue("CN=c4,%s" % self.ou_computers in dn_list)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression=("(|(memberOf:1.2.840.113556.1.4.1941:=cn=g3,%s)"
+                                           "(memberOf:1.2.840.113556.1.4.1941:=cn=g4,%s))") % (
+                                    self.ou_groups, self.ou_groups))
+        self.assertEqual(len(res1), 5)
+        dn_list = [str(res.dn) for res in res1]
+        self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=u4,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
+        self.assertTrue("CN=c3,%s" % self.ou_computers in dn_list)
+        self.assertTrue("CN=c4,%s" % self.ou_computers in dn_list)
+
+    def test_and_memberOf_queries(self):
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression=("(&(memberOf:1.2.840.113556.1.4.1941:=cn=g1,%s)"
+                                           "(memberOf:1.2.840.113556.1.4.1941:=cn=g2,%s))") % (
+                                    self.ou_groups, self.ou_groups))
+        self.assertEqual(len(res1), 5)
+        dn_list = [str(res.dn) for res in res1]
+        self.assertTrue("CN=u2,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=g3,%s" % self.ou_groups in dn_list)
+        self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
+        self.assertTrue("CN=c3,%s" % self.ou_computers in dn_list)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression=("(&(memberOf:1.2.840.113556.1.4.1941:=cn=g1,%s)"
+                                           "(memberOf:1.2.840.113556.1.4.1941:=cn=g3,%s))") % (
+                                    self.ou_groups, self.ou_groups))
+        self.assertEqual(len(res1), 3)
+        dn_list = [str(res.dn) for res in res1]
+        self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
+        self.assertTrue("CN=c3,%s" % self.ou_computers in dn_list)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression=("(&(memberOf:1.2.840.113556.1.4.1941:=cn=g1,%s)"
+                                           "(memberOf:1.2.840.113556.1.4.1941:=cn=g4,%s))") % (
+                                    self.ou_groups, self.ou_groups))
+        self.assertEqual(len(res1), 2)
+        dn_list = [str(res.dn) for res in res1]
+        self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression=("(&(memberOf:1.2.840.113556.1.4.1941:=cn=g2,%s)"
+                                           "(memberOf:1.2.840.113556.1.4.1941:=cn=g3,%s))") % (
+                                    self.ou_groups, self.ou_groups))
+        self.assertEqual(len(res1), 3)
+        dn_list = [str(res.dn) for res in res1]
+        self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
+        self.assertTrue("CN=c3,%s" % self.ou_computers in dn_list)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression=("(&(memberOf:1.2.840.113556.1.4.1941:=cn=g2,%s)"
+                                           "(memberOf:1.2.840.113556.1.4.1941:=cn=g4,%s))") % (
+                                    self.ou_groups, self.ou_groups))
+        self.assertEqual(len(res1), 2)
+        dn_list = [str(res.dn) for res in res1]
+        self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression=("(&(memberOf:1.2.840.113556.1.4.1941:=cn=g3,%s)"
+                                           "(memberOf:1.2.840.113556.1.4.1941:=cn=g4,%s))") % (
+                                    self.ou_groups, self.ou_groups))
+        self.assertEqual(len(res1), 2)
+        dn_list = [str(res.dn) for res in res1]
+        self.assertTrue("CN=u3,%s" % self.ou_users in dn_list)
+        self.assertTrue("CN=c1,%s" % self.ou_computers in dn_list)
+
+        res1 = self.ldb.search(self.ou,
+                               scope=SCOPE_SUBTREE,
+                               expression=("(&(memberOf:1.2.840.113556.1.4.1941:=cn=g1,%s)"
+                                           "(memberOf:1.2.840.113556.1.4.1941:=cn=c1,%s))") % (
+                                    self.ou_groups, self.ou_computers))
+        self.assertEqual(len(res1), 0)
+
 
 parser = optparse.OptionParser("match_rules.py [options] <host>")
 sambaopts = options.SambaOptions(parser)