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 convert_asn_to_ldap_func* csi_converter = NULL ;
40 free_component_func* component_destructor = NULL ;
41 test_component_func* test_one_component = NULL;
42 test_component_func* test_all_components = 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
49 peek_componentId_type( ComponentAssertionValue* cav );
52 strip_cav_str( ComponentAssertionValue* cav, char* str);
55 peek_cav_str( ComponentAssertionValue* cav, char* str );
58 parse_comp_filter( Operation* op, ComponentAssertionValue* cav,
59 ComponentFilter** filt, const char** text );
62 free_comp_filter( ComponentFilter* f );
65 test_comp_filter( Syntax *syn, Attribute *a, struct berval *bv,
69 componentCertificateValidate(
77 componentFilterValidate(
85 allComponentsValidate(
93 componentFilterMatch (
101 Attribute *a = (Attribute*)value;
102 MatchingRuleAssertion * ma = (MatchingRuleAssertion*)assertedValue;
106 if ( !(mr && mr->smr_usage & SLAP_MR_COMPONENT) || !ma->ma_cf )
107 return LDAP_INAPPROPRIATE_MATCHING;
109 rc = test_comp_filter( syntax, a, a->a_vals, ma->ma_cf );
111 if ( rc == LDAP_COMPARE_TRUE ) {
115 else if ( rc == LDAP_COMPARE_FALSE ) {
120 return LDAP_INAPPROPRIATE_MATCHING;
125 directoryComponentsMatch(
130 struct berval *value,
131 void *assertedValue )
133 /* Only for Registeration */
144 struct berval *value,
145 void *assertedValue )
147 /* Only for Registeration */
153 slapd_ber2cav( struct berval* bv, ComponentAssertionValue* cav)
157 cav->cav_ptr = cav->cav_buf = bv->bv_val;
158 cav->cav_end = bv->bv_val + bv->bv_len;
164 get_comp_filter( Operation* op, struct berval* bv, ComponentFilter** filt,
167 ComponentAssertionValue cav;
170 Debug( LDAP_DEBUG_FILTER, "get_comp_filter\n", 0, 0, 0 );
171 if ( (rc = slapd_ber2cav(bv, &cav) ) != LDAP_SUCCESS ) {
174 rc = parse_comp_filter( op, &cav, filt, text );
175 bv->bv_val = cav.cav_ptr;
181 eat_whsp( ComponentAssertionValue* cav )
183 for ( ; ( *cav->cav_ptr == ' ' ) && ( cav->cav_ptr < cav->cav_end ) ; ) {
189 cav_cur_len( ComponentAssertionValue* cav )
191 return cav->cav_end - cav->cav_ptr;
195 comp_first_element( ComponentAssertionValue* cav )
198 if ( cav_cur_len( cav ) >= 8 && strncmp( cav->cav_ptr, "item", 4 ) == 0 ) {
199 return LDAP_COMP_FILTER_ITEM;
201 else if ( cav_cur_len( cav ) >= 7 && strncmp( cav->cav_ptr, "and", 3 ) == 0 ) {
202 return LDAP_COMP_FILTER_AND;
204 else if ( cav_cur_len( cav ) >= 6 && strncmp( cav->cav_ptr, "or" , 2 ) == 0 ) {
205 return LDAP_COMP_FILTER_OR;
207 else if ( cav_cur_len( cav ) >= 7 && strncmp( cav->cav_ptr, "not", 3 ) == 0 ) {
208 return LDAP_COMP_FILTER_NOT;
211 return LDAP_COMP_FILTER_UNDEFINED;
215 comp_next_element( ComponentAssertionValue* cav )
219 if ( *(cav->cav_ptr) == ',' ) {
220 /* move pointer to the next CA */
222 return comp_first_element( cav );
224 else return LDAP_COMP_FILTER_UNDEFINED;
228 get_comp_filter_list( Operation *op, ComponentAssertionValue *cav,
229 ComponentFilter** f, const char** text )
231 ComponentFilter **new;
235 Debug( LDAP_DEBUG_FILTER, "get_comp_filter_list\n", 0, 0, 0 );
237 for ( tag = comp_first_element( cav ); tag != LDAP_COMP_FILTER_UNDEFINED;
238 tag = comp_next_element( cav ) )
240 err = parse_comp_filter( op, cav, new, text );
241 if ( err != LDAP_SUCCESS )
243 new = &(*new)->cf_next;
247 return( LDAP_SUCCESS );
251 get_componentId( Operation *op, ComponentAssertionValue* cav,
252 ComponentId ** cid, const char** text )
258 type = peek_componentId_type( cav );
260 Debug( LDAP_DEBUG_FILTER, "get_compId [%d]\n", type, 0, 0 );
265 case LDAP_COMPREF_IDENTIFIER :
266 _cid.ci_val.ci_identifier.bv_val = cav->cav_ptr;
267 for( ;cav->cav_ptr[len] != ' ' && cav->cav_ptr[len] != '\0' &&
268 cav->cav_ptr[len] != '.' && cav->cav_ptr[len] != '\"' ; len++ );
269 _cid.ci_val.ci_identifier.bv_len = len;
272 case LDAP_COMPREF_FROM_BEGINNING :
273 for( ;cav->cav_ptr[len] != ' ' && cav->cav_ptr[len] != '\0' &&
274 cav->cav_ptr[len] != '.' && cav->cav_ptr[len] != '\"' ; len++ );
275 _cid.ci_val.ci_from_beginning = strtol( cav->cav_ptr, NULL, 0 );
278 case LDAP_COMPREF_FROM_END :
279 for( ;cav->cav_ptr[len] != ' ' && cav->cav_ptr[len] != '\0' &&
280 cav->cav_ptr[len] != '.' && cav->cav_ptr[len] != '\"' ; len++ );
281 _cid.ci_val.ci_from_end = strtol( cav->cav_ptr, NULL, 0 );
284 case LDAP_COMPREF_COUNT :
285 _cid.ci_val.ci_count = 0;
288 case LDAP_COMPREF_CONTENT :
289 _cid.ci_val.ci_content = 1;
290 cav->cav_ptr += strlen("content");
292 case LDAP_COMPREF_SELECT :
293 if ( cav->cav_ptr[len] != '(' )
294 return LDAP_COMPREF_UNDEFINED;
295 for( ;cav->cav_ptr[len] != ' ' && cav->cav_ptr[len] != '\0' &&
296 cav->cav_ptr[len] != '.' && cav->cav_ptr[len] != '\"' &&
297 cav->cav_ptr[len] != ')' ; len++ );
298 _cid.ci_val.ci_select_value.bv_val = cav->cav_ptr + 1;
299 _cid.ci_val.ci_select_value.bv_len = len - 1 ;
302 case LDAP_COMPREF_ALL :
303 _cid.ci_val.ci_all = '*';
307 return LDAP_COMPREF_UNDEFINED;
310 *cid = op->o_tmpalloc( sizeof( ComponentId ), op->o_tmpmemctx );
316 peek_componentId_type( ComponentAssertionValue* cav )
319 if ( cav->cav_ptr[0] == '-' )
320 return LDAP_COMPREF_FROM_END;
321 else if ( cav->cav_ptr[0] == '(' )
322 return LDAP_COMPREF_SELECT;
323 else if ( cav->cav_ptr[0] == '*' )
324 return LDAP_COMPREF_ALL;
325 else if ( strncmp(cav->cav_ptr,"all",3) == 0 )
326 return LDAP_COMPREF_ALL;
327 else if ( cav->cav_ptr[0] == '0' )
328 return LDAP_COMPREF_COUNT;
329 else if ( cav->cav_ptr[0] > '0' && cav->cav_ptr[0] <= '9' )
330 return LDAP_COMPREF_FROM_BEGINNING;
331 else if ( (cav->cav_end - cav->cav_ptr) >= 7 &&
332 strncmp(cav->cav_ptr,"content",7) == 0 )
333 return LDAP_COMPREF_CONTENT;
334 else if ( (cav->cav_ptr[0] >= 'a' && cav->cav_ptr[0] <= 'z') ||
335 (cav->cav_ptr[0] >= 'A' && cav->cav_ptr[0] <= 'Z') )
337 return LDAP_COMPREF_IDENTIFIER;
339 return LDAP_COMPREF_UNDEFINED;
343 comp_next_id( ComponentAssertionValue* cav )
346 if ( *(cav->cav_ptr) == '.' ) {
348 return LDAP_COMPREF_DEFINED;
350 else return LDAP_COMPREF_UNDEFINED;
354 get_component_reference( Operation *op, ComponentAssertionValue* cav,
355 ComponentReference** cr, const char** text )
359 ComponentReference* ca_comp_ref;
360 ComponentId** cr_list;
364 if ( ( rc = strip_cav_str( cav,"\"") ) != LDAP_SUCCESS )
368 op->o_tmpalloc( sizeof( ComponentReference ), op->o_tmpmemctx );
370 cr_list = &ca_comp_ref->cr_list;
372 for ( type = peek_componentId_type( cav ) ; type != LDAP_COMPREF_UNDEFINED
373 ; type = comp_next_id( cav ), count++ ) {
374 rc = get_componentId( op, cav, cr_list, text );
375 if ( rc == LDAP_SUCCESS ) {
376 if ( count == 0 ) ca_comp_ref->cr_curr = ca_comp_ref->cr_list;
377 cr_list = &(*cr_list)->ci_next;
379 else if ( rc == LDAP_COMPREF_UNDEFINED )
382 ca_comp_ref->cr_len = count;
384 if ( ( rc = strip_cav_str( cav,"\"") ) != LDAP_SUCCESS ) {
385 op->o_tmpfree( ca_comp_ref , op->o_tmpmemctx );
389 if ( rc == LDAP_SUCCESS ) {
393 else op->o_tmpfree( ca_comp_ref , op->o_tmpmemctx );
399 get_ca_use_default( Operation *op, ComponentAssertionValue* cav,
400 int* ca_use_def, const char** text )
402 strip_cav_str( cav, "useDefaultValues" );
403 if ( peek_cav_str( cav, "TRUE" ) == LDAP_SUCCESS ) {
404 strip_cav_str( cav, "TRUE" );
406 } else if ( peek_cav_str( cav, "FALSE" ) == LDAP_SUCCESS ) {
407 strip_cav_str( cav, "FALSE" );
410 return LDAP_INVALID_SYNTAX;
417 get_matching_rule( Operation *op, ComponentAssertionValue* cav,
418 MatchingRule** mr, const char** text )
421 struct berval rule_text = { 0L, NULL };
425 for ( ; ; count++ ) {
426 if ( cav->cav_ptr[count] == ' ' || cav->cav_ptr[count] == ',' ||
427 cav->cav_ptr[count] == '\0' || cav->cav_ptr[count] == '{' ||
428 cav->cav_ptr[count] == '}' || cav->cav_ptr[count] == '\n' )
433 *text = "component matching rule not recognized";
434 return LDAP_INAPPROPRIATE_MATCHING;
437 rule_text.bv_len = count;
438 rule_text.bv_val = cav->cav_ptr;
439 *mr = mr_bvfind( &rule_text );
440 cav->cav_ptr += count;
441 Debug( LDAP_DEBUG_FILTER, "get_matching_rule: %s\n", (*mr)->smr_mrule.mr_oid, 0, 0 );
443 *text = "component matching rule not recognized";
444 return LDAP_INAPPROPRIATE_MATCHING;
450 get_GSER_value( ComponentAssertionValue* cav, struct berval* bv )
452 int count, sequent_dquote, unclosed_brace, succeed;
456 * Four cases of GSER <Values>
458 * StringVal, GeneralizedTimeVal, UTCTimeVal, ObjectDescriptorVal
459 * 2) '...'B or '...'H :
460 * BitStringVal, OctetStringVal
462 * SEQUENCE, SEQUENCEOF, SETOF, SET, CHOICE
463 * 4) Between two white spaces
464 * INTEGER, BOOLEAN, NULL,ENUMERATE, etc
468 if ( cav->cav_ptr[0] == '"' ) {
469 for( count = 1, sequent_dquote = 0 ; ; count++ ) {
470 /* In order to find escaped double quote */
471 if ( cav->cav_ptr[count] == '"' ) sequent_dquote++;
472 else sequent_dquote = 0;
474 if ( cav->cav_ptr[count] == '\0' || (cav->cav_ptr+count) > cav->cav_end ) {
478 if ( ( cav->cav_ptr[count] == '"' && cav->cav_ptr[count-1] != '"') ||
479 ( sequent_dquote > 2 && (sequent_dquote%2) == 1 ) ) {
485 else if ( cav->cav_ptr[0] == '\'' ) {
486 for( count = 1 ; ; count++ ) {
487 if ( cav->cav_ptr[count] == '\0' || (cav->cav_ptr+count) > cav->cav_end ) {
490 if ((cav->cav_ptr[count-1] == '\'' && cav->cav_ptr[count] == 'B')||
491 (cav->cav_ptr[count-1] == '\'' && cav->cav_ptr[count] == 'H') ) {
498 else if ( cav->cav_ptr[0] == '{' ) {
499 for( count = 1, unclosed_brace = 1 ; ; count++ ) {
500 if ( cav->cav_ptr[count] == '{' ) unclosed_brace++;
501 if ( cav->cav_ptr[count] == '}' ) unclosed_brace--;
503 if ( cav->cav_ptr[count] == '\0' || (cav->cav_ptr+count) > cav->cav_end )
505 if ( unclosed_brace == 0 ) {
513 /*Find following white space where the value is ended*/
514 for( count = 1 ; ; count++ ) {
515 if ( cav->cav_ptr[count] == '\0' || cav->cav_ptr[count] == ' ' || (cav->cav_ptr+count) > cav->cav_end ) {
521 if ( !succeed ) return LDAP_FILTER_ERROR;
523 bv->bv_val = cav->cav_ptr;
525 cav->cav_ptr += count;
530 get_matching_value( Operation *op, ComponentAssertion* ca,
531 ComponentAssertionValue* cav, struct berval* bv,
534 if ( !(ca->ca_ma_rule->smr_usage & (SLAP_MR_COMPONENT)) ) {
535 if ( get_GSER_value( cav, bv ) != LDAP_SUCCESS ) {
536 return LDAP_FILTER_ERROR;
540 /* embeded componentFilterMatch Description */
541 bv->bv_val = cav->cav_ptr;
542 bv->bv_len = cav_cur_len( cav );
548 /* Don't move the position pointer, just peek given string */
550 peek_cav_str( ComponentAssertionValue* cav, char* str )
553 if ( cav_cur_len( cav ) >= strlen( str ) &&
554 strncmp( cav->cav_ptr, str, strlen( str ) ) == 0 )
557 return LDAP_INVALID_SYNTAX;
561 strip_cav_str( ComponentAssertionValue* cav, char* str)
564 if ( cav_cur_len( cav ) >= strlen( str ) &&
565 strncmp( cav->cav_ptr, str, strlen( str ) ) == 0 ) {
566 cav->cav_ptr += strlen( str );
570 return LDAP_INVALID_SYNTAX;
574 * TAG : "item", "and", "or", "not"
577 strip_cav_tag( ComponentAssertionValue* cav )
581 if ( cav_cur_len( cav ) >= 8 && strncmp( cav->cav_ptr, "item", 4 ) == 0 ) {
582 strip_cav_str( cav , "item:" );
583 return LDAP_COMP_FILTER_ITEM;
585 else if ( cav_cur_len( cav ) >= 7 && strncmp( cav->cav_ptr, "and", 3 ) == 0 ) {
586 strip_cav_str( cav , "and:" );
587 return LDAP_COMP_FILTER_AND;
589 else if ( cav_cur_len( cav ) >= 6 && strncmp( cav->cav_ptr, "or" , 2 ) == 0 ) {
590 strip_cav_str( cav , "or:" );
591 return LDAP_COMP_FILTER_OR;
593 else if ( cav_cur_len( cav ) >= 7 && strncmp( cav->cav_ptr, "not", 3 ) == 0 ) {
594 strip_cav_str( cav , "not:" );
595 return LDAP_COMP_FILTER_NOT;
602 * when encoding, "item" is denotation of ComponentAssertion
603 * ComponentAssertion :: SEQUENCE {
604 * component ComponentReference (SIZE(1..MAX)) OPTIONAL,
605 * useDefaultValues BOOLEAN DEFAULT TRUE,
606 * rule MATCHING-RULE.&id,
607 * value MATCHING-RULE.&AssertionType }
610 get_item( Operation *op, ComponentAssertionValue* cav, ComponentAssertion** ca,
614 ComponentAssertion* _ca;
616 Debug( LDAP_DEBUG_FILTER, "get_item: %s\n", 0, 0, 0 );
617 _ca = op->o_tmpalloc( sizeof( ComponentAssertion ), op->o_tmpmemctx );
619 _ca->ca_comp_data.cd_tree = NULL;
620 _ca->ca_comp_data.cd_mem_op = NULL;
622 rc = peek_cav_str( cav, "component" );
623 if ( rc == LDAP_SUCCESS ) {
624 strip_cav_str( cav, "component" );
625 rc = get_component_reference( op, cav, &_ca->ca_comp_ref, text );
626 if ( rc != LDAP_SUCCESS ) {
627 rc = LDAP_INVALID_SYNTAX;
628 op->o_tmpfree( _ca, op->o_tmpmemctx );
633 if ( ( rc = strip_cav_str( cav,",") ) != LDAP_SUCCESS )
636 rc = peek_cav_str( cav, "useDefaultValues");
637 if ( rc == LDAP_SUCCESS ) {
638 rc = get_ca_use_default( op, cav, &_ca->ca_use_def, text );
639 if ( rc != LDAP_SUCCESS ) {
640 rc = LDAP_INVALID_SYNTAX;
641 op->o_tmpfree( _ca, op->o_tmpmemctx );
644 if ( ( rc = strip_cav_str( cav,",") ) != LDAP_SUCCESS )
647 else _ca->ca_use_def = 1;
649 if ( !( strip_cav_str( cav, "rule" ) == LDAP_SUCCESS &&
650 get_matching_rule( op, cav , &_ca->ca_ma_rule, text ) == LDAP_SUCCESS )) {
651 rc = LDAP_INAPPROPRIATE_MATCHING;
652 op->o_tmpfree( _ca, op->o_tmpmemctx );
656 if ( ( rc = strip_cav_str( cav,",") ) != LDAP_SUCCESS )
658 if ( !(strip_cav_str( cav, "value" ) == LDAP_SUCCESS &&
659 get_matching_value( op, _ca, cav, &_ca->ca_ma_value,text ) == LDAP_SUCCESS )) {
660 rc = LDAP_INVALID_SYNTAX;
661 op->o_tmpfree( _ca, op->o_tmpmemctx );
665 /* componentFilterMatch contains componentFilterMatch in it */
666 if ( strcmp(_ca->ca_ma_rule->smr_mrule.mr_oid, OID_COMP_FILTER_MATCH ) == 0) {
668 bv.bv_val = cav->cav_ptr;
669 bv.bv_len = cav_cur_len( cav );
670 rc = get_comp_filter( op, &bv,(ComponentFilter**)&_ca->ca_cf, text );
671 if ( rc != LDAP_SUCCESS ) {
672 op->o_tmpfree( _ca, op->o_tmpmemctx );
675 cav->cav_ptr = bv.bv_val;
676 assert( cav->cav_end >= bv.bv_val );
684 parse_comp_filter( Operation* op, ComponentAssertionValue* cav,
685 ComponentFilter** filt, const char** text )
688 * A component filter looks like this coming in:
689 * Filter ::= CHOICE {
690 * item [0] ComponentAssertion,
691 * and [1] SEQUENCE OF ComponentFilter,
692 * or [2] SEQUENCE OF ComponentFilter,
693 * not [3] ComponentFilter,
700 /* TAG : item, and, or, not in RFC 2254 */
701 tag = strip_cav_tag( cav );
703 if ( tag == LBER_ERROR ) {
704 *text = "error decoding comp filter";
705 return LDAP_PROTOCOL_ERROR;
708 if ( tag != LDAP_COMP_FILTER_NOT )
709 strip_cav_str( cav, "{");
716 switch ( f.cf_choice ) {
717 case LDAP_COMP_FILTER_AND:
718 Debug( LDAP_DEBUG_FILTER, "LDAP_COMP_FILTER_AND\n", 0, 0, 0 );
719 err = get_comp_filter_list( op, cav, &f.cf_and, text );
720 if ( err != LDAP_SUCCESS ) {
723 if ( f.cf_and == NULL ) {
724 f.cf_choice = SLAPD_FILTER_COMPUTED;
725 f.cf_result = LDAP_COMPARE_TRUE;
729 case LDAP_COMP_FILTER_OR:
730 Debug( LDAP_DEBUG_FILTER, "LDAP_COMP_FILTER_OR\n", 0, 0, 0 );
731 err = get_comp_filter_list( op, cav, &f.cf_or, text );
732 if ( err != LDAP_SUCCESS ) {
735 if ( f.cf_or == NULL ) {
736 f.cf_choice = SLAPD_FILTER_COMPUTED;
737 f.cf_result = LDAP_COMPARE_FALSE;
739 /* no assert - list could be empty */
742 case LDAP_COMP_FILTER_NOT:
743 Debug( LDAP_DEBUG_FILTER, "LDAP_COMP_FILTER_NOT\n", 0, 0, 0 );
744 err = parse_comp_filter( op, cav, &f.cf_not, text );
745 if ( err != LDAP_SUCCESS ) {
749 assert( f.cf_not != NULL );
750 if ( f.cf_not->cf_choice == SLAPD_FILTER_COMPUTED ) {
751 int fresult = f.cf_not->cf_result;
752 f.cf_choice = SLAPD_FILTER_COMPUTED;
753 op->o_tmpfree( f.cf_not, op->o_tmpmemctx );
757 case LDAP_COMPARE_TRUE:
758 f.cf_result = LDAP_COMPARE_FALSE;
760 case LDAP_COMPARE_FALSE:
761 f.cf_result = LDAP_COMPARE_TRUE;
764 /* (!Undefined) is Undefined */
769 case LDAP_COMP_FILTER_ITEM:
770 Debug( LDAP_DEBUG_FILTER, "LDAP_COMP_FILTER_ITEM\n", 0, 0, 0 );
771 err = get_item( op, cav, &f.cf_ca, text );
772 if ( err != LDAP_SUCCESS ) {
776 assert( f.cf_ca != NULL );
780 f.cf_choice = SLAPD_FILTER_COMPUTED;
781 f.cf_result = SLAPD_COMPARE_UNDEFINED;
785 if ( tag != LDAP_COMP_FILTER_NOT )
786 strip_cav_str( cav, "}");
788 if ( err != LDAP_SUCCESS && err != SLAPD_DISCONNECT ) {
790 f.cf_choice = SLAPD_FILTER_COMPUTED;
791 f.cf_result = SLAPD_COMPARE_UNDEFINED;
795 if ( err == LDAP_SUCCESS ) {
796 *filt = op->o_tmpalloc( sizeof(f), op->o_tmpmemctx );
804 test_comp_filter_and(
808 ComponentFilter *flist )
811 int rtn = LDAP_COMPARE_TRUE;
813 for ( f = flist ; f != NULL; f = f->cf_next ) {
814 int rc = test_comp_filter( syn, a, bv, f );
815 if ( rc == LDAP_COMPARE_FALSE ) {
820 if ( rc != LDAP_COMPARE_TRUE ) {
833 ComponentFilter *flist )
836 int rtn = LDAP_COMPARE_TRUE;
838 for ( f = flist ; f != NULL; f = f->cf_next ) {
839 int rc = test_comp_filter( syn, a, bv, f );
840 if ( rc == LDAP_COMPARE_TRUE ) {
845 if ( rc != LDAP_COMPARE_FALSE ) {
854 csi_value_match( MatchingRule *mr, struct berval* bv_attr,
855 struct berval* bv_assert )
860 assert( mr != NULL );
861 assert( !(mr->smr_usage & SLAP_MR_COMPONENT) );
863 if( !mr->smr_match ) {
864 return LDAP_INAPPROPRIATE_MATCHING;
867 rc = (mr->smr_match)( &match, 0, NULL /*ad->ad_type->sat_syntax*/,
868 mr, bv_attr, bv_assert );
869 if ( rc == LDAP_SUCCESS )
870 return match? LDAP_COMPARE_FALSE:LDAP_COMPARE_TRUE;
876 component_value_match( MatchingRule* mr,
877 ComponentSyntaxInfo* csi_attr, ComponentSyntaxInfo* csi_assert )
879 if ( mr->smr_usage & SLAP_MR_COMPONENT ){
880 if ( strcmp( mr->smr_mrule.mr_oid, OID_ALL_COMP_MATCH ) == 0 )
882 /* allComponentMatch */
883 return csi_attr->csi_comp_desc->cd_all_match( NULL,
884 csi_attr, csi_assert );
886 return csi_assert->csi_comp_desc->cd_all_match(
887 mr->smr_mrule.mr_oid, csi_attr, csi_assert );
891 if ( csi_attr->csi_comp_desc->cd_type == ASN_BASIC ) {
892 struct berval bv1, bv2;
893 char attr_buf[MAX_LDAP_STR_LEN],assert_buf[MAX_LDAP_STR_LEN];
894 bv1.bv_val = attr_buf;
895 bv2.bv_val = assert_buf;
896 if ( csi_converter &&
897 ( csi_converter ( csi_attr, &bv1 ) == LDAP_SUCCESS ) &&
898 ( csi_converter ( csi_assert, &bv2 ) == LDAP_SUCCESS ) )
900 return csi_value_match( mr, &bv1, &bv2 );
903 return LDAP_INAPPROPRIATE_MATCHING;
906 } else if ( csi_attr->csi_comp_desc->cd_type == ASN_COMPOSITE )
908 return LDAP_INAPPROPRIATE_MATCHING;
914 * return codes : LDAP_COMPARE_TRUE, LDAP_COMPARE_FALSE
917 test_comp_filter_item(
921 ComponentAssertion *ca )
924 ComponentSyntaxInfo* csi_attr, *csi_assert=NULL;
925 void *attr_nm, *assert_nm;
927 if ( strcmp(ca->ca_ma_rule->smr_mrule.mr_oid,
928 OID_COMP_FILTER_MATCH ) == 0 && ca->ca_cf ) {
929 /* componentFilterMatch inside of componentFilterMatch */
930 rc = test_comp_filter( syn, a, bv, ca->ca_cf );
934 /* load attribute containg components */
935 if ( !a->a_comp_data && attr_converter && nibble_mem_allocator ) {
936 a->a_comp_data = malloc( sizeof( ComponentData ) );
937 /* Memory chunk pre-allocation for decoders */
938 a->a_comp_data->cd_mem_op = (void*) nibble_mem_allocator ( 1024, 128 );
939 a->a_comp_data->cd_tree = attr_converter (a, syn, bv);
942 if ( a->a_comp_data->cd_tree == NULL ) {
943 free ( a->a_comp_data );
944 return LDAP_PROTOCOL_ERROR;
947 /* Memory for storing will-be-extracted attribute values */
948 attr_nm = nibble_mem_allocator ( 256, 64 );
949 if ( !attr_nm )return LDAP_PROTOCOL_ERROR;
950 /* component reference initialization */
951 ca->ca_comp_ref->cr_curr = ca->ca_comp_ref->cr_list;
952 /* load component containg the referenced component */
953 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 );
955 return LDAP_PROTOCOL_ERROR;
957 /* Memory for storing component assertion values */
958 assert_nm = nibble_mem_allocator ( 256, 64 );
959 if ( !assert_nm ) return LDAP_PROTOCOL_ERROR;
960 /* perform matching */
961 if ( ca->ca_comp_ref->cr_curr->ci_type == LDAP_COMPREF_ALL ) {
963 * If <all> type component referenced is used
964 * more than one component will be tested
966 if ( test_all_components )
967 rc = test_all_components ( assert_nm, csi_attr, ca );
969 rc = LDAP_PROTOCOL_ERROR;
972 * Exactly one component is referenced
973 * Fast Path for matching for this case
975 if ( test_one_component )
976 rc = test_one_component ( assert_nm, csi_attr, ca );
978 rc = LDAP_PROTOCOL_ERROR;
980 /* free memory used for storing extracted attribute value */
981 nibble_mem_free ( attr_nm );
994 if ( !f ) return LDAP_PROTOCOL_ERROR;
996 Debug( LDAP_DEBUG_FILTER, "test_comp_filter\n", 0, 0, 0 );
997 switch ( f->cf_choice ) {
998 case SLAPD_FILTER_COMPUTED:
1001 case LDAP_COMP_FILTER_AND:
1002 rc = test_comp_filter_and( syn, a, bv, f->cf_and );
1004 case LDAP_COMP_FILTER_OR:
1005 rc = test_comp_filter_or( syn, a, bv, f->cf_or );
1007 case LDAP_COMP_FILTER_NOT:
1008 rc = test_comp_filter( syn, a, bv, f->cf_not );
1011 case LDAP_COMPARE_TRUE:
1012 rc = LDAP_COMPARE_FALSE;
1014 case LDAP_COMPARE_FALSE:
1015 rc = LDAP_COMPARE_TRUE;
1019 case LDAP_COMP_FILTER_ITEM:
1020 rc = test_comp_filter_item( syn, a, bv, f->cf_ca );
1023 rc = LDAP_PROTOCOL_ERROR;
1030 free_comp_filter_list( ComponentFilter* f )
1032 ComponentFilter* tmp;
1033 for ( tmp = f ; tmp; tmp = tmp->cf_next );
1035 free_comp_filter( tmp );
1040 free_comp_filter( ComponentFilter* f )
1042 switch ( f->cf_choice ) {
1043 case LDAP_COMP_FILTER_AND:
1044 case LDAP_COMP_FILTER_OR:
1045 case LDAP_COMP_FILTER_NOT:
1046 free_comp_filter( f->cf_any );
1049 case LDAP_COMP_FILTER_ITEM:
1050 if ( nibble_mem_free && f->cf_ca->ca_comp_data.cd_mem_op )
1051 nibble_mem_free( f->cf_ca->ca_comp_data.cd_mem_op );
1060 component_free( ComponentFilter *f ) {
1061 free_comp_filter( f );