From 1b268479c3a72d83f138c39cc436afd2a51175f1 Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Wed, 26 Jan 2005 21:48:36 +0000 Subject: [PATCH] fix ITS#3406 - normalize attributes according to MR syntax in MRA filters --- servers/slapd/filterentry.c | 124 +++++++++++++++++++++++++++------- servers/slapd/matchedValues.c | 51 ++++++++++---- 2 files changed, 136 insertions(+), 39 deletions(-) diff --git a/servers/slapd/filterentry.c b/servers/slapd/filterentry.c index 5cc91fbb8c..005c6f7aa4 100644 --- a/servers/slapd/filterentry.c +++ b/servers/slapd/filterentry.c @@ -172,7 +172,7 @@ static int test_mra_filter( * one attribute, and SEARCH permissions can be checked * directly. */ - if( !access_allowed( op, e, + if ( !access_allowed( op, e, mra->ma_desc, &mra->ma_value, ACL_SEARCH, NULL ) ) { return LDAP_INSUFFICIENT_ACCESS; @@ -191,18 +191,20 @@ static int test_mra_filter( return LDAP_COMPARE_FALSE; } - for(a = attrs_find( e->e_attrs, mra->ma_desc ); + for ( a = attrs_find( e->e_attrs, mra->ma_desc ); a != NULL; a = attrs_find( a->a_next, mra->ma_desc ) ) { - struct berval *bv; + struct berval *bv; + int normalize_attribute = 0; + #ifdef LDAP_COMP_MATCH /* Component Matching */ - if( mra->ma_cf && mra->ma_rule->smr_usage & SLAP_MR_COMPONENT ) { + if ( mra->ma_cf && mra->ma_rule->smr_usage & SLAP_MR_COMPONENT ) { num_attr_vals = 0; if ( !a->a_comp_data ) { for ( ; - a->a_vals[num_attr_vals].bv_val != NULL; + !BER_BVISNULL( &a->a_vals[num_attr_vals] ); num_attr_vals++ ) { /* empty */; @@ -231,22 +233,25 @@ static int test_mra_filter( /* If ma_rule is not the same as the attribute's * normal rule, then we can't use the a_nvals. */ - if (mra->ma_rule == a->a_desc->ad_type->sat_equality) { + if ( mra->ma_rule == a->a_desc->ad_type->sat_equality ) { bv = a->a_nvals; + } else { bv = a->a_vals; + normalize_attribute = 1; } #ifdef LDAP_COMP_MATCH i = 0; #endif - for ( ; bv->bv_val != NULL; bv++ ) { + for ( ; !BER_BVISNULL( bv ); bv++ ) { int ret; int rc; const char *text; #ifdef LDAP_COMP_MATCH - if( mra->ma_cf && - mra->ma_rule->smr_usage & SLAP_MR_COMPONENT ) { + if ( mra->ma_cf && + mra->ma_rule->smr_usage & SLAP_MR_COMPONENT ) + { /* Check if decoded component trees are already linked */ if ( num_attr_vals ) { a->a_comp_data->cd_tree[i] = attr_converter( @@ -262,11 +267,53 @@ static int test_mra_filter( } else #endif { + struct berval nbv = BER_BVNULL; + + if ( normalize_attribute && mra->ma_rule->smr_normalize ) { + /* + + Document: draft-ietf-ldapbis-protocol + + 4.5.1. Search Request + ... + If the type field is present and the matchingRule is present, + the matchValue is compared against entry attributes of the + specified type. In this case, the matchingRule MUST be one + suitable for use with the specified type (see [Syntaxes]), + otherwise the filter item is Undefined. + + + In this case, since the matchingRule requires the assertion + value to be normalized, we normalize the attribute value + according to the syntax of the matchingRule. + + This should likely be done inside value_match(), by passing + the appropriate flags, but this is not done at present. + See ITS#3406. + */ + if ( mra->ma_rule->smr_normalize( + SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX, + mra->ma_rule->smr_syntax, + mra->ma_rule, + bv, &nbv, memctx ) != LDAP_SUCCESS ) + { + /* FIXME: stop processing? */ + continue; + } + + } else { + nbv = *bv; + } + rc = value_match( &ret, a->a_desc, mra->ma_rule, 0, - bv, &mra->ma_value, &text ); + &nbv, &mra->ma_value, &text ); + + if ( nbv.bv_val != bv->bv_val ) { + memfree( nbv.bv_val, memctx ); + } } - if( rc != LDAP_SUCCESS ) return rc; + if ( rc != LDAP_SUCCESS ) return rc; if ( ret == 0 ) return LDAP_COMPARE_TRUE; } } @@ -279,9 +326,10 @@ static int test_mra_filter( struct berval *bv, value; const char *text = NULL; int rc; + int normalize_attribute = 0; /* check if matching is appropriate */ - if ( !mr_usable_with_at( mra->ma_rule, a->a_desc->ad_type )) { + if ( !mr_usable_with_at( mra->ma_rule, a->a_desc->ad_type ) ) { continue; } @@ -293,20 +341,21 @@ static int test_mra_filter( /* check search access */ if ( !access_allowed( op, e, - a->a_desc, &value, ACL_SEARCH, NULL ) ) { + a->a_desc, &value, ACL_SEARCH, NULL ) ) + { memfree( value.bv_val, memctx ); continue; } #ifdef LDAP_COMP_MATCH /* Component Matching */ - if( mra->ma_cf && - mra->ma_rule->smr_usage & SLAP_MR_COMPONENT) + if ( mra->ma_cf && + mra->ma_rule->smr_usage & SLAP_MR_COMPONENT ) { int ret; rc = value_match( &ret, a->a_desc, mra->ma_rule, 0, (struct berval*)a, (void*)mra, &text ); - if( rc != LDAP_SUCCESS ) break; + if ( rc != LDAP_SUCCESS ) break; if ( ret == 0 ) { rc = LDAP_COMPARE_TRUE; @@ -317,19 +366,42 @@ static int test_mra_filter( #endif /* check match */ - if (mra->ma_rule == a->a_desc->ad_type->sat_equality) { + if ( mra->ma_rule == a->a_desc->ad_type->sat_equality ) { bv = a->a_nvals; + } else { bv = a->a_vals; + normalize_attribute = 1; } - for ( ; bv->bv_val != NULL; bv++ ) { - int ret; - + for ( ; !BER_BVISNULL( bv ); bv++ ) { + int ret; + struct berval nbv = BER_BVNULL; + + if ( normalize_attribute && mra->ma_rule->smr_normalize ) { + /* see comment above */ + if ( mra->ma_rule->smr_normalize( + SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX, + mra->ma_rule->smr_syntax, + mra->ma_rule, + bv, &nbv, memctx ) != LDAP_SUCCESS ) + { + /* FIXME: stop processing? */ + continue; + } + + } else { + nbv = *bv; + } + rc = value_match( &ret, a->a_desc, mra->ma_rule, 0, - bv, &value, &text ); + &nbv, &value, &text ); + + if ( nbv.bv_val != bv->bv_val ) { + memfree( nbv.bv_val, memctx ); + } - if( rc != LDAP_SUCCESS ) break; + if ( rc != LDAP_SUCCESS ) break; if ( ret == 0 ) { rc = LDAP_COMPARE_TRUE; @@ -378,7 +450,7 @@ static int test_mra_filter( const char *text = NULL; /* check if matching is appropriate */ - if ( !mr_usable_with_at( mra->ma_rule, ad->ad_type )) { + if ( !mr_usable_with_at( mra->ma_rule, ad->ad_type ) ) { continue; } @@ -407,7 +479,7 @@ static int test_mra_filter( if ( rc == LDAP_SUCCESS && ret == 0 ) rc = LDAP_COMPARE_TRUE; - if( rc != LDAP_SUCCESS ) { + if ( rc != LDAP_SUCCESS ) { ldap_dnfree_x( dn, memctx ); return rc; } @@ -532,7 +604,7 @@ test_ava_filter( continue; } - for ( bv = a->a_nvals; bv->bv_val != NULL; bv++ ) { + for ( bv = a->a_nvals; !BER_BVISNULL( bv ); bv++ ) { int ret, match; const char *text; @@ -721,7 +793,7 @@ test_substrings_filter( continue; } - for ( bv = a->a_nvals; bv->bv_val != NULL; bv++ ) { + for ( bv = a->a_nvals; !BER_BVISNULL( bv ); bv++ ) { int ret, match; const char *text; diff --git a/servers/slapd/matchedValues.c b/servers/slapd/matchedValues.c index b95765ef93..2ef1d934e8 100644 --- a/servers/slapd/matchedValues.c +++ b/servers/slapd/matchedValues.c @@ -171,7 +171,7 @@ test_ava_vrFilter( if( mr == NULL ) continue; bv = a->a_nvals; - for ( j=0; bv->bv_val != NULL; bv++, j++ ) { + for ( j=0; !BER_BVISNULL( bv ); bv++, j++ ) { int rc, match; const char *text; @@ -218,7 +218,7 @@ test_presence_vrFilter( if ( !is_ad_subtype( a->a_desc, desc ) ) continue; - for ( bv = a->a_vals, j=0; bv->bv_val != NULL; bv++, j++ ); + for ( bv = a->a_vals, j = 0; !BER_BVISNULL( bv ); bv++, j++ ); memset( (*e_flags)[i], 1, j); } @@ -245,7 +245,7 @@ test_substrings_vrFilter( if( mr == NULL ) continue; bv = a->a_nvals; - for ( j = 0; bv->bv_val != NULL; bv++, j++ ) { + for ( j = 0; !BER_BVISNULL( bv ); bv++, j++ ) { int rc, match; const char *text; @@ -270,10 +270,11 @@ test_mra_vrFilter( MatchingRuleAssertion *mra, char ***e_flags ) { - int i, j; + int i, j; - for ( i=0; a != NULL; a = a->a_next, i++ ) { - struct berval *bv, assertedValue; + for ( i = 0; a != NULL; a = a->a_next, i++ ) { + struct berval *bv, assertedValue; + int normalize_attribute = 0; if ( mra->ma_desc ) { if ( !is_ad_subtype( a->a_desc, mra->ma_desc ) ) { @@ -294,23 +295,47 @@ test_mra_vrFilter( SLAP_MR_EXT|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX, &mra->ma_value, &assertedValue, &text, op->o_tmpmemctx ); - if( rc != LDAP_SUCCESS ) continue; + if ( rc != LDAP_SUCCESS ) continue; } /* check match */ - if (mra->ma_rule == a->a_desc->ad_type->sat_equality) { + if ( mra->ma_rule == a->a_desc->ad_type->sat_equality ) { bv = a->a_nvals; + } else { bv = a->a_vals; + normalize_attribute = 1; } - for ( j = 0; bv->bv_val != NULL; bv++, j++ ) { - int rc, match; - const char *text; + for ( j = 0; !BER_BVISNULL( bv ); bv++, j++ ) { + int rc, match; + const char *text; + struct berval nbv = BER_BVNULL; + + if ( normalize_attribute && mra->ma_rule->smr_normalize ) { + /* see comment in filterentry.c */ + if ( mra->ma_rule->smr_normalize( + SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX, + mra->ma_rule->smr_syntax, + mra->ma_rule, + bv, &nbv, op->o_tmpmemctx ) != LDAP_SUCCESS ) + { + /* FIXME: stop processing? */ + continue; + } + + } else { + nbv = *bv; + } rc = value_match( &match, a->a_desc, mra->ma_rule, 0, - bv, &assertedValue, &text ); - if( rc != LDAP_SUCCESS ) return rc; + &nbv, &assertedValue, &text ); + + if ( nbv.bv_val != bv->bv_val ) { + op->o_tmpfree( nbv.bv_val, op->o_tmpmemctx ); + } + + if ( rc != LDAP_SUCCESS ) return rc; if ( match == 0 ) { (*e_flags)[i][j] = 1; -- 2.39.5