Commit 4efa87ee authored by Kurt Zeilenga's avatar Kurt Zeilenga
Browse files

Fix transposed send_search_entry args.

Toy with back-passwd/search scopes.
parent d0e12df4
......@@ -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;
......
......@@ -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;
......
......@@ -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
......
......@@ -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) );
......
......@@ -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 );
......
......@@ -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 );
}
......
......@@ -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 );
}
......
/* 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 <bcollins@debian.org>, 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);
}
......
......@@ -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 ));
......
......@@ -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(