1 /* filter.c - routines for parsing and dealing with filters */
4 * Copyright 1998-1999 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(Connection *conn, BerElement *ber, Filter **f, char **fstr);
18 static int get_substring_filter(Connection *conn, BerElement *ber, Filter *f, char **fstr);
21 get_filter( Connection *conn, BerElement *ber, Filter **filt, char **fstr )
28 Debug( LDAP_DEBUG_FILTER, "begin get_filter\n", 0, 0, 0 );
31 * A filter looks like this coming in:
33 * and [0] SET OF Filter,
34 * or [1] SET OF Filter,
36 * equalityMatch [3] AttributeValueAssertion,
37 * substrings [4] SubstringFilter,
38 * greaterOrEqual [5] AttributeValueAssertion,
39 * lessOrEqual [6] AttributeValueAssertion,
40 * present [7] AttributeType,,
41 * approxMatch [8] AttributeValueAssertion
42 * extensibleMatch [9] MatchingRuleAssertion
45 * SubstringFilter ::= SEQUENCE {
47 * SEQUENCE OF CHOICE {
48 * initial [0] IA5String,
54 * MatchingRuleAssertion ::= SEQUENCE {
55 * matchingRule [1] MatchingRuleId OPTIONAL,
56 * type [2] AttributeDescription OPTIONAL,
57 * matchValue [3] AssertionValue,
58 * dnAttributes [4] BOOLEAN DEFAULT FALSE
63 f = (Filter *) ch_malloc( sizeof(Filter) );
68 f->f_choice = ber_peek_tag( ber, &len );
70 switch ( f->f_choice ) {
71 #ifndef SLAPD_SCHEMA_NOT_COMPAT
72 case LDAP_FILTER_EQUALITY:
73 Debug( LDAP_DEBUG_FILTER, "EQUALITY\n", 0, 0, 0 );
74 if ( (err = get_ava( ber, &f->f_ava )) == LDAP_SUCCESS ) {
75 *fstr = ch_malloc(4 + strlen( f->f_avtype ) +
77 sprintf( *fstr, "(%s=%s)", f->f_avtype,
78 f->f_avvalue.bv_val );
82 case LDAP_FILTER_SUBSTRINGS:
83 Debug( LDAP_DEBUG_FILTER, "SUBSTRINGS\n", 0, 0, 0 );
84 err = get_substring_filter( conn, ber, f, fstr );
88 Debug( LDAP_DEBUG_FILTER, "GE\n", 0, 0, 0 );
89 if ( (err = get_ava( ber, &f->f_ava )) == LDAP_SUCCESS ) {
90 *fstr = ch_malloc(5 + strlen( f->f_avtype ) +
92 sprintf( *fstr, "(%s>=%s)", f->f_avtype,
93 f->f_avvalue.bv_val );
98 Debug( LDAP_DEBUG_FILTER, "LE\n", 0, 0, 0 );
99 if ( (err = get_ava( ber, &f->f_ava )) == LDAP_SUCCESS ) {
100 *fstr = ch_malloc(5 + strlen( f->f_avtype ) +
101 f->f_avvalue.bv_len);
102 sprintf( *fstr, "(%s<=%s)", f->f_avtype,
103 f->f_avvalue.bv_val );
107 case LDAP_FILTER_PRESENT:
108 Debug( LDAP_DEBUG_FILTER, "PRESENT\n", 0, 0, 0 );
109 if ( ber_scanf( ber, "a", &f->f_type ) == LBER_ERROR ) {
113 attr_normalize( f->f_type );
114 *fstr = ch_malloc( 5 + strlen( f->f_type ) );
115 sprintf( *fstr, "(%s=*)", f->f_type );
119 case LDAP_FILTER_APPROX:
120 Debug( LDAP_DEBUG_FILTER, "APPROX\n", 0, 0, 0 );
121 if ( (err = get_ava( ber, &f->f_ava )) == LDAP_SUCCESS ) {
122 *fstr = ch_malloc(5 + strlen( f->f_avtype ) +
123 f->f_avvalue.bv_len);
124 sprintf( *fstr, "(%s~=%s)", f->f_avtype,
125 f->f_avvalue.bv_val );
130 case LDAP_FILTER_AND:
131 Debug( LDAP_DEBUG_FILTER, "AND\n", 0, 0, 0 );
132 if ( (err = get_filter_list( conn, ber, &f->f_and, &ftmp ))
134 if (ftmp == NULL) ftmp = ch_strdup("");
135 *fstr = ch_malloc( 4 + strlen( ftmp ) );
136 sprintf( *fstr, "(&%s)", ftmp );
142 Debug( LDAP_DEBUG_FILTER, "OR\n", 0, 0, 0 );
143 if ( (err = get_filter_list( conn, ber, &f->f_or, &ftmp ))
145 if (ftmp == NULL) ftmp = ch_strdup("");
146 *fstr = ch_malloc( 4 + strlen( ftmp ) );
147 sprintf( *fstr, "(|%s)", ftmp );
152 case LDAP_FILTER_NOT:
153 Debug( LDAP_DEBUG_FILTER, "NOT\n", 0, 0, 0 );
154 (void) ber_skip_tag( ber, &len );
155 if ( (err = get_filter( conn, ber, &f->f_not, &ftmp )) == LDAP_SUCCESS ) {
156 if (ftmp == NULL) ftmp = ch_strdup("");
157 *fstr = ch_malloc( 4 + strlen( ftmp ) );
158 sprintf( *fstr, "(!%s)", ftmp );
163 case LDAP_FILTER_EXT:
164 /* not yet implemented */
165 Debug( LDAP_DEBUG_ANY, "extensible match not yet implemented.\n",
171 Debug( LDAP_DEBUG_ANY, "decoding filter error\n",
177 Debug( LDAP_DEBUG_ANY, "unknown filter type %lu\n",
179 err = LDAP_PROTOCOL_ERROR;
183 if ( err != LDAP_SUCCESS ) {
185 if ( *fstr != NULL ) {
192 Debug( LDAP_DEBUG_FILTER, "end get_filter %d\n", err, 0, 0 );
197 get_filter_list( Connection *conn, BerElement *ber, Filter **f, char **fstr )
205 Debug( LDAP_DEBUG_FILTER, "begin get_filter_list\n", 0, 0, 0 );
209 for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT;
210 tag = ber_next_element( ber, &len, last ) )
212 if ( (err = get_filter( conn, ber, new, &ftmp )) != LDAP_SUCCESS )
214 if ( *fstr == NULL ) {
217 *fstr = ch_realloc( *fstr, strlen( *fstr ) +
218 strlen( ftmp ) + 1 );
219 strcat( *fstr, ftmp );
222 new = &(*new)->f_next;
226 Debug( LDAP_DEBUG_FILTER, "end get_filter_list\n", 0, 0, 0 );
227 return( LDAP_SUCCESS );
230 #ifndef SLAPD_SCHEMA_NOT_COMPAT
233 get_substring_filter(
247 Debug( LDAP_DEBUG_FILTER, "begin get_substring_filter\n", 0, 0, 0 );
249 if ( ber_scanf( ber, "{a" /*}*/, &f->f_sub_type ) == LBER_ERROR ) {
253 attr_normalize( f->f_sub_type );
255 #ifdef SLAPD_SCHEMA_NOT_COMPAT
256 /* not yet implemented */
258 /* should get real syntax and see if we have a substring matching rule */
259 syntax = attr_syntax( f->f_sub_type );
262 f->f_sub_initial = NULL;
264 f->f_sub_final = NULL;
267 *fstr = ch_malloc( strlen( f->f_sub_type ) + 3 );
268 sprintf( *fstr, "(%s=", f->f_sub_type );
271 for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT;
272 tag = ber_next_element( ber, &len, last ) )
274 rc = ber_scanf( ber, "O", &val );
275 if ( rc == LBER_ERROR ) {
280 if ( val == NULL || val->bv_len == 0 ) {
282 rc = LDAP_INVALID_SYNTAX;
286 rc = LDAP_PROTOCOL_ERROR;
288 #ifdef SLAPD_SCHEMA_NOT_COMPAT
289 /* not yet implemented */
291 /* we should call a substring syntax normalization routine */
292 value_normalize( val->bv_val, syntax );
293 /* this is bogus, value_normalize should take a berval */
294 val->bv_len = strlen( val->bv_val );
298 case LDAP_SUBSTRING_INITIAL:
299 Debug( LDAP_DEBUG_FILTER, " INITIAL\n", 0, 0, 0 );
300 if ( f->f_sub_initial != NULL ) {
304 f->f_sub_initial = val;
307 *fstr = ch_realloc( *fstr,
308 strlen( *fstr ) + val->bv_len + 1 );
309 strcat( *fstr, val->bv_val );
313 case LDAP_SUBSTRING_ANY:
314 Debug( LDAP_DEBUG_FILTER, " ANY\n", 0, 0, 0 );
315 if( ber_bvecadd( &f->f_sub_any, val ) < 0 ) {
321 *fstr = ch_realloc( *fstr,
322 strlen( *fstr ) + val->bv_len + 2 );
323 strcat( *fstr, "*" );
324 strcat( *fstr, val->bv_val );
328 case LDAP_SUBSTRING_FINAL:
329 Debug( LDAP_DEBUG_FILTER, " FINAL\n", 0, 0, 0 );
330 if ( f->f_sub_final != NULL ) {
334 f->f_sub_final = val;
337 *fstr = ch_realloc( *fstr,
338 strlen( *fstr ) + val->bv_len + 2 );
339 strcat( *fstr, "*" );
340 strcat( *fstr, val->bv_val );
345 Debug( LDAP_DEBUG_FILTER, " unknown type\n", tag, 0,
351 Debug( LDAP_DEBUG_FILTER, " error=%d\n", rc, 0, 0 );
358 ch_free( f->f_sub_type );
359 ber_bvfree( f->f_sub_initial );
360 ber_bvecfree( f->f_sub_any );
361 ber_bvfree( f->f_sub_final );
367 *fstr = ch_realloc( *fstr, strlen( *fstr ) + 3 );
368 if ( f->f_sub_final == NULL ) {
369 strcat( *fstr, "*" );
371 strcat( *fstr, ")" );
374 Debug( LDAP_DEBUG_FILTER, "end get_substring_filter\n", 0, 0, 0 );
375 return( LDAP_SUCCESS );
378 #endif /* not compat */
381 filter_free( Filter *f )
389 switch ( f->f_choice ) {
390 case LDAP_FILTER_PRESENT:
391 #ifdef SLAPD_SCHEMA_NOT_COMPAT
392 ad_free( f->f_desc, 1 );
394 if ( f->f_type != NULL ) {
400 case LDAP_FILTER_EQUALITY:
403 case LDAP_FILTER_APPROX:
404 #ifdef SLAPD_SCHEMA_NOT_COMPAT
405 ava_free( f->f_ava, 1 );
407 ava_free( &f->f_ava, 0 );
411 case LDAP_FILTER_SUBSTRINGS:
412 #ifdef SLAPD_SCHEMA_NOT_COMPAT
413 ad_free( f->f_sub_desc, 1 );
414 if ( f->f_sub_initial != NULL ) {
415 ber_bvfree( f->f_sub_initial );
417 ber_bvecfree( f->f_sub_any );
418 if ( f->f_sub_final != NULL ) {
419 ber_bvfree( f->f_sub_final );
422 if ( f->f_sub_type != NULL ) {
423 free( f->f_sub_type );
425 if ( f->f_sub_initial != NULL ) {
426 ber_bvfree( f->f_sub_initial );
428 ber_bvecfree( f->f_sub_any );
429 if ( f->f_sub_final != NULL ) {
430 ber_bvfree( f->f_sub_final );
435 case LDAP_FILTER_AND:
437 case LDAP_FILTER_NOT:
438 for ( p = f->f_list; p != NULL; p = next ) {
445 Debug( LDAP_DEBUG_ANY, "unknown filter type %lu\n",
456 filter_print( Filter *f )
462 fprintf( stderr, "NULL" );
465 switch ( f->f_choice ) {
466 case LDAP_FILTER_EQUALITY:
467 #ifdef SLAPD_SCHEMA_NOT_COMPAT
468 fprintf( stderr, "(%s=%s)",
469 f->f_ava->aa_desc->ad_cname,
470 f->f_ava->aa_value->bv_val );
472 fprintf( stderr, "(%s=%s)", f->f_ava.ava_type,
473 f->f_ava.ava_value.bv_val );
478 #ifdef SLAPD_SCHEMA_NOT_COMPAT
479 fprintf( stderr, "(%s>=%s)",
480 f->f_ava->aa_desc->ad_cname,
481 f->f_ava->aa_value->bv_val );
483 fprintf( stderr, "(%s>=%s)", f->f_ava.ava_type,
484 f->f_ava.ava_value.bv_val );
489 #ifdef SLAPD_SCHEMA_NOT_COMPAT
490 fprintf( stderr, "(%s<=%s)",
491 f->f_ava->aa_desc->ad_cname,
492 f->f_ava->aa_value->bv_val );
494 fprintf( stderr, "(%s<=%s)", f->f_ava.ava_type,
495 f->f_ava.ava_value.bv_val );
499 case LDAP_FILTER_APPROX:
500 #ifdef SLAPD_SCHEMA_NOT_COMPAT
501 fprintf( stderr, "(%s~=%s)",
502 f->f_ava->aa_desc->ad_cname,
503 f->f_ava->aa_value->bv_val );
505 fprintf( stderr, "(%s~=%s)", f->f_ava.ava_type,
506 f->f_ava.ava_value.bv_val );
510 case LDAP_FILTER_SUBSTRINGS:
511 #ifdef SLAPD_SCHEMA_NOT_COMPAT
512 fprintf( stderr, "(%s=" /*)*/, f->f_sub_desc->ad_cname );
514 fprintf( stderr, "(%s=" /*)*/, f->f_sub_type );
516 if ( f->f_sub_initial != NULL ) {
517 fprintf( stderr, "%s", f->f_sub_initial->bv_val );
519 if ( f->f_sub_any != NULL ) {
520 for ( i = 0; f->f_sub_any[i] != NULL; i++ ) {
521 fprintf( stderr, "*%s", f->f_sub_any[i]->bv_val );
524 if ( f->f_sub_final != NULL ) {
525 fprintf( stderr, "*%s", f->f_sub_final->bv_val );
527 fprintf( stderr, /*(*/ ")" );
530 case LDAP_FILTER_PRESENT:
531 #ifdef SLAPD_SCHEMA_NOT_COMPAT
532 fprintf( stderr, "(%s=*)",
533 f->f_desc->ad_cname );
535 fprintf( stderr, "%s=*", f->f_type );
539 case LDAP_FILTER_AND:
541 case LDAP_FILTER_NOT:
542 fprintf( stderr, "(%c" /*)*/,
543 f->f_choice == LDAP_FILTER_AND ? '&' :
544 f->f_choice == LDAP_FILTER_OR ? '|' : '!' );
545 for ( p = f->f_list; p != NULL; p = p->f_next ) {
548 fprintf( stderr, /*(*/ ")" );
552 fprintf( stderr, "(unknown filter %lu)", f->f_choice );
557 #endif /* ldap_debug */