]> git.sur5r.net Git - openldap/commitdiff
fix hasSubordinate filtering; now it can be safely turned on
authorPierangelo Masarati <ando@openldap.org>
Sat, 26 Oct 2002 16:18:31 +0000 (16:18 +0000)
committerPierangelo Masarati <ando@openldap.org>
Sat, 26 Oct 2002 16:18:31 +0000 (16:18 +0000)
13 files changed:
servers/slapd/back-bdb/external.h
servers/slapd/back-bdb/init.c
servers/slapd/back-bdb/lcup.c
servers/slapd/back-bdb/operational.c
servers/slapd/back-bdb/search.c
servers/slapd/back-ldbm/external.h
servers/slapd/back-ldbm/init.c
servers/slapd/back-ldbm/operational.c
servers/slapd/back-ldbm/search.c
servers/slapd/back-sql/search.c
servers/slapd/filterentry.c
servers/slapd/proto-slap.h
servers/slapd/slap.h

index f7c285a808621fd2c84810ded9b298ca033c3f8d..9e595ef9ff622a4342f8578969c19a2537092282 100644 (file)
@@ -33,6 +33,10 @@ extern BI_chk_referrals      bdb_referrals;
 
 extern BI_operational  bdb_operational;
 
+#ifdef SLAP_X_FILTER_HASSUBORDINATES
+extern BI_has_subordinates bdb_hasSubordinates;
+#endif /* SLAP_X_FILTER_HASSUBORDINATES */
+
 /* tools.c */
 extern BI_tool_entry_open      bdb_tool_entry_open;
 extern BI_tool_entry_close     bdb_tool_entry_close;
index 0e3cab45de7a5aa4019d16aa890941f66e293e0d..aa956d2b1e31049f10393a310913e3af98829cef 100644 (file)
@@ -615,6 +615,9 @@ bdb_initialize(
 
        bi->bi_chk_referrals = bdb_referrals;
        bi->bi_operational = bdb_operational;
+#ifdef SLAP_X_FILTER_HASSUBORDINATES
+       bi->bi_has_subordinates = bdb_hasSubordinates;
+#endif /* SLAP_X_FILTER_HASSUBORDINATES */
        bi->bi_entry_release_rw = bdb_entry_release;
 
        /*
index 9cf1a1479efe43b1bdc6daea421cac907bb5579e..633d8111af680f08fcac991e713f6c1143a58833 100644 (file)
@@ -110,11 +110,6 @@ bdb_psearch(
        int isroot = 0;
        int scopeok = 0;
 
-#ifdef SLAP_X_FILTER_HASSUBORDINATES
-       int             filter_hasSubordinates = 0;
-       Attribute       *hasSubordinates = NULL;
-#endif /* SLAP_X_FILTER_HASSUBORDINATES */
-
        u_int32_t       locker;
        DB_LOCK         lock;
 
@@ -386,14 +381,6 @@ dn2entry_retry:
                }
        }
 
-#ifdef SLAP_X_FILTER_HASSUBORDINATES
-       /*
-        * is hasSubordinates used in the filter ?
-        * FIXME: we may compute this directly when parsing the filter
-        */
-       filter_hasSubordinates = filter_has_subordinates( filter );
-#endif /* SLAP_X_FILTER_HASSUBORDINATES */
-
        lcupf.f_choice = LDAP_FILTER_AND;
        lcupf.f_and = &csnfnot;
        lcupf.f_next = NULL;
@@ -568,52 +555,12 @@ dn2entry_retry:
                goto test_done;
        }
 
-#ifdef SLAP_X_FILTER_HASSUBORDINATES
-       /*
-        * if hasSubordinates is used in the filter,
-        * append it to the entry's attributes
-        */
-       if ( filter_hasSubordinates ) {
-               int     hs;
-
-               rc = bdb_hasSubordinates( be, ps_conn, ps_op, e, &hs);
-               if ( rc != LDAP_SUCCESS ) {
-                       goto test_done;
-               }
-
-               hasSubordinates = slap_operational_hasSubordinate(
-                       hs == LDAP_COMPARE_TRUE );
-
-               if ( hasSubordinates == NULL ) {
-                       goto test_done;
-               }
-
-               hasSubordinates->a_next = e->e_attrs;
-               e->e_attrs = hasSubordinates;
-       }
-#endif /* SLAP_X_FILTER_HASSUBORDINATES */
-
        if ( psearch_type != LCUP_PSEARCH_BY_SCOPEOUT ) {
                rc = test_filter( be, ps_conn, ps_op, e, &lcupf );
        } else {
                rc = LDAP_COMPARE_TRUE;
        }
 
