]> git.sur5r.net Git - openldap/commitdiff
handle undefined filters in back-ldap (more about ITS#6814)
authorPierangelo Masarati <ando@openldap.org>
Sat, 29 Jan 2011 12:29:20 +0000 (12:29 +0000)
committerPierangelo Masarati <ando@openldap.org>
Sat, 29 Jan 2011 12:29:20 +0000 (12:29 +0000)
servers/slapd/back-ldap/search.c
servers/slapd/filter.c
servers/slapd/proto-slap.h

index ccba7fb68a1d808fe688a65d9a964995bb53c921..a4a9aa4d8553df7bb8e197c4a7549dc0c3944cad 100644 (file)
@@ -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 */
index 246b4ac6b13c0cd856f6d097bf281f6c0a064f3a..60d638949782e7d3af0c008e462db83c95246d5e 100644 (file)
@@ -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 *
index dd86bf9ed361ea9f488da3262a43343a2e43a944..e9f9577aa9e8058b9e8e014202c045f9d50f7ec5 100644 (file)
@@ -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,