]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/filter.c
ITS#4458 re-encode passwd request
[openldap] / servers / slapd / filter.c
index 4fb874fdc821dece9c235a88c01a716761439db4..87cfd7193730c6672e6859cd389e18836fcce2e1 100644 (file)
@@ -562,77 +562,97 @@ filter2bv_x( Operation *op, Filter *f, struct berval *fstr )
        switch ( f->f_choice ) {
        case LDAP_FILTER_EQUALITY:
                filter_escape_value_x( &f->f_av_value, &tmp, op->o_tmpmemctx );
+               /* NOTE: tmp can legitimately be NULL (meaning empty) 
+                * since in a Filter values in AVAs are supposed
+                * to have been normalized, meaning that an empty value
+                * is legal for that attribute's syntax */
 
                fstr->bv_len = f->f_av_desc->ad_cname.bv_len +
-                       tmp.bv_len + ( sizeof("(=)") - 1 );
+                       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)",
                        f->f_av_desc->ad_cname.bv_val,
-                       tmp.bv_len ? tmp.bv_val : "(null)");
+                       tmp.bv_len ? tmp.bv_val : ");
 
                ber_memfree_x( tmp.bv_val, op->o_tmpmemctx );
                break;
 
        case LDAP_FILTER_GE:
                filter_escape_value_x( &f->f_av_value, &tmp, op->o_tmpmemctx );
+               /* NOTE: tmp can legitimately be NULL (meaning empty) 
+                * since in a Filter values in AVAs are supposed
+                * to have been normalized, meaning that an empty value
+                * is legal for that attribute's syntax */
 
                fstr->bv_len = f->f_av_desc->ad_cname.bv_len +
-                       tmp.bv_len + ( sizeof("(>=)") - 1 );
+                       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)",
                        f->f_av_desc->ad_cname.bv_val,
-                       tmp.bv_len ? tmp.bv_val : "(null)");
+                       tmp.bv_len ? tmp.bv_val : "");
 
                ber_memfree_x( tmp.bv_val, op->o_tmpmemctx );
                break;
 
        case LDAP_FILTER_LE:
                filter_escape_value_x( &f->f_av_value, &tmp, op->o_tmpmemctx );
+               /* NOTE: tmp can legitimately be NULL (meaning empty) 
+                * since in a Filter values in AVAs are supposed
+                * to have been normalized, meaning that an empty value
+                * is legal for that attribute's syntax */
 
                fstr->bv_len = f->f_av_desc->ad_cname.bv_len +
-                       tmp.bv_len + ( sizeof("(<=)") - 1 );
+                       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)",
                        f->f_av_desc->ad_cname.bv_val,
-                       tmp.bv_len ? tmp.bv_val : "(null)");
+                       tmp.bv_len ? tmp.bv_val : "");
 
                ber_memfree_x( tmp.bv_val, op->o_tmpmemctx );
                break;
 
        case LDAP_FILTER_APPROX:
                filter_escape_value_x( &f->f_av_value, &tmp, op->o_tmpmemctx );
+               /* NOTE: tmp can legitimately be NULL (meaning empty) 
+                * since in a Filter values in AVAs are supposed
+                * to have been normalized, meaning that an empty value
+                * is legal for that attribute's syntax */
 
                fstr->bv_len = f->f_av_desc->ad_cname.bv_len +
-                       tmp.bv_len + ( sizeof("(~=)") - 1 );
+                       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)",
                        f->f_av_desc->ad_cname.bv_val,
-                       tmp.bv_len ? tmp.bv_val : "(null)");
+                       tmp.bv_len ? tmp.bv_val : "");
                ber_memfree_x( tmp.bv_val, op->o_tmpmemctx );
                break;
 
        case LDAP_FILTER_SUBSTRINGS:
                fstr->bv_len = f->f_sub_desc->ad_cname.bv_len +
