--- servers/slapd/filter.c 2008/09/05 22:00:37 1.150 +++ servers/slapd/filter.c 2011/01/29 13:16:02 1.160 @@ -1,8 +1,8 @@ /* filter.c - routines for parsing and dealing with filters */ -/* $OpenLDAP: pkg/ldap/servers/slapd/filter.c,v 1.149 2008/02/18 18:47:07 ando Exp $ */ +/* $OpenLDAP: pkg/ldap/servers/slapd/filter.c,v 1.159 2011/01/29 11:29:20 ando Exp $ */ /* This work is part of OpenLDAP Software . * - * Copyright 1998-2008 The OpenLDAP Foundation. + * Copyright 1998-2011 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -348,7 +348,7 @@ get_ssa( { ber_tag_t tag; ber_len_t len; - ber_tag_t rc; + int rc; struct berval desc, value, nvalue; char *last; SubstringsAssertion ssa; @@ -385,14 +385,24 @@ get_ssa( rc = LDAP_PROTOCOL_ERROR; + /* If there is no substring matching rule, there's nothing + * we can do with this filter. But we continue to parse it + * for logging purposes. + */ + if ( ssa.sa_desc->ad_type->sat_substr == NULL ) { + f->f_choice |= SLAPD_FILTER_UNDEFINED; + Debug( LDAP_DEBUG_FILTER, + "get_ssa: no substring matching rule for attributeType %s\n", + desc.bv_val, 0, 0 ); + } + for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT; tag = ber_next_element( ber, &len, last ) ) { unsigned usage; - rc = ber_scanf( ber, "m", &value ); - if ( rc == LBER_ERROR ) { + if ( ber_scanf( ber, "m", &value ) == LBER_ERROR ) { rc = SLAPD_DISCONNECT; goto return_error; } @@ -444,7 +454,13 @@ get_ssa( rc = asserted_value_validate_normalize( ssa.sa_desc, ssa.sa_desc->ad_type->sat_equality, usage, &value, &nvalue, text, op->o_tmpmemctx ); - if( rc != LDAP_SUCCESS ) goto return_error; + if( rc != LDAP_SUCCESS ) { + f->f_choice |= SLAPD_FILTER_UNDEFINED; + Debug( LDAP_DEBUG_FILTER, + "get_ssa: illegal value for attributeType %s (%d) %s\n", + desc.bv_val, rc, *text ); + ber_dupbv_x( &nvalue, &value, op->o_tmpmemctx ); + } switch ( tag ) { case LDAP_SUBSTRING_INITIAL: @@ -492,7 +508,7 @@ return_error: } void -filter_free_x( Operation *op, Filter *f ) +filter_free_x( Operation *op, Filter *f, int freeme ) { Filter *p, *next; @@ -504,6 +520,8 @@ filter_free_x( Operation *op, Filter *f switch ( f->f_choice ) { case LDAP_FILTER_PRESENT: + if ( f->f_desc->ad_flags & SLAP_DESC_TEMPORARY ) + op->o_tmpfree( f->f_desc, op->o_tmpmemctx ); break; case LDAP_FILTER_EQUALITY: @@ -531,7 +549,7 @@ filter_free_x( Operation *op, Filter *f case LDAP_FILTER_NOT: for ( p = f->f_list; p != NULL; p = next ) { next = p->f_next; - filter_free_x( op, p ); + filter_free_x( op, p, 1 ); } break; @@ -548,7 +566,9 @@ filter_free_x( Operation *op, Filter *f break; } - op->o_tmpfree( f, op->o_tmpmemctx ); + if ( freeme ) { + op->o_tmpfree( f, op->o_tmpmemctx ); + } } void @@ -560,12 +580,18 @@ filter_free( Filter *f ) op.o_hdr = &ohdr; op.o_tmpmemctx = slap_sl_context( f ); op.o_tmpmfuncs = &slap_sl_mfuncs; - filter_free_x( &op, f ); + filter_free_x( &op, f, 1 ); } 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; struct berval tmp, value; @@ -575,10 +601,12 @@ filter2bv_x( Operation *op, Filter *f, s ber_bvundefined = BER_BVC( "(?=undefined)" ), ber_bverror = BER_BVC( "(?=error)" ), ber_bvunknown = BER_BVC( "(?=unknown)" ), - ber_bvnone = BER_BVC( "(?=none)" ); + ber_bvnone = BER_BVC( "(?=none)" ), + ber_bvF = BER_BVC( "(|)" ), + ber_bvT = BER_BVC( "(&)" ); ber_len_t len; ber_tag_t choice; - int undef; + int undef, undef2; char *sign; if ( f == NULL ) { @@ -587,6 +615,7 @@ filter2bv_x( Operation *op, Filter *f, s } undef = f->f_choice & SLAPD_FILTER_UNDEFINED; + undef2 = (undef && !noundef); choice = f->f_choice & SLAPD_FILTER_MASK; switch ( choice ) { @@ -624,12 +653,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 : "" ); @@ -643,12 +672,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 ) { @@ -717,13 +746,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; @@ -740,7 +769,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, @@ -772,13 +801,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 ? ":" : "", @@ -790,11 +820,11 @@ simple: case SLAPD_FILTER_COMPUTED: switch ( f->f_result ) { case LDAP_COMPARE_FALSE: - tmp = ber_bvfalse; + tmp = ( noundef ? ber_bvF : ber_bvfalse ); break; case LDAP_COMPARE_TRUE: - tmp = ber_bvtrue; + tmp = ( noundef ? ber_bvT : ber_bvtrue ); break; case SLAPD_COMPARE_UNDEFINED: @@ -818,6 +848,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; @@ -825,7 +861,7 @@ filter2bv( Filter *f, struct berval *fst op.o_tmpmemctx = NULL; op.o_tmpmfuncs = &ch_mfuncs; - filter2bv_x( &op, f, fstr ); + filter2bv_undef_x( &op, f, noundef, fstr ); } Filter *