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
44 peek_componentId_type( ComponentAssertionValue* cav );
47 strip_cav_str( ComponentAssertionValue* cav, char* str);
50 peek_cav_str( ComponentAssertionValue* cav, char* str );
53 parse_comp_filter( Operation* op, ComponentAssertionValue* cav,
54 ComponentFilter** filt, const char** text );
57 test_comp_filter( Syntax *syn, Attribute *a, struct berval *bv,
60 componentCertificateValidate(
67 componentFilterValidate(
75 allComponentsValidate(
83 componentFilterMatch (
91 Attribute *a = (Attribute*)value;
92 MatchingRuleAssertion * ma = (MatchingRuleAssertion*)assertedValue;
96 if ( !(mr && mr->smr_usage & SLAP_MR_COMPONENT) || !ma->ma_cf )
97 return LDAP_INAPPROPRIATE_MATCHING;
99 rc = test_comp_filter( syntax, a, a->a_vals, ma->ma_cf );
100 if ( component_destructor && a->a_component_values ) {
101 component_destructor(a->a_component_values);
102 a->a_component_values = NULL;
104 if ( rc == LDAP_COMPARE_TRUE ) {
108 else if ( rc == LDAP_COMPARE_FALSE ) {
113 return LDAP_INAPPROPRIATE_MATCHING;
124 struct berval *value,
125 void *assertedValue )
127 /* Only for Registeration */
133 slapd_ber2cav( struct berval* bv, ComponentAssertionValue* cav)
137 len = ldap_pvt_filter_value_unescape( bv->bv_val );
138 cav->cav_ptr = cav->cav_buf = bv->bv_val;
139 cav->cav_end = bv->bv_val + len;
143 get_comp_filter ( Operation* op, struct berval* bv, ComponentFilter** filt,
146 ComponentAssertionValue cav;
148 Debug( LDAP_DEBUG_FILTER, "get_comp_filter\n", 0, 0, 0 );
149 slapd_ber2cav(bv, &cav);
150 rc = parse_comp_filter( op, &cav, filt, text );
151 bv->bv_val = cav.cav_ptr;
156 eat_whsp( ComponentAssertionValue* cav )
158 for ( ; ( *cav->cav_ptr == ' ' ) && ( cav->cav_ptr < cav->cav_end ) ; ) {
164 cav_cur_len( ComponentAssertionValue* cav )
166 return cav->cav_end - cav->cav_ptr;
170 comp_first_element( ComponentAssertionValue* cav )
173 if ( cav_cur_len( cav ) >= 8 && strncmp( cav->cav_ptr, "item", 4 ) == 0 ) {
174 return LDAP_COMP_FILTER_ITEM;
176 else if ( cav_cur_len( cav ) >= 7 && strncmp( cav->cav_ptr, "and", 3 ) == 0 ) {
177 return LDAP_COMP_FILTER_AND;
179 else if ( cav_cur_len( cav ) >= 6 && strncmp( cav->cav_ptr, "or" , 2 ) == 0 ) {
180 return LDAP_COMP_FILTER_OR;
182 else if ( cav_cur_len( cav ) >= 7 && strncmp( cav->cav_ptr, "not", 3 ) == 0 ) {
183 return LDAP_COMP_FILTER_NOT;
186 return LDAP_COMP_FILTER_UNDEFINED;
190 comp_next_element( ComponentAssertionValue* cav )
194 if ( *(cav->cav_ptr) == ',' ) {
195 /* move pointer to the next CA */
197 return comp_first_element( cav );
199 else return LDAP_COMP_FILTER_UNDEFINED;
203 get_comp_filter_list( Operation *op, ComponentAssertionValue *cav,
204 ComponentFilter** f, const char** text )
206 ComponentFilter **new;
212 Debug( LDAP_DEBUG_FILTER, "get_comp_filter_list\n", 0, 0, 0 );
214 for ( tag = comp_first_element( cav ); tag != LDAP_COMP_FILTER_UNDEFINED;
215 tag = comp_next_element( cav ) )
217 err = parse_comp_filter( op, cav, new, text );
218 if ( err != LDAP_SUCCESS )
220 new = &(*new)->cf_next;
225 return( LDAP_SUCCESS );
229 get_componentId( Operation *op, ComponentAssertionValue* cav,
230 ComponentId ** cid, const char** text )
236 type = peek_componentId_type( cav );
238 Debug( LDAP_DEBUG_FILTER, "get_compId [%d]\n", type, 0, 0 );
243 case LDAP_COMPREF_IDENTIFIER :
244 _cid.ci_val.ci_identifier.bv_val = cav->cav_ptr;
245 for( ;cav->cav_ptr[len] != ' ' && cav->cav_ptr[len] != '\0' &&
246 cav->cav_ptr[len] != '.' && cav->cav_ptr[len] != '\"' ; len++ );
247 _cid.ci_val.ci_identifier.bv_len = len;
250 case LDAP_COMPREF_FROM_BEGINNING :
251 for( ;cav->cav_ptr[len] != ' ' && cav->cav_ptr[len] != '\0' &&
252 cav->cav_ptr[len] != '.' && cav->cav_ptr[len] != '\"' ; len++ );
253 _cid.ci_val.ci_from_beginning = strtol( cav->cav_ptr, NULL, 0 );
256 case LDAP_COMPREF_FROM_END :
257 for( ;cav->cav_ptr[len] != ' ' && cav->cav_ptr[len] != '\0' &&
258 cav->cav_ptr[len] != '.' && cav->cav_ptr[len] != '\"' ; len++ );
259 _cid.ci_val.ci_from_end = strtol( cav->cav_ptr, NULL, 0 );
262 case LDAP_COMPREF_COUNT :
263 _cid.ci_val.ci_count = 0;
266 case LDAP_COMPREF_CONTENT :
267 /* FIXEME: yet to be implemented */
269 case LDAP_COMPREF_SELECT :
270 /* FIXEME: yet to be implemented */
272 case LDAP_COMPREF_ALL :
273 _cid.ci_val.ci_all = '*';
275 Debug( LDAP_DEBUG_FILTER, "get_compId : ALL\n", 0, 0, 0 );
278 return LDAP_COMPREF_UNDEFINED;
281 *cid = op->o_tmpalloc( sizeof( ComponentId ), op->o_tmpmemctx );
287 peek_componentId_type( ComponentAssertionValue* cav )
290 if ( cav->cav_ptr[0] == '-' )
291 return LDAP_COMPREF_FROM_END;
292 else if ( cav->cav_ptr[0] == '(' )
293 return LDAP_COMPREF_SELECT;
294 else if ( cav->cav_ptr[0] == '*' )
295 return LDAP_COMPREF_ALL;
296 else if ( cav->cav_ptr[0] == '0' )
297 return LDAP_COMPREF_COUNT;
298 else if ( cav->cav_ptr[0] > '0' && cav->cav_ptr[0] <= '9' )
299 return LDAP_COMPREF_FROM_BEGINNING;
300 else if ( (cav->cav_end - cav->cav_ptr) >= 7 &&
301 strncmp(cav->cav_ptr,"content",7) == 0 )
302 return LDAP_COMPREF_CONTENT;
303 else if ( (cav->cav_ptr[0] >= 'a' && cav->cav_ptr[0] <= 'z') ||
304 (cav->cav_ptr[0] >= 'A' && cav->cav_ptr[0] <= 'Z') )
306 return LDAP_COMPREF_IDENTIFIER;
308 return LDAP_COMPREF_UNDEFINED;
312 comp_next_id( ComponentAssertionValue* cav )
315 if ( *(cav->cav_ptr) == '.' ) {
317 return LDAP_COMPREF_DEFINED;
319 else return LDAP_COMPREF_UNDEFINED;
323 get_component_reference( Operation *op, ComponentAssertionValue* cav,
324 ComponentReference** cr, const char** text )
328 ComponentReference* ca_comp_ref;
329 ComponentId** cr_list;
333 op->o_tmpalloc( sizeof( ComponentReference ), op->o_tmpmemctx );
335 cr_list = &ca_comp_ref->cr_list;
336 strip_cav_str( cav, "\"");
337 for ( type = peek_componentId_type( cav ) ; type != LDAP_COMPREF_UNDEFINED
338 ; type = comp_next_id( cav ), count++ ) {
339 rc = get_componentId( op, cav, cr_list, text );
340 if ( rc == LDAP_SUCCESS ) {
341 if ( count == 0 ) ca_comp_ref->cr_curr = ca_comp_ref->cr_list;
342 cr_list = &(*cr_list)->ci_next;
344 else if ( rc == LDAP_COMPREF_UNDEFINED )
347 ca_comp_ref->cr_len = count;
348 strip_cav_str( cav, "\"");
350 if ( rc == LDAP_SUCCESS ) {
354 else op->o_tmpfree( ca_comp_ref , op->o_tmpmemctx );
360 get_ca_use_default( Operation *op, ComponentAssertionValue* cav,
361 int* ca_use_def, const char** text )
364 if ( peek_cav_str( cav, "useDefaultValues" ) == LDAP_SUCCESS ) {
365 strip_cav_str( cav, "useDefaultValues" );
366 if ( peek_cav_str( cav, "TRUE" ) == LDAP_SUCCESS ) {
367 strip_cav_str( cav, "TRUE" );
370 else if ( peek_cav_str( cav, "FALSE" ) == LDAP_SUCCESS ) {
371 strip_cav_str( cav, "FALSE" );
375 return LDAP_INVALID_SYNTAX;
377 else /* If not defined, default value is TRUE */
383 get_matching_rule( Operation *op, ComponentAssertionValue* cav,
384 MatchingRule** mr, const char** text )
388 struct berval rule_text = { 0L, NULL };
392 for ( ; ; count++ ) {
393 if ( cav->cav_ptr[count] == ' ' || cav->cav_ptr[count] == ',' ||
394 cav->cav_ptr[count] == '\0' || cav->cav_ptr[count] == '{' ||
395 cav->cav_ptr[count] == '}' || cav->cav_ptr[count] == '\n' )
400 *text = "component matching rule not recognized";
401 return LDAP_INAPPROPRIATE_MATCHING;
404 rule_text.bv_len = count;
405 rule_text.bv_val = cav->cav_ptr;
406 *mr = mr_bvfind( &rule_text );
407 cav->cav_ptr += count;
408 Debug( LDAP_DEBUG_FILTER, "get_matching_rule: %s\n", (*mr)->smr_mrule.mr_oid, 0, 0 );
410 *text = "component matching rule not recognized";
411 return LDAP_INAPPROPRIATE_MATCHING;
417 get_GSER_value( ComponentAssertionValue* cav, struct berval* bv )
419 int count, sequent_dquote, unclosed_brace, succeed;
423 * Four cases of GSER <Values>
425 * StringVal, GeneralizedTimeVal, UTCTimeVal, ObjectDescriptorVal
426 * 2) '...'B or '...'H :
427 * BitStringVal, OctetStringVal
429 * SEQUENCE, SEQUENCEOF, SETOF, SET, CHOICE
430 * 4) Between two white spaces
431 * INTEGER, BOOLEAN, NULL,ENUMERATE, etc
435 if ( cav->cav_ptr[0] == '"' ) {
436 for( count = 1, sequent_dquote = 0 ; ; count++ ) {
437 /* In order to find escaped double quote */
438 if ( cav->cav_ptr[count] == '"' ) sequent_dquote++;
439 else sequent_dquote = 0;
441 if ( cav->cav_ptr[count] == '\0' || cav->cav_ptr > cav->cav_end ) {
445 if ( ( cav->cav_ptr[count] == '"' && cav->cav_ptr[count-1] != '"') ||
446 ( sequent_dquote > 2 && (sequent_dquote%2) == 1 ) ) {
452 else if ( cav->cav_ptr[0] == '\'' ) {
453 for( count = 1 ; ; count++ ) {
454 if ( cav->cav_ptr[count] == '\0' || cav->cav_ptr > cav->cav_end ) {
457 if ((cav->cav_ptr[count-1] == '\'' && cav->cav_ptr[count] == 'B')||
458 (cav->cav_ptr[count-1] == '\'' && cav->cav_ptr[count] == 'H') ) {
465 else if ( cav->cav_ptr[0] == '{' ) {
466 for( count = 1, unclosed_brace = 1 ; ; count++ ) {
467 if ( cav->cav_ptr[count] == '{' ) unclosed_brace++;
468 if ( cav->cav_ptr[count] == '}' ) unclosed_brace--;
470 if ( cav->cav_ptr[count] == '\0' || cav->cav_ptr > cav->cav_end )
472 if ( unclosed_brace == 0 ) {
480 count = cav->cav_end - cav->cav_ptr;
483 if ( !succeed ) return LDAP_FILTER_ERROR;
485 bv->bv_val = cav->cav_ptr;
486 bv->bv_len = count + 1 ;
487 cav->cav_ptr += count;
492 get_matching_value( Operation *op, ComponentAssertion* ca,
493 ComponentAssertionValue* cav, struct berval* bv,
499 if ( !(ca->ca_ma_rule->smr_usage & (SLAP_MR_COMPONENT)) ) {
500 if ( get_GSER_value( cav, bv ) != LDAP_SUCCESS )
501 return LDAP_FILTER_ERROR;
504 /* embeded componentFilterMatch Description */
505 bv->bv_val = cav->cav_ptr;
506 bv->bv_len = cav_cur_len( cav );
512 /* Don't move the position pointer, just peek given string */
514 peek_cav_str( ComponentAssertionValue* cav, char* str )
517 if ( cav_cur_len( cav ) >= strlen( str ) &&
518 strncmp( cav->cav_ptr, str, strlen( str ) ) == 0 )
521 return LDAP_INVALID_SYNTAX;
525 strip_cav_str( ComponentAssertionValue* cav, char* str)
528 if ( cav_cur_len( cav ) >= strlen( str ) &&
529 strncmp( cav->cav_ptr, str, strlen( str ) ) == 0 ) {
530 cav->cav_ptr += strlen( str );
534 return LDAP_INVALID_SYNTAX;
538 * TAG : "item", "and", "or", "not"
541 strip_cav_tag( ComponentAssertionValue* cav )
545 if ( cav_cur_len( cav ) >= 8 && strncmp( cav->cav_ptr, "item", 4 ) == 0 ) {
546 strip_cav_str( cav , "item:" );
547 return LDAP_COMP_FILTER_ITEM;
549 else if ( cav_cur_len( cav ) >= 7 && strncmp( cav->cav_ptr, "and", 3 ) == 0 ) {
550 strip_cav_str( cav , "and:" );
551 return LDAP_COMP_FILTER_AND;
553 else if ( cav_cur_len( cav ) >= 6 && strncmp( cav->cav_ptr, "or" , 2 ) == 0 ) {
554 strip_cav_str( cav , "or:" );
555 return LDAP_COMP_FILTER_OR;
557 else if ( cav_cur_len( cav ) >= 7 && strncmp( cav->cav_ptr, "not", 3 ) == 0 ) {
558 strip_cav_str( cav , "not:" );
559 return LDAP_COMP_FILTER_NOT;
566 * when encoding, "item" is denotation of ComponentAssertion
567 * ComponentAssertion :: SEQUENCE {
568 * component ComponentReference (SIZE(1..MAX)) OPTIONAL,
569 * useDefaultValues BOOLEAN DEFAULT TRUE,
570 * rule MATCHING-RULE.&id,
571 * value MATCHING-RULE.&AssertionType }
574 get_item( Operation *op, ComponentAssertionValue* cav, ComponentAssertion** ca,
578 ComponentAssertion* _ca;
580 Debug( LDAP_DEBUG_FILTER, "get_item: %s\n", 0, 0, 0 );
581 _ca = op->o_tmpalloc( sizeof( ComponentAssertion ), op->o_tmpmemctx );
583 _ca->ca_component_values = NULL;
585 rc = peek_cav_str( cav, "component" );
586 if ( rc == LDAP_SUCCESS ) {
587 strip_cav_str( cav, "component" );
588 rc = get_component_reference( op, cav, &_ca->ca_comp_ref, text );
589 if ( rc != LDAP_SUCCESS ) {
590 rc = LDAP_INVALID_SYNTAX;
591 op->o_tmpfree( _ca, op->o_tmpmemctx );
596 strip_cav_str( cav,",");
597 rc = peek_cav_str( cav, "useDefaultValues");
598 if ( rc == LDAP_SUCCESS ) {
599 rc = get_ca_use_default( op, cav, &_ca->ca_use_def, text );
600 if ( rc != LDAP_SUCCESS ) {
601 rc = LDAP_INVALID_SYNTAX;
602 op->o_tmpfree( _ca, op->o_tmpmemctx );
605 strip_cav_str( cav,",");
608 if ( !( strip_cav_str( cav, "rule" ) == LDAP_SUCCESS &&
609 get_matching_rule( op, cav , &_ca->ca_ma_rule, text ) == LDAP_SUCCESS )) {
610 rc = LDAP_INAPPROPRIATE_MATCHING;
611 op->o_tmpfree( _ca, op->o_tmpmemctx );
615 strip_cav_str( cav,",");
616 if ( !(strip_cav_str( cav, "value" ) == LDAP_SUCCESS &&
617 get_matching_value( op, _ca, cav, &_ca->ca_ma_value,text ) == LDAP_SUCCESS )) {
618 rc = LDAP_INVALID_SYNTAX;
619 op->o_tmpfree( _ca, op->o_tmpmemctx );
623 /* componentFilterMatch contains componentFilterMatch in it */
624 if ( strcmp(_ca->ca_ma_rule->smr_mrule.mr_oid, OID_COMP_FILTER_MATCH ) == 0) {
626 bv.bv_val = cav->cav_ptr;
627 bv.bv_len = cav_cur_len( cav );
628 rc = get_comp_filter( op, &bv,(ComponentFilter**)&_ca->ca_cf, text );
629 if ( rc != LDAP_SUCCESS ) {
630 op->o_tmpfree( _ca, op->o_tmpmemctx );
633 cav->cav_ptr = bv.bv_val;
634 assert( cav->cav_end >= bv.bv_val );
642 parse_comp_filter( Operation* op, ComponentAssertionValue* cav,
643 ComponentFilter** filt, const char** text )
646 * A component filter looks like this coming in:
647 * Filter ::= CHOICE {
648 * item [0] ComponentAssertion,
649 * and [1] SEQUENCE OF ComponentFilter,
650 * or [2] SEQUENCE OF ComponentFilter,
651 * not [3] ComponentFilter,
659 /* TAG : item, and, or, not in RFC 2254 */
660 tag = strip_cav_tag( cav );
662 if ( tag == LBER_ERROR ) {
663 *text = "error decoding comp filter";
664 return LDAP_PROTOCOL_ERROR;
667 if ( tag != LDAP_COMP_FILTER_NOT )
668 strip_cav_str( cav, "{");
675 switch ( f.cf_choice ) {
676 case LDAP_COMP_FILTER_AND:
677 Debug( LDAP_DEBUG_FILTER, "LDAP_COMP_FILTER_AND\n", 0, 0, 0 );
678 err = get_comp_filter_list( op, cav, &f.cf_and, text );
679 if ( err != LDAP_SUCCESS ) {
682 if ( f.cf_and == NULL ) {
683 f.cf_choice = SLAPD_FILTER_COMPUTED;
684 f.cf_result = LDAP_COMPARE_TRUE;
688 case LDAP_COMP_FILTER_OR:
689 Debug( LDAP_DEBUG_FILTER, "LDAP_COMP_FILTER_OR\n", 0, 0, 0 );
690 err = get_comp_filter_list( op, cav, &f.cf_or, text );
691 if ( err != LDAP_SUCCESS ) {
694 if ( f.cf_or == NULL ) {
695 f.cf_choice = SLAPD_FILTER_COMPUTED;
696 f.cf_result = LDAP_COMPARE_FALSE;
698 /* no assert - list could be empty */
701 case LDAP_COMP_FILTER_NOT:
702 Debug( LDAP_DEBUG_FILTER, "LDAP_COMP_FILTER_NOT\n", 0, 0, 0 );
703 err = parse_comp_filter( op, cav, &f.cf_not, text );
704 if ( err != LDAP_SUCCESS ) {
708 assert( f.cf_not != NULL );
709 if ( f.cf_not->cf_choice == SLAPD_FILTER_COMPUTED ) {
710 int fresult = f.cf_not->cf_result;
711 f.cf_choice = SLAPD_FILTER_COMPUTED;
712 op->o_tmpfree( f.cf_not, op->o_tmpmemctx );
716 case LDAP_COMPARE_TRUE:
717 f.cf_result = LDAP_COMPARE_FALSE;
719 case LDAP_COMPARE_FALSE:
720 f.cf_result = LDAP_COMPARE_TRUE;
723 /* (!Undefined) is Undefined */
728 case LDAP_COMP_FILTER_ITEM:
729 Debug( LDAP_DEBUG_FILTER, "LDAP_COMP_FILTER_ITEM\n", 0, 0, 0 );
730 err = get_item( op, cav, &f.cf_ca, text );
731 if ( err != LDAP_SUCCESS ) {
735 assert( f.cf_ca != NULL );
739 f.cf_choice = SLAPD_FILTER_COMPUTED;
740 f.cf_result = SLAPD_COMPARE_UNDEFINED;
744 if ( tag != LDAP_COMP_FILTER_NOT )
745 strip_cav_str( cav, "}");
747 if ( err != LDAP_SUCCESS && err != SLAPD_DISCONNECT ) {
749 f.cf_choice = SLAPD_FILTER_COMPUTED;
750 f.cf_result = SLAPD_COMPARE_UNDEFINED;
754 if ( err == LDAP_SUCCESS ) {
755 *filt = op->o_tmpalloc( sizeof(f), op->o_tmpmemctx );
763 test_comp_filter_and(
767 ComponentFilter *flist )
770 int rtn = LDAP_COMPARE_TRUE;
772 for ( f = flist ; f != NULL; f = f->cf_next ) {
773 int rc = test_comp_filter( syn, a, bv, f );
774 if ( rc == LDAP_COMPARE_FALSE ) {
779 if ( rc != LDAP_COMPARE_TRUE ) {
792 ComponentFilter *flist )
795 int rtn = LDAP_COMPARE_TRUE;
797 for ( f = flist ; f != NULL; f = f->cf_next ) {
798 int rc = test_comp_filter( syn, a, bv, f );
799 if ( rc == LDAP_COMPARE_TRUE ) {
804 if ( rc != LDAP_COMPARE_FALSE ) {
813 csi_value_match( MatchingRule *mr, struct berval* bv_attr,
814 struct berval* bv_assert )
819 assert( mr != NULL );
820 assert( !(mr->smr_usage & SLAP_MR_COMPONENT) );
822 if( !mr->smr_match ) {
823 return LDAP_INAPPROPRIATE_MATCHING;
826 rc = (mr->smr_match)( &match, 0, NULL /*ad->ad_type->sat_syntax*/,
827 mr, bv_attr, bv_assert );
828 if ( rc == LDAP_SUCCESS )
829 return match? LDAP_COMPARE_FALSE:LDAP_COMPARE_TRUE;
835 component_value_match( MatchingRule* mr,
836 ComponentSyntaxInfo* csi_attr, ComponentSyntaxInfo* csi_assert )
840 if ( mr->smr_usage & SLAP_MR_COMPONENT ){
841 if( strcmp( mr->smr_mrule.mr_oid, OID_ALL_COMP_MATCH ) == 0 ){
842 /* allComponentMatch */
843 return csi_attr->csi_comp_desc->cd_all_match( NULL,
844 csi_attr, csi_assert );
847 return csi_assert->csi_comp_desc->cd_all_match(
848 mr->smr_mrule.mr_oid, csi_attr, csi_assert );
852 if ( csi_attr->csi_comp_desc->cd_type == ASN_BASIC ) {
853 struct berval bv1, bv2;
854 char attr_buf[MAX_LDAP_STR_LEN],assert_buf[MAX_LDAP_STR_LEN];
855 bv1.bv_val = attr_buf;
856 bv2.bv_val = assert_buf;
857 if ( csi_converter &&
858 ( csi_converter ( csi_attr, &bv1 ) == LDAP_SUCCESS ) && ( csi_converter ( csi_assert, &bv2 ) == LDAP_SUCCESS ) )
859 return csi_value_match( mr, &bv1, &bv2 );
861 return LDAP_INAPPROPRIATE_MATCHING;
864 else if ( csi_attr->csi_comp_desc->cd_type == ASN_COMPOSITE ) {
865 return LDAP_INAPPROPRIATE_MATCHING;
871 * return codes : LDAP_COMPARE_TRUE, LDAP_COMPARE_FALSE
875 test_comp_filter_item(
879 ComponentAssertion *ca )
882 ComponentSyntaxInfo* csi_attr, *csi_assert=NULL;
884 if ( strcmp(ca->ca_ma_rule->smr_mrule.mr_oid,
885 OID_COMP_FILTER_MATCH ) == 0 && ca->ca_cf ) {
886 /* componentFilterMatch inside of componentFilterMatch */
887 rc = test_comp_filter( syn, a, bv, ca->ca_cf );
891 /* load attribute containg components */
892 /* For a testing purpose, link following function here */
893 if ( !a->a_component_values && attr_converter )
894 a->a_component_values = attr_converter (a, syn, bv);
896 if ( a->a_component_values == NULL )
897 return LDAP_PROTOCOL_ERROR;
899 /* load component containg the referenced component */
900 ca->ca_comp_ref->cr_curr = ca->ca_comp_ref->cr_list;
901 csi_attr = (((ComponentSyntaxInfo*)a->a_component_values)->csi_comp_desc->cd_extract_i)( ca->ca_comp_ref, a->a_component_values );
904 return LDAP_PROTOCOL_ERROR;
906 /* decode the asserted value */
907 if( !ca->ca_component_values && assert_converter ) {
908 assert_converter ( csi_attr, &ca->ca_ma_value,
909 &csi_assert, &len, DEC_ALLOC_MODE_0 );
910 ca->ca_component_values = (void*)csi_assert;
912 else csi_assert = ca->ca_component_values;
915 return LDAP_PROTOCOL_ERROR;
917 return component_value_match( ca->ca_ma_rule, csi_attr, csi_assert);
929 if ( !f ) return LDAP_PROTOCOL_ERROR;
931 Debug( LDAP_DEBUG_FILTER, "test_comp_filter\n", 0, 0, 0 );
932 switch ( f->cf_choice ) {
933 case SLAPD_FILTER_COMPUTED:
936 case LDAP_COMP_FILTER_AND:
937 rc = test_comp_filter_and( syn, a, bv, f->cf_and );
939 case LDAP_COMP_FILTER_OR:
940 rc = test_comp_filter_or( syn, a, bv, f->cf_or );
942 case LDAP_COMP_FILTER_NOT:
943 rc = test_comp_filter( syn, a, bv, f->cf_not );
946 case LDAP_COMPARE_TRUE:
947 rc = LDAP_COMPARE_FALSE;
949 case LDAP_COMPARE_FALSE:
950 rc = LDAP_COMPARE_TRUE;
954 case LDAP_COMP_FILTER_ITEM:
955 rc = test_comp_filter_item( syn, a, bv, f->cf_ca );
958 rc = LDAP_PROTOCOL_ERROR;
965 free_comp_filter_list( ComponentFilter* f )
967 ComponentFilter* tmp;
968 for ( tmp = f ; tmp; tmp = tmp->cf_next );
970 free_comp_filter( tmp );
975 free_comp_filter( ComponentFilter* f )
977 switch ( f->cf_choice ) {
978 case LDAP_COMP_FILTER_AND:
979 case LDAP_COMP_FILTER_OR:
980 case LDAP_COMP_FILTER_NOT:
981 free_comp_filter( f->cf_any );
984 case LDAP_COMP_FILTER_ITEM:
985 if ( component_destructor && f->cf_ca->ca_component_values )
986 component_destructor( f->cf_ca->ca_component_values );
995 component_free( ComponentFilter *f ) {
996 free_comp_filter( f );