1 /* filter.c - routines for parsing and dealing with filters */
4 * Copyright 1998-2000 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(
24 static int get_substring_filter(
31 static int filter_escape_value(
48 struct berval escaped;
51 LDAP_LOG(( "filter", LDAP_LEVEL_ENTRY, "get_filter: conn %d\n",
54 Debug( LDAP_DEBUG_FILTER, "begin get_filter\n", 0, 0, 0 );
57 * A filter looks like this coming in:
59 * and [0] SET OF Filter,
60 * or [1] SET OF Filter,
62 * equalityMatch [3] AttributeValueAssertion,
63 * substrings [4] SubstringFilter,
64 * greaterOrEqual [5] AttributeValueAssertion,
65 * lessOrEqual [6] AttributeValueAssertion,
66 * present [7] AttributeType,,
67 * approxMatch [8] AttributeValueAssertion
68 * extensibleMatch [9] MatchingRuleAssertion
71 * SubstringFilter ::= SEQUENCE {
73 * SEQUENCE OF CHOICE {
74 * initial [0] IA5String,
80 * MatchingRuleAssertion ::= SEQUENCE {
81 * matchingRule [1] MatchingRuleId OPTIONAL,
82 * type [2] AttributeDescription OPTIONAL,
83 * matchValue [3] AssertionValue,
84 * dnAttributes [4] BOOLEAN DEFAULT FALSE
89 tag = ber_peek_tag( ber, &len );
91 if( tag == LBER_ERROR ) {
92 *text = "error decoding filter";
93 return SLAPD_DISCONNECT;
96 f = (Filter *) ch_malloc( sizeof(Filter) );
103 switch ( f->f_choice ) {
104 case LDAP_FILTER_EQUALITY:
106 LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL2,
107 "get_filter: conn %d EQUALITY\n", conn->c_connid ));
109 Debug( LDAP_DEBUG_FILTER, "EQUALITY\n", 0, 0, 0 );
111 err = get_ava( ber, &f->f_ava, SLAP_MR_EQUALITY, text );
112 if ( err != LDAP_SUCCESS ) {
116 assert( f->f_ava != NULL );
118 filter_escape_value( f->f_av_value, &escaped );
120 *fstr = ch_malloc( sizeof("(=)")
121 + f->f_av_desc->ad_cname->bv_len
124 sprintf( *fstr, "(%s=%s)",
125 f->f_av_desc->ad_cname->bv_val,
128 ber_memfree( escaped.bv_val );
131 case LDAP_FILTER_SUBSTRINGS:
133 LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1,
134 "get_filter: conn %d SUBSTRINGS\n", conn->c_connid ));
136 Debug( LDAP_DEBUG_FILTER, "SUBSTRINGS\n", 0, 0, 0 );
138 err = get_substring_filter( conn, ber, f, fstr, text );
143 LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1,
144 "get_filter: conn %d GE\n", conn->c_connid ));
146 Debug( LDAP_DEBUG_FILTER, "GE\n", 0, 0, 0 );
148 err = get_ava( ber, &f->f_ava, SLAP_MR_ORDERING, text );
149 if ( err != LDAP_SUCCESS ) {
153 filter_escape_value( f->f_av_value, &escaped );
155 *fstr = ch_malloc( sizeof("(>=)")
156 + f->f_av_desc->ad_cname->bv_len
159 sprintf( *fstr, "(%s>=%s)",
160 f->f_av_desc->ad_cname->bv_val,
163 ber_memfree( escaped.bv_val );
168 LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1,
169 "get_filter: conn %d LE\n", conn->c_connid ));
171 Debug( LDAP_DEBUG_FILTER, "LE\n", 0, 0, 0 );
173 err = get_ava( ber, &f->f_ava, SLAP_MR_ORDERING, text );
174 if ( err != LDAP_SUCCESS ) {
179 filter_escape_value( f->f_av_value, &escaped );
181 *fstr = ch_malloc( sizeof("(<=)")
182 + f->f_av_desc->ad_cname->bv_len
185 sprintf( *fstr, "(%s<=%s)",
186 f->f_av_desc->ad_cname->bv_val,
189 ber_memfree( escaped.bv_val );
192 case LDAP_FILTER_PRESENT: {
196 LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1,
197 "get_filter: conn %d PRESENT\n", conn->c_connid ));
199 Debug( LDAP_DEBUG_FILTER, "PRESENT\n", 0, 0, 0 );
201 if ( ber_scanf( ber, "o", &type ) == LBER_ERROR ) {
202 err = SLAPD_DISCONNECT;
203 *text = "error decoding filter";
208 err = slap_bv2ad( &type, &f->f_desc, text );
210 if( err != LDAP_SUCCESS ) {
211 ch_free( type.bv_val );
215 ch_free( type.bv_val );
217 *fstr = ch_malloc( sizeof("(=*)")
218 + f->f_desc->ad_cname->bv_len );
219 sprintf( *fstr, "(%s=*)",
220 f->f_desc->ad_cname->bv_val );
224 case LDAP_FILTER_APPROX:
226 LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1,
227 "get_filter: conn %d APPROX\n", conn->c_connid ));
229 Debug( LDAP_DEBUG_FILTER, "APPROX\n", 0, 0, 0 );
231 err = get_ava( ber, &f->f_ava, SLAP_MR_EQUALITY_APPROX, text );
232 if ( err != LDAP_SUCCESS ) {
236 filter_escape_value( f->f_av_value, &escaped );
238 *fstr = ch_malloc( sizeof("(~=)")
239 + f->f_av_desc->ad_cname->bv_len
242 sprintf( *fstr, "(%s~=%s)",
243 f->f_av_desc->ad_cname->bv_val,
246 ber_memfree( escaped.bv_val );
249 case LDAP_FILTER_AND:
251 LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1,
252 "get_filter: conn %d AND\n", conn->c_connid ));
254 Debug( LDAP_DEBUG_FILTER, "AND\n", 0, 0, 0 );
256 err = get_filter_list( conn, ber, &f->f_and, &ftmp, text );
257 if ( err != LDAP_SUCCESS ) {
260 *fstr = ch_malloc( sizeof("(&)")
261 + ( ftmp == NULL ? 0 : strlen( ftmp ) ) );
262 sprintf( *fstr, "(&%s)",
263 ftmp == NULL ? "" : ftmp );
268 LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1,
269 "get_filter: conn %d OR\n", conn->c_connid ));
271 Debug( LDAP_DEBUG_FILTER, "OR\n", 0, 0, 0 );
273 err = get_filter_list( conn, ber, &f->f_and, &ftmp, text );
274 if ( err != LDAP_SUCCESS ) {
277 *fstr = ch_malloc( sizeof("(!)")
278 + ( ftmp == NULL ? 0 : strlen( ftmp ) ) );
279 sprintf( *fstr, "(|%s)",
280 ftmp == NULL ? "" : ftmp );
283 case LDAP_FILTER_NOT:
285 LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1,
286 "get_filter: conn %d NOT\n", conn->c_connid ));
288 Debug( LDAP_DEBUG_FILTER, "NOT\n", 0, 0, 0 );
290 (void) ber_skip_tag( ber, &len );
291 err = get_filter( conn, ber, &f->f_not, &ftmp, text );
292 if ( err != LDAP_SUCCESS ) {
295 *fstr = ch_malloc( sizeof("(!)")
296 + ( ftmp == NULL ? 0 : strlen( ftmp ) ) );
297 sprintf( *fstr, "(!%s)",
298 ftmp == NULL ? "" : ftmp );
301 case LDAP_FILTER_EXT:
303 LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1,
304 "get_filter: conn %d EXTENSIBLE\n", conn->c_connid ));
306 Debug( LDAP_DEBUG_FILTER, "EXTENSIBLE\n", 0, 0, 0 );
309 err = get_mra( ber, &f->f_mra, text );
310 if ( err != LDAP_SUCCESS ) {
314 assert( f->f_mra != NULL );
316 filter_escape_value( f->f_mr_value, &escaped );
318 *fstr = ch_malloc( sizeof("(:dn::=)")
319 + (f->f_mr_desc ? f->f_mr_desc->ad_cname->bv_len : 0)
320 + (f->f_mr_rule_text ? strlen(f->f_mr_rule_text) : 0)
323 sprintf( *fstr, "(%s%s%s%s:=%s)",
324 (f->f_mr_desc ? f->f_mr_desc->ad_cname->bv_val : ""),
325 (f->f_mr_dnattrs ? ":dn" : ""),
326 (f->f_mr_rule_text ? ":" : ""),
327 (f->f_mr_rule_text ? f->f_mr_rule_text : ""),
330 ber_memfree( escaped.bv_val );
334 (void) ber_scanf( ber, "x" ); /* skip the element */
336 LDAP_LOG(( "filter", LDAP_LEVEL_ERR,
337 "get_filter: conn %d unknown filter type=%lu\n",
338 conn->c_connid, f->f_choice ));
340 Debug( LDAP_DEBUG_ANY, "get_filter: unknown filter type=%lu\n",
343 f->f_choice = SLAPD_FILTER_COMPUTED;
344 f->f_result = SLAPD_COMPARE_UNDEFINED;
345 *fstr = ch_strdup( "(undefined)" );
351 if ( err != LDAP_SUCCESS ) {
352 if ( *fstr != NULL ) {
356 if( err != SLAPD_DISCONNECT ) {
358 f->f_choice = SLAPD_FILTER_COMPUTED;
359 f->f_result = SLAPD_COMPARE_UNDEFINED;
360 *fstr = ch_strdup( "(badfilter)" );
372 LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL2,
373 "get_filter: conn %d exit\n", conn->c_connid ));
375 Debug( LDAP_DEBUG_FILTER, "end get_filter %d\n", err, 0, 0 );
381 get_filter_list( Connection *conn, BerElement *ber,
382 Filter **f, char **fstr,
392 LDAP_LOG(( "filter", LDAP_LEVEL_ENTRY,
393 "get_filter_list: conn %d start\n", conn->c_connid ));
395 Debug( LDAP_DEBUG_FILTER, "begin get_filter_list\n", 0, 0, 0 );
399 for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT;
400 tag = ber_next_element( ber, &len, last ) )
402 err = get_filter( conn, ber, new, &ftmp, text );
403 if ( err != LDAP_SUCCESS )
406 if ( *fstr == NULL ) {
409 *fstr = ch_realloc( *fstr, strlen( *fstr ) +
410 strlen( ftmp ) + 1 );
411 strcat( *fstr, ftmp );
414 new = &(*new)->f_next;
419 LDAP_LOG(( "filter", LDAP_LEVEL_ENTRY,
420 "get_filter_list: conn %d exit\n", conn->c_connid ));
422 Debug( LDAP_DEBUG_FILTER, "end get_filter_list\n", 0, 0, 0 );
424 return( LDAP_SUCCESS );
428 get_substring_filter(
439 struct berval *value;
440 struct berval escaped;
443 struct berval *nvalue;
444 *text = "error decoding filter";
447 LDAP_LOG(( "filter", LDAP_LEVEL_ENTRY,
448 "get_substring_filter: conn %d begin\n", conn->c_connid ));
450 Debug( LDAP_DEBUG_FILTER, "begin get_substring_filter\n", 0, 0, 0 );
452 if ( ber_scanf( ber, "{o" /*}*/, &type ) == LBER_ERROR ) {
453 return SLAPD_DISCONNECT;
456 f->f_sub = ch_calloc( 1, sizeof(SubstringsAssertion) );
457 f->f_sub_desc = NULL;
458 rc = slap_bv2ad( &type, &f->f_sub_desc, text );
460 ch_free( type.bv_val );
462 if( rc != LDAP_SUCCESS ) {
465 f->f_choice = SLAPD_FILTER_COMPUTED;
466 f->f_result = SLAPD_COMPARE_UNDEFINED;
467 *fstr = ch_strdup( "(undefined)" );
471 f->f_sub_initial = NULL;
473 f->f_sub_final = NULL;
476 *fstr = ch_malloc( sizeof("(=" /*)*/) +
477 f->f_sub_desc->ad_cname->bv_len );
478 sprintf( *fstr, "(%s=" /*)*/, f->f_sub_desc->ad_cname->bv_val );
481 for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT;
482 tag = ber_next_element( ber, &len, last ) )
486 rc = ber_scanf( ber, "O", &value );
487 if ( rc == LBER_ERROR ) {
488 rc = SLAPD_DISCONNECT;
492 if ( value == NULL || value->bv_len == 0 ) {
494 rc = LDAP_INVALID_SYNTAX;
499 case LDAP_SUBSTRING_INITIAL:
500 usage = SLAP_MR_SUBSTR_INITIAL;
503 case LDAP_SUBSTRING_ANY:
504 usage = SLAP_MR_SUBSTR_ANY;
507 case LDAP_SUBSTRING_FINAL:
508 usage = SLAP_MR_SUBSTR_FINAL;
512 rc = LDAP_PROTOCOL_ERROR;
515 LDAP_LOG(( "filter", LDAP_LEVEL_ERR,
516 "get_filter_substring: conn %d unknown substring choice=%ld\n",
517 conn->c_connid, (long)tag ));
519 Debug( LDAP_DEBUG_FILTER,
520 " unknown substring choice=%ld\n",
527 rc = value_normalize( f->f_sub_desc, usage, value, &nvalue, text );
530 if( rc != LDAP_SUCCESS ) {
536 rc = LDAP_PROTOCOL_ERROR;
539 case LDAP_SUBSTRING_INITIAL:
541 LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1,
542 "get_substring_filter: conn %d INITIAL\n",
545 Debug( LDAP_DEBUG_FILTER, " INITIAL\n", 0, 0, 0 );
548 if ( f->f_sub_initial != NULL
549 || f->f_sub_any != NULL
550 || f->f_sub_final != NULL )
556 f->f_sub_initial = value;
559 filter_escape_value( value, &escaped );
560 *fstr = ch_realloc( *fstr,
561 strlen( *fstr ) + escaped.bv_len + 1 );
562 strcat( *fstr, escaped.bv_val );
563 ber_memfree( escaped.bv_val );
567 case LDAP_SUBSTRING_ANY:
569 LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1,
570 "get_substring_filter: conn %d ANY\n",
573 Debug( LDAP_DEBUG_FILTER, " ANY\n", 0, 0, 0 );
576 if ( f->f_sub_final != NULL ) {
581 if( ber_bvecadd( &f->f_sub_any, value ) < 0 ) {
587 filter_escape_value( value, &escaped );
588 *fstr = ch_realloc( *fstr,
589 strlen( *fstr ) + escaped.bv_len + 2 );
590 strcat( *fstr, "*" );
591 strcat( *fstr, escaped.bv_val );
592 ber_memfree( escaped.bv_val );
596 case LDAP_SUBSTRING_FINAL:
598 LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1,
599 "get_substring_filter: conn %d FINAL\n",
602 Debug( LDAP_DEBUG_FILTER, " FINAL\n", 0, 0, 0 );
605 if ( f->f_sub_final != NULL ) {
610 f->f_sub_final = value;
613 filter_escape_value( value, &escaped );
614 *fstr = ch_realloc( *fstr,
615 strlen( *fstr ) + escaped.bv_len + 2 );
616 strcat( *fstr, "*" );
617 strcat( *fstr, escaped.bv_val );
618 ber_memfree( escaped.bv_val );
624 LDAP_LOG(( "filter", LDAP_LEVEL_INFO,
625 "get_substring_filter: conn %d unknown substring type %ld\n",
626 conn->c_connid, (long)tag ));
628 Debug( LDAP_DEBUG_FILTER,
629 " unknown substring type=%ld\n",
637 LDAP_LOG(( "filter", LDAP_LEVEL_INFO,
638 "get_substring_filter: conn %d error %ld\n",
639 conn->c_connid, (long)rc ));
641 Debug( LDAP_DEBUG_FILTER, " error=%ld\n",
649 ad_free( f->f_sub_desc, 1 );
650 ber_bvfree( f->f_sub_initial );
651 ber_bvecfree( f->f_sub_any );
652 ber_bvfree( f->f_sub_final );
659 *fstr = ch_realloc( *fstr, strlen( *fstr ) + 3 );
660 if ( f->f_sub_final == NULL ) {
661 strcat( *fstr, "*" );
663 strcat( *fstr, /*(*/ ")" );
667 LDAP_LOG(( "filter", LDAP_LEVEL_ENTRY,
668 "get_substring_filter: conn %d exit\n", conn->c_connid ));
670 Debug( LDAP_DEBUG_FILTER, "end get_substring_filter\n", 0, 0, 0 );
672 return( LDAP_SUCCESS );
676 filter_free( Filter *f )
684 switch ( f->f_choice ) {
685 case LDAP_FILTER_PRESENT:
686 ad_free( f->f_desc, 1 );
689 case LDAP_FILTER_EQUALITY:
692 case LDAP_FILTER_APPROX:
693 ava_free( f->f_ava, 1 );
696 case LDAP_FILTER_SUBSTRINGS:
697 ad_free( f->f_sub_desc, 1 );
698 if ( f->f_sub_initial != NULL ) {
699 ber_bvfree( f->f_sub_initial );
701 ber_bvecfree( f->f_sub_any );
702 if ( f->f_sub_final != NULL ) {
703 ber_bvfree( f->f_sub_final );
708 case LDAP_FILTER_AND:
710 case LDAP_FILTER_NOT:
711 for ( p = f->f_list; p != NULL; p = next ) {
717 case SLAPD_FILTER_COMPUTED:
722 LDAP_LOG(( "filter", LDAP_LEVEL_ERR,
723 "filter_free: unknown filter type %lu\n", f->f_choice ));
725 Debug( LDAP_DEBUG_ANY, "filter_free: unknown filter type=%lu\n",
736 filter_print( Filter *f )
740 struct berval escaped;
743 fprintf( stderr, "No filter!" );
746 switch ( f->f_choice ) {
747 case LDAP_FILTER_EQUALITY:
748 filter_escape_value( f->f_av_value, &escaped );
749 fprintf( stderr, "(%s=%s)",
750 f->f_av_desc->ad_cname->bv_val,
752 ber_memfree( escaped.bv_val );
756 filter_escape_value( f->f_av_value, &escaped );
757 fprintf( stderr, "(%s>=%s)",
758 f->f_av_desc->ad_cname->bv_val,
760 ber_memfree( escaped.bv_val );
764 filter_escape_value( f->f_av_value, &escaped );
765 fprintf( stderr, "(%s<=%s)",
766 f->f_ava->aa_desc->ad_cname->bv_val,
768 ber_memfree( escaped.bv_val );
771 case LDAP_FILTER_APPROX:
772 filter_escape_value( f->f_av_value, &escaped );
773 fprintf( stderr, "(%s~=%s)",
774 f->f_ava->aa_desc->ad_cname->bv_val,
776 ber_memfree( escaped.bv_val );
779 case LDAP_FILTER_SUBSTRINGS:
780 fprintf( stderr, "(%s=" /*)*/,
781 f->f_sub_desc->ad_cname->bv_val );
782 if ( f->f_sub_initial != NULL ) {
783 filter_escape_value( f->f_sub_initial, &escaped );
784 fprintf( stderr, "%s",
786 ber_memfree( escaped.bv_val );
788 if ( f->f_sub_any != NULL ) {
789 for ( i = 0; f->f_sub_any[i] != NULL; i++ ) {
790 filter_escape_value( f->f_sub_any[i], &escaped );
791 fprintf( stderr, "*%s",
793 ber_memfree( escaped.bv_val );
796 if ( f->f_sub_final != NULL ) {
797 filter_escape_value( f->f_sub_final, &escaped );
799 "*%s", escaped.bv_val );
800 ber_memfree( escaped.bv_val );
802 fprintf( stderr, /*(*/ ")" );
805 case LDAP_FILTER_PRESENT:
806 fprintf( stderr, "(%s=*)",
807 f->f_desc->ad_cname->bv_val );
810 case LDAP_FILTER_AND:
812 case LDAP_FILTER_NOT:
813 fprintf( stderr, "(%c" /*)*/,
814 f->f_choice == LDAP_FILTER_AND ? '&' :
815 f->f_choice == LDAP_FILTER_OR ? '|' : '!' );
816 for ( p = f->f_list; p != NULL; p = p->f_next ) {
819 fprintf( stderr, /*(*/ ")" );
822 case SLAPD_FILTER_COMPUTED:
823 fprintf( stderr, "(?=%s)",
824 f->f_result == LDAP_COMPARE_FALSE ? "false" :
825 f->f_result == LDAP_COMPARE_TRUE ? "true" :
826 f->f_result == SLAPD_COMPARE_UNDEFINED ? "undefined" :
831 fprintf( stderr, "(unknown-filter=%lu)", f->f_choice );
836 #endif /* ldap_debug */
838 int filter_escape_value(
846 out->bv_val = (char *) ch_malloc( ( in->bv_len * 3 ) + 1 );
849 for( i=0; i < in->bv_len ; i++ ) {
850 if( FILTER_ESCAPE(in->bv_val[i]) ) {
851 out->bv_val[out->bv_len++] = SLAP_ESCAPE_CHAR;
852 out->bv_val[out->bv_len++] = SLAP_ESCAPE_HI( in->bv_val[i] );
853 out->bv_val[out->bv_len++] = SLAP_ESCAPE_LO( in->bv_val[i] );
855 out->bv_val[out->bv_len++] = in->bv_val[i];
859 out->bv_val[out->bv_len] = '\0';