1 /* component.c -- Component Filter Match Routines */
2 /* $OpenLDAP$ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 *
5 * Copyright 2003-2021 The OpenLDAP Foundation.
6 * Portions Copyright 2004 by IBM Corporation.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted only as authorized by the OpenLDAP
11 * Public License.
12 *
13 * A copy of this license is available in the file LICENSE in the
14 * top-level directory of the distribution or, alternatively, at
15 * <http://www.OpenLDAP.org/license.html>.
16 */
17
18 #include "portable.h"
19
20 #include <ac/string.h>
21 #include <ac/socket.h>
22
23 #include "lutil.h"
24 #include <ldap.h>
25 #include "slap.h"
26
27 #ifdef LDAP_COMP_MATCH
28
29 #include "component.h"
30
31 /*
32 * Following function pointers are initialized
33 * when a component module is loaded
34 */
35 alloc_nibble_func* nibble_mem_allocator = NULL;
36 free_nibble_func* nibble_mem_free = NULL;
37 convert_attr_to_comp_func* attr_converter = NULL;
38 convert_assert_to_comp_func* assert_converter = NULL ;
39 free_component_func* component_destructor = NULL ;
40 test_component_func* test_components = NULL;
41 test_membership_func* is_aliased_attribute = NULL;
42 component_encoder_func* component_encoder = NULL;
43 get_component_info_func* get_component_description = NULL;
44 #define OID_ALL_COMP_MATCH "1.2.36.79672281.1.13.6"
45 #define OID_COMP_FILTER_MATCH "1.2.36.79672281.1.13.2"
46 #define MAX_LDAP_STR_LEN 128
47
48 static int
49 peek_componentId_type( ComponentAssertionValue* cav );
50
51 static int
52 strip_cav_str( ComponentAssertionValue* cav, char* str);
53
54 static int
55 peek_cav_str( ComponentAssertionValue* cav, char* str );
56
57 static int
58 parse_comp_filter( Operation* op, ComponentAssertionValue* cav,
59 ComponentFilter** filt, const char** text );
60
61 static void
62 free_comp_filter( ComponentFilter* f );
63
64 static int
65 test_comp_filter( Syntax *syn, ComponentSyntaxInfo *a, ComponentFilter *f );
66
67 int
componentCertificateValidate(Syntax * syntax,struct berval * val)68 componentCertificateValidate(
69 Syntax *syntax,
70 struct berval *val )
71 {
72 return LDAP_SUCCESS;
73 }
74
75 int
componentFilterValidate(Syntax * syntax,struct berval * val)76 componentFilterValidate(
77 Syntax *syntax,
78 struct berval *val )
79 {
80 return LDAP_SUCCESS;
81 }
82
83 int
allComponentsValidate(Syntax * syntax,struct berval * val)84 allComponentsValidate(
85 Syntax *syntax,
86 struct berval *val )
87 {
88 return LDAP_SUCCESS;
89 }
90
91 int
componentFilterMatch(int * matchp,slap_mask_t flags,Syntax * syntax,MatchingRule * mr,struct berval * value,void * assertedValue)92 componentFilterMatch (
93 int *matchp,
94 slap_mask_t flags,
95 Syntax *syntax,
96 MatchingRule *mr,
97 struct berval *value,
98 void *assertedValue )
99 {
100 ComponentSyntaxInfo *csi_attr = (ComponentSyntaxInfo*)value;
101 MatchingRuleAssertion * ma = (MatchingRuleAssertion*)assertedValue;
102 int rc;
103
104 if ( !mr || !ma->ma_cf ) return LDAP_INAPPROPRIATE_MATCHING;
105
106 /* Check if the component module is loaded */
107 if ( !attr_converter || !nibble_mem_allocator ) {
108 return LDAP_OTHER;
109 }
110
111 rc = test_comp_filter( syntax, csi_attr, ma->ma_cf );
112
113 if ( rc == LDAP_COMPARE_TRUE ) {
114 *matchp = 0;
115 return LDAP_SUCCESS;
116 }
117 else if ( rc == LDAP_COMPARE_FALSE ) {
118 *matchp = 1;
119 return LDAP_SUCCESS;
120 }
121 else {
122 return LDAP_INAPPROPRIATE_MATCHING;
123 }
124 }
125
126 int
directoryComponentsMatch(int * matchp,slap_mask_t flags,Syntax * syntax,MatchingRule * mr,struct berval * value,void * assertedValue)127 directoryComponentsMatch(
128 int *matchp,
129 slap_mask_t flags,
130 Syntax *syntax,
131 MatchingRule *mr,
132 struct berval *value,
133 void *assertedValue )
134 {
135 /* Only for registration */
136 *matchp = 0;
137 return LDAP_SUCCESS;
138 }
139
140 int
allComponentsMatch(int * matchp,slap_mask_t flags,Syntax * syntax,MatchingRule * mr,struct berval * value,void * assertedValue)141 allComponentsMatch(
142 int *matchp,
143 slap_mask_t flags,
144 Syntax *syntax,
145 MatchingRule *mr,
146 struct berval *value,
147 void *assertedValue )
148 {
149 /* Only for registration */
150 *matchp = 0;
151 return LDAP_SUCCESS;
152 }
153
154 static int
slapd_ber2cav(struct berval * bv,ComponentAssertionValue * cav)155 slapd_ber2cav( struct berval* bv, ComponentAssertionValue* cav )
156 {
157 cav->cav_ptr = cav->cav_buf = bv->bv_val;
158 cav->cav_end = bv->bv_val + bv->bv_len;
159
160 return LDAP_SUCCESS;
161 }
162
163 ComponentReference*
dup_comp_ref(Operation * op,ComponentReference * cr)164 dup_comp_ref ( Operation* op, ComponentReference* cr )
165 {
166 ComponentReference* dup_cr;
167 ComponentId* ci_curr;
168 ComponentId** ci_temp;
169
170 dup_cr = op->o_tmpalloc( sizeof( ComponentReference ), op->o_tmpmemctx );
171
172 dup_cr->cr_len = cr->cr_len;
173 dup_cr->cr_string = cr->cr_string;
174
175 ci_temp = &dup_cr->cr_list;
176 ci_curr = cr->cr_list;
177
178 for ( ; ci_curr != NULL ;
179 ci_curr = ci_curr->ci_next, ci_temp = &(*ci_temp)->ci_next )
180 {
181 *ci_temp = op->o_tmpalloc( sizeof( ComponentId ), op->o_tmpmemctx );
182 if ( !*ci_temp ) return NULL;
183 **ci_temp = *ci_curr;
184 }
185
186 dup_cr->cr_curr = dup_cr->cr_list;
187
188 return dup_cr;
189 }
190
191 static int
dup_comp_filter_list(Operation * op,struct berval * bv,ComponentFilter * in_f,ComponentFilter ** out_f)192 dup_comp_filter_list (
193 Operation *op,
194 struct berval *bv,
195 ComponentFilter* in_f,
196 ComponentFilter** out_f )
197 {
198 ComponentFilter **new, *f;
199 int rc;
200
201 new = out_f;
202 for ( f = in_f; f != NULL; f = f->cf_next ) {
203 rc = dup_comp_filter( op, bv, f, new );
204 if ( rc != LDAP_SUCCESS ) {
205 return rc;
206 }
207 new = &(*new)->cf_next;
208 }
209 return LDAP_SUCCESS;
210 }
211
212 int
get_len_of_next_assert_value(struct berval * bv,char separator)213 get_len_of_next_assert_value ( struct berval* bv, char separator )
214 {
215 ber_len_t i = 0;
216 while (1) {
217 if ( (bv->bv_val[ i ] == separator) || ( i >= bv->bv_len) )
218 break;
219 i++;
220 }
221 bv->bv_val += (i + 1);
222 bv->bv_len -= (i + 1);
223 return i;
224 }
225
226 int
dup_comp_filter_item(Operation * op,struct berval * assert_bv,ComponentAssertion * in_ca,ComponentAssertion ** out_ca)227 dup_comp_filter_item (
228 Operation *op,
229 struct berval* assert_bv,
230 ComponentAssertion* in_ca,
231 ComponentAssertion** out_ca )
232 {
233 int len;
234
235 if ( !in_ca->ca_comp_ref ) return SLAPD_DISCONNECT;
236
237 *out_ca = op->o_tmpalloc( sizeof( ComponentAssertion ), op->o_tmpmemctx );
238 if ( !(*out_ca) ) return LDAP_NO_MEMORY;
239
240 (*out_ca)->ca_comp_data.cd_tree = NULL;
241 (*out_ca)->ca_comp_data.cd_mem_op = NULL;
242
243 (*out_ca)->ca_comp_ref = dup_comp_ref ( op, in_ca->ca_comp_ref );
244 (*out_ca)->ca_use_def = 0;
245 (*out_ca)->ca_ma_rule = in_ca->ca_ma_rule;
246
247 (*out_ca)->ca_ma_value.bv_val = assert_bv->bv_val;
248 len = get_len_of_next_assert_value ( assert_bv, '$' );
249 if ( len <= 0 ) return SLAPD_DISCONNECT;
250 (*out_ca)->ca_ma_value.bv_len = len;
251
252 return LDAP_SUCCESS;
253 }
254
255 int
dup_comp_filter(Operation * op,struct berval * bv,ComponentFilter * in_f,ComponentFilter ** out_f)256 dup_comp_filter (
257 Operation* op,
258 struct berval *bv,
259 ComponentFilter *in_f,
260 ComponentFilter **out_f )
261 {
262 int rc;
263 ComponentFilter dup_f = {0};
264
265 if ( !in_f ) return LDAP_PROTOCOL_ERROR;
266
267 switch ( in_f->cf_choice ) {
268 case LDAP_COMP_FILTER_AND:
269 rc = dup_comp_filter_list( op, bv, in_f->cf_and, &dup_f.cf_and);
270 dup_f.cf_choice = LDAP_COMP_FILTER_AND;
271 break;
272 case LDAP_COMP_FILTER_OR:
273 rc = dup_comp_filter_list( op, bv, in_f->cf_or, &dup_f.cf_or);
274 dup_f.cf_choice = LDAP_COMP_FILTER_OR;
275 break;
276 case LDAP_COMP_FILTER_NOT:
277 rc = dup_comp_filter( op, bv, in_f->cf_not, &dup_f.cf_not);
278 dup_f.cf_choice = LDAP_COMP_FILTER_NOT;
279 break;
280 case LDAP_COMP_FILTER_ITEM:
281 rc = dup_comp_filter_item( op, bv, in_f->cf_ca ,&dup_f.cf_ca );
282 dup_f.cf_choice = LDAP_COMP_FILTER_ITEM;
283 break;
284 default:
285 rc = LDAP_PROTOCOL_ERROR;
286 }
287
288 if ( rc == LDAP_SUCCESS ) {
289 *out_f = op->o_tmpalloc( sizeof(dup_f), op->o_tmpmemctx );
290 **out_f = dup_f;
291 }
292
293 return( rc );
294 }
295
296 int
get_aliased_filter_aa(Operation * op,AttributeAssertion * a_assert,AttributeAliasing * aa,const char ** text)297 get_aliased_filter_aa ( Operation* op, AttributeAssertion* a_assert, AttributeAliasing* aa, const char** text )
298 {
299 struct berval assert_bv;
300
301 Debug( LDAP_DEBUG_FILTER, "get_aliased_filter\n" );
302
303 if ( !aa->aa_cf )
304 return LDAP_PROTOCOL_ERROR;
305
306 assert_bv = a_assert->aa_value;
307 /*
308 * Duplicate aa->aa_cf to ma->ma_cf by replacing the
309 * the component assertion value in assert_bv
310 * Multiple values may be separated with '$'
311 */
312 return dup_comp_filter ( op, &assert_bv, aa->aa_cf, &a_assert->aa_cf );
313 }
314
315 int
get_aliased_filter(Operation * op,MatchingRuleAssertion * ma,AttributeAliasing * aa,const char ** text)316 get_aliased_filter( Operation* op,
317 MatchingRuleAssertion* ma, AttributeAliasing* aa,
318 const char** text )
319 {
320 struct berval assert_bv;
321
322 Debug( LDAP_DEBUG_FILTER, "get_aliased_filter\n" );
323
324 if ( !aa->aa_cf ) return LDAP_PROTOCOL_ERROR;
325
326 assert_bv = ma->ma_value;
327 /* Attribute Description is replaced with aliased one */
328 ma->ma_desc = aa->aa_aliased_ad;
329 ma->ma_rule = aa->aa_mr;
330 /*
331 * Duplicate aa->aa_cf to ma->ma_cf by replacing the
332 * the component assertion value in assert_bv
333 * Multiple values may be separated with '$'
334 */
335 return dup_comp_filter ( op, &assert_bv, aa->aa_cf, &ma->ma_cf );
336 }
337
338 int
get_comp_filter(Operation * op,struct berval * bv,ComponentFilter ** filt,const char ** text)339 get_comp_filter( Operation* op, struct berval* bv,
340 ComponentFilter** filt, const char **text )
341 {
342 ComponentAssertionValue cav;
343 int rc;
344
345 Debug( LDAP_DEBUG_FILTER, "get_comp_filter\n" );
346 if ( (rc = slapd_ber2cav(bv, &cav) ) != LDAP_SUCCESS ) {
347 return rc;
348 }
349 rc = parse_comp_filter( op, &cav, filt, text );
350 /* bv->bv_val = cav.cav_ptr; */
351
352 return rc;
353 }
354
355 static void
eat_whsp(ComponentAssertionValue * cav)356 eat_whsp( ComponentAssertionValue* cav )
357 {
358 for ( ; ( *cav->cav_ptr == ' ' ) && ( cav->cav_ptr < cav->cav_end ) ; ) {
359 cav->cav_ptr++;
360 }
361 }
362
363 static int
cav_cur_len(ComponentAssertionValue * cav)364 cav_cur_len( ComponentAssertionValue* cav )
365 {
366 return cav->cav_end - cav->cav_ptr;
367 }
368
369 static ber_tag_t
comp_first_element(ComponentAssertionValue * cav)370 comp_first_element( ComponentAssertionValue* cav )
371 {
372 eat_whsp( cav );
373 if ( cav_cur_len( cav ) >= 8 && strncmp( cav->cav_ptr, "item", 4 ) == 0 ) {
374 return LDAP_COMP_FILTER_ITEM;
375
376 } else if ( cav_cur_len( cav ) >= 7 &&
377 strncmp( cav->cav_ptr, "and", 3 ) == 0 )
378 {
379 return LDAP_COMP_FILTER_AND;
380
381 } else if ( cav_cur_len( cav ) >= 6 &&
382 strncmp( cav->cav_ptr, "or" , 2 ) == 0 )
383 {
384 return LDAP_COMP_FILTER_OR;
385
386 } else if ( cav_cur_len( cav ) >= 7 &&
387 strncmp( cav->cav_ptr, "not", 3 ) == 0 )
388 {
389 return LDAP_COMP_FILTER_NOT;
390
391 } else {
392 return LDAP_COMP_FILTER_UNDEFINED;
393 }
394 }
395
396 static ber_tag_t
comp_next_element(ComponentAssertionValue * cav)397 comp_next_element( ComponentAssertionValue* cav )
398 {
399 eat_whsp( cav );
400 if ( *(cav->cav_ptr) == ',' ) {
401 /* move pointer to the next CA */
402 cav->cav_ptr++;
403 return comp_first_element( cav );
404 }
405 else return LDAP_COMP_FILTER_UNDEFINED;
406 }
407
408 static int
get_comp_filter_list(Operation * op,ComponentAssertionValue * cav,ComponentFilter ** f,const char ** text)409 get_comp_filter_list( Operation *op, ComponentAssertionValue *cav,
410 ComponentFilter** f, const char** text )
411 {
412 ComponentFilter **new;
413 int err;
414 ber_tag_t tag;
415
416 Debug( LDAP_DEBUG_FILTER, "get_comp_filter_list\n" );
417 new = f;
418 for ( tag = comp_first_element( cav );
419 tag != LDAP_COMP_FILTER_UNDEFINED;
420 tag = comp_next_element( cav ) )
421 {
422 err = parse_comp_filter( op, cav, new, text );
423 if ( err != LDAP_SUCCESS ) return ( err );
424 new = &(*new)->cf_next;
425 }
426 *new = NULL;
427
428 return( LDAP_SUCCESS );
429 }
430
431 static int
get_componentId(Operation * op,ComponentAssertionValue * cav,ComponentId ** cid,const char ** text)432 get_componentId( Operation *op, ComponentAssertionValue* cav,
433 ComponentId ** cid, const char** text )
434 {
435 ber_tag_t type;
436 ComponentId _cid;
437 int len;
438
439 type = peek_componentId_type( cav );
440
441 Debug( LDAP_DEBUG_FILTER, "get_compId [%lu]\n",
442 (unsigned long) type );
443 len = 0;
444 _cid.ci_type = type;
445 _cid.ci_next = NULL;
446 switch ( type ) {
447 case LDAP_COMPREF_IDENTIFIER :
448 _cid.ci_val.ci_identifier.bv_val = cav->cav_ptr;
449 for( ;cav->cav_ptr[len] != ' ' && cav->cav_ptr[len] != '\0' &&
450 cav->cav_ptr[len] != '.' && cav->cav_ptr[len] != '\"' ; len++ );
451 _cid.ci_val.ci_identifier.bv_len = len;
452 cav->cav_ptr += len;
453 break;
454 case LDAP_COMPREF_FROM_BEGINNING :
455 for( ;cav->cav_ptr[len] != ' ' && cav->cav_ptr[len] != '\0' &&
456 cav->cav_ptr[len] != '.' && cav->cav_ptr[len] != '\"' ; len++ );
457 _cid.ci_val.ci_from_beginning = strtol( cav->cav_ptr, NULL, 0 );
458 cav->cav_ptr += len;
459 break;
460 case LDAP_COMPREF_FROM_END :
461 for( ;cav->cav_ptr[len] != ' ' && cav->cav_ptr[len] != '\0' &&
462 cav->cav_ptr[len] != '.' && cav->cav_ptr[len] != '\"' ; len++ );
463 _cid.ci_val.ci_from_end = strtol( cav->cav_ptr, NULL, 0 );
464 cav->cav_ptr += len;
465 break;
466 case LDAP_COMPREF_COUNT :
467 _cid.ci_val.ci_count = 0;
468 cav->cav_ptr++;
469 break;
470 case LDAP_COMPREF_CONTENT :
471 _cid.ci_val.ci_content = 1;
472 cav->cav_ptr += strlen("content");
473 break;
474 case LDAP_COMPREF_SELECT :
475 if ( cav->cav_ptr[len] != '(' ) return LDAP_COMPREF_UNDEFINED;
476 for( ;cav->cav_ptr[len] != ' ' && cav->cav_ptr[len] != '\0' &&
477 cav->cav_ptr[len] != '\"' && cav->cav_ptr[len] != ')'
478 ; len++ );
479 _cid.ci_val.ci_select_value.bv_val = cav->cav_ptr + 1;
480 _cid.ci_val.ci_select_value.bv_len = len - 1 ;
481 cav->cav_ptr += len + 1;
482 break;
483 case LDAP_COMPREF_ALL :
484 _cid.ci_val.ci_all = '*';
485 cav->cav_ptr++;
486 break;
487 default :
488 return LDAP_COMPREF_UNDEFINED;
489 }
490
491 if ( op ) {
492 *cid = op->o_tmpalloc( sizeof( ComponentId ), op->o_tmpmemctx );
493 } else {
494 *cid = SLAP_MALLOC( sizeof( ComponentId ) );
495 }
496 if (*cid == NULL) {
497 return LDAP_NO_MEMORY;
498 }
499 **cid = _cid;
500 return LDAP_SUCCESS;
501 }
502
503 static int
peek_componentId_type(ComponentAssertionValue * cav)504 peek_componentId_type( ComponentAssertionValue* cav )
505 {
506 eat_whsp( cav );
507
508 if ( cav->cav_ptr[0] == '-' ) {
509 return LDAP_COMPREF_FROM_END;
510
511 } else if ( cav->cav_ptr[0] == '(' ) {
512 return LDAP_COMPREF_SELECT;
513
514 } else if ( cav->cav_ptr[0] == '*' ) {
515 return LDAP_COMPREF_ALL;
516
517 } else if ( cav->cav_ptr[0] == '0' ) {
518 return LDAP_COMPREF_COUNT;
519
520 } else if ( cav->cav_ptr[0] > '0' && cav->cav_ptr[0] <= '9' ) {
521 return LDAP_COMPREF_FROM_BEGINNING;
522
523 } else if ( (cav->cav_end - cav->cav_ptr) >= 7 &&
524 strncmp(cav->cav_ptr,"content",7) == 0 )
525 {
526 return LDAP_COMPREF_CONTENT;
527 } else if ( (cav->cav_ptr[0] >= 'a' && cav->cav_ptr[0] <= 'z') ||
528 (cav->cav_ptr[0] >= 'A' && cav->cav_ptr[0] <= 'Z') )
529 {
530 return LDAP_COMPREF_IDENTIFIER;
531 }
532
533 return LDAP_COMPREF_UNDEFINED;
534 }
535
536 static ber_tag_t
comp_next_id(ComponentAssertionValue * cav)537 comp_next_id( ComponentAssertionValue* cav )
538 {
539 if ( *(cav->cav_ptr) == '.' ) {
540 cav->cav_ptr++;
541 return LDAP_COMPREF_DEFINED;
542 }
543
544 return LDAP_COMPREF_UNDEFINED;
545 }
546
547
548
549 static int
get_component_reference(Operation * op,ComponentAssertionValue * cav,ComponentReference ** cr,const char ** text)550 get_component_reference(
551 Operation *op,
552 ComponentAssertionValue* cav,
553 ComponentReference** cr,
554 const char** text )
555 {
556 int rc, count = 0;
557 ber_int_t type;
558 ComponentReference* ca_comp_ref;
559 ComponentId** cr_list;
560 char* start, *end;
561
562 eat_whsp( cav );
563
564 start = cav->cav_ptr;
565 if ( ( rc = strip_cav_str( cav,"\"") ) != LDAP_SUCCESS ) return rc;
566 if ( op ) {
567 ca_comp_ref = op->o_tmpalloc( sizeof( ComponentReference ),
568 op->o_tmpmemctx );
569 } else {
570 ca_comp_ref = SLAP_MALLOC( sizeof( ComponentReference ) );
571 }
572
573 if ( !ca_comp_ref ) return LDAP_NO_MEMORY;
574
575 cr_list = &ca_comp_ref->cr_list;
576
577 for ( type = peek_componentId_type( cav ) ; type != LDAP_COMPREF_UNDEFINED
578 ; type = comp_next_id( cav ), count++ )
579 {
580 rc = get_componentId( op, cav, cr_list, text );
581 if ( rc == LDAP_SUCCESS ) {
582 if ( count == 0 ) ca_comp_ref->cr_curr = ca_comp_ref->cr_list;
583 cr_list = &(*cr_list)->ci_next;
584
585 } else if ( rc == LDAP_COMPREF_UNDEFINED ) {
586 if ( op ) {
587 op->o_tmpfree( ca_comp_ref , op->o_tmpmemctx );
588 } else {
589 free( ca_comp_ref );
590 }
591 return rc;
592 }
593 }
594 ca_comp_ref->cr_len = count;
595 end = cav->cav_ptr;
596 if ( ( rc = strip_cav_str( cav,"\"") ) != LDAP_SUCCESS ) {
597 if ( op ) {
598 op->o_tmpfree( ca_comp_ref , op->o_tmpmemctx );
599 } else {
600 free( ca_comp_ref );
601 }
602 return rc;
603 }
604
605 *cr = ca_comp_ref;
606 **cr = *ca_comp_ref;
607
608 (*cr)->cr_string.bv_val = start;
609 (*cr)->cr_string.bv_len = end - start + 1;
610
611 return rc;
612 }
613
614 int
insert_component_reference(ComponentReference * cr,ComponentReference ** cr_list)615 insert_component_reference(
616 ComponentReference *cr,
617 ComponentReference** cr_list)
618 {
619 if ( !cr ) return LDAP_PARAM_ERROR;
620
621 if ( !(*cr_list) ) {
622 *cr_list = cr;
623 cr->cr_next = NULL;
624 } else {
625 cr->cr_next = *cr_list;
626 *cr_list = cr;
627 }
628 return LDAP_SUCCESS;
629 }
630
631 /*
632 * If there is '.' in the name of a given attribute
633 * the first '.'- following characters are considered
634 * as a component reference of the attribute
635 * EX) userCertificate.toBeSigned.serialNumber
636 * attribute : userCertificate
637 * component reference : toBeSigned.serialNumber
638 */
639 int
is_component_reference(char * attr)640 is_component_reference( char* attr ) {
641 int i;
642 for ( i=0; attr[i] != '\0' ; i++ ) {
643 if ( attr[i] == '.' ) return (1);
644 }
645 return (0);
646 }
647
648 int
extract_component_reference(char * attr,ComponentReference ** cr)649 extract_component_reference(
650 char* attr,
651 ComponentReference** cr )
652 {
653 int i, rc;
654 char* cr_ptr;
655 int cr_len;
656 ComponentAssertionValue cav;
657 char text[1][128];
658
659 for ( i=0; attr[i] != '\0' ; i++ ) {
660 if ( attr[i] == '.' ) break;
661 }
662
663 if (attr[i] != '.' ) return LDAP_PARAM_ERROR;
664 attr[i] = '\0';
665
666 cr_ptr = attr + i + 1 ;
667 cr_len = strlen ( cr_ptr );
668 if ( cr_len <= 0 ) return LDAP_PARAM_ERROR;
669
670 /* enclosed between double quotes*/
671 cav.cav_ptr = cav.cav_buf = ch_malloc (cr_len+2);
672 memcpy( cav.cav_buf+1, cr_ptr, cr_len );
673 cav.cav_buf[0] = '"';
674 cav.cav_buf[cr_len+1] = '"';
675 cav.cav_end = cr_ptr + cr_len + 2;
676
677 rc = get_component_reference ( NULL, &cav, cr, (const char**)text );
678 if ( rc != LDAP_SUCCESS ) return rc;
679 (*cr)->cr_string.bv_val = cav.cav_buf;
680 (*cr)->cr_string.bv_len = cr_len + 2;
681
682 return LDAP_SUCCESS;
683 }
684
685 static int
get_ca_use_default(Operation * op,ComponentAssertionValue * cav,int * ca_use_def,const char ** text)686 get_ca_use_default( Operation *op,
687 ComponentAssertionValue* cav,
688 int* ca_use_def, const char** text )
689 {
690 strip_cav_str( cav, "useDefaultValues" );
691
692 if ( peek_cav_str( cav, "TRUE" ) == LDAP_SUCCESS ) {
693 strip_cav_str( cav, "TRUE" );
694 *ca_use_def = 1;
695
696 } else if ( peek_cav_str( cav, "FALSE" ) == LDAP_SUCCESS ) {
697 strip_cav_str( cav, "FALSE" );
698 *ca_use_def = 0;
699
700 } else {
701 return LDAP_INVALID_SYNTAX;
702 }
703
704 return LDAP_SUCCESS;
705 }
706
707 static int
get_matching_rule(Operation * op,ComponentAssertionValue * cav,MatchingRule ** mr,const char ** text)708 get_matching_rule( Operation *op, ComponentAssertionValue* cav,
709 MatchingRule** mr, const char** text )
710 {
711 int count = 0;
712 struct berval rule_text = { 0L, NULL };
713
714 eat_whsp( cav );
715
716 for ( ; ; count++ ) {
717 if ( cav->cav_ptr[count] == ' ' || cav->cav_ptr[count] == ',' ||
718 cav->cav_ptr[count] == '\0' || cav->cav_ptr[count] == '{' ||
719 cav->cav_ptr[count] == '}' || cav->cav_ptr[count] == '\n' )
720 {
721 break;
722 }
723 }
724
725 if ( count == 0 ) {
726 *text = "component matching rule not recognized";
727 return LDAP_INAPPROPRIATE_MATCHING;
728 }
729
730 rule_text.bv_len = count;
731 rule_text.bv_val = cav->cav_ptr;
732 *mr = mr_bvfind( &rule_text );
733 cav->cav_ptr += count;
734 Debug( LDAP_DEBUG_FILTER, "get_matching_rule: %s\n",
735 (*mr)->smr_mrule.mr_oid );
736 if ( *mr == NULL ) {
737 *text = "component matching rule not recognized";
738 return LDAP_INAPPROPRIATE_MATCHING;
739 }
740 return LDAP_SUCCESS;
741 }
742
743 static int
get_GSER_value(ComponentAssertionValue * cav,struct berval * bv)744 get_GSER_value( ComponentAssertionValue* cav, struct berval* bv )
745 {
746 int count, sequent_dquote, unclosed_brace, succeed;
747
748 eat_whsp( cav );
749 /*
750 * Four cases of GSER <Values>
751 * 1) "..." :
752 * StringVal, GeneralizedTimeVal, UTCTimeVal, ObjectDescriptorVal
753 * 2) '...'B or '...'H :
754 * BitStringVal, OctetStringVal
755 * 3) {...} :
756 * SEQUENCE, SEQUENCEOF, SETOF, SET, CHOICE
757 * 4) Between two white spaces
758 * INTEGER, BOOLEAN, NULL,ENUMERATE, etc
759 */
760
761 succeed = 0;
762 if ( cav->cav_ptr[0] == '"' ) {
763 for( count = 1, sequent_dquote = 0 ; ; count++ ) {
764 /* In order to find escaped double quote */
765 if ( cav->cav_ptr[count] == '"' ) sequent_dquote++;
766 else sequent_dquote = 0;
767
768 if ( cav->cav_ptr[count] == '\0' ||
769 (cav->cav_ptr+count) > cav->cav_end )
770 {
771 break;
772 }
773
774 if ( ( cav->cav_ptr[count] == '"' &&
775 cav->cav_ptr[count-1] != '"') ||
776 ( sequent_dquote > 2 && (sequent_dquote%2) == 1 ) )
777 {
778 succeed = 1;
779 break;
780 }
781 }
782
783 if ( !succeed || cav->cav_ptr[count] != '"' ) {
784 return LDAP_FILTER_ERROR;
785 }
786
787 bv->bv_val = cav->cav_ptr + 1;
788 bv->bv_len = count - 1; /* exclude '"' */
789
790 } else if ( cav->cav_ptr[0] == '\'' ) {
791 for( count = 1 ; ; count++ ) {
792 if ( cav->cav_ptr[count] == '\0' ||
793 (cav->cav_ptr+count) > cav->cav_end )
794 {
795 break;
796 }
797 if ((cav->cav_ptr[count-1] == '\'' && cav->cav_ptr[count] == 'B') ||
798 (cav->cav_ptr[count-1] == '\'' && cav->cav_ptr[count] == 'H') )
799 {
800 succeed = 1;
801 break;
802 }
803 }
804
805 if ( !succeed ||
806 !(cav->cav_ptr[count] == 'H' || cav->cav_ptr[count] == 'B') )
807 {
808 return LDAP_FILTER_ERROR;
809 }
810
811 bv->bv_val = cav->cav_ptr + 1;/*the next to '"' */
812 bv->bv_len = count - 2;/* exclude "'H" or "'B" */
813
814 } else if ( cav->cav_ptr[0] == '{' ) {
815 for( count = 1, unclosed_brace = 1 ; ; count++ ) {
816 if ( cav->cav_ptr[count] == '{' ) unclosed_brace++;
817 if ( cav->cav_ptr[count] == '}' ) unclosed_brace--;
818
819 if ( cav->cav_ptr[count] == '\0' ||
820 (cav->cav_ptr+count) > cav->cav_end )
821 {
822 break;
823 }
824 if ( unclosed_brace == 0 ) {
825 succeed = 1;
826 break;
827 }
828 }
829
830 if ( !succeed || cav->cav_ptr[count] != '}' ) return LDAP_FILTER_ERROR;
831
832 bv->bv_val = cav->cav_ptr + 1;/*the next to '"' */
833 bv->bv_len = count - 1;/* exclude "'B" */
834
835 } else {
836 succeed = 1;
837 /*Find following white space where the value is ended*/
838 for( count = 1 ; ; count++ ) {
839 if ( cav->cav_ptr[count] == '\0' ||
840 cav->cav_ptr[count] == ' ' || cav->cav_ptr[count] == '}' ||
841 cav->cav_ptr[count] == '{' ||
842 (cav->cav_ptr+count) > cav->cav_end )
843 {
844 break;
845 }
846 }
847 bv->bv_val = cav->cav_ptr;
848 bv->bv_len = count;
849 }
850
851 cav->cav_ptr += bv->bv_len;
852 return LDAP_SUCCESS;
853 }
854
855 static int
get_matching_value(Operation * op,ComponentAssertion * ca,ComponentAssertionValue * cav,struct berval * bv,const char ** text)856 get_matching_value( Operation *op, ComponentAssertion* ca,
857 ComponentAssertionValue* cav, struct berval* bv,
858 const char** text )
859 {
860 if ( !(ca->ca_ma_rule->smr_usage & (SLAP_MR_COMPONENT)) ) {
861 if ( get_GSER_value( cav, bv ) != LDAP_SUCCESS ) {
862 return LDAP_FILTER_ERROR;
863 }
864
865 } else {
866 /* embedded componentFilterMatch Description */
867 bv->bv_val = cav->cav_ptr;
868 bv->bv_len = cav_cur_len( cav );
869 }
870
871 return LDAP_SUCCESS;
872 }
873
874 /* Don't move the position pointer, just peek given string */
875 static int
peek_cav_str(ComponentAssertionValue * cav,char * str)876 peek_cav_str( ComponentAssertionValue* cav, char* str )
877 {
878 eat_whsp( cav );
879 if ( cav_cur_len( cav ) >= strlen( str ) &&
880 strncmp( cav->cav_ptr, str, strlen( str ) ) == 0 )
881 {
882 return LDAP_SUCCESS;
883 }
884
885 return LDAP_INVALID_SYNTAX;
886 }
887
888 static int
strip_cav_str(ComponentAssertionValue * cav,char * str)889 strip_cav_str( ComponentAssertionValue* cav, char* str)
890 {
891 eat_whsp( cav );
892 if ( cav_cur_len( cav ) >= strlen( str ) &&
893 strncmp( cav->cav_ptr, str, strlen( str ) ) == 0 )
894 {
895 cav->cav_ptr += strlen( str );
896 return LDAP_SUCCESS;
897 }
898
899 return LDAP_INVALID_SYNTAX;
900 }
901
902 /*
903 * TAG : "item", "and", "or", "not"
904 */
905 static ber_tag_t
strip_cav_tag(ComponentAssertionValue * cav)906 strip_cav_tag( ComponentAssertionValue* cav )
907 {
908 int rc;
909
910 eat_whsp( cav );
911 if ( cav_cur_len( cav ) >= 8 && strncmp( cav->cav_ptr, "item", 4 ) == 0 ) {
912 if ( strip_cav_str( cav , "item:" ))
913 goto fail;
914 return LDAP_COMP_FILTER_ITEM;
915
916 } else if ( cav_cur_len( cav ) >= 7 &&
917 strncmp( cav->cav_ptr, "and", 3 ) == 0 )
918 {
919 if ( strip_cav_str( cav , "and:" ))
920 goto fail;
921 return LDAP_COMP_FILTER_AND;
922
923 } else if ( cav_cur_len( cav ) >= 6 &&
924 strncmp( cav->cav_ptr, "or" , 2 ) == 0 )
925 {
926 if ( strip_cav_str( cav , "or:" ))
927 goto fail;
928 return LDAP_COMP_FILTER_OR;
929
930 } else if ( cav_cur_len( cav ) >= 7 &&
931 strncmp( cav->cav_ptr, "not", 3 ) == 0 )
932 {
933 if ( strip_cav_str( cav , "not:" ))
934 goto fail;
935 return LDAP_COMP_FILTER_NOT;
936 }
937
938 fail:
939 return LBER_ERROR;
940 }
941
942 /*
943 * when encoding, "item" is denotation of ComponentAssertion
944 * ComponentAssertion :: SEQUENCE {
945 * component ComponentReference (SIZE(1..MAX)) OPTIONAL,
946 * useDefaultValues BOOLEAN DEFAULT TRUE,
947 * rule MATCHING-RULE.&id,
948 * value MATCHING-RULE.&AssertionType }
949 */
950 static int
get_item(Operation * op,ComponentAssertionValue * cav,ComponentAssertion ** ca,const char ** text)951 get_item( Operation *op, ComponentAssertionValue* cav, ComponentAssertion** ca,
952 const char** text )
953 {
954 int rc, freeval = 0;
955 ComponentAssertion* _ca;
956 struct berval value;
957 MatchingRule* mr;
958
959 Debug( LDAP_DEBUG_FILTER, "get_item \n" );
960 if ( op )
961 _ca = op->o_tmpalloc( sizeof( ComponentAssertion ), op->o_tmpmemctx );
962 else
963 _ca = SLAP_MALLOC( sizeof( ComponentAssertion ) );
964
965 if ( !_ca ) return LDAP_NO_MEMORY;
966
967 _ca->ca_comp_data.cd_tree = NULL;
968 _ca->ca_comp_data.cd_mem_op = NULL;
969 BER_BVZERO( &_ca->ca_ma_value );
970
971 rc = peek_cav_str( cav, "component" );
972 if ( rc == LDAP_SUCCESS ) {
973 strip_cav_str( cav, "component" );
974 rc = get_component_reference( op, cav, &_ca->ca_comp_ref, text );
975 if ( rc != LDAP_SUCCESS ) {
976 rc = LDAP_INVALID_SYNTAX;
977 fail:
978 if ( freeval )
979 op->o_tmpfree( _ca->ca_ma_value.bv_val, op->o_tmpmemctx );
980 if ( op )
981 op->o_tmpfree( _ca, op->o_tmpmemctx );
982 else
983 free( _ca );
984 return rc;
985 }
986 if ( ( rc = strip_cav_str( cav,",") ) != LDAP_SUCCESS )
987 goto fail;
988 } else {
989 _ca->ca_comp_ref = NULL;
990 }
991
992 rc = peek_cav_str( cav, "useDefaultValues");
993 if ( rc == LDAP_SUCCESS ) {
994 rc = get_ca_use_default( op, cav, &_ca->ca_use_def, text );
995 if ( rc != LDAP_SUCCESS ) {
996 rc = LDAP_INVALID_SYNTAX;
997 goto fail;
998 }
999 if ( ( rc = strip_cav_str( cav,",") ) != LDAP_SUCCESS )
1000 goto fail;
1001 }
1002 else _ca->ca_use_def = 1;
1003
1004 if ( !( strip_cav_str( cav, "rule" ) == LDAP_SUCCESS &&
1005 get_matching_rule( op, cav , &_ca->ca_ma_rule, text ) == LDAP_SUCCESS )) {
1006 rc = LDAP_INAPPROPRIATE_MATCHING;
1007 goto fail;
1008 }
1009
1010 if ( ( rc = strip_cav_str( cav,",") ) != LDAP_SUCCESS )
1011 goto fail;
1012 if ( !(strip_cav_str( cav, "value" ) == LDAP_SUCCESS &&
1013 get_matching_value( op, _ca, cav,&value ,text ) == LDAP_SUCCESS )) {
1014 rc = LDAP_INVALID_SYNTAX;
1015 goto fail;
1016 }
1017
1018 /*
1019 * Normalize the value of this component assertion when the matching
1020 * rule is one of existing matching rules
1021 */
1022 mr = _ca->ca_ma_rule;
1023 if ( op && !(mr->smr_usage & (SLAP_MR_COMPONENT)) && mr->smr_normalize ) {
1024
1025 value.bv_val[value.bv_len] = '\0';
1026 rc = mr->smr_normalize (
1027 SLAP_MR_VALUE_OF_ASSERTION_SYNTAX,
1028 NULL, mr,
1029 &value, &_ca->ca_ma_value, op->o_tmpmemctx );
1030 if ( rc != LDAP_SUCCESS )
1031 goto fail;
1032 freeval = 1;
1033 }
1034 else
1035 _ca->ca_ma_value = value;
1036 /*
1037 * Validate the value of this component assertion
1038 */
1039 if ( op && mr->smr_syntax->ssyn_validate( mr->smr_syntax, &_ca->ca_ma_value) != LDAP_SUCCESS ) {
1040 rc = LDAP_INVALID_SYNTAX;
1041 goto fail;
1042 }
1043
1044
1045 /* componentFilterMatch contains componentFilterMatch in it */
1046 if ( strcmp(_ca->ca_ma_rule->smr_mrule.mr_oid, OID_COMP_FILTER_MATCH ) == 0) {
1047 struct berval bv;
1048 bv.bv_val = cav->cav_ptr;
1049 bv.bv_len = cav_cur_len( cav );
1050 rc = get_comp_filter( op, &bv,(ComponentFilter**)&_ca->ca_cf, text );
1051 if ( rc != LDAP_SUCCESS )
1052 goto fail;
1053 cav->cav_ptr = bv.bv_val;
1054 assert( cav->cav_end >= bv.bv_val );
1055 }
1056
1057 *ca = _ca;
1058 return LDAP_SUCCESS;
1059 }
1060
1061 static int
parse_comp_filter(Operation * op,ComponentAssertionValue * cav,ComponentFilter ** filt,const char ** text)1062 parse_comp_filter( Operation* op, ComponentAssertionValue* cav,
1063 ComponentFilter** filt, const char** text )
1064 {
1065 /*
1066 * A component filter looks like this coming in:
1067 * Filter ::= CHOICE {
1068 * item [0] ComponentAssertion,
1069 * and [1] SEQUENCE OF ComponentFilter,
1070 * or [2] SEQUENCE OF ComponentFilter,
1071 * not [3] ComponentFilter,
1072 * }
1073 */
1074
1075 ber_tag_t tag;
1076 int err = LDAP_SUCCESS;
1077 ComponentFilter f;
1078 /* TAG : item, and, or, not in RFC 4515 */
1079 tag = strip_cav_tag( cav );
1080
1081 if ( tag == LBER_ERROR ) {
1082 *text = "error decoding comp filter";
1083 return LDAP_PROTOCOL_ERROR;
1084 }
1085
1086 if ( tag != LDAP_COMP_FILTER_NOT ) {
1087 err = strip_cav_str( cav, "{");
1088 if ( err )
1089 goto invalid;
1090 }
1091
1092 f.cf_next = NULL;
1093 f.cf_choice = tag;
1094
1095 switch ( f.cf_choice ) {
1096 case LDAP_COMP_FILTER_AND:
1097 Debug( LDAP_DEBUG_FILTER, "LDAP_COMP_FILTER_AND\n" );
1098 err = get_comp_filter_list( op, cav, &f.cf_and, text );
1099 if ( err != LDAP_SUCCESS ) {
1100 break;
1101 }
1102 if ( f.cf_and == NULL ) {
1103 f.cf_choice = SLAPD_FILTER_COMPUTED;
1104 f.cf_result = LDAP_COMPARE_TRUE;
1105 }
1106 break;
1107
1108 case LDAP_COMP_FILTER_OR:
1109 Debug( LDAP_DEBUG_FILTER, "LDAP_COMP_FILTER_OR\n" );
1110 err = get_comp_filter_list( op, cav, &f.cf_or, text );
1111 if ( err != LDAP_SUCCESS ) {
1112 break;
1113 }
1114 if ( f.cf_or == NULL ) {
1115 f.cf_choice = SLAPD_FILTER_COMPUTED;
1116 f.cf_result = LDAP_COMPARE_FALSE;
1117 }
1118 /* no assert - list could be empty */
1119 break;
1120
1121 case LDAP_COMP_FILTER_NOT:
1122 Debug( LDAP_DEBUG_FILTER, "LDAP_COMP_FILTER_NOT\n" );
1123 err = parse_comp_filter( op, cav, &f.cf_not, text );
1124 if ( err != LDAP_SUCCESS ) {
1125 break;
1126 }
1127
1128 assert( f.cf_not != NULL );
1129 if ( f.cf_not->cf_choice == SLAPD_FILTER_COMPUTED ) {
1130 int fresult = f.cf_not->cf_result;
1131 f.cf_choice = SLAPD_FILTER_COMPUTED;
1132 op->o_tmpfree( f.cf_not, op->o_tmpmemctx );
1133 f.cf_not = NULL;
1134
1135 switch ( fresult ) {
1136 case LDAP_COMPARE_TRUE:
1137 f.cf_result = LDAP_COMPARE_FALSE;
1138 break;
1139 case LDAP_COMPARE_FALSE:
1140 f.cf_result = LDAP_COMPARE_TRUE;
1141 break;
1142 default: ;
1143 /* (!Undefined) is Undefined */
1144 }
1145 }
1146 break;
1147
1148 case LDAP_COMP_FILTER_ITEM:
1149 Debug( LDAP_DEBUG_FILTER, "LDAP_COMP_FILTER_ITEM\n" );
1150 err = get_item( op, cav, &f.cf_ca, text );
1151 if ( err != LDAP_SUCCESS ) {
1152 break;
1153 }
1154
1155 assert( f.cf_ca != NULL );
1156 break;
1157
1158 default:
1159 f.cf_choice = SLAPD_FILTER_COMPUTED;
1160 f.cf_result = SLAPD_COMPARE_UNDEFINED;
1161 break;
1162 }
1163
1164 invalid:
1165 if ( err != LDAP_SUCCESS && err != SLAPD_DISCONNECT ) {
1166 *text = "Component Filter Syntax Error";
1167 return err;
1168 }
1169
1170 if ( tag != LDAP_COMP_FILTER_NOT )
1171 err = strip_cav_str( cav, "}");
1172
1173 if ( err == LDAP_SUCCESS ) {
1174 if ( op ) {
1175 *filt = op->o_tmpalloc( sizeof(f), op->o_tmpmemctx );
1176 } else {
1177 *filt = SLAP_MALLOC( sizeof(f) );
1178 }
1179 if ( *filt == NULL ) {
1180 return LDAP_NO_MEMORY;
1181 }
1182 **filt = f;
1183 }
1184
1185 return( err );
1186 }
1187
1188 static int
test_comp_filter_and(Syntax * syn,ComponentSyntaxInfo * a,ComponentFilter * flist)1189 test_comp_filter_and(
1190 Syntax *syn,
1191 ComponentSyntaxInfo *a,
1192 ComponentFilter *flist )
1193 {
1194 ComponentFilter *f;
1195 int rtn = LDAP_COMPARE_TRUE;
1196
1197 for ( f = flist ; f != NULL; f = f->cf_next ) {
1198 int rc = test_comp_filter( syn, a, f );
1199 if ( rc == LDAP_COMPARE_FALSE ) {
1200 rtn = rc;
1201 break;
1202 }
1203
1204 if ( rc != LDAP_COMPARE_TRUE ) {
1205 rtn = rc;
1206 }
1207 }
1208
1209 return rtn;
1210 }
1211
1212 static int
test_comp_filter_or(Syntax * syn,ComponentSyntaxInfo * a,ComponentFilter * flist)1213 test_comp_filter_or(
1214 Syntax *syn,
1215 ComponentSyntaxInfo *a,
1216 ComponentFilter *flist )
1217 {
1218 ComponentFilter *f;
1219 int rtn = LDAP_COMPARE_TRUE;
1220
1221 for ( f = flist ; f != NULL; f = f->cf_next ) {
1222 int rc = test_comp_filter( syn, a, f );
1223 if ( rc == LDAP_COMPARE_TRUE ) {
1224 rtn = rc;
1225 break;
1226 }
1227
1228 if ( rc != LDAP_COMPARE_FALSE ) {
1229 rtn = rc;
1230 }
1231 }
1232
1233 return rtn;
1234 }
1235
1236 int
csi_value_match(MatchingRule * mr,struct berval * bv_attr,struct berval * bv_assert)1237 csi_value_match( MatchingRule *mr, struct berval* bv_attr,
1238 struct berval* bv_assert )
1239 {
1240 int rc;
1241 int match;
1242
1243 assert( mr != NULL );
1244 assert( !(mr->smr_usage & SLAP_MR_COMPONENT) );
1245
1246 if( !mr->smr_match ) return LDAP_INAPPROPRIATE_MATCHING;
1247
1248 rc = (mr->smr_match)( &match, 0, NULL /*ad->ad_type->sat_syntax*/,
1249 mr, bv_attr, bv_assert );
1250
1251 if ( rc != LDAP_SUCCESS ) return rc;
1252
1253 return match ? LDAP_COMPARE_FALSE : LDAP_COMPARE_TRUE;
1254 }
1255
1256 /*
1257 * return codes : LDAP_COMPARE_TRUE, LDAP_COMPARE_FALSE
1258 */
1259 static int
test_comp_filter_item(Syntax * syn,ComponentSyntaxInfo * csi_attr,ComponentAssertion * ca)1260 test_comp_filter_item(
1261 Syntax *syn,
1262 ComponentSyntaxInfo *csi_attr,
1263 ComponentAssertion *ca )
1264 {
1265 int rc;
1266 void *attr_nm, *assert_nm;
1267
1268 if ( strcmp(ca->ca_ma_rule->smr_mrule.mr_oid,
1269 OID_COMP_FILTER_MATCH ) == 0 && ca->ca_cf ) {
1270 /* componentFilterMatch inside of componentFilterMatch */
1271 rc = test_comp_filter( syn, csi_attr, ca->ca_cf );
1272 return rc;
1273 }
1274
1275 /* Memory for storing will-be-extracted attribute values */
1276 attr_nm = nibble_mem_allocator ( 1024*4 , 1024 );
1277 if ( !attr_nm ) return LDAP_PROTOCOL_ERROR;
1278
1279 /* Memory for storing component assertion values */
1280 if( !ca->ca_comp_data.cd_mem_op ) {
1281 assert_nm = nibble_mem_allocator ( 256, 64 );
1282 if ( !assert_nm ) {
1283 nibble_mem_free ( attr_nm );
1284 return LDAP_PROTOCOL_ERROR;
1285 }
1286 ca->ca_comp_data.cd_mem_op = assert_nm;
1287
1288 } else {
1289 assert_nm = ca->ca_comp_data.cd_mem_op;
1290 }
1291
1292 /* component reference initialization */
1293 if ( ca->ca_comp_ref ) {
1294 ca->ca_comp_ref->cr_curr = ca->ca_comp_ref->cr_list;
1295 }
1296 rc = test_components( attr_nm, assert_nm, csi_attr, ca );
1297
1298 /* free memory used for storing extracted attribute value */
1299 nibble_mem_free ( attr_nm );
1300 return rc;
1301 }
1302
1303 static int
test_comp_filter(Syntax * syn,ComponentSyntaxInfo * a,ComponentFilter * f)1304 test_comp_filter(
1305 Syntax *syn,
1306 ComponentSyntaxInfo *a,
1307 ComponentFilter *f )
1308 {
1309 int rc;
1310
1311 if ( !f ) return LDAP_PROTOCOL_ERROR;
1312
1313 Debug( LDAP_DEBUG_FILTER, "test_comp_filter\n" );
1314 switch ( f->cf_choice ) {
1315 case SLAPD_FILTER_COMPUTED:
1316 rc = f->cf_result;
1317 break;
1318 case LDAP_COMP_FILTER_AND:
1319 rc = test_comp_filter_and( syn, a, f->cf_and );
1320 break;
1321 case LDAP_COMP_FILTER_OR:
1322 rc = test_comp_filter_or( syn, a, f->cf_or );
1323 break;
1324 case LDAP_COMP_FILTER_NOT:
1325 rc = test_comp_filter( syn, a, f->cf_not );
1326
1327 switch ( rc ) {
1328 case LDAP_COMPARE_TRUE:
1329 rc = LDAP_COMPARE_FALSE;
1330 break;
1331 case LDAP_COMPARE_FALSE:
1332 rc = LDAP_COMPARE_TRUE;
1333 break;
1334 }
1335 break;
1336 case LDAP_COMP_FILTER_ITEM:
1337 rc = test_comp_filter_item( syn, a, f->cf_ca );
1338 break;
1339 default:
1340 rc = LDAP_PROTOCOL_ERROR;
1341 }
1342
1343 return( rc );
1344 }
1345
1346 static void
free_comp_filter_list(ComponentFilter * f)1347 free_comp_filter_list( ComponentFilter* f )
1348 {
1349 ComponentFilter* tmp;
1350 for ( tmp = f; tmp; tmp = tmp->cf_next ) {
1351 free_comp_filter( tmp );
1352 }
1353 }
1354
1355 static void
free_comp_filter(ComponentFilter * f)1356 free_comp_filter( ComponentFilter* f )
1357 {
1358 if ( !f ) {
1359 Debug( LDAP_DEBUG_FILTER,
1360 "free_comp_filter: Invalid filter so failed to release memory\n" );
1361 return;
1362 }
1363 switch ( f->cf_choice ) {
1364 case LDAP_COMP_FILTER_AND:
1365 case LDAP_COMP_FILTER_OR:
1366 free_comp_filter_list( f->cf_any );
1367 break;
1368 case LDAP_COMP_FILTER_NOT:
1369 free_comp_filter( f->cf_any );
1370 break;
1371 case LDAP_COMP_FILTER_ITEM:
1372 if ( nibble_mem_free && f->cf_ca->ca_comp_data.cd_mem_op ) {
1373 nibble_mem_free( f->cf_ca->ca_comp_data.cd_mem_op );
1374 }
1375 break;
1376 default:
1377 break;
1378 }
1379 }
1380
1381 void
component_free(ComponentFilter * f)1382 component_free( ComponentFilter *f ) {
1383 free_comp_filter( f );
1384 }
1385
1386 void
free_ComponentData(Attribute * a)1387 free_ComponentData( Attribute *a ) {
1388 if ( a->a_comp_data->cd_mem_op )
1389 component_destructor( a->a_comp_data->cd_mem_op );
1390 free ( a->a_comp_data );
1391 a->a_comp_data = NULL;
1392 }
1393 #endif
1394