]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/back-bdb/search.c
Last changes should have been #ifdef
[openldap] / servers / slapd / back-bdb / search.c
index a4687be4018f90cacbca8e3f4b0d8329a683aeac..20e44d0ebddcf4317ee203a8e3d55066e1cf8518 100644 (file)
 #include <ac/string.h>
 
 #include "back-bdb.h"
+#include "idl.h"
 #include "external.h"
 
 static int base_candidate(
-    BackendDB  *be,
+       BackendDB       *be,
        Entry   *e,
        ID              *ids );
 static int search_candidates(
        BackendDB *be,
        Entry *e,
        Filter *filter,
-    int scope,
+       int scope,
        int deref,
        int manageDSAit,
        ID      *ids );
 
-static ID idl_first( ID *ids, ID *cursor );
-static ID idl_next( ID *ids, ID *cursor );
-
 int
 bdb_search(
-    BackendDB  *be,
-    Connection *conn,
-    Operation  *op,
-    const char *base,
-    const char *nbase,
-    int                scope,
-    int                deref,
-    int                slimit,
-    int                tlimit,
-    Filter     *filter,
-    const char *filterstr,
-    char       **attrs,
-    int                attrsonly )
+       BackendDB       *be,
+       Connection      *conn,
+       Operation       *op,
+       const char      *base,
+       const char      *nbase,
+       int             scope,
+       int             deref,
+       int             slimit,
+       int             tlimit,
+       Filter  *filter,
+       const char      *filterstr,
+       char    **attrs,
+       int             attrsonly )
 {
        struct bdb_info *bdb = (struct bdb_info *) be->be_private;
        int              abandon;
@@ -72,8 +70,7 @@ bdb_search(
        } else
 #endif
        {
-               /* obtain entry */
-               rc = dn2entry_r( be, NULL, nbase, &e, &matched );
+               rc = bdb_dn2entry( be, NULL, nbase, &e, &matched, 0 );
        }
 
        switch(rc) {
@@ -82,7 +79,7 @@ bdb_search(
                break;
        default:
                send_ldap_result( conn, op, rc=LDAP_OTHER,
-                   NULL, "internal error", NULL, NULL );
+                       NULL, "internal error", NULL, NULL );
                return rc;
        }
 
@@ -108,6 +105,7 @@ bdb_search(
                        ber_bvecfree( refs );
                        free( matched_dn );
                        bdb_entry_return( be, matched );
+                       matched = NULL;
                }
 
                return rc;
@@ -120,12 +118,13 @@ bdb_search(
                        conn, op, e );
 
                bdb_entry_return( be, e );
+               e = NULL;
 
                Debug( LDAP_DEBUG_TRACE, "bdb_search: entry is referral\n",
                        0, 0, 0 );
 
                send_ldap_result( conn, op, LDAP_REFERRAL,
-                   matched_dn, NULL, refs, NULL );
+                       matched_dn, NULL, refs, NULL );
 
                ber_bvecfree( refs );
                free( matched_dn );
@@ -137,7 +136,7 @@ bdb_search(
                tlimit = -1;    /* allow root to set no limit */
        } else {
                tlimit = (tlimit > be->be_timelimit || tlimit < 1) ?
-                   be->be_timelimit : tlimit;
+                       be->be_timelimit : tlimit;
                stoptime = op->o_time + tlimit;
        }
 
@@ -145,7 +144,7 @@ bdb_search(
                slimit = -1;    /* allow root to set no limit */
        } else {
                slimit = (slimit > be->be_sizelimit || slimit < 1) ?
-                   be->be_sizelimit : slimit;
+                       be->be_sizelimit : slimit;
        }
 
        if ( scope == LDAP_SCOPE_BASE ) {
@@ -153,7 +152,7 @@ bdb_search(
 
        } else {
                rc = search_candidates( be, e, filter,
-                   scope, deref, manageDSAit, candidates );
+                       scope, deref, manageDSAit, candidates );
        }
 
        /* need normalized dn below */
