X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fcomponent.c;h=54f544140d277928b299c91b5476bf5217f32d24;hb=2f770f8af7bd0c633000319f1cb53f1a95bfe921;hp=9e006e21982d2a5e4f0cdd173175b6a3abbf8f22;hpb=78d08a8271deea5cf1976e625087c3d5db3fac31;p=openldap diff --git a/servers/slapd/component.c b/servers/slapd/component.c index 9e006e2198..54f544140d 100644 --- a/servers/slapd/component.c +++ b/servers/slapd/component.c @@ -2,7 +2,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 2003-2004 The OpenLDAP Foundation. + * Copyright 2003-2007 The OpenLDAP Foundation. * Portions Copyright 2004 by IBM Corporation. * All rights reserved. * @@ -20,14 +20,30 @@ #include #include -#include "ldap_pvt.h" #include "lutil.h" #include #include "slap.h" #ifdef LDAP_COMP_MATCH -#include "asn.h" +#include "component.h" + +/* + * Following function pointers are initialized + * when a component module is loaded + */ +alloc_nibble_func* nibble_mem_allocator = NULL; +free_nibble_func* nibble_mem_free = NULL; +convert_attr_to_comp_func* attr_converter = NULL; +convert_assert_to_comp_func* assert_converter = NULL ; +free_component_func* component_destructor = NULL ; +test_component_func* test_components = NULL; +test_membership_func* is_aliased_attribute = NULL; +component_encoder_func* component_encoder = NULL; +get_component_info_func* get_component_description = NULL; +#define OID_ALL_COMP_MATCH "1.2.36.79672281.1.13.6" +#define OID_COMP_FILTER_MATCH "1.2.36.79672281.1.13.2" +#define MAX_LDAP_STR_LEN 128 static int peek_componentId_type( ComponentAssertionValue* cav ); @@ -42,9 +58,19 @@ static int parse_comp_filter( Operation* op, ComponentAssertionValue* cav, ComponentFilter** filt, const char** text ); +static void +free_comp_filter( ComponentFilter* f ); + static int -test_comp_filter_attr( Operation *op, Attribute *a, struct berval *bv, - ComponentFilter *f ); +test_comp_filter( Syntax *syn, ComponentSyntaxInfo *a, ComponentFilter *f ); + +int +componentCertificateValidate( + Syntax *syntax, + struct berval *val ) +{ + return LDAP_SUCCESS; +} int componentFilterValidate( @@ -54,6 +80,14 @@ componentFilterValidate( return LDAP_SUCCESS; } +int +allComponentsValidate( + Syntax *syntax, + struct berval *val ) +{ + return LDAP_SUCCESS; +} + int componentFilterMatch ( int *matchp, @@ -63,46 +97,266 @@ componentFilterMatch ( struct berval *value, void *assertedValue ) { - /* FIXME: to be implemented */ + ComponentSyntaxInfo *csi_attr = (ComponentSyntaxInfo*)value; + MatchingRuleAssertion * ma = (MatchingRuleAssertion*)assertedValue; + int rc; + + if ( !mr || !ma->ma_cf ) return LDAP_INAPPROPRIATE_MATCHING; + + /* Check if the component module is loaded */ + if ( !attr_converter || !nibble_mem_allocator ) { + return LDAP_OTHER; + } + + rc = test_comp_filter( syntax, csi_attr, ma->ma_cf ); + + if ( rc == LDAP_COMPARE_TRUE ) { + *matchp = 0; + return LDAP_SUCCESS; + } + else if ( rc == LDAP_COMPARE_FALSE ) { + *matchp = 1; + return LDAP_SUCCESS; + } + else { + return LDAP_INAPPROPRIATE_MATCHING; + } +} + +int +directoryComponentsMatch( + int *matchp, + slap_mask_t flags, + Syntax *syntax, + MatchingRule *mr, + struct berval *value, + void *assertedValue ) +{ + /* Only for registration */ *matchp = 0; return LDAP_SUCCESS; } +int +allComponentsMatch( + int *matchp, + slap_mask_t flags, + Syntax *syntax, + MatchingRule *mr, + struct berval *value, + void *assertedValue ) +{ + /* Only for registration */ + *matchp = 0; + return LDAP_SUCCESS; +} + +static int +slapd_ber2cav( struct berval* bv, ComponentAssertionValue* cav ) +{ + cav->cav_ptr = cav->cav_buf = bv->bv_val; + cav->cav_end = bv->bv_val + bv->bv_len; + + return LDAP_SUCCESS; +} + +ComponentReference* +dup_comp_ref ( Operation* op, ComponentReference* cr ) +{ + ComponentReference* dup_cr; + ComponentId* ci_curr; + ComponentId** ci_temp; + + dup_cr = op->o_tmpalloc( sizeof( ComponentReference ), op->o_tmpmemctx ); + + dup_cr->cr_len = cr->cr_len; + dup_cr->cr_string = cr->cr_string; + + ci_temp = &dup_cr->cr_list; + ci_curr = cr->cr_list; + + for ( ; ci_curr != NULL ; + ci_curr = ci_curr->ci_next, ci_temp = &(*ci_temp)->ci_next ) + { + *ci_temp = op->o_tmpalloc( sizeof( ComponentId ), op->o_tmpmemctx ); + if ( !ci_temp ) return NULL; + **ci_temp = *ci_curr; + } + + dup_cr->cr_curr = dup_cr->cr_list; + + return dup_cr; +} static int -slapd_ber2cav( struct berval* bv, ComponentAssertionValue* cav) +dup_comp_filter_list ( + Operation *op, + struct berval *bv, + ComponentFilter* in_f, + ComponentFilter** out_f ) +{ + ComponentFilter **new, *f; + int rc; + + new = out_f; + for ( f = in_f; f != NULL; f = f->cf_next ) { + rc = dup_comp_filter( op, bv, f, new ); + if ( rc != LDAP_SUCCESS ) { + return rc; + } + new = &(*new)->cf_next; + } + return LDAP_SUCCESS; +} + +int +get_len_of_next_assert_value ( struct berval* bv, char separator ) +{ + int i = 0; + while (1) { + if ( (bv->bv_val[ i ] == separator) || ( i >= bv->bv_len) ) + break; + i++; + } + bv->bv_val += (i + 1); + bv->bv_len -= (i + 1); + return i; +} + +int +dup_comp_filter_item ( + Operation *op, + struct berval* assert_bv, + ComponentAssertion* in_ca, + ComponentAssertion** out_ca ) { int len; - len = ldap_pvt_filter_value_unescape( bv->bv_val ); - cav->cav_ptr = cav->cav_buf = bv->bv_val; - cav->cav_end = bv->bv_val + len; + if ( !in_ca->ca_comp_ref ) return SLAPD_DISCONNECT; + + *out_ca = op->o_tmpalloc( sizeof( ComponentAssertion ), op->o_tmpmemctx ); + if ( !(*out_ca) ) return LDAP_NO_MEMORY; + + (*out_ca)->ca_comp_data.cd_tree = NULL; + (*out_ca)->ca_comp_data.cd_mem_op = NULL; + + (*out_ca)->ca_comp_ref = dup_comp_ref ( op, in_ca->ca_comp_ref ); + (*out_ca)->ca_use_def = 0; + (*out_ca)->ca_ma_rule = in_ca->ca_ma_rule; + + (*out_ca)->ca_ma_value.bv_val = assert_bv->bv_val; + len = get_len_of_next_assert_value ( assert_bv, '$' ); + if ( len <= 0 ) return SLAPD_DISCONNECT; + (*out_ca)->ca_ma_value.bv_len = len; + + return LDAP_SUCCESS; +} + +int +dup_comp_filter ( + Operation* op, + struct berval *bv, + ComponentFilter *in_f, + ComponentFilter **out_f ) +{ + int rc; + ComponentFilter dup_f = {0}; + + if ( !in_f ) return LDAP_PROTOCOL_ERROR; + + switch ( in_f->cf_choice ) { + case LDAP_COMP_FILTER_AND: + rc = dup_comp_filter_list( op, bv, in_f->cf_and, &dup_f.cf_and); + dup_f.cf_choice = LDAP_COMP_FILTER_AND; + break; + case LDAP_COMP_FILTER_OR: + rc = dup_comp_filter_list( op, bv, in_f->cf_or, &dup_f.cf_or); + dup_f.cf_choice = LDAP_COMP_FILTER_OR; + break; + case LDAP_COMP_FILTER_NOT: + rc = dup_comp_filter( op, bv, in_f->cf_not, &dup_f.cf_not); + dup_f.cf_choice = LDAP_COMP_FILTER_NOT; + break; + case LDAP_COMP_FILTER_ITEM: + rc = dup_comp_filter_item( op, bv, in_f->cf_ca ,&dup_f.cf_ca ); + dup_f.cf_choice = LDAP_COMP_FILTER_ITEM; + break; + default: + rc = LDAP_PROTOCOL_ERROR; + } + + if ( rc == LDAP_SUCCESS ) { + *out_f = op->o_tmpalloc( sizeof(dup_f), op->o_tmpmemctx ); + **out_f = dup_f; + } + + return( rc ); +} + +int +get_aliased_filter_aa ( Operation* op, AttributeAssertion* a_assert, AttributeAliasing* aa, const char** text ) +{ + struct berval assert_bv; + + Debug( LDAP_DEBUG_FILTER, "get_aliased_filter\n", 0, 0, 0 ); + + if ( !aa->aa_cf ) + return LDAP_PROTOCOL_ERROR; + + assert_bv = a_assert->aa_value; + /* + * Duplicate aa->aa_cf to ma->ma_cf by replacing the + * the component assertion value in assert_bv + * Multiple values may be separated with '$' + */ + return dup_comp_filter ( op, &assert_bv, aa->aa_cf, &a_assert->aa_cf ); } int -get_comp_filter ( Operation* op, struct berval* bv, ComponentFilter** filt, - const char **text ) +get_aliased_filter( Operation* op, + MatchingRuleAssertion* ma, AttributeAliasing* aa, + const char** text ) +{ + struct berval assert_bv; + + Debug( LDAP_DEBUG_FILTER, "get_aliased_filter\n", 0, 0, 0 ); + + if ( !aa->aa_cf ) return LDAP_PROTOCOL_ERROR; + + assert_bv = ma->ma_value; + /* Attribute Description is replaced with aliased one */ + ma->ma_desc = aa->aa_aliased_ad; + ma->ma_rule = aa->aa_mr; + /* + * Duplicate aa->aa_cf to ma->ma_cf by replacing the + * the component assertion value in assert_bv + * Multiple values may be separated with '$' + */ + return dup_comp_filter ( op, &assert_bv, aa->aa_cf, &ma->ma_cf ); +} + +int +get_comp_filter( Operation* op, struct berval* bv, + ComponentFilter** filt, const char **text ) { ComponentAssertionValue cav; - int len, rc; -#ifdef NEW_LOGGING - LDAP_LOG( FILTER, ENTRY, "get_comp_filter\n", 0, 0, 0 ); -#else + int rc; + Debug( LDAP_DEBUG_FILTER, "get_comp_filter\n", 0, 0, 0 ); -#endif - slapd_ber2cav(bv, &cav); + if ( (rc = slapd_ber2cav(bv, &cav) ) != LDAP_SUCCESS ) { + return rc; + } rc = parse_comp_filter( op, &cav, filt, text ); bv->bv_val = cav.cav_ptr; + return rc; } static void eat_whsp( ComponentAssertionValue* cav ) { - int count = 0; - for ( ; ; ) { - if ( cav->cav_ptr[count++] == ' ' ) cav->cav_ptr++; - else break; + for ( ; ( *cav->cav_ptr == ' ' ) && ( cav->cav_ptr < cav->cav_end ) ; ) { + cav->cav_ptr++; } } @@ -118,24 +372,30 @@ comp_first_element( ComponentAssertionValue* cav ) eat_whsp( cav ); if ( cav_cur_len( cav ) >= 8 && strncmp( cav->cav_ptr, "item", 4 ) == 0 ) { return LDAP_COMP_FILTER_ITEM; - } - else if ( cav_cur_len( cav ) >= 7 && strncmp( cav->cav_ptr, "and", 3 ) == 0 ) { + + } else if ( cav_cur_len( cav ) >= 7 && + strncmp( cav->cav_ptr, "and", 3 ) == 0 ) + { return LDAP_COMP_FILTER_AND; - } - else if ( cav_cur_len( cav ) >= 6 && strncmp( cav->cav_ptr, "or" , 2 ) == 0 ) { + + } else if ( cav_cur_len( cav ) >= 6 && + strncmp( cav->cav_ptr, "or" , 2 ) == 0 ) + { return LDAP_COMP_FILTER_OR; - } - else if ( cav_cur_len( cav ) >= 7 && strncmp( cav->cav_ptr, "not", 3 ) == 0 ) { + + } else if ( cav_cur_len( cav ) >= 7 && + strncmp( cav->cav_ptr, "not", 3 ) == 0 ) + { return LDAP_COMP_FILTER_NOT; - } - else + + } else { return LDAP_COMP_FILTER_UNDEFINED; + } } static ber_tag_t comp_next_element( ComponentAssertionValue* cav ) { - eat_whsp( cav ); if ( *(cav->cav_ptr) == ',' ) { /* move pointer to the next CA */ @@ -147,37 +407,30 @@ comp_next_element( ComponentAssertionValue* cav ) static int get_comp_filter_list( Operation *op, ComponentAssertionValue *cav, - ComponentFilter** f, const char** text ) + ComponentFilter** f, const char** text ) { ComponentFilter **new; int err; ber_tag_t tag; - ber_len_t len; - char *last; -#ifdef NEW_LOGGING - LDAP_LOG( FILTER, ENTRY, "get_comp_filter_list\n", 0, 0, 0 ); -#else Debug( LDAP_DEBUG_FILTER, "get_comp_filter_list\n", 0, 0, 0 ); -#endif new = f; - for ( tag = comp_first_element( cav ); tag != LDAP_COMP_FILTER_UNDEFINED; + for ( tag = comp_first_element( cav ); + tag != LDAP_COMP_FILTER_UNDEFINED; tag = comp_next_element( cav ) ) { err = parse_comp_filter( op, cav, new, text ); - if ( err != LDAP_SUCCESS ) - return ( err ); + if ( err != LDAP_SUCCESS ) return ( err ); new = &(*new)->cf_next; } *new = NULL; - return( LDAP_SUCCESS ); } static int get_componentId( Operation *op, ComponentAssertionValue* cav, - ComponentId ** cid, const char** text ) + ComponentId ** cid, const char** text ) { ber_tag_t type; ComponentId _cid; @@ -185,11 +438,8 @@ get_componentId( Operation *op, ComponentAssertionValue* cav, type = peek_componentId_type( cav ); -#ifdef NEW_LOGGING - LDAP_LOG( FILTER, ENTRY, "get_compId [%d]\n", type, 0, 0 ); -#else - Debug( LDAP_DEBUG_FILTER, "get_compId [%d]\n", type, 0, 0 ); -#endif + Debug( LDAP_DEBUG_FILTER, "get_compId [%lu]\n", + (unsigned long) type, 0, 0 ); len = 0; _cid.ci_type = type; _cid.ci_next = NULL; @@ -218,25 +468,31 @@ get_componentId( Operation *op, ComponentAssertionValue* cav, cav->cav_ptr++; break; case LDAP_COMPREF_CONTENT : - /* FIXEME: yet to be implemented */ + _cid.ci_val.ci_content = 1; + cav->cav_ptr += strlen("content"); break; case LDAP_COMPREF_SELECT : - /* FIXEME: yet to be implemented */ + if ( cav->cav_ptr[len] != '(' ) return LDAP_COMPREF_UNDEFINED; + for( ;cav->cav_ptr[len] != ' ' && cav->cav_ptr[len] != '\0' && + cav->cav_ptr[len] != '\"' && cav->cav_ptr[len] != ')' + ; len++ ); + _cid.ci_val.ci_select_value.bv_val = cav->cav_ptr + 1; + _cid.ci_val.ci_select_value.bv_len = len - 1 ; + cav->cav_ptr += len + 1; break; case LDAP_COMPREF_ALL : _cid.ci_val.ci_all = '*'; cav->cav_ptr++; -#ifdef NEW_LOGGING - LDAP_LOG( FILTER, ENTRY, "get_compId : ALL\n", 0, 0, 0 ); -#else - Debug( LDAP_DEBUG_FILTER, "get_compId : ALL\n", 0, 0, 0 ); -#endif break; default : return LDAP_COMPREF_UNDEFINED; } - *cid = op->o_tmpalloc( sizeof( ComponentId ), op->o_tmpmemctx ); + if ( op ) { + *cid = op->o_tmpalloc( sizeof( ComponentId ), op->o_tmpmemctx ); + } else { + *cid = malloc( sizeof( ComponentId ) ); + } **cid = _cid; return LDAP_SUCCESS; } @@ -245,91 +501,206 @@ static int peek_componentId_type( ComponentAssertionValue* cav ) { eat_whsp( cav ); - if ( cav->cav_ptr[0] == '-' ) + + if ( cav->cav_ptr[0] == '-' ) { return LDAP_COMPREF_FROM_END; - else if ( cav->cav_ptr[0] == '(' ) + + } else if ( cav->cav_ptr[0] == '(' ) { return LDAP_COMPREF_SELECT; - else if ( cav->cav_ptr[0] == '*' ) + + } else if ( cav->cav_ptr[0] == '*' ) { return LDAP_COMPREF_ALL; - else if ( cav->cav_ptr[0] == '0' ) + + } else if ( cav->cav_ptr[0] == '0' ) { return LDAP_COMPREF_COUNT; - else if ( cav->cav_ptr[0] > '0' && cav->cav_ptr[0] <= '9' ) + + } else if ( cav->cav_ptr[0] > '0' && cav->cav_ptr[0] <= '9' ) { return LDAP_COMPREF_FROM_BEGINNING; - else if ( (cav->cav_end - cav->cav_ptr) >= 7 && + + } else if ( (cav->cav_end - cav->cav_ptr) >= 7 && strncmp(cav->cav_ptr,"content",7) == 0 ) + { return LDAP_COMPREF_CONTENT; - else if ( cav->cav_ptr[0] >= 'a' && cav->cav_ptr[0] <= 'z' ) + } else if ( (cav->cav_ptr[0] >= 'a' && cav->cav_ptr[0] <= 'z') || + (cav->cav_ptr[0] >= 'A' && cav->cav_ptr[0] <= 'Z') ) + { return LDAP_COMPREF_IDENTIFIER; - else - return LDAP_COMPREF_UNDEFINED; + } + + return LDAP_COMPREF_UNDEFINED; } static ber_tag_t comp_next_id( ComponentAssertionValue* cav ) { - if ( *(cav->cav_ptr) == '.' ) { cav->cav_ptr++; return LDAP_COMPREF_DEFINED; } - else return LDAP_COMPREF_UNDEFINED; + + return LDAP_COMPREF_UNDEFINED; } + + static int -get_component_reference( Operation *op, ComponentAssertionValue* cav, - ComponentReference** cr, const char** text ) +get_component_reference( + Operation *op, + ComponentAssertionValue* cav, + ComponentReference** cr, + const char** text ) { - int rc,count=0; + int rc, count = 0; ber_int_t type; ComponentReference* ca_comp_ref; ComponentId** cr_list; + char* start, *end; eat_whsp( cav ); - ca_comp_ref = - op->o_tmpalloc( sizeof( ComponentReference ), op->o_tmpmemctx ); + + start = cav->cav_ptr; + if ( ( rc = strip_cav_str( cav,"\"") ) != LDAP_SUCCESS ) return rc; + if ( op ) { + ca_comp_ref = op->o_tmpalloc( sizeof( ComponentReference ), + op->o_tmpmemctx ); + } else { + ca_comp_ref = malloc( sizeof( ComponentReference ) ); + } + + if ( !ca_comp_ref ) return LDAP_NO_MEMORY; cr_list = &ca_comp_ref->cr_list; - strip_cav_str( cav, "\""); + for ( type = peek_componentId_type( cav ) ; type != LDAP_COMPREF_UNDEFINED - ; type = comp_next_id( cav ), count++ ) { + ; type = comp_next_id( cav ), count++ ) + { rc = get_componentId( op, cav, cr_list, text ); if ( rc == LDAP_SUCCESS ) { if ( count == 0 ) ca_comp_ref->cr_curr = ca_comp_ref->cr_list; cr_list = &(*cr_list)->ci_next; + + } else if ( rc == LDAP_COMPREF_UNDEFINED ) { + return rc; } } ca_comp_ref->cr_len = count; - strip_cav_str( cav, "\""); + end = cav->cav_ptr; + if ( ( rc = strip_cav_str( cav,"\"") ) != LDAP_SUCCESS ) { + if ( op ) { + op->o_tmpfree( ca_comp_ref , op->o_tmpmemctx ); + } else { + free( ca_comp_ref ); + } + return rc; + } if ( rc == LDAP_SUCCESS ) { *cr = ca_comp_ref; **cr = *ca_comp_ref; + + } else if ( op ) { + op->o_tmpfree( ca_comp_ref , op->o_tmpmemctx ); + + } else { + free( ca_comp_ref ) ; } - else op->o_tmpfree( ca_comp_ref , op->o_tmpmemctx ); + (*cr)->cr_string.bv_val = start; + (*cr)->cr_string.bv_len = end - start + 1; + return rc; } -static int -get_ca_use_default( Operation *op, ComponentAssertionValue* cav, - int* ca_use_def, const char** text ) +int +insert_component_reference( + ComponentReference *cr, + ComponentReference** cr_list) { - int rc; - if ( peek_cav_str( cav, "useDefaultValues" ) == LDAP_SUCCESS ) { - strip_cav_str( cav, "useDefaultValues" ); - if ( peek_cav_str( cav, "TRUE" ) == LDAP_SUCCESS ) { - strip_cav_str( cav, "TRUE" ); - *ca_use_def = 1; - } - else if ( peek_cav_str( cav, "FALSE" ) == LDAP_SUCCESS ) { - strip_cav_str( cav, "FALSE" ); - *ca_use_def = 0; - } - else - return LDAP_INVALID_SYNTAX; + if ( !cr ) return LDAP_PARAM_ERROR; + + if ( !(*cr_list) ) { + *cr_list = cr; + cr->cr_next = NULL; + } else { + cr->cr_next = *cr_list; + *cr_list = cr; + } + return LDAP_SUCCESS; +} + +/* + * If there is '.' in the name of a given attribute + * the first '.'- following characters are considered + * as a component reference of the attribute + * EX) userCertificate.toBeSigned.serialNumber + * attribute : userCertificate + * component reference : toBeSigned.serialNumber + */ +int +is_component_reference( char* attr ) { + int i; + for ( i=0; attr[i] != '\0' ; i++ ) { + if ( attr[i] == '.' ) return (1); + } + return (0); +} + +int +extract_component_reference( + char* attr, + ComponentReference** cr ) +{ + int i, rc; + char* cr_ptr; + int cr_len; + ComponentAssertionValue cav; + char text[1][128]; + + for ( i=0; attr[i] != '\0' ; i++ ) { + if ( attr[i] == '.' ) break; } - else /* If not defined, default value is TRUE */ + + if (attr[i] != '.' ) return LDAP_PARAM_ERROR; + attr[i] = '\0'; + + cr_ptr = attr + i + 1 ; + cr_len = strlen ( cr_ptr ); + if ( cr_len <= 0 ) return LDAP_PARAM_ERROR; + + /* enclosed between double quotes*/ + cav.cav_ptr = cav.cav_buf = ch_malloc (cr_len+2); + memcpy( cav.cav_buf+1, cr_ptr, cr_len ); + cav.cav_buf[0] = '"'; + cav.cav_buf[cr_len+1] = '"'; + cav.cav_end = cr_ptr + cr_len + 2; + + rc = get_component_reference ( NULL, &cav, cr, (const char**)text ); + if ( rc != LDAP_SUCCESS ) return rc; + (*cr)->cr_string.bv_val = cav.cav_buf; + (*cr)->cr_string.bv_len = cr_len + 2; + + return LDAP_SUCCESS; +} + +static int +get_ca_use_default( Operation *op, + ComponentAssertionValue* cav, + int* ca_use_def, const char** text ) +{ + strip_cav_str( cav, "useDefaultValues" ); + + if ( peek_cav_str( cav, "TRUE" ) == LDAP_SUCCESS ) { + strip_cav_str( cav, "TRUE" ); *ca_use_def = 1; + + } else if ( peek_cav_str( cav, "FALSE" ) == LDAP_SUCCESS ) { + strip_cav_str( cav, "FALSE" ); + *ca_use_def = 0; + + } else { + return LDAP_INVALID_SYNTAX; + } + return LDAP_SUCCESS; } @@ -338,7 +709,6 @@ get_matching_rule( Operation *op, ComponentAssertionValue* cav, MatchingRule** mr, const char** text ) { int count = 0; - char temp; struct berval rule_text = { 0L, NULL }; eat_whsp( cav ); @@ -347,7 +717,9 @@ get_matching_rule( Operation *op, ComponentAssertionValue* cav, if ( cav->cav_ptr[count] == ' ' || cav->cav_ptr[count] == ',' || cav->cav_ptr[count] == '\0' || cav->cav_ptr[count] == '{' || cav->cav_ptr[count] == '}' || cav->cav_ptr[count] == '\n' ) + { break; + } } if ( count == 0 ) { @@ -359,11 +731,8 @@ get_matching_rule( Operation *op, ComponentAssertionValue* cav, rule_text.bv_val = cav->cav_ptr; *mr = mr_bvfind( &rule_text ); cav->cav_ptr += count; -#ifdef NEW_LOGGING - LDAP_LOG( FILTER, ENTRY, "get_matching_rule: %s\n", (*mr)->smr_mrule.mr_oid, 0, 0 ); -#else - Debug( LDAP_DEBUG_FILTER, "get_matching_rule: %s\n", (*mr)->smr_mrule.mr_oid, 0, 0 ); -#endif + Debug( LDAP_DEBUG_FILTER, "get_matching_rule: %s\n", + (*mr)->smr_mrule.mr_oid, 0, 0 ); if ( *mr == NULL ) { *text = "component matching rule not recognized"; return LDAP_INAPPROPRIATE_MATCHING; @@ -371,10 +740,10 @@ get_matching_rule( Operation *op, ComponentAssertionValue* cav, return LDAP_SUCCESS; } -static void +static int get_GSER_value( ComponentAssertionValue* cav, struct berval* bv ) { - int count; + int count, sequent_dquote, unclosed_brace, succeed; eat_whsp( cav ); /* @@ -389,53 +758,111 @@ get_GSER_value( ComponentAssertionValue* cav, struct berval* bv ) * INTEGER, BOOLEAN, NULL,ENUMERATE, etc */ + succeed = 0; if ( cav->cav_ptr[0] == '"' ) { - for( count = 0 ; ; count++ ) { + for( count = 1, sequent_dquote = 0 ; ; count++ ) { + /* In order to find escaped double quote */ + if ( cav->cav_ptr[count] == '"' ) sequent_dquote++; + else sequent_dquote = 0; + if ( cav->cav_ptr[count] == '\0' || - ( cav->cav_ptr[count] == '"' && cav->cav_ptr[count-1] != '"') ) + (cav->cav_ptr+count) > cav->cav_end ) + { break; + } + + if ( ( cav->cav_ptr[count] == '"' && + cav->cav_ptr[count-1] != '"') || + ( sequent_dquote > 2 && (sequent_dquote%2) == 1 ) ) + { + succeed = 1; + break; + } } - } - else if ( cav->cav_ptr[0] == '\'' ) { - for( count = 0 ; ; count++ ) { + + if ( !succeed || cav->cav_ptr[count] != '"' ) { + return LDAP_FILTER_ERROR; + } + + bv->bv_val = cav->cav_ptr + 1; + bv->bv_len = count - 1; /* exclude '"' */ + + } else if ( cav->cav_ptr[0] == '\'' ) { + for( count = 1 ; ; count++ ) { if ( cav->cav_ptr[count] == '\0' || - (cav->cav_ptr[count] == '\'' && cav->cav_ptr[count] == 'B')|| - (cav->cav_ptr[count] == '\'' && cav->cav_ptr[count] == 'H') ) + (cav->cav_ptr+count) > cav->cav_end ) + { break; + } + if ((cav->cav_ptr[count-1] == '\'' && cav->cav_ptr[count] == 'B') || + (cav->cav_ptr[count-1] == '\'' && cav->cav_ptr[count] == 'H') ) + { + succeed = 1; + break; + } } + + if ( !succeed || + !(cav->cav_ptr[count] == 'H' || cav->cav_ptr[count] == 'B') ) + { + return LDAP_FILTER_ERROR; + } + + bv->bv_val = cav->cav_ptr + 1;/*the next to '"' */ + bv->bv_len = count - 2;/* exclude "'H" or "'B" */ - } - else if ( cav->cav_ptr[0] == '{' ) { - for( count = 0 ; ; count++ ) { + } else if ( cav->cav_ptr[0] == '{' ) { + for( count = 1, unclosed_brace = 1 ; ; count++ ) { + if ( cav->cav_ptr[count] == '{' ) unclosed_brace++; + if ( cav->cav_ptr[count] == '}' ) unclosed_brace--; + if ( cav->cav_ptr[count] == '\0' || - (cav->cav_ptr[count] == '}' && cav->cav_ptr[count] == ' ') ) + (cav->cav_ptr+count) > cav->cav_end ) + { break; + } + if ( unclosed_brace == 0 ) { + succeed = 1; + break; + } } - } - else { - for( count = 0 ; ; count++ ) { - if ( cav->cav_ptr[count] == ' ') + + if ( !succeed || cav->cav_ptr[count] != '}' ) return LDAP_FILTER_ERROR; + + bv->bv_val = cav->cav_ptr + 1;/*the next to '"' */ + bv->bv_len = count - 1;/* exclude "'B" */ + + } else { + succeed = 1; + /*Find following white space where the value is ended*/ + for( count = 1 ; ; count++ ) { + if ( cav->cav_ptr[count] == '\0' || + cav->cav_ptr[count] == ' ' || cav->cav_ptr[count] == '}' || + cav->cav_ptr[count] == '{' || + (cav->cav_ptr+count) > cav->cav_end ) + { break; + } } + bv->bv_val = cav->cav_ptr; + bv->bv_len = count; } - bv->bv_val = cav->cav_ptr; - bv->bv_len = count; - cav->cav_ptr += count; + cav->cav_ptr += bv->bv_len; + return LDAP_SUCCESS; } static int get_matching_value( Operation *op, ComponentAssertion* ca, - ComponentAssertionValue* cav, struct berval* bv, - const char** text ) + ComponentAssertionValue* cav, struct berval* bv, + const char** text ) { - int count; - ber_tag_t tag; - if ( !(ca->ca_ma_rule->smr_usage & (SLAP_MR_COMPONENT)) ) { - get_GSER_value( cav, bv ); - } - else { + if ( get_GSER_value( cav, bv ) != LDAP_SUCCESS ) { + return LDAP_FILTER_ERROR; + } + + } else { /* embeded componentFilterMatch Description */ bv->bv_val = cav->cav_ptr; bv->bv_len = cav_cur_len( cav ); @@ -451,9 +878,11 @@ peek_cav_str( ComponentAssertionValue* cav, char* str ) eat_whsp( cav ); if ( cav_cur_len( cav ) >= strlen( str ) && strncmp( cav->cav_ptr, str, strlen( str ) ) == 0 ) + { return LDAP_SUCCESS; - else - return LDAP_INVALID_SYNTAX; + } + + return LDAP_INVALID_SYNTAX; } static int @@ -461,18 +890,19 @@ strip_cav_str( ComponentAssertionValue* cav, char* str) { eat_whsp( cav ); if ( cav_cur_len( cav ) >= strlen( str ) && - strncmp( cav->cav_ptr, str, strlen( str ) ) == 0 ) { + strncmp( cav->cav_ptr, str, strlen( str ) ) == 0 ) + { cav->cav_ptr += strlen( str ); return LDAP_SUCCESS; } - else - return LDAP_INVALID_SYNTAX; + + return LDAP_INVALID_SYNTAX; } /* * TAG : "item", "and", "or", "not" */ -static int +static ber_tag_t strip_cav_tag( ComponentAssertionValue* cav ) { @@ -480,21 +910,27 @@ strip_cav_tag( ComponentAssertionValue* cav ) if ( cav_cur_len( cav ) >= 8 && strncmp( cav->cav_ptr, "item", 4 ) == 0 ) { strip_cav_str( cav , "item:" ); return LDAP_COMP_FILTER_ITEM; - } - else if ( cav_cur_len( cav ) >= 7 && strncmp( cav->cav_ptr, "and", 3 ) == 0 ) { + + } else if ( cav_cur_len( cav ) >= 7 && + strncmp( cav->cav_ptr, "and", 3 ) == 0 ) + { strip_cav_str( cav , "and:" ); return LDAP_COMP_FILTER_AND; - } - else if ( cav_cur_len( cav ) >= 6 && strncmp( cav->cav_ptr, "or" , 2 ) == 0 ) { + + } else if ( cav_cur_len( cav ) >= 6 && + strncmp( cav->cav_ptr, "or" , 2 ) == 0 ) + { strip_cav_str( cav , "or:" ); return LDAP_COMP_FILTER_OR; - } - else if ( cav_cur_len( cav ) >= 7 && strncmp( cav->cav_ptr, "not", 3 ) == 0 ) { + + } else if ( cav_cur_len( cav ) >= 7 && + strncmp( cav->cav_ptr, "not", 3 ) == 0 ) + { strip_cav_str( cav , "not:" ); return LDAP_COMP_FILTER_NOT; } - else - return LBER_ERROR; + + return LBER_ERROR; } /* @@ -511,59 +947,108 @@ get_item( Operation *op, ComponentAssertionValue* cav, ComponentAssertion** ca, { int rc; ComponentAssertion* _ca; + struct berval value; + MatchingRule* mr; -#ifdef NEW_LOGGING - LDAP_LOG( FILTER, ENTRY, "get_item: %s\n", 0, 0, 0 ); -#else - Debug( LDAP_DEBUG_FILTER, "get_item: %s\n", 0, 0, 0 ); -#endif - _ca = op->o_tmpalloc( sizeof( ComponentAssertion ), op->o_tmpmemctx ); + Debug( LDAP_DEBUG_FILTER, "get_item \n", 0, 0, 0 ); + if ( op ) + _ca = op->o_tmpalloc( sizeof( ComponentAssertion ), op->o_tmpmemctx ); + else + _ca = malloc( sizeof( ComponentAssertion ) ); + + if ( !_ca ) return LDAP_NO_MEMORY; + + _ca->ca_comp_data.cd_tree = NULL; + _ca->ca_comp_data.cd_mem_op = NULL; rc = peek_cav_str( cav, "component" ); if ( rc == LDAP_SUCCESS ) { strip_cav_str( cav, "component" ); rc = get_component_reference( op, cav, &_ca->ca_comp_ref, text ); if ( rc != LDAP_SUCCESS ) { - rc = LDAP_INVALID_SYNTAX; - op->o_tmpfree( _ca, op->o_tmpmemctx ); - return rc; + if ( op ) + op->o_tmpfree( _ca, op->o_tmpmemctx ); + else + free( _ca ); + return LDAP_INVALID_SYNTAX; } + if ( ( rc = strip_cav_str( cav,",") ) != LDAP_SUCCESS ) + return rc; + } else { + _ca->ca_comp_ref = NULL; } - strip_cav_str( cav,","); rc = peek_cav_str( cav, "useDefaultValues"); if ( rc == LDAP_SUCCESS ) { rc = get_ca_use_default( op, cav, &_ca->ca_use_def, text ); if ( rc != LDAP_SUCCESS ) { - rc = LDAP_INVALID_SYNTAX; - op->o_tmpfree( _ca, op->o_tmpmemctx ); - return rc; + if ( op ) + op->o_tmpfree( _ca, op->o_tmpmemctx ); + else + free( _ca ); + return LDAP_INVALID_SYNTAX; } + if ( ( rc = strip_cav_str( cav,",") ) != LDAP_SUCCESS ) + return rc; } + else _ca->ca_use_def = 1; if ( !( strip_cav_str( cav, "rule" ) == LDAP_SUCCESS && get_matching_rule( op, cav , &_ca->ca_ma_rule, text ) == LDAP_SUCCESS )) { - rc = LDAP_INAPPROPRIATE_MATCHING; - op->o_tmpfree( _ca, op->o_tmpmemctx ); - return rc; + if ( op ) + op->o_tmpfree( _ca, op->o_tmpmemctx ); + else + free( _ca ); + return LDAP_INAPPROPRIATE_MATCHING; } - strip_cav_str( cav,","); - if ( !(strip_cav_str( cav, "value" ) == LDAP_SUCCESS && - get_matching_value( op, _ca, cav, &_ca->ca_ma_value,text ) == LDAP_SUCCESS )) { - rc = LDAP_INVALID_SYNTAX; - op->o_tmpfree( _ca, op->o_tmpmemctx ); + if ( ( rc = strip_cav_str( cav,",") ) != LDAP_SUCCESS ) return rc; + if ( !(strip_cav_str( cav, "value" ) == LDAP_SUCCESS && + get_matching_value( op, _ca, cav,&value ,text ) == LDAP_SUCCESS )) { + if ( op ) + op->o_tmpfree( _ca, op->o_tmpmemctx ); + else + free( _ca ); + return LDAP_INVALID_SYNTAX; + } + + /* + * Normalize the value of this component assertion when the matching + * rule is one of existing matching rules + */ + mr = _ca->ca_ma_rule; + if ( op && !(mr->smr_usage & (SLAP_MR_COMPONENT)) && mr->smr_normalize ) { + + value.bv_val[value.bv_len] = '\0'; + rc = mr->smr_normalize ( + SLAP_MR_VALUE_OF_ASSERTION_SYNTAX, + NULL, mr, + &value, &_ca->ca_ma_value, op->o_tmpmemctx ); + if ( rc != LDAP_SUCCESS ) + return rc; + } + else + _ca->ca_ma_value = value; + /* + * Validate the value of this component assertion + */ + if ( op && mr->smr_syntax->ssyn_validate( mr->smr_syntax, &_ca->ca_ma_value) != LDAP_SUCCESS ) { + return LDAP_INVALID_SYNTAX; } + /* componentFilterMatch contains componentFilterMatch in it */ - if ( _ca->ca_ma_rule->smr_usage & (SLAP_MR_COMPONENT) ) { + if ( strcmp(_ca->ca_ma_rule->smr_mrule.mr_oid, OID_COMP_FILTER_MATCH ) == 0) { struct berval bv; bv.bv_val = cav->cav_ptr; bv.bv_len = cav_cur_len( cav ); rc = get_comp_filter( op, &bv,(ComponentFilter**)&_ca->ca_cf, text ); if ( rc != LDAP_SUCCESS ) { - op->o_tmpfree( _ca, op->o_tmpmemctx ); + if ( op ) + op->o_tmpfree( _ca, op->o_tmpmemctx ); + else + free( _ca ); return rc; } cav->cav_ptr = bv.bv_val; @@ -589,7 +1074,6 @@ parse_comp_filter( Operation* op, ComponentAssertionValue* cav, */ ber_tag_t tag; - ber_len_t len; int err; ComponentFilter f; /* TAG : item, and, or, not in RFC 2254 */ @@ -610,11 +1094,7 @@ parse_comp_filter( Operation* op, ComponentAssertionValue* cav, switch ( f.cf_choice ) { case LDAP_COMP_FILTER_AND: -#ifdef NEW_LOGGING - LDAP_LOG( FILTER, ENTRY, "LDAP_COMP_FILTER_AND\n", 0, 0, 0 ); -#else Debug( LDAP_DEBUG_FILTER, "LDAP_COMP_FILTER_AND\n", 0, 0, 0 ); -#endif err = get_comp_filter_list( op, cav, &f.cf_and, text ); if ( err != LDAP_SUCCESS ) { break; @@ -626,11 +1106,7 @@ parse_comp_filter( Operation* op, ComponentAssertionValue* cav, break; case LDAP_COMP_FILTER_OR: -#ifdef NEW_LOGGING - LDAP_LOG( FILTER, ENTRY, "LDAP_COMP_FILTER_OR\n", 0, 0, 0 ); -#else Debug( LDAP_DEBUG_FILTER, "LDAP_COMP_FILTER_OR\n", 0, 0, 0 ); -#endif err = get_comp_filter_list( op, cav, &f.cf_or, text ); if ( err != LDAP_SUCCESS ) { break; @@ -643,11 +1119,7 @@ parse_comp_filter( Operation* op, ComponentAssertionValue* cav, break; case LDAP_COMP_FILTER_NOT: -#ifdef NEW_LOGGING - LDAP_LOG( FILTER, ENTRY, "LDAP_COMP_FILTER_NOT\n", 0, 0, 0 ); -#else Debug( LDAP_DEBUG_FILTER, "LDAP_COMP_FILTER_NOT\n", 0, 0, 0 ); -#endif err = parse_comp_filter( op, cav, &f.cf_not, text ); if ( err != LDAP_SUCCESS ) { break; @@ -674,11 +1146,7 @@ parse_comp_filter( Operation* op, ComponentAssertionValue* cav, break; case LDAP_COMP_FILTER_ITEM: -#ifdef NEW_LOGGING - LDAP_LOG( FILTER, ENTRY, "LDAP_COMP_FILTER_ITEM\n", 0, 0, 0 ); -#else Debug( LDAP_DEBUG_FILTER, "LDAP_COMP_FILTER_ITEM\n", 0, 0, 0 ); -#endif err = get_item( op, cav, &f.cf_ca, text ); if ( err != LDAP_SUCCESS ) { break; @@ -693,18 +1161,20 @@ parse_comp_filter( Operation* op, ComponentAssertionValue* cav, break; } - if ( tag != LDAP_COMP_FILTER_NOT ) - strip_cav_str( cav, "}"); - if ( err != LDAP_SUCCESS && err != SLAPD_DISCONNECT ) { - *text = NULL; - f.cf_choice = SLAPD_FILTER_COMPUTED; - f.cf_result = SLAPD_COMPARE_UNDEFINED; - err = LDAP_SUCCESS; + *text = "Component Filter Syntax Error"; + return err; } + if ( tag != LDAP_COMP_FILTER_NOT ) + strip_cav_str( cav, "}"); + if ( err == LDAP_SUCCESS ) { - *filt = op->o_tmpalloc( sizeof(f), op->o_tmpmemctx ); + if ( op ) { + *filt = op->o_tmpalloc( sizeof(f), op->o_tmpmemctx ); + } else { + *filt = malloc( sizeof(f) ); + } **filt = f; } @@ -713,16 +1183,15 @@ parse_comp_filter( Operation* op, ComponentAssertionValue* cav, static int test_comp_filter_and( - Operation *op, - Attribute *a, - struct berval *bv, + Syntax *syn, + ComponentSyntaxInfo *a, ComponentFilter *flist ) { ComponentFilter *f; int rtn = LDAP_COMPARE_TRUE; for ( f = flist ; f != NULL; f = f->cf_next ) { - int rc = test_comp_filter_attr( op, a, bv, f ); + int rc = test_comp_filter( syn, a, f ); if ( rc == LDAP_COMPARE_FALSE ) { rtn = rc; break; @@ -738,16 +1207,15 @@ test_comp_filter_and( static int test_comp_filter_or( - Operation *op, - Attribute *a, - struct berval *bv, + Syntax *syn, + ComponentSyntaxInfo *a, ComponentFilter *flist ) { ComponentFilter *f; int rtn = LDAP_COMPARE_TRUE; for ( f = flist ; f != NULL; f = f->cf_next ) { - int rc = test_comp_filter_attr( op, a, bv, f ); + int rc = test_comp_filter( syn, a, f ); if ( rc == LDAP_COMPARE_TRUE ) { rtn = rc; break; @@ -761,144 +1229,96 @@ test_comp_filter_or( return rtn; } -/* - * Convert attribute value to C internal data structure - * This function has an associated ASN.1 type - * bv must contain the value for the type( type name is T1 ) - * This function is linked to ssyn_attr2comp - */ +int +csi_value_match( MatchingRule *mr, struct berval* bv_attr, + struct berval* bv_assert ) +{ + int rc; + int match; + + assert( mr != NULL ); + assert( !(mr->smr_usage & SLAP_MR_COMPONENT) ); + + if( !mr->smr_match ) return LDAP_INAPPROPRIATE_MATCHING; + + rc = (mr->smr_match)( &match, 0, NULL /*ad->ad_type->sat_syntax*/, + mr, bv_attr, bv_assert ); + + if ( rc != LDAP_SUCCESS ) return rc; + + return match ? LDAP_COMPARE_FALSE : LDAP_COMPARE_TRUE; +} /* * return codes : LDAP_COMPARE_TRUE, LDAP_COMPARE_FALSE */ static int test_comp_filter_item( - Operation *op, - Attribute *a, - struct berval *bv, + Syntax *syn, + ComponentSyntaxInfo *csi_attr, ComponentAssertion *ca ) { - int rc = LDAP_COMPARE_TRUE; - int len; - ComponentSyntaxInfo* csi_attr, *csi_assert; + int rc; + void *attr_nm, *assert_nm; - if ( (ca->ca_ma_rule->smr_usage & SLAP_MR_COMPONENT) && ca->ca_cf ) { + if ( strcmp(ca->ca_ma_rule->smr_mrule.mr_oid, + OID_COMP_FILTER_MATCH ) == 0 && ca->ca_cf ) { /* componentFilterMatch inside of componentFilterMatch */ - rc = test_comp_filter_attr( op, a, bv, ca->ca_cf ); + rc = test_comp_filter( syn, csi_attr, ca->ca_cf ); return rc; } - assert( !(ca->ca_ma_rule->smr_usage & SLAP_MR_COMPONENT) ); - /* FIXME : Return ALWAYS true */ - return LDAP_COMPARE_TRUE; -} - -/* - * If matched, LDAP_COMPARE_TRUE is returned - */ -int -test_comp_filter_entry( - Operation *op, - Entry *e, - MatchingRuleAssertion *mra ) -{ - Attribute *a; - void *memctx; - - mra->cf->cf_ca->ca_mra = mra; + /* Memory for storing will-be-extracted attribute values */ + attr_nm = nibble_mem_allocator ( 1024*4 , 1024 ); + if ( !attr_nm ) return LDAP_PROTOCOL_ERROR; -#ifdef NEW_LOGGING - LDAP_LOG( FILTER, ENTRY, "test_comp_filter_entry\n", 0, 0, 0 ); -#else - Debug( LDAP_DEBUG_FILTER, "test_comp_filter_entry\n", 0, 0, 0 ); -#endif - if ( mra->ma_desc ) { - /* - * ma_desc is available, so filtering for one attribute - * SEARCH permissionc can be checked directly - */ - if ( !access_allowed( op, e, mra->ma_desc, - &mra->ma_value, ACL_SEARCH, NULL ) ) - { - return LDAP_INSUFFICIENT_ACCESS; - } - /* Find attributes that componentFilter Match can be applied to */ - for( a=attrs_find( e->e_attrs, mra->ma_desc ); - a != NULL ; - a = attrs_find( a->a_next, mra->ma_desc ) ) - { - struct berval *bv = a->a_vals; - - for ( ; bv->bv_val != NULL ; bv++ ) { - int ret, rc; - const char *text; - rc = test_comp_filter_attr( op, a, bv, mra->cf ); - if ( rc == LDAP_COMPARE_TRUE ) return rc; - } + /* Memory for storing component assertion values */ + if( !ca->ca_comp_data.cd_mem_op ) { + assert_nm = nibble_mem_allocator ( 256, 64 ); + if ( !assert_nm ) { + nibble_mem_free ( attr_nm ); + return LDAP_PROTOCOL_ERROR; } + ca->ca_comp_data.cd_mem_op = assert_nm; } else { - /* - * No attribute description : test all - */ - for ( a = e->e_attrs; a != NULL; a = a->a_next ) { - struct berval *bv, value; - const char *text = NULL; - int rc; - - /* check if matching is appropriate */ - if ( !mr_usable_with_at( mra->ma_rule, a->a_desc->ad_type -)) { - continue; - } - - /* check search access */ - if ( !access_allowed( op, e, - a->a_desc, &value, ACL_SEARCH, NULL ) ) { - continue; - } - - bv = a->a_vals; - - for ( ; bv->bv_val != NULL ; bv++ ) { - int ret, rc; - const char *text; - rc = test_comp_filter_attr( op, a, bv, mra->cf ); - if ( rc == LDAP_COMPARE_TRUE ) break; - } - if ( rc != LDAP_SUCCESS ) return rc; - } + assert_nm = ca->ca_comp_data.cd_mem_op; } - return LDAP_COMPARE_FALSE; + /* component reference initialization */ + if ( ca->ca_comp_ref ) { + ca->ca_comp_ref->cr_curr = ca->ca_comp_ref->cr_list; + } + rc = test_components( attr_nm, assert_nm, csi_attr, ca ); + + /* free memory used for storing extracted attribute value */ + nibble_mem_free ( attr_nm ); + return rc; } static int -test_comp_filter_attr( - Operation *op, - Attribute *a, - struct berval *bv, +test_comp_filter( + Syntax *syn, + ComponentSyntaxInfo *a, ComponentFilter *f ) { int rc; -#ifdef NEW_LOGGING - LDAP_LOG( FILTER, ENTRY, "test_comp_filter_attr\n", 0, 0, 0 ); -#else - Debug( LDAP_DEBUG_FILTER, "test_comp_filter_attr\n", 0, 0, 0 ); -#endif + if ( !f ) return LDAP_PROTOCOL_ERROR; + + Debug( LDAP_DEBUG_FILTER, "test_comp_filter\n", 0, 0, 0 ); switch ( f->cf_choice ) { case SLAPD_FILTER_COMPUTED: rc = f->cf_result; break; case LDAP_COMP_FILTER_AND: - rc = test_comp_filter_and( op, a, bv, f->cf_and ); + rc = test_comp_filter_and( syn, a, f->cf_and ); break; case LDAP_COMP_FILTER_OR: - rc = test_comp_filter_or( op, a, bv, f->cf_or ); + rc = test_comp_filter_or( syn, a, f->cf_or ); break; case LDAP_COMP_FILTER_NOT: - rc = test_comp_filter_attr( op, a, bv, f->cf_not ); + rc = test_comp_filter( syn, a, f->cf_not ); switch ( rc ) { case LDAP_COMPARE_TRUE: @@ -910,7 +1330,7 @@ test_comp_filter_attr( } break; case LDAP_COMP_FILTER_ITEM: - rc = test_comp_filter_item( op, a, bv, f->cf_ca ); + rc = test_comp_filter_item( syn, a, f->cf_ca ); break; default: rc = LDAP_PROTOCOL_ERROR; @@ -918,4 +1338,53 @@ test_comp_filter_attr( return( rc ); } + +static void +free_comp_filter_list( ComponentFilter* f ) +{ + ComponentFilter* tmp; + for ( tmp = f; tmp; tmp = tmp->cf_next ) { + free_comp_filter( tmp ); + } +} + +static void +free_comp_filter( ComponentFilter* f ) +{ + if ( !f ) { + Debug( LDAP_DEBUG_FILTER, + "free_comp_filter: Invalid filter so failed to release memory\n", + 0, 0, 0 ); + return; + } + switch ( f->cf_choice ) { + case LDAP_COMP_FILTER_AND: + case LDAP_COMP_FILTER_OR: + free_comp_filter_list( f->cf_any ); + break; + case LDAP_COMP_FILTER_NOT: + free_comp_filter( f->cf_any ); + break; + case LDAP_COMP_FILTER_ITEM: + if ( nibble_mem_free && f->cf_ca->ca_comp_data.cd_mem_op ) { + nibble_mem_free( f->cf_ca->ca_comp_data.cd_mem_op ); + } + break; + default: + break; + } +} + +void +component_free( ComponentFilter *f ) { + free_comp_filter( f ); +} + +void +free_ComponentData( Attribute *a ) { + if ( a->a_comp_data->cd_mem_op ) + component_destructor( a->a_comp_data->cd_mem_op ); + free ( a->a_comp_data ); + a->a_comp_data = NULL; +} #endif