1 /* component.c -- Component Filter Match Routines */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 2003-2004 The OpenLDAP Foundation.
6 * Portions Copyright 2004 by IBM Corporation.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted only as authorized by the OpenLDAP
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>.
20 #include <ac/string.h>
21 #include <ac/socket.h>
27 #ifdef LDAP_COMP_MATCH
29 #include "component.h"
32 * This three function pointers are initialized
33 * when a component module is loaded
35 convert_attr_to_comp_func* attr_converter = NULL ;
36 convert_assert_to_comp_func* assert_converter = NULL ;
37 convert_asn_to_ldap_func* csi_converter = NULL ;
38 free_component_func* component_destructor = NULL ;
40 #define OID_ALL_COMP_MATCH "1.2.36.79672281.1.13.6"
41 #define OID_COMP_FILTER_MATCH "1.2.36.79672281.1.13.2"
42 #define MAX_LDAP_STR_LEN 128
45 peek_componentId_type( ComponentAssertionValue* cav );
48 strip_cav_str( ComponentAssertionValue* cav, char* str);
51 peek_cav_str( ComponentAssertionValue* cav, char* str );
54 parse_comp_filter( Operation* op, ComponentAssertionValue* cav,
55 ComponentFilter** filt, const char** text );
58 free_comp_filter( ComponentFilter* f );
61 test_comp_filter( Syntax *syn, Attribute *a, struct berval *bv,
65 componentCertificateValidate(
73 componentFilterValidate(
81 allComponentsValidate(
89 componentFilterMatch (
97 Attribute *a = (Attribute*)value;
98 MatchingRuleAssertion * ma = (MatchingRuleAssertion*)assertedValue;
102 if ( !(mr && mr->smr_usage & SLAP_MR_COMPONENT) || !ma->ma_cf )
103 return LDAP_INAPPROPRIATE_MATCHING;
105 rc = test_comp_filter( syntax, a, a->a_vals, ma->ma_cf );
106 if ( component_destructor && a->a_component_values ) {
107 component_destructor(a->a_component_values);
108 a->a_component_values = NULL;
110 if ( rc == LDAP_COMPARE_TRUE ) {
114 else if ( rc == LDAP_COMPARE_FALSE ) {
119 return LDAP_INAPPROPRIATE_MATCHING;
130 struct berval *value,
131 void *assertedValue )
133 /* Only for Registeration */
139 slapd_ber2cav( struct berval* bv, ComponentAssertionValue* cav)
143 len = ldap_pvt_filter_value_unescape( bv->bv_val );
145 return LDAP_FILTER_ERROR;
147 cav->cav_ptr = cav->cav_buf = bv->bv_val;
148 cav->cav_end = bv->bv_val + len;
150 /* FIXME: should it check return value
151 * of ldap_pvt_filter_value_unescape? */
156 get_comp_filter( Operation* op, struct berval* bv, ComponentFilter** filt,
159 ComponentAssertionValue cav;
162 Debug( LDAP_DEBUG_FILTER, "get_comp_filter\n", 0, 0, 0 );
163 if ( (rc = slapd_ber2cav(bv, &cav) ) != LDAP_SUCCESS ) {
166 rc = parse_comp_filter( op, &cav, filt, text );
167 bv->bv_val = cav.cav_ptr;
173 eat_whsp( ComponentAssertionValue* cav )
175 for ( ; ( *cav->cav_ptr == ' ' ) && ( cav->cav_ptr < cav->cav_end ) ; ) {
181 cav_cur_len( ComponentAssertionValue* cav )
183 return cav->cav_end - cav->cav_ptr;
187 comp_first_element( ComponentAssertionValue* cav )
190 if ( cav_cur_len( cav ) >= 8 && strncmp( cav->cav_ptr, "item", 4 ) == 0 ) {
191 return LDAP_COMP_FILTER_ITEM;
193 else if ( cav_cur_len( cav ) >= 7 && strncmp( cav->cav_ptr, "and", 3 ) == 0 ) {
194 return LDAP_COMP_FILTER_AND;
196 else if ( cav_cur_len( cav ) >= 6 && strncmp( cav->cav_ptr, "or" , 2 ) == 0 ) {
197 return LDAP_COMP_FILTER_OR;
199 else if ( cav_cur_len( cav ) >= 7 && strncmp( cav->cav_ptr, "not", 3 ) == 0 ) {
200 return LDAP_COMP_FILTER_NOT;
203 return LDAP_COMP_FILTER_UNDEFINED;
207 comp_next_element( ComponentAssertionValue* cav )
211 if ( *(cav->cav_ptr) == ',' ) {
212 /* move pointer to the next CA */
214 return comp_first_element( cav );
216 else return LDAP_COMP_FILTER_UNDEFINED;
220 get_comp_filter_list( Operation *op, ComponentAssertionValue *cav,
221 ComponentFilter** f, const char** text )
223 ComponentFilter **new;
227 Debug( LDAP_DEBUG_FILTER, "get_comp_filter_list\n", 0, 0, 0 );
229 for ( tag = comp_first_element( cav ); tag != LDAP_COMP_FILTER_UNDEFINED;
230 tag = comp_next_element( cav ) )
232 err = parse_comp_filter( op, cav, new, text );
233 if ( err != LDAP_SUCCESS )
235 new = &(*new)->cf_next;
239 return( LDAP_SUCCESS );
243 get_componentId( Operation *op, ComponentAssertionValue* cav,
244 ComponentId ** cid, const char** text )
250 type = peek_componentId_type( cav );
252 Debug( LDAP_DEBUG_FILTER, "get_compId [%d]\n", type, 0, 0 );
257 case LDAP_COMPREF_IDENTIFIER :
258 _cid.ci_val.ci_identifier.bv_val = cav->cav_ptr;
259 for( ;cav->cav_ptr[len] != ' ' && cav->cav_ptr[len] != '\0' &&
260 cav->cav_ptr[len] != '.' && cav->cav_ptr[len] != '\"' ; len++ );
261 _cid.ci_val.ci_identifier.bv_len = len;
264 case LDAP_COMPREF_FROM_BEGINNING :
265 for( ;cav->cav_ptr[len] != ' ' && cav->cav_ptr[len] != '\0' &&
266 cav->cav_ptr[len] != '.' && cav->cav_ptr[len] != '\"' ; len++ );
267 _cid.ci_val.ci_from_beginning = strtol( cav->cav_ptr, NULL, 0 );
270 case LDAP_COMPREF_FROM_END :
271 for( ;cav->cav_ptr[len] != ' ' && cav->cav_ptr[len] != '\0' &&
272 cav->cav_ptr[len] != '.' && cav->cav_ptr[len] != '\"' ; len++ );
273 _cid.ci_val.ci_from_end = strtol( cav->cav_ptr, NULL, 0 );
276 case LDAP_COMPREF_COUNT :
277 _cid.ci_val.ci_count = 0;
280 case LDAP_COMPREF_CONTENT :
281 /* FIXEME: yet to be implemented */
283 case LDAP_COMPREF_SELECT :
284 /* FIXEME: yet to be implemented */
286 case LDAP_COMPREF_ALL :
287 _cid.ci_val.ci_all = '*';
289 Debug( LDAP_DEBUG_FILTER, "get_compId : ALL\n", 0, 0, 0 );
292 return LDAP_COMPREF_UNDEFINED;
295 *cid = op->o_tmpalloc( sizeof( ComponentId ), op->o_tmpmemctx );
301 peek_componentId_type( ComponentAssertionValue* cav )
304 if ( cav->cav_ptr[0] == '-' )
305 return LDAP_COMPREF_FROM_END;
306 else if ( cav->cav_ptr[0] == '(' )
307 return LDAP_COMPREF_SELECT;
308 else if ( cav->cav_ptr[0] == '*' )
309 return LDAP_COMPREF_ALL;
310 else if ( cav->cav_ptr[0] == '0' )
311 return LDAP_COMPREF_COUNT;
312 else if ( cav->cav_ptr[0] > '0' && cav->cav_ptr[0] <= '9' )
313 return LDAP_COMPREF_FROM_BEGINNING;
314 else if ( (cav->cav_end - cav->cav_ptr) >= 7 &&
315 strncmp(cav->cav_ptr,"content",7) == 0 )
316 return LDAP_COMPREF_CONTENT;
317 else if ( (cav->cav_ptr[0] >= 'a' && cav->cav_ptr[0] <= 'z') ||
318 (cav->cav_ptr[0] >= 'A' && cav->cav_ptr[0] <= 'Z') )
320 return LDAP_COMPREF_IDENTIFIER;
322 return LDAP_COMPREF_UNDEFINED;
326 comp_next_id( ComponentAssertionValue* cav )
329 if ( *(cav->cav_ptr) == '.' ) {
331 return LDAP_COMPREF_DEFINED;
333 else return LDAP_COMPREF_UNDEFINED;
337 get_component_reference( Operation *op, ComponentAssertionValue* cav,
338 ComponentReference** cr, const char** text )
342 ComponentReference* ca_comp_ref;
343 ComponentId** cr_list;
347 op->o_tmpalloc( sizeof( ComponentReference ), op->o_tmpmemctx );
349 cr_list = &ca_comp_ref->cr_list;
350 strip_cav_str( cav, "\"");
351 for ( type = peek_componentId_type( cav ) ; type != LDAP_COMPREF_UNDEFINED
352 ; type = comp_next_id( cav ), count++ ) {
353 rc = get_componentId( op, cav, cr_list, text );
354 if ( rc == LDAP_SUCCESS ) {
355 if ( count == 0 ) ca_comp_ref->cr_curr = ca_comp_ref->cr_list;
356 cr_list = &(*cr_list)->ci_next;
358 else if ( rc == LDAP_COMPREF_UNDEFINED )
361 ca_comp_ref->cr_len = count;
362 strip_cav_str( cav, "\"");
364 if ( rc == LDAP_SUCCESS ) {
368 else op->o_tmpfree( ca_comp_ref , op->o_tmpmemctx );
374 get_ca_use_default( Operation *op, ComponentAssertionValue* cav,
375 int* ca_use_def, const char** text )
377 if ( peek_cav_str( cav, "useDefaultValues" ) == LDAP_SUCCESS ) {
378 strip_cav_str( cav, "useDefaultValues" );
379 if ( peek_cav_str( cav, "TRUE" ) == LDAP_SUCCESS ) {
380 strip_cav_str( cav, "TRUE" );
382 } else if ( peek_cav_str( cav, "FALSE" ) == LDAP_SUCCESS ) {
383 strip_cav_str( cav, "FALSE" );
386 return LDAP_INVALID_SYNTAX;
390 /* If not defined, default value is TRUE */
398 get_matching_rule( Operation *op, ComponentAssertionValue* cav,
399 MatchingRule** mr, const char** text )
402 struct berval rule_text = { 0L, NULL };
406 for ( ; ; count++ ) {
407 if ( cav->cav_ptr[count] == ' ' || cav->cav_ptr[count] == ',' ||
408 cav->cav_ptr[count] == '\0' || cav->cav_ptr[count] == '{' ||
409 cav->cav_ptr[count] == '}' || cav->cav_ptr[count] == '\n' )
414 *text = "component matching rule not recognized";
415 return LDAP_INAPPROPRIATE_MATCHING;
418 rule_text.bv_len = count;
419 rule_text.bv_val = cav->cav_ptr;
420 *mr = mr_bvfind( &rule_text );
421 cav->cav_ptr += count;
422 Debug( LDAP_DEBUG_FILTER, "get_matching_rule: %s\n", (*mr)->smr_mrule.mr_oid, 0, 0 );
424 *text = "component matching rule not recognized";
425 return LDAP_INAPPROPRIATE_MATCHING;
431 get_GSER_value( ComponentAssertionValue* cav, struct berval* bv )
433 int count, sequent_dquote, unclosed_brace, succeed;
437 * Four cases of GSER <Values>
439 * StringVal, GeneralizedTimeVal, UTCTimeVal, ObjectDescriptorVal
440 * 2) '...'B or '...'H :
441 * BitStringVal, OctetStringVal
443 * SEQUENCE, SEQUENCEOF, SETOF, SET, CHOICE
444 * 4) Between two white spaces
445 * INTEGER, BOOLEAN, NULL,ENUMERATE, etc
449 if ( cav->cav_ptr[0] == '"' ) {
450 for( count = 1, sequent_dquote = 0 ; ; count++ ) {
451 /* In order to find escaped double quote */
452 if ( cav->cav_ptr[count] == '"' ) sequent_dquote++;
453 else sequent_dquote = 0;
455 if ( cav->cav_ptr[count] == '\0' || cav->cav_ptr > cav->cav_end ) {
459 if ( ( cav->cav_ptr[count] == '"' && cav->cav_ptr[count-1] != '"') ||
460 ( sequent_dquote > 2 && (sequent_dquote%2) == 1 ) ) {
466 else if ( cav->cav_ptr[0] == '\'' ) {
467 for( count = 1 ; ; count++ ) {
468 if ( cav->cav_ptr[count] == '\0' || cav->cav_ptr > cav->cav_end ) {
471 if ((cav->cav_ptr[count-1] == '\'' && cav->cav_ptr[count] == 'B')||
472 (cav->cav_ptr[count-1] == '\'' && cav->cav_ptr[count] == 'H') ) {
479 else if ( cav->cav_ptr[0] == '{' ) {
480 for( count = 1, unclosed_brace = 1 ; ; count++ ) {
481 if ( cav->cav_ptr[count] == '{' ) unclosed_brace++;
482 if ( cav->cav_ptr[count] == '}' ) unclosed_brace--;
484 if ( cav->cav_ptr[count] == '\0' || cav->cav_ptr > cav->cav_end )
486 if ( unclosed_brace == 0 ) {
494 count = cav->cav_end - cav->cav_ptr;
497 if ( !succeed ) return LDAP_FILTER_ERROR;
499 bv->bv_val = cav->cav_ptr;
500 bv->bv_len = count + 1 ;
501 cav->cav_ptr += count;
506 get_matching_value( Operation *op, ComponentAssertion* ca,
507 ComponentAssertionValue* cav, struct berval* bv,
510 if ( !(ca->ca_ma_rule->smr_usage & (SLAP_MR_COMPONENT)) ) {
511 if ( get_GSER_value( cav, bv ) != LDAP_SUCCESS ) {
512 return LDAP_FILTER_ERROR;
516 /* embeded componentFilterMatch Description */
517 bv->bv_val = cav->cav_ptr;
518 bv->bv_len = cav_cur_len( cav );
524 /* Don't move the position pointer, just peek given string */
526 peek_cav_str( ComponentAssertionValue* cav, char* str )
529 if ( cav_cur_len( cav ) >= strlen( str ) &&
530 strncmp( cav->cav_ptr, str, strlen( str ) ) == 0 )
533 return LDAP_INVALID_SYNTAX;
537 strip_cav_str( ComponentAssertionValue* cav, char* str)
540 if ( cav_cur_len( cav ) >= strlen( str ) &&
541 strncmp( cav->cav_ptr, str, strlen( str ) ) == 0 ) {
542 cav->cav_ptr += strlen( str );
546 return LDAP_INVALID_SYNTAX;
550 * TAG : "item", "and", "or", "not"
553 strip_cav_tag( ComponentAssertionValue* cav )
557 if ( cav_cur_len( cav ) >= 8 && strncmp( cav->cav_ptr, "item", 4 ) == 0 ) {
558 strip_cav_str( cav , "item:" );
559 return LDAP_COMP_FILTER_ITEM;
561 else if ( cav_cur_len( cav ) >= 7 && strncmp( cav->cav_ptr, "and", 3 ) == 0 ) {
562 strip_cav_str( cav , "and:" );
563 return LDAP_COMP_FILTER_AND;
565 else if ( cav_cur_len( cav ) >= 6 && strncmp( cav->cav_ptr, "or" , 2 ) == 0 ) {
566 strip_cav_str( cav , "or:" );
567 return LDAP_COMP_FILTER_OR;
569 else if ( cav_cur_len( cav ) >= 7 && strncmp( cav->cav_ptr, "not", 3 ) == 0 ) {
570 strip_cav_str( cav , "not:" );
571 return LDAP_COMP_FILTER_NOT;
578 * when encoding, "item" is denotation of ComponentAssertion
579 * ComponentAssertion :: SEQUENCE {
580 * component ComponentReference (SIZE(1..MAX)) OPTIONAL,
581 * useDefaultValues BOOLEAN DEFAULT TRUE,
582 * rule MATCHING-RULE.&id,
583 * value MATCHING-RULE.&AssertionType }
586 get_item( Operation *op, ComponentAssertionValue* cav, ComponentAssertion** ca,
590 ComponentAssertion* _ca;
592 Debug( LDAP_DEBUG_FILTER, "get_item: %s\n", 0, 0, 0 );
593 _ca = op->o_tmpalloc( sizeof( ComponentAssertion ), op->o_tmpmemctx );
595 _ca->ca_component_values = NULL;
597 rc = peek_cav_str( cav, "component" );
598 if ( rc == LDAP_SUCCESS ) {
599 strip_cav_str( cav, "component" );
600 rc = get_component_reference( op, cav, &_ca->ca_comp_ref, text );
601 if ( rc != LDAP_SUCCESS ) {
602 rc = LDAP_INVALID_SYNTAX;
603 op->o_tmpfree( _ca, op->o_tmpmemctx );
608 strip_cav_str( cav,",");
609 rc = peek_cav_str( cav, "useDefaultValues");
610 if ( rc == LDAP_SUCCESS ) {
611 rc = get_ca_use_default( op, cav, &_ca->ca_use_def, text );
612 if ( rc != LDAP_SUCCESS ) {
613 rc = LDAP_INVALID_SYNTAX;
614 op->o_tmpfree( _ca, op->o_tmpmemctx );
617 strip_cav_str( cav,",");
620 if ( !( strip_cav_str( cav, "rule" ) == LDAP_SUCCESS &&
621 get_matching_rule( op, cav , &_ca->ca_ma_rule, text ) == LDAP_SUCCESS )) {
622 rc = LDAP_INAPPROPRIATE_MATCHING;
623 op->o_tmpfree( _ca, op->o_tmpmemctx );
627 strip_cav_str( cav,",");
628 if ( !(strip_cav_str( cav, "value" ) == LDAP_SUCCESS &&
629 get_matching_value( op, _ca, cav, &_ca->ca_ma_value,text ) == LDAP_SUCCESS )) {
630 rc = LDAP_INVALID_SYNTAX;
631 op->o_tmpfree( _ca, op->o_tmpmemctx );
635 /* componentFilterMatch contains componentFilterMatch in it */
636 if ( strcmp(_ca->ca_ma_rule->smr_mrule.mr_oid, OID_COMP_FILTER_MATCH ) == 0) {
638 bv.bv_val = cav->cav_ptr;
639 bv.bv_len = cav_cur_len( cav );
640 rc = get_comp_filter( op, &bv,(ComponentFilter**)&_ca->ca_cf, text );
641 if ( rc != LDAP_SUCCESS ) {
642 op->o_tmpfree( _ca, op->o_tmpmemctx );
645 cav->cav_ptr = bv.bv_val;
646 assert( cav->cav_end >= bv.bv_val );
654 parse_comp_filter( Operation* op, ComponentAssertionValue* cav,
655 ComponentFilter** filt, const char** text )
658 * A component filter looks like this coming in:
659 * Filter ::= CHOICE {
660 * item [0] ComponentAssertion,
661 * and [1] SEQUENCE OF ComponentFilter,
662 * or [2] SEQUENCE OF ComponentFilter,
663 * not [3] ComponentFilter,
670 /* TAG : item, and, or, not in RFC 2254 */
671 tag = strip_cav_tag( cav );
673 if ( tag == LBER_ERROR ) {
674 *text = "error decoding comp filter";
675 return LDAP_PROTOCOL_ERROR;
678 if ( tag != LDAP_COMP_FILTER_NOT )
679 strip_cav_str( cav, "{");
686 switch ( f.cf_choice ) {
687 case LDAP_COMP_FILTER_AND:
688 Debug( LDAP_DEBUG_FILTER, "LDAP_COMP_FILTER_AND\n", 0, 0, 0 );
689 err = get_comp_filter_list( op, cav, &f.cf_and, text );
690 if ( err != LDAP_SUCCESS ) {
693 if ( f.cf_and == NULL ) {
694 f.cf_choice = SLAPD_FILTER_COMPUTED;
695 f.cf_result = LDAP_COMPARE_TRUE;
699 case LDAP_COMP_FILTER_OR:
700 Debug( LDAP_DEBUG_FILTER, "LDAP_COMP_FILTER_OR\n", 0, 0, 0 );
701 err = get_comp_filter_list( op, cav, &f.cf_or, text );
702 if ( err != LDAP_SUCCESS ) {
705 if ( f.cf_or == NULL ) {
706 f.cf_choice = SLAPD_FILTER_COMPUTED;
707 f.cf_result = LDAP_COMPARE_FALSE;
709 /* no assert - list could be empty */
712 case LDAP_COMP_FILTER_NOT:
713 Debug( LDAP_DEBUG_FILTER, "LDAP_COMP_FILTER_NOT\n", 0, 0, 0 );
714 err = parse_comp_filter( op, cav, &f.cf_not, text );
715 if ( err != LDAP_SUCCESS ) {
719 assert( f.cf_not != NULL );
720 if ( f.cf_not->cf_choice == SLAPD_FILTER_COMPUTED ) {
721 int fresult = f.cf_not->cf_result;
722 f.cf_choice = SLAPD_FILTER_COMPUTED;
723 op->o_tmpfree( f.cf_not, op->o_tmpmemctx );
727 case LDAP_COMPARE_TRUE:
728 f.cf_result = LDAP_COMPARE_FALSE;
730 case LDAP_COMPARE_FALSE:
731 f.cf_result = LDAP_COMPARE_TRUE;
734 /* (!Undefined) is Undefined */
739 case LDAP_COMP_FILTER_ITEM:
740 Debug( LDAP_DEBUG_FILTER, "LDAP_COMP_FILTER_ITEM\n", 0, 0, 0 );
741 err = get_item( op, cav, &f.cf_ca, text );
742 if ( err != LDAP_SUCCESS ) {
746 assert( f.cf_ca != NULL );
750 f.cf_choice = SLAPD_FILTER_COMPUTED;
751 f.cf_result = SLAPD_COMPARE_UNDEFINED;
755 if ( tag != LDAP_COMP_FILTER_NOT )
756 strip_cav_str( cav, "}");
758 if ( err != LDAP_SUCCESS && err != SLAPD_DISCONNECT ) {
760 f.cf_choice = SLAPD_FILTER_COMPUTED;
761 f.cf_result = SLAPD_COMPARE_UNDEFINED;
765 if ( err == LDAP_SUCCESS ) {
766 *filt = op->o_tmpalloc( sizeof(f), op->o_tmpmemctx );
774 test_comp_filter_and(
778 ComponentFilter *flist )
781 int rtn = LDAP_COMPARE_TRUE;
783 for ( f = flist ; f != NULL; f = f->cf_next ) {
784 int rc = test_comp_filter( syn, a, bv, f );
785 if ( rc == LDAP_COMPARE_FALSE ) {
790 if ( rc != LDAP_COMPARE_TRUE ) {
803 ComponentFilter *flist )
806 int rtn = LDAP_COMPARE_TRUE;
808 for ( f = flist ; f != NULL; f = f->cf_next ) {
809 int rc = test_comp_filter( syn, a, bv, f );
810 if ( rc == LDAP_COMPARE_TRUE ) {
815 if ( rc != LDAP_COMPARE_FALSE ) {
824 csi_value_match( MatchingRule *mr, struct berval* bv_attr,
825 struct berval* bv_assert )
830 assert( mr != NULL );
831 assert( !(mr->smr_usage & SLAP_MR_COMPONENT) );
833 if( !mr->smr_match ) {
834 return LDAP_INAPPROPRIATE_MATCHING;
837 rc = (mr->smr_match)( &match, 0, NULL /*ad->ad_type->sat_syntax*/,
838 mr, bv_attr, bv_assert );
839 if ( rc == LDAP_SUCCESS )
840 return match? LDAP_COMPARE_FALSE:LDAP_COMPARE_TRUE;
846 component_value_match( MatchingRule* mr,
847 ComponentSyntaxInfo* csi_attr, ComponentSyntaxInfo* csi_assert )
849 if ( mr->smr_usage & SLAP_MR_COMPONENT ){
850 if ( strcmp( mr->smr_mrule.mr_oid, OID_ALL_COMP_MATCH ) == 0 )
852 /* allComponentMatch */
853 return csi_attr->csi_comp_desc->cd_all_match( NULL,
854 csi_attr, csi_assert );
856 return csi_assert->csi_comp_desc->cd_all_match(
857 mr->smr_mrule.mr_oid, csi_attr, csi_assert );
861 if ( csi_attr->csi_comp_desc->cd_type == ASN_BASIC ) {
862 struct berval bv1, bv2;
863 char attr_buf[MAX_LDAP_STR_LEN],assert_buf[MAX_LDAP_STR_LEN];
864 bv1.bv_val = attr_buf;
865 bv2.bv_val = assert_buf;
866 if ( csi_converter &&
867 ( csi_converter ( csi_attr, &bv1 ) == LDAP_SUCCESS ) &&
868 ( csi_converter ( csi_assert, &bv2 ) == LDAP_SUCCESS ) )
870 return csi_value_match( mr, &bv1, &bv2 );
873 return LDAP_INAPPROPRIATE_MATCHING;
876 } else if ( csi_attr->csi_comp_desc->cd_type == ASN_COMPOSITE )
878 return LDAP_INAPPROPRIATE_MATCHING;
882 /* FIXME: what should be returned here? Is this rachable at all? */
883 return LDAP_INAPPROPRIATE_MATCHING;
887 * return codes : LDAP_COMPARE_TRUE, LDAP_COMPARE_FALSE
891 test_comp_filter_item(
895 ComponentAssertion *ca )
898 ComponentSyntaxInfo* csi_attr, *csi_assert=NULL;
900 if ( strcmp(ca->ca_ma_rule->smr_mrule.mr_oid,
901 OID_COMP_FILTER_MATCH ) == 0 && ca->ca_cf ) {
902 /* componentFilterMatch inside of componentFilterMatch */
903 rc = test_comp_filter( syn, a, bv, ca->ca_cf );
907 /* load attribute containg components */
908 /* For a testing purpose, link following function here */
909 if ( !a->a_component_values && attr_converter )
910 a->a_component_values = attr_converter (a, syn, bv);
912 if ( a->a_component_values == NULL )
913 return LDAP_PROTOCOL_ERROR;
915 /* load component containg the referenced component */
916 ca->ca_comp_ref->cr_curr = ca->ca_comp_ref->cr_list;
917 csi_attr = (((ComponentSyntaxInfo*)a->a_component_values)->csi_comp_desc->cd_extract_i)( ca->ca_comp_ref, a->a_component_values );
920 return LDAP_PROTOCOL_ERROR;
922 /* decode the asserted value */
923 if( !ca->ca_component_values && assert_converter ) {
924 assert_converter ( csi_attr, &ca->ca_ma_value,
925 &csi_assert, &len, DEC_ALLOC_MODE_0 );
926 ca->ca_component_values = (void*)csi_assert;
928 else csi_assert = ca->ca_component_values;
931 return LDAP_PROTOCOL_ERROR;
933 return component_value_match( ca->ca_ma_rule, csi_attr, csi_assert);
945 if ( !f ) return LDAP_PROTOCOL_ERROR;
947 Debug( LDAP_DEBUG_FILTER, "test_comp_filter\n", 0, 0, 0 );
948 switch ( f->cf_choice ) {
949 case SLAPD_FILTER_COMPUTED:
952 case LDAP_COMP_FILTER_AND:
953 rc = test_comp_filter_and( syn, a, bv, f->cf_and );
955 case LDAP_COMP_FILTER_OR:
956 rc = test_comp_filter_or( syn, a, bv, f->cf_or );
958 case LDAP_COMP_FILTER_NOT:
959 rc = test_comp_filter( syn, a, bv, f->cf_not );
962 case LDAP_COMPARE_TRUE:
963 rc = LDAP_COMPARE_FALSE;
965 case LDAP_COMPARE_FALSE:
966 rc = LDAP_COMPARE_TRUE;
970 case LDAP_COMP_FILTER_ITEM:
971 rc = test_comp_filter_item( syn, a, bv, f->cf_ca );
974 rc = LDAP_PROTOCOL_ERROR;
981 free_comp_filter_list( ComponentFilter* f )
983 ComponentFilter* tmp;
984 for ( tmp = f ; tmp; tmp = tmp->cf_next );
986 free_comp_filter( tmp );
991 free_comp_filter( ComponentFilter* f )
993 switch ( f->cf_choice ) {
994 case LDAP_COMP_FILTER_AND:
995 case LDAP_COMP_FILTER_OR:
996 case LDAP_COMP_FILTER_NOT:
997 free_comp_filter( f->cf_any );
1000 case LDAP_COMP_FILTER_ITEM:
1001 if ( component_destructor && f->cf_ca->ca_component_values )
1002 component_destructor( f->cf_ca->ca_component_values );
1011 component_free( ComponentFilter *f ) {
1012 free_comp_filter( f );