mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-01-06 10:46:21 +08:00
fix hasSubordinate filtering; now it can be safely turned on
This commit is contained in:
parent
69343add5a
commit
7b3f889ec1
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
/*
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user