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 )
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) );
54 f->f_choice = ber_peek_tag( ber, &len );
56 switch ( f->f_choice ) {
57 case LDAP_FILTER_EQUALITY:
58 Debug( LDAP_DEBUG_FILTER, "EQUALITY\n", 0, 0, 0 );
59 if ( (err = get_ava( ber, &f->f_ava )) == 0 ) {
60 *fstr = ch_malloc(4 + strlen( f->f_avtype ) +
62 sprintf( *fstr, "(%s=%s)", f->f_avtype,
63 f->f_avvalue.bv_val );
67 case LDAP_FILTER_SUBSTRINGS:
68 Debug( LDAP_DEBUG_FILTER, "SUBSTRINGS\n", 0, 0, 0 );
69 err = get_substring_filter( conn, ber, f, fstr );
73 Debug( LDAP_DEBUG_FILTER, "GE\n", 0, 0, 0 );
74 if ( (err = get_ava( ber, &f->f_ava )) == 0 ) {
75 *fstr = ch_malloc(5 + strlen( f->f_avtype ) +
77 sprintf( *fstr, "(%s>=%s)", f->f_avtype,
78 f->f_avvalue.bv_val );
83 Debug( LDAP_DEBUG_FILTER, "LE\n", 0, 0, 0 );
84 if ( (err = get_ava( ber, &f->f_ava )) == 0 ) {
85 *fstr = ch_malloc(5 + strlen( f->f_avtype ) +
87 sprintf( *fstr, "(%s<=%s)", f->f_avtype,
88 f->f_avvalue.bv_val );
92 case LDAP_FILTER_PRESENT:
93 Debug( LDAP_DEBUG_FILTER, "PRESENT\n", 0, 0, 0 );
94 if ( ber_scanf( ber, "a", &f->f_type ) == LBER_ERROR ) {
95 err = LDAP_PROTOCOL_ERROR;
98 attr_normalize( f->f_type );
99 *fstr = ch_malloc( 5 + strlen( f->f_type ) );
100 sprintf( *fstr, "(%s=*)", f->f_type );
104 case LDAP_FILTER_APPROX:
105 Debug( LDAP_DEBUG_FILTER, "APPROX\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_AND:
115 Debug( LDAP_DEBUG_FILTER, "AND\n", 0, 0, 0 );
116 if ( (err = get_filter_list( conn, ber, &f->f_and, &ftmp ))
118 if (ftmp == NULL) ftmp = ch_strdup("");
119 *fstr = ch_malloc( 4 + strlen( ftmp ) );
120 sprintf( *fstr, "(&%s)", ftmp );
126 Debug( LDAP_DEBUG_FILTER, "OR\n", 0, 0, 0 );
127 if ( (err = get_filter_list( conn, ber, &f->f_or, &ftmp ))
129 if (ftmp == NULL) ftmp = ch_strdup("");
130 *fstr = ch_malloc( 4 + strlen( ftmp ) );
131 sprintf( *fstr, "(|%s)", ftmp );
136 case LDAP_FILTER_NOT:
137 Debug( LDAP_DEBUG_FILTER, "NOT\n", 0, 0, 0 );
138 (void) ber_skip_tag( ber, &len );
139 if ( (err = get_filter( conn, ber, &f->f_not, &ftmp )) == 0 ) {
140 if (ftmp == NULL) ftmp = ch_strdup("");
141 *fstr = ch_malloc( 4 + strlen( ftmp ) );
142 sprintf( *fstr, "(!%s)", ftmp );
148 Debug( LDAP_DEBUG_ANY, "unknown filter type %lu\n",
150 err = LDAP_PROTOCOL_ERROR;
156 if ( *fstr != NULL ) {
163 Debug( LDAP_DEBUG_FILTER, "end get_filter %d\n", err, 0, 0 );
168 get_filter_list( Connection *conn, BerElement *ber, Filter **f, char **fstr )
176 Debug( LDAP_DEBUG_FILTER, "begin get_filter_list\n", 0, 0, 0 );
180 for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT;
181 tag = ber_next_element( ber, &len, last ) ) {
182 if ( (err = get_filter( conn, ber, new, &ftmp )) != 0 )
184 if ( *fstr == NULL ) {
187 *fstr = ch_realloc( *fstr, strlen( *fstr ) +
188 strlen( ftmp ) + 1 );
189 strcat( *fstr, ftmp );
192 new = &(*new)->f_next;
196 Debug( LDAP_DEBUG_FILTER, "end get_filter_list\n", 0, 0, 0 );
201 get_substring_filter(
214 Debug( LDAP_DEBUG_FILTER, "begin get_substring_filter\n", 0, 0, 0 );
216 if ( ber_scanf( ber, "{a" /*}*/, &f->f_sub_type ) == LBER_ERROR ) {
217 return( LDAP_PROTOCOL_ERROR );
219 attr_normalize( f->f_sub_type );
220 syntax = attr_syntax( f->f_sub_type );
221 f->f_sub_initial = NULL;
223 f->f_sub_final = NULL;
225 *fstr = ch_malloc( strlen( f->f_sub_type ) + 3 );
226 sprintf( *fstr, "(%s=", f->f_sub_type );
227 for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT;
228 tag = ber_next_element( ber, &len, last ) ) {
229 rc = ber_scanf( ber, "a", &val );
230 if ( rc == LBER_ERROR ) {
231 return( LDAP_PROTOCOL_ERROR );
233 if ( val == NULL || *val == '\0' ) {
237 return( LDAP_INVALID_SYNTAX );
239 value_normalize( val, syntax );
242 case LDAP_SUBSTRING_INITIAL:
243 Debug( LDAP_DEBUG_FILTER, " INITIAL\n", 0, 0, 0 );
244 if ( f->f_sub_initial != NULL ) {
245 return( LDAP_PROTOCOL_ERROR );
247 f->f_sub_initial = val;
248 *fstr = ch_realloc( *fstr, strlen( *fstr ) +
250 strcat( *fstr, val );
253 case LDAP_SUBSTRING_ANY:
254 Debug( LDAP_DEBUG_FILTER, " ANY\n", 0, 0, 0 );
255 charray_add( &f->f_sub_any, val );
256 *fstr = ch_realloc( *fstr, strlen( *fstr ) +
258 strcat( *fstr, "*" );
259 strcat( *fstr, val );
262 case LDAP_SUBSTRING_FINAL:
263 Debug( LDAP_DEBUG_FILTER, " FINAL\n", 0, 0, 0 );
264 if ( f->f_sub_final != NULL ) {
265 return( LDAP_PROTOCOL_ERROR );
267 f->f_sub_final = val;
268 *fstr = ch_realloc( *fstr, strlen( *fstr ) +
270 strcat( *fstr, "*" );
271 strcat( *fstr, val );
275 Debug( LDAP_DEBUG_FILTER, " unknown type\n", tag, 0,
277 return( LDAP_PROTOCOL_ERROR );
280 *fstr = ch_realloc( *fstr, strlen( *fstr ) + 3 );
281 if ( f->f_sub_final == NULL ) {
282 strcat( *fstr, "*" );
284 strcat( *fstr, ")" );
286 Debug( LDAP_DEBUG_FILTER, "end get_substring_filter\n", 0, 0, 0 );
291 filter_free( Filter *f )
299 switch ( f->f_choice ) {
300 case LDAP_FILTER_EQUALITY:
303 case LDAP_FILTER_APPROX:
304 ava_free( &f->f_ava, 0 );
307 case LDAP_FILTER_SUBSTRINGS:
308 if ( f->f_sub_type != NULL ) {
309 free( f->f_sub_type );
311 if ( f->f_sub_initial != NULL ) {
312 free( f->f_sub_initial );
314 charray_free( f->f_sub_any );
315 if ( f->f_sub_final != NULL ) {
316 free( f->f_sub_final );
320 case LDAP_FILTER_PRESENT:
321 if ( f->f_type != NULL ) {
326 case LDAP_FILTER_AND:
328 case LDAP_FILTER_NOT:
329 for ( p = f->f_list; p != NULL; p = next ) {
336 Debug( LDAP_DEBUG_ANY, "unknown filter type %lu\n",
346 filter_print( Filter *f )
352 fprintf( stderr, "NULL" );
355 switch ( f->f_choice ) {
356 case LDAP_FILTER_EQUALITY:
357 fprintf( stderr, "(%s=%s)", f->f_ava.ava_type,
358 f->f_ava.ava_value.bv_val );
362 fprintf( stderr, "(%s>=%s)", f->f_ava.ava_type,
363 f->f_ava.ava_value.bv_val );
367 fprintf( stderr, "(%s<=%s)", f->f_ava.ava_type,
368 f->f_ava.ava_value.bv_val );
371 case LDAP_FILTER_APPROX:
372 fprintf( stderr, "(%s~=%s)", f->f_ava.ava_type,
373 f->f_ava.ava_value.bv_val );
376 case LDAP_FILTER_SUBSTRINGS:
377 fprintf( stderr, "(%s=", f->f_sub_type );
378 if ( f->f_sub_initial != NULL ) {
379 fprintf( stderr, "%s", f->f_sub_initial );
381 if ( f->f_sub_any != NULL ) {
382 for ( i = 0; f->f_sub_any[i] != NULL; i++ ) {
383 fprintf( stderr, "*%s", f->f_sub_any[i] );
386 charray_free( f->f_sub_any );
387 if ( f->f_sub_final != NULL ) {
388 fprintf( stderr, "*%s", f->f_sub_final );
392 case LDAP_FILTER_PRESENT:
393 fprintf( stderr, "%s=*", f->f_type );
396 case LDAP_FILTER_AND:
398 case LDAP_FILTER_NOT:
399 fprintf( stderr, "(%c", f->f_choice == LDAP_FILTER_AND ? '&' :
400 f->f_choice == LDAP_FILTER_OR ? '|' : '!' );
401 for ( p = f->f_list; p != NULL; p = p->f_next ) {
404 fprintf( stderr, ")" );
408 fprintf( stderr, "unknown type %lu", f->f_choice );
413 #endif /* ldap_debug */