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(
235 Debug( LDAP_DEBUG_FILTER, "begin get_substring_filter\n", 0, 0, 0 );
237 if ( ber_scanf( ber, "{a" /*}*/, &f->f_sub_type ) == LBER_ERROR ) {
240 attr_normalize( f->f_sub_type );
241 syntax = attr_syntax( f->f_sub_type );
242 f->f_sub_initial = NULL;
244 f->f_sub_final = NULL;
246 *fstr = ch_malloc( strlen( f->f_sub_type ) + 3 );
247 sprintf( *fstr, "(%s=", f->f_sub_type );
248 for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT;
249 tag = ber_next_element( ber, &len, last ) )
251 rc = ber_scanf( ber, "a", &val );
252 if ( rc == LBER_ERROR ) {
255 if ( val == NULL || *val == '\0' ) {
259 return( LDAP_INVALID_SYNTAX );
261 value_normalize( val, syntax );
264 case LDAP_SUBSTRING_INITIAL:
265 Debug( LDAP_DEBUG_FILTER, " INITIAL\n", 0, 0, 0 );
266 if ( f->f_sub_initial != NULL ) {
267 return( LDAP_PROTOCOL_ERROR );
269 f->f_sub_initial = val;
270 *fstr = ch_realloc( *fstr, strlen( *fstr ) +
272 strcat( *fstr, val );
275 case LDAP_SUBSTRING_ANY:
276 Debug( LDAP_DEBUG_FILTER, " ANY\n", 0, 0, 0 );
277 charray_add( &f->f_sub_any, val );
278 *fstr = ch_realloc( *fstr, strlen( *fstr ) +
280 strcat( *fstr, "*" );
281 strcat( *fstr, val );
284 case LDAP_SUBSTRING_FINAL:
285 Debug( LDAP_DEBUG_FILTER, " FINAL\n", 0, 0, 0 );
286 if ( f->f_sub_final != NULL ) {
287 return( LDAP_PROTOCOL_ERROR );
289 f->f_sub_final = val;
290 *fstr = ch_realloc( *fstr, strlen( *fstr ) +
292 strcat( *fstr, "*" );
293 strcat( *fstr, val );
297 Debug( LDAP_DEBUG_FILTER, " unknown type\n", tag, 0,
299 return( LDAP_PROTOCOL_ERROR );
302 *fstr = ch_realloc( *fstr, strlen( *fstr ) + 3 );
303 if ( f->f_sub_final == NULL ) {
304 strcat( *fstr, "*" );
306 strcat( *fstr, ")" );
308 Debug( LDAP_DEBUG_FILTER, "end get_substring_filter\n", 0, 0, 0 );
309 return( LDAP_SUCCESS );
313 filter_free( Filter *f )
321 switch ( f->f_choice ) {
322 case LDAP_FILTER_EQUALITY:
325 case LDAP_FILTER_APPROX:
326 ava_free( &f->f_ava, 0 );
329 case LDAP_FILTER_SUBSTRINGS:
330 if ( f->f_sub_type != NULL ) {
331 free( f->f_sub_type );
333 if ( f->f_sub_initial != NULL ) {
334 free( f->f_sub_initial );
336 charray_free( f->f_sub_any );
337 if ( f->f_sub_final != NULL ) {
338 free( f->f_sub_final );
342 case LDAP_FILTER_PRESENT:
343 if ( f->f_type != NULL ) {
348 case LDAP_FILTER_AND:
350 case LDAP_FILTER_NOT:
351 for ( p = f->f_list; p != NULL; p = next ) {
358 Debug( LDAP_DEBUG_ANY, "unknown filter type %lu\n",
368 filter_print( Filter *f )
374 fprintf( stderr, "NULL" );
377 switch ( f->f_choice ) {
378 case LDAP_FILTER_EQUALITY:
379 fprintf( stderr, "(%s=%s)", f->f_ava.ava_type,
380 f->f_ava.ava_value.bv_val );
384 fprintf( stderr, "(%s>=%s)", f->f_ava.ava_type,
385 f->f_ava.ava_value.bv_val );
389 fprintf( stderr, "(%s<=%s)", f->f_ava.ava_type,
390 f->f_ava.ava_value.bv_val );
393 case LDAP_FILTER_APPROX:
394 fprintf( stderr, "(%s~=%s)", f->f_ava.ava_type,
395 f->f_ava.ava_value.bv_val );
398 case LDAP_FILTER_SUBSTRINGS:
399 fprintf( stderr, "(%s=", f->f_sub_type );
400 if ( f->f_sub_initial != NULL ) {
401 fprintf( stderr, "%s", f->f_sub_initial );
403 if ( f->f_sub_any != NULL ) {
404 for ( i = 0; f->f_sub_any[i] != NULL; i++ ) {
405 fprintf( stderr, "*%s", f->f_sub_any[i] );
408 charray_free( f->f_sub_any );
409 if ( f->f_sub_final != NULL ) {
410 fprintf( stderr, "*%s", f->f_sub_final );
414 case LDAP_FILTER_PRESENT:
415 fprintf( stderr, "%s=*", f->f_type );
418 case LDAP_FILTER_AND:
420 case LDAP_FILTER_NOT:
421 fprintf( stderr, "(%c", f->f_choice == LDAP_FILTER_AND ? '&' :
422 f->f_choice == LDAP_FILTER_OR ? '|' : '!' );
423 for ( p = f->f_list; p != NULL; p = p->f_next ) {
426 fprintf( stderr, ")" );
430 fprintf( stderr, "unknown type %lu", f->f_choice );
435 #endif /* ldap_debug */