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(
23 static int get_substring_filter(
44 Debug( LDAP_DEBUG_FILTER, "begin get_filter\n", 0, 0, 0 );
47 * A filter looks like this coming in:
49 * and [0] SET OF Filter,
50 * or [1] SET OF Filter,
52 * equalityMatch [3] AttributeValueAssertion,
53 * substrings [4] SubstringFilter,
54 * greaterOrEqual [5] AttributeValueAssertion,
55 * lessOrEqual [6] AttributeValueAssertion,
56 * present [7] AttributeType,,
57 * approxMatch [8] AttributeValueAssertion
58 * extensibleMatch [9] MatchingRuleAssertion
61 * SubstringFilter ::= SEQUENCE {
63 * SEQUENCE OF CHOICE {
64 * initial [0] IA5String,
70 * MatchingRuleAssertion ::= SEQUENCE {
71 * matchingRule [1] MatchingRuleId OPTIONAL,
72 * type [2] AttributeDescription OPTIONAL,
73 * matchValue [3] AssertionValue,
74 * dnAttributes [4] BOOLEAN DEFAULT FALSE
79 tag = ber_peek_tag( ber, &len );
81 if( tag == LBER_ERROR ) {
82 *text = "error decoding filter";
83 return SLAPD_DISCONNECT;
86 f = (Filter *) ch_malloc( sizeof(Filter) );
93 switch ( f->f_choice ) {
94 case LDAP_FILTER_EQUALITY:
95 Debug( LDAP_DEBUG_FILTER, "EQUALITY\n", 0, 0, 0 );
96 #ifdef SLAPD_SCHEMA_NOT_COMPAT
97 if ( (err = get_ava( ber, &f->f_ava )) != LDAP_SUCCESS ) {
98 *text = "error decoding filter";
102 *fstr = ch_malloc( sizeof("(=)")
103 + f->f_av_desc->ad_cname->bv_len
104 + f->f_av_value->bv_len );
106 sprintf( *fstr, "(%s=%s)",
107 f->f_av_desc->ad_cname->bv_val,
108 f->f_av_value->bv_val );
111 if ( (err = get_ava( ber, f->f_ava )) != LDAP_SUCCESS ) {
112 *text = "error decoding filter";
116 *fstr = ch_malloc( sizeof("(=)")
117 + strlen( f->f_avtype )
118 + f->f_avvalue.bv_len);
119 sprintf( *fstr, "(%s=%s)", f->f_avtype,
120 f->f_avvalue.bv_val );
124 case LDAP_FILTER_SUBSTRINGS:
125 Debug( LDAP_DEBUG_FILTER, "SUBSTRINGS\n", 0, 0, 0 );
126 err = get_substring_filter( conn, ber, f, fstr, text );
130 Debug( LDAP_DEBUG_FILTER, "GE\n", 0, 0, 0 );
131 #ifdef SLAPD_SCHEMA_NOT_COMPAT
132 if ( (err = get_ava( ber, &f->f_ava )) != LDAP_SUCCESS ) {
133 *text = "decoding filter error";
137 *fstr = ch_malloc( sizeof("(>=)")
138 + f->f_av_desc->ad_cname->bv_len
139 + f->f_av_value->bv_len );
141 sprintf( *fstr, "(%s>=%s)",
142 f->f_av_desc->ad_cname->bv_val,
143 f->f_av_value->bv_val );
146 if ( (err = get_ava( ber, f->f_ava )) != LDAP_SUCCESS ) {
147 *text = "decoding filter error";
151 *fstr = ch_malloc( sizeof("(>=)"
152 + strlen( f->f_avtype )
153 + f->f_avvalue.bv_len);
154 sprintf( *fstr, "(%s>=%s)", f->f_avtype,
155 f->f_avvalue.bv_val );
160 Debug( LDAP_DEBUG_FILTER, "LE\n", 0, 0, 0 );
161 #ifdef SLAPD_SCHEMA_NOT_COMPAT
162 if ( (err = get_ava( ber, &f->f_ava )) != LDAP_SUCCESS ) {
163 *text = "decoding filter error";
167 *fstr = ch_malloc( sizeof("(<=)")
168 + f->f_av_desc->ad_cname->bv_len
169 + f->f_av_value->bv_len );
171 sprintf( *fstr, "(%s<=%s)",
172 f->f_av_desc->ad_cname->bv_val,
173 f->f_av_value->bv_val );
176 if ( (err = get_ava( ber, f->f_ava )) != LDAP_SUCCESS ) {
177 *text = "error decoding filter";
180 *fstr = ch_malloc( sizeof("(<=)"
181 + strlen( f->f_avtype )
182 + f->f_avvalue.bv_len);
183 sprintf( *fstr, "(%s<=%s)", f->f_avtype,
184 f->f_avvalue.bv_val );
188 case LDAP_FILTER_PRESENT: {
191 Debug( LDAP_DEBUG_FILTER, "PRESENT\n", 0, 0, 0 );
193 if ( ber_scanf( ber, "o", &type ) == LBER_ERROR ) {
194 err = SLAPD_DISCONNECT;
195 *text = "error decoding filter";
199 #ifdef SLAPD_SCHEMA_NOT_COMPAT
204 err = slap_bv2ad( &type, &f->f_desc, &text );
206 if( err != LDAP_SUCCESS ) {
207 ch_free( type.bv_val );
211 ch_free( type.bv_val );
214 *fstr = ch_malloc( sizeof("(=*)")
215 + f->f_desc->ad_cname->bv_len );
216 sprintf( *fstr, "(%s=*)",
217 f->f_desc->ad_cname->bv_val );
219 f->f_type = type.bv_val;
221 attr_normalize( f->f_type );
222 *fstr = ch_malloc( sizeof("(=*)")
223 + strlen( f->f_type ) );
224 sprintf( *fstr, "(%s=*)", f->f_type );
228 case LDAP_FILTER_APPROX:
229 Debug( LDAP_DEBUG_FILTER, "APPROX\n", 0, 0, 0 );
230 #ifdef SLAPD_SCHEMA_NOT_COMPAT
231 if ( (err = get_ava( ber, &f->f_ava )) != LDAP_SUCCESS ) {
232 *text = "decoding filter error";
236 *fstr = ch_malloc( sizeof("(~=)")
237 + f->f_av_desc->ad_cname->bv_len
238 + f->f_av_value->bv_len );
240 sprintf( *fstr, "(%s~=%s)",
241 f->f_av_desc->ad_cname->bv_val,
242 f->f_av_value->bv_val );
245 if ( (err = get_ava( ber, f->f_ava )) != LDAP_SUCCESS ) {
246 *text = "error decoding filter";
249 *fstr = ch_malloc( sizeof("(~=)"
250 + strlen( f->f_avtype )
251 + f->f_avvalue.bv_len);
252 sprintf( *fstr, "(%s~=%s)", f->f_avtype,
253 f->f_avvalue.bv_val );
257 case LDAP_FILTER_AND:
258 Debug( LDAP_DEBUG_FILTER, "AND\n", 0, 0, 0 );
259 err = get_filter_list( conn, ber, &f->f_and, &ftmp, text );
260 if ( err != LDAP_SUCCESS ) {
263 if (ftmp == NULL) ftmp = ch_strdup("");
264 *fstr = ch_malloc( 4 + strlen( ftmp ) );
265 sprintf( *fstr, "(&%s)", ftmp );
270 Debug( LDAP_DEBUG_FILTER, "OR\n", 0, 0, 0 );
271 err = get_filter_list( conn, ber, &f->f_and, &ftmp, text );
272 if ( err != LDAP_SUCCESS ) {
275 if (ftmp == NULL) ftmp = ch_strdup("");
276 *fstr = ch_malloc( 4 + strlen( ftmp ) );
277 sprintf( *fstr, "(|%s)", ftmp );
281 case LDAP_FILTER_NOT:
282 Debug( LDAP_DEBUG_FILTER, "NOT\n", 0, 0, 0 );
283 (void) ber_skip_tag( ber, &len );
284 err = get_filter( conn, ber, &f->f_not, &ftmp, text );
285 if ( err != LDAP_SUCCESS ) {
288 if (ftmp == NULL) ftmp = ch_strdup("");
289 *fstr = ch_malloc( 4 + strlen( ftmp ) );
290 sprintf( *fstr, "(!%s)", ftmp );
294 case LDAP_FILTER_EXT:
295 /* not yet implemented */
296 Debug( LDAP_DEBUG_ANY, "extensible match not yet implemented.\n",
298 err = LDAP_PROTOCOL_ERROR;
299 *text = "extensible match not yet implemented";
303 Debug( LDAP_DEBUG_ANY, "get_filter: unknown filter type=%lu\n",
305 err = LDAP_PROTOCOL_ERROR;
306 *text = "unknown filter type";
310 if ( err != LDAP_SUCCESS ) {
312 if ( *fstr != NULL ) {
319 Debug( LDAP_DEBUG_FILTER, "end get_filter %d\n", err, 0, 0 );
324 get_filter_list( Connection *conn, BerElement *ber, Filter **f, char **fstr, char **text )
332 Debug( LDAP_DEBUG_FILTER, "begin get_filter_list\n", 0, 0, 0 );
336 for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT;
337 tag = ber_next_element( ber, &len, last ) )
339 err = get_filter( conn, ber, new, &ftmp, text );
340 if ( err != LDAP_SUCCESS )
343 if ( *fstr == NULL ) {
346 *fstr = ch_realloc( *fstr, strlen( *fstr ) +
347 strlen( ftmp ) + 1 );
348 strcat( *fstr, ftmp );
351 new = &(*new)->f_next;
355 Debug( LDAP_DEBUG_FILTER, "end get_filter_list\n", 0, 0, 0 );
356 return( LDAP_SUCCESS );
360 get_substring_filter(
376 *text = "error decoding filter";
378 Debug( LDAP_DEBUG_FILTER, "begin get_substring_filter\n", 0, 0, 0 );
380 if ( ber_scanf( ber, "{a" /*}*/, &type ) == LBER_ERROR ) {
381 return SLAPD_DISCONNECT;
384 #ifdef SLAPD_SCHEMA_NOT_COMPAT
385 /* not yet implemented */
387 f->f_sub_type = type;
388 attr_normalize( f->f_sub_type );
390 /* should get real syntax and see if we have a substring matching rule */
391 syntax = attr_syntax( f->f_sub_type );
394 f->f_sub_initial = NULL;
396 f->f_sub_final = NULL;
398 #ifdef SLAPD_SCHEMA_NOT_COMPAT
399 /* not yet implemented */
402 *fstr = ch_malloc( strlen( f->f_sub_type ) + 3 );
403 sprintf( *fstr, "(%s=" /*)*/, f->f_sub_type );
407 for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT;
408 tag = ber_next_element( ber, &len, last ) )
410 rc = ber_scanf( ber, "O", &val );
411 if ( rc == LBER_ERROR ) {
412 rc = SLAPD_DISCONNECT;
416 if ( val == NULL || val->bv_len == 0 ) {
418 rc = LDAP_INVALID_SYNTAX;
422 rc = LDAP_PROTOCOL_ERROR;
424 #ifdef SLAPD_SCHEMA_NOT_COMPAT
425 /* not yet implemented */
427 /* we should call a substring syntax normalization routine */
428 value_normalize( val->bv_val, syntax );
429 /* this is bogus, value_normalize should take a berval */
430 val->bv_len = strlen( val->bv_val );
434 case LDAP_SUBSTRING_INITIAL:
435 Debug( LDAP_DEBUG_FILTER, " INITIAL\n", 0, 0, 0 );
436 if ( f->f_sub_initial != NULL ) {
440 f->f_sub_initial = val;
443 *fstr = ch_realloc( *fstr,
444 strlen( *fstr ) + val->bv_len + 1 );
445 strcat( *fstr, val->bv_val );
449 case LDAP_SUBSTRING_ANY:
450 Debug( LDAP_DEBUG_FILTER, " ANY\n", 0, 0, 0 );
451 if( ber_bvecadd( &f->f_sub_any, val ) < 0 ) {
457 *fstr = ch_realloc( *fstr,
458 strlen( *fstr ) + val->bv_len + 2 );
459 strcat( *fstr, "*" );
460 strcat( *fstr, val->bv_val );
464 case LDAP_SUBSTRING_FINAL:
465 Debug( LDAP_DEBUG_FILTER, " FINAL\n", 0, 0, 0 );
466 if ( f->f_sub_final != NULL ) {
470 f->f_sub_final = val;
473 *fstr = ch_realloc( *fstr,
474 strlen( *fstr ) + val->bv_len + 2 );
475 strcat( *fstr, "*" );
476 strcat( *fstr, val->bv_val );
481 Debug( LDAP_DEBUG_FILTER,
482 " unknown substring type=%ld\n",
488 Debug( LDAP_DEBUG_FILTER, " error=%ld\n",
496 #ifdef SLAPD_SCHEMA_NOT_COMPAT
497 /* not yet implemented */
499 ch_free( f->f_sub_type );
501 ber_bvfree( f->f_sub_initial );
502 ber_bvecfree( f->f_sub_any );
503 ber_bvfree( f->f_sub_final );
509 *fstr = ch_realloc( *fstr, strlen( *fstr ) + 3 );
510 if ( f->f_sub_final == NULL ) {
511 strcat( *fstr, "*" );
513 strcat( *fstr, /*(*/ ")" );
516 Debug( LDAP_DEBUG_FILTER, "end get_substring_filter\n", 0, 0, 0 );
517 return( LDAP_SUCCESS );
521 filter_free( Filter *f )
529 switch ( f->f_choice ) {
530 case LDAP_FILTER_PRESENT:
531 #ifdef SLAPD_SCHEMA_NOT_COMPAT
532 ad_free( f->f_desc, 1 );
534 if ( f->f_type != NULL ) {
540 case LDAP_FILTER_EQUALITY:
543 case LDAP_FILTER_APPROX:
544 #ifdef SLAPD_SCHEMA_NOT_COMPAT
545 ava_free( f->f_ava, 1 );
547 ava_free( &f->f_ava, 0 );
551 case LDAP_FILTER_SUBSTRINGS:
552 #ifdef SLAPD_SCHEMA_NOT_COMPAT
553 ad_free( f->f_sub_desc, 1 );
554 if ( f->f_sub_initial != NULL ) {
555 ber_bvfree( f->f_sub_initial );
557 ber_bvecfree( f->f_sub_any );
558 if ( f->f_sub_final != NULL ) {
559 ber_bvfree( f->f_sub_final );
562 if ( f->f_sub_type != NULL ) {
563 free( f->f_sub_type );
565 if ( f->f_sub_initial != NULL ) {
566 ber_bvfree( f->f_sub_initial );
568 ber_bvecfree( f->f_sub_any );
569 if ( f->f_sub_final != NULL ) {
570 ber_bvfree( f->f_sub_final );
575 case LDAP_FILTER_AND:
577 case LDAP_FILTER_NOT:
578 for ( p = f->f_list; p != NULL; p = next ) {
584 case SLAPD_FILTER_COMPUTED:
588 Debug( LDAP_DEBUG_ANY, "filter_free: unknown filter type=%lu\n",
599 filter_print( Filter *f )
605 fprintf( stderr, "No filter!" );
608 switch ( f->f_choice ) {
609 case LDAP_FILTER_EQUALITY:
610 #ifdef SLAPD_SCHEMA_NOT_COMPAT
611 fprintf( stderr, "(%s=%s)",
612 f->f_av_desc->ad_cname->bv_val,
613 f->f_av_value->bv_val );
615 fprintf( stderr, "(%s=%s)", f->f_ava.ava_type,
616 f->f_ava.ava_value.bv_val );
621 #ifdef SLAPD_SCHEMA_NOT_COMPAT
622 fprintf( stderr, "(%s>=%s)",
623 f->f_av_desc->ad_cname->bv_val,
624 f->f_av_value->bv_val );
626 fprintf( stderr, "(%s>=%s)", f->f_ava.ava_type,
627 f->f_ava.ava_value.bv_val );
632 #ifdef SLAPD_SCHEMA_NOT_COMPAT
633 fprintf( stderr, "(%s<=%s)",
634 f->f_ava->aa_desc->ad_cname->bv_val,
635 f->f_ava->aa_value->bv_val );
637 fprintf( stderr, "(%s<=%s)", f->f_ava.ava_type,
638 f->f_ava.ava_value.bv_val );
642 case LDAP_FILTER_APPROX:
643 #ifdef SLAPD_SCHEMA_NOT_COMPAT
644 fprintf( stderr, "(%s~=%s)",
645 f->f_ava->aa_desc->ad_cname->bv_val,
646 f->f_ava->aa_value->bv_val );
648 fprintf( stderr, "(%s~=%s)", f->f_ava.ava_type,
649 f->f_ava.ava_value.bv_val );
653 case LDAP_FILTER_SUBSTRINGS:
654 #ifdef SLAPD_SCHEMA_NOT_COMPAT
655 fprintf( stderr, "(%s=" /*)*/,
656 f->f_sub_desc->ad_cname->bv_val );
658 fprintf( stderr, "(%s=" /*)*/, f->f_sub_type );
660 if ( f->f_sub_initial != NULL ) {
661 fprintf( stderr, "%s", f->f_sub_initial->bv_val );
663 if ( f->f_sub_any != NULL ) {
664 for ( i = 0; f->f_sub_any[i] != NULL; i++ ) {
665 fprintf( stderr, "*%s", f->f_sub_any[i]->bv_val );
668 if ( f->f_sub_final != NULL ) {
669 fprintf( stderr, "*%s", f->f_sub_final->bv_val );
671 fprintf( stderr, /*(*/ ")" );
674 case LDAP_FILTER_PRESENT:
675 #ifdef SLAPD_SCHEMA_NOT_COMPAT
676 fprintf( stderr, "(%s=*)",
677 f->f_desc->ad_cname->bv_val );
679 fprintf( stderr, "(%s=*)", f->f_type );
683 case LDAP_FILTER_AND:
685 case LDAP_FILTER_NOT:
686 fprintf( stderr, "(%c" /*)*/,
687 f->f_choice == LDAP_FILTER_AND ? '&' :
688 f->f_choice == LDAP_FILTER_OR ? '|' : '!' );
689 for ( p = f->f_list; p != NULL; p = p->f_next ) {
692 fprintf( stderr, /*(*/ ")" );
695 case SLAPD_FILTER_COMPUTED:
696 fprintf( stderr, "(%s)",
697 f->f_result == LDAP_COMPARE_FALSE ? "false" :
698 f->f_result == LDAP_COMPARE_TRUE ? "true" :
699 f->f_result == SLAPD_COMPARE_UNDEFINED ? "undefined" :
704 fprintf( stderr, "(unknown filter %lu)", f->f_choice );
709 #endif /* ldap_debug */