mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-01-30 13:30:57 +08:00
fix support for absoluteFilters
This commit is contained in:
parent
d30933af36
commit
7f61a2739a
@ -41,26 +41,109 @@ ldap_build_entry( Operation *op, LDAPMessage *e, Entry *ent,
|
||||
struct berval *bdn, int flags );
|
||||
#define LDAP_BUILD_ENTRY_PRIVATE 0x01
|
||||
|
||||
/*
|
||||
* Quick'n'dirty rewrite of filter in case of error, to deal with
|
||||
* <draft-zeilenga-ldap-t-f>.
|
||||
*/
|
||||
static int
|
||||
munge_filter(
|
||||
Operation *op,
|
||||
struct berval *filter )
|
||||
{
|
||||
struct ldapinfo *li = (struct ldapinfo *) op->o_bd->be_private;
|
||||
|
||||
char *ptr;
|
||||
int gotit = 0;
|
||||
|
||||
Debug( LDAP_DEBUG_ARGS, "=> ldap_back_munge_filter \"%s\"\n",
|
||||
filter->bv_val, 0, 0 );
|
||||
|
||||
for ( ptr = strstr( filter->bv_val, "(?=" );
|
||||
ptr;
|
||||
ptr = strstr( ptr, "(?=" ) )
|
||||
{
|
||||
static struct berval
|
||||
bv_true = BER_BVC( "(?=true)" ),
|
||||
bv_false = BER_BVC( "(?=false)" ),
|
||||
bv_t = BER_BVC( "(&)" ),
|
||||
bv_f = BER_BVC( "(|)" ),
|
||||
bv_T = BER_BVC( "(objectClass=*)" ),
|
||||
bv_F = BER_BVC( "(!(objectClass=*))" );
|
||||
struct berval *oldbv = NULL,
|
||||
*newbv = NULL,
|
||||
oldfilter = BER_BVNULL;
|
||||
|
||||
if ( strncmp( ptr, bv_true.bv_val, bv_true.bv_len ) == 0 ) {
|
||||
oldbv = &bv_true;
|
||||
if ( li->flags & LDAP_BACK_F_SUPPORT_T_F ) {
|
||||
newbv = &bv_t;
|
||||
|
||||
} else {
|
||||
newbv = &bv_T;
|
||||
}
|
||||
|
||||
} else if ( strncmp( ptr, bv_false.bv_val, bv_false.bv_len ) == 0 )
|
||||
{
|
||||
oldbv = &bv_false;
|
||||
if ( li->flags & LDAP_BACK_F_SUPPORT_T_F ) {
|
||||
newbv = &bv_f;
|
||||
|
||||
} else {
|
||||
newbv = &bv_F;
|
||||
}
|
||||
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
oldfilter = *filter;
|
||||
if ( !( li->flags & LDAP_BACK_F_SUPPORT_T_F ) ) {
|
||||
filter->bv_len += newbv->bv_len - oldbv->bv_len;
|
||||
if ( filter->bv_val == op->ors_filterstr.bv_val ) {
|
||||
filter->bv_val = op->o_tmpalloc( filter->bv_len + 1,
|
||||
op->o_tmpmemctx );
|
||||
|
||||
AC_MEMCPY( filter->bv_val, op->ors_filterstr.bv_val,
|
||||
op->ors_filterstr.bv_len + 1 );
|
||||
|
||||
} else {
|
||||
filter->bv_val = op->o_tmprealloc( filter->bv_val,
|
||||
filter->bv_len + 1, op->o_tmpmemctx );
|
||||
}
|
||||
|
||||
ptr = filter->bv_val + ( ptr - oldfilter.bv_val );
|
||||
}
|
||||
|
||||
AC_MEMCPY( &ptr[ newbv->bv_len ],
|
||||
&ptr[ oldbv->bv_len ],
|
||||
oldfilter.bv_len - ( ptr - filter->bv_val ) - oldbv->bv_len + 1 );
|
||||
AC_MEMCPY( ptr, newbv->bv_val, newbv->bv_len );
|
||||
|
||||
ptr += newbv->bv_len;
|
||||
gotit = 1;
|
||||
}
|
||||
|
||||
Debug( LDAP_DEBUG_ARGS, "<= ldap_back_munge_filter \"%s\" (%d)\n",
|
||||
filter->bv_val, gotit, 0 );
|
||||
|
||||
return gotit;
|
||||
}
|
||||
|
||||
int
|
||||
ldap_back_search(
|
||||
Operation *op,
|
||||
SlapReply *rs )
|
||||
{
|
||||
struct ldapinfo *li = (struct ldapinfo *) op->o_bd->be_private;
|
||||
|
||||
struct ldapconn *lc;
|
||||
struct timeval tv;
|
||||
LDAPMessage *res,
|
||||
*e;
|
||||
int rc = 0,
|
||||
msgid;
|
||||
struct berval match = BER_BVNULL;
|
||||
struct berval match = BER_BVNULL,
|
||||
filter = BER_BVNULL;
|
||||
int i;
|
||||
char **attrs = NULL,
|
||||
*filter = NULL;
|
||||
static struct berval
|
||||
bv_true = BER_BVC( "(?=true)" ),
|
||||
bv_false = BER_BVC( "(?=false)" );
|
||||
char **attrs = NULL;
|
||||
int dontfreetext = 0;
|
||||
int do_retry = 1;
|
||||
LDAPControl **ctrls = NULL;
|
||||
@ -117,51 +200,40 @@ ldap_back_search(
|
||||
}
|
||||
|
||||
/* deal with <draft-zeilenga-ldap-t-f> filters */
|
||||
filter = op->ors_filterstr.bv_val;
|
||||
if ( bvmatch( &op->ors_filterstr, &bv_true ) ) {
|
||||
if ( li->flags & LDAP_BACK_F_SUPPORT_T_F ) {
|
||||
filter = "(&)";
|
||||
|
||||
} else {
|
||||
/* better than nothing... */
|
||||
filter = "(objectClass=*)";
|
||||
}
|
||||
|
||||
} else if ( bvmatch( &op->ors_filterstr, &bv_false ) ) {
|
||||
if ( li->flags & LDAP_BACK_F_SUPPORT_T_F ) {
|
||||
filter = "(|)";
|
||||
|
||||
} else {
|
||||
/* better than nothing... */
|
||||
filter = "(!(objectClass=*))";
|
||||
}
|
||||
}
|
||||
|
||||
filter = op->ors_filterstr;
|
||||
retry:
|
||||
rs->sr_err = ldap_search_ext( lc->lc_ld, op->o_req_ndn.bv_val,
|
||||
op->ors_scope, filter,
|
||||
op->ors_scope, filter.bv_val,
|
||||
attrs, op->ors_attrsonly, ctrls, NULL,
|
||||
tv.tv_sec ? &tv : NULL,
|
||||
op->ors_slimit, &msgid );
|
||||
|
||||
if ( rs->sr_err != LDAP_SUCCESS ) {
|
||||
fail:;
|
||||
if ( rs->sr_err != LDAP_SERVER_DOWN ) {
|
||||
switch ( rs->sr_err ) {
|
||||
case LDAP_SERVER_DOWN:
|
||||
if ( do_retry ) {
|
||||
do_retry = 0;
|
||||
if ( ldap_back_retry( lc, op, rs, LDAP_BACK_DONTSEND ) ) {
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
rc = ldap_back_op_result( lc, op, rs, msgid, LDAP_BACK_DONTSEND );
|
||||
ldap_back_freeconn( op, lc );
|
||||
lc = NULL;
|
||||
goto finish;
|
||||
|
||||
case LDAP_FILTER_ERROR:
|
||||
if ( munge_filter( op, &filter ) ) {
|
||||
goto retry;
|
||||
}
|
||||
/* fallthru */
|
||||
|
||||
default:
|
||||
rs->sr_err = slap_map_api2result( rs );
|
||||
rs->sr_text = NULL;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if ( do_retry ) {
|
||||
do_retry = 0;
|
||||
if ( ldap_back_retry( lc, op, rs, LDAP_BACK_DONTSEND ) ) {
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
rc = ldap_back_op_result( lc, op, rs, msgid, LDAP_BACK_DONTSEND );
|
||||
ldap_back_freeconn( op, lc );
|
||||
lc = NULL;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* We pull apart the ber result, stuff it into a slapd entry, and
|
||||
@ -201,18 +273,16 @@ fail:;
|
||||
abort = send_search_entry( op, rs );
|
||||
while ( ent.e_attrs ) {
|
||||
Attribute *a;
|
||||
BerVarray v;
|
||||
|
||||
a = ent.e_attrs;
|
||||
ent.e_attrs = a->a_next;
|
||||
|
||||
v = a->a_vals;
|
||||
if ( a->a_nvals != a->a_vals ) {
|
||||
ber_bvarray_free( a->a_nvals );
|
||||
}
|
||||
if ( a->a_vals != &slap_dummy_bv ) {
|
||||
ber_bvarray_free( a->a_vals );
|
||||
}
|
||||
if ( a->a_nvals != v ) {
|
||||
ber_bvarray_free( a->a_nvals );
|
||||
}
|
||||
ch_free( a );
|
||||
}
|
||||
|
||||
@ -341,6 +411,10 @@ finish:;
|
||||
LDAP_FREE( match.bv_val );
|
||||
}
|
||||
|
||||
if ( !BER_BVISNULL( &filter ) && filter.bv_val != op->ors_filterstr.bv_val ) {
|
||||
op->o_tmpfree( filter.bv_val, op->o_tmpmemctx );
|
||||
}
|
||||
|
||||
if ( rs->sr_text ) {
|
||||
if ( !dontfreetext ) {
|
||||
LDAP_FREE( (char *)rs->sr_text );
|
||||
|
Loading…
Reference in New Issue
Block a user