fix hasSubordinate filtering; now it can be safely turned on

This commit is contained in:
Pierangelo Masarati 2002-10-26 16:18:31 +00:00
parent 69343add5a
commit 7b3f889ec1
13 changed files with 114 additions and 163 deletions

View File

@ -33,6 +33,10 @@ extern BI_chk_referrals bdb_referrals;
extern BI_operational bdb_operational;
#ifdef SLAP_X_FILTER_HASSUBORDINATES
extern BI_has_subordinates bdb_hasSubordinates;
#endif /* SLAP_X_FILTER_HASSUBORDINATES */
/* tools.c */
extern BI_tool_entry_open bdb_tool_entry_open;
extern BI_tool_entry_close bdb_tool_entry_close;

View File

@ -615,6 +615,9 @@ bdb_initialize(
bi->bi_chk_referrals = bdb_referrals;
bi->bi_operational = bdb_operational;
#ifdef SLAP_X_FILTER_HASSUBORDINATES
bi->bi_has_subordinates = bdb_hasSubordinates;
#endif /* SLAP_X_FILTER_HASSUBORDINATES */
bi->bi_entry_release_rw = bdb_entry_release;
/*

View File

@ -110,11 +110,6 @@ bdb_psearch(
int isroot = 0;
int scopeok = 0;
#ifdef SLAP_X_FILTER_HASSUBORDINATES
int filter_hasSubordinates = 0;
Attribute *hasSubordinates = NULL;
#endif /* SLAP_X_FILTER_HASSUBORDINATES */
u_int32_t locker;
DB_LOCK lock;
@ -386,14 +381,6 @@ dn2entry_retry:
}
}
#ifdef SLAP_X_FILTER_HASSUBORDINATES
/*
* is hasSubordinates used in the filter ?
* FIXME: we may compute this directly when parsing the filter
*/
filter_hasSubordinates = filter_has_subordinates( filter );
#endif /* SLAP_X_FILTER_HASSUBORDINATES */
lcupf.f_choice = LDAP_FILTER_AND;
lcupf.f_and = &csnfnot;
lcupf.f_next = NULL;
@ -568,52 +555,12 @@ dn2entry_retry:
goto test_done;
}
#ifdef SLAP_X_FILTER_HASSUBORDINATES
/*
* if hasSubordinates is used in the filter,
* append it to the entry's attributes
*/
if ( filter_hasSubordinates ) {
int hs;
rc = bdb_hasSubordinates( be, ps_conn, ps_op, e, &hs);
if ( rc != LDAP_SUCCESS ) {
goto test_done;
}
hasSubordinates = slap_operational_hasSubordinate(
hs == LDAP_COMPARE_TRUE );
if ( hasSubordinates == NULL ) {
goto test_done;
}
hasSubordinates->a_next = e->e_attrs;
e->e_attrs = hasSubordinates;
}
#endif /* SLAP_X_FILTER_HASSUBORDINATES */
if ( psearch_type != LCUP_PSEARCH_BY_SCOPEOUT ) {
rc = test_filter( be, ps_conn, ps_op, e, &lcupf );
} else {
rc = LDAP_COMPARE_TRUE;
}
#ifdef SLAP_X_FILTER_HASSUBORDINATES
if ( hasSubordinates ) {
/*
* FIXME: this is fairly inefficient, because
* if hasSubordinates is among the required
* attrs, it will be added again later;
* maybe we should leave it and check
* check later if it's already present,
* if required
*/
e->e_attrs = e->e_attrs->a_next;
attr_free( hasSubordinates );
}
#endif /* SLAP_X_FILTER_HASSUBORDINATES */
if ( rc == LDAP_COMPARE_TRUE ) {
struct berval dn;

View File

@ -16,9 +16,9 @@
#include "proto-bdb.h"
/*
* sets the supported operational attributes (if required)
* sets *hasSubordinates to LDAP_COMPARE_TRUE/LDAP_COMPARE_FALSE
* if the entry has children or not.
*/
int
bdb_hasSubordinates(
BackendDB *be,
@ -124,6 +124,9 @@ return_results:
return rc;
}
/*
* sets the supported operational attributes (if required)
*/
int
bdb_operational(
BackendDB *be,

View File

@ -67,10 +67,6 @@ bdb_search(
struct slap_limits_set *limit = NULL;
int isroot = 0;
#ifdef SLAP_X_FILTER_HASSUBORDINATES
int filter_hasSubordinates = 0;
#endif /* SLAP_X_FILTER_HASSUBORDINATES */
u_int32_t locker;
DB_LOCK lock;
@ -342,14 +338,6 @@ dn2entry_retry:
}
}
#ifdef SLAP_X_FILTER_HASSUBORDINATES
/*
* is hasSubordinates used in the filter ?
* FIXME: we may compute this directly when parsing the filter
*/
filter_hasSubordinates = filter_has_subordinates( filter );
#endif /* SLAP_X_FILTER_HASSUBORDINATES */
#ifdef LDAP_CLIENT_UPDATE
if ( op->o_clientupdate_type & SLAP_LCUP_SYNC ) {
lcupf.f_choice = LDAP_FILTER_AND;
@ -382,9 +370,6 @@ dn2entry_retry:
id = bdb_idl_next( candidates, &cursor ) )
{
int scopeok = 0;
#ifdef SLAP_X_FILTER_HASSUBORDINATES
Attribute *hasSubordinates = NULL;
#endif /* SLAP_X_FILTER_HASSUBORDINATES */
/* check for abandon */
if ( op->o_abandon ) {
@ -548,31 +533,6 @@ id2entry_retry:
goto loop_continue;
}
#ifdef SLAP_X_FILTER_HASSUBORDINATES
/*
* if hasSubordinates is used in the filter,
* append it to the entry's attributes
*/
if ( filter_hasSubordinates ) {
int hs;
rc = bdb_hasSubordinates( be, conn, op, e, &hs);
if ( rc != LDAP_SUCCESS ) {
goto loop_continue;
}
hasSubordinates = slap_operational_hasSubordinate(
hs == LDAP_COMPARE_TRUE );
if ( hasSubordinates == NULL ) {
goto loop_continue;
}
hasSubordinates->a_next = e->e_attrs;
e->e_attrs = hasSubordinates;
}
#endif /* SLAP_X_FILTER_HASSUBORDINATES */
/* if it matches the filter and scope, send it */
#ifdef LDAP_CLIENT_UPDATE
if ( op->o_clientupdate_type & SLAP_LCUP_SYNC ) {
@ -583,21 +543,6 @@ id2entry_retry:
rc = test_filter( be, conn, op, e, filter );
}
#ifdef SLAP_X_FILTER_HASSUBORDINATES
if ( hasSubordinates ) {
/*
* FIXME: this is fairly inefficient, because
* if hasSubordinates is among the required
* attrs, it will be added again later;
* maybe we should leave it and check
* check later if it's already present,
* if required
*/
e->e_attrs = e->e_attrs->a_next;
attr_free( hasSubordinates );
}
#endif /* SLAP_X_FILTER_HASSUBORDINATES */
if ( rc == LDAP_COMPARE_TRUE ) {
struct berval dn;

View File

@ -43,6 +43,10 @@ extern BI_acl_attribute ldbm_back_attribute;
extern BI_operational ldbm_back_operational;
#ifdef SLAP_X_FILTER_HASSUBORDINATES
extern BI_has_subordinates ldbm_back_hasSubordinates;
#endif /* SLAP_X_FILTER_HASSUBORDINATES */
/* hooks for slap tools */
extern BI_tool_entry_open ldbm_tool_entry_open;
extern BI_tool_entry_close ldbm_tool_entry_close;

View File

@ -71,6 +71,9 @@ ldbm_back_initialize(
bi->bi_acl_attribute = ldbm_back_attribute;
bi->bi_chk_referrals = ldbm_back_referrals;
bi->bi_operational = ldbm_back_operational;
#ifdef SLAP_X_FILTER_HASSUBORDINATES
bi->bi_has_subordinates = ldbm_back_hasSubordinates;
#endif /* SLAP_X_FILTER_HASSUBORDINATES */
/*
* hooks for slap tools

View File

@ -15,10 +15,31 @@
#include "back-ldbm.h"
#include "proto-back-ldbm.h"
/*
* sets *hasSubordinates to LDAP_COMPARE_TRUE/LDAP_COMPARE_FALSE
* if the entry has children or not.
*/
int
ldbm_back_hasSubordinates(
BackendDB *be,
Connection *conn,
Operation *op,
Entry *e,
int *hasSubordinates )
{
if ( has_children( be, e ) ) {
*hasSubordinates = LDAP_COMPARE_TRUE;
} else {
*hasSubordinates = LDAP_COMPARE_FALSE;
}
return 0;
}
/*
* sets the supported operational attributes (if required)
*/
int
ldbm_back_operational(
BackendDB *be,

View File

@ -57,10 +57,6 @@ ldbm_back_search(
struct slap_limits_set *limit = NULL;
int isroot = 0;
#ifdef SLAP_X_FILTER_HASSUBORDINATES
int filter_hasSubordinates = 0;
#endif /* SLAP_X_FILTER_HASSUBORDINATES */
#ifdef NEW_LOGGING
LDAP_LOG( BACK_LDBM, ENTRY, "ldbm_back_search: enter\n", 0, 0, 0 );
#else
@ -292,22 +288,11 @@ searchit:
/* compute it anyway; root does not use it */
stoptime = op->o_time + tlimit;
#ifdef SLAP_X_FILTER_HASSUBORDINATES
/*
* is hasSubordinates used in the filter ?
* FIXME: we may compute this directly when parsing the filter
*/
filter_hasSubordinates = filter_has_subordinates( filter );
#endif /* SLAP_X_FILTER_HASSUBORDINATES */
for ( id = idl_firstid( candidates, &cursor ); id != NOID;
id = idl_nextid( candidates, &cursor ) )
{
int scopeok = 0;
int result = 0;
#ifdef SLAP_X_FILTER_HASSUBORDINATES
Attribute *hasSubordinates = NULL;
#endif /* SLAP_X_FILTER_HASSUBORDINATES */
/* check for abandon */
if ( op->o_abandon ) {
@ -436,43 +421,9 @@ searchit:
goto loop_continue;
}
#ifdef SLAP_X_FILTER_HASSUBORDINATES
/*
* if hasSubordinates is used in the filter,
* append it to the entry's attributes
*/
if ( filter_hasSubordinates ) {
int hs;
hs = has_children( be, e );
hasSubordinates = slap_operational_hasSubordinate( hs );
if ( hasSubordinates == NULL ) {
goto loop_continue;
}
hasSubordinates->a_next = e->e_attrs;
e->e_attrs = hasSubordinates;
}
#endif /* SLAP_X_FILTER_HASSUBORDINATES */
/* if it matches the filter and scope, send it */
result = test_filter( be, conn, op, e, filter );
#ifdef SLAP_X_FILTER_HASSUBORDINATES
if ( hasSubordinates ) {
/*
* FIXME: this is fairly inefficient, because
* if hasSubordinates is among the required
* attrs, it will be added again later;
* maybe we should leave it and check
* check later if it's already present,
* if required
*/
e->e_attrs = e->e_attrs->a_next;
attr_free( hasSubordinates );
}
#endif /* SLAP_X_FILTER_HASSUBORDINATES */
if ( result == LDAP_COMPARE_TRUE ) {
struct berval dn;

View File

@ -399,7 +399,7 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f )
*/
backsql_strfcat( &bsi->flt_where, &bsi->fwhere_len, "l",
(ber_len_t)sizeof( "1=1" ) - 1, "1=1" );
if ( ad != NULL ) {
if ( ad == slap_schema.si_ad_hasSubordinates ) {
/*
* We use this flag since we need to parse
* the filter anyway; we should have used
@ -407,6 +407,7 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f )
* filter_has_subordinates()
*/
bsi->bsi_flags |= BSQL_SF_FILTER_HASSUBORDINATE;
} else {
/*
* clear attributes to fetch, to require ALL

View File

@ -460,6 +460,41 @@ test_ava_filter(
}
}
#ifdef SLAP_X_FILTER_HASSUBORDINATES
if ( ava->aa_desc == slap_schema.si_ad_hasSubordinates
&& be && be->be_has_subordinates ) {
int hasSubordinates;
struct berval hs;
/*
* No other match should be allowed ...
*/
assert( type == LDAP_FILTER_EQUALITY );
if ( (*be->be_has_subordinates)( be, conn, op, e, &hasSubordinates ) ) {
return LDAP_OTHER;
}
if ( hasSubordinates == LDAP_COMPARE_TRUE ) {
hs.bv_val = "TRUE";
hs.bv_len = sizeof( "TRUE" ) - 1;
} else if ( hasSubordinates == LDAP_COMPARE_FALSE ) {
hs.bv_val = "FALSE";
hs.bv_len = sizeof( "FALSE" ) - 1;
} else {
return LDAP_OTHER;
}
if ( bvmatch( &ava->aa_value, &hs ) ) {
return LDAP_COMPARE_TRUE;
}
return LDAP_COMPARE_FALSE;
}
#endif /* SLAP_X_FILTER_HASSUBORDINATES */
return( LDAP_COMPARE_FALSE );
}
@ -473,13 +508,33 @@ test_presence_filter(
AttributeDescription *desc
)
{
Attribute *a;
if ( !access_allowed( be, conn, op, e, desc, NULL, ACL_SEARCH, NULL ) )
{
return LDAP_INSUFFICIENT_ACCESS;
}
return attrs_find( e->e_attrs, desc ) != NULL
? LDAP_COMPARE_TRUE : LDAP_COMPARE_FALSE;
a = attrs_find( e->e_attrs, desc );
#ifdef SLAP_X_FILTER_HASSUBORDINATES
if ( a == NULL && desc == slap_schema.si_ad_hasSubordinates ) {
/*
* XXX: fairly optimistic: if the function is defined,
* then PRESENCE must succeed, because hasSubordinate
* is boolean-valued; I think we may live with this
* simplification by now
*/
if ( be && be->be_has_subordinates ) {
return LDAP_COMPARE_TRUE;
}
return LDAP_COMPARE_FALSE;
}
#endif /* SLAP_X_FILTER_HASSUBORDINATES */
return a != NULL ? LDAP_COMPARE_TRUE : LDAP_COMPARE_FALSE;
}

View File

@ -485,6 +485,8 @@ LDAP_SLAPD_F (void) vrFilter2bv LDAP_P(( ValuesReturnFilter *f, struct berval *f
/*
* define to honor hasSubordinates operational attribute in search filters
* (in previous use there was a flaw with back-bdb and back-ldbm; now it
* is fixed).
*/
#undef SLAP_X_FILTER_HASSUBORDINATES

View File

@ -1206,6 +1206,9 @@ struct slap_backend_db {
#define be_group bd_info->bi_acl_group
#define be_attribute bd_info->bi_acl_attribute
#define be_operational bd_info->bi_operational
#ifdef SLAP_X_FILTER_HASSUBORDINATES
#define be_has_subordinates bd_info->bi_has_subordinates
#endif /* SLAP_X_FILTER_HASSUBORDINATES */
#define be_controls bd_info->bi_controls
@ -1406,6 +1409,12 @@ typedef int (BI_operational) LDAP_P((Backend *bd,
struct slap_conn *c, struct slap_op *o,
Entry *e, AttributeName *attrs, int opattrs, Attribute **a ));
#ifdef SLAP_X_FILTER_HASSUBORDINATES
typedef int (BI_has_subordinates) LDAP_P((Backend *bd,
struct slap_conn *c, struct slap_op *o,
Entry *e, int *has_subordinates ));
#endif /* SLAP_X_FILTER_HASSUBORDINATES */
typedef int (BI_connection_init) LDAP_P((BackendDB *bd,
struct slap_conn *c));
typedef int (BI_connection_destroy) LDAP_P((BackendDB *bd,
@ -1499,6 +1508,9 @@ struct slap_backend_info {
BI_acl_attribute *bi_acl_attribute;
BI_operational *bi_operational;
#ifdef SLAP_X_FILTER_HASSUBORDINATES
BI_has_subordinates *bi_has_subordinates;
#endif /* SLAP_X_FILTER_HASSUBORDINATES */
BI_connection_init *bi_connection_init;
BI_connection_destroy *bi_connection_destroy;