-                       ( sizeof("(=*)") - 1 );
+                       STRLENOF("(=*)");
                fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 128, op->o_tmpmemctx );
 
                snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=*)",
                        f->f_sub_desc->ad_cname.bv_val );
 
                if ( f->f_sub_initial.bv_val != NULL ) {
+                       ber_len_t tmplen;
+
                        len = fstr->bv_len;
 
                        filter_escape_value_x( &f->f_sub_initial, &tmp, op->o_tmpmemctx );
+                       tmplen = tmp.bv_len ? tmp.bv_len : STRLENOF( "(null)" );
 
-                       fstr->bv_len += tmp.bv_len;
-                       fstr->bv_val = op->o_tmprealloc( fstr->bv_val, fstr->bv_len + 1,
-                               op->o_tmpmemctx );
+                       fstr->bv_len += tmplen;
+                       fstr->bv_val = op->o_tmprealloc( fstr->bv_val,
+                               fstr->bv_len + 1, op->o_tmpmemctx );
 
-                       snprintf( &fstr->bv_val[len-2], tmp.bv_len+3,
+                       snprintf( &fstr->bv_val[len-2],
+                               tmplen + STRLENOF( /*(*/ "*)" ) + 1,
                                /* "(attr=" */ "%s*)",
                                tmp.bv_len ? tmp.bv_val : "(null)");
 
@@ -641,15 +661,19 @@ filter2bv_x( Operation *op, Filter *f, struct berval *fstr )
 
                if ( f->f_sub_any != NULL ) {
                        for ( i = 0; f->f_sub_any[i].bv_val != NULL; i++ ) {
+                               ber_len_t tmplen;
+
                                len = fstr->bv_len;
                                filter_escape_value_x( &f->f_sub_any[i],
                                        &tmp, op->o_tmpmemctx );
+                               tmplen = tmp.bv_len ? tmp.bv_len : STRLENOF( "(null)" );
 
-                               fstr->bv_len += tmp.bv_len + 1;
-                               fstr->bv_val = op->o_tmprealloc( fstr->bv_val, fstr->bv_len + 1,
-                                       op->o_tmpmemctx );
+                               fstr->bv_len += tmplen + STRLENOF( /*(*/ ")" );
+                               fstr->bv_val = op->o_tmprealloc( fstr->bv_val,
+                                       fstr->bv_len + 1, op->o_tmpmemctx );
 
-                               snprintf( &fstr->bv_val[len-1], tmp.bv_len+3,
+                               snprintf( &fstr->bv_val[len-1],
+                                       tmplen + STRLENOF( /*(*/ "*)" ) + 1,
                                        /* "(attr=[init]*[any*]" */ "%s*)",
                                        tmp.bv_len ? tmp.bv_val : "(null)");
                                ber_memfree_x( tmp.bv_val, op->o_tmpmemctx );
@@ -657,15 +681,19 @@ filter2bv_x( Operation *op, Filter *f, struct berval *fstr )
                }
 
                if ( f->f_sub_final.bv_val != NULL ) {
+                       ber_len_t tmplen;
+
                        len = fstr->bv_len;
 
                        filter_escape_value_x( &f->f_sub_final, &tmp, op->o_tmpmemctx );
+                       tmplen = tmp.bv_len ? tmp.bv_len : STRLENOF( "(null)" );
 
-                       fstr->bv_len += tmp.bv_len;
-                       fstr->bv_val = op->o_tmprealloc( fstr->bv_val, fstr->bv_len + 1,
-                               op->o_tmpmemctx );
+                       fstr->bv_len += tmplen;
+                       fstr->bv_val = op->o_tmprealloc( fstr->bv_val,
+                               fstr->bv_len + 1, op->o_tmpmemctx );
 
-                       snprintf( &fstr->bv_val[len-1], tmp.bv_len+3,
+                       snprintf( &fstr->bv_val[len-1],
+                               tmplen + STRLENOF( /*(*/ ")" ) + 1,
                                /* "(attr=[init*][any*]" */ "%s)",
                                tmp.bv_len ? tmp.bv_val : "(null)");
 
@@ -676,7 +704,7 @@ filter2bv_x( Operation *op, Filter *f, struct berval *fstr )
 
        case LDAP_FILTER_PRESENT:
                fstr->bv_len = f->f_desc->ad_cname.bv_len +
-                       ( sizeof("(=*)") - 1 );
+                       STRLENOF("(=*)");
                fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx );
 
                snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=*)",
@@ -686,7 +714,7 @@ filter2bv_x( Operation *op, Filter *f, struct berval *fstr )
        case LDAP_FILTER_AND:
        case LDAP_FILTER_OR:
        case LDAP_FILTER_NOT:
-               fstr->bv_len = sizeof("(%)") - 1;
+               fstr->bv_len = STRLENOF("(%)");
                fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 128, op->o_tmpmemctx );
 
                snprintf( fstr->bv_val, fstr->bv_len + 1, "(%c)",
@@ -702,7 +730,8 @@ filter2bv_x( Operation *op, Filter *f, struct berval *fstr )
                        fstr->bv_val = op->o_tmprealloc( fstr->bv_val, fstr->bv_len + 1,
                                op->o_tmpmemctx );
 
-                       snprintf( &fstr->bv_val[len-1], tmp.bv_len + 2, 
+                       snprintf( &fstr->bv_val[len-1],
+                               tmp.bv_len + STRLENOF( /*(*/ ")" ) + 1, 
                                /*"("*/ "%s)", tmp.bv_val );
 
                        op->o_tmpfree( tmp.bv_val, op->o_tmpmemctx );
@@ -711,29 +740,34 @@ filter2bv_x( Operation *op, Filter *f, struct berval *fstr )
                break;
 
        case LDAP_FILTER_EXT: {
-                       struct berval ad;
-                       filter_escape_value_x( &f->f_mr_value, &tmp, op->o_tmpmemctx );
-
-                       if ( f->f_mr_desc ) {
-                               ad = f->f_mr_desc->ad_cname;
-                       } else {
-                               ad.bv_len = 0;
-                               ad.bv_val = "";
-                       }
-                       
-                       fstr->bv_len = ad.bv_len +
-                               ( f->f_mr_dnattrs ? sizeof(":dn")-1 : 0 ) +
-                               ( f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_len+1 : 0 ) +
-                               tmp.bv_len + ( sizeof("(:=)") - 1 );
-                       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)",
-                               ad.bv_val,
-                               f->f_mr_dnattrs ? ":dn" : "",
-                               f->f_mr_rule_text.bv_len ? ":" : "",
-                               f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_val : "",
-                               tmp.bv_len ? tmp.bv_val : "(null)");
-                       ber_memfree_x( tmp.bv_val, op->o_tmpmemctx );
+               struct berval ad;
+
+               filter_escape_value_x( &f->f_mr_value, &tmp, op->o_tmpmemctx );
+               /* NOTE: tmp can legitimately be NULL (meaning empty) 
+                * since in a Filter values in MRAs are supposed
+                * to have been normalized, meaning that an empty value
+                * is legal for that attribute's syntax */
+
+               if ( f->f_mr_desc ) {
+                       ad = f->f_mr_desc->ad_cname;
+               } else {
+                       ad.bv_len = 0;
+                       ad.bv_val = "";
+               }
+               
+               fstr->bv_len = ad.bv_len +
+                       ( f->f_mr_dnattrs ? STRLENOF(":dn") : 0 ) +
+                       ( f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_len+1 : 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)",
+                       ad.bv_val,
+                       f->f_mr_dnattrs ? ":dn" : "",
+                       f->f_mr_rule_text.bv_len ? ":" : "",
+                       f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_val : "",
+                       tmp.bv_len ? tmp.bv_val : "" );
+               ber_memfree_x( tmp.bv_val, op->o_tmpmemctx );
                } break;
 
        case SLAPD_FILTER_COMPUTED:
@@ -777,6 +811,81 @@ filter2bv( Filter *f, struct berval *fstr )
        filter2bv_x( &op, f, fstr );
 }
 
+Filter *
+filter_dup( Filter *f, void *memctx )
+{
+       BerMemoryFunctions *mf = &slap_sl_mfuncs;
+       Filter *n;
+
+       if ( !f )
+               return NULL;
+
+       n = mf->bmf_malloc( sizeof(Filter), memctx );
+       n->f_choice = f->f_choice;
+       n->f_next = NULL;
+
+       switch( f->f_choice ) {
+       case SLAPD_FILTER_COMPUTED:
+               n->f_result = f->f_result;
+               break;
+       case LDAP_FILTER_PRESENT:
+               n->f_desc = f->f_desc;
+               break;
+       case LDAP_FILTER_EQUALITY:
+       case LDAP_FILTER_GE:
+       case LDAP_FILTER_LE:
+       case LDAP_FILTER_APPROX:
+               /* Should this be ava_dup() ? */
+               n->f_ava = mf->bmf_calloc( 1, sizeof(AttributeAssertion), memctx );
+               *n->f_ava = *f->f_ava;
+               ber_dupbv_x( &n->f_av_value, &f->f_av_value, memctx );
+               break;
+       case LDAP_FILTER_SUBSTRINGS:
+               n->f_sub = mf->bmf_calloc( 1, sizeof(SubstringsAssertion), memctx );
+               n->f_sub_desc = f->f_sub_desc;
+               if ( !BER_BVISNULL( &f->f_sub_initial ))
+                       ber_dupbv_x( &n->f_sub_initial, &f->f_sub_initial, memctx );
+               if ( f->f_sub_any ) {
+                       int i;
+                       for ( i = 0; !BER_BVISNULL( &f->f_sub_any[i] ); i++ );
+                       n->f_sub_any = mf->bmf_malloc(( i+1 )*sizeof( struct berval ),
+                               memctx );
+                       for ( i = 0; !BER_BVISNULL( &f->f_sub_any[i] ); i++ ) {
+                               ber_dupbv_x( &n->f_sub_any[i], &f->f_sub_any[i], memctx );
+                       }
+                       BER_BVZERO( &n->f_sub_any[i] );
+               }
+               if ( !BER_BVISNULL( &f->f_sub_final ))
+                       ber_dupbv_x( &n->f_sub_final, &f->f_sub_final, memctx );
+               break;
+       case LDAP_FILTER_EXT: {
+               /* Should this be mra_dup() ? */
+               ber_len_t length;
+               length = sizeof(MatchingRuleAssertion);
+               if ( !BER_BVISNULL( &f->f_mr_rule_text ))
+                       length += f->f_mr_rule_text.bv_len + 1;
+               n->f_mra = mf->bmf_calloc( 1, length, memctx );
+               *n->f_mra = *f->f_mra;
+               ber_dupbv_x( &n->f_mr_value, &f->f_mr_value, memctx );
+               if ( !BER_BVISNULL( &f->f_mr_rule_text )) {
+                       n->f_mr_rule_text.bv_val = (char *)(n->f_mra+1);
+                       AC_MEMCPY(n->f_mr_rule_text.bv_val,
+                               f->f_mr_rule_text.bv_val, f->f_mr_rule_text.bv_len );
+               }
+               } break;
+       case LDAP_FILTER_AND:
+       case LDAP_FILTER_OR:
+       case LDAP_FILTER_NOT: {
+               Filter **p;
+               for ( p = &n->f_list, f = f->f_list; f; f = f->f_next ) {
+                       *p = filter_dup( f, memctx );
+                       p = &(*p)->f_next;
+               }
+               } break;
+       }
+       return n;
+}
+
 static int
 get_simple_vrFilter(
        Operation *op,
@@ -1041,12 +1150,12 @@ vrFilter2bv( Operation *op, ValuesReturnFilter *vrf, struct berval *fstr )
        ber_len_t len;
 
        if ( vrf == NULL ) {
-               ber_str2bv_x( "No filter!", sizeof("No filter!")-1,
+               ber_str2bv_x( "No filter!", STRLENOF("No filter!"),
                        1, fstr, op->o_tmpmemctx );
                return;
        }
 
-       fstr->bv_len = sizeof("()") - 1;
+       fstr->bv_len = STRLENOF("()");
        fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 128, op->o_tmpmemctx );
 
        snprintf( fstr->bv_val, fstr->bv_len + 1, "()");
@@ -1074,7 +1183,7 @@ simple_vrFilter2bv( Operation *op, ValuesReturnFilter *vrf, struct berval *fstr
        ber_len_t len;
 
        if ( vrf == NULL ) {
-               ber_str2bv_x( "No filter!", sizeof("No filter!")-1, 1, fstr,
+               ber_str2bv_x( "No filter!", STRLENOF("No filter!"), 1, fstr,
                        op->o_tmpmemctx );
                return;
        }
@@ -1084,7 +1193,7 @@ simple_vrFilter2bv( Operation *op, ValuesReturnFilter *vrf, struct berval *fstr
                filter_escape_value_x( &vrf->vrf_av_value, &tmp, op->o_tmpmemctx );
 
                fstr->bv_len = vrf->vrf_av_desc->ad_cname.bv_len +
-                       tmp.bv_len + ( sizeof("(=)") - 1 );
+                       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)",
@@ -1098,7 +1207,7 @@ simple_vrFilter2bv( Operation *op, ValuesReturnFilter *vrf, struct berval *fstr
                filter_escape_value_x( &vrf->vrf_av_value, &tmp, op->o_tmpmemctx );
 
                fstr->bv_len = vrf->vrf_av_desc->ad_cname.bv_len +
-                       tmp.bv_len + ( sizeof("(>=)") - 1 );
+                       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)",
@@ -1112,7 +1221,7 @@ simple_vrFilter2bv( Operation *op, ValuesReturnFilter *vrf, struct berval *fstr
                filter_escape_value_x( &vrf->vrf_av_value, &tmp, op->o_tmpmemctx );
 
                fstr->bv_len = vrf->vrf_av_desc->ad_cname.bv_len +
-                       tmp.bv_len + ( sizeof("(<=)") - 1 );
+                       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)",
@@ -1126,7 +1235,7 @@ simple_vrFilter2bv( Operation *op, ValuesReturnFilter *vrf, struct berval *fstr
                filter_escape_value_x( &vrf->vrf_av_value, &tmp, op->o_tmpmemctx );
 
                fstr->bv_len = vrf->vrf_av_desc->ad_cname.bv_len +
-                       tmp.bv_len + ( sizeof("(~=)") - 1 );
+                       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)",
@@ -1137,7 +1246,7 @@ simple_vrFilter2bv( Operation *op, ValuesReturnFilter *vrf, struct berval *fstr
 
        case LDAP_FILTER_SUBSTRINGS:
                fstr->bv_len = vrf->vrf_sub_desc->ad_cname.bv_len +
-                       ( sizeof("(=*)") - 1 );
+                       STRLENOF("(=*)");
                fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 128, op->o_tmpmemctx );
 
                snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=*)",
@@ -1197,7 +1306,7 @@ simple_vrFilter2bv( Operation *op, ValuesReturnFilter *vrf, struct berval *fstr
 
        case LDAP_FILTER_PRESENT:
                fstr->bv_len = vrf->vrf_desc->ad_cname.bv_len +
-                       ( sizeof("(=*)") - 1 );
+                       STRLENOF("(=*)");
                fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx );
 
                snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=*)",
@@ -1216,10 +1325,10 @@ simple_vrFilter2bv( Operation *op, ValuesReturnFilter *vrf, struct berval *fstr
                }
                        
                fstr->bv_len = ad.bv_len +
-                       ( vrf->vrf_mr_dnattrs ? sizeof(":dn")-1 : 0 ) +
+                       ( vrf->vrf_mr_dnattrs ? STRLENOF(":dn") : 0 ) +
                        ( vrf->vrf_mr_rule_text.bv_len
                                ? vrf->vrf_mr_rule_text.bv_len+1 : 0 ) +
-                       tmp.bv_len + ( sizeof("(:=)") - 1 );
+                       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)",
@@ -1238,15 +1347,15 @@ simple_vrFilter2bv( Operation *op, ValuesReturnFilter *vrf, struct berval *fstr
                        vrf->vrf_result == LDAP_COMPARE_TRUE ? "(?=true)" :
                        vrf->vrf_result == SLAPD_COMPARE_UNDEFINED
                                ? "(?=undefined)" : "(?=error)",
-                       vrf->vrf_result == LDAP_COMPARE_FALSE ? sizeof("(?=false)")-1 :
-                       vrf->vrf_result == LDAP_COMPARE_TRUE ? sizeof("(?=true)")-1 :
+                       vrf->vrf_result == LDAP_COMPARE_FALSE ? STRLENOF("(?=false)") :
+                       vrf->vrf_result == LDAP_COMPARE_TRUE ? STRLENOF("(?=true)") :
                        vrf->vrf_result == SLAPD_COMPARE_UNDEFINED
-                               ? sizeof("(?=undefined)")-1 : sizeof("(?=error)")-1,
+                               ? STRLENOF("(?=undefined)") : STRLENOF("(?=error)"),
                        1, fstr, op->o_tmpmemctx );
                break;
 
        default:
-               ber_str2bv_x( "(?=unknown)", sizeof("(?=unknown)")-1,
+               ber_str2bv_x( "(?=unknown)", STRLENOF("(?=unknown)"),
                        1, fstr, op->o_tmpmemctx );
                break;
        }