]> git.sur5r.net Git - openldap/blob - servers/slapd/filter.c
SLAPD_SCHEMA_NOT_COMPAT:
[openldap] / servers / slapd / filter.c
1 /* filter.c - routines for parsing and dealing with filters */
2 /* $OpenLDAP$ */
3 /*
4  * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
5  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
6  */
7
8 #include "portable.h"
9
10 #include <stdio.h>
11
12 #include <ac/socket.h>
13 #include <ac/string.h>
14
15 #include "slap.h"
16
17 static int      get_filter_list(
18         Connection *conn,
19         BerElement *ber,
20         Filter **f,
21         char **fstr,
22         const char **text );
23
24 static int      get_substring_filter(
25         Connection *conn,
26         BerElement *ber,
27         Filter *f,
28         char **fstr,
29         const char **text );
30
31 int
32 get_filter(
33         Connection *conn,
34         BerElement *ber,
35         Filter **filt,
36         char **fstr,
37         const char **text )
38 {
39         ber_tag_t       tag;
40         ber_len_t       len;
41         int             err;
42         Filter          *f;
43         char            *ftmp = NULL;
44
45         Debug( LDAP_DEBUG_FILTER, "begin get_filter\n", 0, 0, 0 );
46
47         /*
48          * A filter looks like this coming in:
49          *      Filter ::= CHOICE {
50          *              and             [0]     SET OF Filter,
51          *              or              [1]     SET OF Filter,
52          *              not             [2]     Filter,
53          *              equalityMatch   [3]     AttributeValueAssertion,
54          *              substrings      [4]     SubstringFilter,
55          *              greaterOrEqual  [5]     AttributeValueAssertion,
56          *              lessOrEqual     [6]     AttributeValueAssertion,
57          *              present         [7]     AttributeType,,
58          *              approxMatch     [8]     AttributeValueAssertion
59          *              extensibleMatch [9] MatchingRuleAssertion
60          *      }
61          *
62          *      SubstringFilter ::= SEQUENCE {
63          *              type               AttributeType,
64          *              SEQUENCE OF CHOICE {
65          *                      initial          [0] IA5String,
66          *                      any              [1] IA5String,
67          *                      final            [2] IA5String
68          *              }
69          *      }
70          *
71      *  MatchingRuleAssertion ::= SEQUENCE {
72      *          matchingRule    [1] MatchingRuleId OPTIONAL,
73      *          type            [2] AttributeDescription OPTIONAL,
74      *          matchValue      [3] AssertionValue,
75      *          dnAttributes    [4] BOOLEAN DEFAULT FALSE
76          *      }
77          *
78          */
79
80         tag = ber_peek_tag( ber, &len );
81
82         if( tag == LBER_ERROR ) {
83                 *text = "error decoding filter";
84                 return SLAPD_DISCONNECT;
85         }
86
87         f = (Filter *) ch_malloc( sizeof(Filter) );
88         f->f_next = NULL;
89
90         err = LDAP_SUCCESS;
91         *fstr = NULL;
92         f->f_choice = tag; 
93
94         switch ( f->f_choice ) {
95         case LDAP_FILTER_EQUALITY:
96                 Debug( LDAP_DEBUG_FILTER, "EQUALITY\n", 0, 0, 0 );
97
98 #ifdef SLAPD_SCHEMA_NOT_COMPAT
99                 err = get_ava( ber, &f->f_ava, SLAP_MR_EQUALITY, text );
100 #else
101                 err = get_ava( ber, &f->f_ava, text );
102 #endif
103                 if ( err != LDAP_SUCCESS ) {
104                         break;
105                 }
106
107 #ifdef SLAPD_SCHEMA_NOT_COMPAT
108                 assert( f->f_ava != NULL );
109
110                 *fstr = ch_malloc( sizeof("(=)")
111                         + f->f_av_desc->ad_cname->bv_len
112                         + f->f_av_value->bv_len );
113
114                 sprintf( *fstr, "(%s=%s)",
115                         f->f_av_desc->ad_cname->bv_val,
116                     f->f_av_value->bv_val );
117
118 #else
119                 *fstr = ch_malloc( sizeof("(=)")
120                         + strlen( f->f_avtype )
121                         + f->f_avvalue.bv_len);
122                 sprintf( *fstr, "(%s=%s)", f->f_avtype,
123                     f->f_avvalue.bv_val );
124 #endif
125                 break;
126
127         case LDAP_FILTER_SUBSTRINGS:
128                 Debug( LDAP_DEBUG_FILTER, "SUBSTRINGS\n", 0, 0, 0 );
129                 err = get_substring_filter( conn, ber, f, fstr, text );
130                 break;
131
132         case LDAP_FILTER_GE:
133                 Debug( LDAP_DEBUG_FILTER, "GE\n", 0, 0, 0 );
134
135 #ifdef SLAPD_SCHEMA_NOT_COMPAT
136                 err = get_ava( ber, &f->f_ava, SLAP_MR_ORDERING, text );
137 #else
138                 err = get_ava( ber, &f->f_ava, text );
139 #endif
140                 if ( err != LDAP_SUCCESS ) {
141                         break;
142                 }
143
144 #ifdef SLAPD_SCHEMA_NOT_COMPAT
145                 *fstr = ch_malloc( sizeof("(>=)")
146                         + f->f_av_desc->ad_cname->bv_len
147                         + f->f_av_value->bv_len );
148
149                 sprintf( *fstr, "(%s>=%s)",
150                         f->f_av_desc->ad_cname->bv_val,
151                     f->f_av_value->bv_val );
152
153 #else
154                 *fstr = ch_malloc( sizeof("(>=)")
155                         + strlen( f->f_avtype )
156                         + f->f_avvalue.bv_len);
157                 sprintf( *fstr, "(%s>=%s)", f->f_avtype,
158                     f->f_avvalue.bv_val );
159 #endif
160                 break;
161
162         case LDAP_FILTER_LE:
163                 Debug( LDAP_DEBUG_FILTER, "LE\n", 0, 0, 0 );
164
165 #ifdef SLAPD_SCHEMA_NOT_COMPAT
166                 err = get_ava( ber, &f->f_ava, SLAP_MR_ORDERING, text );
167 #else
168                 err = get_ava( ber, &f->f_ava, text );
169 #endif
170                 if ( err != LDAP_SUCCESS ) {
171                         break;
172                 }
173
174
175 #ifdef SLAPD_SCHEMA_NOT_COMPAT
176                 *fstr = ch_malloc( sizeof("(<=)")
177                         + f->f_av_desc->ad_cname->bv_len
178                         + f->f_av_value->bv_len );
179
180                 sprintf( *fstr, "(%s<=%s)",
181                         f->f_av_desc->ad_cname->bv_val,
182                     f->f_av_value->bv_val );
183
184 #else
185                 *fstr = ch_malloc( sizeof("(<=)")
186                         + strlen( f->f_avtype )
187                         + f->f_avvalue.bv_len);
188                 sprintf( *fstr, "(%s<=%s)", f->f_avtype,
189                     f->f_avvalue.bv_val );
190 #endif
191                 break;
192
193         case LDAP_FILTER_PRESENT: {
194                 struct berval type;
195
196                 Debug( LDAP_DEBUG_FILTER, "PRESENT\n", 0, 0, 0 );
197
198                 if ( ber_scanf( ber, "o", &type ) == LBER_ERROR ) {
199                         err = SLAPD_DISCONNECT;
200                         *text = "error decoding filter";
201                         break;
202                 }
203
204 #ifdef SLAPD_SCHEMA_NOT_COMPAT
205                 f->f_desc = NULL;
206                 err = slap_bv2ad( &type, &f->f_desc, text );
207
208                 if( err != LDAP_SUCCESS ) {
209                         ch_free( type.bv_val );
210                         break;
211                 }
212
213                 ch_free( type.bv_val );
214
215                 *fstr = ch_malloc( sizeof("(=*)")
216                         + f->f_desc->ad_cname->bv_len );
217                 sprintf( *fstr, "(%s=*)",
218                         f->f_desc->ad_cname->bv_val );
219
220 #else
221                 f->f_type = type.bv_val;
222                 err = LDAP_SUCCESS;
223                 attr_normalize( f->f_type );
224                 *fstr = ch_malloc( sizeof("(=*)")
225                         + strlen( f->f_type ) );
226                 sprintf( *fstr, "(%s=*)", f->f_type );
227 #endif
228                 } break;
229
230         case LDAP_FILTER_APPROX:
231                 Debug( LDAP_DEBUG_FILTER, "APPROX\n", 0, 0, 0 );
232
233 #ifdef SLAPD_SCHEMA_NOT_COMPAT
234                 err = get_ava( ber, &f->f_ava, SLAP_MR_EQUALITY_APPROX, text );
235 #else
236                 err = get_ava( ber, &f->f_ava, text );
237 #endif
238                 if ( err != LDAP_SUCCESS ) {
239                         break;
240                 }
241
242 #ifdef SLAPD_SCHEMA_NOT_COMPAT
243                 *fstr = ch_malloc( sizeof("(~=)")
244                         + f->f_av_desc->ad_cname->bv_len
245                         + f->f_av_value->bv_len );
246
247                 sprintf( *fstr, "(%s~=%s)",
248                         f->f_av_desc->ad_cname->bv_val,
249                     f->f_av_value->bv_val );
250
251 #else
252                 *fstr = ch_malloc( sizeof("(~=)")
253                         + strlen( f->f_avtype )
254                         + f->f_avvalue.bv_len);
255                 sprintf( *fstr, "(%s~=%s)", f->f_avtype,
256                     f->f_avvalue.bv_val );
257 #endif
258                 break;
259
260         case LDAP_FILTER_AND:
261                 Debug( LDAP_DEBUG_FILTER, "AND\n", 0, 0, 0 );
262                 err = get_filter_list( conn, ber, &f->f_and, &ftmp, text );
263                 if ( err != LDAP_SUCCESS ) {
264                         break;
265                 }
266                 *fstr = ch_malloc( sizeof("(&)")
267                         + ( ftmp == NULL ? 0 : strlen( ftmp ) ) );
268                 sprintf( *fstr, "(&%s)",
269                         ftmp == NULL ? "" : ftmp );
270                 break;
271
272         case LDAP_FILTER_OR:
273                 Debug( LDAP_DEBUG_FILTER, "OR\n", 0, 0, 0 );
274                 err = get_filter_list( conn, ber, &f->f_and, &ftmp, text );
275                 if ( err != LDAP_SUCCESS ) {
276                         break;
277                 }
278                 *fstr = ch_malloc( sizeof("(!)")
279                         + ( ftmp == NULL ? 0 : strlen( ftmp ) ) );
280                 sprintf( *fstr, "(|%s)",
281                         ftmp == NULL ? "" : ftmp );
282                 break;
283
284         case LDAP_FILTER_NOT:
285                 Debug( LDAP_DEBUG_FILTER, "NOT\n", 0, 0, 0 );
286                 (void) ber_skip_tag( ber, &len );
287                 err = get_filter( conn, ber, &f->f_not, &ftmp, text );
288                 if ( err != LDAP_SUCCESS ) {
289                         break;
290                 }
291                 *fstr = ch_malloc( sizeof("(!)")
292                         + ( ftmp == NULL ? 0 : strlen( ftmp ) ) );
293                 sprintf( *fstr, "(!%s)",
294                         ftmp == NULL ? "" : ftmp );
295                 break;
296
297         case LDAP_FILTER_EXT:
298                 /* not yet implemented */
299                 Debug( LDAP_DEBUG_ANY, "extensible match not yet implemented.\n",
300                        f->f_choice, 0, 0 );
301                 f->f_choice = SLAPD_FILTER_COMPUTED;
302                 f->f_result = SLAPD_COMPARE_UNDEFINED;
303                 *fstr = ch_strdup( "(extended)" );
304                 break;
305
306         default:
307                 Debug( LDAP_DEBUG_ANY, "get_filter: unknown filter type=%lu\n",
308                        f->f_choice, 0, 0 );
309                 f->f_choice = SLAPD_FILTER_COMPUTED;
310                 f->f_result = SLAPD_COMPARE_UNDEFINED;
311                 *fstr = ch_strdup( "(undefined)" );
312                 break;
313         }
314
315         free( ftmp );
316
317         if ( err != LDAP_SUCCESS ) {
318                 if ( *fstr != NULL ) {
319                         free( *fstr );
320                 }
321
322                 if( err != SLAPD_DISCONNECT ) {
323                         /* ignore error */
324                         f->f_choice = SLAPD_FILTER_COMPUTED;
325                         f->f_result = SLAPD_COMPARE_UNDEFINED;
326                         *fstr = ch_strdup( "(badfilter)" );
327                         err = LDAP_SUCCESS;
328                         *filt = f;
329
330                 } else {
331                         free(f);
332                 }
333         } else {
334                 *filt = f;
335         }
336
337         Debug( LDAP_DEBUG_FILTER, "end get_filter %d\n", err, 0, 0 );
338         return( err );
339 }
340
341 static int
342 get_filter_list( Connection *conn, BerElement *ber,
343         Filter **f, char **fstr,
344         const char **text )
345 {
346         Filter          **new;
347         int             err;
348         ber_tag_t       tag;
349         ber_len_t       len;
350         char            *last, *ftmp;
351
352         Debug( LDAP_DEBUG_FILTER, "begin get_filter_list\n", 0, 0, 0 );
353
354         *fstr = NULL;
355         new = f;
356         for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT;
357             tag = ber_next_element( ber, &len, last ) )
358         {
359                 err = get_filter( conn, ber, new, &ftmp, text );
360                 if ( err != LDAP_SUCCESS )
361                         return( err );
362
363                 if ( *fstr == NULL ) {
364                         *fstr = ftmp;
365                 } else {
366                         *fstr = ch_realloc( *fstr, strlen( *fstr ) +
367                             strlen( ftmp ) + 1 );
368                         strcat( *fstr, ftmp );
369                         free( ftmp );
370                 }
371                 new = &(*new)->f_next;
372         }
373         *new = NULL;
374
375         Debug( LDAP_DEBUG_FILTER, "end get_filter_list\n", 0, 0, 0 );
376         return( LDAP_SUCCESS );
377 }
378
379 static int
380 get_substring_filter(
381     Connection  *conn,
382     BerElement  *ber,
383     Filter      *f,
384     char        **fstr,
385         const char      **text
386 )
387 {
388         ber_tag_t       tag;
389         ber_len_t       len;
390         ber_tag_t       rc;
391         struct berval *value;
392         char            *last;
393         struct berval type;
394 #ifdef SLAPD_SCHEMA_NOT_COMPAT
395         struct berval *nvalue;
396 #else
397         int             syntax;
398 #endif
399         *text = "error decoding filter";
400
401         Debug( LDAP_DEBUG_FILTER, "begin get_substring_filter\n", 0, 0, 0 );
402
403         if ( ber_scanf( ber, "{o" /*}*/, &type ) == LBER_ERROR ) {
404                 return SLAPD_DISCONNECT;
405         }
406
407 #ifdef SLAPD_SCHEMA_NOT_COMPAT
408         f->f_sub_desc = NULL;
409         rc = slap_bv2ad( &type, &f->f_sub_desc, text );
410
411         ch_free( type.bv_val );
412
413         if( rc != LDAP_SUCCESS ) {
414                 text = NULL;
415                 f->f_choice = SLAPD_FILTER_COMPUTED;
416                 f->f_result = SLAPD_COMPARE_UNDEFINED;
417                 *fstr = ch_strdup( "(undefined)" );
418                 return LDAP_SUCCESS;
419         }
420 #else
421         f->f_sub_type = type.bv_val;
422         attr_normalize( f->f_sub_type );
423
424         /* should get real syntax and see if we have a substring matching rule */
425         syntax = attr_syntax( f->f_sub_type );
426 #endif
427
428         f->f_sub_initial = NULL;
429         f->f_sub_any = NULL;
430         f->f_sub_final = NULL;
431
432 #ifdef SLAPD_SCHEMA_NOT_COMPAT
433         if( fstr ) {
434                 *fstr = ch_malloc( sizeof("(=" /*)*/) +
435                         f->f_sub_desc->ad_cname->bv_len );
436                 sprintf( *fstr, "(%s=" /*)*/, f->f_sub_desc->ad_cname->bv_val );
437         }
438 #else
439         if( fstr ) {
440                 *fstr = ch_malloc( strlen( f->f_sub_type ) + 3 );
441                 sprintf( *fstr, "(%s=" /*)*/, f->f_sub_type );
442         }
443 #endif
444
445         for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT;
446             tag = ber_next_element( ber, &len, last ) )
447         {
448 #ifdef SLAPD_SCHEMA_NOT_COMPAT
449                 unsigned usage;
450 #endif
451
452                 rc = ber_scanf( ber, "O", &value );
453                 if ( rc == LBER_ERROR ) {
454                         rc = SLAPD_DISCONNECT;
455                         goto return_error;
456                 }
457
458                 if ( value == NULL || value->bv_len == 0 ) {
459                         ber_bvfree( value );
460                         rc = LDAP_INVALID_SYNTAX;
461                         goto return_error;
462                 } 
463
464 #ifdef SLAPD_SCHEMA_NOT_COMPAT
465                 switch ( tag ) {
466                 case LDAP_SUBSTRING_INITIAL:
467                         usage = SLAP_MR_SUBSTR_INITIAL;
468                         break;
469
470                 case LDAP_SUBSTRING_ANY:
471                         usage = SLAP_MR_SUBSTR_ANY;
472                         break;
473
474                 case LDAP_SUBSTRING_FINAL:
475                         usage = SLAP_MR_SUBSTR_FINAL;
476                         break;
477
478                 default:
479                         rc = LDAP_PROTOCOL_ERROR;
480
481                         Debug( LDAP_DEBUG_FILTER,
482                                 "  unknown substring choice=%ld\n",
483                                 (long) tag, 0, 0 );
484
485                         ber_bvfree( value );
486                         goto return_error;
487                 }
488
489                 rc = value_normalize( f->f_sub_desc, usage, value, &nvalue, text );
490                 ber_bvfree( value );
491
492                 if( rc != LDAP_SUCCESS ) {
493                         goto return_error;
494                 }
495
496                 value = nvalue;
497 #else
498
499                 /* we should call a substring syntax normalization routine */
500                 value_normalize( value->bv_val, syntax );
501                 /* this is bogus, value_normalize should take a berval */
502                 value->bv_len = strlen( value->bv_val );
503 #endif
504
505                 rc = LDAP_PROTOCOL_ERROR;
506
507                 switch ( tag ) {
508                 case LDAP_SUBSTRING_INITIAL:
509                         Debug( LDAP_DEBUG_FILTER, "  INITIAL\n", 0, 0, 0 );
510                         if ( f->f_sub_initial != NULL ) {
511                                 ber_bvfree( value );
512                                 goto return_error;
513                         }
514
515                         f->f_sub_initial = value;
516
517                         if( fstr ) {
518                                 *fstr = ch_realloc( *fstr,
519                                         strlen( *fstr ) + value->bv_len + 1 );
520                                 strcat( *fstr, value->bv_val );
521                         }
522                         break;
523
524                 case LDAP_SUBSTRING_ANY:
525                         Debug( LDAP_DEBUG_FILTER, "  ANY\n", 0, 0, 0 );
526                         if( ber_bvecadd( &f->f_sub_any, value ) < 0 ) {
527                                 ber_bvfree( value );
528                                 goto return_error;
529                         }
530
531                         if( fstr ) {
532                                 *fstr = ch_realloc( *fstr,
533                                         strlen( *fstr ) + value->bv_len + 2 );
534                                 strcat( *fstr, "*" );
535                                 strcat( *fstr, value->bv_val );
536                         }
537                         break;
538
539                 case LDAP_SUBSTRING_FINAL:
540                         Debug( LDAP_DEBUG_FILTER, "  FINAL\n", 0, 0, 0 );
541                         if ( f->f_sub_final != NULL ) {
542                                 ber_bvfree( value );
543                                 goto return_error;
544                         }
545                         f->f_sub_final = value;
546
547                         if( fstr ) {
548                                 *fstr = ch_realloc( *fstr,
549                                         strlen( *fstr ) + value->bv_len + 2 );
550                                 strcat( *fstr, "*" );
551                                 strcat( *fstr, value->bv_val );
552                         }
553                         break;
554
555                 default:
556                         Debug( LDAP_DEBUG_FILTER,
557                                 "  unknown substring type=%ld\n",
558                                 (long) tag, 0, 0 );
559
560                         ber_bvfree( value );
561
562 return_error:
563                         Debug( LDAP_DEBUG_FILTER, "  error=%ld\n",
564                                 (long) rc, 0, 0 );
565
566                         if( fstr ) {
567                                 free( *fstr );
568                                 *fstr = NULL;
569                         }
570
571 #ifdef SLAPD_SCHEMA_NOT_COMPAT
572                         ad_free( f->f_sub_desc, 1 );
573 #else
574                         ch_free( f->f_sub_type );
575 #endif
576                         ber_bvfree( f->f_sub_initial );
577                         ber_bvecfree( f->f_sub_any );
578                         ber_bvfree( f->f_sub_final );
579                         return rc;
580                 }
581         }
582
583         if( fstr ) {
584                 *fstr = ch_realloc( *fstr, strlen( *fstr ) + 3 );
585                 if ( f->f_sub_final == NULL ) {
586                         strcat( *fstr, "*" );
587                 }
588                 strcat( *fstr, /*(*/ ")" );
589         }
590
591         Debug( LDAP_DEBUG_FILTER, "end get_substring_filter\n", 0, 0, 0 );
592         return( LDAP_SUCCESS );
593 }
594
595 void
596 filter_free( Filter *f )
597 {
598         Filter  *p, *next;
599
600         if ( f == NULL ) {
601                 return;
602         }
603
604         switch ( f->f_choice ) {
605         case LDAP_FILTER_PRESENT:
606 #ifdef SLAPD_SCHEMA_NOT_COMPAT
607                 ad_free( f->f_desc, 1 );
608 #else
609                 if ( f->f_type != NULL ) {
610                         free( f->f_type );
611                 }
612 #endif
613                 break;
614
615         case LDAP_FILTER_EQUALITY:
616         case LDAP_FILTER_GE:
617         case LDAP_FILTER_LE:
618         case LDAP_FILTER_APPROX:
619 #ifdef SLAPD_SCHEMA_NOT_COMPAT
620                 ava_free( f->f_ava, 1 );
621 #else
622                 ava_free( &f->f_ava, 0 );
623 #endif
624                 break;
625
626         case LDAP_FILTER_SUBSTRINGS:
627 #ifdef SLAPD_SCHEMA_NOT_COMPAT
628                 ad_free( f->f_sub_desc, 1 );
629                 if ( f->f_sub_initial != NULL ) {
630                         ber_bvfree( f->f_sub_initial );
631                 }
632                 ber_bvecfree( f->f_sub_any );
633                 if ( f->f_sub_final != NULL ) {
634                         ber_bvfree( f->f_sub_final );
635                 }
636 #else
637                 if ( f->f_sub_type != NULL ) {
638                         free( f->f_sub_type );
639                 }
640                 if ( f->f_sub_initial != NULL ) {
641                         ber_bvfree( f->f_sub_initial );
642                 }
643                 ber_bvecfree( f->f_sub_any );
644                 if ( f->f_sub_final != NULL ) {
645                         ber_bvfree( f->f_sub_final );
646                 }
647 #endif
648                 break;
649
650         case LDAP_FILTER_AND:
651         case LDAP_FILTER_OR:
652         case LDAP_FILTER_NOT:
653                 for ( p = f->f_list; p != NULL; p = next ) {
654                         next = p->f_next;
655                         filter_free( p );
656                 }
657                 break;
658
659         case SLAPD_FILTER_COMPUTED:
660                 break;
661
662         default:
663                 Debug( LDAP_DEBUG_ANY, "filter_free: unknown filter type=%lu\n",
664                        f->f_choice, 0, 0 );
665                 break;
666         }
667
668         free( f );
669 }
670
671 #ifdef LDAP_DEBUG
672
673 void
674 filter_print( Filter *f )
675 {
676         int     i;
677         Filter  *p;
678
679         if ( f == NULL ) {
680                 fprintf( stderr, "No filter!" );
681         }
682
683         switch ( f->f_choice ) {
684         case LDAP_FILTER_EQUALITY:
685 #ifdef SLAPD_SCHEMA_NOT_COMPAT
686                 fprintf( stderr, "(%s=%s)",
687                         f->f_av_desc->ad_cname->bv_val,
688                     f->f_av_value->bv_val );
689 #else
690                 fprintf( stderr, "(%s=%s)",
691                         f->f_ava.ava_type,
692                     f->f_ava.ava_value.bv_val );
693 #endif
694                 break;
695
696         case LDAP_FILTER_GE:
697 #ifdef SLAPD_SCHEMA_NOT_COMPAT
698                 fprintf( stderr, "(%s>=%s)",
699                         f->f_av_desc->ad_cname->bv_val,
700                     f->f_av_value->bv_val );
701 #else
702                 fprintf( stderr, "(%s>=%s)",
703                         f->f_ava.ava_type,
704                     f->f_ava.ava_value.bv_val );
705 #endif
706                 break;
707
708         case LDAP_FILTER_LE:
709 #ifdef SLAPD_SCHEMA_NOT_COMPAT
710                 fprintf( stderr, "(%s<=%s)",
711                         f->f_ava->aa_desc->ad_cname->bv_val,
712                     f->f_ava->aa_value->bv_val );
713 #else
714                 fprintf( stderr, "(%s<=%s)",
715                         f->f_ava.ava_type,
716                     f->f_ava.ava_value.bv_val );
717 #endif
718                 break;
719
720         case LDAP_FILTER_APPROX:
721 #ifdef SLAPD_SCHEMA_NOT_COMPAT
722                 fprintf( stderr, "(%s~=%s)",
723                         f->f_ava->aa_desc->ad_cname->bv_val,
724                     f->f_ava->aa_value->bv_val );
725 #else
726                 fprintf( stderr, "(%s~=%s)",
727                         f->f_ava.ava_type,
728                     f->f_ava.ava_value.bv_val );
729 #endif
730                 break;
731
732         case LDAP_FILTER_SUBSTRINGS:
733 #ifdef SLAPD_SCHEMA_NOT_COMPAT
734                 fprintf( stderr, "(%s=" /*)*/,
735                         f->f_sub_desc->ad_cname->bv_val );
736 #else
737                 fprintf( stderr, "(%s=" /*)*/,
738                         f->f_sub_type );
739 #endif
740                 if ( f->f_sub_initial != NULL ) {
741                         fprintf( stderr, "%s",
742                                 f->f_sub_initial->bv_val );
743                 }
744                 if ( f->f_sub_any != NULL ) {
745                         for ( i = 0; f->f_sub_any[i] != NULL; i++ ) {
746                                 fprintf( stderr, "*%s",
747                                         f->f_sub_any[i]->bv_val );
748                         }
749                 }
750                 if ( f->f_sub_final != NULL ) {
751                         fprintf( stderr,
752                                 "*%s", f->f_sub_final->bv_val );
753                 }
754                 fprintf( stderr, /*(*/ ")" );
755                 break;
756
757         case LDAP_FILTER_PRESENT:
758 #ifdef SLAPD_SCHEMA_NOT_COMPAT
759                 fprintf( stderr, "(%s=*)",
760                         f->f_desc->ad_cname->bv_val );
761 #else
762                 fprintf( stderr, "(%s=*)",
763                         f->f_type );
764 #endif
765                 break;
766
767         case LDAP_FILTER_AND:
768         case LDAP_FILTER_OR:
769         case LDAP_FILTER_NOT:
770                 fprintf( stderr, "(%c" /*)*/,
771                         f->f_choice == LDAP_FILTER_AND ? '&' :
772                     f->f_choice == LDAP_FILTER_OR ? '|' : '!' );
773                 for ( p = f->f_list; p != NULL; p = p->f_next ) {
774                         filter_print( p );
775                 }
776                 fprintf( stderr, /*(*/ ")" );
777                 break;
778
779         case SLAPD_FILTER_COMPUTED:
780                 fprintf( stderr, "(?=%s)",
781                         f->f_result == LDAP_COMPARE_FALSE ? "false" :
782                         f->f_result == LDAP_COMPARE_TRUE ? "true" :
783                         f->f_result == SLAPD_COMPARE_UNDEFINED ? "undefined" :
784                         "error" );
785                 break;
786
787         default:
788                 fprintf( stderr, "(unknown-filter=%lu)", f->f_choice );
789                 break;
790         }
791 }
792
793 #endif /* ldap_debug */