1 /* filter.c - routines for parsing and dealing with filters */
4 * Copyright 1998-2002 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(
23 static int get_substring_filter(
29 static int filter_escape_value(
33 static void simple_vrFilter2bv(
34 ValuesReturnFilter *f,
35 struct berval *fstr );
37 static int get_simple_vrFilter(
40 ValuesReturnFilter **f,
57 LDAP_LOG(( "filter", LDAP_LEVEL_ENTRY, "get_filter: conn %d\n",
60 Debug( LDAP_DEBUG_FILTER, "begin get_filter\n", 0, 0, 0 );
63 * A filter looks like this coming in:
65 * and [0] SET OF Filter,
66 * or [1] SET OF Filter,
68 * equalityMatch [3] AttributeValueAssertion,
69 * substrings [4] SubstringFilter,
70 * greaterOrEqual [5] AttributeValueAssertion,
71 * lessOrEqual [6] AttributeValueAssertion,
72 * present [7] AttributeType,,
73 * approxMatch [8] AttributeValueAssertion
74 * extensibleMatch [9] MatchingRuleAssertion
77 * SubstringFilter ::= SEQUENCE {
79 * SEQUENCE OF CHOICE {
80 * initial [0] IA5String,
86 * MatchingRuleAssertion ::= SEQUENCE {
87 * matchingRule [1] MatchingRuleId OPTIONAL,
88 * type [2] AttributeDescription OPTIONAL,
89 * matchValue [3] AssertionValue,
90 * dnAttributes [4] BOOLEAN DEFAULT FALSE
95 tag = ber_peek_tag( ber, &len );
97 if( tag == LBER_ERROR ) {
98 *text = "error decoding filter";
99 return SLAPD_DISCONNECT;
102 f = (Filter *) ch_malloc( sizeof(Filter) );
108 switch ( f->f_choice ) {
109 case LDAP_FILTER_EQUALITY:
111 LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL2,
112 "get_filter: conn %d EQUALITY\n", conn->c_connid ));
114 Debug( LDAP_DEBUG_FILTER, "EQUALITY\n", 0, 0, 0 );
116 err = get_ava( ber, &f->f_ava, SLAP_MR_EQUALITY, text );
117 if ( err != LDAP_SUCCESS ) {
121 assert( f->f_ava != NULL );
124 case LDAP_FILTER_SUBSTRINGS:
126 LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1,
127 "get_filter: conn %d SUBSTRINGS\n", conn->c_connid ));
129 Debug( LDAP_DEBUG_FILTER, "SUBSTRINGS\n", 0, 0, 0 );
131 err = get_substring_filter( conn, ber, f, text );
136 LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1,
137 "get_filter: conn %d GE\n", conn->c_connid ));
139 Debug( LDAP_DEBUG_FILTER, "GE\n", 0, 0, 0 );
141 err = get_ava( ber, &f->f_ava, SLAP_MR_ORDERING, text );
142 if ( err != LDAP_SUCCESS ) {
149 LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1,
150 "get_filter: conn %d LE\n", conn->c_connid ));
152 Debug( LDAP_DEBUG_FILTER, "LE\n", 0, 0, 0 );
154 err = get_ava( ber, &f->f_ava, SLAP_MR_ORDERING, text );
155 if ( err != LDAP_SUCCESS ) {
160 case LDAP_FILTER_PRESENT: {
164 LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1,
165 "get_filter: conn %d PRESENT\n", conn->c_connid ));
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 case LDAP_FILTER_APPROX:
189 LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1,
190 "get_filter: conn %d APPROX\n", conn->c_connid ));
192 Debug( LDAP_DEBUG_FILTER, "APPROX\n", 0, 0, 0 );
194 err = get_ava( ber, &f->f_ava, SLAP_MR_EQUALITY_APPROX, text );
195 if ( err != LDAP_SUCCESS ) {
200 case LDAP_FILTER_AND:
202 LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1,
203 "get_filter: conn %d AND\n", conn->c_connid ));
205 Debug( LDAP_DEBUG_FILTER, "AND\n", 0, 0, 0 );
207 err = get_filter_list( conn, ber, &f->f_and, text );
208 if ( err != LDAP_SUCCESS ) {
215 LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1,
216 "get_filter: conn %d OR\n", conn->c_connid ));
218 Debug( LDAP_DEBUG_FILTER, "OR\n", 0, 0, 0 );
220 err = get_filter_list( conn, ber, &f->f_or, text );
221 if ( err != LDAP_SUCCESS ) {
226 case LDAP_FILTER_NOT:
228 LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1,
229 "get_filter: conn %d NOT\n", conn->c_connid ));
231 Debug( LDAP_DEBUG_FILTER, "NOT\n", 0, 0, 0 );
233 (void) ber_skip_tag( ber, &len );
234 err = get_filter( conn, ber, &f->f_not, text );
235 if ( err != LDAP_SUCCESS ) {
240 case LDAP_FILTER_EXT:
242 LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1,
243 "get_filter: conn %d EXTENSIBLE\n", conn->c_connid ));
245 Debug( LDAP_DEBUG_FILTER, "EXTENSIBLE\n", 0, 0, 0 );
248 err = get_mra( ber, &f->f_mra, text );
249 if ( err != LDAP_SUCCESS ) {
253 assert( f->f_mra != NULL );
257 (void) ber_scanf( ber, "x" ); /* skip the element */
259 LDAP_LOG(( "filter", LDAP_LEVEL_ERR,
260 "get_filter: conn %d unknown filter type=%lu\n",
261 conn->c_connid, f->f_choice ));
263 Debug( LDAP_DEBUG_ANY, "get_filter: unknown filter type=%lu\n",
266 f->f_choice = SLAPD_FILTER_COMPUTED;
267 f->f_result = SLAPD_COMPARE_UNDEFINED;
271 if ( err != LDAP_SUCCESS ) {
272 if( err != SLAPD_DISCONNECT ) {
274 f->f_choice = SLAPD_FILTER_COMPUTED;
275 f->f_result = SLAPD_COMPARE_UNDEFINED;
288 LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL2,
289 "get_filter: conn %d exit\n", conn->c_connid ));
291 Debug( LDAP_DEBUG_FILTER, "end get_filter %d\n", err, 0, 0 );
297 get_filter_list( Connection *conn, BerElement *ber,
308 LDAP_LOG(( "filter", LDAP_LEVEL_ENTRY,
309 "get_filter_list: conn %d start\n", conn->c_connid ));
311 Debug( LDAP_DEBUG_FILTER, "begin get_filter_list\n", 0, 0, 0 );
314 for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT;
315 tag = ber_next_element( ber, &len, last ) )
317 err = get_filter( conn, ber, new, text );
318 if ( err != LDAP_SUCCESS )
320 new = &(*new)->f_next;
325 LDAP_LOG(( "filter", LDAP_LEVEL_ENTRY,
326 "get_filter_list: conn %d exit\n", conn->c_connid ));
328 Debug( LDAP_DEBUG_FILTER, "end get_filter_list\n", 0, 0, 0 );
330 return( LDAP_SUCCESS );
334 get_substring_filter(
346 *text = "error decoding filter";
349 LDAP_LOG(( "filter", LDAP_LEVEL_ENTRY,
350 "get_substring_filter: conn %d begin\n", conn->c_connid ));
352 Debug( LDAP_DEBUG_FILTER, "begin get_substring_filter\n", 0, 0, 0 );
354 if ( ber_scanf( ber, "{m" /*}*/, &bv ) == LBER_ERROR ) {
355 return SLAPD_DISCONNECT;
358 f->f_sub = ch_calloc( 1, sizeof(SubstringsAssertion) );
359 f->f_sub_desc = NULL;
360 rc = slap_bv2ad( &bv, &f->f_sub_desc, text );
362 if( rc != LDAP_SUCCESS ) {
365 f->f_choice = SLAPD_FILTER_COMPUTED;
366 f->f_result = SLAPD_COMPARE_UNDEFINED;
370 f->f_sub_initial.bv_val = NULL;
372 f->f_sub_final.bv_val = NULL;
374 for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT;
375 tag = ber_next_element( ber, &len, last ) )
379 rc = ber_scanf( ber, "m", &value );
380 if ( rc == LBER_ERROR ) {
381 rc = SLAPD_DISCONNECT;
385 if ( value.bv_val == NULL || value.bv_len == 0 ) {
386 rc = LDAP_INVALID_SYNTAX;
391 case LDAP_SUBSTRING_INITIAL:
392 usage = SLAP_MR_SUBSTR_INITIAL;
395 case LDAP_SUBSTRING_ANY:
396 usage = SLAP_MR_SUBSTR_ANY;
399 case LDAP_SUBSTRING_FINAL:
400 usage = SLAP_MR_SUBSTR_FINAL;
404 rc = LDAP_PROTOCOL_ERROR;
407 LDAP_LOG(( "filter", LDAP_LEVEL_ERR,
408 "get_filter_substring: conn %d unknown substring choice=%ld\n",
409 conn->c_connid, (long)tag ));
411 Debug( LDAP_DEBUG_FILTER,
412 " unknown substring choice=%ld\n",
418 /* valiate using equality matching rule validator! */
419 rc = value_validate( f->f_sub_desc->ad_type->sat_equality,
421 if( rc != LDAP_SUCCESS ) {
425 rc = value_normalize( f->f_sub_desc, usage,
427 if( rc != LDAP_SUCCESS ) {
433 rc = LDAP_PROTOCOL_ERROR;
436 case LDAP_SUBSTRING_INITIAL:
438 LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1,
439 "get_substring_filter: conn %d INITIAL\n",
442 Debug( LDAP_DEBUG_FILTER, " INITIAL\n", 0, 0, 0 );
445 if ( f->f_sub_initial.bv_val != NULL
446 || f->f_sub_any != NULL
447 || f->f_sub_final.bv_val != NULL )
449 free( value.bv_val );
453 f->f_sub_initial = value;
456 case LDAP_SUBSTRING_ANY:
458 LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1,
459 "get_substring_filter: conn %d ANY\n",
462 Debug( LDAP_DEBUG_FILTER, " ANY\n", 0, 0, 0 );
465 if ( f->f_sub_final.bv_val != NULL ) {
466 free( value.bv_val );
470 ber_bvarray_add( &f->f_sub_any, &value );
473 case LDAP_SUBSTRING_FINAL:
475 LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1,
476 "get_substring_filter: conn %d FINAL\n",
479 Debug( LDAP_DEBUG_FILTER, " FINAL\n", 0, 0, 0 );
482 if ( f->f_sub_final.bv_val != NULL ) {
483 free( value.bv_val );
487 f->f_sub_final = value;
492 LDAP_LOG(( "filter", LDAP_LEVEL_INFO,
493 "get_substring_filter: conn %d unknown substring type %ld\n",
494 conn->c_connid, (long)tag ));
496 Debug( LDAP_DEBUG_FILTER,
497 " unknown substring type=%ld\n",
501 free( value.bv_val );
505 LDAP_LOG(( "filter", LDAP_LEVEL_INFO,
506 "get_substring_filter: conn %d error %ld\n",
507 conn->c_connid, (long)rc ));
509 Debug( LDAP_DEBUG_FILTER, " error=%ld\n",
512 free( f->f_sub_initial.bv_val );
513 ber_bvarray_free( f->f_sub_any );
514 free( f->f_sub_final.bv_val );
521 LDAP_LOG(( "filter", LDAP_LEVEL_ENTRY,
522 "get_substring_filter: conn %d exit\n", conn->c_connid ));
524 Debug( LDAP_DEBUG_FILTER, "end get_substring_filter\n", 0, 0, 0 );
526 return( LDAP_SUCCESS );
530 filter_free( Filter *f )
538 switch ( f->f_choice ) {
539 case LDAP_FILTER_PRESENT:
542 case LDAP_FILTER_EQUALITY:
545 case LDAP_FILTER_APPROX:
546 ava_free( f->f_ava, 1 );
549 case LDAP_FILTER_SUBSTRINGS:
550 if ( f->f_sub_initial.bv_val != NULL ) {
551 free( f->f_sub_initial.bv_val );
553 ber_bvarray_free( f->f_sub_any );
554 if ( f->f_sub_final.bv_val != NULL ) {
555 free( f->f_sub_final.bv_val );
560 case LDAP_FILTER_AND:
562 case LDAP_FILTER_NOT:
563 for ( p = f->f_list; p != NULL; p = next ) {
569 case LDAP_FILTER_EXT:
570 mra_free( f->f_mra, 1 );
573 case SLAPD_FILTER_COMPUTED:
578 LDAP_LOG(( "filter", LDAP_LEVEL_ERR,
579 "filter_free: unknown filter type %lu\n", f->f_choice ));
581 Debug( LDAP_DEBUG_ANY, "filter_free: unknown filter type=%lu\n",
591 filter2bv( Filter *f, struct berval *fstr )
599 ber_str2bv( "No filter!", sizeof("No filter!")-1, 1, fstr );
603 switch ( f->f_choice ) {
604 case LDAP_FILTER_EQUALITY:
605 filter_escape_value( &f->f_av_value, &tmp );
607 fstr->bv_len = f->f_av_desc->ad_cname.bv_len +
608 tmp.bv_len + ( sizeof("(=)") - 1 );
609 fstr->bv_val = malloc( fstr->bv_len + 1 );
611 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=%s)",
612 f->f_av_desc->ad_cname.bv_val,
615 ber_memfree( tmp.bv_val );
619 filter_escape_value( &f->f_av_value, &tmp );
621 fstr->bv_len = f->f_av_desc->ad_cname.bv_len +
622 tmp.bv_len + ( sizeof("(>=)") - 1 );
623 fstr->bv_val = malloc( fstr->bv_len + 1 );
625 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s>=%s)",
626 f->f_av_desc->ad_cname.bv_val,
629 ber_memfree( tmp.bv_val );
633 filter_escape_value( &f->f_av_value, &tmp );
635 fstr->bv_len = f->f_av_desc->ad_cname.bv_len +
636 tmp.bv_len + ( sizeof("(<=)") - 1 );
637 fstr->bv_val = malloc( fstr->bv_len + 1 );
639 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s<=%s)",
640 f->f_av_desc->ad_cname.bv_val,
643 ber_memfree( tmp.bv_val );
646 case LDAP_FILTER_APPROX:
647 filter_escape_value( &f->f_av_value, &tmp );
649 fstr->bv_len = f->f_av_desc->ad_cname.bv_len +
650 tmp.bv_len + ( sizeof("(~=)") - 1 );
651 fstr->bv_val = malloc( fstr->bv_len + 1 );
653 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s~=%s)",
654 f->f_av_desc->ad_cname.bv_val,
656 ber_memfree( tmp.bv_val );
659 case LDAP_FILTER_SUBSTRINGS:
660 fstr->bv_len = f->f_sub_desc->ad_cname.bv_len +
661 ( sizeof("(=*)") - 1 );
662 fstr->bv_val = malloc( fstr->bv_len + 128 );
664 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=*)",
665 f->f_sub_desc->ad_cname.bv_val );
667 if ( f->f_sub_initial.bv_val != NULL ) {
670 filter_escape_value( &f->f_sub_initial, &tmp );
672 fstr->bv_len += tmp.bv_len;
673 fstr->bv_val = ch_realloc( fstr->bv_val, fstr->bv_len + 1 );
675 snprintf( &fstr->bv_val[len-2], tmp.bv_len+3,
676 /* "(attr=" */ "%s*)",
679 ber_memfree( tmp.bv_val );
682 if ( f->f_sub_any != NULL ) {
683 for ( i = 0; f->f_sub_any[i].bv_val != NULL; i++ ) {
685 filter_escape_value( &f->f_sub_any[i], &tmp );
687 fstr->bv_len += tmp.bv_len + 1;
688 fstr->bv_val = ch_realloc( fstr->bv_val, fstr->bv_len + 1 );
690 snprintf( &fstr->bv_val[len-1], tmp.bv_len+3,
691 /* "(attr=[init]*[any*]" */ "%s*)",
693 ber_memfree( tmp.bv_val );
697 if ( f->f_sub_final.bv_val != NULL ) {
700 filter_escape_value( &f->f_sub_final, &tmp );
702 fstr->bv_len += tmp.bv_len;
703 fstr->bv_val = ch_realloc( fstr->bv_val, fstr->bv_len + 1 );
705 snprintf( &fstr->bv_val[len-1], tmp.bv_len+3,
706 /* "(attr=[init*][any*]" */ "%s)",
709 ber_memfree( tmp.bv_val );
714 case LDAP_FILTER_PRESENT:
715 fstr->bv_len = f->f_desc->ad_cname.bv_len +
716 ( sizeof("(=*)") - 1 );
717 fstr->bv_val = malloc( fstr->bv_len + 1 );
719 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=*)",
720 f->f_desc->ad_cname.bv_val );
723 case LDAP_FILTER_AND:
725 case LDAP_FILTER_NOT:
726 fstr->bv_len = sizeof("(%)") - 1;
727 fstr->bv_val = malloc( fstr->bv_len + 128 );
729 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%c)",
730 f->f_choice == LDAP_FILTER_AND ? '&' :
731 f->f_choice == LDAP_FILTER_OR ? '|' : '!' );
733 for ( p = f->f_list; p != NULL; p = p->f_next ) {
736 filter2bv( p, &tmp );
738 fstr->bv_len += tmp.bv_len;
739 fstr->bv_val = ch_realloc( fstr->bv_val, fstr->bv_len + 1 );
741 snprintf( &fstr->bv_val[len-1], tmp.bv_len + 2,
742 /*"("*/ "%s)", tmp.bv_val );
744 ch_free( tmp.bv_val );
749 case LDAP_FILTER_EXT:
750 filter_escape_value( &f->f_mr_value, &tmp );
752 fstr->bv_len = f->f_mr_desc->ad_cname.bv_len +
753 ( f->f_mr_dnattrs ? sizeof(":dn")-1 : 0 ) +
754 ( f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_len+1 : 0 ) +
755 tmp.bv_len + ( sizeof("(:=)") - 1 );
756 fstr->bv_val = malloc( fstr->bv_len + 1 );
758 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s%s%s%s:=%s)",
759 f->f_mr_desc->ad_cname.bv_val,
760 f->f_mr_dnattrs ? ":dn" : "",
761 f->f_mr_rule_text.bv_len ? ":" : "",
762 f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_val : "",
764 ber_memfree( tmp.bv_val );
767 case SLAPD_FILTER_COMPUTED:
769 f->f_result == LDAP_COMPARE_FALSE ? "(?=false)" :
770 f->f_result == LDAP_COMPARE_TRUE ? "(?=true)" :
771 f->f_result == SLAPD_COMPARE_UNDEFINED ? "(?=undefined)" :
773 f->f_result == LDAP_COMPARE_FALSE ? sizeof("(?=false)")-1 :
774 f->f_result == LDAP_COMPARE_TRUE ? sizeof("(?=true)")-1 :
775 f->f_result == SLAPD_COMPARE_UNDEFINED ? sizeof("(?=undefined)")-1 :
776 sizeof("(?=error)")-1,
781 ber_str2bv( "(?=unknown)", sizeof("(?=unknown)")-1, 1, fstr );
786 static int filter_escape_value(
794 out->bv_val = (char *) ch_malloc( ( in->bv_len * 3 ) + 1 );
797 for( i=0; i < in->bv_len ; i++ ) {
798 if( FILTER_ESCAPE(in->bv_val[i]) ) {
799 out->bv_val[out->bv_len++] = SLAP_ESCAPE_CHAR;
800 out->bv_val[out->bv_len++] = SLAP_ESCAPE_HI( in->bv_val[i] );
801 out->bv_val[out->bv_len++] = SLAP_ESCAPE_LO( in->bv_val[i] );
803 out->bv_val[out->bv_len++] = in->bv_val[i];
807 out->bv_val[out->bv_len] = '\0';
815 ValuesReturnFilter **filt,
821 ValuesReturnFilter *f;
824 LDAP_LOG(( "filter", LDAP_LEVEL_ENTRY, "get_simple_vrFilter: conn %d\n",
827 Debug( LDAP_DEBUG_FILTER, "begin get_simple_vrFilter\n", 0, 0, 0 );
830 tag = ber_peek_tag( ber, &len );
832 if( tag == LBER_ERROR ) {
833 *text = "error decoding filter";
834 return SLAPD_DISCONNECT;
837 f = (ValuesReturnFilter *) ch_malloc( sizeof(ValuesReturnFilter) );
843 switch ( f->f_choice ) {
844 case LDAP_FILTER_EQUALITY:
846 LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL2,
847 "get_simple_vrFilter: conn %d EQUALITY\n", conn->c_connid ));
849 Debug( LDAP_DEBUG_FILTER, "EQUALITY\n", 0, 0, 0 );
851 err = get_ava( ber, &f->f_ava, SLAP_MR_EQUALITY, text );
852 if ( err != LDAP_SUCCESS ) {
856 assert( f->f_ava != NULL );
859 case LDAP_FILTER_SUBSTRINGS:
861 LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1,
862 "get_simple_vrFilter: conn %d SUBSTRINGS\n", conn->c_connid ));
864 Debug( LDAP_DEBUG_FILTER, "SUBSTRINGS\n", 0, 0, 0 );
866 err = get_substring_filter( conn, ber, (Filter *)f, text );
871 LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1,
872 "get_simple_vrFilter: conn %d GE\n", conn->c_connid ));
874 Debug( LDAP_DEBUG_FILTER, "GE\n", 0, 0, 0 );
876 err = get_ava( ber, &f->f_ava, SLAP_MR_ORDERING, text );
877 if ( err != LDAP_SUCCESS ) {
884 LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1,
885 "get_simple_vrFilter: conn %d LE\n", conn->c_connid ));
887 Debug( LDAP_DEBUG_FILTER, "LE\n", 0, 0, 0 );
889 err = get_ava( ber, &f->f_ava, SLAP_MR_ORDERING, text );
890 if ( err != LDAP_SUCCESS ) {
895 case LDAP_FILTER_PRESENT: {
899 LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1,
900 "get_simple_vrFilter: conn %d PRESENT\n", conn->c_connid ));
902 Debug( LDAP_DEBUG_FILTER, "PRESENT\n", 0, 0, 0 );
904 if ( ber_scanf( ber, "m", &type ) == LBER_ERROR ) {
905 err = SLAPD_DISCONNECT;
906 *text = "error decoding filter";
911 err = slap_bv2ad( &type, &f->f_desc, text );
913 if( err != LDAP_SUCCESS ) {
914 /* unrecognized attribute description or other error */
915 f->f_choice = SLAPD_FILTER_COMPUTED;
916 f->f_result = LDAP_COMPARE_FALSE;
922 case LDAP_FILTER_APPROX:
924 LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1,
925 "get_simple_vrFilter: conn %d APPROX\n", conn->c_connid ));
927 Debug( LDAP_DEBUG_FILTER, "APPROX\n", 0, 0, 0 );
929 err = get_ava( ber, &f->f_ava, SLAP_MR_EQUALITY_APPROX, text );
930 if ( err != LDAP_SUCCESS ) {
935 case LDAP_FILTER_EXT:
937 LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1,
938 "get_simple_vrFilter: conn %d EXTENSIBLE\n", conn->c_connid ));
940 Debug( LDAP_DEBUG_FILTER, "EXTENSIBLE\n", 0, 0, 0 );
943 err = get_mra( ber, &f->f_mra, text );
944 if ( err != LDAP_SUCCESS ) {
948 assert( f->f_mra != NULL );
952 (void) ber_scanf( ber, "x" ); /* skip the element */
954 LDAP_LOG(( "filter", LDAP_LEVEL_ERR,
955 "get_simple_vrFilter: conn %d unknown filter type=%lu\n",
956 conn->c_connid, f->f_choice ));
958 Debug( LDAP_DEBUG_ANY, "get_simple_vrFilter: unknown filter type=%lu\n",
961 f->f_choice = SLAPD_FILTER_COMPUTED;
962 f->f_result = SLAPD_COMPARE_UNDEFINED;
966 if ( err != LDAP_SUCCESS ) {
967 if( err != SLAPD_DISCONNECT ) {
969 f->f_choice = SLAPD_FILTER_COMPUTED;
970 f->f_result = SLAPD_COMPARE_UNDEFINED;
983 LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL2,
984 "get_simple_vrFilter: conn %d exit\n", conn->c_connid ));
986 Debug( LDAP_DEBUG_FILTER, "end get_simple_vrFilter %d\n", err, 0, 0 );
992 get_vrFilter( Connection *conn, BerElement *ber,
993 ValuesReturnFilter **f,
997 * A ValuesReturnFilter looks like this:
999 * ValuesReturnFilter ::= SEQUENCE OF SimpleFilterItem
1000 * SimpleFilterItem ::= CHOICE {
1001 * equalityMatch [3] AttributeValueAssertion,
1002 * substrings [4] SubstringFilter,
1003 * greaterOrEqual [5] AttributeValueAssertion,
1004 * lessOrEqual [6] AttributeValueAssertion,
1005 * present [7] AttributeType,
1006 * approxMatch [8] AttributeValueAssertion,
1007 * extensibleMatch [9] SimpleMatchingAssertion -- LDAPv3
1010 * SubstringFilter ::= SEQUENCE {
1011 * type AttributeType,
1012 * SEQUENCE OF CHOICE {
1013 * initial [0] IA5String,
1014 * any [1] IA5String,
1015 * final [2] IA5String
1019 * SimpleMatchingAssertion ::= SEQUENCE { -- LDAPv3
1020 * matchingRule [1] MatchingRuleId OPTIONAL,
1021 * type [2] AttributeDescription OPTIONAL,
1022 * matchValue [3] AssertionValue }
1025 ValuesReturnFilter **new;
1031 LDAP_LOG(( "filter", LDAP_LEVEL_ENTRY,
1032 "get_vrFilter: conn %d start\n", conn->c_connid ));
1034 Debug( LDAP_DEBUG_FILTER, "begin get_vrFilter\n", 0, 0, 0 );
1037 tag = ber_peek_tag( ber, &len );
1039 if( tag == LBER_ERROR ) {
1040 *text = "error decoding vrFilter";
1041 return SLAPD_DISCONNECT;
1044 if( tag != LBER_SEQUENCE ) {
1045 *text = "error decoding vrFilter, expect SEQUENCE tag";
1046 return SLAPD_DISCONNECT;
1050 for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT;
1051 tag = ber_next_element( ber, &len, last ) )
1053 int err = get_simple_vrFilter( conn, ber, new, text );
1054 if ( err != LDAP_SUCCESS )
1056 new = &(*new)->f_next;
1061 LDAP_LOG(( "filter", LDAP_LEVEL_ENTRY,
1062 "get_vrFilter: conn %d exit\n", conn->c_connid ));
1064 Debug( LDAP_DEBUG_FILTER, "end get_vrFilter\n", 0, 0, 0 );
1066 return( LDAP_SUCCESS );
1070 vrFilter_free( ValuesReturnFilter *f )
1072 ValuesReturnFilter *p, *next;
1078 for ( p = f; p != NULL; p = next ) {
1081 switch ( f->f_choice ) {
1082 case LDAP_FILTER_PRESENT:
1085 case LDAP_FILTER_EQUALITY:
1086 case LDAP_FILTER_GE:
1087 case LDAP_FILTER_LE:
1088 case LDAP_FILTER_APPROX:
1089 ava_free( f->f_ava, 1 );
1092 case LDAP_FILTER_SUBSTRINGS:
1093 if ( f->f_sub_initial.bv_val != NULL ) {
1094 free( f->f_sub_initial.bv_val );
1096 ber_bvarray_free( f->f_sub_any );
1097 if ( f->f_sub_final.bv_val != NULL ) {
1098 free( f->f_sub_final.bv_val );
1100 ch_free( f->f_sub );
1103 case LDAP_FILTER_EXT:
1104 mra_free( f->f_mra, 1 );
1107 case SLAPD_FILTER_COMPUTED:
1112 LDAP_LOG(( "filter", LDAP_LEVEL_ERR,
1113 "filter_free: unknown filter type %lu\n", f->f_choice ));
1115 Debug( LDAP_DEBUG_ANY, "filter_free: unknown filter type=%lu\n",
1116 f->f_choice, 0, 0 );
1127 vrFilter2bv( ValuesReturnFilter *f, struct berval *fstr )
1130 ValuesReturnFilter *p;
1135 ber_str2bv( "No filter!", sizeof("No filter!")-1, 1, fstr );
1139 fstr->bv_len = sizeof("()") - 1;
1140 fstr->bv_val = malloc( fstr->bv_len + 128 );
1142 snprintf( fstr->bv_val, fstr->bv_len + 1, "()");
1144 for ( p = f; p != NULL; p = p->f_next ) {
1147 simple_vrFilter2bv( p, &tmp );
1149 fstr->bv_len += tmp.bv_len;
1150 fstr->bv_val = ch_realloc( fstr->bv_val, fstr->bv_len + 1 );
1152 snprintf( &fstr->bv_val[len-1], tmp.bv_len + 2,
1153 /*"("*/ "%s)", tmp.bv_val );
1155 ch_free( tmp.bv_val );
1160 simple_vrFilter2bv( ValuesReturnFilter *f, struct berval *fstr )
1163 ValuesReturnFilter *p;
1168 ber_str2bv( "No filter!", sizeof("No filter!")-1, 1, fstr );
1172 switch ( f->f_choice ) {
1173 case LDAP_FILTER_EQUALITY:
1174 filter_escape_value( &f->f_av_value, &tmp );
1176 fstr->bv_len = f->f_av_desc->ad_cname.bv_len +
1177 tmp.bv_len + ( sizeof("(=)") - 1 );
1178 fstr->bv_val = malloc( fstr->bv_len + 1 );
1180 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=%s)",
1181 f->f_av_desc->ad_cname.bv_val,
1184 ber_memfree( tmp.bv_val );
1187 case LDAP_FILTER_GE:
1188 filter_escape_value( &f->f_av_value, &tmp );
1190 fstr->bv_len = f->f_av_desc->ad_cname.bv_len +
1191 tmp.bv_len + ( sizeof("(>=)") - 1 );
1192 fstr->bv_val = malloc( fstr->bv_len + 1 );
1194 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s>=%s)",
1195 f->f_av_desc->ad_cname.bv_val,
1198 ber_memfree( tmp.bv_val );
1201 case LDAP_FILTER_LE:
1202 filter_escape_value( &f->f_av_value, &tmp );
1204 fstr->bv_len = f->f_av_desc->ad_cname.bv_len +
1205 tmp.bv_len + ( sizeof("(<=)") - 1 );
1206 fstr->bv_val = malloc( fstr->bv_len + 1 );
1208 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s<=%s)",
1209 f->f_av_desc->ad_cname.bv_val,
1212 ber_memfree( tmp.bv_val );
1215 case LDAP_FILTER_APPROX:
1216 filter_escape_value( &f->f_av_value, &tmp );
1218 fstr->bv_len = f->f_av_desc->ad_cname.bv_len +
1219 tmp.bv_len + ( sizeof("(~=)") - 1 );
1220 fstr->bv_val = malloc( fstr->bv_len + 1 );
1222 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s~=%s)",
1223 f->f_av_desc->ad_cname.bv_val,
1225 ber_memfree( tmp.bv_val );
1228 case LDAP_FILTER_SUBSTRINGS:
1229 fstr->bv_len = f->f_sub_desc->ad_cname.bv_len +
1230 ( sizeof("(=*)") - 1 );
1231 fstr->bv_val = malloc( fstr->bv_len + 128 );
1233 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=*)",
1234 f->f_sub_desc->ad_cname.bv_val );
1236 if ( f->f_sub_initial.bv_val != NULL ) {
1239 filter_escape_value( &f->f_sub_initial, &tmp );
1241 fstr->bv_len += tmp.bv_len;
1242 fstr->bv_val = ch_realloc( fstr->bv_val, fstr->bv_len + 1 );
1244 snprintf( &fstr->bv_val[len-2], tmp.bv_len+3,
1245 /* "(attr=" */ "%s*)",
1248 ber_memfree( tmp.bv_val );
1251 if ( f->f_sub_any != NULL ) {
1252 for ( i = 0; f->f_sub_any[i].bv_val != NULL; i++ ) {
1254 filter_escape_value( &f->f_sub_any[i], &tmp );
1256 fstr->bv_len += tmp.bv_len + 1;
1257 fstr->bv_val = ch_realloc( fstr->bv_val, fstr->bv_len + 1 );
1259 snprintf( &fstr->bv_val[len-1], tmp.bv_len+3,
1260 /* "(attr=[init]*[any*]" */ "%s*)",
1262 ber_memfree( tmp.bv_val );
1266 if ( f->f_sub_final.bv_val != NULL ) {
1269 filter_escape_value( &f->f_sub_final, &tmp );
1271 fstr->bv_len += tmp.bv_len;
1272 fstr->bv_val = ch_realloc( fstr->bv_val, fstr->bv_len + 1 );
1274 snprintf( &fstr->bv_val[len-1], tmp.bv_len+3,
1275 /* "(attr=[init*][any*]" */ "%s)",
1278 ber_memfree( tmp.bv_val );
1283 case LDAP_FILTER_PRESENT:
1284 fstr->bv_len = f->f_desc->ad_cname.bv_len +
1285 ( sizeof("(=*)") - 1 );
1286 fstr->bv_val = malloc( fstr->bv_len + 1 );
1288 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=*)",
1289 f->f_desc->ad_cname.bv_val );
1292 case LDAP_FILTER_EXT:
1293 filter_escape_value( &f->f_mr_value, &tmp );
1295 fstr->bv_len = f->f_mr_desc->ad_cname.bv_len +
1296 ( f->f_mr_dnattrs ? sizeof(":dn")-1 : 0 ) +
1297 ( f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_len+1 : 0 ) +
1298 tmp.bv_len + ( sizeof("(:=)") - 1 );
1299 fstr->bv_val = malloc( fstr->bv_len + 1 );
1301 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s%s%s%s:=%s)",
1302 f->f_mr_desc->ad_cname.bv_val,
1303 f->f_mr_dnattrs ? ":dn" : "",
1304 f->f_mr_rule_text.bv_len ? ":" : "",
1305 f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_val : "",
1307 ber_memfree( tmp.bv_val );
1310 case SLAPD_FILTER_COMPUTED:
1312 f->f_result == LDAP_COMPARE_FALSE ? "(?=false)" :
1313 f->f_result == LDAP_COMPARE_TRUE ? "(?=true)" :
1314 f->f_result == SLAPD_COMPARE_UNDEFINED ? "(?=undefined)" :
1316 f->f_result == LDAP_COMPARE_FALSE ? sizeof("(?=false)")-1 :
1317 f->f_result == LDAP_COMPARE_TRUE ? sizeof("(?=true)")-1 :
1318 f->f_result == SLAPD_COMPARE_UNDEFINED ? sizeof("(?=undefined)")-1 :
1319 sizeof("(?=error)")-1,
1324 ber_str2bv( "(?=unknown)", sizeof("(?=unknown)")-1, 1, fstr );
1330 get_substring_vrFilter(
1333 ValuesReturnFilter *f,
1339 struct berval value;
1342 *text = "error decoding filter";
1345 LDAP_LOG(( "filter", LDAP_LEVEL_ENTRY,
1346 "get_substring_filter: conn %d begin\n", conn->c_connid ));
1348 Debug( LDAP_DEBUG_FILTER, "begin get_substring_filter\n", 0, 0, 0 );
1350 if ( ber_scanf( ber, "{m" /*}*/, &bv ) == LBER_ERROR ) {
1351 return SLAPD_DISCONNECT;
1354 f->f_sub = ch_calloc( 1, sizeof(SubstringsAssertion) );
1355 f->f_sub_desc = NULL;
1356 rc = slap_bv2ad( &bv, &f->f_sub_desc, text );
1358 if( rc != LDAP_SUCCESS ) {
1360 ch_free( f->f_sub );
1361 f->f_choice = SLAPD_FILTER_COMPUTED;
1362 f->f_result = SLAPD_COMPARE_UNDEFINED;
1363 return LDAP_SUCCESS;
1366 f->f_sub_initial.bv_val = NULL;
1367 f->f_sub_any = NULL;
1368 f->f_sub_final.bv_val = NULL;
1370 for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT;
1371 tag = ber_next_element( ber, &len, last ) )
1375 rc = ber_scanf( ber, "m", &value );
1376 if ( rc == LBER_ERROR ) {
1377 rc = SLAPD_DISCONNECT;
1381 if ( value.bv_val == NULL || value.bv_len == 0 ) {
1382 rc = LDAP_INVALID_SYNTAX;
1387 case LDAP_SUBSTRING_INITIAL:
1388 usage = SLAP_MR_SUBSTR_INITIAL;
1391 case LDAP_SUBSTRING_ANY:
1392 usage = SLAP_MR_SUBSTR_ANY;
1395 case LDAP_SUBSTRING_FINAL:
1396 usage = SLAP_MR_SUBSTR_FINAL;
1400 rc = LDAP_PROTOCOL_ERROR;
1403 LDAP_LOG(( "filter", LDAP_LEVEL_ERR,
1404 "get_filter_substring: conn %d unknown substring choice=%ld\n",
1405 conn->c_connid, (long)tag ));
1407 Debug( LDAP_DEBUG_FILTER,
1408 " unknown substring choice=%ld\n",
1414 /* valiate using equality matching rule validator! */
1415 rc = value_validate( f->f_sub_desc->ad_type->sat_equality,
1417 if( rc != LDAP_SUCCESS ) {
1421 rc = value_normalize( f->f_sub_desc, usage,
1422 &value, &bv, text );
1423 if( rc != LDAP_SUCCESS ) {
1429 rc = LDAP_PROTOCOL_ERROR;
1432 case LDAP_SUBSTRING_INITIAL:
1434 LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1,
1435 "get_substring_filter: conn %d INITIAL\n",
1438 Debug( LDAP_DEBUG_FILTER, " INITIAL\n", 0, 0, 0 );
1441 if ( f->f_sub_initial.bv_val != NULL
1442 || f->f_sub_any != NULL
1443 || f->f_sub_final.bv_val != NULL )
1445 free( value.bv_val );
1449 f->f_sub_initial = value;
1452 case LDAP_SUBSTRING_ANY:
1454 LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1,
1455 "get_substring_filter: conn %d ANY\n",
1458 Debug( LDAP_DEBUG_FILTER, " ANY\n", 0, 0, 0 );
1461 if ( f->f_sub_final.bv_val != NULL ) {
1462 free( value.bv_val );
1466 ber_bvarray_add( &f->f_sub_any, &value );
1469 case LDAP_SUBSTRING_FINAL:
1471 LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1,
1472 "get_substring_filter: conn %d FINAL\n",
1475 Debug( LDAP_DEBUG_FILTER, " FINAL\n", 0, 0, 0 );
1478 if ( f->f_sub_final.bv_val != NULL ) {
1479 free( value.bv_val );
1483 f->f_sub_final = value;
1488 LDAP_LOG(( "filter", LDAP_LEVEL_INFO,
1489 "get_substring_filter: conn %d unknown substring type %ld\n",
1490 conn->c_connid, (long)tag ));
1492 Debug( LDAP_DEBUG_FILTER,
1493 " unknown substring type=%ld\n",
1497 free( value.bv_val );
1501 LDAP_LOG(( "filter", LDAP_LEVEL_INFO,
1502 "get_substring_filter: conn %d error %ld\n",
1503 conn->c_connid, (long)rc ));
1505 Debug( LDAP_DEBUG_FILTER, " error=%ld\n",
1508 free( f->f_sub_initial.bv_val );
1509 ber_bvarray_free( f->f_sub_any );
1510 free( f->f_sub_final.bv_val );
1511 ch_free( f->f_sub );
1517 LDAP_LOG(( "filter", LDAP_LEVEL_ENTRY,
1518 "get_substring_filter: conn %d exit\n", conn->c_connid ));
1520 Debug( LDAP_DEBUG_FILTER, "end get_substring_filter\n", 0, 0, 0 );
1522 return( LDAP_SUCCESS );