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(
45 Debug( LDAP_DEBUG_FILTER, "begin get_filter\n", 0, 0, 0 );
48 * A filter looks like this coming in:
50 * and [0] SET OF Filter,
51 * or [1] SET OF Filter,
53 * equalityMatch [3] AttributeValueAssertion,
54 * substrings [4] SubstringFilter,
55 * greaterOrEqual [5] AttributeValueAssertion,
56 * lessOrEqual [6] AttributeValueAssertion,
57 * present [7] AttributeType,,
58 * approxMatch [8] AttributeValueAssertion
59 * extensibleMatch [9] MatchingRuleAssertion
62 * SubstringFilter ::= SEQUENCE {
64 * SEQUENCE OF CHOICE {
65 * initial [0] IA5String,
71 * MatchingRuleAssertion ::= SEQUENCE {
72 * matchingRule [1] MatchingRuleId OPTIONAL,
73 * type [2] AttributeDescription OPTIONAL,
74 * matchValue [3] AssertionValue,
75 * dnAttributes [4] BOOLEAN DEFAULT FALSE
80 tag = ber_peek_tag( ber, &len );
82 if( tag == LBER_ERROR ) {
83 *text = "error decoding filter";
84 return SLAPD_DISCONNECT;
87 f = (Filter *) ch_malloc( sizeof(Filter) );
94 switch ( f->f_choice ) {
95 case LDAP_FILTER_EQUALITY:
96 Debug( LDAP_DEBUG_FILTER, "EQUALITY\n", 0, 0, 0 );
98 err = get_ava( ber, &f->f_ava, SLAP_MR_EQUALITY, text );
99 if ( err != LDAP_SUCCESS ) {
103 assert( f->f_ava != NULL );
105 *fstr = ch_malloc( sizeof("(=)")
106 + f->f_av_desc->ad_cname->bv_len
107 + f->f_av_value->bv_len );
109 sprintf( *fstr, "(%s=%s)",
110 f->f_av_desc->ad_cname->bv_val,
111 f->f_av_value->bv_val );
115 case LDAP_FILTER_SUBSTRINGS:
116 Debug( LDAP_DEBUG_FILTER, "SUBSTRINGS\n", 0, 0, 0 );
117 err = get_substring_filter( conn, ber, f, fstr, text );
121 Debug( LDAP_DEBUG_FILTER, "GE\n", 0, 0, 0 );
123 err = get_ava( ber, &f->f_ava, SLAP_MR_ORDERING, text );
124 if ( err != LDAP_SUCCESS ) {
128 *fstr = ch_malloc( sizeof("(>=)")
129 + f->f_av_desc->ad_cname->bv_len
130 + f->f_av_value->bv_len );
132 sprintf( *fstr, "(%s>=%s)",
133 f->f_av_desc->ad_cname->bv_val,
134 f->f_av_value->bv_val );
139 Debug( LDAP_DEBUG_FILTER, "LE\n", 0, 0, 0 );
141 err = get_ava( ber, &f->f_ava, SLAP_MR_ORDERING, text );
142 if ( err != LDAP_SUCCESS ) {
147 *fstr = ch_malloc( sizeof("(<=)")
148 + f->f_av_desc->ad_cname->bv_len
149 + f->f_av_value->bv_len );
151 sprintf( *fstr, "(%s<=%s)",
152 f->f_av_desc->ad_cname->bv_val,
153 f->f_av_value->bv_val );
157 case LDAP_FILTER_PRESENT: {
160 Debug( LDAP_DEBUG_FILTER, "PRESENT\n", 0, 0, 0 );
162 if ( ber_scanf( ber, "o", &type ) == LBER_ERROR ) {
163 err = SLAPD_DISCONNECT;
164 *text = "error decoding filter";
169 err = slap_bv2ad( &type, &f->f_desc, text );
171 if( err != LDAP_SUCCESS ) {
172 ch_free( type.bv_val );
176 ch_free( type.bv_val );
178 *fstr = ch_malloc( sizeof("(=*)")
179 + f->f_desc->ad_cname->bv_len );
180 sprintf( *fstr, "(%s=*)",
181 f->f_desc->ad_cname->bv_val );
185 case LDAP_FILTER_APPROX:
186 Debug( LDAP_DEBUG_FILTER, "APPROX\n", 0, 0, 0 );
188 err = get_ava( ber, &f->f_ava, SLAP_MR_EQUALITY_APPROX, text );
189 if ( err != LDAP_SUCCESS ) {
193 *fstr = ch_malloc( sizeof("(~=)")
194 + f->f_av_desc->ad_cname->bv_len
195 + f->f_av_value->bv_len );
197 sprintf( *fstr, "(%s~=%s)",
198 f->f_av_desc->ad_cname->bv_val,
199 f->f_av_value->bv_val );
203 case LDAP_FILTER_AND:
204 Debug( LDAP_DEBUG_FILTER, "AND\n", 0, 0, 0 );
205 err = get_filter_list( conn, ber, &f->f_and, &ftmp, text );
206 if ( err != LDAP_SUCCESS ) {
209 *fstr = ch_malloc( sizeof("(&)")
210 + ( ftmp == NULL ? 0 : strlen( ftmp ) ) );
211 sprintf( *fstr, "(&%s)",
212 ftmp == NULL ? "" : ftmp );
216 Debug( LDAP_DEBUG_FILTER, "OR\n", 0, 0, 0 );
217 err = get_filter_list( conn, ber, &f->f_and, &ftmp, text );
218 if ( err != LDAP_SUCCESS ) {
221 *fstr = ch_malloc( sizeof("(!)")
222 + ( ftmp == NULL ? 0 : strlen( ftmp ) ) );
223 sprintf( *fstr, "(|%s)",
224 ftmp == NULL ? "" : ftmp );
227 case LDAP_FILTER_NOT:
228 Debug( LDAP_DEBUG_FILTER, "NOT\n", 0, 0, 0 );
229 (void) ber_skip_tag( ber, &len );
230 err = get_filter( conn, ber, &f->f_not, &ftmp, text );
231 if ( err != LDAP_SUCCESS ) {
234 *fstr = ch_malloc( sizeof("(!)")
235 + ( ftmp == NULL ? 0 : strlen( ftmp ) ) );
236 sprintf( *fstr, "(!%s)",
237 ftmp == NULL ? "" : ftmp );
240 case LDAP_FILTER_EXT:
241 /* not yet implemented */
242 Debug( LDAP_DEBUG_ANY, "extensible match not yet implemented.\n",
244 f->f_choice = SLAPD_FILTER_COMPUTED;
245 f->f_result = SLAPD_COMPARE_UNDEFINED;
246 *fstr = ch_strdup( "(extended)" );
250 Debug( LDAP_DEBUG_ANY, "get_filter: unknown filter type=%lu\n",
252 f->f_choice = SLAPD_FILTER_COMPUTED;
253 f->f_result = SLAPD_COMPARE_UNDEFINED;
254 *fstr = ch_strdup( "(undefined)" );
260 if ( err != LDAP_SUCCESS ) {
261 if ( *fstr != NULL ) {
265 if( err != SLAPD_DISCONNECT ) {
267 f->f_choice = SLAPD_FILTER_COMPUTED;
268 f->f_result = SLAPD_COMPARE_UNDEFINED;
269 *fstr = ch_strdup( "(badfilter)" );
280 Debug( LDAP_DEBUG_FILTER, "end get_filter %d\n", err, 0, 0 );
285 get_filter_list( Connection *conn, BerElement *ber,
286 Filter **f, char **fstr,
295 Debug( LDAP_DEBUG_FILTER, "begin get_filter_list\n", 0, 0, 0 );
299 for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT;
300 tag = ber_next_element( ber, &len, last ) )
302 err = get_filter( conn, ber, new, &ftmp, text );
303 if ( err != LDAP_SUCCESS )
306 if ( *fstr == NULL ) {
309 *fstr = ch_realloc( *fstr, strlen( *fstr ) +
310 strlen( ftmp ) + 1 );
311 strcat( *fstr, ftmp );
314 new = &(*new)->f_next;
318 Debug( LDAP_DEBUG_FILTER, "end get_filter_list\n", 0, 0, 0 );
319 return( LDAP_SUCCESS );
323 get_substring_filter(
334 struct berval *value;
337 struct berval *nvalue;
338 *text = "error decoding filter";
340 Debug( LDAP_DEBUG_FILTER, "begin get_substring_filter\n", 0, 0, 0 );
342 if ( ber_scanf( ber, "{o" /*}*/, &type ) == LBER_ERROR ) {
343 return SLAPD_DISCONNECT;
346 f->f_sub = ch_calloc( 1, sizeof(SubstringsAssertion) );
347 f->f_sub_desc = NULL;
348 rc = slap_bv2ad( &type, &f->f_sub_desc, text );
350 ch_free( type.bv_val );
352 if( rc != LDAP_SUCCESS ) {
355 f->f_choice = SLAPD_FILTER_COMPUTED;
356 f->f_result = SLAPD_COMPARE_UNDEFINED;
357 *fstr = ch_strdup( "(undefined)" );
361 f->f_sub_initial = NULL;
363 f->f_sub_final = NULL;
366 *fstr = ch_malloc( sizeof("(=" /*)*/) +
367 f->f_sub_desc->ad_cname->bv_len );
368 sprintf( *fstr, "(%s=" /*)*/, f->f_sub_desc->ad_cname->bv_val );
371 for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT;
372 tag = ber_next_element( ber, &len, last ) )
376 rc = ber_scanf( ber, "O", &value );
377 if ( rc == LBER_ERROR ) {
378 rc = SLAPD_DISCONNECT;
382 if ( value == NULL || value->bv_len == 0 ) {
384 rc = LDAP_INVALID_SYNTAX;
389 case LDAP_SUBSTRING_INITIAL:
390 usage = SLAP_MR_SUBSTR_INITIAL;
393 case LDAP_SUBSTRING_ANY:
394 usage = SLAP_MR_SUBSTR_ANY;
397 case LDAP_SUBSTRING_FINAL:
398 usage = SLAP_MR_SUBSTR_FINAL;
402 rc = LDAP_PROTOCOL_ERROR;
404 Debug( LDAP_DEBUG_FILTER,
405 " unknown substring choice=%ld\n",
412 rc = value_normalize( f->f_sub_desc, usage, value, &nvalue, text );
415 if( rc != LDAP_SUCCESS ) {
421 rc = LDAP_PROTOCOL_ERROR;
424 case LDAP_SUBSTRING_INITIAL:
425 Debug( LDAP_DEBUG_FILTER, " INITIAL\n", 0, 0, 0 );
426 if ( f->f_sub_initial != NULL ) {
431 f->f_sub_initial = value;
434 *fstr = ch_realloc( *fstr,
435 strlen( *fstr ) + value->bv_len + 1 );
436 strcat( *fstr, value->bv_val );
440 case LDAP_SUBSTRING_ANY:
441 Debug( LDAP_DEBUG_FILTER, " ANY\n", 0, 0, 0 );
442 if( ber_bvecadd( &f->f_sub_any, value ) < 0 ) {
448 *fstr = ch_realloc( *fstr,
449 strlen( *fstr ) + value->bv_len + 2 );
450 strcat( *fstr, "*" );
451 strcat( *fstr, value->bv_val );
455 case LDAP_SUBSTRING_FINAL:
456 Debug( LDAP_DEBUG_FILTER, " FINAL\n", 0, 0, 0 );
457 if ( f->f_sub_final != NULL ) {
461 f->f_sub_final = value;
464 *fstr = ch_realloc( *fstr,
465 strlen( *fstr ) + value->bv_len + 2 );
466 strcat( *fstr, "*" );
467 strcat( *fstr, value->bv_val );
472 Debug( LDAP_DEBUG_FILTER,
473 " unknown substring type=%ld\n",
479 Debug( LDAP_DEBUG_FILTER, " error=%ld\n",
487 ad_free( f->f_sub_desc, 1 );
488 ber_bvfree( f->f_sub_initial );
489 ber_bvecfree( f->f_sub_any );
490 ber_bvfree( f->f_sub_final );
497 *fstr = ch_realloc( *fstr, strlen( *fstr ) + 3 );
498 if ( f->f_sub_final == NULL ) {
499 strcat( *fstr, "*" );
501 strcat( *fstr, /*(*/ ")" );
504 Debug( LDAP_DEBUG_FILTER, "end get_substring_filter\n", 0, 0, 0 );
505 return( LDAP_SUCCESS );
509 filter_free( Filter *f )
517 switch ( f->f_choice ) {
518 case LDAP_FILTER_PRESENT:
519 ad_free( f->f_desc, 1 );
522 case LDAP_FILTER_EQUALITY:
525 case LDAP_FILTER_APPROX:
526 ava_free( f->f_ava, 1 );
529 case LDAP_FILTER_SUBSTRINGS:
530 ad_free( f->f_sub_desc, 1 );
531 if ( f->f_sub_initial != NULL ) {
532 ber_bvfree( f->f_sub_initial );
534 ber_bvecfree( f->f_sub_any );
535 if ( f->f_sub_final != NULL ) {
536 ber_bvfree( f->f_sub_final );
540 case LDAP_FILTER_AND:
542 case LDAP_FILTER_NOT:
543 for ( p = f->f_list; p != NULL; p = next ) {
549 case SLAPD_FILTER_COMPUTED:
553 Debug( LDAP_DEBUG_ANY, "filter_free: unknown filter type=%lu\n",
564 filter_print( Filter *f )
570 fprintf( stderr, "No filter!" );
573 switch ( f->f_choice ) {
574 case LDAP_FILTER_EQUALITY:
575 fprintf( stderr, "(%s=%s)",
576 f->f_av_desc->ad_cname->bv_val,
577 f->f_av_value->bv_val );
581 fprintf( stderr, "(%s>=%s)",
582 f->f_av_desc->ad_cname->bv_val,
583 f->f_av_value->bv_val );
587 fprintf( stderr, "(%s<=%s)",
588 f->f_ava->aa_desc->ad_cname->bv_val,
589 f->f_ava->aa_value->bv_val );
592 case LDAP_FILTER_APPROX:
593 fprintf( stderr, "(%s~=%s)",
594 f->f_ava->aa_desc->ad_cname->bv_val,
595 f->f_ava->aa_value->bv_val );
598 case LDAP_FILTER_SUBSTRINGS:
599 fprintf( stderr, "(%s=" /*)*/,
600 f->f_sub_desc->ad_cname->bv_val );
601 if ( f->f_sub_initial != NULL ) {
602 fprintf( stderr, "%s",
603 f->f_sub_initial->bv_val );
605 if ( f->f_sub_any != NULL ) {
606 for ( i = 0; f->f_sub_any[i] != NULL; i++ ) {
607 fprintf( stderr, "*%s",
608 f->f_sub_any[i]->bv_val );
611 if ( f->f_sub_final != NULL ) {
613 "*%s", f->f_sub_final->bv_val );
615 fprintf( stderr, /*(*/ ")" );
618 case LDAP_FILTER_PRESENT:
619 fprintf( stderr, "(%s=*)",
620 f->f_desc->ad_cname->bv_val );
623 case LDAP_FILTER_AND:
625 case LDAP_FILTER_NOT:
626 fprintf( stderr, "(%c" /*)*/,
627 f->f_choice == LDAP_FILTER_AND ? '&' :
628 f->f_choice == LDAP_FILTER_OR ? '|' : '!' );
629 for ( p = f->f_list; p != NULL; p = p->f_next ) {
632 fprintf( stderr, /*(*/ ")" );
635 case SLAPD_FILTER_COMPUTED:
636 fprintf( stderr, "(?=%s)",
637 f->f_result == LDAP_COMPARE_FALSE ? "false" :
638 f->f_result == LDAP_COMPARE_TRUE ? "true" :
639 f->f_result == SLAPD_COMPARE_UNDEFINED ? "undefined" :
644 fprintf( stderr, "(unknown-filter=%lu)", f->f_choice );
649 #endif /* ldap_debug */