-#ifdef SLAP_X_FILTER_HASSUBORDINATES
-       if ( hasSubordinates ) {
-               /*
-                * FIXME: this is fairly inefficient, because 
-                * if hasSubordinates is among the required
-                * attrs, it will be added again later;
-                * maybe we should leave it and check
-                * check later if it's already present,
-                * if required
-                */
-               e->e_attrs = e->e_attrs->a_next;
-               attr_free( hasSubordinates );
-       }
-#endif /* SLAP_X_FILTER_HASSUBORDINATES */
-
        if ( rc == LDAP_COMPARE_TRUE ) {
                struct berval   dn;
 
index 1c5d4b14d6580bbc60bde18d608d0bd79e7c81c0..7cead61e7c3d7cb375fcc8d29fba72f2c2087472 100644 (file)
@@ -16,9 +16,9 @@
 #include "proto-bdb.h"
 
 /*
- * sets the supported operational attributes (if required)
+ * sets *hasSubordinates to LDAP_COMPARE_TRUE/LDAP_COMPARE_FALSE
+ * if the entry has children or not.
  */
-
 int
 bdb_hasSubordinates(
        BackendDB       *be,
@@ -124,6 +124,9 @@ return_results:
        return rc;
 }
 
+/*
+ * sets the supported operational attributes (if required)
+ */
 int
 bdb_operational(
        BackendDB       *be,
index 03a0a540bc96fc14883f926743c1e8e15c05f753..5d2bdcec14855ac86a36ebeafd93ddb23f50d006 100644 (file)
@@ -67,10 +67,6 @@ bdb_search(
        struct slap_limits_set *limit = NULL;
        int isroot = 0;
 
-#ifdef SLAP_X_FILTER_HASSUBORDINATES
-       int             filter_hasSubordinates = 0;
-#endif /* SLAP_X_FILTER_HASSUBORDINATES */
-
        u_int32_t       locker;
        DB_LOCK         lock;
 
@@ -342,14 +338,6 @@ dn2entry_retry:
                }
        }
 
-#ifdef SLAP_X_FILTER_HASSUBORDINATES
-       /*
-        * is hasSubordinates used in the filter ?
-        * FIXME: we may compute this directly when parsing the filter
-        */
-       filter_hasSubordinates = filter_has_subordinates( filter );
-#endif /* SLAP_X_FILTER_HASSUBORDINATES */
-
 #ifdef LDAP_CLIENT_UPDATE
        if ( op->o_clientupdate_type & SLAP_LCUP_SYNC ) {
                lcupf.f_choice = LDAP_FILTER_AND;
@@ -382,9 +370,6 @@ dn2entry_retry:
                id = bdb_idl_next( candidates, &cursor ) )
        {
                int             scopeok = 0;
-#ifdef SLAP_X_FILTER_HASSUBORDINATES
-               Attribute       *hasSubordinates = NULL;
-#endif /* SLAP_X_FILTER_HASSUBORDINATES */
 
                /* check for abandon */
                if ( op->o_abandon ) {
@@ -548,31 +533,6 @@ id2entry_retry:
                        goto loop_continue;
                }
 
-#ifdef SLAP_X_FILTER_HASSUBORDINATES
-               /*
-                * if hasSubordinates is used in the filter,
-                * append it to the entry's attributes
-                */
-               if ( filter_hasSubordinates ) {
-                       int     hs;
-
-                       rc = bdb_hasSubordinates( be, conn, op, e, &hs);
-                       if ( rc != LDAP_SUCCESS ) {
-                               goto loop_continue;
-                       }
-
-                       hasSubordinates = slap_operational_hasSubordinate(
-                               hs == LDAP_COMPARE_TRUE );
-
-                       if ( hasSubordinates == NULL ) {
-                               goto loop_continue;
-                       }
-
-                       hasSubordinates->a_next = e->e_attrs;
-                       e->e_attrs = hasSubordinates;
-               }
-#endif /* SLAP_X_FILTER_HASSUBORDINATES */
-
                /* if it matches the filter and scope, send it */
 #ifdef LDAP_CLIENT_UPDATE
                if ( op->o_clientupdate_type & SLAP_LCUP_SYNC ) {
@@ -583,21 +543,6 @@ id2entry_retry:
                        rc = test_filter( be, conn, op, e, filter );
                }
 
-#ifdef SLAP_X_FILTER_HASSUBORDINATES
-               if ( hasSubordinates ) {
-                       /*
-                        * FIXME: this is fairly inefficient, because 
-                        * if hasSubordinates is among the required
-                        * attrs, it will be added again later;
-                        * maybe we should leave it and check
-                        * check later if it's already present,
-                        * if required
-                        */
-                       e->e_attrs = e->e_attrs->a_next;
-                       attr_free( hasSubordinates );
-               }
-#endif /* SLAP_X_FILTER_HASSUBORDINATES */
-
                if ( rc == LDAP_COMPARE_TRUE ) {
                        struct berval   dn;
 
index 7c3faad166a8b590e674b117cbd79f335d386784..93b40b1dd446b58d1b86fef699e56dabb107bd30 100644 (file)
@@ -43,6 +43,10 @@ extern BI_acl_attribute      ldbm_back_attribute;
 
 extern BI_operational  ldbm_back_operational;
 
+#ifdef SLAP_X_FILTER_HASSUBORDINATES
+extern BI_has_subordinates     ldbm_back_hasSubordinates;
+#endif /* SLAP_X_FILTER_HASSUBORDINATES */
+
 /* hooks for slap tools */
 extern BI_tool_entry_open      ldbm_tool_entry_open;
 extern BI_tool_entry_close     ldbm_tool_entry_close;
index be55fac73c7de7d47d77186e5d3188493fb6bab5..327b0b79a99b1612b29fcc178405d6d200c0de87 100644 (file)
@@ -71,6 +71,9 @@ ldbm_back_initialize(
        bi->bi_acl_attribute = ldbm_back_attribute;
        bi->bi_chk_referrals = ldbm_back_referrals;
        bi->bi_operational = ldbm_back_operational;
+#ifdef SLAP_X_FILTER_HASSUBORDINATES
+       bi->bi_has_subordinates = ldbm_back_hasSubordinates;
+#endif /* SLAP_X_FILTER_HASSUBORDINATES */
 
        /*
         * hooks for slap tools
index 51c0fb710f7e85a47a26a9d8bbbabfe16807a017..bc68116c281c2e2a726ea26492546fdf5aa47cfc 100644 (file)
 #include "proto-back-ldbm.h"
 
 /*
- * sets the supported operational attributes (if required)
+ * sets *hasSubordinates to LDAP_COMPARE_TRUE/LDAP_COMPARE_FALSE
+ * if the entry has children or not.
  */
+int
+ldbm_back_hasSubordinates(
+       BackendDB       *be,
+       Connection      *conn, 
+       Operation       *op,
+       Entry           *e,
+       int             *hasSubordinates )
+{
+       if ( has_children( be, e ) ) {
+               *hasSubordinates = LDAP_COMPARE_TRUE;
 
+       } else {
+               *hasSubordinates = LDAP_COMPARE_FALSE;
+       }
+
+       return 0;
+}
+
+/*
+ * sets the supported operational attributes (if required)
+ */
 int
 ldbm_back_operational(
        BackendDB       *be,
index eac5f831e9cc125a7bba4b4bb83afe27462ce404..1d41140078e5d8ea107e6be99b22680834de4890 100644 (file)
@@ -57,10 +57,6 @@ ldbm_back_search(
        struct slap_limits_set *limit = NULL;
        int isroot = 0;
                
-#ifdef SLAP_X_FILTER_HASSUBORDINATES
-       int             filter_hasSubordinates = 0;
-#endif /* SLAP_X_FILTER_HASSUBORDINATES */
-
 #ifdef NEW_LOGGING
        LDAP_LOG( BACK_LDBM, ENTRY, "ldbm_back_search: enter\n", 0, 0, 0 );
 #else
@@ -292,22 +288,11 @@ searchit:
        /* compute it anyway; root does not use it */
        stoptime = op->o_time + tlimit;
 
-#ifdef SLAP_X_FILTER_HASSUBORDINATES
-       /*
-        * is hasSubordinates used in the filter ?
-        * FIXME: we may compute this directly when parsing the filter
-        */
-       filter_hasSubordinates = filter_has_subordinates( filter );
-#endif /* SLAP_X_FILTER_HASSUBORDINATES */
-
        for ( id = idl_firstid( candidates, &cursor ); id != NOID;
            id = idl_nextid( candidates, &cursor ) )
        {
                int scopeok = 0;
                int result = 0;
-#ifdef SLAP_X_FILTER_HASSUBORDINATES
-               Attribute       *hasSubordinates = NULL;
-#endif /* SLAP_X_FILTER_HASSUBORDINATES */
 
                /* check for abandon */
                if ( op->o_abandon ) {
@@ -436,43 +421,9 @@ searchit:
                        goto loop_continue;
                }
 
-#ifdef SLAP_X_FILTER_HASSUBORDINATES
-               /*
-                * if hasSubordinates is used in the filter,
-                * append it to the entry's attributes
-                */
-               if ( filter_hasSubordinates ) {
-                       int     hs;
-
-                       hs = has_children( be, e );
-                       hasSubordinates = slap_operational_hasSubordinate( hs );
-                       if ( hasSubordinates == NULL ) {
-                               goto loop_continue;
-                       }
-
-                       hasSubordinates->a_next = e->e_attrs;
-                       e->e_attrs = hasSubordinates;
-               }
-#endif /* SLAP_X_FILTER_HASSUBORDINATES */
-
                /* if it matches the filter and scope, send it */
                result = test_filter( be, conn, op, e, filter );
 
-#ifdef SLAP_X_FILTER_HASSUBORDINATES
-               if ( hasSubordinates ) {
-                       /*
-                        * FIXME: this is fairly inefficient, because 
-                        * if hasSubordinates is among the required
-                        * attrs, it will be added again later;
-                        * maybe we should leave it and check
-                        * check later if it's already present,
-                        * if required
-                        */
-                       e->e_attrs = e->e_attrs->a_next;
-                       attr_free( hasSubordinates );
-               }
-#endif /* SLAP_X_FILTER_HASSUBORDINATES */
-
                if ( result == LDAP_COMPARE_TRUE ) {
                        struct berval   dn;
 
index 0032f2ffdf329e0c856bb522ef18f963791b7ecc..77428ea18c05543a73edd73efe337bebb2596e13 100644 (file)
@@ -399,7 +399,7 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f )
                 */
                backsql_strfcat( &bsi->flt_where, &bsi->fwhere_len, "l",
                                (ber_len_t)sizeof( "1=1" ) - 1, "1=1" );
-               if ( ad != NULL ) {
+               if ( ad == slap_schema.si_ad_hasSubordinates ) {
                        /*
                         * We use this flag since we need to parse
                         * the filter anyway; we should have used
@@ -407,6 +407,7 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f )
                         * filter_has_subordinates()
                         */
                        bsi->bsi_flags |= BSQL_SF_FILTER_HASSUBORDINATE;
+
                } else {
                        /*
                         * clear attributes to fetch, to require ALL
index 82cd8cd327609843b92086015f996087657a0c5b..eee672a9b958d47df2b025abe7d2ac51d48f4c8c 100644 (file)
@@ -460,6 +460,41 @@ test_ava_filter(
                }
        }
 
+#ifdef SLAP_X_FILTER_HASSUBORDINATES
+       if ( ava->aa_desc == slap_schema.si_ad_hasSubordinates 
+                       && be && be->be_has_subordinates ) {
+               int             hasSubordinates;
+               struct berval   hs;
+
+               /*
+                * No other match should be allowed ...
+                */
+               assert( type == LDAP_FILTER_EQUALITY );
+               
+               if ( (*be->be_has_subordinates)( be, conn, op, e, &hasSubordinates ) ) {
+                       return LDAP_OTHER;
+               }
+
+               if ( hasSubordinates == LDAP_COMPARE_TRUE ) {
+                       hs.bv_val = "TRUE";
+                       hs.bv_len = sizeof( "TRUE" ) - 1;
+
+               } else if ( hasSubordinates == LDAP_COMPARE_FALSE ) {
+                       hs.bv_val = "FALSE";
+                       hs.bv_len = sizeof( "FALSE" ) - 1;
+
+               } else {
+                       return LDAP_OTHER;
+               }
+
+               if ( bvmatch( &ava->aa_value, &hs ) ) {
+                       return LDAP_COMPARE_TRUE;
+               }
+
+               return LDAP_COMPARE_FALSE;
+       }
+#endif /* SLAP_X_FILTER_HASSUBORDINATES */
+
        return( LDAP_COMPARE_FALSE );
 }
 
@@ -473,13 +508,33 @@ test_presence_filter(
        AttributeDescription *desc
 )
 {
+       Attribute       *a;
+
        if ( !access_allowed( be, conn, op, e, desc, NULL, ACL_SEARCH, NULL ) )
        {
                return LDAP_INSUFFICIENT_ACCESS;
        }
 
-       return attrs_find( e->e_attrs, desc ) != NULL
-               ? LDAP_COMPARE_TRUE : LDAP_COMPARE_FALSE;
+       a = attrs_find( e->e_attrs, desc );
+
+#ifdef SLAP_X_FILTER_HASSUBORDINATES
+       if ( a == NULL && desc == slap_schema.si_ad_hasSubordinates ) {
+
+               /*
+                * XXX: fairly optimistic: if the function is defined,
+                * then PRESENCE must succeed, because hasSubordinate
+                * is boolean-valued; I think we may live with this 
+                * simplification by now
+                */
+               if ( be && be->be_has_subordinates ) {
+                       return LDAP_COMPARE_TRUE;
+               }
+
+               return LDAP_COMPARE_FALSE;
+       }
+#endif /* SLAP_X_FILTER_HASSUBORDINATES */
+
+       return a != NULL ? LDAP_COMPARE_TRUE : LDAP_COMPARE_FALSE;
 }
 
 
index 51dec17aea3e616fb4663bdebafc49d3cda3a55b..3d2bd8065fe6586802343584db1aa0e1680cc66e 100644 (file)
@@ -485,6 +485,8 @@ LDAP_SLAPD_F (void) vrFilter2bv LDAP_P(( ValuesReturnFilter *f, struct berval *f
 
 /*
  * define to honor hasSubordinates operational attribute in search filters
+ * (in previous use there was a flaw with back-bdb and back-ldbm; now it 
+ * is fixed).
  */
 #undef SLAP_X_FILTER_HASSUBORDINATES
 
index bb611b8fc88e4b46b510aaba2365aee8b2739620..e3cb7d55e609786679633826796f8f9e2224d4a5 100644 (file)
@@ -1206,6 +1206,9 @@ struct slap_backend_db {
 #define                be_group        bd_info->bi_acl_group
 #define                be_attribute    bd_info->bi_acl_attribute
 #define                be_operational  bd_info->bi_operational
+#ifdef SLAP_X_FILTER_HASSUBORDINATES
+#define                be_has_subordinates bd_info->bi_has_subordinates
+#endif /* SLAP_X_FILTER_HASSUBORDINATES */
 
 #define                be_controls     bd_info->bi_controls
 
@@ -1406,6 +1409,12 @@ typedef int (BI_operational)  LDAP_P((Backend *bd,
                struct slap_conn *c, struct slap_op *o,
                Entry *e, AttributeName *attrs, int opattrs, Attribute **a ));
 
+#ifdef SLAP_X_FILTER_HASSUBORDINATES
+typedef int (BI_has_subordinates) LDAP_P((Backend *bd,
+               struct slap_conn *c, struct slap_op *o,
+               Entry *e, int *has_subordinates ));
+#endif /* SLAP_X_FILTER_HASSUBORDINATES */
+
 typedef int (BI_connection_init) LDAP_P((BackendDB *bd,
                struct slap_conn *c));
 typedef int (BI_connection_destroy) LDAP_P((BackendDB *bd,
@@ -1499,6 +1508,9 @@ struct slap_backend_info {
        BI_acl_attribute        *bi_acl_attribute;
 
        BI_operational  *bi_operational;
+#ifdef SLAP_X_FILTER_HASSUBORDINATES
+       BI_has_subordinates     *bi_has_subordinates;
+#endif /* SLAP_X_FILTER_HASSUBORDINATES */
 
        BI_connection_init      *bi_connection_init;
        BI_connection_destroy   *bi_connection_destroy;