From 4efa87ee13cc6a8a172b0ab67c641f2810e16d0f Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Wed, 14 Jul 1999 02:54:35 +0000 Subject: [PATCH] Fix transposed send_search_entry args. Toy with back-passwd/search scopes. --- servers/slapd/back-bdb2/search.c | 2 +- servers/slapd/back-ldap/search.c | 2 +- servers/slapd/back-ldbm/proto-back-ldbm.h | 18 +- servers/slapd/back-ldbm/search.c | 215 ++++++++++++---------- servers/slapd/back-passwd/search.c | 106 ++++++----- servers/slapd/back-perl/search.c | 2 +- servers/slapd/back-shell/result.c | 2 +- servers/slapd/back-tcl/tcl_util.c | 4 +- servers/slapd/proto-slap.h | 2 +- servers/slapd/result.c | 14 +- 10 files changed, 195 insertions(+), 172 deletions(-) diff --git a/servers/slapd/back-bdb2/search.c b/servers/slapd/back-bdb2/search.c index 77197e849e..86c4438c56 100644 --- a/servers/slapd/back-bdb2/search.c +++ b/servers/slapd/back-bdb2/search.c @@ -243,7 +243,7 @@ bdb2i_back_search_internal( if (e) { switch ( send_search_entry( be, conn, op, e, - attrs, attrsonly, 0 ) ) { + attrs, attrsonly, 0, NULL ) ) { case 0: /* entry sent ok */ nentries++; break; diff --git a/servers/slapd/back-ldap/search.c b/servers/slapd/back-ldap/search.c index d0a5cf688c..c742248c5e 100644 --- a/servers/slapd/back-ldap/search.c +++ b/servers/slapd/back-ldap/search.c @@ -159,7 +159,7 @@ ldap_send_entry( if (!attr->a_vals) attr->a_vals = &dummy; } - send_search_entry( be, lc->conn, op, &ent, attrs, attrsonly, NULL, 0 ); + send_search_entry( be, lc->conn, op, &ent, attrs, attrsonly, 0, NULL ); for (;ent.e_attrs;) { attr=ent.e_attrs; ent.e_attrs = attr->a_next; diff --git a/servers/slapd/back-ldbm/proto-back-ldbm.h b/servers/slapd/back-ldbm/proto-back-ldbm.h index 19da039055..2d48d36611 100644 --- a/servers/slapd/back-ldbm/proto-back-ldbm.h +++ b/servers/slapd/back-ldbm/proto-back-ldbm.h @@ -10,29 +10,15 @@ LDAP_BEGIN_DECL /* * alias.c */ -Entry *deref_alias_r LDAP_P(( - Backend *be, - Connection *conn, - Operation *op, - Entry *e )); - -char *deref_dn LDAP_P(( - Backend *be, - Connection *conn, - Operation *op, - char *dn )); - Entry *alias_dn2entry_r LDAP_P(( Backend *be, char *dn, Entry **matched, int *err )); -Entry *alias_id2entry_r LDAP_P(( +Entry *alias2entry_r LDAP_P(( Backend *be, - ID id, - Entry **matched, - int *err )); + Entry *e )); /* * attr.c diff --git a/servers/slapd/back-ldbm/search.c b/servers/slapd/back-ldbm/search.c index 8aae226f5a..c6e818908f 100644 --- a/servers/slapd/back-ldbm/search.c +++ b/servers/slapd/back-ldbm/search.c @@ -36,28 +36,24 @@ ldbm_back_search( ) { struct ldbminfo *li = (struct ldbminfo *) be->be_private; - int err; + int rc, err; time_t stoptime; ID_BLOCK *candidates; ID id; Entry *e; struct berval **v2refs = NULL; Entry *matched = NULL; - char *matched_dn = NULL; + char *realbase = NULL; int nentries = 0; int manageDSAit = get_manageDSAit( op ); Debug(LDAP_DEBUG_TRACE, "=> ldbm_back_search\n", 0, 0, 0); /* get entry with reader lock */ - switch ( deref ) { -#ifdef SLAPD_ALIASES - case LDAP_DEREF_FINDING: - case LDAP_DEREF_ALWAYS: + if ( deref & LDAP_DEREF_FINDING ) { e = alias_dn2entry_r( be, base, &matched, &err ); - break; -#endif - default: + + } else { e = dn2entry_r( be, base, &matched ); err = e != NULL ? LDAP_SUCCESS : LDAP_REFERRAL; } @@ -131,7 +127,7 @@ ldbm_back_search( } /* need normalized dn below */ - matched_dn = ch_strdup( e->e_ndn ); + realbase = ch_strdup( e->e_ndn ); cache_return_entry_r( &li->li_cache, e ); if ( candidates == NULL ) { @@ -143,133 +139,156 @@ ldbm_back_search( LDAP_SUCCESS, NULL, NULL, NULL, NULL, 0 ); - free( matched_dn ); - return 1; + rc = 1; } for ( id = idl_firstid( candidates ); id != NOID; - id = idl_nextid( candidates, id ) ) { + id = idl_nextid( candidates, id ) ) + { + int scopeok = 0; /* check for abandon */ ldap_pvt_thread_mutex_lock( &op->o_abandonmutex ); + if ( op->o_abandon ) { ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex ); - idl_free( candidates ); - ber_bvecfree( v2refs ); - free( matched_dn ); - return( 0 ); + rc = 0; + goto done; } + ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex ); /* check time limit */ if ( tlimit != -1 && slap_get_time() > stoptime ) { send_search_result( conn, op, LDAP_TIMELIMIT_EXCEEDED, NULL, NULL, v2refs, NULL, nentries ); - idl_free( candidates ); - ber_bvecfree( v2refs ); - free( matched_dn ); - return( 0 ); + rc = 0; + goto done; } /* get the entry with reader lock */ - switch ( deref ) { -#ifdef SLAPD_ALIASES - case LDAP_DEREF_SEARCHING: - case LDAP_DEREF_ALWAYS: - e = alias_id2entry_r( be, id, &matched, &err ); - break; -#endif - default: - e = id2entry_r( be, id ); - err = e != NULL ? LDAP_SUCCESS : LDAP_REFERRAL; - } + e = id2entry_r( be, id ); if ( e == NULL ) { - Debug( LDAP_DEBUG_ARGS, "candidate %ld not found\n", + Debug( LDAP_DEBUG_ARGS, "search: candidate %ld not found\n", id, 0, 0 ); - continue; + + goto loop_continue; + } + + if ( deref & LDAP_DEREF_SEARCHING && is_entry_alias( e ) ) { + Entry *newe; + + newe = alias2entry_r( be, e ); + + if( newe == NULL ) { + goto loop_continue; + } + + cache_return_entry_r( &li->li_cache, e ); + e = newe; + + /* need to skip alias which deref into scope */ + if( scope & LDAP_SCOPE_ONELEVEL ) { + char *pdn = dn_parent( NULL, e->e_ndn ); + if ( pdn != NULL ) { + if( strcmp( pdn, realbase ) ) { + free( pdn ); + goto loop_continue; + } + free(pdn); + } + + } else if ( dn_issuffix( e->e_ndn, realbase ) ) { + /* alias is within scope */ + Debug( LDAP_DEBUG_ARGS, "search: \"%s\" in subtree\n", + e->e_dn, 0, 0 ); + goto loop_continue; + } + + scopeok = 1; } /* * if it's a referral, add it to the list of referrals. only do - * this for subtree searches, and don't check the filter + * this for non-base searches, and don't check the filter * explicitly here since it's only a candidate anyway. */ if ( !manageDSAit && scope != LDAP_SCOPE_BASE && is_entry_referral( e ) ) { - struct berval **refs = get_entry_referrals( be, conn, op, e ); + struct berval **refs = get_entry_referrals( + be, conn, op, e ); send_search_reference( be, conn, op, - e, refs, NULL, &v2refs ); + e, refs, scope, NULL, &v2refs ); ber_bvecfree( refs ); - /* otherwise it's an entry - see if it matches the filter */ - } else { - /* if it matches the filter and scope, send it */ - if ( test_filter( be, conn, op, e, filter ) == 0 ) { - int scopeok; - char *dn; - - /* check scope */ - if ( scope == LDAP_SCOPE_ONELEVEL ) { - if ( (dn = dn_parent( be, e->e_ndn )) != NULL ) { - (void) dn_normalize_case( dn ); - scopeok = (dn == matched_dn) - ? 1 - : (strcmp( dn, matched_dn ) ? 0 : 1 ); - free( dn ); - } else { - scopeok = (matched_dn == NULL || *matched_dn == '\0'); - } - } else if ( scope == LDAP_SCOPE_SUBTREE ) { - dn = ch_strdup( e->e_ndn ); - scopeok = dn_issuffix( dn, matched_dn ); + goto loop_continue; + } + + /* if it matches the filter and scope, send it */ + if ( test_filter( be, conn, op, e, filter ) == 0 ) { + char *dn; + + /* check scope */ + if ( !scopeok && scope == LDAP_SCOPE_ONELEVEL ) { + if ( (dn = dn_parent( be, e->e_ndn )) != NULL ) { + (void) dn_normalize_case( dn ); + scopeok = (dn == realbase) + ? 1 + : (strcmp( dn, realbase ) ? 0 : 1 ); free( dn ); + } else { - scopeok = 1; + scopeok = (realbase == NULL || *realbase == '\0'); } - if ( scopeok ) { - /* check size limit */ - if ( --slimit == -1 ) { - cache_return_entry_r( &li->li_cache, e ); - send_search_result( conn, op, - LDAP_SIZELIMIT_EXCEEDED, NULL, NULL, - v2refs, NULL, nentries ); - idl_free( candidates ); - ber_bvecfree( v2refs ); - free( matched_dn ); - return( 0 ); - } + } else if ( !scopeok && scope == LDAP_SCOPE_SUBTREE ) { + dn = ch_strdup( e->e_ndn ); + scopeok = dn_issuffix( dn, realbase ); + free( dn ); - if (e) { - switch ( send_search_entry( be, conn, op, e, - attrs, attrsonly, 0, NULL ) ) { - case 0: /* entry sent ok */ - nentries++; - break; - case 1: /* entry not sent */ - break; - case -1: /* connection closed */ - cache_return_entry_r( &li->li_cache, e ); - idl_free( candidates ); - ber_bvecfree( v2refs ); - free( matched_dn ); - return( 0 ); - } + } else { + scopeok = 1; + } + + if ( scopeok ) { + /* check size limit */ + if ( --slimit == -1 ) { + cache_return_entry_r( &li->li_cache, e ); + send_search_result( conn, op, + LDAP_SIZELIMIT_EXCEEDED, NULL, NULL, + v2refs, NULL, nentries ); + rc = 0; + goto done; + } + + if (e) { + switch ( send_search_entry( be, conn, op, e, + attrs, attrsonly, 0, NULL ) ) { + case 0: /* entry sent ok */ + nentries++; + break; + case 1: /* entry not sent */ + break; + case -1: /* connection closed */ + cache_return_entry_r( &li->li_cache, e ); + rc = 0; + goto done; } - } else { - Debug( LDAP_DEBUG_TRACE, "candidate %ld scope not okay\n", - id, 0, 0 ); } } else { - Debug( LDAP_DEBUG_TRACE, "candidate %ld does match filter\n", + Debug( LDAP_DEBUG_TRACE, "candidate %ld scope not okay\n", id, 0, 0 ); } + } else { + Debug( LDAP_DEBUG_TRACE, "candidate %ld does match filter\n", + id, 0, 0 ); } +loop_continue: if( e != NULL ) { /* free reader lock */ cache_return_entry_r( &li->li_cache, e ); @@ -277,15 +296,19 @@ ldbm_back_search( ldap_pvt_thread_yield(); } - idl_free( candidates ); - send_search_result( conn, op, v2refs == NULL ? LDAP_SUCCESS : LDAP_REFERRAL, NULL, NULL, v2refs, NULL, nentries ); + rc = 0; + +done: + idl_free( candidates ); + ber_bvecfree( v2refs ); + if( realbase ) free( realbase ); - return( 0 ); + return rc; } static ID_BLOCK * @@ -341,8 +364,7 @@ search_candidates( f = filter; } -#ifdef SLAPD_ALIASES - if( deref == LDAP_DEREF_SEARCHING || deref == LDAP_DEREF_ALWAYS ) { + if( deref & LDAP_DEREF_SEARCHING ) { /* match aliases */ af = (Filter *) ch_malloc( sizeof(Filter) ); af->f_next = NULL; @@ -357,9 +379,6 @@ search_candidates( } else { af = NULL; } -#else - af = NULL; -#endif if ( scope == LDAP_SCOPE_SUBTREE ) { lf = (Filter *) ch_malloc( sizeof(Filter) ); diff --git a/servers/slapd/back-passwd/search.c b/servers/slapd/back-passwd/search.c index 90e8a52e78..231d664869 100644 --- a/servers/slapd/back-passwd/search.c +++ b/servers/slapd/back-passwd/search.c @@ -35,12 +35,13 @@ passwd_back_search( int attrsonly ) { - int sent = 0; struct passwd *pw; Entry *e; char *s; time_t stoptime; - int err = LDAP_NO_SUCH_OBJECT; + + int sent = 0; + int err = LDAP_SUCCESS; char *rdn = NULL; char *parent = NULL; @@ -68,44 +69,47 @@ passwd_back_search( vals[0] = &val; vals[1] = NULL; - /* Create an entry corresponding to the base DN */ - e = (Entry *) ch_calloc(1, sizeof(Entry)); - e->e_attrs = NULL; - e->e_dn = strdup(base); + matched = ch_strdup( base ); - /* Use the first attribute of the DN - * as an attribute within the entry itself. - */ - rdn = dn_rdn(NULL, base); + if( scope != LDAP_SCOPE_ONELEVEL ) { + /* Create an entry corresponding to the base DN */ + e = (Entry *) ch_calloc(1, sizeof(Entry)); + e->e_attrs = NULL; + e->e_dn = ch_strdup( base ); - if( rdn == NULL || (s = strchr(rdn, '=')) == NULL ) { - err = LDAP_INVALID_DN_SYNTAX; - goto done; - } + /* Use the first attribute of the DN + * as an attribute within the entry itself. + */ + rdn = dn_rdn(NULL, base); - val.bv_val = rdn_attr_value(rdn); - val.bv_len = strlen( val.bv_val ); - attr_merge( e, rdn_attr_type(rdn), vals ); - - free(rdn); - rdn = NULL; + if( rdn == NULL || (s = strchr(rdn, '=')) == NULL ) { + err = LDAP_INVALID_DN_SYNTAX; + goto done; + } - /* Every entry needs an objectclass. We don't really - * know if our hardcoded choice here agrees with the - * DN that was configured for this backend, but it's - * better than nothing. - * - * should be a configuratable item - */ - val.bv_val = "organizationalUnit"; - val.bv_len = strlen( val.bv_val ); - attr_merge( e, "objectClass", vals ); + val.bv_val = rdn_attr_value(rdn); + val.bv_len = strlen( val.bv_val ); + attr_merge( e, rdn_attr_type(rdn), vals ); + + free(rdn); + rdn = NULL; + + /* Every entry needs an objectclass. We don't really + * know if our hardcoded choice here agrees with the + * DN that was configured for this backend, but it's + * better than nothing. + * + * should be a configuratable item + */ + val.bv_val = "organizationalUnit"; + val.bv_len = strlen( val.bv_val ); + attr_merge( e, "objectClass", vals ); - if ( test_filter( be, conn, op, e, filter ) == 0 ) { - send_search_entry( be, conn, op, - e, attrs, attrsonly, NULL, 0 ); - matched = strdup( be->be_suffix[0] ); - sent++; + if ( test_filter( be, conn, op, e, filter ) == 0 ) { + send_search_entry( be, conn, op, + e, attrs, attrsonly, 0, NULL ); + sent++; + } } if ( scope != LDAP_SCOPE_BASE ) { @@ -141,7 +145,7 @@ passwd_back_search( } send_search_entry( be, conn, op, - e, attrs, attrsonly, NULL, 0 ); + e, attrs, attrsonly, 0, NULL ); sent++; } @@ -157,13 +161,25 @@ passwd_back_search( * anything deeper than that. */ if( !be_issuffix( be, parent ) ) { + int i; + for( i=0; be->be_suffix[i] != NULL; i++ ) { + if( dn_issuffix( base, be->be_suffix[i] ) ) { + matched = ch_strdup( be->be_suffix[i] ); + break; + } + } + err = LDAP_NO_SUCH_OBJECT; + goto done; + } + + if( scope == LDAP_SCOPE_ONELEVEL ) { goto done; } rdn = dn_rdn( NULL, base ); if ( (user = rdn_attr_value(rdn)) == NULL) { - err = LDAP_INVALID_DN_SYNTAX; + err = LDAP_OPERATIONS_ERROR; goto done; } @@ -172,6 +188,9 @@ passwd_back_search( } if ( (pw = getpwnam( user )) == NULL ) { + matched = parent; + parent = NULL; + err = LDAP_NO_SUCH_OBJECT; goto done; } @@ -179,7 +198,7 @@ passwd_back_search( if ( test_filter( be, conn, op, e, filter ) == 0 ) { send_search_entry( be, conn, op, - e, attrs, attrsonly, NULL, 0 ); + e, attrs, attrsonly, 0, NULL ); sent++; } @@ -187,14 +206,9 @@ passwd_back_search( } done: - if( sent ) { - send_ldap_result( conn, op, LDAP_SUCCESS, - NULL, NULL, NULL, NULL ); - - } else { - send_ldap_result( conn, op, err, - matched, NULL, NULL, NULL ); - } + send_ldap_result( conn, op, + err, err == LDAP_NO_SUCH_OBJECT ? matched : NULL, NULL, + NULL, NULL ); if( matched != NULL ) free( matched ); if( parent != NULL ) free( parent ); diff --git a/servers/slapd/back-perl/search.c b/servers/slapd/back-perl/search.c index 0a2558a148..16648d658c 100644 --- a/servers/slapd/back-perl/search.c +++ b/servers/slapd/back-perl/search.c @@ -87,7 +87,7 @@ perl_back_search( } else { send_search_entry( be, conn, op, - e, attrs, attrsonly, NULL, 0 ); + e, attrs, attrsonly, 0, NULL ); entry_free( e ); } diff --git a/servers/slapd/back-shell/result.c b/servers/slapd/back-shell/result.c index a0182de969..7e895001ac 100644 --- a/servers/slapd/back-shell/result.c +++ b/servers/slapd/back-shell/result.c @@ -59,7 +59,7 @@ read_and_send_results( buf, 0, 0 ); } else { send_search_entry( be, conn, op, e, attrs, - attrsonly, NULL, 0 ); + attrsonly, 0, NULL ); entry_free( e ); } diff --git a/servers/slapd/back-tcl/tcl_util.c b/servers/slapd/back-tcl/tcl_util.c index 994b24ab96..8827e011b7 100644 --- a/servers/slapd/back-tcl/tcl_util.c +++ b/servers/slapd/back-tcl/tcl_util.c @@ -1,6 +1,6 @@ /* result.c - tcl backend utility functions * - * $Id: tcl_util.c,v 1.6 1999/07/07 16:51:41 kdz Exp $ + * $Id: tcl_util.c,v 1.6.2.1 1999/07/09 18:02:59 kdz Exp $ * * Copyright 1999, Ben Collins , All rights reserved. * @@ -80,7 +80,7 @@ interp_send_results ( buf, 0, 0); } else { send_search_entry (be, conn, op, e, attrs, - attrsonly, 0 ); + attrsonly, 0, NULL ); entry_free (e); } diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index 847f947515..ca878ab63a 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -283,7 +283,7 @@ void send_search_result LDAP_P(( int send_search_reference LDAP_P(( Backend *be, Connection *conn, Operation *op, - Entry *e, struct berval **refs, + Entry *e, struct berval **refs, int scope, LDAPControl **ctrls, struct berval ***v2refs )); diff --git a/servers/slapd/result.c b/servers/slapd/result.c index 57dd8ef1d9..5b67b48ead 100644 --- a/servers/slapd/result.c +++ b/servers/slapd/result.c @@ -94,16 +94,15 @@ static void trim_refs_urls( } struct berval **get_entry_referrals( - Backend *be, Connection *conn, Operation *op, Entry *e ) + Backend *be, + Connection *conn, + Operation *op, + Entry *e ) { Attribute *attr; struct berval **refs; unsigned i, j; - if( is_entry_referral( e ) ) { - return NULL; - } - attr = attr_find( e->e_attrs, "ref" ); if( attr == NULL ) return NULL; @@ -369,6 +368,10 @@ send_ldap_result( assert( err != LDAP_PARTIAL_RESULTS ); + if( op->o_tag != LDAP_REQ_SEARCH ) { + trim_refs_urls( ref ); + } + if ( err == LDAP_REFERRAL ) { if( ref == NULL ) { err = LDAP_NO_SUCH_OBJECT; @@ -642,6 +645,7 @@ send_search_reference( Operation *op, Entry *e, struct berval **refs, + int scope, LDAPControl **ctrls, struct berval ***v2refs ) -- 2.39.5