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 )
1129 ValuesReturnFilter *p;
1134 ber_str2bv( "No filter!", sizeof("No filter!")-1, 1, fstr );
1138 fstr->bv_len = sizeof("()") - 1;
1139 fstr->bv_val = malloc( fstr->bv_len + 128 );
1141 snprintf( fstr->bv_val, fstr->bv_len + 1, "()");
1143 for ( p = f; p != NULL; p = p->f_next ) {
1146 simple_vrFilter2bv( p, &tmp );
1148 fstr->bv_len += tmp.bv_len;
1149 fstr->bv_val = ch_realloc( fstr->bv_val, fstr->bv_len + 1 );
1151 snprintf( &fstr->bv_val[len-1], tmp.bv_len + 2,
1152 /*"("*/ "%s)", tmp.bv_val );
1154 ch_free( tmp.bv_val );
1159 simple_vrFilter2bv( ValuesReturnFilter *f, struct berval *fstr )
1165 ber_str2bv( "No filter!", sizeof("No filter!")-1, 1, fstr );
1169 switch ( f->f_choice ) {
1170 case LDAP_FILTER_EQUALITY:
1171 filter_escape_value( &f->f_av_value, &tmp );
1173 fstr->bv_len = f->f_av_desc->ad_cname.bv_len +
1174 tmp.bv_len + ( sizeof("(=)") - 1 );
1175 fstr->bv_val = malloc( fstr->bv_len + 1 );
1177 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=%s)",
1178 f->f_av_desc->ad_cname.bv_val,
1181 ber_memfree( tmp.bv_val );
1184 case LDAP_FILTER_GE:
1185 filter_escape_value( &f->f_av_value, &tmp );
1187 fstr->bv_len = f->f_av_desc->ad_cname.bv_len +
1188 tmp.bv_len + ( sizeof("(>=)") - 1 );
1189 fstr->bv_val = malloc( fstr->bv_len + 1 );
1191 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s>=%s)",
1192 f->f_av_desc->ad_cname.bv_val,
1195 ber_memfree( tmp.bv_val );
1198 case LDAP_FILTER_LE:
1199 filter_escape_value( &f->f_av_value, &tmp );
1201 fstr->bv_len = f->f_av_desc->ad_cname.bv_len +
1202 tmp.bv_len + ( sizeof("(<=)") - 1 );
1203 fstr->bv_val = malloc( fstr->bv_len + 1 );
1205 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s<=%s)",
1206 f->f_av_desc->ad_cname.bv_val,
1209 ber_memfree( tmp.bv_val );
1212 case LDAP_FILTER_APPROX:
1213 filter_escape_value( &f->f_av_value, &tmp );
1215 fstr->bv_len = f->f_av_desc->ad_cname.bv_len +
1216 tmp.bv_len + ( sizeof("(~=)") - 1 );
1217 fstr->bv_val = malloc( fstr->bv_len + 1 );
1219 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s~=%s)",
1220 f->f_av_desc->ad_cname.bv_val,
1222 ber_memfree( tmp.bv_val );
1225 case LDAP_FILTER_SUBSTRINGS:
1226 fstr->bv_len = f->f_sub_desc->ad_cname.bv_len +
1227 ( sizeof("(=*)") - 1 );
1228 fstr->bv_val = malloc( fstr->bv_len + 128 );
1230 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=*)",
1231 f->f_sub_desc->ad_cname.bv_val );
1233 if ( f->f_sub_initial.bv_val != NULL ) {
1236 filter_escape_value( &f->f_sub_initial, &tmp );
1238 fstr->bv_len += tmp.bv_len;
1239 fstr->bv_val = ch_realloc( fstr->bv_val, fstr->bv_len + 1 );
1241 snprintf( &fstr->bv_val[len-2], tmp.bv_len+3,
1242 /* "(attr=" */ "%s*)",
1245 ber_memfree( tmp.bv_val );
1248 if ( f->f_sub_any != NULL ) {
1250 for ( i = 0; f->f_sub_any[i].bv_val != NULL; i++ ) {
1252 filter_escape_value( &f->f_sub_any[i], &tmp );
1254 fstr->bv_len += tmp.bv_len + 1;
1255 fstr->bv_val = ch_realloc( fstr->bv_val, fstr->bv_len + 1 );
1257 snprintf( &fstr->bv_val[len-1], tmp.bv_len+3,
1258 /* "(attr=[init]*[any*]" */ "%s*)",
1260 ber_memfree( tmp.bv_val );
1264 if ( f->f_sub_final.bv_val != NULL ) {
1267 filter_escape_value( &f->f_sub_final, &tmp );
1269 fstr->bv_len += tmp.bv_len;
1270 fstr->bv_val = ch_realloc( fstr->bv_val, fstr->bv_len + 1 );
1272 snprintf( &fstr->bv_val[len-1], tmp.bv_len+3,
1273 /* "(attr=[init*][any*]" */ "%s)",
1276 ber_memfree( tmp.bv_val );
1281 case LDAP_FILTER_PRESENT:
1282 fstr->bv_len = f->f_desc->ad_cname.bv_len +
1283 ( sizeof("(=*)") - 1 );
1284 fstr->bv_val = malloc( fstr->bv_len + 1 );
1286 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=*)",
1287 f->f_desc->ad_cname.bv_val );
1290 case LDAP_FILTER_EXT:
1291 filter_escape_value( &f->f_mr_value, &tmp );
1293 fstr->bv_len = f->f_mr_desc->ad_cname.bv_len +
1294 ( f->f_mr_dnattrs ? sizeof(":dn")-1 : 0 ) +
1295 ( f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_len+1 : 0 ) +
1296 tmp.bv_len + ( sizeof("(:=)") - 1 );
1297 fstr->bv_val = malloc( fstr->bv_len + 1 );
1299 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s%s%s%s:=%s)",
1300 f->f_mr_desc->ad_cname.bv_val,
1301 f->f_mr_dnattrs ? ":dn" : "",
1302 f->f_mr_rule_text.bv_len ? ":" : "",
1303 f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_val : "",
1305 ber_memfree( tmp.bv_val );
1308 case SLAPD_FILTER_COMPUTED:
1310 f->f_result == LDAP_COMPARE_FALSE ? "(?=false)" :
1311 f->f_result == LDAP_COMPARE_TRUE ? "(?=true)" :
1312 f->f_result == SLAPD_COMPARE_UNDEFINED ? "(?=undefined)" :
1314 f->f_result == LDAP_COMPARE_FALSE ? sizeof("(?=false)")-1 :
1315 f->f_result == LDAP_COMPARE_TRUE ? sizeof("(?=true)")-1 :
1316 f->f_result == SLAPD_COMPARE_UNDEFINED ? sizeof("(?=undefined)")-1 :
1317 sizeof("(?=error)")-1,
1322 ber_str2bv( "(?=unknown)", sizeof("(?=unknown)")-1, 1, fstr );
1328 get_substring_vrFilter(
1331 ValuesReturnFilter *f,
1337 struct berval value;
1340 *text = "error decoding filter";
1343 LDAP_LOG(( "filter", LDAP_LEVEL_ENTRY,
1344 "get_substring_filter: conn %d begin\n", conn->c_connid ));
1346 Debug( LDAP_DEBUG_FILTER, "begin get_substring_filter\n", 0, 0, 0 );
1348 if ( ber_scanf( ber, "{m" /*}*/, &bv ) == LBER_ERROR ) {
1349 return SLAPD_DISCONNECT;
1352 f->f_sub = ch_calloc( 1, sizeof(SubstringsAssertion) );
1353 f->f_sub_desc = NULL;
1354 rc = slap_bv2ad( &bv, &f->f_sub_desc, text );
1356 if( rc != LDAP_SUCCESS ) {
1358 ch_free( f->f_sub );
1359 f->f_choice = SLAPD_FILTER_COMPUTED;
1360 f->f_result = SLAPD_COMPARE_UNDEFINED;
1361 return LDAP_SUCCESS;
1364 f->f_sub_initial.bv_val = NULL;
1365 f->f_sub_any = NULL;
1366 f->f_sub_final.bv_val = NULL;
1368 for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT;
1369 tag = ber_next_element( ber, &len, last ) )
1373 rc = ber_scanf( ber, "m", &value );
1374 if ( rc == LBER_ERROR ) {
1375 rc = SLAPD_DISCONNECT;
1379 if ( value.bv_val == NULL || value.bv_len == 0 ) {
1380 rc = LDAP_INVALID_SYNTAX;
1385 case LDAP_SUBSTRING_INITIAL:
1386 usage = SLAP_MR_SUBSTR_INITIAL;
1389 case LDAP_SUBSTRING_ANY:
1390 usage = SLAP_MR_SUBSTR_ANY;
1393 case LDAP_SUBSTRING_FINAL:
1394 usage = SLAP_MR_SUBSTR_FINAL;
1398 rc = LDAP_PROTOCOL_ERROR;
1401 LDAP_LOG(( "filter", LDAP_LEVEL_ERR,
1402 "get_filter_substring: conn %d unknown substring choice=%ld\n",
1403 conn->c_connid, (long)tag ));
1405 Debug( LDAP_DEBUG_FILTER,
1406 " unknown substring choice=%ld\n",
1412 /* valiate using equality matching rule validator! */
1413 rc = value_validate( f->f_sub_desc->ad_type->sat_equality,
1415 if( rc != LDAP_SUCCESS ) {
1419 rc = value_normalize( f->f_sub_desc, usage,
1420 &value, &bv, text );
1421 if( rc != LDAP_SUCCESS ) {
1427 rc = LDAP_PROTOCOL_ERROR;
1430 case LDAP_SUBSTRING_INITIAL:
1432 LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1,
1433 "get_substring_filter: conn %d INITIAL\n",
1436 Debug( LDAP_DEBUG_FILTER, " INITIAL\n", 0, 0, 0 );
1439 if ( f->f_sub_initial.bv_val != NULL
1440 || f->f_sub_any != NULL
1441 || f->f_sub_final.bv_val != NULL )
1443 free( value.bv_val );
1447 f->f_sub_initial = value;
1450 case LDAP_SUBSTRING_ANY:
1452 LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1,
1453 "get_substring_filter: conn %d ANY\n",
1456 Debug( LDAP_DEBUG_FILTER, " ANY\n", 0, 0, 0 );
1459 if ( f->f_sub_final.bv_val != NULL ) {
1460 free( value.bv_val );
1464 ber_bvarray_add( &f->f_sub_any, &value );
1467 case LDAP_SUBSTRING_FINAL:
1469 LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1,
1470 "get_substring_filter: conn %d FINAL\n",
1473 Debug( LDAP_DEBUG_FILTER, " FINAL\n", 0, 0, 0 );
1476 if ( f->f_sub_final.bv_val != NULL ) {
1477 free( value.bv_val );
1481 f->f_sub_final = value;
1486 LDAP_LOG(( "filter", LDAP_LEVEL_INFO,
1487 "get_substring_filter: conn %d unknown substring type %ld\n",
1488 conn->c_connid, (long)tag ));
1490 Debug( LDAP_DEBUG_FILTER,
1491 " unknown substring type=%ld\n",
1495 free( value.bv_val );
1499 LDAP_LOG(( "filter", LDAP_LEVEL_INFO,
1500 "get_substring_filter: conn %d error %ld\n",
1501 conn->c_connid, (long)rc ));
1503 Debug( LDAP_DEBUG_FILTER, " error=%ld\n",
1506 free( f->f_sub_initial.bv_val );
1507 ber_bvarray_free( f->f_sub_any );
1508 free( f->f_sub_final.bv_val );
1509 ch_free( f->f_sub );
1515 LDAP_LOG(( "filter", LDAP_LEVEL_ENTRY,
1516 "get_substring_filter: conn %d exit\n", conn->c_connid ));
1518 Debug( LDAP_DEBUG_FILTER, "end get_substring_filter\n", 0, 0, 0 );
1520 return( LDAP_SUCCESS );