X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fcomponent.c;h=3fe99d1dfd4dca4fc2da984d3bd316a9bee843b4;hb=7ce9e7b7c637a69fa1fdd78cfdfbf2581bb8217e;hp=8e851bea225a8740f838cb67c01d40f932220a95;hpb=55b4021183c4674e9bf91dd42f47417bc0861be8;p=openldap diff --git a/servers/slapd/component.c b/servers/slapd/component.c index 8e851bea22..3fe99d1dfd 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-2006 The OpenLDAP Foundation. * Portions Copyright 2004 by IBM Corporation. * All rights reserved. * @@ -29,14 +29,18 @@ #include "component.h" /* - * This three function pointers are initialized + * Following function pointers are initialized * when a component module is loaded */ -convert_attr_to_comp_func* attr_converter = NULL ; +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 ; -convert_asn_to_ldap_func* csi_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 @@ -58,8 +62,7 @@ static void free_comp_filter( ComponentFilter* f ); static int -test_comp_filter( Syntax *syn, Attribute *a, struct berval *bv, - ComponentFilter *f ); +test_comp_filter( Syntax *syn, ComponentSyntaxInfo *a, ComponentFilter *f ); int componentCertificateValidate( @@ -94,19 +97,19 @@ componentFilterMatch ( struct berval *value, void *assertedValue ) { - Attribute *a = (Attribute*)value; + ComponentSyntaxInfo *csi_attr = (ComponentSyntaxInfo*)value; MatchingRuleAssertion * ma = (MatchingRuleAssertion*)assertedValue; - int rc; - if ( !(mr && mr->smr_usage & SLAP_MR_COMPONENT) || !ma->ma_cf ) - return LDAP_INAPPROPRIATE_MATCHING; - - rc = test_comp_filter( syntax, a, a->a_vals, ma->ma_cf ); - if ( component_destructor && a->a_component_values ) { - component_destructor(a->a_component_values); - a->a_component_values = NULL; + 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; @@ -118,7 +121,20 @@ componentFilterMatch ( 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 @@ -130,29 +146,198 @@ allComponentsMatch( struct berval *value, void *assertedValue ) { - /* Only for Registeration */ + /* Only for registration */ *matchp = 0; return LDAP_SUCCESS; } static int -slapd_ber2cav( struct berval* bv, ComponentAssertionValue* cav) +slapd_ber2cav( struct berval* bv, ComponentAssertionValue* cav ) { - int len; + 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; - len = ldap_pvt_filter_value_unescape( bv->bv_val ); - if ( len == -1 ) { - return LDAP_FILTER_ERROR; + 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; } - cav->cav_ptr = cav->cav_buf = bv->bv_val; - cav->cav_end = bv->bv_val + len; + dup_cr->cr_curr = dup_cr->cr_list; + + return dup_cr; +} + +static int +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; + + 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 -get_comp_filter( Operation* op, struct berval* bv, ComponentFilter** filt, - const char **text ) +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_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 rc; @@ -187,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 */ @@ -216,7 +407,7 @@ 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; @@ -224,12 +415,12 @@ get_comp_filter_list( Operation *op, ComponentAssertionValue *cav, Debug( LDAP_DEBUG_FILTER, "get_comp_filter_list\n", 0, 0, 0 ); 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; @@ -239,7 +430,7 @@ get_comp_filter_list( Operation *op, ComponentAssertionValue *cav, static int get_componentId( Operation *op, ComponentAssertionValue* cav, - ComponentId ** cid, const char** text ) + ComponentId ** cid, const char** text ) { ber_tag_t type; ComponentId _cid; @@ -247,7 +438,8 @@ get_componentId( Operation *op, ComponentAssertionValue* cav, type = peek_componentId_type( cav ); - Debug( LDAP_DEBUG_FILTER, "get_compId [%d]\n", type, 0, 0 ); + Debug( LDAP_DEBUG_FILTER, "get_compId [%lu]\n", + (unsigned long) type, 0, 0 ); len = 0; _cid.ci_type = type; _cid.ci_next = NULL; @@ -276,21 +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++; - Debug( LDAP_DEBUG_FILTER, "get_compId : ALL\n", 0, 0, 0 ); 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; } @@ -299,94 +501,204 @@ 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 ) + + } 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 ) -{ - 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; - } +int +insert_component_reference( + ComponentReference *cr, + ComponentReference** cr_list) +{ + if ( !cr ) return LDAP_PARAM_ERROR; + if ( !(*cr_list) ) { + *cr_list = cr; + cr->cr_next = NULL; } else { - /* If not defined, default value is TRUE */ + 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; + } + + 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; @@ -405,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 ) { @@ -417,7 +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; - Debug( LDAP_DEBUG_FILTER, "get_matching_rule: %s\n", (*mr)->smr_mrule.mr_oid, 0, 0 ); + 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; @@ -450,60 +765,97 @@ get_GSER_value( ComponentAssertionValue* cav, struct berval* bv ) if ( cav->cav_ptr[count] == '"' ) sequent_dquote++; else sequent_dquote = 0; - if ( cav->cav_ptr[count] == '\0' || cav->cav_ptr > cav->cav_end ) { + if ( cav->cav_ptr[count] == '\0' || + (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 ) ) { + 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] == '\'' ) { + + 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 > cav->cav_end ) { + if ( cav->cav_ptr[count] == '\0' || + (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') ) { + 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] == '{' ) { + } 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 > cav->cav_end ) + if ( cav->cav_ptr[count] == '\0' || + (cav->cav_ptr+count) > cav->cav_end ) + { break; + } if ( unclosed_brace == 0 ) { succeed = 1; break; } } - } - else { + + 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; - count = cav->cav_end - cav->cav_ptr; + /*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; } - if ( !succeed ) return LDAP_FILTER_ERROR; - - bv->bv_val = cav->cav_ptr; - bv->bv_len = count + 1 ; - 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 ) { if ( !(ca->ca_ma_rule->smr_usage & (SLAP_MR_COMPONENT)) ) { if ( get_GSER_value( cav, bv ) != LDAP_SUCCESS ) { @@ -526,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 @@ -536,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 ) { @@ -555,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; } /* @@ -586,50 +947,97 @@ get_item( Operation *op, ComponentAssertionValue* cav, ComponentAssertion** ca, { int rc; ComponentAssertion* _ca; + struct berval value; + MatchingRule* mr; + + 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 ) ); - Debug( LDAP_DEBUG_FILTER, "get_item: %s\n", 0, 0, 0 ); - _ca = op->o_tmpalloc( sizeof( ComponentAssertion ), op->o_tmpmemctx ); + if ( !_ca ) return LDAP_NO_MEMORY; - _ca->ca_component_values = NULL; + _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; } - strip_cav_str( cav,","); + 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 ( strcmp(_ca->ca_ma_rule->smr_mrule.mr_oid, OID_COMP_FILTER_MATCH ) == 0) { struct berval bv; @@ -637,7 +1045,10 @@ get_item( Operation *op, ComponentAssertionValue* cav, ComponentAssertion** ca, 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; @@ -750,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; } @@ -771,15 +1184,14 @@ parse_comp_filter( Operation* op, ComponentAssertionValue* cav, static int test_comp_filter_and( Syntax *syn, - Attribute *a, - struct berval *bv, + 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( syn, a, bv, f ); + int rc = test_comp_filter( syn, a, f ); if ( rc == LDAP_COMPARE_FALSE ) { rtn = rc; break; @@ -796,15 +1208,14 @@ test_comp_filter_and( static int test_comp_filter_or( Syntax *syn, - Attribute *a, - struct berval *bv, + 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( syn, a, bv, f ); + int rc = test_comp_filter( syn, a, f ); if ( rc == LDAP_COMPARE_TRUE ) { rtn = rc; break; @@ -818,9 +1229,9 @@ test_comp_filter_or( return rtn; } -static int +int csi_value_match( MatchingRule *mr, struct berval* bv_attr, - struct berval* bv_assert ) + struct berval* bv_assert ) { int rc; int match; @@ -828,114 +1239,67 @@ csi_value_match( MatchingRule *mr, struct berval* bv_attr, assert( mr != NULL ); assert( !(mr->smr_usage & SLAP_MR_COMPONENT) ); - if( !mr->smr_match ) { - return LDAP_INAPPROPRIATE_MATCHING; - } + 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 match? LDAP_COMPARE_FALSE:LDAP_COMPARE_TRUE; - else - return rc; -} - -int -component_value_match( MatchingRule* mr, - ComponentSyntaxInfo* csi_attr, ComponentSyntaxInfo* csi_assert ) -{ - if ( mr->smr_usage & SLAP_MR_COMPONENT ){ - if ( strcmp( mr->smr_mrule.mr_oid, OID_ALL_COMP_MATCH ) == 0 ) - { - /* allComponentMatch */ - return csi_attr->csi_comp_desc->cd_all_match( NULL, - csi_attr, csi_assert ); - } else { - return csi_assert->csi_comp_desc->cd_all_match( - mr->smr_mrule.mr_oid, csi_attr, csi_assert ); - } - - } else { - if ( csi_attr->csi_comp_desc->cd_type == ASN_BASIC ) { - struct berval bv1, bv2; - char attr_buf[MAX_LDAP_STR_LEN],assert_buf[MAX_LDAP_STR_LEN]; - bv1.bv_val = attr_buf; - bv2.bv_val = assert_buf; - if ( csi_converter && - ( csi_converter ( csi_attr, &bv1 ) == LDAP_SUCCESS ) && - ( csi_converter ( csi_assert, &bv2 ) == LDAP_SUCCESS ) ) - { - return csi_value_match( mr, &bv1, &bv2 ); - - } else { - return LDAP_INAPPROPRIATE_MATCHING; - } + mr, bv_attr, bv_assert ); - } else if ( csi_attr->csi_comp_desc->cd_type == ASN_COMPOSITE ) - { - return LDAP_INAPPROPRIATE_MATCHING; - } - } + if ( rc != LDAP_SUCCESS ) return rc; - /* FIXME: what should be returned here? Is this rachable at all? */ - return LDAP_INAPPROPRIATE_MATCHING; + return match ? LDAP_COMPARE_FALSE : LDAP_COMPARE_TRUE; } /* * return codes : LDAP_COMPARE_TRUE, LDAP_COMPARE_FALSE */ - static int test_comp_filter_item( Syntax *syn, - Attribute *a, - struct berval *bv, + ComponentSyntaxInfo *csi_attr, ComponentAssertion *ca ) { - int rc, len; - ComponentSyntaxInfo* csi_attr, *csi_assert=NULL; + int rc; + void *attr_nm, *assert_nm; 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( syn, a, bv, ca->ca_cf ); + rc = test_comp_filter( syn, csi_attr, ca->ca_cf ); return rc; } - /* load attribute containg components */ - /* For a testing purpose, link following function here */ - if ( !a->a_component_values && attr_converter ) - a->a_component_values = attr_converter (a, syn, bv); - - if ( a->a_component_values == NULL ) - return LDAP_PROTOCOL_ERROR; - - /* load component containg the referenced component */ - ca->ca_comp_ref->cr_curr = ca->ca_comp_ref->cr_list; - csi_attr = (((ComponentSyntaxInfo*)a->a_component_values)->csi_comp_desc->cd_extract_i)( ca->ca_comp_ref, a->a_component_values ); + /* Memory for storing will-be-extracted attribute values */ + attr_nm = nibble_mem_allocator ( 1024*4 , 1024 ); + if ( !attr_nm ) return LDAP_PROTOCOL_ERROR; - if ( !csi_attr ) - return LDAP_PROTOCOL_ERROR; + /* 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; - /* decode the asserted value */ - if( !ca->ca_component_values && assert_converter ) { - assert_converter ( csi_attr, &ca->ca_ma_value, - &csi_assert, &len, DEC_ALLOC_MODE_0 ); - ca->ca_component_values = (void*)csi_assert; + } else { + assert_nm = ca->ca_comp_data.cd_mem_op; } - else csi_assert = ca->ca_component_values; - if ( !csi_assert ) - return LDAP_PROTOCOL_ERROR; + /* 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 ); - return component_value_match( ca->ca_ma_rule, csi_attr, csi_assert); + /* free memory used for storing extracted attribute value */ + nibble_mem_free ( attr_nm ); + return rc; } static int test_comp_filter( Syntax *syn, - Attribute *a, - struct berval *bv, + ComponentSyntaxInfo *a, ComponentFilter *f ) { int rc; @@ -948,13 +1312,13 @@ test_comp_filter( rc = f->cf_result; break; case LDAP_COMP_FILTER_AND: - rc = test_comp_filter_and( syn, 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( syn, 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( syn, a, bv, f->cf_not ); + rc = test_comp_filter( syn, a, f->cf_not ); switch ( rc ) { case LDAP_COMPARE_TRUE: @@ -966,7 +1330,7 @@ test_comp_filter( } break; case LDAP_COMP_FILTER_ITEM: - rc = test_comp_filter_item( syn, a, bv, f->cf_ca ); + rc = test_comp_filter_item( syn, a, f->cf_ca ); break; default: rc = LDAP_PROTOCOL_ERROR; @@ -979,8 +1343,7 @@ static void free_comp_filter_list( ComponentFilter* f ) { ComponentFilter* tmp; - for ( tmp = f ; tmp; tmp = tmp->cf_next ); - { + for ( tmp = f; tmp; tmp = tmp->cf_next ) { free_comp_filter( tmp ); } } @@ -988,18 +1351,25 @@ free_comp_filter_list( ComponentFilter* f ) 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 ( component_destructor && f->cf_ca->ca_component_values ) - component_destructor( f->cf_ca->ca_component_values ); + 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; } @@ -1010,4 +1380,11 @@ 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