]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/back-ldbm/search.c
Merge in latest from -current.
[openldap] / servers / slapd / back-ldbm / search.c
index 6a53be4f112485ab38b91886aafa8f2f438d941c..19dafe4c017680d060d5da3af5f0a0d04d1c0c77 100644 (file)
@@ -6,14 +6,12 @@
 #include <sys/socket.h>
 #include "slap.h"
 #include "back-ldbm.h"
+#include "proto-back-ldbm.h"
 
 extern time_t          currenttime;
 extern pthread_mutex_t currenttime_mutex;
 
-extern ID              dn2id();
 extern IDList          *idl_alloc();
-extern Entry           *id2entry();
-extern Entry           *dn2entry();
 extern Attribute       *attr_find();
 extern IDList          *filter_candidates();
 extern char            *ch_realloc();
@@ -62,6 +60,8 @@ ldbm_back_search(
        char            *rbuf, *rcur, *r;
        int             nentries = 0;
 
+       Debug(LDAP_DEBUG_ARGS, "=> ldbm_back_search\n", 0, 0, 0);
+
        if ( tlimit == 0 && be_isroot( be, op->o_dn ) ) {
                tlimit = -1;    /* allow root to set no limit */
        } else {
@@ -139,10 +139,9 @@ ldbm_back_search(
                }
                pthread_mutex_unlock( &currenttime_mutex );
 
-               /* get the entry */
-               if ( (e = id2entry( be, id )) == NULL ) {
-                       Debug( LDAP_DEBUG_ARGS, "candidate %d not found\n", id,
-                           0, 0 );
+               /* 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 );
                        continue;
                }
 
@@ -152,14 +151,14 @@ ldbm_back_search(
                 * 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 )
+                       == 0 && (ref = attr_find( e->e_attrs, "ref" )) != NULL &&
+                       scope == LDAP_SCOPE_SUBTREE )
                {
                        int     i, len;
 
                        if ( ref->a_vals == NULL ) {
                                Debug( LDAP_DEBUG_ANY, "null ref in (%s)\n", 0,
-                                   0, 0 );
+                                       0, 0 );
                        } else {
                                for ( i = 0; ref->a_vals[i] != NULL; i++ ) {
                                        /* referral + newline + null */
@@ -200,7 +199,7 @@ ldbm_back_search(
                                if ( scopeok ) {
                                        /* check size limit */
                                        if ( --slimit == -1 ) {
-                                               cache_return_entry( &li->li_cache, e );
+                                               cache_return_entry_r( &li->li_cache, e );
                                                send_ldap_search_result( conn, op,
                                                        LDAP_SIZELIMIT_EXCEEDED, NULL,
                                                        nrefs > 0 ? rbuf : NULL, nentries );
@@ -217,7 +216,7 @@ ldbm_back_search(
                                        case 1:         /* entry not sent */
                                                break;
                                        case -1:        /* connection closed */
-                                               cache_return_entry( &li->li_cache, e );
+                                               cache_return_entry_r( &li->li_cache, e );
                                                idl_free( candidates );
                                                free( rbuf );
                                                return( 0 );
@@ -226,7 +225,10 @@ ldbm_back_search(
                        }
                }
 
-               cache_return_entry( &li->li_cache, e );
+               if( e == NULL ) {
+                       /* free reader lock */
+                       cache_return_entry_r( &li->li_cache, e );
+               }
 
                pthread_yield();
        }
@@ -262,16 +264,24 @@ base_candidates(
        IDList          *idl;
        Entry           *e;
 
+       Debug(LDAP_DEBUG_TRACE, "base_candidates: base: %s\n", base, 0, 0);
+
        *err = LDAP_SUCCESS;
-       if ( (e = dn2entry( be, base, matched )) == NULL ) {
+
+       /* get entry with reader lock */
+       if ( (e = dn2entry_r( be, base, matched )) == NULL ) {
                *err = LDAP_NO_SUCH_OBJECT;
                return( NULL );
        }
 
+       /* check for deleted */
+
        idl = idl_alloc( 1 );
        idl_insert( &idl, e->e_id, 1 );
 
-       cache_return_entry( &li->li_cache, e );
+
+       /* free reader lock */
+       cache_return_entry_r( &li->li_cache, e );
 
        return( idl );
 }
@@ -295,11 +305,14 @@ onelevel_candidates(
        char            buf[20];
        IDList          *candidates;
 
+       Debug(LDAP_DEBUG_TRACE, "onelevel_candidates: base: %s\n", base, 0, 0);
+
        *err = LDAP_SUCCESS;
        e = NULL;
-       /* get the base object */
-       if ( base != NULL && *base != '\0' && (e = dn2entry( be, base,
-           matched )) == NULL ) {
+       /* get the base object with reader lock */
+       if ( base != NULL && *base != '\0' &&
+               (e = dn2entry_r( be, base, matched )) == NULL )
+       {
                *err = LDAP_NO_SUCH_OBJECT;
                return( NULL );
        }
@@ -329,6 +342,8 @@ onelevel_candidates(
        f->f_and->f_next = NULL;
        filter_free( f );
 
+       /* free entry and reader lock */
+       cache_return_entry_r( &li->li_cache, e );
        return( candidates );
 }
 
@@ -351,6 +366,9 @@ subtree_candidates(
        Filter          *f;
        IDList          *candidates;
 
+       Debug(LDAP_DEBUG_TRACE, "subtree_candidates: base: %s\n",
+               base ? base : "NULL", 0, 0);
+
        /*
         * get the base object - unless we already have it (from one-level).
         * also, unless this is a one-level search or a subtree search
@@ -365,20 +383,26 @@ subtree_candidates(
        *err = LDAP_SUCCESS;
        f = NULL;
        if ( lookupbase ) {
-               if ( base != NULL && *base != '\0' && (e = dn2entry( be, base,
-                   matched )) == NULL ) {
+               if ( base != NULL && *base != '\0' &&
+                       (e = dn2entry_r( be, base, matched )) == NULL )
+               {
                        *err = LDAP_NO_SUCH_OBJECT;
                        return( NULL );
                }
 
+               if (e) {
+                       cache_return_entry_r( &li->li_cache, e );
+               }
+
                f = (Filter *) ch_malloc( sizeof(Filter) );
                f->f_next = NULL;
                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_avvalue.bv_val = strdup( "referral" );
-               f->f_or->f_avvalue.bv_len = strlen( "referral" );
+               /* Patch to use normalized uppercase */
+               f->f_or->f_avvalue.bv_val = strdup( "REFERRAL" );
+               f->f_or->f_avvalue.bv_len = strlen( "REFERRAL" );
                f->f_or->f_next = filter;
                filter = f;
 
@@ -406,9 +430,5 @@ subtree_candidates(
                filter_free( f );
        }
 
-       if ( e != NULL ) {
-               cache_return_entry( &li->li_cache, e );
-       }
-
        return( candidates );
 }