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 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_one_component = NULL;
41 test_component_func* test_all_components = NULL;
43 #define OID_ALL_COMP_MATCH "1.2.36.79672281.1.13.6"
44 #define OID_COMP_FILTER_MATCH "1.2.36.79672281.1.13.2"
45 #define MAX_LDAP_STR_LEN 128
48 peek_componentId_type( ComponentAssertionValue* cav );
51 strip_cav_str( ComponentAssertionValue* cav, char* str);
54 peek_cav_str( ComponentAssertionValue* cav, char* str );
57 parse_comp_filter( Operation* op, ComponentAssertionValue* cav,
58 ComponentFilter** filt, const char** text );
61 free_comp_filter( ComponentFilter* f );
64 test_comp_filter( Syntax *syn, Attribute *a, struct berval *bv,
68 componentCertificateValidate(
76 componentFilterValidate(
84 allComponentsValidate(
92 componentFilterMatch (
100 Attribute *a = (Attribute*)value;
101 MatchingRuleAssertion * ma = (MatchingRuleAssertion*)assertedValue;
105 if ( !(mr && mr->smr_usage & SLAP_MR_COMPONENT) || !ma->ma_cf )
106 return LDAP_INAPPROPRIATE_MATCHING;
108 rc = test_comp_filter( syntax, a, a->a_vals, ma->ma_cf );
110 if ( rc == LDAP_COMPARE_TRUE ) {
114 else if ( rc == LDAP_COMPARE_FALSE ) {
119 return LDAP_INAPPROPRIATE_MATCHING;
124 directoryComponentsMatch(
129 struct berval *value,
130 void *assertedValue )
132 /* Only for Registeration */
143 struct berval *value,
144 void *assertedValue )
146 /* Only for Registeration */
152 slapd_ber2cav( struct berval* bv, ComponentAssertionValue* cav)
156 cav->cav_ptr = cav->cav_buf = bv->bv_val;
157 cav->cav_end = bv->bv_val + bv->bv_len;
163 get_comp_filter( Operation* op, struct berval* bv, ComponentFilter** filt,
166 ComponentAssertionValue cav;
169 Debug( LDAP_DEBUG_FILTER, "get_comp_filter\n", 0, 0, 0 );
170 if ( (rc = slapd_ber2cav(bv, &cav) ) != LDAP_SUCCESS ) {
173 rc = parse_comp_filter( op, &cav, filt, text );
174 bv->bv_val = cav.cav_ptr;
180 eat_whsp( ComponentAssertionValue* cav )
182 for ( ; ( *cav->cav_ptr == ' ' ) && ( cav->cav_ptr < cav->cav_end ) ; ) {
188 cav_cur_len( ComponentAssertionValue* cav )
190 return cav->cav_end - cav->cav_ptr;
194 comp_first_element( ComponentAssertionValue* cav )
197 if ( cav_cur_len( cav ) >= 8 && strncmp( cav->cav_ptr, "item", 4 ) == 0 ) {
198 return LDAP_COMP_FILTER_ITEM;
200 else if ( cav_cur_len( cav ) >= 7 && strncmp( cav->cav_ptr, "and", 3 ) == 0 ) {
201 return LDAP_COMP_FILTER_AND;
203 else if ( cav_cur_len( cav ) >= 6 && strncmp( cav->cav_ptr, "or" , 2 ) == 0 ) {
204 return LDAP_COMP_FILTER_OR;
206 else if ( cav_cur_len( cav ) >= 7 && strncmp( cav->cav_ptr, "not", 3 ) == 0 ) {
207 return LDAP_COMP_FILTER_NOT;
210 return LDAP_COMP_FILTER_UNDEFINED;
214 comp_next_element( ComponentAssertionValue* cav )
218 if ( *(cav->cav_ptr) == ',' ) {
219 /* move pointer to the next CA */
221 return comp_first_element( cav );
223 else return LDAP_COMP_FILTER_UNDEFINED;
227 get_comp_filter_list( Operation *op, ComponentAssertionValue *cav,
228 ComponentFilter** f, const char** text )
230 ComponentFilter **new;
234 Debug( LDAP_DEBUG_FILTER, "get_comp_filter_list\n", 0, 0, 0 );
236 for ( tag = comp_first_element( cav ); tag != LDAP_COMP_FILTER_UNDEFINED;
237 tag = comp_next_element( cav ) )
239 err = parse_comp_filter( op, cav, new, text );
240 if ( err != LDAP_SUCCESS )
242 new = &(*new)->cf_next;
246 return( LDAP_SUCCESS );
250 get_componentId( Operation *op, ComponentAssertionValue* cav,
251 ComponentId ** cid, const char** text )
257 type = peek_componentId_type( cav );
259 Debug( LDAP_DEBUG_FILTER, "get_compId [%d]\n", type, 0, 0 );
264 case LDAP_COMPREF_IDENTIFIER :
265 _cid.ci_val.ci_identifier.bv_val = cav->cav_ptr;
266 for( ;cav->cav_ptr[len] != ' ' && cav->cav_ptr[len] != '\0' &&
267 cav->cav_ptr[len] != '.' && cav->cav_ptr[len] != '\"' ; len++ );
268 _cid.ci_val.ci_identifier.bv_len = len;
271 case LDAP_COMPREF_FROM_BEGINNING :
272 for( ;cav->cav_ptr[len] != ' ' && cav->cav_ptr[len] != '\0' &&
273 cav->cav_ptr[len] != '.' && cav->cav_ptr[len] != '\"' ; len++ );
274 _cid.ci_val.ci_from_beginning = strtol( cav->cav_ptr, NULL, 0 );
277 case LDAP_COMPREF_FROM_END :
278 for( ;cav->cav_ptr[len] != ' ' && cav->cav_ptr[len] != '\0' &&
279 cav->cav_ptr[len] != '.' && cav->cav_ptr[len] != '\"' ; len++ );
280 _cid.ci_val.ci_from_end = strtol( cav->cav_ptr, NULL, 0 );
283 case LDAP_COMPREF_COUNT :
284 _cid.ci_val.ci_count = 0;
287 case LDAP_COMPREF_CONTENT :
288 _cid.ci_val.ci_content = 1;
289 cav->cav_ptr += strlen("content");
291 case LDAP_COMPREF_SELECT :
292 if ( cav->cav_ptr[len] != '(' )
293 return LDAP_COMPREF_UNDEFINED;
294 for( ;cav->cav_ptr[len] != ' ' && cav->cav_ptr[len] != '\0' &&
295 cav->cav_ptr[len] != '.' && cav->cav_ptr[len] != '\"' &&
296 cav->cav_ptr[len] != ')' ; len++ );
297 _cid.ci_val.ci_select_value.bv_val = cav->cav_ptr + 1;
298 _cid.ci_val.ci_select_value.bv_len = len - 1 ;
301 case LDAP_COMPREF_ALL :
302 _cid.ci_val.ci_all = '*';
306 return LDAP_COMPREF_UNDEFINED;
309 *cid = op->o_tmpalloc( sizeof( ComponentId ), op->o_tmpmemctx );
315 peek_componentId_type( ComponentAssertionValue* cav )
318 if ( cav->cav_ptr[0] == '-' )
319 return LDAP_COMPREF_FROM_END;
320 else if ( cav->cav_ptr[0] == '(' )
321 return LDAP_COMPREF_SELECT;
322 else if ( cav->cav_ptr[0] == '*' )
323 return LDAP_COMPREF_ALL;
324 else if ( strncmp(cav->cav_ptr,"all",3) == 0 )
325 return LDAP_COMPREF_ALL;
326 else if ( cav->cav_ptr[0] == '0' )
327 return LDAP_COMPREF_COUNT;
328 else if ( cav->cav_ptr[0] > '0' && cav->cav_ptr[0] <= '9' )
329 return LDAP_COMPREF_FROM_BEGINNING;
330 else if ( (cav->cav_end - cav->cav_ptr) >= 7 &&
331 strncmp(cav->cav_ptr,"content",7) == 0 )
332 return LDAP_COMPREF_CONTENT;
333 else if ( (cav->cav_ptr[0] >= 'a' && cav->cav_ptr[0] <= 'z') ||
334 (cav->cav_ptr[0] >= 'A' && cav->cav_ptr[0] <= 'Z') )
336 return LDAP_COMPREF_IDENTIFIER;
338 return LDAP_COMPREF_UNDEFINED;
342 comp_next_id( ComponentAssertionValue* cav )
345 if ( *(cav->cav_ptr) == '.' ) {
347 return LDAP_COMPREF_DEFINED;
349 else return LDAP_COMPREF_UNDEFINED;
353 get_component_reference( Operation *op, ComponentAssertionValue* cav,
354 ComponentReference** cr, const char** text )
358 ComponentReference* ca_comp_ref;
359 ComponentId** cr_list;
363 if ( ( rc = strip_cav_str( cav,"\"") ) != LDAP_SUCCESS )
367 op->o_tmpalloc( sizeof( ComponentReference ), op->o_tmpmemctx );
369 cr_list = &ca_comp_ref->cr_list;
371 for ( type = peek_componentId_type( cav ) ; type != LDAP_COMPREF_UNDEFINED
372 ; type = comp_next_id( cav ), count++ ) {
373 rc = get_componentId( op, cav, cr_list, text );
374 if ( rc == LDAP_SUCCESS ) {
375 if ( count == 0 ) ca_comp_ref->cr_curr = ca_comp_ref->cr_list;
376 cr_list = &(*cr_list)->ci_next;
378 else if ( rc == LDAP_COMPREF_UNDEFINED )
381 ca_comp_ref->cr_len = count;
383 if ( ( rc = strip_cav_str( cav,"\"") ) != LDAP_SUCCESS ) {
384 op->o_tmpfree( ca_comp_ref , op->o_tmpmemctx );
388 if ( rc == LDAP_SUCCESS ) {
392 else op->o_tmpfree( ca_comp_ref , op->o_tmpmemctx );
398 get_ca_use_default( Operation *op, ComponentAssertionValue* cav,
399 int* ca_use_def, const char** text )
401 strip_cav_str( cav, "useDefaultValues" );
402 if ( peek_cav_str( cav, "TRUE" ) == LDAP_SUCCESS ) {
403 strip_cav_str( cav, "TRUE" );
405 } else if ( peek_cav_str( cav, "FALSE" ) == LDAP_SUCCESS ) {
406 strip_cav_str( cav, "FALSE" );
409 return LDAP_INVALID_SYNTAX;
416 get_matching_rule( Operation *op, ComponentAssertionValue* cav,
417 MatchingRule** mr, const char** text )
420 struct berval rule_text = { 0L, NULL };
424 for ( ; ; count++ ) {
425 if ( cav->cav_ptr[count] == ' ' || cav->cav_ptr[count] == ',' ||
426 cav->cav_ptr[count] == '\0' || cav->cav_ptr[count] == '{' ||
427 cav->cav_ptr[count] == '}' || cav->cav_ptr[count] == '\n' )
432 *text = "component matching rule not recognized";
433 return LDAP_INAPPROPRIATE_MATCHING;
436 rule_text.bv_len = count;
437 rule_text.bv_val = cav->cav_ptr;
438 *mr = mr_bvfind( &rule_text );
439 cav->cav_ptr += count;
440 Debug( LDAP_DEBUG_FILTER, "get_matching_rule: %s\n", (*mr)->smr_mrule.mr_oid, 0, 0 );
442 *text = "component matching rule not recognized";
443 return LDAP_INAPPROPRIATE_MATCHING;
449 get_GSER_value( ComponentAssertionValue* cav, struct berval* bv )
451 int count, sequent_dquote, unclosed_brace, succeed;
455 * Four cases of GSER <Values>
457 * StringVal, GeneralizedTimeVal, UTCTimeVal, ObjectDescriptorVal
458 * 2) '...'B or '...'H :
459 * BitStringVal, OctetStringVal
461 * SEQUENCE, SEQUENCEOF, SETOF, SET, CHOICE
462 * 4) Between two white spaces
463 * INTEGER, BOOLEAN, NULL,ENUMERATE, etc
467 if ( cav->cav_ptr[0] == '"' ) {
468 for( count = 1, sequent_dquote = 0 ; ; count++ ) {
469 /* In order to find escaped double quote */
470 if ( cav->cav_ptr[count] == '"' ) sequent_dquote++;
471 else sequent_dquote = 0;
473 if ( cav->cav_ptr[count] == '\0' || (cav->cav_ptr+count) > cav->cav_end ) {
477 if ( ( cav->cav_ptr[count] == '"' && cav->cav_ptr[count-1] != '"') ||
478 ( sequent_dquote > 2 && (sequent_dquote%2) == 1 ) ) {
484 else if ( cav->cav_ptr[0] == '\'' ) {
485 for( count = 1 ; ; count++ ) {
486 if ( cav->cav_ptr[count] == '\0' || (cav->cav_ptr+count) > cav->cav_end ) {
489 if ((cav->cav_ptr[count-1] == '\'' && cav->cav_ptr[count] == 'B')||
490 (cav->cav_ptr[count-1] == '\'' && cav->cav_ptr[count] == 'H') ) {
497 else if ( cav->cav_ptr[0] == '{' ) {
498 for( count = 1, unclosed_brace = 1 ; ; count++ ) {
499 if ( cav->cav_ptr[count] == '{' ) unclosed_brace++;
500 if ( cav->cav_ptr[count] == '}' ) unclosed_brace--;
502 if ( cav->cav_ptr[count] == '\0' || (cav->cav_ptr+count) > cav->cav_end )
504 if ( unclosed_brace == 0 ) {
512 /*Find following white space where the value is ended*/
513 for( count = 1 ; ; count++ ) {
514 if ( cav->cav_ptr[count] == '\0' || cav->cav_ptr[count] == ' ' || (cav->cav_ptr+count) > cav->cav_end ) {
520 if ( !succeed ) return LDAP_FILTER_ERROR;
522 bv->bv_val = cav->cav_ptr;
524 cav->cav_ptr += count;
529 get_matching_value( Operation *op, ComponentAssertion* ca,
530 ComponentAssertionValue* cav, struct berval* bv,
533 if ( !(ca->ca_ma_rule->smr_usage & (SLAP_MR_COMPONENT)) ) {
534 if ( get_GSER_value( cav, bv ) != LDAP_SUCCESS ) {
535 return LDAP_FILTER_ERROR;
539 /* embeded componentFilterMatch Description */
540 bv->bv_val = cav->cav_ptr;
541 bv->bv_len = cav_cur_len( cav );
547 /* Don't move the position pointer, just peek given string */
549 peek_cav_str( ComponentAssertionValue* cav, char* str )
552 if ( cav_cur_len( cav ) >= strlen( str ) &&
553 strncmp( cav->cav_ptr, str, strlen( str ) ) == 0 )
556 return LDAP_INVALID_SYNTAX;
560 strip_cav_str( ComponentAssertionValue* cav, char* str)
563 if ( cav_cur_len( cav ) >= strlen( str ) &&
564 strncmp( cav->cav_ptr, str, strlen( str ) ) == 0 ) {
565 cav->cav_ptr += strlen( str );
569 return LDAP_INVALID_SYNTAX;
573 * TAG : "item", "and", "or", "not"
576 strip_cav_tag( ComponentAssertionValue* cav )
580 if ( cav_cur_len( cav ) >= 8 && strncmp( cav->cav_ptr, "item", 4 ) == 0 ) {
581 strip_cav_str( cav , "item:" );
582 return LDAP_COMP_FILTER_ITEM;
584 else if ( cav_cur_len( cav ) >= 7 && strncmp( cav->cav_ptr, "and", 3 ) == 0 ) {
585 strip_cav_str( cav , "and:" );
586 return LDAP_COMP_FILTER_AND;
588 else if ( cav_cur_len( cav ) >= 6 && strncmp( cav->cav_ptr, "or" , 2 ) == 0 ) {
589 strip_cav_str( cav , "or:" );
590 return LDAP_COMP_FILTER_OR;
592 else if ( cav_cur_len( cav ) >= 7 && strncmp( cav->cav_ptr, "not", 3 ) == 0 ) {
593 strip_cav_str( cav , "not:" );
594 return LDAP_COMP_FILTER_NOT;
601 * when encoding, "item" is denotation of ComponentAssertion
602 * ComponentAssertion :: SEQUENCE {
603 * component ComponentReference (SIZE(1..MAX)) OPTIONAL,
604 * useDefaultValues BOOLEAN DEFAULT TRUE,
605 * rule MATCHING-RULE.&id,
606 * value MATCHING-RULE.&AssertionType }
609 get_item( Operation *op, ComponentAssertionValue* cav, ComponentAssertion** ca,
613 ComponentAssertion* _ca;
615 Debug( LDAP_DEBUG_FILTER, "get_item: %s\n", 0, 0, 0 );
616 _ca = op->o_tmpalloc( sizeof( ComponentAssertion ), op->o_tmpmemctx );
618 _ca->ca_comp_data.cd_tree = NULL;
619 _ca->ca_comp_data.cd_mem_op = NULL;
621 rc = peek_cav_str( cav, "component" );
622 if ( rc == LDAP_SUCCESS ) {
623 strip_cav_str( cav, "component" );
624 rc = get_component_reference( op, cav, &_ca->ca_comp_ref, text );
625 if ( rc != LDAP_SUCCESS ) {
626 rc = LDAP_INVALID_SYNTAX;
627 op->o_tmpfree( _ca, op->o_tmpmemctx );
632 if ( ( rc = strip_cav_str( cav,",") ) != LDAP_SUCCESS )
635 rc = peek_cav_str( cav, "useDefaultValues");
636 if ( rc == LDAP_SUCCESS ) {
637 rc = get_ca_use_default( op, cav, &_ca->ca_use_def, text );
638 if ( rc != LDAP_SUCCESS ) {
639 rc = LDAP_INVALID_SYNTAX;
640 op->o_tmpfree( _ca, op->o_tmpmemctx );
643 if ( ( rc = strip_cav_str( cav,",") ) != LDAP_SUCCESS )
646 else _ca->ca_use_def = 1;
648 if ( !( strip_cav_str( cav, "rule" ) == LDAP_SUCCESS &&
649 get_matching_rule( op, cav , &_ca->ca_ma_rule, text ) == LDAP_SUCCESS )) {
650 rc = LDAP_INAPPROPRIATE_MATCHING;
651 op->o_tmpfree( _ca, op->o_tmpmemctx );
655 if ( ( rc = strip_cav_str( cav,",") ) != LDAP_SUCCESS )
657 if ( !(strip_cav_str( cav, "value" ) == LDAP_SUCCESS &&
658 get_matching_value( op, _ca, cav, &_ca->ca_ma_value,text ) == LDAP_SUCCESS )) {
659 rc = LDAP_INVALID_SYNTAX;
660 op->o_tmpfree( _ca, op->o_tmpmemctx );
664 /* componentFilterMatch contains componentFilterMatch in it */
665 if ( strcmp(_ca->ca_ma_rule->smr_mrule.mr_oid, OID_COMP_FILTER_MATCH ) == 0) {
667 bv.bv_val = cav->cav_ptr;
668 bv.bv_len = cav_cur_len( cav );
669 rc = get_comp_filter( op, &bv,(ComponentFilter**)&_ca->ca_cf, text );
670 if ( rc != LDAP_SUCCESS ) {
671 op->o_tmpfree( _ca, op->o_tmpmemctx );
674 cav->cav_ptr = bv.bv_val;
675 assert( cav->cav_end >= bv.bv_val );
683 parse_comp_filter( Operation* op, ComponentAssertionValue* cav,
684 ComponentFilter** filt, const char** text )
687 * A component filter looks like this coming in:
688 * Filter ::= CHOICE {
689 * item [0] ComponentAssertion,
690 * and [1] SEQUENCE OF ComponentFilter,
691 * or [2] SEQUENCE OF ComponentFilter,
692 * not [3] ComponentFilter,
699 /* TAG : item, and, or, not in RFC 2254 */
700 tag = strip_cav_tag( cav );
702 if ( tag == LBER_ERROR ) {
703 *text = "error decoding comp filter";
704 return LDAP_PROTOCOL_ERROR;
707 if ( tag != LDAP_COMP_FILTER_NOT )
708 strip_cav_str( cav, "{");
715 switch ( f.cf_choice ) {
716 case LDAP_COMP_FILTER_AND:
717 Debug( LDAP_DEBUG_FILTER, "LDAP_COMP_FILTER_AND\n", 0, 0, 0 );
718 err = get_comp_filter_list( op, cav, &f.cf_and, text );
719 if ( err != LDAP_SUCCESS ) {
722 if ( f.cf_and == NULL ) {
723 f.cf_choice = SLAPD_FILTER_COMPUTED;
724 f.cf_result = LDAP_COMPARE_TRUE;
728 case LDAP_COMP_FILTER_OR:
729 Debug( LDAP_DEBUG_FILTER, "LDAP_COMP_FILTER_OR\n", 0, 0, 0 );
730 err = get_comp_filter_list( op, cav, &f.cf_or, text );
731 if ( err != LDAP_SUCCESS ) {
734 if ( f.cf_or == NULL ) {
735 f.cf_choice = SLAPD_FILTER_COMPUTED;
736 f.cf_result = LDAP_COMPARE_FALSE;
738 /* no assert - list could be empty */
741 case LDAP_COMP_FILTER_NOT:
742 Debug( LDAP_DEBUG_FILTER, "LDAP_COMP_FILTER_NOT\n", 0, 0, 0 );
743 err = parse_comp_filter( op, cav, &f.cf_not, text );
744 if ( err != LDAP_SUCCESS ) {
748 assert( f.cf_not != NULL );
749 if ( f.cf_not->cf_choice == SLAPD_FILTER_COMPUTED ) {
750 int fresult = f.cf_not->cf_result;
751 f.cf_choice = SLAPD_FILTER_COMPUTED;
752 op->o_tmpfree( f.cf_not, op->o_tmpmemctx );
756 case LDAP_COMPARE_TRUE:
757 f.cf_result = LDAP_COMPARE_FALSE;
759 case LDAP_COMPARE_FALSE:
760 f.cf_result = LDAP_COMPARE_TRUE;
763 /* (!Undefined) is Undefined */
768 case LDAP_COMP_FILTER_ITEM:
769 Debug( LDAP_DEBUG_FILTER, "LDAP_COMP_FILTER_ITEM\n", 0, 0, 0 );
770 err = get_item( op, cav, &f.cf_ca, text );
771 if ( err != LDAP_SUCCESS ) {
775 assert( f.cf_ca != NULL );
779 f.cf_choice = SLAPD_FILTER_COMPUTED;
780 f.cf_result = SLAPD_COMPARE_UNDEFINED;
784 if ( tag != LDAP_COMP_FILTER_NOT )
785 strip_cav_str( cav, "}");
787 if ( err != LDAP_SUCCESS && err != SLAPD_DISCONNECT ) {
789 f.cf_choice = SLAPD_FILTER_COMPUTED;
790 f.cf_result = SLAPD_COMPARE_UNDEFINED;
794 if ( err == LDAP_SUCCESS ) {
795 *filt = op->o_tmpalloc( sizeof(f), op->o_tmpmemctx );
803 test_comp_filter_and(
807 ComponentFilter *flist )
810 int rtn = LDAP_COMPARE_TRUE;
812 for ( f = flist ; f != NULL; f = f->cf_next ) {
813 int rc = test_comp_filter( syn, a, bv, f );
814 if ( rc == LDAP_COMPARE_FALSE ) {
819 if ( rc != LDAP_COMPARE_TRUE ) {
832 ComponentFilter *flist )
835 int rtn = LDAP_COMPARE_TRUE;
837 for ( f = flist ; f != NULL; f = f->cf_next ) {
838 int rc = test_comp_filter( syn, a, bv, f );
839 if ( rc == LDAP_COMPARE_TRUE ) {
844 if ( rc != LDAP_COMPARE_FALSE ) {
853 csi_value_match( MatchingRule *mr, struct berval* bv_attr,
854 struct berval* bv_assert )
859 assert( mr != NULL );
860 assert( !(mr->smr_usage & SLAP_MR_COMPONENT) );
862 if( !mr->smr_match ) {
863 return LDAP_INAPPROPRIATE_MATCHING;
866 rc = (mr->smr_match)( &match, 0, NULL /*ad->ad_type->sat_syntax*/,
867 mr, bv_attr, bv_assert );
868 if ( rc == LDAP_SUCCESS )
869 return match? LDAP_COMPARE_FALSE:LDAP_COMPARE_TRUE;
875 * return codes : LDAP_COMPARE_TRUE, LDAP_COMPARE_FALSE
878 test_comp_filter_item(
882 ComponentAssertion *ca )
885 ComponentSyntaxInfo* csi_attr, *csi_assert=NULL;
886 void *attr_nm, *assert_nm;
888 if ( strcmp(ca->ca_ma_rule->smr_mrule.mr_oid,
889 OID_COMP_FILTER_MATCH ) == 0 && ca->ca_cf ) {
890 /* componentFilterMatch inside of componentFilterMatch */
891 rc = test_comp_filter( syn, a, bv, ca->ca_cf );
895 /* load attribute containg components */
896 if ( !a->a_comp_data && attr_converter && nibble_mem_allocator ) {
897 a->a_comp_data = malloc( sizeof( ComponentData ) );
898 /* Memory chunk pre-allocation for decoders */
899 a->a_comp_data->cd_mem_op = (void*) nibble_mem_allocator ( 1024, 128 );
900 a->a_comp_data->cd_tree = attr_converter (a, syn, bv);
903 if ( a->a_comp_data->cd_tree == NULL ) {
904 free ( a->a_comp_data );
905 return LDAP_PROTOCOL_ERROR;
908 /* Memory for storing will-be-extracted attribute values */
909 attr_nm = nibble_mem_allocator ( 256, 64 );
910 if ( !attr_nm )return LDAP_PROTOCOL_ERROR;
911 /* component reference initialization */
912 ca->ca_comp_ref->cr_curr = ca->ca_comp_ref->cr_list;
913 /* load component containg the referenced component */
914 csi_attr = (((ComponentSyntaxInfo*)a->a_comp_data->cd_tree)->csi_comp_desc->cd_extract_i)( attr_nm, ca->ca_comp_ref, a->a_comp_data->cd_tree );
916 return LDAP_PROTOCOL_ERROR;
918 /* Memory for storing component assertion values */
919 if( !ca->ca_comp_data.cd_mem_op ) {
920 assert_nm = nibble_mem_allocator ( 256, 64 );
922 return LDAP_PROTOCOL_ERROR;
923 ca->ca_comp_data.cd_mem_op = assert_nm;
926 assert_nm = ca->ca_comp_data.cd_mem_op;
928 /* perform matching */
929 if ( ca->ca_comp_ref->cr_curr->ci_type == LDAP_COMPREF_ALL ) {
931 * If <all> type component referenced is used
932 * more than one component will be tested
934 if ( test_all_components )
935 rc = test_all_components ( assert_nm, csi_attr, ca );
937 rc = LDAP_PROTOCOL_ERROR;
940 * Exactly one component is referenced
941 * Fast Path for matching for this case
943 if ( test_one_component )
944 rc = test_one_component ( assert_nm, csi_attr, ca );
946 rc = LDAP_PROTOCOL_ERROR;
948 /* free memory used for storing extracted attribute value */
949 nibble_mem_free ( attr_nm );
962 if ( !f ) return LDAP_PROTOCOL_ERROR;
964 Debug( LDAP_DEBUG_FILTER, "test_comp_filter\n", 0, 0, 0 );
965 switch ( f->cf_choice ) {
966 case SLAPD_FILTER_COMPUTED:
969 case LDAP_COMP_FILTER_AND:
970 rc = test_comp_filter_and( syn, a, bv, f->cf_and );
972 case LDAP_COMP_FILTER_OR:
973 rc = test_comp_filter_or( syn, a, bv, f->cf_or );
975 case LDAP_COMP_FILTER_NOT:
976 rc = test_comp_filter( syn, a, bv, f->cf_not );
979 case LDAP_COMPARE_TRUE:
980 rc = LDAP_COMPARE_FALSE;
982 case LDAP_COMPARE_FALSE:
983 rc = LDAP_COMPARE_TRUE;
987 case LDAP_COMP_FILTER_ITEM:
988 rc = test_comp_filter_item( syn, a, bv, f->cf_ca );
991 rc = LDAP_PROTOCOL_ERROR;
998 free_comp_filter_list( ComponentFilter* f )
1000 ComponentFilter* tmp;
1001 for ( tmp = f ; tmp; tmp = tmp->cf_next );
1003 free_comp_filter( tmp );
1008 free_comp_filter( ComponentFilter* f )
1010 switch ( f->cf_choice ) {
1011 case LDAP_COMP_FILTER_AND:
1012 case LDAP_COMP_FILTER_OR:
1013 case LDAP_COMP_FILTER_NOT:
1014 free_comp_filter( f->cf_any );
1017 case LDAP_COMP_FILTER_ITEM:
1018 if ( nibble_mem_free && f->cf_ca->ca_comp_data.cd_mem_op )
1019 nibble_mem_free( f->cf_ca->ca_comp_data.cd_mem_op );
1028 component_free( ComponentFilter *f ) {
1029 free_comp_filter( f );