1 /* filter.c - routines for parsing and dealing with filters */
8 #include <sys/socket.h>
11 static int get_filter_list();
12 static int get_substring_filter();
15 extern char *ch_malloc();
16 extern char *ch_realloc();
19 get_filter( Connection *conn, BerElement *ber, Filter **filt, char **fstr )
21 unsigned long tag, len;
26 Debug( LDAP_DEBUG_FILTER, "begin get_filter\n", 0, 0, 0 );
29 * A filter looks like this coming in:
31 * and [0] SET OF Filter,
32 * or [1] SET OF Filter,
34 * equalityMatch [3] AttributeValueAssertion,
35 * substrings [4] SubstringFilter,
36 * greaterOrEqual [5] AttributeValueAssertion,
37 * lessOrEqual [6] AttributeValueAssertion,
38 * present [7] AttributeType,,
39 * approxMatch [8] AttributeValueAssertion
42 * SubstringFilter ::= SEQUENCE {
44 * SEQUENCE OF CHOICE {
45 * initial [0] IA5String,
52 f = (Filter *) ch_malloc( sizeof(Filter) );
58 f->f_choice = ber_peek_tag( ber, &len );
60 if ( conn->c_version == 30 ) {
61 switch ( f->f_choice ) {
62 case LDAP_FILTER_EQUALITY:
65 case LDAP_FILTER_PRESENT:
66 case LDAP_FILTER_PRESENT_30:
67 case LDAP_FILTER_APPROX:
68 (void) ber_skip_tag( ber, &len );
69 if ( f->f_choice == LDAP_FILTER_PRESENT_30 ) {
70 f->f_choice = LDAP_FILTER_PRESENT;
78 switch ( f->f_choice ) {
79 case LDAP_FILTER_EQUALITY:
80 Debug( LDAP_DEBUG_FILTER, "EQUALITY\n", 0, 0, 0 );
81 if ( (err = get_ava( ber, &f->f_ava )) == 0 ) {
82 *fstr = ch_malloc(4 + strlen( f->f_avtype ) +
84 sprintf( *fstr, "(%s=%s)", f->f_avtype,
85 f->f_avvalue.bv_val );
89 case LDAP_FILTER_SUBSTRINGS:
90 Debug( LDAP_DEBUG_FILTER, "SUBSTRINGS\n", 0, 0, 0 );
91 err = get_substring_filter( conn, ber, f, fstr );
95 Debug( LDAP_DEBUG_FILTER, "GE\n", 0, 0, 0 );
96 if ( (err = get_ava( ber, &f->f_ava )) == 0 ) {
97 *fstr = ch_malloc(5 + strlen( f->f_avtype ) +
99 sprintf( *fstr, "(%s>=%s)", f->f_avtype,
100 f->f_avvalue.bv_val );
105 Debug( LDAP_DEBUG_FILTER, "LE\n", 0, 0, 0 );
106 if ( (err = get_ava( ber, &f->f_ava )) == 0 ) {
107 *fstr = ch_malloc(5 + strlen( f->f_avtype ) +
108 f->f_avvalue.bv_len);
109 sprintf( *fstr, "(%s<=%s)", f->f_avtype,
110 f->f_avvalue.bv_val );
114 case LDAP_FILTER_PRESENT:
115 Debug( LDAP_DEBUG_FILTER, "PRESENT\n", 0, 0, 0 );
116 if ( ber_scanf( ber, "a", &f->f_type ) == LBER_ERROR ) {
117 err = LDAP_PROTOCOL_ERROR;
120 attr_normalize( f->f_type );
121 *fstr = ch_malloc( 5 + strlen( f->f_type ) );
122 sprintf( *fstr, "(%s=*)", f->f_type );
126 case LDAP_FILTER_APPROX:
127 Debug( LDAP_DEBUG_FILTER, "APPROX\n", 0, 0, 0 );
128 if ( (err = get_ava( ber, &f->f_ava )) == 0 ) {
129 *fstr = ch_malloc(5 + strlen( f->f_avtype ) +
130 f->f_avvalue.bv_len);
131 sprintf( *fstr, "(%s~=%s)", f->f_avtype,
132 f->f_avvalue.bv_val );
136 case LDAP_FILTER_AND:
137 Debug( LDAP_DEBUG_FILTER, "AND\n", 0, 0, 0 );
138 if ( (err = get_filter_list( conn, ber, &f->f_and, &ftmp ))
140 if (ftmp == NULL) ftmp = strdup("");
141 *fstr = ch_malloc( 4 + strlen( ftmp ) );
142 sprintf( *fstr, "(&%s)", ftmp );
148 Debug( LDAP_DEBUG_FILTER, "OR\n", 0, 0, 0 );
149 if ( (err = get_filter_list( conn, ber, &f->f_or, &ftmp ))
151 if (ftmp == NULL) ftmp = strdup("");
152 *fstr = ch_malloc( 4 + strlen( ftmp ) );
153 sprintf( *fstr, "(|%s)", ftmp );
158 case LDAP_FILTER_NOT:
159 Debug( LDAP_DEBUG_FILTER, "NOT\n", 0, 0, 0 );
160 (void) ber_skip_tag( ber, &len );
161 if ( (err = get_filter( conn, ber, &f->f_not, &ftmp )) == 0 ) {
162 if (ftmp == NULL) ftmp = strdup("");
163 *fstr = ch_malloc( 4 + strlen( ftmp ) );
164 sprintf( *fstr, "(!%s)", ftmp );
170 Debug( LDAP_DEBUG_ANY, "unknown filter type %d\n", f->f_choice,
172 err = LDAP_PROTOCOL_ERROR;
178 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 )
192 unsigned long tag, len;
195 Debug( LDAP_DEBUG_FILTER, "begin get_filter_list\n", 0, 0, 0 );
198 if ( conn->c_version == 30 ) {
199 (void) ber_skip_tag( ber, &len );
204 for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT;
205 tag = ber_next_element( ber, &len, last ) ) {
206 if ( (err = get_filter( conn, ber, new, &ftmp )) != 0 )
208 if ( *fstr == NULL ) {
211 *fstr = ch_realloc( *fstr, strlen( *fstr ) +
212 strlen( ftmp ) + 1 );
213 strcat( *fstr, ftmp );
216 new = &(*new)->f_next;
220 Debug( LDAP_DEBUG_FILTER, "end get_filter_list\n", 0, 0, 0 );
225 get_substring_filter(
232 unsigned long tag, len, rc;
236 Debug( LDAP_DEBUG_FILTER, "begin get_substring_filter\n", 0, 0, 0 );
239 if ( conn->c_version == 30 ) {
240 (void) ber_skip_tag( ber, &len );
243 if ( ber_scanf( ber, "{a", &f->f_sub_type ) == LBER_ERROR ) {
244 return( LDAP_PROTOCOL_ERROR );
246 attr_normalize( f->f_sub_type );
247 syntax = attr_syntax( f->f_sub_type );
248 f->f_sub_initial = NULL;
250 f->f_sub_final = NULL;
252 *fstr = ch_malloc( strlen( f->f_sub_type ) + 3 );
253 sprintf( *fstr, "(%s=", f->f_sub_type );
254 for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT;
255 tag = ber_next_element( ber, &len, last ) ) {
257 if ( conn->c_version == 30 ) {
258 rc = ber_scanf( ber, "{a}", &val );
261 rc = ber_scanf( ber, "a", &val );
262 if ( rc == LBER_ERROR ) {
263 return( LDAP_PROTOCOL_ERROR );
265 if ( val == NULL || *val == '\0' ) {
269 return( LDAP_INVALID_SYNTAX );
271 value_normalize( val, syntax );
275 case LDAP_SUBSTRING_INITIAL_30:
277 case LDAP_SUBSTRING_INITIAL:
278 Debug( LDAP_DEBUG_FILTER, " INITIAL\n", 0, 0, 0 );
279 if ( f->f_sub_initial != NULL ) {
280 return( LDAP_PROTOCOL_ERROR );
282 f->f_sub_initial = val;
283 *fstr = ch_realloc( *fstr, strlen( *fstr ) +
285 strcat( *fstr, val );
289 case LDAP_SUBSTRING_ANY_30:
291 case LDAP_SUBSTRING_ANY:
292 Debug( LDAP_DEBUG_FILTER, " ANY\n", 0, 0, 0 );
293 charray_add( &f->f_sub_any, val );
294 *fstr = ch_realloc( *fstr, strlen( *fstr ) +
296 strcat( *fstr, "*" );
297 strcat( *fstr, val );
301 case LDAP_SUBSTRING_FINAL_30:
303 case LDAP_SUBSTRING_FINAL:
304 Debug( LDAP_DEBUG_FILTER, " FINAL\n", 0, 0, 0 );
305 if ( f->f_sub_final != NULL ) {
306 return( LDAP_PROTOCOL_ERROR );
308 f->f_sub_final = val;
309 *fstr = ch_realloc( *fstr, strlen( *fstr ) +
311 strcat( *fstr, "*" );
312 strcat( *fstr, val );
316 Debug( LDAP_DEBUG_FILTER, " unknown type\n", tag, 0,
318 return( LDAP_PROTOCOL_ERROR );
321 *fstr = ch_realloc( *fstr, strlen( *fstr ) + 3 );
322 if ( f->f_sub_final == NULL ) {
323 strcat( *fstr, "*" );
325 strcat( *fstr, ")" );
327 Debug( LDAP_DEBUG_FILTER, "end get_substring_filter\n", 0, 0, 0 );
332 filter_free( Filter *f )
340 switch ( f->f_choice ) {
341 case LDAP_FILTER_EQUALITY:
344 case LDAP_FILTER_APPROX:
345 ava_free( &f->f_ava, 0 );
348 case LDAP_FILTER_SUBSTRINGS:
349 if ( f->f_sub_type != NULL ) {
350 free( f->f_sub_type );
352 if ( f->f_sub_initial != NULL ) {
353 free( f->f_sub_initial );
355 charray_free( f->f_sub_any );
356 if ( f->f_sub_final != NULL ) {
357 free( f->f_sub_final );
361 case LDAP_FILTER_PRESENT:
362 if ( f->f_type != NULL ) {
367 case LDAP_FILTER_AND:
369 case LDAP_FILTER_NOT:
370 for ( p = f->f_list; p != NULL; p = next ) {
377 Debug( LDAP_DEBUG_ANY, "unknown filter type %d\n", f->f_choice,
387 filter_print( Filter *f )
396 switch ( f->f_choice ) {
397 case LDAP_FILTER_EQUALITY:
398 printf( "(%s=%s)", f->f_ava.ava_type,
399 f->f_ava.ava_value.bv_val );
403 printf( "(%s>=%s)", f->f_ava.ava_type,
404 f->f_ava.ava_value.bv_val );
408 printf( "(%s<=%s)", f->f_ava.ava_type,
409 f->f_ava.ava_value.bv_val );
412 case LDAP_FILTER_APPROX:
413 printf( "(%s~=%s)", f->f_ava.ava_type,
414 f->f_ava.ava_value.bv_val );
417 case LDAP_FILTER_SUBSTRINGS:
418 printf( "(%s=", f->f_sub_type );
419 if ( f->f_sub_initial != NULL ) {
420 printf( "%s", f->f_sub_initial );
422 if ( f->f_sub_any != NULL ) {
423 for ( i = 0; f->f_sub_any[i] != NULL; i++ ) {
424 printf( "*%s", f->f_sub_any[i] );
427 charray_free( f->f_sub_any );
428 if ( f->f_sub_final != NULL ) {
429 printf( "*%s", f->f_sub_final );
433 case LDAP_FILTER_PRESENT:
434 printf( "%s=*", f->f_type );
437 case LDAP_FILTER_AND:
439 case LDAP_FILTER_NOT:
440 printf( "(%c", f->f_choice == LDAP_FILTER_AND ? '&' :
441 f->f_choice == LDAP_FILTER_OR ? '|' : '!' );
442 for ( p = f->f_list; p != NULL; p = p->f_next ) {
449 printf( "unknown type %d", f->f_choice );
454 #endif /* ldap_debug */