]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/back-ldbm/search.c
Import minor trace output cleanup
[openldap] / servers / slapd / back-ldbm / search.c
index 6a53be4f112485ab38b91886aafa8f2f438d941c..438397f441d8dfb5dd3095036c39c350842bdd02 100644 (file)
@@ -1,27 +1,19 @@
 /* search.c - ldbm backend search function */
 
+#include "portable.h"
+
 #include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include "slap.h"
-#include "back-ldbm.h"
 
-extern time_t          currenttime;
-extern pthread_mutex_t currenttime_mutex;
+#include <ac/string.h>
+#include <ac/socket.h>
 
-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();
-extern char            *dn_parent();
+#include "slap.h"
+#include "back-ldbm.h"
+#include "proto-back-ldbm.h"
 
-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
 
@@ -61,6 +53,9 @@ ldbm_back_search(
        int             rmaxsize, nrefs;
        char            *rbuf, *rcur, *r;
        int             nentries = 0;
+       char            *realBase;
+
+       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 */
@@ -76,25 +71,47 @@ ldbm_back_search(
                    be->be_sizelimit : slimit;
        }
 
+       /*
+        * check and apply aliasing where the dereferencing applies to
+        * the subordinates of the base
+        */
+
+       switch ( deref ) {
+       case LDAP_DEREF_FINDING:
+       case LDAP_DEREF_ALWAYS:
+               realBase = derefDN ( be, conn, op, base );
+               break;
+       default:
+               realBase = ch_strdup(base);
+       }
+
+       (void) dn_normalize (realBase);
+
+       Debug( LDAP_DEBUG_TRACE, "using base \"%s\"\n",
+               realBase, 0, 0 );
+
        switch ( scope ) {
        case LDAP_SCOPE_BASE:
-               candidates = base_candidates( be, conn, op, base, filter,
+               candidates = base_candidates( be, conn, op, realBase, filter,
                    attrs, attrsonly, &matched, &err );
                break;
 
        case LDAP_SCOPE_ONELEVEL:
-               candidates = onelevel_candidates( be, conn, op, base, filter,
+               candidates = onelevel_candidates( be, conn, op, realBase, filter,
                    attrs, attrsonly, &matched, &err );
                break;
 
        case LDAP_SCOPE_SUBTREE:
-               candidates = subtree_candidates( be, conn, op, base, filter,
+               candidates = subtree_candidates( be, conn, op, realBase, filter,
                    attrs, attrsonly, &matched, NULL, &err, 1 );
                break;
 
        default:
                send_ldap_result( conn, op, LDAP_PROTOCOL_ERROR, "",
                    "Bad scope" );
+               if( realBase != NULL) {
+                       free( realBase );
+               }
                return( -1 );
        }
 
@@ -104,9 +121,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;
@@ -121,6 +145,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 );
@@ -135,14 +162,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 */
-               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 %lu not found\n",
+                              id, 0, 0 );
                        continue;
                }
 
@@ -151,22 +181,23 @@ 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 ( e->e_dn != NULL &&
+                       strncasecmp( e->e_dn, "ref=", 4 ) == 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 );
+                               Debug( LDAP_DEBUG_ANY, "null ref in (%s)\n", 
+                                       e->e_dn, 0, 0 );
                        } else {
                                for ( i = 0; ref->a_vals[i] != NULL; i++ ) {
                                        /* referral + newline + null */
                                        MAKE_SPACE( ref->a_vals[i]->bv_len + 2 );
                                        *rcur++ = '\n';
                                        strncpy( rcur, ref->a_vals[i]->bv_val,
-                                         ref->a_vals[i]->bv_len );
+                                               ref->a_vals[i]->bv_len );
                                        rcur = rcur + ref->a_vals[i]->bv_len;
                                        *rcur = '\0';
                                        nrefs++;
@@ -185,30 +216,49 @@ ldbm_back_search(
                                if ( scope == LDAP_SCOPE_ONELEVEL ) {
                                        if ( (dn = dn_parent( be, e->e_dn )) != NULL ) {
                                                (void) dn_normalize( dn );
-                                               scopeok = (dn == base) ? 1 : (! strcasecmp( dn, base ));
+                                               scopeok = (dn == realBase) ? 1 : (! strcasecmp( dn, realBase ));
                                        } else {
-                                               scopeok = (base == NULL || *base == '\0');
+                                               scopeok = (realBase == NULL || *realBase == '\0');
                                        }
                                        free( dn );
                                } else if ( scope == LDAP_SCOPE_SUBTREE ) {
-                                       dn = strdup( e->e_dn );
+                                       dn = ch_strdup( e->e_dn );
                                        (void) dn_normalize( dn );
-                                       scopeok = dn_issuffix( dn, base );
+                                       scopeok = dn_issuffix( dn, realBase );
                                        free( dn );
                                }
 
                                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 );
                                                idl_free( candidates );
                                                free( rbuf );
+
+                                               if( realBase != NULL) {
+                                                       free( realBase );
+                                               }
                                                return( 0 );
                                        }
 
+                                       /*
+                                        * check and apply aliasing where the dereferencing applies to
+                                        * the subordinates of the base
+                                        */
+                                       switch ( deref ) {
+                                       case LDAP_DEREF_SEARCHING:
+                                       case LDAP_DEREF_ALWAYS:
+                                               {
+                                                       Entry *newe = derefAlias_r( be, conn, op, e );
+                                                       cache_return_entry_r( &li->li_cache, e );
+                                                       e = newe;
+                                               }
+                                               break;
+                                       }
+
                                        switch ( send_search_entry( be, conn, op, e,
                                                attrs, attrsonly ) ) {
                                        case 0:         /* entry sent ok */
@@ -217,16 +267,23 @@ 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 );
+
+                                               if( realBase != NULL) {
+                                                       free( realBase );
+                                               }
                                                return( 0 );
                                        }
                                }
                        }
                }
 
-               cache_return_entry( &li->li_cache, e );
+               if( e != NULL ) {
+                       /* free reader lock */
+                       cache_return_entry_r( &li->li_cache, e );
+               }
 
                pthread_yield();
        }
@@ -240,6 +297,10 @@ ldbm_back_search(
        }
        free( rbuf );
 
+       if( realBase != NULL) {
+               free( realBase );
+       }
+
        return( 0 );
 }
 
@@ -262,16 +323,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 +364,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 );
        }
@@ -315,9 +387,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;
 
@@ -329,6 +401,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 );
 }
 
@@ -348,9 +422,12 @@ 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\" %s\n",
+               base ? base : "NULL", lookupbase ? "lookupbase" : "", 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,21 +442,28 @@ 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" );
-               f->f_or->f_next = filter;
+               f->f_or->f_avtype = ch_strdup( "objectclass" );
+               /* Patch to use normalized uppercase */
+               f->f_or->f_avvalue.bv_val = ch_strdup( "REFERRAL" );
+               f->f_or->f_avvalue.bv_len = strlen( "REFERRAL" );
+               filterarg_ptr = &f->f_or->f_next;
+               *filterarg_ptr = filter;
                filter = f;
 
                if ( ! be_issuffix( be, base ) ) {
@@ -388,10 +472,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;
@@ -402,13 +486,9 @@ 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 );
        }
 
-       if ( e != NULL ) {
-               cache_return_entry( &li->li_cache, e );
-       }
-
        return( candidates );
 }