From 7f61a2739acf22e046235481d629fbc82b4bee81 Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Thu, 5 May 2005 11:19:11 +0000 Subject: [PATCH] fix support for absoluteFilters --- servers/slapd/back-ldap/search.c | 164 ++++++++++++++++++++++--------- 1 file changed, 119 insertions(+), 45 deletions(-) diff --git a/servers/slapd/back-ldap/search.c b/servers/slapd/back-ldap/search.c index 37aae39db1..bde4326a9d 100644 --- a/servers/slapd/back-ldap/search.c +++ b/servers/slapd/back-ldap/search.c @@ -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 + * . + */ +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 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 ) { - rs->sr_err = slap_map_api2result( rs ); - rs->sr_text = NULL; + 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; - } - if ( do_retry ) { - do_retry = 0; - if ( ldap_back_retry( lc, op, rs, LDAP_BACK_DONTSEND ) ) { + 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; } - 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 ); -- 2.39.5