]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/back-ldbm/search.c
Import resetting of c_dn/c_cdn after anonymous bind.
[openldap] / servers / slapd / back-ldbm / search.c
index 2ec7b0902bc6e579255ed698ecabd7d1e6c04649..6b6d62adab70818bb93c8f00d9a8408fa2e0121a 100644 (file)
 #include "back-ldbm.h"
 #include "proto-back-ldbm.h"
 
-extern time_t          currenttime;
-extern pthread_mutex_t currenttime_mutex;
-
-extern IDList          *idl_alloc();
-extern Attribute       *attr_find();
-extern IDList          *filter_candidates();
-extern char            *ch_realloc();
-extern char            *dn_parent();
-
-static IDList  *base_candidates();
-static IDList  *onelevel_candidates();
-static IDList  *subtree_candidates();
+static IDList  *base_candidates(Backend *be, Connection *conn, Operation *op, char *base, Filter *filter, char **attrs, int attrsonly, char **matched, int *err);
+static IDList  *onelevel_candidates(Backend *be, Connection *conn, Operation *op, char *base, Filter *filter, char **attrs, int attrsonly, char **matched, int *err);
+static IDList  *subtree_candidates(Backend *be, Connection *conn, Operation *op, char *base, Filter *filter, char **attrs, int attrsonly, char **matched, Entry *e, int *err, int lookupbase);
 
 #define GRABSIZE       BUFSIZ
 
