X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fback-ldbm%2Fsearch.c;h=19dafe4c017680d060d5da3af5f0a0d04d1c0c77;hb=76ed17f7942d4e3810fa90b46143e615af311167;hp=6a53be4f112485ab38b91886aafa8f2f438d941c;hpb=58ea169c92679eb5b0598c2420c95c626ccac27d;p=openldap diff --git a/servers/slapd/back-ldbm/search.c b/servers/slapd/back-ldbm/search.c index 6a53be4f11..19dafe4c01 100644 --- a/servers/slapd/back-ldbm/search.c +++ b/servers/slapd/back-ldbm/search.c @@ -6,14 +6,12 @@ #include #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( ¤ttime_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 ); }