From e7e8ec90b61c67b8dae11e0a5f6642187e78e57c Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Sat, 26 Mar 2005 02:07:00 +0000 Subject: [PATCH] Update uniqueMemberMatch to be consistent with latest draft-ietf-ldapbis-syntaxes Add uniqueMemberMatch approximate support Add uniqueMemberMatch indexing support --- servers/slapd/filterentry.c | 45 +++++++++------- servers/slapd/schema_init.c | 101 +++++++++++++++++++++++++++++++++++- 2 files changed, 127 insertions(+), 19 deletions(-) diff --git a/servers/slapd/filterentry.c b/servers/slapd/filterentry.c index a9d8bd17a0..b201fd469d 100644 --- a/servers/slapd/filterentry.c +++ b/servers/slapd/filterentry.c @@ -186,7 +186,7 @@ static int test_mra_filter( const char *text; rc = value_match( &ret, slap_schema.si_ad_entryDN, mra->ma_rule, - 0, &e->e_nname, &mra->ma_value, &text ); + SLAP_MR_EXT, &e->e_nname, &mra->ma_value, &text ); if( rc != LDAP_SUCCESS ) return rc; @@ -264,7 +264,8 @@ static int test_mra_filter( if ( !a->a_comp_data->cd_tree[i] ) { return LDAP_OPERATIONS_ERROR; } - rc = value_match( &ret, a->a_desc, mra->ma_rule, 0, + rc = value_match( &ret, a->a_desc, mra->ma_rule, + SLAP_MR_COMPONENT, (struct berval*)a->a_comp_data->cd_tree[i++], (void*)mra, &text ); } else @@ -308,8 +309,8 @@ static int test_mra_filter( nbv = *bv; } - rc = value_match( &ret, a->a_desc, mra->ma_rule, 0, - &nbv, &mra->ma_value, &text ); + rc = value_match( &ret, a->a_desc, mra->ma_rule, + SLAP_MR_EXT, &nbv, &mra->ma_value, &text ); if ( nbv.bv_val != bv->bv_val ) { memfree( nbv.bv_val, memctx ); @@ -356,7 +357,8 @@ static int test_mra_filter( { int ret; - rc = value_match( &ret, a->a_desc, mra->ma_rule, 0, + rc = value_match( &ret, a->a_desc, mra->ma_rule, + SLAP_MR_COMPONENT, (struct berval*)a, (void*)mra, &text ); if ( rc != LDAP_SUCCESS ) break; @@ -397,8 +399,8 @@ static int test_mra_filter( nbv = *bv; } - rc = value_match( &ret, a->a_desc, mra->ma_rule, 0, - &nbv, &value, &text ); + rc = value_match( &ret, a->a_desc, mra->ma_rule, + SLAP_MR_EXT, &nbv, &value, &text ); if ( nbv.bv_val != bv->bv_val ) { memfree( nbv.bv_val, memctx ); @@ -494,7 +496,7 @@ static int test_mra_filter( } /* check match */ - rc = value_match( &ret, ad, mra->ma_rule, 0, + rc = value_match( &ret, ad, mra->ma_rule, SLAP_MR_EXT, &nbv, &value, &text ); cleanup:; @@ -588,8 +590,8 @@ test_ava_filter( mr = slap_schema.si_ad_entryDN->ad_type->sat_equality; assert( mr ); - rc = value_match( &match, slap_schema.si_ad_entryDN, mr, 0, - &e->e_nname, &ava->aa_value, &text ); + rc = value_match( &match, slap_schema.si_ad_entryDN, mr, + SLAP_MR_EXT, &e->e_nname, &ava->aa_value, &text ); if( rc != LDAP_SUCCESS ) return rc; if( match == 0 ) return LDAP_COMPARE_TRUE; @@ -613,6 +615,7 @@ test_ava_filter( a != NULL; a = attrs_find( a->a_next, ava->aa_desc ) ) { + int use; MatchingRule *mr; struct berval *bv; @@ -623,19 +626,24 @@ test_ava_filter( continue; } + use = SLAP_MR_EQUALITY; + switch ( type ) { case LDAP_FILTER_APPROX: + use = SLAP_MR_EQUALITY_APPROX; mr = a->a_desc->ad_type->sat_approx; if( mr != NULL ) break; - /* use EQUALITY matching rule if no APPROX rule */ + /* fallthru: use EQUALITY matching rule if no APPROX rule */ case LDAP_FILTER_EQUALITY: + /* use variable set above so fall thru use is not clobbered */ mr = a->a_desc->ad_type->sat_equality; break; case LDAP_FILTER_GE: case LDAP_FILTER_LE: + use = SLAP_MR_ORDERING; mr = a->a_desc->ad_type->sat_ordering; break; @@ -700,8 +708,10 @@ test_ava_filter( return LDAP_OPERATIONS_ERROR; } - ret = value_match( &match, a->a_desc, cf_mr, 0, - (struct berval*)a->a_comp_data->cd_tree[i++], (void*)&mra, &text ); + ret = value_match( &match, a->a_desc, cf_mr, + SLAP_MR_COMPONENT, + (struct berval*)a->a_comp_data->cd_tree[i++], + (void*)&mra, &text ); if ( ret == LDAP_INAPPROPRIATE_MATCHING ) { /* cached component tree is broken, just remove it */ free_ComponentData ( a ); @@ -709,12 +719,11 @@ test_ava_filter( } if ( a_alias ) ava->aa_desc = a_alias->aa_aliasing_ad; - } - else + + } else #endif { - - ret = value_match( &match, a->a_desc, mr, 0, + ret = value_match( &match, a->a_desc, mr, use, bv, &ava->aa_value, &text ); } @@ -909,7 +918,7 @@ test_substrings_filter( int ret, match; const char *text; - ret = value_match( &match, a->a_desc, mr, 0, + ret = value_match( &match, a->a_desc, mr, SLAP_MR_SUBSTR, bv, f->f_sub, &text ); if( ret != LDAP_SUCCESS ) { diff --git a/servers/slapd/schema_init.c b/servers/slapd/schema_init.c index 4f4edc6c35..90f2fb7647 100644 --- a/servers/slapd/schema_init.c +++ b/servers/slapd/schema_init.c @@ -1060,6 +1060,7 @@ uniqueMemberMatch( struct berval assertedUID = BER_BVNULL; struct berval valueDN = BER_BVNULL; struct berval valueUID = BER_BVNULL; + int approx = ((flags & SLAP_MR_EQUALITY_APPROX) == SLAP_MR_EQUALITY_APPROX); if ( !BER_BVISEMPTY( asserted ) ) { assertedUID.bv_val = strrchr( assertedDN.bv_val, '#' ); @@ -1107,11 +1108,109 @@ uniqueMemberMatch( *matchp = match; return LDAP_SUCCESS; } + + } else if ( !approx && valueUID.bv_len ) { + match = -1; + *matchp = match; + return LDAP_SUCCESS; + + } else if ( !approx && assertedUID.bv_len ) { + match = 1; + *matchp = match; + return LDAP_SUCCESS; } return dnMatch( matchp, flags, syntax, mr, &valueDN, &assertedDN ); } +static int +uniqueMemberIndexer( + slap_mask_t use, + slap_mask_t flags, + Syntax *syntax, + MatchingRule *mr, + struct berval *prefix, + BerVarray values, + BerVarray *keysp, + void *ctx ) +{ + BerVarray dnvalues; + int rc; + int i; + for( i=0; !BER_BVISNULL( &values[i] ); i++ ) { + /* just count them */ + } + assert( i > 0 ); + + dnvalues = slap_sl_malloc( sizeof( struct berval ) * (i+1), ctx ); + + for( i=0; !BER_BVISNULL( &values[i] ); i++ ) { + struct berval assertedDN = values[i]; + struct berval assertedUID = BER_BVNULL; + + if ( !BER_BVISEMPTY( &assertedDN ) ) { + assertedUID.bv_val = strrchr( assertedDN.bv_val, '#' ); + if ( !BER_BVISNULL( &assertedUID ) ) { + assertedUID.bv_val++; + assertedUID.bv_len = assertedDN.bv_len + - ( assertedUID.bv_val - assertedDN.bv_val ); + + if ( bitStringValidate( NULL, &assertedUID ) == LDAP_SUCCESS ) { + assertedDN.bv_len -= assertedUID.bv_len + 1; + + } else { + BER_BVZERO( &assertedUID ); + } + } + } + + dnvalues[i] = assertedDN; + } + BER_BVZERO( &dnvalues[i] ); + + rc = octetStringIndexer( use, flags, syntax, mr, prefix, + dnvalues, keysp, ctx ); + + slap_sl_free( dnvalues, ctx ); + return rc; +} + +static int +uniqueMemberFilter( + slap_mask_t use, + slap_mask_t flags, + Syntax *syntax, + MatchingRule *mr, + struct berval *prefix, + void * assertedValue, + BerVarray *keysp, + void *ctx ) +{ + struct berval *asserted = (struct berval *) assertedValue; + struct berval assertedDN = *asserted; + struct berval assertedUID = BER_BVNULL; + + if ( !BER_BVISEMPTY( asserted ) ) { + assertedUID.bv_val = strrchr( assertedDN.bv_val, '#' ); + if ( !BER_BVISNULL( &assertedUID ) ) { + assertedUID.bv_val++; + assertedUID.bv_len = assertedDN.bv_len + - ( assertedUID.bv_val - assertedDN.bv_val ); + + if ( bitStringValidate( NULL, &assertedUID ) == LDAP_SUCCESS ) { + assertedDN.bv_len -= assertedUID.bv_len + 1; + + } else { + BER_BVZERO( &assertedUID ); + } + } + } + + return octetStringFilter( use, flags, syntax, mr, prefix, + &assertedDN, keysp, ctx ); +} + + /* * Handling boolean syntax and matching is quite rigid. * A more flexible approach would be to allow a variety @@ -3638,7 +3737,7 @@ static slap_mrule_defs_rec mrule_defs[] = { "SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )", SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL, NULL, uniqueMemberNormalize, uniqueMemberMatch, - NULL, NULL, + uniqueMemberIndexer, uniqueMemberFilter, NULL }, {"( 2.5.13.24 NAME 'protocolInformationMatch' " -- 2.39.2