1 /* filter.c - routines for parsing and dealing with filters */
4 * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
5 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
12 #include <ac/socket.h>
13 #include <ac/string.h>
17 static int get_filter_list(
26 SubstringsAssertion **s,
29 static void simple_vrFilter2bv(
31 ValuesReturnFilter *f,
32 struct berval *fstr );
34 static int get_simple_vrFilter(
37 ValuesReturnFilter **f,
53 LDAP_LOG( FILTER, ENTRY, "get_filter: conn %d\n", op->o_connid, 0, 0 );
55 Debug( LDAP_DEBUG_FILTER, "begin get_filter\n", 0, 0, 0 );
58 * A filter looks like this coming in:
60 * and [0] SET OF Filter,
61 * or [1] SET OF Filter,
63 * equalityMatch [3] AttributeValueAssertion,
64 * substrings [4] SubstringFilter,
65 * greaterOrEqual [5] AttributeValueAssertion,
66 * lessOrEqual [6] AttributeValueAssertion,
67 * present [7] AttributeType,,
68 * approxMatch [8] AttributeValueAssertion
69 * extensibleMatch [9] MatchingRuleAssertion
72 * SubstringFilter ::= SEQUENCE {
74 * SEQUENCE OF CHOICE {
75 * initial [0] IA5String,
81 * MatchingRuleAssertion ::= SEQUENCE {
82 * matchingRule [1] MatchingRuleId OPTIONAL,
83 * type [2] AttributeDescription OPTIONAL,
84 * matchValue [3] AssertionValue,
85 * dnAttributes [4] BOOLEAN DEFAULT FALSE
90 tag = ber_peek_tag( ber, &len );
92 if( tag == LBER_ERROR ) {
93 *text = "error decoding filter";
94 return SLAPD_DISCONNECT;
102 switch ( f.f_choice ) {
103 case LDAP_FILTER_EQUALITY:
105 LDAP_LOG( FILTER, DETAIL2,
106 "get_filter: conn %d EQUALITY\n", op->o_connid, 0, 0 );
108 Debug( LDAP_DEBUG_FILTER, "EQUALITY\n", 0, 0, 0 );
110 err = get_ava( op, ber, &f.f_ava, SLAP_MR_EQUALITY, text );
111 if ( err != LDAP_SUCCESS ) {
115 assert( f.f_ava != NULL );
118 case LDAP_FILTER_SUBSTRINGS:
120 LDAP_LOG( FILTER, DETAIL1,
121 "get_filter: conn %d SUBSTRINGS\n", op->o_connid, 0, 0 );
123 Debug( LDAP_DEBUG_FILTER, "SUBSTRINGS\n", 0, 0, 0 );
125 err = get_ssa( op, ber, &f.f_sub, text );
126 if( err != LDAP_SUCCESS ) {
129 assert( f.f_sub != NULL );
134 LDAP_LOG( FILTER, DETAIL1,
135 "get_filter: conn %d GE\n", op->o_connid, 0, 0 );
137 Debug( LDAP_DEBUG_FILTER, "GE\n", 0, 0, 0 );
139 err = get_ava( op, ber, &f.f_ava, SLAP_MR_ORDERING, text );
140 if ( err != LDAP_SUCCESS ) {
143 assert( f.f_ava != NULL );
148 LDAP_LOG( FILTER, DETAIL1,
149 "get_filter: conn %d LE\n", op->o_connid, 0, 0 );
151 Debug( LDAP_DEBUG_FILTER, "LE\n", 0, 0, 0 );
153 err = get_ava( op, ber, &f.f_ava, SLAP_MR_ORDERING, text );
154 if ( err != LDAP_SUCCESS ) {
157 assert( f.f_ava != NULL );
160 case LDAP_FILTER_PRESENT: {
164 LDAP_LOG( FILTER, DETAIL1,
165 "get_filter: conn %d PRESENT\n", op->o_connid, 0, 0 );
167 Debug( LDAP_DEBUG_FILTER, "PRESENT\n", 0, 0, 0 );
169 if ( ber_scanf( ber, "m", &type ) == LBER_ERROR ) {
170 err = SLAPD_DISCONNECT;
171 *text = "error decoding filter";
176 err = slap_bv2ad( &type, &f.f_desc, text );
178 if( err != LDAP_SUCCESS ) {
179 /* unrecognized attribute description or other error */
180 f.f_choice = SLAPD_FILTER_COMPUTED;
181 f.f_result = LDAP_COMPARE_FALSE;
187 assert( f.f_desc != NULL );
190 case LDAP_FILTER_APPROX:
192 LDAP_LOG( FILTER, DETAIL1,
193 "get_filter: conn %d APPROX\n", op->o_connid, 0, 0 );
195 Debug( LDAP_DEBUG_FILTER, "APPROX\n", 0, 0, 0 );
197 err = get_ava( op, ber, &f.f_ava, SLAP_MR_EQUALITY_APPROX, text );
198 if ( err != LDAP_SUCCESS ) {
201 assert( f.f_ava != NULL );
204 case LDAP_FILTER_AND:
206 LDAP_LOG( FILTER, DETAIL1,
207 "get_filter: conn %d AND\n", op->o_connid, 0, 0 );
209 Debug( LDAP_DEBUG_FILTER, "AND\n", 0, 0, 0 );
211 err = get_filter_list( op, ber, &f.f_and, text );
212 if ( err != LDAP_SUCCESS ) {
215 if ( f.f_and == NULL ) {
216 f.f_choice = SLAPD_FILTER_COMPUTED;
217 f.f_result = LDAP_COMPARE_TRUE;
219 /* no assert - list could be empty */
224 LDAP_LOG( FILTER, DETAIL1,
225 "get_filter: conn %d OR\n", op->o_connid, 0, 0 );
227 Debug( LDAP_DEBUG_FILTER, "OR\n", 0, 0, 0 );
229 err = get_filter_list( op, ber, &f.f_or, text );
230 if ( err != LDAP_SUCCESS ) {
233 if ( f.f_or == NULL ) {
234 f.f_choice = SLAPD_FILTER_COMPUTED;
235 f.f_result = LDAP_COMPARE_FALSE;
237 /* no assert - list could be empty */
240 case LDAP_FILTER_NOT:
242 LDAP_LOG( FILTER, DETAIL1,
243 "get_filter: conn %d NOT\n", op->o_connid, 0, 0 );
245 Debug( LDAP_DEBUG_FILTER, "NOT\n", 0, 0, 0 );
247 (void) ber_skip_tag( ber, &len );
248 err = get_filter( op, ber, &f.f_not, text );
249 if ( err != LDAP_SUCCESS ) {
253 assert( f.f_not != NULL );
254 if ( f.f_not->f_choice == SLAPD_FILTER_COMPUTED ) {
255 int fresult = f.f_not->f_result;
256 f.f_choice = SLAPD_FILTER_COMPUTED;
257 op->o_tmpfree( f.f_not, op->o_tmpmemctx );
261 case LDAP_COMPARE_TRUE:
262 f.f_result = LDAP_COMPARE_FALSE;
264 case LDAP_COMPARE_FALSE:
265 f.f_result = LDAP_COMPARE_TRUE;
268 /* (!Undefined) is Undefined */
273 case LDAP_FILTER_EXT:
275 LDAP_LOG( FILTER, DETAIL1,
276 "get_filter: conn %d EXTENSIBLE\n", op->o_connid, 0, 0 );
278 Debug( LDAP_DEBUG_FILTER, "EXTENSIBLE\n", 0, 0, 0 );
281 err = get_mra( op, ber, &f.f_mra, text );
282 if ( err != LDAP_SUCCESS ) {
286 assert( f.f_mra != NULL );
290 (void) ber_scanf( ber, "x" ); /* skip the element */
292 LDAP_LOG( FILTER, ERR,
293 "get_filter: conn %d unknown filter type=%lu\n",
294 op->o_connid, f.f_choice, 0 );
296 Debug( LDAP_DEBUG_ANY, "get_filter: unknown filter type=%lu\n",
299 f.f_choice = SLAPD_FILTER_COMPUTED;
300 f.f_result = SLAPD_COMPARE_UNDEFINED;
304 if( err != LDAP_SUCCESS && err != SLAPD_DISCONNECT ) {
307 f.f_choice = SLAPD_FILTER_COMPUTED;
308 f.f_result = SLAPD_COMPARE_UNDEFINED;
312 if ( err == LDAP_SUCCESS ) {
313 *filt = op->o_tmpalloc( sizeof(f), op->o_tmpmemctx );
318 LDAP_LOG( FILTER, DETAIL2,
319 "get_filter: conn %d exit\n", op->o_connid, 0, 0 );
321 Debug( LDAP_DEBUG_FILTER, "end get_filter %d\n", err, 0, 0 );
328 get_filter_list( Operation *op, BerElement *ber,
339 LDAP_LOG( FILTER, ENTRY,
340 "get_filter_list: conn %d start\n", op->o_connid, 0, 0 );
342 Debug( LDAP_DEBUG_FILTER, "begin get_filter_list\n", 0, 0, 0 );
345 for ( tag = ber_first_element( ber, &len, &last );
347 tag = ber_next_element( ber, &len, last ) )
349 err = get_filter( op, ber, new, text );
350 if ( err != LDAP_SUCCESS )
352 new = &(*new)->f_next;
357 LDAP_LOG( FILTER, ENTRY,
358 "get_filter_list: conn %d exit\n", op->o_connid, 0, 0 );
360 Debug( LDAP_DEBUG_FILTER, "end get_filter_list\n", 0, 0, 0 );
362 return( LDAP_SUCCESS );
369 SubstringsAssertion **out,
375 struct berval desc, value, nvalue;
377 SubstringsAssertion ssa;
379 *text = "error decoding filter";
382 LDAP_LOG( FILTER, ENTRY,
383 "get_ssa: conn %d begin\n", op->o_connid, 0, 0 );
385 Debug( LDAP_DEBUG_FILTER, "begin get_ssa\n", 0, 0, 0 );
387 if ( ber_scanf( ber, "{m" /*}*/, &desc ) == LBER_ERROR ) {
388 return SLAPD_DISCONNECT;
394 ssa.sa_initial.bv_val = NULL;
396 ssa.sa_final.bv_val = NULL;
398 rc = slap_bv2ad( &desc, &ssa.sa_desc, text );
400 if( rc != LDAP_SUCCESS ) {
401 /* skip over the rest of this filter */
402 for ( tag = ber_first_element( ber, &len, &last );
404 tag = ber_next_element( ber, &len, last ) ) {
405 ber_scanf( ber, "x" );
410 rc = LDAP_PROTOCOL_ERROR;
412 for ( tag = ber_first_element( ber, &len, &last );
414 tag = ber_next_element( ber, &len, last ) )
418 rc = ber_scanf( ber, "m", &value );
419 if ( rc == LBER_ERROR ) {
420 rc = SLAPD_DISCONNECT;
424 if ( value.bv_val == NULL || value.bv_len == 0 ) {
425 rc = LDAP_INVALID_SYNTAX;
430 case LDAP_SUBSTRING_INITIAL:
431 usage = SLAP_MR_SUBSTR_INITIAL;
434 case LDAP_SUBSTRING_ANY:
435 usage = SLAP_MR_SUBSTR_ANY;
438 case LDAP_SUBSTRING_FINAL:
439 usage = SLAP_MR_SUBSTR_FINAL;
443 rc = LDAP_PROTOCOL_ERROR;
446 LDAP_LOG( FILTER, ERR,
447 "get_filter_substring: conn %d unknown substring choice=%ld\n",
448 op->o_connid, (long)tag, 0 );
450 Debug( LDAP_DEBUG_FILTER,
451 " unknown substring choice=%ld\n",
458 /* validate/normalize using equality matching rule validator! */
459 rc = asserted_value_validate_normalize(
460 ssa.sa_desc, ssa.sa_desc->ad_type->sat_equality,
461 usage, &value, &nvalue, text, op->o_tmpmemctx );
463 if( rc != LDAP_SUCCESS ) {
467 rc = LDAP_PROTOCOL_ERROR;
470 case LDAP_SUBSTRING_INITIAL:
472 LDAP_LOG( FILTER, DETAIL1,
473 "get_ssa: conn %d INITIAL\n",
474 op->o_connid, 0, 0 );
476 Debug( LDAP_DEBUG_FILTER, " INITIAL\n", 0, 0, 0 );
479 if ( ssa.sa_initial.bv_val != NULL
480 || ssa.sa_any != NULL
481 || ssa.sa_final.bv_val != NULL )
483 sl_free( nvalue.bv_val, op->o_tmpmemctx );
487 ssa.sa_initial = nvalue;
490 case LDAP_SUBSTRING_ANY:
492 LDAP_LOG( FILTER, DETAIL1,
493 "get_ssa: conn %d ANY\n",
494 op->o_connid, 0, 0 );
496 Debug( LDAP_DEBUG_FILTER, " ANY\n", 0, 0, 0 );
499 if ( ssa.sa_final.bv_val != NULL ) {
500 sl_free( nvalue.bv_val, op->o_tmpmemctx );
504 ber_bvarray_add_x( &ssa.sa_any, &nvalue, op->o_tmpmemctx );
507 case LDAP_SUBSTRING_FINAL:
509 LDAP_LOG( FILTER, DETAIL1,
510 "get_ssa: conn %d FINAL\n",
511 op->o_connid, 0, 0 );
513 Debug( LDAP_DEBUG_FILTER, " FINAL\n", 0, 0, 0 );
516 if ( ssa.sa_final.bv_val != NULL ) {
517 sl_free( nvalue.bv_val, op->o_tmpmemctx );
521 ssa.sa_final = nvalue;
526 LDAP_LOG( FILTER, INFO,
527 "get_ssa: conn %d unknown substring type %ld\n",
528 op->o_connid, (long)tag, 0 );
530 Debug( LDAP_DEBUG_FILTER,
531 " unknown substring type=%ld\n",
536 sl_free( nvalue.bv_val, op->o_tmpmemctx );
540 LDAP_LOG( FILTER, INFO,
541 "get_ssa: conn %d error %ld\n",
542 op->o_connid, (long)rc, 0 );
544 Debug( LDAP_DEBUG_FILTER, " error=%ld\n",
547 sl_free( ssa.sa_initial.bv_val, op->o_tmpmemctx );
548 ber_bvarray_free_x( ssa.sa_any, op->o_tmpmemctx );
549 sl_free( ssa.sa_final.bv_val, op->o_tmpmemctx );
556 if( rc == LDAP_SUCCESS ) {
557 *out = op->o_tmpalloc( sizeof( ssa ), op->o_tmpmemctx );
562 LDAP_LOG( FILTER, ENTRY,
563 "get_ssa: conn %d exit\n", op->o_connid, 0, 0 );
565 Debug( LDAP_DEBUG_FILTER, "end get_ssa\n", 0, 0, 0 );
572 filter_free_x( Operation *op, Filter *f )
580 switch ( f->f_choice ) {
581 case LDAP_FILTER_PRESENT:
584 case LDAP_FILTER_EQUALITY:
587 case LDAP_FILTER_APPROX:
588 ava_free( op, f->f_ava, 1 );
591 case LDAP_FILTER_SUBSTRINGS:
592 if ( f->f_sub_initial.bv_val != NULL ) {
593 op->o_tmpfree( f->f_sub_initial.bv_val, op->o_tmpmemctx );
595 ber_bvarray_free_x( f->f_sub_any, op->o_tmpmemctx );
596 if ( f->f_sub_final.bv_val != NULL ) {
597 op->o_tmpfree( f->f_sub_final.bv_val, op->o_tmpmemctx );
599 op->o_tmpfree( f->f_sub, op->o_tmpmemctx );
602 case LDAP_FILTER_AND:
604 case LDAP_FILTER_NOT:
605 for ( p = f->f_list; p != NULL; p = next ) {
607 filter_free_x( op, p );
611 case LDAP_FILTER_EXT:
612 mra_free( op, f->f_mra, 1 );
615 case SLAPD_FILTER_COMPUTED:
620 LDAP_LOG( FILTER, ERR,
621 "filter_free: unknown filter type %lu\n", f->f_choice, 0, 0 );
623 Debug( LDAP_DEBUG_ANY, "filter_free: unknown filter type=%lu\n",
629 op->o_tmpfree( f, op->o_tmpmemctx );
633 filter_free( Filter *f )
637 op.o_tmpmemctx = sl_context( f );
638 op.o_tmpmfuncs = &sl_mfuncs;
639 filter_free_x( &op, f );
643 filter2bv_x( Operation *op, Filter *f, struct berval *fstr )
651 ber_str2bv_x( "No filter!", sizeof("No filter!")-1, 1, fstr, op->o_tmpmemctx );
655 switch ( f->f_choice ) {
656 case LDAP_FILTER_EQUALITY:
657 filter_escape_value_x( &f->f_av_value, &tmp, op->o_tmpmemctx );
659 fstr->bv_len = f->f_av_desc->ad_cname.bv_len +
660 tmp.bv_len + ( sizeof("(=)") - 1 );
661 fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx );
663 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=%s)",
664 f->f_av_desc->ad_cname.bv_val,
667 ber_memfree_x( tmp.bv_val, op->o_tmpmemctx );
671 filter_escape_value_x( &f->f_av_value, &tmp, op->o_tmpmemctx );
673 fstr->bv_len = f->f_av_desc->ad_cname.bv_len +
674 tmp.bv_len + ( sizeof("(>=)") - 1 );
675 fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx );
677 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s>=%s)",
678 f->f_av_desc->ad_cname.bv_val,
681 ber_memfree_x( tmp.bv_val, op->o_tmpmemctx );
685 filter_escape_value_x( &f->f_av_value, &tmp, op->o_tmpmemctx );
687 fstr->bv_len = f->f_av_desc->ad_cname.bv_len +
688 tmp.bv_len + ( sizeof("(<=)") - 1 );
689 fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx );
691 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s<=%s)",
692 f->f_av_desc->ad_cname.bv_val,
695 ber_memfree_x( tmp.bv_val, op->o_tmpmemctx );
698 case LDAP_FILTER_APPROX:
699 filter_escape_value_x( &f->f_av_value, &tmp, op->o_tmpmemctx );
701 fstr->bv_len = f->f_av_desc->ad_cname.bv_len +
702 tmp.bv_len + ( sizeof("(~=)") - 1 );
703 fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx );
705 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s~=%s)",
706 f->f_av_desc->ad_cname.bv_val,
708 ber_memfree_x( tmp.bv_val, op->o_tmpmemctx );
711 case LDAP_FILTER_SUBSTRINGS:
712 fstr->bv_len = f->f_sub_desc->ad_cname.bv_len +
713 ( sizeof("(=*)") - 1 );
714 fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 128, op->o_tmpmemctx );
716 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=*)",
717 f->f_sub_desc->ad_cname.bv_val );
719 if ( f->f_sub_initial.bv_val != NULL ) {
722 filter_escape_value_x( &f->f_sub_initial, &tmp, op->o_tmpmemctx );
724 fstr->bv_len += tmp.bv_len;
725 fstr->bv_val = op->o_tmprealloc( fstr->bv_val, fstr->bv_len + 1, op->o_tmpmemctx );
727 snprintf( &fstr->bv_val[len-2], tmp.bv_len+3,
728 /* "(attr=" */ "%s*)",
731 ber_memfree_x( tmp.bv_val, op->o_tmpmemctx );
734 if ( f->f_sub_any != NULL ) {
735 for ( i = 0; f->f_sub_any[i].bv_val != NULL; i++ ) {
737 filter_escape_value_x( &f->f_sub_any[i], &tmp, op->o_tmpmemctx );
739 fstr->bv_len += tmp.bv_len + 1;
740 fstr->bv_val = op->o_tmprealloc( fstr->bv_val, fstr->bv_len + 1, op->o_tmpmemctx );
742 snprintf( &fstr->bv_val[len-1], tmp.bv_len+3,
743 /* "(attr=[init]*[any*]" */ "%s*)",
745 ber_memfree_x( tmp.bv_val, op->o_tmpmemctx );
749 if ( f->f_sub_final.bv_val != NULL ) {
752 filter_escape_value_x( &f->f_sub_final, &tmp, op->o_tmpmemctx );
754 fstr->bv_len += tmp.bv_len;
755 fstr->bv_val = op->o_tmprealloc( fstr->bv_val, fstr->bv_len + 1, op->o_tmpmemctx );
757 snprintf( &fstr->bv_val[len-1], tmp.bv_len+3,
758 /* "(attr=[init*][any*]" */ "%s)",
761 ber_memfree_x( tmp.bv_val, op->o_tmpmemctx );
766 case LDAP_FILTER_PRESENT:
767 fstr->bv_len = f->f_desc->ad_cname.bv_len +
768 ( sizeof("(=*)") - 1 );
769 fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx );
771 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=*)",
772 f->f_desc->ad_cname.bv_val );
775 case LDAP_FILTER_AND:
777 case LDAP_FILTER_NOT:
778 fstr->bv_len = sizeof("(%)") - 1;
779 fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 128, op->o_tmpmemctx );
781 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%c)",
782 f->f_choice == LDAP_FILTER_AND ? '&' :
783 f->f_choice == LDAP_FILTER_OR ? '|' : '!' );
785 for ( p = f->f_list; p != NULL; p = p->f_next ) {
788 filter2bv_x( op, p, &tmp );
790 fstr->bv_len += tmp.bv_len;
791 fstr->bv_val = op->o_tmprealloc( fstr->bv_val, fstr->bv_len + 1, op->o_tmpmemctx );
793 snprintf( &fstr->bv_val[len-1], tmp.bv_len + 2,
794 /*"("*/ "%s)", tmp.bv_val );
796 op->o_tmpfree( tmp.bv_val, op->o_tmpmemctx );
801 case LDAP_FILTER_EXT: {
803 filter_escape_value_x( &f->f_mr_value, &tmp, op->o_tmpmemctx );
805 if ( f->f_mr_desc ) {
806 ad = f->f_mr_desc->ad_cname;
812 fstr->bv_len = ad.bv_len +
813 ( f->f_mr_dnattrs ? sizeof(":dn")-1 : 0 ) +
814 ( f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_len+1 : 0 ) +
815 tmp.bv_len + ( sizeof("(:=)") - 1 );
816 fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx );
818 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s%s%s%s:=%s)",
820 f->f_mr_dnattrs ? ":dn" : "",
821 f->f_mr_rule_text.bv_len ? ":" : "",
822 f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_val : "",
824 ber_memfree_x( tmp.bv_val, op->o_tmpmemctx );
827 case SLAPD_FILTER_COMPUTED:
829 f->f_result == LDAP_COMPARE_FALSE ? "(?=false)" :
830 f->f_result == LDAP_COMPARE_TRUE ? "(?=true)" :
831 f->f_result == SLAPD_COMPARE_UNDEFINED ? "(?=undefined)" :
833 f->f_result == LDAP_COMPARE_FALSE ? sizeof("(?=false)")-1 :
834 f->f_result == LDAP_COMPARE_TRUE ? sizeof("(?=true)")-1 :
835 f->f_result == SLAPD_COMPARE_UNDEFINED ? sizeof("(?=undefined)")-1 :
836 sizeof("(?=error)")-1,
837 1, fstr, op->o_tmpmemctx );
841 ber_str2bv_x( "(?=unknown)", sizeof("(?=unknown)")-1,
842 1, fstr, op->o_tmpmemctx );
848 filter2bv( Filter *f, struct berval *fstr )
851 op.o_tmpmemctx = NULL;
852 op.o_tmpmfuncs = &ch_mfuncs;
854 filter2bv_x( &op, f, fstr );
858 filter_escape_value_x(
867 i = in->bv_len * 3 + 1;
868 out->bv_val = ctx ? sl_malloc( i, ctx ) : ch_malloc( i );
871 for( i=0; i < in->bv_len ; i++ ) {
872 if( FILTER_ESCAPE(in->bv_val[i]) ) {
873 out->bv_val[out->bv_len++] = SLAP_ESCAPE_CHAR;
874 out->bv_val[out->bv_len++] = SLAP_ESCAPE_HI( in->bv_val[i] );
875 out->bv_val[out->bv_len++] = SLAP_ESCAPE_LO( in->bv_val[i] );
877 out->bv_val[out->bv_len++] = in->bv_val[i];
881 out->bv_val[out->bv_len] = '\0';
890 return filter_escape_value_x( in, out, NULL );
897 ValuesReturnFilter **filt,
903 ValuesReturnFilter vrf;
906 LDAP_LOG( FILTER, ENTRY,
907 "get_simple_vrFilter: conn %d\n", op->o_connid, 0, 0 );
909 Debug( LDAP_DEBUG_FILTER, "begin get_simple_vrFilter\n", 0, 0, 0 );
912 tag = ber_peek_tag( ber, &len );
914 if( tag == LBER_ERROR ) {
915 *text = "error decoding filter";
916 return SLAPD_DISCONNECT;
922 vrf.vrf_choice = tag;
924 switch ( vrf.vrf_choice ) {
925 case LDAP_FILTER_EQUALITY:
927 LDAP_LOG( FILTER, DETAIL2,
928 "get_simple_vrFilter: conn %d EQUALITY\n", op->o_connid, 0, 0 );
930 Debug( LDAP_DEBUG_FILTER, "EQUALITY\n", 0, 0, 0 );
932 err = get_ava( op, ber, &vrf.vrf_ava, SLAP_MR_EQUALITY, text );
933 if ( err != LDAP_SUCCESS ) {
937 assert( vrf.vrf_ava != NULL );
940 case LDAP_FILTER_SUBSTRINGS:
942 LDAP_LOG( FILTER, DETAIL1,
943 "get_simple_vrFilter: conn %d SUBSTRINGS\n", op->o_connid, 0, 0 );
945 Debug( LDAP_DEBUG_FILTER, "SUBSTRINGS\n", 0, 0, 0 );
947 err = get_ssa( op, ber, &vrf.vrf_sub, text );
952 LDAP_LOG( FILTER, DETAIL1,
953 "get_simple_vrFilter: conn %d GE\n", op->o_connid, 0, 0 );
955 Debug( LDAP_DEBUG_FILTER, "GE\n", 0, 0, 0 );
957 err = get_ava( op, ber, &vrf.vrf_ava, SLAP_MR_ORDERING, text );
958 if ( err != LDAP_SUCCESS ) {
965 LDAP_LOG( FILTER, DETAIL1,
966 "get_simple_vrFilter: conn %d LE\n", op->o_connid, 0, 0 );
968 Debug( LDAP_DEBUG_FILTER, "LE\n", 0, 0, 0 );
970 err = get_ava( op, ber, &vrf.vrf_ava, SLAP_MR_ORDERING, text );
971 if ( err != LDAP_SUCCESS ) {
976 case LDAP_FILTER_PRESENT: {
980 LDAP_LOG( FILTER, DETAIL1,
981 "get_simple_vrFilter: conn %d PRESENT\n", op->o_connid, 0, 0 );
983 Debug( LDAP_DEBUG_FILTER, "PRESENT\n", 0, 0, 0 );
985 if ( ber_scanf( ber, "m", &type ) == LBER_ERROR ) {
986 err = SLAPD_DISCONNECT;
987 *text = "error decoding filter";
992 err = slap_bv2ad( &type, &vrf.vrf_desc, text );
994 if( err != LDAP_SUCCESS ) {
995 /* unrecognized attribute description or other error */
996 vrf.vrf_choice = SLAPD_FILTER_COMPUTED;
997 vrf.vrf_result = LDAP_COMPARE_FALSE;
1003 case LDAP_FILTER_APPROX:
1005 LDAP_LOG( FILTER, DETAIL1,
1006 "get_simple_vrFilter: conn %d APPROX\n", op->o_connid, 0, 0 );
1008 Debug( LDAP_DEBUG_FILTER, "APPROX\n", 0, 0, 0 );
1010 err = get_ava( op, ber, &vrf.vrf_ava, SLAP_MR_EQUALITY_APPROX, text );
1011 if ( err != LDAP_SUCCESS ) {
1016 case LDAP_FILTER_EXT:
1018 LDAP_LOG( FILTER, DETAIL1,
1019 "get_simple_vrFilter: conn %d EXTENSIBLE\n", op->o_connid, 0, 0 );
1021 Debug( LDAP_DEBUG_FILTER, "EXTENSIBLE\n", 0, 0, 0 );
1024 err = get_mra( op, ber, &vrf.vrf_mra, text );
1025 if ( err != LDAP_SUCCESS ) {
1029 assert( vrf.vrf_mra != NULL );
1033 (void) ber_scanf( ber, "x" ); /* skip the element */
1035 LDAP_LOG( FILTER, ERR,
1036 "get_simple_vrFilter: conn %d unknown filter type=%lu\n",
1037 op->o_connid, vrf.vrf_choice, 0 );
1039 Debug( LDAP_DEBUG_ANY, "get_simple_vrFilter: unknown filter type=%lu\n",
1040 vrf.vrf_choice, 0, 0 );
1042 vrf.vrf_choice = SLAPD_FILTER_COMPUTED;
1043 vrf.vrf_result = SLAPD_COMPARE_UNDEFINED;
1047 if ( err != LDAP_SUCCESS && err != SLAPD_DISCONNECT ) {
1049 vrf.vrf_choice = SLAPD_FILTER_COMPUTED;
1050 vrf.vrf_result = SLAPD_COMPARE_UNDEFINED;
1054 if ( err == LDAP_SUCCESS ) {
1055 *filt = ch_malloc( sizeof vrf );
1060 LDAP_LOG( FILTER, DETAIL2,
1061 "get_simple_vrFilter: conn %d exit\n", op->o_connid, 0, 0 );
1063 Debug( LDAP_DEBUG_FILTER, "end get_simple_vrFilter %d\n", err, 0, 0 );
1070 get_vrFilter( Operation *op, BerElement *ber,
1071 ValuesReturnFilter **vrf,
1075 * A ValuesReturnFilter looks like this:
1077 * ValuesReturnFilter ::= SEQUENCE OF SimpleFilterItem
1078 * SimpleFilterItem ::= CHOICE {
1079 * equalityMatch [3] AttributeValueAssertion,
1080 * substrings [4] SubstringFilter,
1081 * greaterOrEqual [5] AttributeValueAssertion,
1082 * lessOrEqual [6] AttributeValueAssertion,
1083 * present [7] AttributeType,
1084 * approxMatch [8] AttributeValueAssertion,
1085 * extensibleMatch [9] SimpleMatchingAssertion -- LDAPv3
1088 * SubstringFilter ::= SEQUENCE {
1089 * type AttributeType,
1090 * SEQUENCE OF CHOICE {
1091 * initial [0] IA5String,
1092 * any [1] IA5String,
1093 * final [2] IA5String
1097 * SimpleMatchingAssertion ::= SEQUENCE { -- LDAPv3
1098 * matchingRule [1] MatchingRuleId OPTIONAL,
1099 * type [2] AttributeDescription OPTIONAL,
1100 * matchValue [3] AssertionValue }
1103 ValuesReturnFilter **n;
1109 LDAP_LOG( FILTER, ENTRY,
1110 "get_vrFilter: conn %d start\n", op->o_connid, 0, 0 );
1112 Debug( LDAP_DEBUG_FILTER, "begin get_vrFilter\n", 0, 0, 0 );
1115 tag = ber_peek_tag( ber, &len );
1117 if( tag == LBER_ERROR ) {
1118 *text = "error decoding vrFilter";
1119 return SLAPD_DISCONNECT;
1122 if( tag != LBER_SEQUENCE ) {
1123 *text = "error decoding vrFilter, expect SEQUENCE tag";
1124 return SLAPD_DISCONNECT;
1128 for ( tag = ber_first_element( ber, &len, &last );
1129 tag != LBER_DEFAULT;
1130 tag = ber_next_element( ber, &len, last ) )
1132 int err = get_simple_vrFilter( op, ber, n, text );
1134 if ( err != LDAP_SUCCESS ) return( err );
1136 n = &(*n)->vrf_next;
1141 LDAP_LOG( FILTER, ENTRY,
1142 "get_vrFilter: conn %d exit\n", op->o_connid, 0, 0 );
1144 Debug( LDAP_DEBUG_FILTER, "end get_vrFilter\n", 0, 0, 0 );
1146 return( LDAP_SUCCESS );
1150 vrFilter_free( Operation *op, ValuesReturnFilter *vrf )
1152 ValuesReturnFilter *p, *next;
1154 if ( vrf == NULL ) {
1158 for ( p = vrf; p != NULL; p = next ) {
1161 switch ( vrf->vrf_choice ) {
1162 case LDAP_FILTER_PRESENT:
1165 case LDAP_FILTER_EQUALITY:
1166 case LDAP_FILTER_GE:
1167 case LDAP_FILTER_LE:
1168 case LDAP_FILTER_APPROX:
1169 ava_free( op, vrf->vrf_ava, 1 );
1172 case LDAP_FILTER_SUBSTRINGS:
1173 if ( vrf->vrf_sub_initial.bv_val != NULL ) {
1174 op->o_tmpfree( vrf->vrf_sub_initial.bv_val, op->o_tmpmemctx );
1176 ber_bvarray_free_x( vrf->vrf_sub_any, op->o_tmpmemctx );
1177 if ( vrf->vrf_sub_final.bv_val != NULL ) {
1178 op->o_tmpfree( vrf->vrf_sub_final.bv_val, op->o_tmpmemctx );
1180 op->o_tmpfree( vrf->vrf_sub, op->o_tmpmemctx );
1183 case LDAP_FILTER_EXT:
1184 mra_free( op, vrf->vrf_mra, 1 );
1187 case SLAPD_FILTER_COMPUTED:
1192 LDAP_LOG( FILTER, ERR,
1193 "filter_free: unknown filter type %lu\n", vrf->vrf_choice, 0, 0 );
1195 Debug( LDAP_DEBUG_ANY, "filter_free: unknown filter type=%lu\n",
1196 vrf->vrf_choice, 0, 0 );
1201 op->o_tmpfree( vrf, op->o_tmpmemctx );
1206 vrFilter2bv( Operation *op, ValuesReturnFilter *vrf, struct berval *fstr )
1208 ValuesReturnFilter *p;
1212 if ( vrf == NULL ) {
1213 ber_str2bv_x( "No filter!", sizeof("No filter!")-1,
1214 1, fstr, op->o_tmpmemctx );
1218 fstr->bv_len = sizeof("()") - 1;
1219 fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 128, op->o_tmpmemctx );
1221 snprintf( fstr->bv_val, fstr->bv_len + 1, "()");
1223 for ( p = vrf; p != NULL; p = p->vrf_next ) {
1226 simple_vrFilter2bv( op, p, &tmp );
1228 fstr->bv_len += tmp.bv_len;
1229 fstr->bv_val = op->o_tmprealloc( fstr->bv_val, fstr->bv_len + 1, op->o_tmpmemctx );
1231 snprintf( &fstr->bv_val[len-1], tmp.bv_len + 2,
1232 /*"("*/ "%s)", tmp.bv_val );
1234 op->o_tmpfree( tmp.bv_val, op->o_tmpmemctx );
1239 simple_vrFilter2bv( Operation *op, ValuesReturnFilter *vrf, struct berval *fstr )
1244 if ( vrf == NULL ) {
1245 ber_str2bv_x( "No filter!", sizeof("No filter!")-1, 1, fstr, op->o_tmpmemctx );
1249 switch ( vrf->vrf_choice ) {
1250 case LDAP_FILTER_EQUALITY:
1251 filter_escape_value_x( &vrf->vrf_av_value, &tmp, op->o_tmpmemctx );
1253 fstr->bv_len = vrf->vrf_av_desc->ad_cname.bv_len +
1254 tmp.bv_len + ( sizeof("(=)") - 1 );
1255 fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx );
1257 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=%s)",
1258 vrf->vrf_av_desc->ad_cname.bv_val,
1261 ber_memfree_x( tmp.bv_val, op->o_tmpmemctx );
1264 case LDAP_FILTER_GE:
1265 filter_escape_value_x( &vrf->vrf_av_value, &tmp, op->o_tmpmemctx );
1267 fstr->bv_len = vrf->vrf_av_desc->ad_cname.bv_len +
1268 tmp.bv_len + ( sizeof("(>=)") - 1 );
1269 fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx );
1271 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s>=%s)",
1272 vrf->vrf_av_desc->ad_cname.bv_val,
1275 ber_memfree_x( tmp.bv_val, op->o_tmpmemctx );
1278 case LDAP_FILTER_LE:
1279 filter_escape_value_x( &vrf->vrf_av_value, &tmp, op->o_tmpmemctx );
1281 fstr->bv_len = vrf->vrf_av_desc->ad_cname.bv_len +
1282 tmp.bv_len + ( sizeof("(<=)") - 1 );
1283 fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx );
1285 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s<=%s)",
1286 vrf->vrf_av_desc->ad_cname.bv_val,
1289 ber_memfree_x( tmp.bv_val, op->o_tmpmemctx );
1292 case LDAP_FILTER_APPROX:
1293 filter_escape_value_x( &vrf->vrf_av_value, &tmp, op->o_tmpmemctx );
1295 fstr->bv_len = vrf->vrf_av_desc->ad_cname.bv_len +
1296 tmp.bv_len + ( sizeof("(~=)") - 1 );
1297 fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx );
1299 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s~=%s)",
1300 vrf->vrf_av_desc->ad_cname.bv_val,
1302 ber_memfree_x( tmp.bv_val, op->o_tmpmemctx );
1305 case LDAP_FILTER_SUBSTRINGS:
1306 fstr->bv_len = vrf->vrf_sub_desc->ad_cname.bv_len +
1307 ( sizeof("(=*)") - 1 );
1308 fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 128, op->o_tmpmemctx );
1310 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=*)",
1311 vrf->vrf_sub_desc->ad_cname.bv_val );
1313 if ( vrf->vrf_sub_initial.bv_val != NULL ) {
1316 filter_escape_value_x( &vrf->vrf_sub_initial, &tmp, op->o_tmpmemctx );
1318 fstr->bv_len += tmp.bv_len;
1319 fstr->bv_val = op->o_tmprealloc( fstr->bv_val, fstr->bv_len + 1, op->o_tmpmemctx );
1321 snprintf( &fstr->bv_val[len-2], tmp.bv_len+3,
1322 /* "(attr=" */ "%s*)",
1325 ber_memfree_x( tmp.bv_val, op->o_tmpmemctx );
1328 if ( vrf->vrf_sub_any != NULL ) {
1330 for ( i = 0; vrf->vrf_sub_any[i].bv_val != NULL; i++ ) {
1332 filter_escape_value_x( &vrf->vrf_sub_any[i], &tmp, op->o_tmpmemctx );
1334 fstr->bv_len += tmp.bv_len + 1;
1335 fstr->bv_val = op->o_tmprealloc( fstr->bv_val, fstr->bv_len + 1, op->o_tmpmemctx );
1337 snprintf( &fstr->bv_val[len-1], tmp.bv_len+3,
1338 /* "(attr=[init]*[any*]" */ "%s*)",
1340 ber_memfree_x( tmp.bv_val, op->o_tmpmemctx );
1344 if ( vrf->vrf_sub_final.bv_val != NULL ) {
1347 filter_escape_value_x( &vrf->vrf_sub_final, &tmp, op->o_tmpmemctx );
1349 fstr->bv_len += tmp.bv_len;
1350 fstr->bv_val = op->o_tmprealloc( fstr->bv_val, fstr->bv_len + 1, op->o_tmpmemctx );
1352 snprintf( &fstr->bv_val[len-1], tmp.bv_len+3,
1353 /* "(attr=[init*][any*]" */ "%s)",
1356 ber_memfree_x( tmp.bv_val, op->o_tmpmemctx );
1361 case LDAP_FILTER_PRESENT:
1362 fstr->bv_len = vrf->vrf_desc->ad_cname.bv_len +
1363 ( sizeof("(=*)") - 1 );
1364 fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx );
1366 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=*)",
1367 vrf->vrf_desc->ad_cname.bv_val );
1370 case LDAP_FILTER_EXT: {
1372 filter_escape_value_x( &vrf->vrf_mr_value, &tmp, op->o_tmpmemctx );
1374 if ( vrf->vrf_mr_desc ) {
1375 ad = vrf->vrf_mr_desc->ad_cname;
1381 fstr->bv_len = ad.bv_len +
1382 ( vrf->vrf_mr_dnattrs ? sizeof(":dn")-1 : 0 ) +
1383 ( vrf->vrf_mr_rule_text.bv_len ? vrf->vrf_mr_rule_text.bv_len+1 : 0 ) +
1384 tmp.bv_len + ( sizeof("(:=)") - 1 );
1385 fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx );
1387 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s%s%s%s:=%s)",
1389 vrf->vrf_mr_dnattrs ? ":dn" : "",
1390 vrf->vrf_mr_rule_text.bv_len ? ":" : "",
1391 vrf->vrf_mr_rule_text.bv_len ? vrf->vrf_mr_rule_text.bv_val : "",
1394 ber_memfree_x( tmp.bv_val, op->o_tmpmemctx );
1397 case SLAPD_FILTER_COMPUTED:
1399 vrf->vrf_result == LDAP_COMPARE_FALSE ? "(?=false)" :
1400 vrf->vrf_result == LDAP_COMPARE_TRUE ? "(?=true)" :
1401 vrf->vrf_result == SLAPD_COMPARE_UNDEFINED ? "(?=undefined)" :
1403 vrf->vrf_result == LDAP_COMPARE_FALSE ? sizeof("(?=false)")-1 :
1404 vrf->vrf_result == LDAP_COMPARE_TRUE ? sizeof("(?=true)")-1 :
1405 vrf->vrf_result == SLAPD_COMPARE_UNDEFINED ? sizeof("(?=undefined)")-1 :
1406 sizeof("(?=error)")-1,
1407 1, fstr, op->o_tmpmemctx );
1411 ber_str2bv_x( "(?=unknown)", sizeof("(?=unknown)")-1,
1412 1, fstr, op->o_tmpmemctx );