@@ -66,14 +57,14 @@ ldbm_back_search(
 
        Debug(LDAP_DEBUG_ARGS, "=> ldbm_back_search\n", 0, 0, 0);
 
-       if ( tlimit == 0 && be_isroot( be, op->o_dn ) ) {
+       if ( tlimit == 0 && be_isroot( be, op->o_ndn ) ) {
                tlimit = -1;    /* allow root to set no limit */
        } else {
                tlimit = (tlimit > be->be_timelimit || tlimit < 1) ?
                    be->be_timelimit : tlimit;
                stoptime = op->o_time + tlimit;
        }
-       if ( slimit == 0 && be_isroot( be, op->o_dn ) ) {
+       if ( slimit == 0 && be_isroot( be, op->o_ndn ) ) {
                slimit = -1;    /* allow root to set no limit */
        } else {
                slimit = (slimit > be->be_sizelimit || slimit < 1) ?
@@ -84,18 +75,23 @@ ldbm_back_search(
         * check and apply aliasing where the dereferencing applies to
         * the subordinates of the base
         */
-       realBase = strdup (base);
+
+#ifdef SLAPD_ALIAS_DEREF
        switch ( deref ) {
        case LDAP_DEREF_FINDING:
        case LDAP_DEREF_ALWAYS:
-               free (realBase);
                realBase = derefDN ( be, conn, op, base );
                break;
+       default:
+               realBase = ch_strdup(base);
        }
+#else
+               realBase = ch_strdup(base);
+#endif
 
-       (void) dn_normalize (realBase);
+       (void) dn_normalize_case( realBase );
 
-       Debug( LDAP_DEBUG_TRACE, "using base %s\n",
+       Debug( LDAP_DEBUG_TRACE, "using base \"%s\"\n",
                realBase, 0, 0 );
 
        switch ( scope ) {
@@ -117,6 +113,9 @@ ldbm_back_search(
        default:
                send_ldap_result( conn, op, LDAP_PROTOCOL_ERROR, "",
                    "Bad scope" );
+               if( realBase != NULL) {
+                       free( realBase );
+               }
                return( -1 );
        }
 
@@ -126,9 +125,16 @@ ldbm_back_search(
                if ( matched != NULL ) {
                        free( matched );
                }
+               if( realBase != NULL) {
+                       free( realBase );
+               }
                return( -1 );
        }
 
+       if ( matched != NULL ) {
+               free( matched );
+       }
+
        rmaxsize = 0;
        nrefs = 0;
        rbuf = rcur = NULL;
@@ -143,6 +149,9 @@ ldbm_back_search(
                        pthread_mutex_unlock( &op->o_abandonmutex );
                        idl_free( candidates );
                        free( rbuf );
+                       if( realBase != NULL) {
+                               free( realBase );
+                       }
                        return( 0 );
                }
                pthread_mutex_unlock( &op->o_abandonmutex );
@@ -157,13 +166,17 @@ ldbm_back_search(
                            NULL, nentries );
                        idl_free( candidates );
                        free( rbuf );
+                       if( realBase != NULL) {
+                               free( realBase );
+                       }
                        return( 0 );
                }
                pthread_mutex_unlock( &currenttime_mutex );
 
                /* get the entry with reader lock */
                if ( (e = id2entry_r( be, id )) == NULL ) {
-                       Debug( LDAP_DEBUG_ARGS, "candidate %d not found\n", id, 0, 0 );
+                       Debug( LDAP_DEBUG_ARGS, "candidate %lu not found\n",
+                              id, 0, 0 );
                        continue;
                }
 
@@ -172,10 +185,10 @@ ldbm_back_search(
                 * this for subtree searches, and don't check the filter explicitly
                 * here since it's only a candidate anyway.
                 */
-               if ( e->e_dn != NULL &&
-                       strncasecmp( e->e_dn, "ref=", 4 ) == 0 &&
-                       (ref = attr_find( e->e_attrs, "ref" )) != NULL &&
-                       scope == LDAP_SCOPE_SUBTREE )
+               if ( scope == LDAP_SCOPE_SUBTREE &&
+                       e->e_ndn != NULL &&
+                       strncmp( e->e_ndn, "REF=", 4 ) == 0 &&
+                       (ref = attr_find( e->e_attrs, "ref" )) != NULL )
                {
                        int     i, len;
 
@@ -206,15 +219,16 @@ ldbm_back_search(
                                scopeok = 1;
                                if ( scope == LDAP_SCOPE_ONELEVEL ) {
                                        if ( (dn = dn_parent( be, e->e_dn )) != NULL ) {
-                                               (void) dn_normalize( dn );
-                                               scopeok = (dn == realBase) ? 1 : (! strcasecmp( dn, realBase ));
+                                               (void) dn_normalize_case( dn );
+                                               scopeok = (dn == realBase)
+                                                       ? 1
+                                                       : (strcmp( dn, realBase ) ? 0 : 1 );
+                                               free( dn );
                                        } else {
                                                scopeok = (realBase == NULL || *realBase == '\0');
                                        }
-                                       free( dn );
                                } else if ( scope == LDAP_SCOPE_SUBTREE ) {
-                                       dn = strdup( e->e_dn );
-                                       (void) dn_normalize( dn );
+                                       dn = ch_strdup( e->e_ndn );
                                        scopeok = dn_issuffix( dn, realBase );
                                        free( dn );
                                }
@@ -228,9 +242,14 @@ ldbm_back_search(
                                                        nrefs > 0 ? rbuf : NULL, nentries );
                                                idl_free( candidates );
                                                free( rbuf );
+
+                                               if( realBase != NULL) {
+                                                       free( realBase );
+                                               }
                                                return( 0 );
                                        }
 
+#ifdef SLAPD_ALIAS_DEREF
                                        /*
                                         * check and apply aliasing where the dereferencing applies to
                                         * the subordinates of the base
@@ -245,6 +264,7 @@ ldbm_back_search(
                                                }
                                                break;
                                        }
+#endif
 
                                        switch ( send_search_entry( be, conn, op, e,
                                                attrs, attrsonly ) ) {
@@ -257,6 +277,10 @@ ldbm_back_search(
                                                cache_return_entry_r( &li->li_cache, e );
                                                idl_free( candidates );
                                                free( rbuf );
+
+                                               if( realBase != NULL) {
+                                                       free( realBase );
+                                               }
                                                return( 0 );
                                        }
                                }
@@ -280,6 +304,10 @@ ldbm_back_search(
        }
        free( rbuf );
 
+       if( realBase != NULL) {
+               free( realBase );
+       }
+
        return( 0 );
 }
 
@@ -302,7 +330,7 @@ base_candidates(
        IDList          *idl;
        Entry           *e;
 
-       Debug(LDAP_DEBUG_TRACE, "base_candidates: base: %s\n", base, 0, 0);
+       Debug(LDAP_DEBUG_TRACE, "base_candidates: base: \"%s\"\n", base, 0, 0);
 
        *err = LDAP_SUCCESS;
 
@@ -338,15 +366,15 @@ onelevel_candidates(
 )
 {
        struct ldbminfo *li = (struct ldbminfo *) be->be_private;
-       Entry           *e;
+       Entry           *e = NULL;
        Filter          *f;
        char            buf[20];
        IDList          *candidates;
 
-       Debug(LDAP_DEBUG_TRACE, "onelevel_candidates: base: %s\n", base, 0, 0);
+       Debug(LDAP_DEBUG_TRACE, "onelevel_candidates: base: \"%s\"\n", base, 0, 0);
 
        *err = LDAP_SUCCESS;
-       e = NULL;
+
        /* get the base object with reader lock */
        if ( base != NULL && *base != '\0' &&
                (e = dn2entry_r( be, base, matched )) == NULL )
@@ -366,9 +394,9 @@ onelevel_candidates(
        f->f_choice = LDAP_FILTER_AND;
        f->f_and = (Filter *) ch_malloc( sizeof(Filter) );
        f->f_and->f_choice = LDAP_FILTER_EQUALITY;
-       f->f_and->f_ava.ava_type = strdup( "id2children" );
-       sprintf( buf, "%d", e != NULL ? e->e_id : 0 );
-       f->f_and->f_ava.ava_value.bv_val = strdup( buf );
+       f->f_and->f_ava.ava_type = ch_strdup( "id2children" );
+       sprintf( buf, "%ld", e != NULL ? e->e_id : 0 );
+       f->f_and->f_ava.ava_value.bv_val = ch_strdup( buf );
        f->f_and->f_ava.ava_value.bv_len = strlen( buf );
        f->f_and->f_next = filter;
 
@@ -381,7 +409,9 @@ onelevel_candidates(
        filter_free( f );
 
        /* free entry and reader lock */
-       cache_return_entry_r( &li->li_cache, e );
+       if( e != NULL ) {
+               cache_return_entry_r( &li->li_cache, e );
+       }
        return( candidates );
 }
 
@@ -401,11 +431,11 @@ subtree_candidates(
 )
 {
        struct ldbminfo *li = (struct ldbminfo *) be->be_private;
-       Filter          *f;
+       Filter          *f, **filterarg_ptr;
        IDList          *candidates;
 
-       Debug(LDAP_DEBUG_TRACE, "subtree_candidates: base: %s\n",
-               base ? base : "NULL", 0, 0);
+       Debug(LDAP_DEBUG_TRACE, "subtree_candidates: base: \"%s\" %s\n",
+               base ? base : "NULL", lookupbase ? "lookupbase" : "", 0);
 
        /*
         * get the base object - unless we already have it (from one-level).
@@ -421,6 +451,8 @@ subtree_candidates(
        *err = LDAP_SUCCESS;
        f = NULL;
        if ( lookupbase ) {
+               e = NULL;
+
                if ( base != NULL && *base != '\0' &&
                        (e = dn2entry_r( be, base, matched )) == NULL )
                {
@@ -437,11 +469,12 @@ subtree_candidates(
                f->f_choice = LDAP_FILTER_OR;
                f->f_or = (Filter *) ch_malloc( sizeof(Filter) );
                f->f_or->f_choice = LDAP_FILTER_EQUALITY;
-               f->f_or->f_avtype = strdup( "objectclass" );
+               f->f_or->f_avtype = ch_strdup( "objectclass" );
                /* Patch to use normalized uppercase */
-               f->f_or->f_avvalue.bv_val = strdup( "REFERRAL" );
+               f->f_or->f_avvalue.bv_val = ch_strdup( "REFERRAL" );
                f->f_or->f_avvalue.bv_len = strlen( "REFERRAL" );
-               f->f_or->f_next = filter;
+               filterarg_ptr = &f->f_or->f_next;
+               *filterarg_ptr = filter;
                filter = f;
 
                if ( ! be_issuffix( be, base ) ) {
@@ -450,10 +483,10 @@ subtree_candidates(
                        f->f_choice = LDAP_FILTER_AND;
                        f->f_and = (Filter *) ch_malloc( sizeof(Filter) );
                        f->f_and->f_choice = LDAP_FILTER_SUBSTRINGS;
-                       f->f_and->f_sub_type = strdup( "dn" );
+                       f->f_and->f_sub_type = ch_strdup( "dn" );
                        f->f_and->f_sub_initial = NULL;
                        f->f_and->f_sub_any = NULL;
-                       f->f_and->f_sub_final = strdup( base );
+                       f->f_and->f_sub_final = ch_strdup( base );
                        value_normalize( f->f_and->f_sub_final, SYNTAX_CIS );
                        f->f_and->f_next = filter;
                        filter = f;
@@ -464,7 +497,7 @@ subtree_candidates(
 
        /* free up just the parts we allocated above */
        if ( f != NULL ) {
-               f->f_and->f_next = NULL;
+               *filterarg_ptr = NULL;
                filter_free( f );
        }