@@ -163,6 +162,7 @@ bdb_search(
        cursor = e->e_id;
 
        bdb_entry_return( be, e );
+       e = NULL;
 
        if ( candidates[0] == 0 ) {
                Debug( LDAP_DEBUG_TRACE, "bdb_search: no candidates\n",
@@ -176,9 +176,9 @@ bdb_search(
                goto done;
        }
 
-       for ( id = idl_first( candidates, &cursor );
+       for ( id = bdb_idl_first( candidates, &cursor );
                id != NOID;
-           id = idl_next( candidates, &cursor ) )
+               id = bdb_idl_next( candidates, &cursor ) )
        {
                int             scopeok = 0;
 
@@ -203,9 +203,12 @@ bdb_search(
                rc = bdb_id2entry( be, NULL, id, &e );
 
                if ( e == NULL ) {
-                       Debug( LDAP_DEBUG_TRACE,
-                               "bdb_search: candidate %ld not found\n",
-                               id, 0, 0 );
+                       if( !BDB_IDL_IS_RANGE(candidates) ) {
+                               /* only complain for non-range IDLs */
+                               Debug( LDAP_DEBUG_TRACE,
+                                       "bdb_search: candidate %ld not found\n",
+                                       id, 0, 0 );
+                       }
 
                        goto loop_continue;
                }
@@ -301,6 +304,7 @@ bdb_search(
                                /* check size limit */
                                if ( --slimit == -1 ) {
                                        bdb_entry_return( be, e );
+                                       e = NULL;
                                        send_search_result( conn, op,
                                                rc = LDAP_SIZELIMIT_EXCEEDED, NULL, NULL,
                                                v2refs, NULL, nentries );
@@ -319,6 +323,7 @@ bdb_search(
                                                break;
                                        case -1:        /* connection closed */
                                                bdb_entry_return( be, e );
+                                               e = NULL;
                                                rc = LDAP_OTHER;
                                                goto done;
                                        }
@@ -357,7 +362,7 @@ done:
 
 
 static int base_candidate(
-    BackendDB  *be,
+       BackendDB       *be,
        Entry   *e,
        ID              *ids )
 {
@@ -373,56 +378,77 @@ static int search_candidates(
        BackendDB *be,
        Entry *e,
        Filter *filter,
-    int scope,
+       int scope,
        int deref,
        int manageDSAit,
        ID      *ids )
 {
-       Debug(LDAP_DEBUG_TRACE, "subtree_candidates: base: \"%s\" (0x%08lx)\n",
-               e->e_dn, (long) e->e_id, 0);
-
-       ids[0] = NOID;
-       return 0;
-}
-
-static ID idl_first( ID *ids, ID *cursor )
-{
-       ID pos;
+       int rc;
+       Filter          f, fand, rf, xf;
+       AttributeAssertion aa_ref;
+       struct bdb_info *bdb = (struct bdb_info *) be->be_private;
+#ifdef BDB_ALIASES
+       Filter  af;
+       AttributeAssertion aa_alias;
+#endif
 
-       if ( ids[0] == 0 ) {
-               *cursor = NOID;
-               return NOID;
+       Debug(LDAP_DEBUG_TRACE,
+               "search_candidates: base=\"%s\" (0x%08lx) scope=%d\n",
+               e->e_dn, (long) e->e_id, scope );
+
+       xf.f_or = filter;
+       xf.f_choice = LDAP_FILTER_OR;
+       xf.f_next = NULL;
+
+       if( !manageDSAit ) {
+               /* match referrals */
+               static struct berval bv_ref = { sizeof("REFERRAL")-1, "REFERRAL" };
+               rf.f_choice = LDAP_FILTER_EQUALITY;
+               rf.f_ava = &aa_ref;
+               rf.f_av_desc = slap_schema.si_ad_objectClass;
+               rf.f_av_value = &bv_ref;
+               rf.f_next = xf.f_or;
+               xf.f_or = &rf;
        }
 
-       if ( BDB_IS_ALLIDS( ids ) ) {
-               /* XXYYZ: quick hack for testing */
-               ids[1] = 100;
-               return *cursor;
+#ifdef BDB_ALIASES
+       if( deref & LDAP_DEREF_SEARCHING ) {
+               /* match aliases */
+               static struct berval bv_alias = { sizeof("ALIAS")-1, "ALIAS" };
+               af.f_choice = LDAP_FILTER_EQUALITY;
+               af.f_ava = &aa_alias;
+               af.f_av_desc = slap_schema.si_ad_objectClass;
+               af.f_av_value = &bv_alias;
+               af.f_next = xf.f_or;
+               xf.f_or = &af;
        }
+#endif
 
-       pos = bdb_idl_search( ids, *cursor );
+       f.f_next = NULL;
+       f.f_choice = LDAP_FILTER_AND;
+       f.f_and = &fand;
+       fand.f_choice = scope == LDAP_SCOPE_SUBTREE
+               ? SLAPD_FILTER_DN_SUBTREE
+               : SLAPD_FILTER_DN_ONE;
+       fand.f_dn = e->e_ndn;
+       fand.f_next = xf.f_or == filter ? filter : &xf ;
 
-       if( pos > ids[0] ) {
-               return NOID;
-       }
 
-       *cursor = pos;
-       return ids[pos];
-}
-
-static ID idl_next( ID *ids, ID *cursor )
-{
-       if ( BDB_IS_ALLIDS( ids ) ) {
-               if( ++(*cursor) <= ids[1] ) {
-                       return *cursor;
-               }
-               return NOID;
+#ifdef BDB_FILTER_INDICES
+       {
+               ID range[3];
+               BDB_IDL_ID( bdb, range, e->e_id );
+               rc = bdb_filter_candidates( be, range, &f, ids );
        }
+#else
+       BDB_IDL_ID( bdb, ids, e->e_id );
+       rc = 0;
+#endif
 
-       if ( *cursor < ids[0] ) {
-               return ids[(*cursor)++];
-       }
+       Debug(LDAP_DEBUG_TRACE,
+               "search_candidates: id=%ld first=%ld last=%ld\n",
+               ids[0], ids[1],
+               BDB_IDL_IS_RANGE( ids ) ? ids[2] : ids[ids[0]] );
 
-       return NOID;
+       return rc;
 }
-