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 (void) ber_skip_tag( ber, &len );
245 f->f_choice = SLAPD_FILTER_COMPUTED;
246 f->f_result = SLAPD_COMPARE_UNDEFINED;
247 *fstr = ch_strdup( "(extended)" );
251 (void) ber_skip_tag( ber, &len );
252 Debug( LDAP_DEBUG_ANY, "get_filter: unknown filter type=%lu\n",
254 f->f_choice = SLAPD_FILTER_COMPUTED;
255 f->f_result = SLAPD_COMPARE_UNDEFINED;
256 *fstr = ch_strdup( "(undefined)" );
262 if ( err != LDAP_SUCCESS ) {
263 if ( *fstr != NULL ) {
267 if( err != SLAPD_DISCONNECT ) {
269 f->f_choice = SLAPD_FILTER_COMPUTED;
270 f->f_result = SLAPD_COMPARE_UNDEFINED;
271 *fstr = ch_strdup( "(badfilter)" );
282 Debug( LDAP_DEBUG_FILTER, "end get_filter %d\n", err, 0, 0 );
287 get_filter_list( Connection *conn, BerElement *ber,
288 Filter **f, char **fstr,
297 Debug( LDAP_DEBUG_FILTER, "begin get_filter_list\n", 0, 0, 0 );
301 for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT;
302 tag = ber_next_element( ber, &len, last ) )
304 err = get_filter( conn, ber, new, &ftmp, text );
305 if ( err != LDAP_SUCCESS )
308 if ( *fstr == NULL ) {
311 *fstr = ch_realloc( *fstr, strlen( *fstr ) +
312 strlen( ftmp ) + 1 );
313 strcat( *fstr, ftmp );
316 new = &(*new)->f_next;
320 Debug( LDAP_DEBUG_FILTER, "end get_filter_list\n", 0, 0, 0 );
321 return( LDAP_SUCCESS );
325 get_substring_filter(
336 struct berval *value;
339 struct berval *nvalue;
340 *text = "error decoding filter";
342 Debug( LDAP_DEBUG_FILTER, "begin get_substring_filter\n", 0, 0, 0 );
344 if ( ber_scanf( ber, "{o" /*}*/, &type ) == LBER_ERROR ) {
345 return SLAPD_DISCONNECT;
348 f->f_sub = ch_calloc( 1, sizeof(SubstringsAssertion) );
349 f->f_sub_desc = NULL;
350 rc = slap_bv2ad( &type, &f->f_sub_desc, text );
352 ch_free( type.bv_val );
354 if( rc != LDAP_SUCCESS ) {
357 f->f_choice = SLAPD_FILTER_COMPUTED;
358 f->f_result = SLAPD_COMPARE_UNDEFINED;
359 *fstr = ch_strdup( "(undefined)" );
363 f->f_sub_initial = NULL;
365 f->f_sub_final = NULL;
368 *fstr = ch_malloc( sizeof("(=" /*)*/) +
369 f->f_sub_desc->ad_cname->bv_len );
370 sprintf( *fstr, "(%s=" /*)*/, f->f_sub_desc->ad_cname->bv_val );
373 for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT;
374 tag = ber_next_element( ber, &len, last ) )
378 rc = ber_scanf( ber, "O", &value );
379 if ( rc == LBER_ERROR ) {
380 rc = SLAPD_DISCONNECT;
384 if ( value == 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;
406 Debug( LDAP_DEBUG_FILTER,
407 " unknown substring choice=%ld\n",
414 rc = value_normalize( f->f_sub_desc, usage, value, &nvalue, text );
417 if( rc != LDAP_SUCCESS ) {
423 rc = LDAP_PROTOCOL_ERROR;
426 case LDAP_SUBSTRING_INITIAL:
427 Debug( LDAP_DEBUG_FILTER, " INITIAL\n", 0, 0, 0 );
428 if ( f->f_sub_initial != NULL ) {
433 f->f_sub_initial = value;
436 *fstr = ch_realloc( *fstr,
437 strlen( *fstr ) + value->bv_len + 1 );
438 strcat( *fstr, value->bv_val );
442 case LDAP_SUBSTRING_ANY:
443 Debug( LDAP_DEBUG_FILTER, " ANY\n", 0, 0, 0 );
444 if( ber_bvecadd( &f->f_sub_any, value ) < 0 ) {
450 *fstr = ch_realloc( *fstr,
451 strlen( *fstr ) + value->bv_len + 2 );
452 strcat( *fstr, "*" );
453 strcat( *fstr, value->bv_val );
457 case LDAP_SUBSTRING_FINAL:
458 Debug( LDAP_DEBUG_FILTER, " FINAL\n", 0, 0, 0 );
459 if ( f->f_sub_final != NULL ) {
463 f->f_sub_final = value;
466 *fstr = ch_realloc( *fstr,
467 strlen( *fstr ) + value->bv_len + 2 );
468 strcat( *fstr, "*" );
469 strcat( *fstr, value->bv_val );
474 Debug( LDAP_DEBUG_FILTER,
475 " unknown substring type=%ld\n",
481 Debug( LDAP_DEBUG_FILTER, " error=%ld\n",
489 ad_free( f->f_sub_desc, 1 );
490 ber_bvfree( f->f_sub_initial );
491 ber_bvecfree( f->f_sub_any );
492 ber_bvfree( f->f_sub_final );
499 *fstr = ch_realloc( *fstr, strlen( *fstr ) + 3 );
500 if ( f->f_sub_final == NULL ) {
501 strcat( *fstr, "*" );
503 strcat( *fstr, /*(*/ ")" );
506 Debug( LDAP_DEBUG_FILTER, "end get_substring_filter\n", 0, 0, 0 );
507 return( LDAP_SUCCESS );
511 filter_free( Filter *f )
519 switch ( f->f_choice ) {
520 case LDAP_FILTER_PRESENT:
521 ad_free( f->f_desc, 1 );
524 case LDAP_FILTER_EQUALITY:
527 case LDAP_FILTER_APPROX:
528 ava_free( f->f_ava, 1 );
531 case LDAP_FILTER_SUBSTRINGS:
532 ad_free( f->f_sub_desc, 1 );
533 if ( f->f_sub_initial != NULL ) {
534 ber_bvfree( f->f_sub_initial );
536 ber_bvecfree( f->f_sub_any );
537 if ( f->f_sub_final != NULL ) {
538 ber_bvfree( f->f_sub_final );
542 case LDAP_FILTER_AND:
544 case LDAP_FILTER_NOT:
545 for ( p = f->f_list; p != NULL; p = next ) {
551 case SLAPD_FILTER_COMPUTED:
555 Debug( LDAP_DEBUG_ANY, "filter_free: unknown filter type=%lu\n",
566 filter_print( Filter *f )
572 fprintf( stderr, "No filter!" );
575 switch ( f->f_choice ) {
576 case LDAP_FILTER_EQUALITY:
577 fprintf( stderr, "(%s=%s)",
578 f->f_av_desc->ad_cname->bv_val,
579 f->f_av_value->bv_val );
583 fprintf( stderr, "(%s>=%s)",
584 f->f_av_desc->ad_cname->bv_val,
585 f->f_av_value->bv_val );
589 fprintf( stderr, "(%s<=%s)",
590 f->f_ava->aa_desc->ad_cname->bv_val,
591 f->f_ava->aa_value->bv_val );
594 case LDAP_FILTER_APPROX:
595 fprintf( stderr, "(%s~=%s)",
596 f->f_ava->aa_desc->ad_cname->bv_val,
597 f->f_ava->aa_value->bv_val );
600 case LDAP_FILTER_SUBSTRINGS:
601 fprintf( stderr, "(%s=" /*)*/,
602 f->f_sub_desc->ad_cname->bv_val );
603 if ( f->f_sub_initial != NULL ) {
604 fprintf( stderr, "%s",
605 f->f_sub_initial->bv_val );
607 if ( f->f_sub_any != NULL ) {
608 for ( i = 0; f->f_sub_any[i] != NULL; i++ ) {
609 fprintf( stderr, "*%s",
610 f->f_sub_any[i]->bv_val );
613 if ( f->f_sub_final != NULL ) {
615 "*%s", f->f_sub_final->bv_val );
617 fprintf( stderr, /*(*/ ")" );
620 case LDAP_FILTER_PRESENT:
621 fprintf( stderr, "(%s=*)",
622 f->f_desc->ad_cname->bv_val );
625 case LDAP_FILTER_AND:
627 case LDAP_FILTER_NOT:
628 fprintf( stderr, "(%c" /*)*/,
629 f->f_choice == LDAP_FILTER_AND ? '&' :
630 f->f_choice == LDAP_FILTER_OR ? '|' : '!' );
631 for ( p = f->f_list; p != NULL; p = p->f_next ) {
634 fprintf( stderr, /*(*/ ")" );
637 case SLAPD_FILTER_COMPUTED:
638 fprintf( stderr, "(?=%s)",
639 f->f_result == LDAP_COMPARE_FALSE ? "false" :
640 f->f_result == LDAP_COMPARE_TRUE ? "true" :
641 f->f_result == SLAPD_COMPARE_UNDEFINED ? "undefined" :
646 fprintf( stderr, "(unknown-filter=%lu)", f->f_choice );
651 #endif /* ldap_debug */