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 case LDAP_FILTER_EQUALITY:
72 Debug( LDAP_DEBUG_FILTER, "EQUALITY\n", 0, 0, 0 );
73 if ( (err = get_ava( ber, &f->f_ava )) == LDAP_SUCCESS ) {
74 *fstr = ch_malloc(4 + strlen( f->f_avtype ) +
76 sprintf( *fstr, "(%s=%s)", f->f_avtype,
77 f->f_avvalue.bv_val );
81 case LDAP_FILTER_SUBSTRINGS:
82 Debug( LDAP_DEBUG_FILTER, "SUBSTRINGS\n", 0, 0, 0 );
83 err = get_substring_filter( conn, ber, f, fstr );
87 Debug( LDAP_DEBUG_FILTER, "GE\n", 0, 0, 0 );
88 if ( (err = get_ava( ber, &f->f_ava )) == LDAP_SUCCESS ) {
89 *fstr = ch_malloc(5 + strlen( f->f_avtype ) +
91 sprintf( *fstr, "(%s>=%s)", f->f_avtype,
92 f->f_avvalue.bv_val );
97 Debug( LDAP_DEBUG_FILTER, "LE\n", 0, 0, 0 );
98 if ( (err = get_ava( ber, &f->f_ava )) == LDAP_SUCCESS ) {
99 *fstr = ch_malloc(5 + strlen( f->f_avtype ) +
100 f->f_avvalue.bv_len);
101 sprintf( *fstr, "(%s<=%s)", f->f_avtype,
102 f->f_avvalue.bv_val );
106 case LDAP_FILTER_PRESENT:
107 Debug( LDAP_DEBUG_FILTER, "PRESENT\n", 0, 0, 0 );
108 if ( ber_scanf( ber, "a", &f->f_type ) == LBER_ERROR ) {
112 attr_normalize( f->f_type );
113 *fstr = ch_malloc( 5 + strlen( f->f_type ) );
114 sprintf( *fstr, "(%s=*)", f->f_type );
118 case LDAP_FILTER_APPROX:
119 Debug( LDAP_DEBUG_FILTER, "APPROX\n", 0, 0, 0 );
120 if ( (err = get_ava( ber, &f->f_ava )) == LDAP_SUCCESS ) {
121 *fstr = ch_malloc(5 + strlen( f->f_avtype ) +
122 f->f_avvalue.bv_len);
123 sprintf( *fstr, "(%s~=%s)", f->f_avtype,
124 f->f_avvalue.bv_val );
128 case LDAP_FILTER_AND:
129 Debug( LDAP_DEBUG_FILTER, "AND\n", 0, 0, 0 );
130 if ( (err = get_filter_list( conn, ber, &f->f_and, &ftmp ))
132 if (ftmp == NULL) ftmp = ch_strdup("");
133 *fstr = ch_malloc( 4 + strlen( ftmp ) );
134 sprintf( *fstr, "(&%s)", ftmp );
140 Debug( LDAP_DEBUG_FILTER, "OR\n", 0, 0, 0 );
141 if ( (err = get_filter_list( conn, ber, &f->f_or, &ftmp ))
143 if (ftmp == NULL) ftmp = ch_strdup("");
144 *fstr = ch_malloc( 4 + strlen( ftmp ) );
145 sprintf( *fstr, "(|%s)", ftmp );
150 case LDAP_FILTER_NOT:
151 Debug( LDAP_DEBUG_FILTER, "NOT\n", 0, 0, 0 );
152 (void) ber_skip_tag( ber, &len );
153 if ( (err = get_filter( conn, ber, &f->f_not, &ftmp )) == LDAP_SUCCESS ) {
154 if (ftmp == NULL) ftmp = ch_strdup("");
155 *fstr = ch_malloc( 4 + strlen( ftmp ) );
156 sprintf( *fstr, "(!%s)", ftmp );
162 Debug( LDAP_DEBUG_ANY, "decoding filter error\n",
168 Debug( LDAP_DEBUG_ANY, "unknown filter type %lu\n",
170 err = LDAP_PROTOCOL_ERROR;
174 if ( err != LDAP_SUCCESS ) {
176 if ( *fstr != NULL ) {
183 Debug( LDAP_DEBUG_FILTER, "end get_filter %d\n", err, 0, 0 );
188 get_filter_list( Connection *conn, BerElement *ber, Filter **f, char **fstr )
196 Debug( LDAP_DEBUG_FILTER, "begin get_filter_list\n", 0, 0, 0 );
200 for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT;
201 tag = ber_next_element( ber, &len, last ) )
203 if ( (err = get_filter( conn, ber, new, &ftmp )) != LDAP_SUCCESS )
205 if ( *fstr == NULL ) {
208 *fstr = ch_realloc( *fstr, strlen( *fstr ) +
209 strlen( ftmp ) + 1 );
210 strcat( *fstr, ftmp );
213 new = &(*new)->f_next;
217 Debug( LDAP_DEBUG_FILTER, "end get_filter_list\n", 0, 0, 0 );
218 return( LDAP_SUCCESS );
222 get_substring_filter(
236 Debug( LDAP_DEBUG_FILTER, "begin get_substring_filter\n", 0, 0, 0 );
238 if ( ber_scanf( ber, "{a" /*}*/, &f->f_sub_type ) == LBER_ERROR ) {
242 attr_normalize( f->f_sub_type );
244 /* should get real syntax and see if we have a substring matching rule */
245 syntax = attr_syntax( f->f_sub_type );
247 f->f_sub_initial = NULL;
249 f->f_sub_final = NULL;
252 *fstr = ch_malloc( strlen( f->f_sub_type ) + 3 );
253 sprintf( *fstr, "(%s=", f->f_sub_type );
256 for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT;
257 tag = ber_next_element( ber, &len, last ) )
259 rc = ber_scanf( ber, "O", &val );
260 if ( rc == LBER_ERROR ) {
263 if ( val == NULL || val->bv_len == 0 ) {
265 return( LDAP_INVALID_SYNTAX );
268 /* we should call a substring syntax normalization routine */
269 value_normalize( val->bv_val, syntax );
271 /* this is bogus, value_normalize should take a berval */
272 val->bv_len = strlen( val->bv_val );
275 case LDAP_SUBSTRING_INITIAL:
276 Debug( LDAP_DEBUG_FILTER, " INITIAL\n", 0, 0, 0 );
277 if ( f->f_sub_initial != NULL ) {
281 f->f_sub_initial = val;
284 *fstr = ch_realloc( *fstr,
285 strlen( *fstr ) + val->bv_len + 1 );
286 strcat( *fstr, val->bv_val );
290 case LDAP_SUBSTRING_ANY:
291 Debug( LDAP_DEBUG_FILTER, " ANY\n", 0, 0, 0 );
292 charray_add( (char ***) &f->f_sub_any, (char *) val );
295 *fstr = ch_realloc( *fstr,
296 strlen( *fstr ) + val->bv_len + 2 );
297 strcat( *fstr, "*" );
298 strcat( *fstr, val->bv_val );
302 case LDAP_SUBSTRING_FINAL:
303 Debug( LDAP_DEBUG_FILTER, " FINAL\n", 0, 0, 0 );
304 if ( f->f_sub_final != NULL ) {
308 f->f_sub_final = val;
311 *fstr = ch_realloc( *fstr,
312 strlen( *fstr ) + val->bv_len + 2 );
313 strcat( *fstr, "*" );
314 strcat( *fstr, val->bv_val );
319 Debug( LDAP_DEBUG_FILTER, " unknown type\n", tag, 0,
327 ch_free( f->f_sub_type );
328 ber_bvfree( f->f_sub_initial );
329 ber_bvecfree( f->f_sub_any );
330 ber_bvfree( f->f_sub_final );
331 return( LDAP_PROTOCOL_ERROR );
336 *fstr = ch_realloc( *fstr, strlen( *fstr ) + 3 );
337 if ( f->f_sub_final == NULL ) {
338 strcat( *fstr, "*" );
340 strcat( *fstr, ")" );
343 Debug( LDAP_DEBUG_FILTER, "end get_substring_filter\n", 0, 0, 0 );
344 return( LDAP_SUCCESS );
348 filter_free( Filter *f )
356 switch ( f->f_choice ) {
357 case LDAP_FILTER_EQUALITY:
360 case LDAP_FILTER_APPROX:
361 ava_free( &f->f_ava, 0 );
364 case LDAP_FILTER_SUBSTRINGS:
365 if ( f->f_sub_type != NULL ) {
366 free( f->f_sub_type );
368 if ( f->f_sub_initial != NULL ) {
369 ber_bvfree( f->f_sub_initial );
371 ber_bvecfree( f->f_sub_any );
372 if ( f->f_sub_final != NULL ) {
373 ber_bvfree( f->f_sub_final );
377 case LDAP_FILTER_PRESENT:
378 if ( f->f_type != NULL ) {
383 case LDAP_FILTER_AND:
385 case LDAP_FILTER_NOT:
386 for ( p = f->f_list; p != NULL; p = next ) {
393 Debug( LDAP_DEBUG_ANY, "unknown filter type %lu\n",
403 filter_print( Filter *f )
409 fprintf( stderr, "NULL" );
412 switch ( f->f_choice ) {
413 case LDAP_FILTER_EQUALITY:
414 fprintf( stderr, "(%s=%s)", f->f_ava.ava_type,
415 f->f_ava.ava_value.bv_val );
419 fprintf( stderr, "(%s>=%s)", f->f_ava.ava_type,
420 f->f_ava.ava_value.bv_val );
424 fprintf( stderr, "(%s<=%s)", f->f_ava.ava_type,
425 f->f_ava.ava_value.bv_val );
428 case LDAP_FILTER_APPROX:
429 fprintf( stderr, "(%s~=%s)", f->f_ava.ava_type,
430 f->f_ava.ava_value.bv_val );
433 case LDAP_FILTER_SUBSTRINGS:
434 fprintf( stderr, "(%s=", f->f_sub_type );
435 if ( f->f_sub_initial != NULL ) {
436 fprintf( stderr, "%s", f->f_sub_initial->bv_val );
438 if ( f->f_sub_any != NULL ) {
439 for ( i = 0; f->f_sub_any[i] != NULL; i++ ) {
440 fprintf( stderr, "*%s", f->f_sub_any[i]->bv_val );
443 if ( f->f_sub_final != NULL ) {
444 fprintf( stderr, "*%s", f->f_sub_final->bv_val );
448 case LDAP_FILTER_PRESENT:
449 fprintf( stderr, "%s=*", f->f_type );
452 case LDAP_FILTER_AND:
454 case LDAP_FILTER_NOT:
455 fprintf( stderr, "(%c", f->f_choice == LDAP_FILTER_AND ? '&' :
456 f->f_choice == LDAP_FILTER_OR ? '|' : '!' );
457 for ( p = f->f_list; p != NULL; p = p->f_next ) {
460 fprintf( stderr, ")" );
464 fprintf( stderr, "unknown type %lu", f->f_choice );
469 #endif /* ldap_debug */