1 /* $NetBSD: filter.c,v 1.8 2021/08/14 16:14:58 christos Exp $ */
2
3 /* filter.c - routines for parsing and dealing with filters */
4 /* $OpenLDAP$ */
5 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
6 *
7 * Copyright 1998-2021 The OpenLDAP Foundation.
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted only as authorized by the OpenLDAP
12 * Public License.
13 *
14 * A copy of this license is available in the file LICENSE in the
15 * top-level directory of the distribution or, alternatively, at
16 * <http://www.OpenLDAP.org/license.html>.
17 */
18 /* Portions Copyright (c) 1995 Regents of the University of Michigan.
19 * All rights reserved.
20 *
21 * Redistribution and use in source and binary forms are permitted
22 * provided that this notice is preserved and that due credit is given
23 * to the University of Michigan at Ann Arbor. The name of the University
24 * may not be used to endorse or promote products derived from this
25 * software without specific prior written permission. This software
26 * is provided ``as is'' without express or implied warranty.
27 */
28
29 #include <sys/cdefs.h>
30 __RCSID("$NetBSD: filter.c,v 1.8 2021/08/14 16:14:58 christos Exp $");
31
32 #include "portable.h"
33
34 #include <stdio.h>
35
36 #include <ac/socket.h>
37 #include <ac/string.h>
38
39 #include "slap.h"
40 #include "lutil.h"
41
42 const Filter *slap_filter_objectClass_pres;
43 const struct berval *slap_filterstr_objectClass_pres;
44
45 static int get_filter_list(
46 Operation *op,
47 BerElement *ber,
48 Filter **f,
49 const char **text,
50 int depth );
51
52 static int get_ssa(
53 Operation *op,
54 BerElement *ber,
55 Filter *f,
56 const char **text );
57
58 static void simple_vrFilter2bv(
59 Operation *op,
60 ValuesReturnFilter *f,
61 struct berval *fstr );
62
63 static int get_simple_vrFilter(
64 Operation *op,
65 BerElement *ber,
66 ValuesReturnFilter **f,
67 const char **text );
68
69 int
filter_init(void)70 filter_init( void )
71 {
72 static Filter filter_objectClass_pres = { LDAP_FILTER_PRESENT };
73 static struct berval filterstr_objectClass_pres = BER_BVC("(objectClass=*)");
74
75 filter_objectClass_pres.f_desc = slap_schema.si_ad_objectClass;
76
77 slap_filter_objectClass_pres = &filter_objectClass_pres;
78 slap_filterstr_objectClass_pres = &filterstr_objectClass_pres;
79
80 return 0;
81 }
82
83 void
filter_destroy(void)84 filter_destroy( void )
85 {
86 return;
87 }
88
89 static int
get_filter0(Operation * op,BerElement * ber,Filter ** filt,const char ** text,int depth)90 get_filter0(
91 Operation *op,
92 BerElement *ber,
93 Filter **filt,
94 const char **text,
95 int depth )
96 {
97 ber_tag_t tag;
98 ber_len_t len;
99 int err;
100 Filter f;
101
102 Debug( LDAP_DEBUG_FILTER, "begin get_filter\n" );
103 /*
104 * A filter looks like this coming in:
105 * Filter ::= CHOICE {
106 * and [0] SET OF Filter,
107 * or [1] SET OF Filter,
108 * not [2] Filter,
109 * equalityMatch [3] AttributeValueAssertion,
110 * substrings [4] SubstringFilter,
111 * greaterOrEqual [5] AttributeValueAssertion,
112 * lessOrEqual [6] AttributeValueAssertion,
113 * present [7] AttributeType,
114 * approxMatch [8] AttributeValueAssertion,
115 * extensibleMatch [9] MatchingRuleAssertion
116 * }
117 *
118 * SubstringFilter ::= SEQUENCE {
119 * type AttributeType,
120 * SEQUENCE OF CHOICE {
121 * initial [0] IA5String,
122 * any [1] IA5String,
123 * final [2] IA5String
124 * }
125 * }
126 *
127 * MatchingRuleAssertion ::= SEQUENCE {
128 * matchingRule [1] MatchingRuleId OPTIONAL,
129 * type [2] AttributeDescription OPTIONAL,
130 * matchValue [3] AssertionValue,
131 * dnAttributes [4] BOOLEAN DEFAULT FALSE
132 * }
133 *
134 */
135
136 if( depth > slap_max_filter_depth ) {
137 *text = "filter nested too deeply";
138 return SLAPD_DISCONNECT;
139 }
140
141 tag = ber_peek_tag( ber, &len );
142
143 if( tag == LBER_ERROR ) {
144 *text = "error decoding filter";
145 return SLAPD_DISCONNECT;
146 }
147
148 err = LDAP_SUCCESS;
149
150 f.f_next = NULL;
151 f.f_choice = tag;
152
153 switch ( f.f_choice ) {
154 case LDAP_FILTER_EQUALITY:
155 Debug( LDAP_DEBUG_FILTER, "EQUALITY\n" );
156 err = get_ava( op, ber, &f, SLAP_MR_EQUALITY, text );
157 if ( err != LDAP_SUCCESS ) {
158 break;
159 }
160
161 assert( f.f_ava != NULL );
162 break;
163
164 case LDAP_FILTER_SUBSTRINGS:
165 Debug( LDAP_DEBUG_FILTER, "SUBSTRINGS\n" );
166 err = get_ssa( op, ber, &f, text );
167 if( err != LDAP_SUCCESS ) {
168 break;
169 }
170 assert( f.f_sub != NULL );
171 break;
172
173 case LDAP_FILTER_GE:
174 Debug( LDAP_DEBUG_FILTER, "GE\n" );
175 err = get_ava( op, ber, &f, SLAP_MR_ORDERING, text );
176 if ( err != LDAP_SUCCESS ) {
177 break;
178 }
179 assert( f.f_ava != NULL );
180 break;
181
182 case LDAP_FILTER_LE:
183 Debug( LDAP_DEBUG_FILTER, "LE\n" );
184 err = get_ava( op, ber, &f, SLAP_MR_ORDERING, text );
185 if ( err != LDAP_SUCCESS ) {
186 break;
187 }
188 assert( f.f_ava != NULL );
189 break;
190
191 case LDAP_FILTER_PRESENT: {
192 struct berval type;
193
194 Debug( LDAP_DEBUG_FILTER, "PRESENT\n" );
195 if ( ber_scanf( ber, "m", &type ) == LBER_ERROR ) {
196 err = SLAPD_DISCONNECT;
197 *text = "error decoding filter";
198 break;
199 }
200
201 f.f_desc = NULL;
202 err = slap_bv2ad( &type, &f.f_desc, text );
203
204 if( err != LDAP_SUCCESS ) {
205 f.f_choice |= SLAPD_FILTER_UNDEFINED;
206 err = slap_bv2undef_ad( &type, &f.f_desc, text,
207 SLAP_AD_PROXIED|SLAP_AD_NOINSERT );
208
209 if ( err != LDAP_SUCCESS ) {
210 /* unrecognized attribute description or other error */
211 Debug( LDAP_DEBUG_ANY,
212 "get_filter: conn %lu unknown attribute "
213 "type=%s (%d)\n",
214 op->o_connid, type.bv_val, err );
215
216 err = LDAP_SUCCESS;
217 f.f_desc = slap_bv2tmp_ad( &type, op->o_tmpmemctx );
218 }
219 *text = NULL;
220 }
221
222 assert( f.f_desc != NULL );
223 } break;
224
225 case LDAP_FILTER_APPROX:
226 Debug( LDAP_DEBUG_FILTER, "APPROX\n" );
227 err = get_ava( op, ber, &f, SLAP_MR_EQUALITY_APPROX, text );
228 if ( err != LDAP_SUCCESS ) {
229 break;
230 }
231 assert( f.f_ava != NULL );
232 break;
233
234 case LDAP_FILTER_AND:
235 Debug( LDAP_DEBUG_FILTER, "AND\n" );
236 err = get_filter_list( op, ber, &f.f_and, text, depth+1 );
237 if ( err != LDAP_SUCCESS ) {
238 break;
239 }
240 if ( f.f_and == NULL ) {
241 f.f_choice = SLAPD_FILTER_COMPUTED;
242 f.f_result = LDAP_COMPARE_TRUE;
243 }
244 /* no assert - list could be empty */
245 break;
246
247 case LDAP_FILTER_OR:
248 Debug( LDAP_DEBUG_FILTER, "OR\n" );
249 err = get_filter_list( op, ber, &f.f_or, text, depth+1 );
250 if ( err != LDAP_SUCCESS ) {
251 break;
252 }
253 if ( f.f_or == NULL ) {
254 f.f_choice = SLAPD_FILTER_COMPUTED;
255 f.f_result = LDAP_COMPARE_FALSE;
256 }
257 /* no assert - list could be empty */
258 break;
259
260 case LDAP_FILTER_NOT:
261 Debug( LDAP_DEBUG_FILTER, "NOT\n" );
262 (void) ber_skip_tag( ber, &len );
263 err = get_filter0( op, ber, &f.f_not, text, depth+1 );
264 if ( err != LDAP_SUCCESS ) {
265 break;
266 }
267
268 assert( f.f_not != NULL );
269 if ( f.f_not->f_choice == SLAPD_FILTER_COMPUTED ) {
270 int fresult = f.f_not->f_result;
271 f.f_choice = SLAPD_FILTER_COMPUTED;
272 op->o_tmpfree( f.f_not, op->o_tmpmemctx );
273 f.f_not = NULL;
274
275 switch( fresult ) {
276 case LDAP_COMPARE_TRUE:
277 f.f_result = LDAP_COMPARE_FALSE;
278 break;
279 case LDAP_COMPARE_FALSE:
280 f.f_result = LDAP_COMPARE_TRUE;
281 break;
282 default: ;
283 /* (!Undefined) is Undefined */
284 }
285 }
286 break;
287
288 case LDAP_FILTER_EXT:
289 Debug( LDAP_DEBUG_FILTER, "EXTENSIBLE\n" );
290
291 err = get_mra( op, ber, &f, text );
292 if ( err != LDAP_SUCCESS ) {
293 break;
294 }
295
296 assert( f.f_mra != NULL );
297 break;
298
299 default:
300 (void) ber_scanf( ber, "x" ); /* skip the element */
301 Debug( LDAP_DEBUG_ANY, "get_filter: unknown filter type=%lu\n",
302 f.f_choice );
303 f.f_choice = SLAPD_FILTER_COMPUTED;
304 f.f_result = SLAPD_COMPARE_UNDEFINED;
305 break;
306 }
307
308 if( err != LDAP_SUCCESS && err != SLAPD_DISCONNECT ) {
309 /* ignore error */
310 *text = NULL;
311 f.f_choice = SLAPD_FILTER_COMPUTED;
312 f.f_result = SLAPD_COMPARE_UNDEFINED;
313 err = LDAP_SUCCESS;
314 }
315
316 if ( err == LDAP_SUCCESS ) {
317 *filt = op->o_tmpalloc( sizeof(f), op->o_tmpmemctx );
318 **filt = f;
319 }
320
321 Debug( LDAP_DEBUG_FILTER, "end get_filter %d\n", err );
322
323 return( err );
324 }
325
326 int
get_filter(Operation * op,BerElement * ber,Filter ** filt,const char ** text)327 get_filter(
328 Operation *op,
329 BerElement *ber,
330 Filter **filt,
331 const char **text )
332 {
333 return get_filter0( op, ber, filt, text, 0 );
334 }
335
336
337 static int
get_filter_list(Operation * op,BerElement * ber,Filter ** f,const char ** text,int depth)338 get_filter_list( Operation *op, BerElement *ber,
339 Filter **f,
340 const char **text,
341 int depth )
342 {
343 Filter **new;
344 int err;
345 ber_tag_t tag;
346 ber_len_t len;
347 char *last;
348
349 Debug( LDAP_DEBUG_FILTER, "begin get_filter_list\n" );
350 new = f;
351 for ( tag = ber_first_element( ber, &len, &last );
352 tag != LBER_DEFAULT;
353 tag = ber_next_element( ber, &len, last ) )
354 {
355 err = get_filter0( op, ber, new, text, depth );
356 if ( err != LDAP_SUCCESS )
357 return( err );
358 new = &(*new)->f_next;
359 }
360 *new = NULL;
361
362 Debug( LDAP_DEBUG_FILTER, "end get_filter_list\n" );
363 return( LDAP_SUCCESS );
364 }
365
366 static int
get_ssa(Operation * op,BerElement * ber,Filter * f,const char ** text)367 get_ssa(
368 Operation *op,
369 BerElement *ber,
370 Filter *f,
371 const char **text )
372 {
373 ber_tag_t tag;
374 ber_len_t len;
375 int rc;
376 struct berval desc, value, nvalue;
377 char *last;
378 SubstringsAssertion ssa;
379
380 *text = "error decoding filter";
381
382 Debug( LDAP_DEBUG_FILTER, "begin get_ssa\n" );
383 if ( ber_scanf( ber, "{m" /*}*/, &desc ) == LBER_ERROR ) {
384 return SLAPD_DISCONNECT;
385 }
386
387 *text = NULL;
388
389 ssa.sa_desc = NULL;
390 ssa.sa_initial.bv_val = NULL;
391 ssa.sa_any = NULL;
392 ssa.sa_final.bv_val = NULL;
393
394 rc = slap_bv2ad( &desc, &ssa.sa_desc, text );
395
396 if( rc != LDAP_SUCCESS ) {
397 f->f_choice |= SLAPD_FILTER_UNDEFINED;
398 rc = slap_bv2undef_ad( &desc, &ssa.sa_desc, text,
399 SLAP_AD_PROXIED|SLAP_AD_NOINSERT );
400
401 if( rc != LDAP_SUCCESS ) {
402 Debug( LDAP_DEBUG_ANY,
403 "get_ssa: conn %lu unknown attribute type=%s (%ld)\n",
404 op->o_connid, desc.bv_val, (long) rc );
405
406 ssa.sa_desc = slap_bv2tmp_ad( &desc, op->o_tmpmemctx );
407 }
408 }
409
410 rc = LDAP_PROTOCOL_ERROR;
411
412 /* If there is no substring matching rule, there's nothing
413 * we can do with this filter. But we continue to parse it
414 * for logging purposes.
415 */
416 if ( ssa.sa_desc->ad_type->sat_substr == NULL ) {
417 f->f_choice |= SLAPD_FILTER_UNDEFINED;
418 Debug( LDAP_DEBUG_FILTER,
419 "get_ssa: no substring matching rule for attributeType %s\n",
420 desc.bv_val );
421 }
422
423 for ( tag = ber_first_element( ber, &len, &last );
424 tag != LBER_DEFAULT;
425 tag = ber_next_element( ber, &len, last ) )
426 {
427 unsigned usage;
428
429 if ( ber_scanf( ber, "m", &value ) == LBER_ERROR ) {
430 rc = SLAPD_DISCONNECT;
431 goto return_error;
432 }
433
434 if ( value.bv_val == NULL || value.bv_len == 0 ) {
435 rc = LDAP_INVALID_SYNTAX;
436 goto return_error;
437 }
438
439 switch ( tag ) {
440 case LDAP_SUBSTRING_INITIAL:
441 if ( ssa.sa_initial.bv_val != NULL
442 || ssa.sa_any != NULL
443 || ssa.sa_final.bv_val != NULL )
444 {
445 rc = LDAP_PROTOCOL_ERROR;
446 goto return_error;
447 }
448 usage = SLAP_MR_SUBSTR_INITIAL;
449 break;
450
451 case LDAP_SUBSTRING_ANY:
452 if ( ssa.sa_final.bv_val != NULL ) {
453 rc = LDAP_PROTOCOL_ERROR;
454 goto return_error;
455 }
456 usage = SLAP_MR_SUBSTR_ANY;
457 break;
458
459 case LDAP_SUBSTRING_FINAL:
460 if ( ssa.sa_final.bv_val != NULL ) {
461 rc = LDAP_PROTOCOL_ERROR;
462 goto return_error;
463 }
464
465 usage = SLAP_MR_SUBSTR_FINAL;
466 break;
467
468 default:
469 Debug( LDAP_DEBUG_FILTER,
470 " unknown substring choice=%ld\n",
471 (long) tag );
472
473 rc = LDAP_PROTOCOL_ERROR;
474 goto return_error;
475 }
476
477 /* validate/normalize using equality matching rule validator! */
478 rc = asserted_value_validate_normalize(
479 ssa.sa_desc, ssa.sa_desc->ad_type->sat_equality,
480 usage, &value, &nvalue, text, op->o_tmpmemctx );
481 if( rc != LDAP_SUCCESS ) {
482 f->f_choice |= SLAPD_FILTER_UNDEFINED;
483 Debug( LDAP_DEBUG_FILTER,
484 "get_ssa: illegal value for attributeType %s (%d) %s\n",
485 desc.bv_val, rc, *text );
486 ber_dupbv_x( &nvalue, &value, op->o_tmpmemctx );
487 }
488
489 switch ( tag ) {
490 case LDAP_SUBSTRING_INITIAL:
491 Debug( LDAP_DEBUG_FILTER, " INITIAL\n" );
492 ssa.sa_initial = nvalue;
493 break;
494
495 case LDAP_SUBSTRING_ANY:
496 Debug( LDAP_DEBUG_FILTER, " ANY\n" );
497 ber_bvarray_add_x( &ssa.sa_any, &nvalue, op->o_tmpmemctx );
498 break;
499
500 case LDAP_SUBSTRING_FINAL:
501 Debug( LDAP_DEBUG_FILTER, " FINAL\n" );
502 ssa.sa_final = nvalue;
503 break;
504
505 default:
506 assert( 0 );
507 slap_sl_free( nvalue.bv_val, op->o_tmpmemctx );
508 rc = LDAP_PROTOCOL_ERROR;
509
510 return_error:
511 Debug( LDAP_DEBUG_FILTER, " error=%ld\n",
512 (long) rc );
513 slap_sl_free( ssa.sa_initial.bv_val, op->o_tmpmemctx );
514 ber_bvarray_free_x( ssa.sa_any, op->o_tmpmemctx );
515 if ( ssa.sa_desc->ad_flags & SLAP_DESC_TEMPORARY )
516 op->o_tmpfree( ssa.sa_desc, op->o_tmpmemctx );
517 slap_sl_free( ssa.sa_final.bv_val, op->o_tmpmemctx );
518 return rc;
519 }
520
521 *text = NULL;
522 rc = LDAP_SUCCESS;
523 }
524
525 if( rc == LDAP_SUCCESS ) {
526 f->f_sub = op->o_tmpalloc( sizeof( ssa ), op->o_tmpmemctx );
527 *f->f_sub = ssa;
528 }
529
530 Debug( LDAP_DEBUG_FILTER, "end get_ssa\n" );
531 return rc /* LDAP_SUCCESS */ ;
532 }
533
534 void
filter_free_x(Operation * op,Filter * f,int freeme)535 filter_free_x( Operation *op, Filter *f, int freeme )
536 {
537 Filter *p, *next;
538
539 if ( f == NULL ) {
540 return;
541 }
542
543 f->f_choice &= SLAPD_FILTER_MASK;
544
545 switch ( f->f_choice ) {
546 case LDAP_FILTER_PRESENT:
547 if ( f->f_desc->ad_flags & SLAP_DESC_TEMPORARY )
548 op->o_tmpfree( f->f_desc, op->o_tmpmemctx );
549 break;
550
551 case LDAP_FILTER_EQUALITY:
552 case LDAP_FILTER_GE:
553 case LDAP_FILTER_LE:
554 case LDAP_FILTER_APPROX:
555 ava_free( op, f->f_ava, 1 );
556 break;
557
558 case LDAP_FILTER_SUBSTRINGS:
559 if ( f->f_sub_initial.bv_val != NULL ) {
560 op->o_tmpfree( f->f_sub_initial.bv_val, op->o_tmpmemctx );
561 }
562 ber_bvarray_free_x( f->f_sub_any, op->o_tmpmemctx );
563 if ( f->f_sub_final.bv_val != NULL ) {
564 op->o_tmpfree( f->f_sub_final.bv_val, op->o_tmpmemctx );
565 }
566 if ( f->f_sub->sa_desc->ad_flags & SLAP_DESC_TEMPORARY )
567 op->o_tmpfree( f->f_sub->sa_desc, op->o_tmpmemctx );
568 op->o_tmpfree( f->f_sub, op->o_tmpmemctx );
569 break;
570
571 case LDAP_FILTER_AND:
572 case LDAP_FILTER_OR:
573 case LDAP_FILTER_NOT:
574 for ( p = f->f_list; p != NULL; p = next ) {
575 next = p->f_next;
576 filter_free_x( op, p, 1 );
577 }
578 break;
579
580 case LDAP_FILTER_EXT:
581 mra_free( op, f->f_mra, 1 );
582 break;
583
584 case SLAPD_FILTER_COMPUTED:
585 break;
586
587 default:
588 Debug( LDAP_DEBUG_ANY, "filter_free: unknown filter type=%lu\n",
589 f->f_choice );
590 break;
591 }
592
593 if ( freeme ) {
594 op->o_tmpfree( f, op->o_tmpmemctx );
595 }
596 }
597
598 void
filter_free(Filter * f)599 filter_free( Filter *f )
600 {
601 Operation op;
602 Opheader ohdr;
603
604 op.o_hdr = &ohdr;
605 op.o_tmpmemctx = slap_sl_context( f );
606 op.o_tmpmfuncs = &slap_sl_mfuncs;
607 filter_free_x( &op, f, 1 );
608 }
609
610 void
filter2bv_x(Operation * op,Filter * f,struct berval * fstr)611 filter2bv_x( Operation *op, Filter *f, struct berval *fstr )
612 {
613 filter2bv_undef_x( op, f, 0, fstr );
614 }
615
616 void
filter2bv_undef_x(Operation * op,Filter * f,int noundef,struct berval * fstr)617 filter2bv_undef_x( Operation *op, Filter *f, int noundef, struct berval *fstr )
618 {
619 int i;
620 Filter *p;
621 struct berval tmp, value;
622 static struct berval
623 ber_bvfalse = BER_BVC( "(?=false)" ),
624 ber_bvtrue = BER_BVC( "(?=true)" ),
625 ber_bvundefined = BER_BVC( "(?=undefined)" ),
626 ber_bverror = BER_BVC( "(?=error)" ),
627 ber_bvunknown = BER_BVC( "(?=unknown)" ),
628 ber_bvnone = BER_BVC( "(?=none)" ),
629 ber_bvF = BER_BVC( "(|)" ),
630 ber_bvT = BER_BVC( "(&)" );
631 ber_len_t len;
632 ber_tag_t choice;
633 int undef, undef2;
634 char *sign;
635
636 if ( f == NULL ) {
637 ber_dupbv_x( fstr, &ber_bvnone, op->o_tmpmemctx );
638 return;
639 }
640
641 undef = f->f_choice & SLAPD_FILTER_UNDEFINED;
642 undef2 = (undef && !noundef);
643 choice = f->f_choice & SLAPD_FILTER_MASK;
644
645 switch ( choice ) {
646 case LDAP_FILTER_EQUALITY:
647 fstr->bv_len = STRLENOF("(=)");
648 sign = "=";
649 goto simple;
650 case LDAP_FILTER_GE:
651 fstr->bv_len = STRLENOF("(>=)");
652 sign = ">=";
653 goto simple;
654 case LDAP_FILTER_LE:
655 fstr->bv_len = STRLENOF("(<=)");
656 sign = "<=";
657 goto simple;
658 case LDAP_FILTER_APPROX:
659 fstr->bv_len = STRLENOF("(~=)");
660 sign = "~=";
661
662 simple:
663 value = f->f_av_value;
664 if ( f->f_av_desc->ad_type->sat_equality &&
665 !undef &&
666 ( f->f_av_desc->ad_type->sat_equality->smr_usage & SLAP_MR_MUTATION_NORMALIZER ))
667 {
668 f->f_av_desc->ad_type->sat_equality->smr_normalize(
669 (SLAP_MR_DENORMALIZE|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX),
670 NULL, NULL, &f->f_av_value, &value, op->o_tmpmemctx );
671 }
672
673 filter_escape_value_x( &value, &tmp, op->o_tmpmemctx );
674 /* NOTE: tmp can legitimately be NULL (meaning empty)
675 * since in a Filter values in AVAs are supposed
676 * to have been normalized, meaning that an empty value
677 * is legal for that attribute's syntax */
678
679 fstr->bv_len += f->f_av_desc->ad_cname.bv_len + tmp.bv_len;
680 if ( undef2 )
681 fstr->bv_len++;
682 fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx );
683
684 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s%s%s%s)",
685 undef2 ? "?" : "",
686 f->f_av_desc->ad_cname.bv_val, sign,
687 tmp.bv_len ? tmp.bv_val : "" );
688
689 if ( value.bv_val != f->f_av_value.bv_val ) {
690 ber_memfree_x( value.bv_val, op->o_tmpmemctx );
691 }
692
693 ber_memfree_x( tmp.bv_val, op->o_tmpmemctx );
694 break;
695
696 case LDAP_FILTER_SUBSTRINGS:
697 fstr->bv_len = f->f_sub_desc->ad_cname.bv_len +
698 STRLENOF("(=*)");
699 if ( undef2 )
700 fstr->bv_len++;
701 fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 128, op->o_tmpmemctx );
702
703 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s%s=*)",
704 undef2 ? "?" : "",
705 f->f_sub_desc->ad_cname.bv_val );
706
707 if ( f->f_sub_initial.bv_val != NULL ) {
708 ber_len_t tmplen;
709
710 len = fstr->bv_len;
711
712 filter_escape_value_x( &f->f_sub_initial, &tmp, op->o_tmpmemctx );
713 tmplen = tmp.bv_len;
714
715 fstr->bv_len += tmplen;
716 fstr->bv_val = op->o_tmprealloc( fstr->bv_val,
717 fstr->bv_len + 1, op->o_tmpmemctx );
718
719 snprintf( &fstr->bv_val[len - 2],
720 tmplen + STRLENOF( /*(*/ "*)" ) + 1,
721 /* "(attr=" */ "%s*)",
722 tmp.bv_len ? tmp.bv_val : "");
723
724 ber_memfree_x( tmp.bv_val, op->o_tmpmemctx );
725 }
726
727 if ( f->f_sub_any != NULL ) {
728 for ( i = 0; f->f_sub_any[i].bv_val != NULL; i++ ) {
729 ber_len_t tmplen;
730
731 len = fstr->bv_len;
732 filter_escape_value_x( &f->f_sub_any[i],
733 &tmp, op->o_tmpmemctx );
734 tmplen = tmp.bv_len;
735
736 fstr->bv_len += tmplen + STRLENOF( /*(*/ ")" );
737 fstr->bv_val = op->o_tmprealloc( fstr->bv_val,
738 fstr->bv_len + 1, op->o_tmpmemctx );
739
740 snprintf( &fstr->bv_val[len - 1],
741 tmplen + STRLENOF( /*(*/ "*)" ) + 1,
742 /* "(attr=[init]*[any*]" */ "%s*)",
743 tmp.bv_len ? tmp.bv_val : "");
744 ber_memfree_x( tmp.bv_val, op->o_tmpmemctx );
745 }
746 }
747
748 if ( f->f_sub_final.bv_val != NULL ) {
749 ber_len_t tmplen;
750
751 len = fstr->bv_len;
752
753 filter_escape_value_x( &f->f_sub_final, &tmp, op->o_tmpmemctx );
754 tmplen = tmp.bv_len;
755
756 fstr->bv_len += tmplen;
757 fstr->bv_val = op->o_tmprealloc( fstr->bv_val,
758 fstr->bv_len + 1, op->o_tmpmemctx );
759
760 snprintf( &fstr->bv_val[len - 1],
761 tmplen + STRLENOF( /*(*/ ")" ) + 1,
762 /* "(attr=[init*][any*]" */ "%s)",
763 tmp.bv_len ? tmp.bv_val : "");
764
765 ber_memfree_x( tmp.bv_val, op->o_tmpmemctx );
766 }
767
768 break;
769
770 case LDAP_FILTER_PRESENT:
771 fstr->bv_len = f->f_desc->ad_cname.bv_len +
772 STRLENOF("(=*)");
773 if ( undef2 )
774 fstr->bv_len++;
775
776 fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx );
777
778 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s%s=*)",
779 undef2 ? "?" : "",
780 f->f_desc->ad_cname.bv_val );
781 break;
782
783 case LDAP_FILTER_AND:
784 case LDAP_FILTER_OR:
785 case LDAP_FILTER_NOT:
786 fstr->bv_len = STRLENOF("(%)");
787 fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 128, op->o_tmpmemctx );
788
789 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%c)",
790 f->f_choice == LDAP_FILTER_AND ? '&' :
791 f->f_choice == LDAP_FILTER_OR ? '|' : '!' );
792
793 for ( p = f->f_list; p != NULL; p = p->f_next ) {
794 len = fstr->bv_len;
795
796 filter2bv_undef_x( op, p, noundef, &tmp );
797
798 fstr->bv_len += tmp.bv_len;
799 fstr->bv_val = op->o_tmprealloc( fstr->bv_val, fstr->bv_len + 1,
800 op->o_tmpmemctx );
801
802 snprintf( &fstr->bv_val[len-1],
803 tmp.bv_len + STRLENOF( /*(*/ ")" ) + 1,
804 /*"("*/ "%s)", tmp.bv_val );
805
806 op->o_tmpfree( tmp.bv_val, op->o_tmpmemctx );
807 }
808
809 break;
810
811 case LDAP_FILTER_EXT: {
812 struct berval ad;
813
814 filter_escape_value_x( &f->f_mr_value, &tmp, op->o_tmpmemctx );
815 /* NOTE: tmp can legitimately be NULL (meaning empty)
816 * since in a Filter values in MRAs are supposed
817 * to have been normalized, meaning that an empty value
818 * is legal for that attribute's syntax */
819
820 if ( f->f_mr_desc ) {
821 ad = f->f_mr_desc->ad_cname;
822 } else {
823 ad.bv_len = 0;
824 ad.bv_val = "";
825 }
826
827 fstr->bv_len = ad.bv_len +
828 ( undef2 ? 1 : 0 ) +
829 ( f->f_mr_dnattrs ? STRLENOF(":dn") : 0 ) +
830 ( f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_len + STRLENOF(":") : 0 ) +
831 tmp.bv_len + STRLENOF("(:=)");
832 fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx );
833
834 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s%s%s%s%s:=%s)",
835 undef2 ? "?" : "",
836 ad.bv_val,
837 f->f_mr_dnattrs ? ":dn" : "",
838 f->f_mr_rule_text.bv_len ? ":" : "",
839 f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_val : "",
840 tmp.bv_len ? tmp.bv_val : "" );
841 ber_memfree_x( tmp.bv_val, op->o_tmpmemctx );
842 } break;
843
844 case SLAPD_FILTER_COMPUTED:
845 switch ( f->f_result ) {
846 case LDAP_COMPARE_FALSE:
847 tmp = ( noundef ? ber_bvF : ber_bvfalse );
848 break;
849
850 case LDAP_COMPARE_TRUE:
851 tmp = ( noundef ? ber_bvT : ber_bvtrue );
852 break;
853
854 case SLAPD_COMPARE_UNDEFINED:
855 tmp = ber_bvundefined;
856 break;
857
858 default:
859 tmp = ber_bverror;
860 break;
861 }
862
863 ber_dupbv_x( fstr, &tmp, op->o_tmpmemctx );
864 break;
865
866 default:
867 ber_dupbv_x( fstr, &ber_bvunknown, op->o_tmpmemctx );
868 break;
869 }
870 }
871
872 void
filter2bv(Filter * f,struct berval * fstr)873 filter2bv( Filter *f, struct berval *fstr )
874 {
875 filter2bv_undef( f, 0, fstr );
876 }
877
878 void
filter2bv_undef(Filter * f,int noundef,struct berval * fstr)879 filter2bv_undef( Filter *f, int noundef, struct berval *fstr )
880 {
881 Operation op;
882 Opheader ohdr;
883
884 op.o_hdr = &ohdr;
885 op.o_tmpmemctx = NULL;
886 op.o_tmpmfuncs = &ch_mfuncs;
887
888 filter2bv_undef_x( &op, f, noundef, fstr );
889 }
890
891 Filter *
filter_dup(Filter * f,void * memctx)892 filter_dup( Filter *f, void *memctx )
893 {
894 BerMemoryFunctions *mf = &slap_sl_mfuncs;
895 Filter *n;
896
897 if ( !f )
898 return NULL;
899
900 n = mf->bmf_malloc( sizeof(Filter), memctx );
901 n->f_choice = f->f_choice;
902 n->f_next = NULL;
903
904 switch( f->f_choice & SLAPD_FILTER_MASK ) {
905 case SLAPD_FILTER_COMPUTED:
906 n->f_result = f->f_result;
907 break;
908 case LDAP_FILTER_PRESENT:
909 if ( f->f_desc->ad_flags & SLAP_DESC_TEMPORARY )
910 n->f_desc = slap_bv2tmp_ad( &f->f_desc->ad_cname, memctx );
911 else
912 n->f_desc = f->f_desc;
913 break;
914 case LDAP_FILTER_EQUALITY:
915 case LDAP_FILTER_GE:
916 case LDAP_FILTER_LE:
917 case LDAP_FILTER_APPROX:
918 /* Should this be ava_dup() ? */
919 n->f_ava = mf->bmf_calloc( 1, sizeof(AttributeAssertion), memctx );
920 *n->f_ava = *f->f_ava;
921 if ( f->f_av_desc->ad_flags & SLAP_DESC_TEMPORARY )
922 n->f_av_desc = slap_bv2tmp_ad( &f->f_av_desc->ad_cname, memctx );
923 ber_dupbv_x( &n->f_av_value, &f->f_av_value, memctx );
924 break;
925 case LDAP_FILTER_SUBSTRINGS:
926 n->f_sub = mf->bmf_calloc( 1, sizeof(SubstringsAssertion), memctx );
927 if ( f->f_sub_desc->ad_flags & SLAP_DESC_TEMPORARY )
928 n->f_sub_desc = slap_bv2tmp_ad( &f->f_sub_desc->ad_cname, memctx );
929 else
930 n->f_sub_desc = f->f_sub_desc;
931 if ( !BER_BVISNULL( &f->f_sub_initial ))
932 ber_dupbv_x( &n->f_sub_initial, &f->f_sub_initial, memctx );
933 if ( f->f_sub_any ) {
934 int i;
935 for ( i = 0; !BER_BVISNULL( &f->f_sub_any[i] ); i++ );
936 n->f_sub_any = mf->bmf_malloc(( i+1 )*sizeof( struct berval ),
937 memctx );
938 for ( i = 0; !BER_BVISNULL( &f->f_sub_any[i] ); i++ ) {
939 ber_dupbv_x( &n->f_sub_any[i], &f->f_sub_any[i], memctx );
940 }
941 BER_BVZERO( &n->f_sub_any[i] );
942 }
943 if ( !BER_BVISNULL( &f->f_sub_final ))
944 ber_dupbv_x( &n->f_sub_final, &f->f_sub_final, memctx );
945 break;
946 case LDAP_FILTER_EXT: {
947 /* Should this be mra_dup() ? */
948 ber_len_t length;
949 length = sizeof(MatchingRuleAssertion);
950 if ( !BER_BVISNULL( &f->f_mr_rule_text ))
951 length += f->f_mr_rule_text.bv_len + 1;
952 n->f_mra = mf->bmf_calloc( 1, length, memctx );
953 *n->f_mra = *f->f_mra;
954 if ( f->f_mr_desc && ( f->f_sub_desc->ad_flags & SLAP_DESC_TEMPORARY ))
955 n->f_mr_desc = slap_bv2tmp_ad( &f->f_mr_desc->ad_cname, memctx );
956 ber_dupbv_x( &n->f_mr_value, &f->f_mr_value, memctx );
957 if ( !BER_BVISNULL( &f->f_mr_rule_text )) {
958 n->f_mr_rule_text.bv_val = (char *)(n->f_mra+1);
959 AC_MEMCPY(n->f_mr_rule_text.bv_val,
960 f->f_mr_rule_text.bv_val, f->f_mr_rule_text.bv_len );
961 }
962 } break;
963 case LDAP_FILTER_AND:
964 case LDAP_FILTER_OR:
965 case LDAP_FILTER_NOT: {
966 Filter **p;
967 for ( p = &n->f_list, f = f->f_list; f; f = f->f_next ) {
968 *p = filter_dup( f, memctx );
969 p = &(*p)->f_next;
970 }
971 } break;
972 }
973 return n;
974 }
975
976 static int
get_simple_vrFilter(Operation * op,BerElement * ber,ValuesReturnFilter ** filt,const char ** text)977 get_simple_vrFilter(
978 Operation *op,
979 BerElement *ber,
980 ValuesReturnFilter **filt,
981 const char **text )
982 {
983 ber_tag_t tag;
984 ber_len_t len;
985 int err;
986 ValuesReturnFilter vrf;
987
988 Debug( LDAP_DEBUG_FILTER, "begin get_simple_vrFilter\n" );
989
990 tag = ber_peek_tag( ber, &len );
991
992 if( tag == LBER_ERROR ) {
993 *text = "error decoding filter";
994 return SLAPD_DISCONNECT;
995 }
996
997 vrf.vrf_next = NULL;
998
999 err = LDAP_SUCCESS;
1000 vrf.vrf_choice = tag;
1001
1002 switch ( vrf.vrf_choice ) {
1003 case LDAP_FILTER_EQUALITY:
1004 Debug( LDAP_DEBUG_FILTER, "EQUALITY\n" );
1005 err = get_ava( op, ber, (Filter *)&vrf, SLAP_MR_EQUALITY, text );
1006 if ( err != LDAP_SUCCESS ) {
1007 break;
1008 }
1009
1010 assert( vrf.vrf_ava != NULL );
1011 break;
1012
1013 case LDAP_FILTER_SUBSTRINGS:
1014 Debug( LDAP_DEBUG_FILTER, "SUBSTRINGS\n" );
1015 err = get_ssa( op, ber, (Filter *)&vrf, text );
1016 break;
1017
1018 case LDAP_FILTER_GE:
1019 Debug( LDAP_DEBUG_FILTER, "GE\n" );
1020 err = get_ava( op, ber, (Filter *)&vrf, SLAP_MR_ORDERING, text );
1021 if ( err != LDAP_SUCCESS ) {
1022 break;
1023 }
1024 break;
1025
1026 case LDAP_FILTER_LE:
1027 Debug( LDAP_DEBUG_FILTER, "LE\n" );
1028 err = get_ava( op, ber, (Filter *)&vrf, SLAP_MR_ORDERING, text );
1029 if ( err != LDAP_SUCCESS ) {
1030 break;
1031 }
1032 break;
1033
1034 case LDAP_FILTER_PRESENT: {
1035 struct berval type;
1036
1037 Debug( LDAP_DEBUG_FILTER, "PRESENT\n" );
1038 if ( ber_scanf( ber, "m", &type ) == LBER_ERROR ) {
1039 err = SLAPD_DISCONNECT;
1040 *text = "error decoding filter";
1041 break;
1042 }
1043
1044 vrf.vrf_desc = NULL;
1045 err = slap_bv2ad( &type, &vrf.vrf_desc, text );
1046
1047 if( err != LDAP_SUCCESS ) {
1048 vrf.vrf_choice |= SLAPD_FILTER_UNDEFINED;
1049 err = slap_bv2undef_ad( &type, &vrf.vrf_desc, text,
1050 SLAP_AD_PROXIED);
1051
1052 if( err != LDAP_SUCCESS ) {
1053 /* unrecognized attribute description or other error */
1054 Debug( LDAP_DEBUG_ANY,
1055 "get_simple_vrFilter: conn %lu unknown "
1056 "attribute type=%s (%d)\n",
1057 op->o_connid, type.bv_val, err );
1058
1059 vrf.vrf_choice = SLAPD_FILTER_COMPUTED;
1060 vrf.vrf_result = LDAP_COMPARE_FALSE;
1061 err = LDAP_SUCCESS;
1062 break;
1063 }
1064 }
1065 } break;
1066
1067 case LDAP_FILTER_APPROX:
1068 Debug( LDAP_DEBUG_FILTER, "APPROX\n" );
1069 err = get_ava( op, ber, (Filter *)&vrf, SLAP_MR_EQUALITY_APPROX, text );
1070 if ( err != LDAP_SUCCESS ) {
1071 break;
1072 }
1073 break;
1074
1075 case LDAP_FILTER_EXT:
1076 Debug( LDAP_DEBUG_FILTER, "EXTENSIBLE\n" );
1077
1078 err = get_mra( op, ber, (Filter *)&vrf, text );
1079 if ( err != LDAP_SUCCESS ) {
1080 break;
1081 }
1082
1083 assert( vrf.vrf_mra != NULL );
1084 break;
1085
1086 default:
1087 (void) ber_scanf( ber, "x" ); /* skip the element */
1088 Debug( LDAP_DEBUG_ANY, "get_simple_vrFilter: unknown filter type=%lu\n",
1089 vrf.vrf_choice );
1090 vrf.vrf_choice = SLAPD_FILTER_COMPUTED;
1091 vrf.vrf_result = SLAPD_COMPARE_UNDEFINED;
1092 break;
1093 }
1094
1095 if ( err != LDAP_SUCCESS && err != SLAPD_DISCONNECT ) {
1096 /* ignore error */
1097 vrf.vrf_choice = SLAPD_FILTER_COMPUTED;
1098 vrf.vrf_result = SLAPD_COMPARE_UNDEFINED;
1099 err = LDAP_SUCCESS;
1100 }
1101
1102 if ( err == LDAP_SUCCESS ) {
1103 *filt = op->o_tmpalloc( sizeof vrf, op->o_tmpmemctx );
1104 **filt = vrf;
1105 }
1106
1107 Debug( LDAP_DEBUG_FILTER, "end get_simple_vrFilter %d\n", err );
1108
1109 return err;
1110 }
1111
1112 int
get_vrFilter(Operation * op,BerElement * ber,ValuesReturnFilter ** vrf,const char ** text)1113 get_vrFilter( Operation *op, BerElement *ber,
1114 ValuesReturnFilter **vrf,
1115 const char **text )
1116 {
1117 /*
1118 * A ValuesReturnFilter looks like this:
1119 *
1120 * ValuesReturnFilter ::= SEQUENCE OF SimpleFilterItem
1121 * SimpleFilterItem ::= CHOICE {
1122 * equalityMatch [3] AttributeValueAssertion,
1123 * substrings [4] SubstringFilter,
1124 * greaterOrEqual [5] AttributeValueAssertion,
1125 * lessOrEqual [6] AttributeValueAssertion,
1126 * present [7] AttributeType,
1127 * approxMatch [8] AttributeValueAssertion,
1128 * extensibleMatch [9] SimpleMatchingAssertion -- LDAPv3
1129 * }
1130 *
1131 * SubstringFilter ::= SEQUENCE {
1132 * type AttributeType,
1133 * SEQUENCE OF CHOICE {
1134 * initial [0] IA5String,
1135 * any [1] IA5String,
1136 * final [2] IA5String
1137 * }
1138 * }
1139 *
1140 * SimpleMatchingAssertion ::= SEQUENCE { -- LDAPv3
1141 * matchingRule [1] MatchingRuleId OPTIONAL,
1142 * type [2] AttributeDescription OPTIONAL,
1143 * matchValue [3] AssertionValue }
1144 */
1145
1146 ValuesReturnFilter **n;
1147 ber_tag_t tag;
1148 ber_len_t len;
1149 char *last;
1150
1151 Debug( LDAP_DEBUG_FILTER, "begin get_vrFilter\n" );
1152
1153 tag = ber_peek_tag( ber, &len );
1154
1155 if( tag == LBER_ERROR ) {
1156 *text = "error decoding vrFilter";
1157 return SLAPD_DISCONNECT;
1158 }
1159
1160 if( tag != LBER_SEQUENCE ) {
1161 *text = "error decoding vrFilter, expect SEQUENCE tag";
1162 return SLAPD_DISCONNECT;
1163 }
1164
1165 n = vrf;
1166 for ( tag = ber_first_element( ber, &len, &last );
1167 tag != LBER_DEFAULT;
1168 tag = ber_next_element( ber, &len, last ) )
1169 {
1170 int err = get_simple_vrFilter( op, ber, n, text );
1171
1172 if ( err != LDAP_SUCCESS ) return( err );
1173
1174 n = &(*n)->vrf_next;
1175 }
1176 *n = NULL;
1177
1178 Debug( LDAP_DEBUG_FILTER, "end get_vrFilter\n" );
1179 return( LDAP_SUCCESS );
1180 }
1181
1182 void
vrFilter_free(Operation * op,ValuesReturnFilter * vrf)1183 vrFilter_free( Operation *op, ValuesReturnFilter *vrf )
1184 {
1185 ValuesReturnFilter *next;
1186
1187 for ( ; vrf != NULL; vrf = next ) {
1188 next = vrf->vrf_next;
1189
1190 switch ( vrf->vrf_choice & SLAPD_FILTER_MASK ) {
1191 case LDAP_FILTER_PRESENT:
1192 break;
1193
1194 case LDAP_FILTER_EQUALITY:
1195 case LDAP_FILTER_GE:
1196 case LDAP_FILTER_LE:
1197 case LDAP_FILTER_APPROX:
1198 ava_free( op, vrf->vrf_ava, 1 );
1199 break;
1200
1201 case LDAP_FILTER_SUBSTRINGS:
1202 if ( vrf->vrf_sub_initial.bv_val != NULL ) {
1203 op->o_tmpfree( vrf->vrf_sub_initial.bv_val, op->o_tmpmemctx );
1204 }
1205 ber_bvarray_free_x( vrf->vrf_sub_any, op->o_tmpmemctx );
1206 if ( vrf->vrf_sub_final.bv_val != NULL ) {
1207 op->o_tmpfree( vrf->vrf_sub_final.bv_val, op->o_tmpmemctx );
1208 }
1209 op->o_tmpfree( vrf->vrf_sub, op->o_tmpmemctx );
1210 break;
1211
1212 case LDAP_FILTER_EXT:
1213 mra_free( op, vrf->vrf_mra, 1 );
1214 break;
1215
1216 case SLAPD_FILTER_COMPUTED:
1217 break;
1218
1219 default:
1220 Debug( LDAP_DEBUG_ANY, "filter_free: unknown filter type=%lu\n",
1221 vrf->vrf_choice );
1222 break;
1223 }
1224
1225 op->o_tmpfree( vrf, op->o_tmpmemctx );
1226 }
1227 }
1228
1229 void
vrFilter2bv(Operation * op,ValuesReturnFilter * vrf,struct berval * fstr)1230 vrFilter2bv( Operation *op, ValuesReturnFilter *vrf, struct berval *fstr )
1231 {
1232 ValuesReturnFilter *p;
1233 struct berval tmp;
1234 ber_len_t len;
1235
1236 if ( vrf == NULL ) {
1237 ber_str2bv_x( "No filter!", STRLENOF("No filter!"),
1238 1, fstr, op->o_tmpmemctx );
1239 return;
1240 }
1241
1242 fstr->bv_len = STRLENOF("()");
1243 fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 128, op->o_tmpmemctx );
1244
1245 snprintf( fstr->bv_val, fstr->bv_len + 1, "()");
1246
1247 for ( p = vrf; p != NULL; p = p->vrf_next ) {
1248 len = fstr->bv_len;
1249
1250 simple_vrFilter2bv( op, p, &tmp );
1251
1252 fstr->bv_len += tmp.bv_len;
1253 fstr->bv_val = op->o_tmprealloc( fstr->bv_val, fstr->bv_len + 1,
1254 op->o_tmpmemctx );
1255
1256 snprintf( &fstr->bv_val[len-1], tmp.bv_len + 2,
1257 /*"("*/ "%s)", tmp.bv_val );
1258
1259 op->o_tmpfree( tmp.bv_val, op->o_tmpmemctx );
1260 }
1261 }
1262
1263 static void
simple_vrFilter2bv(Operation * op,ValuesReturnFilter * vrf,struct berval * fstr)1264 simple_vrFilter2bv( Operation *op, ValuesReturnFilter *vrf, struct berval *fstr )
1265 {
1266 struct berval tmp;
1267 ber_len_t len;
1268 int undef;
1269
1270 if ( vrf == NULL ) {
1271 ber_str2bv_x( "No filter!", STRLENOF("No filter!"), 1, fstr,
1272 op->o_tmpmemctx );
1273 return;
1274 }
1275 undef = vrf->vrf_choice & SLAPD_FILTER_UNDEFINED;
1276
1277 switch ( vrf->vrf_choice & SLAPD_FILTER_MASK ) {
1278 case LDAP_FILTER_EQUALITY:
1279 filter_escape_value_x( &vrf->vrf_av_value, &tmp, op->o_tmpmemctx );
1280
1281 fstr->bv_len = vrf->vrf_av_desc->ad_cname.bv_len +
1282 tmp.bv_len + STRLENOF("(=)");
1283 if ( undef ) fstr->bv_len++;
1284 fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx );
1285
1286 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=%s)",
1287 vrf->vrf_av_desc->ad_cname.bv_val,
1288 tmp.bv_val );
1289
1290 ber_memfree_x( tmp.bv_val, op->o_tmpmemctx );
1291 break;
1292
1293 case LDAP_FILTER_GE:
1294 filter_escape_value_x( &vrf->vrf_av_value, &tmp, op->o_tmpmemctx );
1295
1296 fstr->bv_len = vrf->vrf_av_desc->ad_cname.bv_len +
1297 tmp.bv_len + STRLENOF("(>=)");
1298 if ( undef ) fstr->bv_len++;
1299 fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx );
1300
1301 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s>=%s)",
1302 vrf->vrf_av_desc->ad_cname.bv_val,
1303 tmp.bv_val );
1304
1305 ber_memfree_x( tmp.bv_val, op->o_tmpmemctx );
1306 break;
1307
1308 case LDAP_FILTER_LE:
1309 filter_escape_value_x( &vrf->vrf_av_value, &tmp, op->o_tmpmemctx );
1310
1311 fstr->bv_len = vrf->vrf_av_desc->ad_cname.bv_len +
1312 tmp.bv_len + STRLENOF("(<=)");
1313 if ( undef ) fstr->bv_len++;
1314 fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx );
1315
1316 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s<=%s)",
1317 vrf->vrf_av_desc->ad_cname.bv_val,
1318 tmp.bv_val );
1319
1320 ber_memfree_x( tmp.bv_val, op->o_tmpmemctx );
1321 break;
1322
1323 case LDAP_FILTER_APPROX:
1324 filter_escape_value_x( &vrf->vrf_av_value, &tmp, op->o_tmpmemctx );
1325
1326 fstr->bv_len = vrf->vrf_av_desc->ad_cname.bv_len +
1327 tmp.bv_len + STRLENOF("(~=)");
1328 if ( undef ) fstr->bv_len++;
1329 fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx );
1330
1331 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s~=%s)",
1332 vrf->vrf_av_desc->ad_cname.bv_val,
1333 tmp.bv_val );
1334 ber_memfree_x( tmp.bv_val, op->o_tmpmemctx );
1335 break;
1336
1337 case LDAP_FILTER_SUBSTRINGS:
1338 fstr->bv_len = vrf->vrf_sub_desc->ad_cname.bv_len +
1339 STRLENOF("(=*)");
1340 if ( undef ) fstr->bv_len++;
1341 fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 128, op->o_tmpmemctx );
1342
1343 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=*)",
1344 vrf->vrf_sub_desc->ad_cname.bv_val );
1345
1346 if ( vrf->vrf_sub_initial.bv_val != NULL ) {
1347 len = fstr->bv_len;
1348
1349 filter_escape_value_x( &vrf->vrf_sub_initial, &tmp, op->o_tmpmemctx );
1350
1351 fstr->bv_len += tmp.bv_len;
1352 fstr->bv_val = op->o_tmprealloc( fstr->bv_val, fstr->bv_len + 1,
1353 op->o_tmpmemctx );
1354
1355 snprintf( &fstr->bv_val[len-2], tmp.bv_len+3,
1356 /* "(attr=" */ "%s*)",
1357 tmp.bv_val );
1358
1359 ber_memfree_x( tmp.bv_val, op->o_tmpmemctx );
1360 }
1361
1362 if ( vrf->vrf_sub_any != NULL ) {
1363 int i;
1364 for ( i = 0; vrf->vrf_sub_any[i].bv_val != NULL; i++ ) {
1365 len = fstr->bv_len;
1366 filter_escape_value_x( &vrf->vrf_sub_any[i], &tmp,
1367 op->o_tmpmemctx );
1368
1369 fstr->bv_len += tmp.bv_len + 1;
1370 fstr->bv_val = op->o_tmprealloc( fstr->bv_val,
1371 fstr->bv_len + 1, op->o_tmpmemctx );
1372
1373 snprintf( &fstr->bv_val[len-1], tmp.bv_len+3,
1374 /* "(attr=[init]*[any*]" */ "%s*)",
1375 tmp.bv_val );
1376 ber_memfree_x( tmp.bv_val, op->o_tmpmemctx );
1377 }
1378 }
1379
1380 if ( vrf->vrf_sub_final.bv_val != NULL ) {
1381 len = fstr->bv_len;
1382
1383 filter_escape_value_x( &vrf->vrf_sub_final, &tmp, op->o_tmpmemctx );
1384
1385 fstr->bv_len += tmp.bv_len;
1386 fstr->bv_val = op->o_tmprealloc( fstr->bv_val, fstr->bv_len + 1,
1387 op->o_tmpmemctx );
1388
1389 snprintf( &fstr->bv_val[len-1], tmp.bv_len+3,
1390 /* "(attr=[init*][any*]" */ "%s)",
1391 tmp.bv_val );
1392
1393 ber_memfree_x( tmp.bv_val, op->o_tmpmemctx );
1394 }
1395
1396 break;
1397
1398 case LDAP_FILTER_PRESENT:
1399 fstr->bv_len = vrf->vrf_desc->ad_cname.bv_len +
1400 STRLENOF("(=*)");
1401 if ( undef ) fstr->bv_len++;
1402 fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx );
1403
1404 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=*)",
1405 vrf->vrf_desc->ad_cname.bv_val );
1406 break;
1407
1408 case LDAP_FILTER_EXT: {
1409 struct berval ad;
1410 filter_escape_value_x( &vrf->vrf_mr_value, &tmp, op->o_tmpmemctx );
1411
1412 if ( vrf->vrf_mr_desc ) {
1413 ad = vrf->vrf_mr_desc->ad_cname;
1414 } else {
1415 ad.bv_len = 0;
1416 ad.bv_val = "";
1417 }
1418
1419 fstr->bv_len = ad.bv_len +
1420 ( vrf->vrf_mr_dnattrs ? STRLENOF(":dn") : 0 ) +
1421 ( vrf->vrf_mr_rule_text.bv_len
1422 ? vrf->vrf_mr_rule_text.bv_len+1 : 0 ) +
1423 tmp.bv_len + STRLENOF("(:=)");
1424 if ( undef ) fstr->bv_len++;
1425 fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx );
1426
1427 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s%s%s%s:=%s)",
1428 ad.bv_val,
1429 vrf->vrf_mr_dnattrs ? ":dn" : "",
1430 vrf->vrf_mr_rule_text.bv_len ? ":" : "",
1431 vrf->vrf_mr_rule_text.bv_len ? vrf->vrf_mr_rule_text.bv_val : "",
1432 tmp.bv_val );
1433
1434 ber_memfree_x( tmp.bv_val, op->o_tmpmemctx );
1435 } break;
1436
1437 case SLAPD_FILTER_COMPUTED:
1438 ber_str2bv_x(
1439 vrf->vrf_result == LDAP_COMPARE_FALSE ? "(?=false)" :
1440 vrf->vrf_result == LDAP_COMPARE_TRUE ? "(?=true)" :
1441 vrf->vrf_result == SLAPD_COMPARE_UNDEFINED
1442 ? "(?=undefined)" : "(?=error)",
1443 vrf->vrf_result == LDAP_COMPARE_FALSE ? STRLENOF("(?=false)") :
1444 vrf->vrf_result == LDAP_COMPARE_TRUE ? STRLENOF("(?=true)") :
1445 vrf->vrf_result == SLAPD_COMPARE_UNDEFINED
1446 ? STRLENOF("(?=undefined)") : STRLENOF("(?=error)"),
1447 1, fstr, op->o_tmpmemctx );
1448 break;
1449
1450 default:
1451 ber_str2bv_x( "(?=unknown)", STRLENOF("(?=unknown)"),
1452 1, fstr, op->o_tmpmemctx );
1453 break;
1454 }
1455 }
1456