Browse Source

Issue 7071 - search filter (&(cn:dn:=groups)) no longer returns results

Description:

When processing an "and" filter and it only contains one filter component then
the logic in the code breaks down and the filter is seen as not matching.

The logic breaks down because we are not setting "nomatch" after the access
check is successful. If there are two components then it works fine
because we do the access check on the first filter component and set that
the access check was done(access_check_done), but "nomatch" is not set yet.
So when the next filter component is checked for access we see that the access
check was done and then we set "nomatch".

To recap we always need to set "nomatch" when the access check is successful
in order to handle the case where an "and" fitler only has one component.

Relates: https://github.com/389ds/389-ds-base/issues/7071

Reviewed by: spichugi(Thanks!)
Mark Reynolds 5 days ago
parent
commit
34d30cf2c1

+ 14 - 3
dirsrvtests/tests/suites/filter/complex_filters_test.py

@@ -33,8 +33,15 @@ AND_FILTERS = [("(&(uid=uid1)(sn=last1)(givenname=first1))", 1),
                ("(&(uid=*)(&(sn=last3)(givenname=*)))", 1),
                ("(&(uid=uid5)(&(&(sn=*))(&(givenname=*))))", 1),
                ("(&(objectclass=*)(uid=*)(sn=last*))", 5),
-               ("(&(objectclass=*)(uid=*)(sn=last1))", 1)]
-
+               ("(&(objectclass=*)(uid=*)(sn=last1))", 1),
+               ("(&(sn:dn:=last1))", 1),
+               ("(&(sn:dn:=last1)(givenname:dn:=first1))", 1),
+               ("(&(sn:dn:=last1)(givenname=first1))", 1),
+               ("(&(sn=last1)(givenname=first1)(uid:dn:=uid1))", 1),
+               ("(&(uid:dn:=uid1))", 1),
+               ("(&(uid:dn:=uid1)(cn:dn:=full1))", 1),
+               ("(&(uid:dn:=uid1)(givenname:dn:=first1))", 1),
+               ("(&(uid:dn:=uid1)(givenname:dn:=first1)(cn:dn:=full1))", 1)]
 OR_FILTERS = [("(|(uid=uid1)(sn=last1)(givenname=first1))", 1),
               ("(|(uid=uid1)(|(sn=last1)(givenname=first1)))", 1),
               ("(|(uid=uid1)(|(|(sn=last1))(|(givenname=first1))))", 1),
@@ -59,7 +66,11 @@ ZERO_AND_FILTERS = [("(&(uid=uid1)(sn=last1)(givenname=NULL))", 0),
                    ("(&(uid=uid1)(&(sn=last1)(givenname=NULL)))", 0),
                    ("(&(uid=uid1)(&(&(sn=last1))(&(givenname=NULL))))", 0),
                    ("(&(uid=uid1)(&(&(sn=last1))(&(givenname=NULL)(sn=*)))(|(sn=NULL)))", 0),
-                   ("(&(uid=uid1)(&(&(sn=last*))(&(givenname=first*)))(&(sn=NULL)))", 0)]
+                   ("(&(uid=uid1)(&(&(sn=last*))(&(givenname=first*)))(&(sn=NULL)))", 0),
+                   ("(&(uid:dn:=not_uid))", 0),
+                   ("(&(uid:dn:=not_uid)(cn:dn:=full1))", 0),
+                   ("(&(uid:dn:=uid1)(givenname:dn:=not_first1))", 0),
+                   ("(&(uid:dn:=uid1)(givenname:dn:=first1)(cn:dn:=not_full1))", 0)]
 
 ZERO_OR_FILTERS = [("(|(uid=NULL)(sn=NULL)(givenname=NULL))", 0),
                   ("(|(uid=NULL)(|(sn=NULL)(givenname=NULL)))", 0),

+ 6 - 1
ldap/servers/slapd/filterentry.c

@@ -1044,13 +1044,18 @@ vattr_test_filter_list_and(
             nomatch = -1;
             break;
         } else {
+            /* We have a match, but we need to check access */
             if (!verify_access || (*access_check_done)) {
                 nomatch = 0;
             } else {
                 /* check access */
                 rc = slapi_vattr_filter_test_ext_internal(pb, e, f, verify_access, 1, access_check_done);
-                if (rc)
+                if (rc) {
                     undefined = rc;
+                } else {
+                    /* Access is good so mark this as a match */
+                    nomatch = 0;
+                }
             }
         }
     }