]> git.sur5r.net Git - openldap/commitdiff
Update uniqueMemberMatch to be consistent with latest
authorKurt Zeilenga <kurt@openldap.org>
Sat, 26 Mar 2005 02:07:00 +0000 (02:07 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Sat, 26 Mar 2005 02:07:00 +0000 (02:07 +0000)
draft-ietf-ldapbis-syntaxes
Add uniqueMemberMatch approximate support
Add uniqueMemberMatch indexing support

servers/slapd/filterentry.c
servers/slapd/schema_init.c

index a9d8bd17a005f3621f89bf208290c6c1dab22d2c..b201fd469d23b2205beab079e27673ec1afa6d0b 100644 (file)
@@ -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 ) {
index 4f4edc6c353bda6baba27dcab305bf161180f2b6..90f2fb7647b3bd8477367838d0cf4c0777eb867f 100644 (file)
@@ -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' "