mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-01-06 10:46:21 +08:00
fix ITS#3406 - normalize attributes according to MR syntax in MRA filters
This commit is contained in:
parent
3dd2f4150b
commit
1b268479c3
@ -172,7 +172,7 @@ static int test_mra_filter(
|
|||||||
* one attribute, and SEARCH permissions can be checked
|
* one attribute, and SEARCH permissions can be checked
|
||||||
* directly.
|
* directly.
|
||||||
*/
|
*/
|
||||||
if( !access_allowed( op, e,
|
if ( !access_allowed( op, e,
|
||||||
mra->ma_desc, &mra->ma_value, ACL_SEARCH, NULL ) )
|
mra->ma_desc, &mra->ma_value, ACL_SEARCH, NULL ) )
|
||||||
{
|
{
|
||||||
return LDAP_INSUFFICIENT_ACCESS;
|
return LDAP_INSUFFICIENT_ACCESS;
|
||||||
@ -191,18 +191,20 @@ static int test_mra_filter(
|
|||||||
return LDAP_COMPARE_FALSE;
|
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 != NULL;
|
||||||
a = attrs_find( a->a_next, mra->ma_desc ) )
|
a = attrs_find( a->a_next, mra->ma_desc ) )
|
||||||
{
|
{
|
||||||
struct berval *bv;
|
struct berval *bv;
|
||||||
|
int normalize_attribute = 0;
|
||||||
|
|
||||||
#ifdef LDAP_COMP_MATCH
|
#ifdef LDAP_COMP_MATCH
|
||||||
/* Component Matching */
|
/* 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;
|
num_attr_vals = 0;
|
||||||
if ( !a->a_comp_data ) {
|
if ( !a->a_comp_data ) {
|
||||||
for ( ;
|
for ( ;
|
||||||
a->a_vals[num_attr_vals].bv_val != NULL;
|
!BER_BVISNULL( &a->a_vals[num_attr_vals] );
|
||||||
num_attr_vals++ )
|
num_attr_vals++ )
|
||||||
{
|
{
|
||||||
/* empty */;
|
/* empty */;
|
||||||
@ -231,22 +233,25 @@ static int test_mra_filter(
|
|||||||
/* If ma_rule is not the same as the attribute's
|
/* If ma_rule is not the same as the attribute's
|
||||||
* normal rule, then we can't use the a_nvals.
|
* 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;
|
bv = a->a_nvals;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
bv = a->a_vals;
|
bv = a->a_vals;
|
||||||
|
normalize_attribute = 1;
|
||||||
}
|
}
|
||||||
#ifdef LDAP_COMP_MATCH
|
#ifdef LDAP_COMP_MATCH
|
||||||
i = 0;
|
i = 0;
|
||||||
#endif
|
#endif
|
||||||
for ( ; bv->bv_val != NULL; bv++ ) {
|
for ( ; !BER_BVISNULL( bv ); bv++ ) {
|
||||||
int ret;
|
int ret;
|
||||||
int rc;
|
int rc;
|
||||||
const char *text;
|
const char *text;
|
||||||
|
|
||||||
#ifdef LDAP_COMP_MATCH
|
#ifdef LDAP_COMP_MATCH
|
||||||
if( mra->ma_cf &&
|
if ( mra->ma_cf &&
|
||||||
mra->ma_rule->smr_usage & SLAP_MR_COMPONENT ) {
|
mra->ma_rule->smr_usage & SLAP_MR_COMPONENT )
|
||||||
|
{
|
||||||
/* Check if decoded component trees are already linked */
|
/* Check if decoded component trees are already linked */
|
||||||
if ( num_attr_vals ) {
|
if ( num_attr_vals ) {
|
||||||
a->a_comp_data->cd_tree[i] = attr_converter(
|
a->a_comp_data->cd_tree[i] = attr_converter(
|
||||||
@ -262,11 +267,53 @@ static int test_mra_filter(
|
|||||||
} else
|
} else
|
||||||
#endif
|
#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,
|
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;
|
if ( ret == 0 ) return LDAP_COMPARE_TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -279,9 +326,10 @@ static int test_mra_filter(
|
|||||||
struct berval *bv, value;
|
struct berval *bv, value;
|
||||||
const char *text = NULL;
|
const char *text = NULL;
|
||||||
int rc;
|
int rc;
|
||||||
|
int normalize_attribute = 0;
|
||||||
|
|
||||||
/* check if matching is appropriate */
|
/* 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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -293,20 +341,21 @@ static int test_mra_filter(
|
|||||||
|
|
||||||
/* check search access */
|
/* check search access */
|
||||||
if ( !access_allowed( op, e,
|
if ( !access_allowed( op, e,
|
||||||
a->a_desc, &value, ACL_SEARCH, NULL ) ) {
|
a->a_desc, &value, ACL_SEARCH, NULL ) )
|
||||||
|
{
|
||||||
memfree( value.bv_val, memctx );
|
memfree( value.bv_val, memctx );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#ifdef LDAP_COMP_MATCH
|
#ifdef LDAP_COMP_MATCH
|
||||||
/* Component Matching */
|
/* Component Matching */
|
||||||
if( mra->ma_cf &&
|
if ( mra->ma_cf &&
|
||||||
mra->ma_rule->smr_usage & SLAP_MR_COMPONENT)
|
mra->ma_rule->smr_usage & SLAP_MR_COMPONENT )
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
rc = value_match( &ret, a->a_desc, mra->ma_rule, 0,
|
rc = value_match( &ret, a->a_desc, mra->ma_rule, 0,
|
||||||
(struct berval*)a, (void*)mra, &text );
|
(struct berval*)a, (void*)mra, &text );
|
||||||
if( rc != LDAP_SUCCESS ) break;
|
if ( rc != LDAP_SUCCESS ) break;
|
||||||
|
|
||||||
if ( ret == 0 ) {
|
if ( ret == 0 ) {
|
||||||
rc = LDAP_COMPARE_TRUE;
|
rc = LDAP_COMPARE_TRUE;
|
||||||
@ -317,19 +366,42 @@ static int test_mra_filter(
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* check match */
|
/* 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;
|
bv = a->a_nvals;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
bv = a->a_vals;
|
bv = a->a_vals;
|
||||||
|
normalize_attribute = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( ; bv->bv_val != NULL; bv++ ) {
|
for ( ; !BER_BVISNULL( bv ); bv++ ) {
|
||||||
int ret;
|
int ret;
|
||||||
|
struct berval nbv = BER_BVNULL;
|
||||||
rc = value_match( &ret, a->a_desc, mra->ma_rule, 0,
|
|
||||||
bv, &value, &text );
|
|
||||||
|
|
||||||
if( rc != LDAP_SUCCESS ) break;
|
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,
|
||||||
|
&nbv, &value, &text );
|
||||||
|
|
||||||
|
if ( nbv.bv_val != bv->bv_val ) {
|
||||||
|
memfree( nbv.bv_val, memctx );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( rc != LDAP_SUCCESS ) break;
|
||||||
|
|
||||||
if ( ret == 0 ) {
|
if ( ret == 0 ) {
|
||||||
rc = LDAP_COMPARE_TRUE;
|
rc = LDAP_COMPARE_TRUE;
|
||||||
@ -378,7 +450,7 @@ static int test_mra_filter(
|
|||||||
const char *text = NULL;
|
const char *text = NULL;
|
||||||
|
|
||||||
/* check if matching is appropriate */
|
/* 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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -407,7 +479,7 @@ static int test_mra_filter(
|
|||||||
|
|
||||||
if ( rc == LDAP_SUCCESS && ret == 0 ) rc = LDAP_COMPARE_TRUE;
|
if ( rc == LDAP_SUCCESS && ret == 0 ) rc = LDAP_COMPARE_TRUE;
|
||||||
|
|
||||||
if( rc != LDAP_SUCCESS ) {
|
if ( rc != LDAP_SUCCESS ) {
|
||||||
ldap_dnfree_x( dn, memctx );
|
ldap_dnfree_x( dn, memctx );
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -532,7 +604,7 @@ test_ava_filter(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( bv = a->a_nvals; bv->bv_val != NULL; bv++ ) {
|
for ( bv = a->a_nvals; !BER_BVISNULL( bv ); bv++ ) {
|
||||||
int ret, match;
|
int ret, match;
|
||||||
const char *text;
|
const char *text;
|
||||||
|
|
||||||
@ -721,7 +793,7 @@ test_substrings_filter(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( bv = a->a_nvals; bv->bv_val != NULL; bv++ ) {
|
for ( bv = a->a_nvals; !BER_BVISNULL( bv ); bv++ ) {
|
||||||
int ret, match;
|
int ret, match;
|
||||||
const char *text;
|
const char *text;
|
||||||
|
|
||||||
|
@ -171,7 +171,7 @@ test_ava_vrFilter(
|
|||||||
if( mr == NULL ) continue;
|
if( mr == NULL ) continue;
|
||||||
|
|
||||||
bv = a->a_nvals;
|
bv = a->a_nvals;
|
||||||
for ( j=0; bv->bv_val != NULL; bv++, j++ ) {
|
for ( j=0; !BER_BVISNULL( bv ); bv++, j++ ) {
|
||||||
int rc, match;
|
int rc, match;
|
||||||
const char *text;
|
const char *text;
|
||||||
|
|
||||||
@ -218,7 +218,7 @@ test_presence_vrFilter(
|
|||||||
|
|
||||||
if ( !is_ad_subtype( a->a_desc, desc ) ) continue;
|
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);
|
memset( (*e_flags)[i], 1, j);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -245,7 +245,7 @@ test_substrings_vrFilter(
|
|||||||
if( mr == NULL ) continue;
|
if( mr == NULL ) continue;
|
||||||
|
|
||||||
bv = a->a_nvals;
|
bv = a->a_nvals;
|
||||||
for ( j = 0; bv->bv_val != NULL; bv++, j++ ) {
|
for ( j = 0; !BER_BVISNULL( bv ); bv++, j++ ) {
|
||||||
int rc, match;
|
int rc, match;
|
||||||
const char *text;
|
const char *text;
|
||||||
|
|
||||||
@ -270,10 +270,11 @@ test_mra_vrFilter(
|
|||||||
MatchingRuleAssertion *mra,
|
MatchingRuleAssertion *mra,
|
||||||
char ***e_flags )
|
char ***e_flags )
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
for ( i=0; a != NULL; a = a->a_next, i++ ) {
|
for ( i = 0; a != NULL; a = a->a_next, i++ ) {
|
||||||
struct berval *bv, assertedValue;
|
struct berval *bv, assertedValue;
|
||||||
|
int normalize_attribute = 0;
|
||||||
|
|
||||||
if ( mra->ma_desc ) {
|
if ( mra->ma_desc ) {
|
||||||
if ( !is_ad_subtype( a->a_desc, 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,
|
SLAP_MR_EXT|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX,
|
||||||
&mra->ma_value, &assertedValue, &text, op->o_tmpmemctx );
|
&mra->ma_value, &assertedValue, &text, op->o_tmpmemctx );
|
||||||
|
|
||||||
if( rc != LDAP_SUCCESS ) continue;
|
if ( rc != LDAP_SUCCESS ) continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check match */
|
/* 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;
|
bv = a->a_nvals;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
bv = a->a_vals;
|
bv = a->a_vals;
|
||||||
|
normalize_attribute = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( j = 0; bv->bv_val != NULL; bv++, j++ ) {
|
for ( j = 0; !BER_BVISNULL( bv ); bv++, j++ ) {
|
||||||
int rc, match;
|
int rc, match;
|
||||||
const char *text;
|
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,
|
rc = value_match( &match, a->a_desc, mra->ma_rule, 0,
|
||||||
bv, &assertedValue, &text );
|
&nbv, &assertedValue, &text );
|
||||||
if( rc != LDAP_SUCCESS ) return rc;
|
|
||||||
|
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 ) {
|
if ( match == 0 ) {
|
||||||
(*e_flags)[i][j] = 1;
|
(*e_flags)[i][j] = 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user