From b996c17eb228c08ce4fd156a895fd316327c7ef3 Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Sat, 29 Jan 2011 12:29:20 +0000 Subject: [PATCH] handle undefined filters in back-ldap (more about ITS#6814) --- servers/slapd/back-ldap/search.c | 28 +++++++++++++++++++++++-- servers/slapd/filter.c | 36 ++++++++++++++++++++++---------- servers/slapd/proto-slap.h | 3 ++- 3 files changed, 53 insertions(+), 14 deletions(-) diff --git a/servers/slapd/back-ldap/search.c b/servers/slapd/back-ldap/search.c index ccba7fb68a..a4a9aa4d85 100644 --- a/servers/slapd/back-ldap/search.c +++ b/servers/slapd/back-ldap/search.c @@ -309,8 +309,32 @@ retry: goto finish; case LDAP_FILTER_ERROR: - if (ldap_back_munge_filter( op, &filter, &freefilter ) > 0 ) { - goto retry; + /* first try? */ + if ( filter.bv_val == op->ors_filterstr.bv_val ) { + if ( strstr( filter.bv_val, "(?" ) ) { + int do_retry = 0; + if ( !LDAP_BACK_NOUNDEFFILTER( li ) ) { + BER_BVZERO( &filter ); + filter2bv_undef_x( op, op->ors_filter, 1, &filter ); + freefilter++; + do_retry++; + } + + /* if anything survives, try replacing t-f */ + if ( strstr( filter.bv_val, "(?" ) ) { + int dmy = 0; + if ( ldap_back_munge_filter( op, &filter, &dmy ) > 0 ) { + do_retry++; + } + if ( dmy ) { + freefilter++; + } + } + + if ( do_retry ) { + goto retry; + } + } } /* invalid filters return success with no data */ diff --git a/servers/slapd/filter.c b/servers/slapd/filter.c index 246b4ac6b1..60d6389497 100644 --- a/servers/slapd/filter.c +++ b/servers/slapd/filter.c @@ -585,6 +585,12 @@ filter_free( Filter *f ) void filter2bv_x( Operation *op, Filter *f, struct berval *fstr ) +{ + return filter2bv_undef_x( op, f, 0, fstr ); +} + +void +filter2bv_undef_x( Operation *op, Filter *f, int noundef, struct berval *fstr ) { int i; Filter *p; @@ -598,7 +604,7 @@ filter2bv_x( Operation *op, Filter *f, struct berval *fstr ) ber_bvnone = BER_BVC( "(?=none)" ); ber_len_t len; ber_tag_t choice; - int undef; + int undef, undef2; char *sign; if ( f == NULL ) { @@ -607,6 +613,7 @@ filter2bv_x( Operation *op, Filter *f, struct berval *fstr ) } undef = f->f_choice & SLAPD_FILTER_UNDEFINED; + undef2 = (undef && !noundef); choice = f->f_choice & SLAPD_FILTER_MASK; switch ( choice ) { @@ -644,12 +651,12 @@ simple: * is legal for that attribute's syntax */ fstr->bv_len += f->f_av_desc->ad_cname.bv_len + tmp.bv_len; - if ( undef ) + if ( undef2 ) fstr->bv_len++; fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx ); snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s%s%s%s)", - undef ? "?" : "", + undef2 ? "?" : "", f->f_av_desc->ad_cname.bv_val, sign, tmp.bv_len ? tmp.bv_val : "" ); @@ -663,12 +670,12 @@ simple: case LDAP_FILTER_SUBSTRINGS: fstr->bv_len = f->f_sub_desc->ad_cname.bv_len + STRLENOF("(=*)"); - if ( undef ) + if ( undef2 ) fstr->bv_len++; fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 128, op->o_tmpmemctx ); snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s%s=*)", - undef ? "?" : "", + undef2 ? "?" : "", f->f_sub_desc->ad_cname.bv_val ); if ( f->f_sub_initial.bv_val != NULL ) { @@ -737,13 +744,13 @@ simple: case LDAP_FILTER_PRESENT: fstr->bv_len = f->f_desc->ad_cname.bv_len + STRLENOF("(=*)"); - if ( undef ) + if ( undef2 ) fstr->bv_len++; fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx ); snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s%s=*)", - undef ? "?" : "", + undef2 ? "?" : "", f->f_desc->ad_cname.bv_val ); break; @@ -760,7 +767,7 @@ simple: for ( p = f->f_list; p != NULL; p = p->f_next ) { len = fstr->bv_len; - filter2bv_x( op, p, &tmp ); + filter2bv_undef_x( op, p, noundef, &tmp ); fstr->bv_len += tmp.bv_len; fstr->bv_val = op->o_tmprealloc( fstr->bv_val, fstr->bv_len + 1, @@ -792,13 +799,14 @@ simple: } fstr->bv_len = ad.bv_len + + ( undef2 ? 1 : 0 ) + ( f->f_mr_dnattrs ? STRLENOF(":dn") : 0 ) + - ( f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_len+1 : 0 ) + + ( f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_len + STRLENOF(":") : 0 ) + tmp.bv_len + STRLENOF("(:=)"); fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx ); snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s%s%s%s%s:=%s)", - undef ? "?" : "", + undef2 ? "?" : "", ad.bv_val, f->f_mr_dnattrs ? ":dn" : "", f->f_mr_rule_text.bv_len ? ":" : "", @@ -837,6 +845,12 @@ simple: void filter2bv( Filter *f, struct berval *fstr ) +{ + return filter2bv_undef( f, 0, fstr ); +} + +void +filter2bv_undef( Filter *f, int noundef, struct berval *fstr ) { Operation op; Opheader ohdr; @@ -845,7 +859,7 @@ filter2bv( Filter *f, struct berval *fstr ) op.o_tmpmemctx = NULL; op.o_tmpmfuncs = &ch_mfuncs; - filter2bv_x( &op, f, fstr ); + filter2bv_undef_x( &op, f, noundef, fstr ); } Filter * diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index dd86bf9ed3..e9f9577aa9 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -1094,7 +1094,8 @@ LDAP_SLAPD_F (int) get_filter LDAP_P(( LDAP_SLAPD_F (void) filter_free LDAP_P(( Filter *f )); LDAP_SLAPD_F (void) filter_free_x LDAP_P(( Operation *op, Filter *f, int freeme )); LDAP_SLAPD_F (void) filter2bv LDAP_P(( Filter *f, struct berval *bv )); -LDAP_SLAPD_F (void) filter2bv_x LDAP_P(( Operation *op, Filter *f, struct berval *bv )); +LDAP_SLAPD_F (void) filter2bv_undef LDAP_P(( Filter *f, int noundef, struct berval *bv )); +LDAP_SLAPD_F (void) filter2bv_undef_x LDAP_P(( Operation *op, Filter *f, int noundef, struct berval *bv )); LDAP_SLAPD_F (Filter *) filter_dup LDAP_P(( Filter *f, void *memctx )); LDAP_SLAPD_F (int) get_vrFilter LDAP_P(( Operation *op, BerElement *ber, -- 2.39.5