1 /* filter.c - routines for parsing and dealing with filters */
12 static int get_filter_list(Connection *conn, BerElement *ber, Filter **f, char **fstr);
13 static int get_substring_filter(Connection *conn, BerElement *ber, Filter *f, char **fstr);
16 get_filter( Connection *conn, BerElement *ber, Filter **filt, char **fstr )
18 unsigned long tag, len;
23 Debug( LDAP_DEBUG_FILTER, "begin get_filter\n", 0, 0, 0 );
26 * A filter looks like this coming in:
28 * and [0] SET OF Filter,
29 * or [1] SET OF Filter,
31 * equalityMatch [3] AttributeValueAssertion,
32 * substrings [4] SubstringFilter,
33 * greaterOrEqual [5] AttributeValueAssertion,
34 * lessOrEqual [6] AttributeValueAssertion,
35 * present [7] AttributeType,,
36 * approxMatch [8] AttributeValueAssertion
39 * SubstringFilter ::= SEQUENCE {
41 * SEQUENCE OF CHOICE {
42 * initial [0] IA5String,
49 f = (Filter *) ch_malloc( sizeof(Filter) );
55 f->f_choice = ber_peek_tag( ber, &len );
57 if ( conn->c_version == 30 ) {
58 switch ( f->f_choice ) {
59 case LDAP_FILTER_EQUALITY:
62 case LDAP_FILTER_PRESENT:
63 case LDAP_FILTER_PRESENT_30:
64 case LDAP_FILTER_APPROX:
65 (void) ber_skip_tag( ber, &len );
66 if ( f->f_choice == LDAP_FILTER_PRESENT_30 ) {
67 f->f_choice = LDAP_FILTER_PRESENT;
75 switch ( f->f_choice ) {
76 case LDAP_FILTER_EQUALITY:
77 Debug( LDAP_DEBUG_FILTER, "EQUALITY\n", 0, 0, 0 );
78 if ( (err = get_ava( ber, &f->f_ava )) == 0 ) {
79 *fstr = ch_malloc(4 + strlen( f->f_avtype ) +
81 sprintf( *fstr, "(%s=%s)", f->f_avtype,
82 f->f_avvalue.bv_val );
86 case LDAP_FILTER_SUBSTRINGS:
87 Debug( LDAP_DEBUG_FILTER, "SUBSTRINGS\n", 0, 0, 0 );
88 err = get_substring_filter( conn, ber, f, fstr );
92 Debug( LDAP_DEBUG_FILTER, "GE\n", 0, 0, 0 );
93 if ( (err = get_ava( ber, &f->f_ava )) == 0 ) {
94 *fstr = ch_malloc(5 + strlen( f->f_avtype ) +
96 sprintf( *fstr, "(%s>=%s)", f->f_avtype,
97 f->f_avvalue.bv_val );
102 Debug( LDAP_DEBUG_FILTER, "LE\n", 0, 0, 0 );
103 if ( (err = get_ava( ber, &f->f_ava )) == 0 ) {
104 *fstr = ch_malloc(5 + strlen( f->f_avtype ) +
105 f->f_avvalue.bv_len);
106 sprintf( *fstr, "(%s<=%s)", f->f_avtype,
107 f->f_avvalue.bv_val );
111 case LDAP_FILTER_PRESENT:
112 Debug( LDAP_DEBUG_FILTER, "PRESENT\n", 0, 0, 0 );
113 if ( ber_scanf( ber, "a", &f->f_type ) == LBER_ERROR ) {
114 err = LDAP_PROTOCOL_ERROR;
117 attr_normalize( f->f_type );
118 *fstr = ch_malloc( 5 + strlen( f->f_type ) );
119 sprintf( *fstr, "(%s=*)", f->f_type );
123 case LDAP_FILTER_APPROX:
124 Debug( LDAP_DEBUG_FILTER, "APPROX\n", 0, 0, 0 );
125 if ( (err = get_ava( ber, &f->f_ava )) == 0 ) {
126 *fstr = ch_malloc(5 + strlen( f->f_avtype ) +
127 f->f_avvalue.bv_len);
128 sprintf( *fstr, "(%s~=%s)", f->f_avtype,
129 f->f_avvalue.bv_val );
133 case LDAP_FILTER_AND:
134 Debug( LDAP_DEBUG_FILTER, "AND\n", 0, 0, 0 );
135 if ( (err = get_filter_list( conn, ber, &f->f_and, &ftmp ))
137 if (ftmp == NULL) ftmp = ch_strdup("");
138 *fstr = ch_malloc( 4 + strlen( ftmp ) );
139 sprintf( *fstr, "(&%s)", ftmp );
145 Debug( LDAP_DEBUG_FILTER, "OR\n", 0, 0, 0 );
146 if ( (err = get_filter_list( conn, ber, &f->f_or, &ftmp ))
148 if (ftmp == NULL) ftmp = ch_strdup("");
149 *fstr = ch_malloc( 4 + strlen( ftmp ) );
150 sprintf( *fstr, "(|%s)", ftmp );
155 case LDAP_FILTER_NOT:
156 Debug( LDAP_DEBUG_FILTER, "NOT\n", 0, 0, 0 );
157 (void) ber_skip_tag( ber, &len );
158 if ( (err = get_filter( conn, ber, &f->f_not, &ftmp )) == 0 ) {
159 if (ftmp == NULL) ftmp = ch_strdup("");
160 *fstr = ch_malloc( 4 + strlen( ftmp ) );
161 sprintf( *fstr, "(!%s)", ftmp );
167 Debug( LDAP_DEBUG_ANY, "unknown filter type %lu\n",
169 err = LDAP_PROTOCOL_ERROR;
175 if ( *fstr != NULL ) {
180 Debug( LDAP_DEBUG_FILTER, "end get_filter %d\n", err, 0, 0 );
185 get_filter_list( Connection *conn, BerElement *ber, Filter **f, char **fstr )
189 unsigned long tag, len;
192 Debug( LDAP_DEBUG_FILTER, "begin get_filter_list\n", 0, 0, 0 );
195 if ( conn->c_version == 30 ) {
196 (void) ber_skip_tag( ber, &len );
201 for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT;
202 tag = ber_next_element( ber, &len, last ) ) {
203 if ( (err = get_filter( conn, ber, new, &ftmp )) != 0 )
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 );
222 get_substring_filter(
229 unsigned long tag, len, rc;
233 Debug( LDAP_DEBUG_FILTER, "begin get_substring_filter\n", 0, 0, 0 );
236 if ( conn->c_version == 30 ) {
237 (void) ber_skip_tag( ber, &len );
240 if ( ber_scanf( ber, "{a", &f->f_sub_type ) == LBER_ERROR ) {
241 return( LDAP_PROTOCOL_ERROR );
243 attr_normalize( f->f_sub_type );
244 syntax = attr_syntax( f->f_sub_type );
245 f->f_sub_initial = NULL;
247 f->f_sub_final = NULL;
249 *fstr = ch_malloc( strlen( f->f_sub_type ) + 3 );
250 sprintf( *fstr, "(%s=", f->f_sub_type );
251 for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT;
252 tag = ber_next_element( ber, &len, last ) ) {
254 if ( conn->c_version == 30 ) {
255 rc = ber_scanf( ber, "{a}", &val );
258 rc = ber_scanf( ber, "a", &val );
259 if ( rc == LBER_ERROR ) {
260 return( LDAP_PROTOCOL_ERROR );
262 if ( val == NULL || *val == '\0' ) {
266 return( LDAP_INVALID_SYNTAX );
268 value_normalize( val, syntax );
272 case LDAP_SUBSTRING_INITIAL_30:
274 case LDAP_SUBSTRING_INITIAL:
275 Debug( LDAP_DEBUG_FILTER, " INITIAL\n", 0, 0, 0 );
276 if ( f->f_sub_initial != NULL ) {
277 return( LDAP_PROTOCOL_ERROR );
279 f->f_sub_initial = val;
280 *fstr = ch_realloc( *fstr, strlen( *fstr ) +
282 strcat( *fstr, val );
286 case LDAP_SUBSTRING_ANY_30:
288 case LDAP_SUBSTRING_ANY:
289 Debug( LDAP_DEBUG_FILTER, " ANY\n", 0, 0, 0 );
290 charray_add( &f->f_sub_any, val );
291 *fstr = ch_realloc( *fstr, strlen( *fstr ) +
293 strcat( *fstr, "*" );
294 strcat( *fstr, val );
298 case LDAP_SUBSTRING_FINAL_30:
300 case LDAP_SUBSTRING_FINAL:
301 Debug( LDAP_DEBUG_FILTER, " FINAL\n", 0, 0, 0 );
302 if ( f->f_sub_final != NULL ) {
303 return( LDAP_PROTOCOL_ERROR );
305 f->f_sub_final = val;
306 *fstr = ch_realloc( *fstr, strlen( *fstr ) +
308 strcat( *fstr, "*" );
309 strcat( *fstr, val );
313 Debug( LDAP_DEBUG_FILTER, " unknown type\n", tag, 0,
315 return( LDAP_PROTOCOL_ERROR );
318 *fstr = ch_realloc( *fstr, strlen( *fstr ) + 3 );
319 if ( f->f_sub_final == NULL ) {
320 strcat( *fstr, "*" );
322 strcat( *fstr, ")" );
324 Debug( LDAP_DEBUG_FILTER, "end get_substring_filter\n", 0, 0, 0 );
329 filter_free( Filter *f )
337 switch ( f->f_choice ) {
338 case LDAP_FILTER_EQUALITY:
341 case LDAP_FILTER_APPROX:
342 ava_free( &f->f_ava, 0 );
345 case LDAP_FILTER_SUBSTRINGS:
346 if ( f->f_sub_type != NULL ) {
347 free( f->f_sub_type );
349 if ( f->f_sub_initial != NULL ) {
350 free( f->f_sub_initial );
352 charray_free( f->f_sub_any );
353 if ( f->f_sub_final != NULL ) {
354 free( f->f_sub_final );
358 case LDAP_FILTER_PRESENT:
359 if ( f->f_type != NULL ) {
364 case LDAP_FILTER_AND:
366 case LDAP_FILTER_NOT:
367 for ( p = f->f_list; p != NULL; p = next ) {
374 Debug( LDAP_DEBUG_ANY, "unknown filter type %lu\n",
384 filter_print( Filter *f )
390 fprintf( stderr, "NULL" );
393 switch ( f->f_choice ) {
394 case LDAP_FILTER_EQUALITY:
395 fprintf( stderr, "(%s=%s)", f->f_ava.ava_type,
396 f->f_ava.ava_value.bv_val );
400 fprintf( stderr, "(%s>=%s)", f->f_ava.ava_type,
401 f->f_ava.ava_value.bv_val );
405 fprintf( stderr, "(%s<=%s)", f->f_ava.ava_type,
406 f->f_ava.ava_value.bv_val );
409 case LDAP_FILTER_APPROX:
410 fprintf( stderr, "(%s~=%s)", f->f_ava.ava_type,
411 f->f_ava.ava_value.bv_val );
414 case LDAP_FILTER_SUBSTRINGS:
415 fprintf( stderr, "(%s=", f->f_sub_type );
416 if ( f->f_sub_initial != NULL ) {
417 fprintf( stderr, "%s", f->f_sub_initial );
419 if ( f->f_sub_any != NULL ) {
420 for ( i = 0; f->f_sub_any[i] != NULL; i++ ) {
421 fprintf( stderr, "*%s", f->f_sub_any[i] );
424 charray_free( f->f_sub_any );
425 if ( f->f_sub_final != NULL ) {
426 fprintf( stderr, "*%s", f->f_sub_final );
430 case LDAP_FILTER_PRESENT:
431 fprintf( stderr, "%s=*", f->f_type );
434 case LDAP_FILTER_AND:
436 case LDAP_FILTER_NOT:
437 fprintf( stderr, "(%c", f->f_choice == LDAP_FILTER_AND ? '&' :
438 f->f_choice == LDAP_FILTER_OR ? '|' : '!' );
439 for ( p = f->f_list; p != NULL; p = p->f_next ) {
442 fprintf( stderr, ")" );
446 fprintf( stderr, "unknown type %lu", f->f_choice );
451 #endif /* ldap_debug */