1 /* filter.c - routines for parsing and dealing with filters */
12 static int get_filter_list();
13 static int get_substring_filter();
16 extern char *ch_malloc();
17 extern char *ch_realloc();
20 get_filter( Connection *conn, BerElement *ber, Filter **filt, char **fstr )
22 unsigned long tag, len;
27 Debug( LDAP_DEBUG_FILTER, "begin get_filter\n", 0, 0, 0 );
30 * A filter looks like this coming in:
32 * and [0] SET OF Filter,
33 * or [1] SET OF Filter,
35 * equalityMatch [3] AttributeValueAssertion,
36 * substrings [4] SubstringFilter,
37 * greaterOrEqual [5] AttributeValueAssertion,
38 * lessOrEqual [6] AttributeValueAssertion,
39 * present [7] AttributeType,,
40 * approxMatch [8] AttributeValueAssertion
43 * SubstringFilter ::= SEQUENCE {
45 * SEQUENCE OF CHOICE {
46 * initial [0] IA5String,
53 f = (Filter *) ch_malloc( sizeof(Filter) );
59 f->f_choice = ber_peek_tag( ber, &len );
61 if ( conn->c_version == 30 ) {
62 switch ( f->f_choice ) {
63 case LDAP_FILTER_EQUALITY:
66 case LDAP_FILTER_PRESENT:
67 case LDAP_FILTER_PRESENT_30:
68 case LDAP_FILTER_APPROX:
69 (void) ber_skip_tag( ber, &len );
70 if ( f->f_choice == LDAP_FILTER_PRESENT_30 ) {
71 f->f_choice = LDAP_FILTER_PRESENT;
79 switch ( f->f_choice ) {
80 case LDAP_FILTER_EQUALITY:
81 Debug( LDAP_DEBUG_FILTER, "EQUALITY\n", 0, 0, 0 );
82 if ( (err = get_ava( ber, &f->f_ava )) == 0 ) {
83 *fstr = ch_malloc(4 + strlen( f->f_avtype ) +
85 sprintf( *fstr, "(%s=%s)", f->f_avtype,
86 f->f_avvalue.bv_val );
90 case LDAP_FILTER_SUBSTRINGS:
91 Debug( LDAP_DEBUG_FILTER, "SUBSTRINGS\n", 0, 0, 0 );
92 err = get_substring_filter( conn, ber, f, fstr );
96 Debug( LDAP_DEBUG_FILTER, "GE\n", 0, 0, 0 );
97 if ( (err = get_ava( ber, &f->f_ava )) == 0 ) {
98 *fstr = ch_malloc(5 + strlen( f->f_avtype ) +
100 sprintf( *fstr, "(%s>=%s)", f->f_avtype,
101 f->f_avvalue.bv_val );
106 Debug( LDAP_DEBUG_FILTER, "LE\n", 0, 0, 0 );
107 if ( (err = get_ava( ber, &f->f_ava )) == 0 ) {
108 *fstr = ch_malloc(5 + strlen( f->f_avtype ) +
109 f->f_avvalue.bv_len);
110 sprintf( *fstr, "(%s<=%s)", f->f_avtype,
111 f->f_avvalue.bv_val );
115 case LDAP_FILTER_PRESENT:
116 Debug( LDAP_DEBUG_FILTER, "PRESENT\n", 0, 0, 0 );
117 if ( ber_scanf( ber, "a", &f->f_type ) == LBER_ERROR ) {
118 err = LDAP_PROTOCOL_ERROR;
121 attr_normalize( f->f_type );
122 *fstr = ch_malloc( 5 + strlen( f->f_type ) );
123 sprintf( *fstr, "(%s=*)", f->f_type );
127 case LDAP_FILTER_APPROX:
128 Debug( LDAP_DEBUG_FILTER, "APPROX\n", 0, 0, 0 );
129 if ( (err = get_ava( ber, &f->f_ava )) == 0 ) {
130 *fstr = ch_malloc(5 + strlen( f->f_avtype ) +
131 f->f_avvalue.bv_len);
132 sprintf( *fstr, "(%s~=%s)", f->f_avtype,
133 f->f_avvalue.bv_val );
137 case LDAP_FILTER_AND:
138 Debug( LDAP_DEBUG_FILTER, "AND\n", 0, 0, 0 );
139 if ( (err = get_filter_list( conn, ber, &f->f_and, &ftmp ))
141 if (ftmp == NULL) ftmp = strdup("");
142 *fstr = ch_malloc( 4 + strlen( ftmp ) );
143 sprintf( *fstr, "(&%s)", ftmp );
149 Debug( LDAP_DEBUG_FILTER, "OR\n", 0, 0, 0 );
150 if ( (err = get_filter_list( conn, ber, &f->f_or, &ftmp ))
152 if (ftmp == NULL) ftmp = strdup("");
153 *fstr = ch_malloc( 4 + strlen( ftmp ) );
154 sprintf( *fstr, "(|%s)", ftmp );
159 case LDAP_FILTER_NOT:
160 Debug( LDAP_DEBUG_FILTER, "NOT\n", 0, 0, 0 );
161 (void) ber_skip_tag( ber, &len );
162 if ( (err = get_filter( conn, ber, &f->f_not, &ftmp )) == 0 ) {
163 if (ftmp == NULL) ftmp = strdup("");
164 *fstr = ch_malloc( 4 + strlen( ftmp ) );
165 sprintf( *fstr, "(!%s)", ftmp );
171 Debug( LDAP_DEBUG_ANY, "unknown filter type %d\n", f->f_choice,
173 err = LDAP_PROTOCOL_ERROR;
179 if ( *fstr != NULL ) {
184 Debug( LDAP_DEBUG_FILTER, "end get_filter %d\n", err, 0, 0 );
189 get_filter_list( Connection *conn, BerElement *ber, Filter **f, char **fstr )
193 unsigned long tag, len;
196 Debug( LDAP_DEBUG_FILTER, "begin get_filter_list\n", 0, 0, 0 );
199 if ( conn->c_version == 30 ) {
200 (void) ber_skip_tag( ber, &len );
205 for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT;
206 tag = ber_next_element( ber, &len, last ) ) {
207 if ( (err = get_filter( conn, ber, new, &ftmp )) != 0 )
209 if ( *fstr == NULL ) {
212 *fstr = ch_realloc( *fstr, strlen( *fstr ) +
213 strlen( ftmp ) + 1 );
214 strcat( *fstr, ftmp );
217 new = &(*new)->f_next;
221 Debug( LDAP_DEBUG_FILTER, "end get_filter_list\n", 0, 0, 0 );
226 get_substring_filter(
233 unsigned long tag, len, rc;
237 Debug( LDAP_DEBUG_FILTER, "begin get_substring_filter\n", 0, 0, 0 );
240 if ( conn->c_version == 30 ) {
241 (void) ber_skip_tag( ber, &len );
244 if ( ber_scanf( ber, "{a", &f->f_sub_type ) == LBER_ERROR ) {
245 return( LDAP_PROTOCOL_ERROR );
247 attr_normalize( f->f_sub_type );
248 syntax = attr_syntax( f->f_sub_type );
249 f->f_sub_initial = NULL;
251 f->f_sub_final = NULL;
253 *fstr = ch_malloc( strlen( f->f_sub_type ) + 3 );
254 sprintf( *fstr, "(%s=", f->f_sub_type );
255 for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT;
256 tag = ber_next_element( ber, &len, last ) ) {
258 if ( conn->c_version == 30 ) {
259 rc = ber_scanf( ber, "{a}", &val );
262 rc = ber_scanf( ber, "a", &val );
263 if ( rc == LBER_ERROR ) {
264 return( LDAP_PROTOCOL_ERROR );
266 if ( val == NULL || *val == '\0' ) {
270 return( LDAP_INVALID_SYNTAX );
272 value_normalize( val, syntax );
276 case LDAP_SUBSTRING_INITIAL_30:
278 case LDAP_SUBSTRING_INITIAL:
279 Debug( LDAP_DEBUG_FILTER, " INITIAL\n", 0, 0, 0 );
280 if ( f->f_sub_initial != NULL ) {
281 return( LDAP_PROTOCOL_ERROR );
283 f->f_sub_initial = val;
284 *fstr = ch_realloc( *fstr, strlen( *fstr ) +
286 strcat( *fstr, val );
290 case LDAP_SUBSTRING_ANY_30:
292 case LDAP_SUBSTRING_ANY:
293 Debug( LDAP_DEBUG_FILTER, " ANY\n", 0, 0, 0 );
294 charray_add( &f->f_sub_any, val );
295 *fstr = ch_realloc( *fstr, strlen( *fstr ) +
297 strcat( *fstr, "*" );
298 strcat( *fstr, val );
302 case LDAP_SUBSTRING_FINAL_30:
304 case LDAP_SUBSTRING_FINAL:
305 Debug( LDAP_DEBUG_FILTER, " FINAL\n", 0, 0, 0 );
306 if ( f->f_sub_final != NULL ) {
307 return( LDAP_PROTOCOL_ERROR );
309 f->f_sub_final = val;
310 *fstr = ch_realloc( *fstr, strlen( *fstr ) +
312 strcat( *fstr, "*" );
313 strcat( *fstr, val );
317 Debug( LDAP_DEBUG_FILTER, " unknown type\n", tag, 0,
319 return( LDAP_PROTOCOL_ERROR );
322 *fstr = ch_realloc( *fstr, strlen( *fstr ) + 3 );
323 if ( f->f_sub_final == NULL ) {
324 strcat( *fstr, "*" );
326 strcat( *fstr, ")" );
328 Debug( LDAP_DEBUG_FILTER, "end get_substring_filter\n", 0, 0, 0 );
333 filter_free( Filter *f )
341 switch ( f->f_choice ) {
342 case LDAP_FILTER_EQUALITY:
345 case LDAP_FILTER_APPROX:
346 ava_free( &f->f_ava, 0 );
349 case LDAP_FILTER_SUBSTRINGS:
350 if ( f->f_sub_type != NULL ) {
351 free( f->f_sub_type );
353 if ( f->f_sub_initial != NULL ) {
354 free( f->f_sub_initial );
356 charray_free( f->f_sub_any );
357 if ( f->f_sub_final != NULL ) {
358 free( f->f_sub_final );
362 case LDAP_FILTER_PRESENT:
363 if ( f->f_type != NULL ) {
368 case LDAP_FILTER_AND:
370 case LDAP_FILTER_NOT:
371 for ( p = f->f_list; p != NULL; p = next ) {
378 Debug( LDAP_DEBUG_ANY, "unknown filter type %d\n", f->f_choice,
388 filter_print( Filter *f )
397 switch ( f->f_choice ) {
398 case LDAP_FILTER_EQUALITY:
399 printf( "(%s=%s)", f->f_ava.ava_type,
400 f->f_ava.ava_value.bv_val );
404 printf( "(%s>=%s)", f->f_ava.ava_type,
405 f->f_ava.ava_value.bv_val );
409 printf( "(%s<=%s)", f->f_ava.ava_type,
410 f->f_ava.ava_value.bv_val );
413 case LDAP_FILTER_APPROX:
414 printf( "(%s~=%s)", f->f_ava.ava_type,
415 f->f_ava.ava_value.bv_val );
418 case LDAP_FILTER_SUBSTRINGS:
419 printf( "(%s=", f->f_sub_type );
420 if ( f->f_sub_initial != NULL ) {
421 printf( "%s", f->f_sub_initial );
423 if ( f->f_sub_any != NULL ) {
424 for ( i = 0; f->f_sub_any[i] != NULL; i++ ) {
425 printf( "*%s", f->f_sub_any[i] );
428 charray_free( f->f_sub_any );
429 if ( f->f_sub_final != NULL ) {
430 printf( "*%s", f->f_sub_final );
434 case LDAP_FILTER_PRESENT:
435 printf( "%s=*", f->f_type );
438 case LDAP_FILTER_AND:
440 case LDAP_FILTER_NOT:
441 printf( "(%c", f->f_choice == LDAP_FILTER_AND ? '&' :
442 f->f_choice == LDAP_FILTER_OR ? '|' : '!' );
443 for ( p = f->f_list; p != NULL; p = p->f_next ) {
450 printf( "unknown type %d", f->f_choice );
455 #endif /* ldap_debug */