]> git.sur5r.net Git - openldap/commitdiff
Attribute Aliasing : equality matching support
authorSang Seok Lim <slim@openldap.org>
Tue, 15 Feb 2005 05:24:48 +0000 (05:24 +0000)
committerSang Seok Lim <slim@openldap.org>
Tue, 15 Feb 2005 05:24:48 +0000 (05:24 +0000)
servers/slapd/ava.c
servers/slapd/back-bdb/filterindex.c
servers/slapd/component.c
servers/slapd/filterentry.c
servers/slapd/slap.h

index 14112134cf0fa29c979504a3592c092ac1bab6e1..d0df3d7c263547e18036666bcf53ecd57060b575 100644 (file)
@@ -33,6 +33,9 @@
 
 #include "slap.h"
 
+#ifdef LDAP_COMP_MATCH
+#include "component.h"
+#endif
 
 void
 ava_free(
@@ -56,6 +59,9 @@ get_ava(
        ber_tag_t rtag;
        struct berval type, value;
        AttributeAssertion *aa;
+#ifdef LDAP_COMP_MATCH
+       AttributeAliasing* a_alias = NULL;
+#endif
 
        rtag = ber_scanf( ber, "{mm}", &type, &value );
 
@@ -68,6 +74,9 @@ get_ava(
        aa = op->o_tmpalloc( sizeof( AttributeAssertion ), op->o_tmpmemctx );
        aa->aa_desc = NULL;
        aa->aa_value.bv_val = NULL;
+#ifdef LDAP_COMP_MATCH
+       aa->aa_cf = NULL;
+#endif
 
        rc = slap_bv2ad( &type, &aa->aa_desc, text );
 
@@ -89,6 +98,19 @@ get_ava(
                return rc;
        }
 
+#ifdef LDAP_COMP_MATCH
+       if( is_aliased_attribute ) {
+               a_alias = is_aliased_attribute ( aa->aa_desc );
+               if ( a_alias ) {
+                       rc = get_aliased_filter_aa ( op, aa, a_alias, text );
+                       if( rc != LDAP_SUCCESS ) {
+                               Debug( LDAP_DEBUG_FILTER,
+                                               "get_ava:Invalid Attribute Aliasing\n", 0, 0, 0 );
+                               return rc;
+                       }
+               }
+       }
+#endif
        *ava = aa;
        return LDAP_SUCCESS;
 }
index d6fa3c32a6971dba2196020d774ef53ab5aa4948..4d9cb47f1223be7d292a9952953601db96575081 100644 (file)
@@ -21,6 +21,9 @@
 
 #include "back-bdb.h"
 #include "idl.h"
+#ifdef LDAP_COMP_MATCH
+#include <component.h>
+#endif
 
 static int presence_candidates(
        Operation *op,
@@ -74,6 +77,15 @@ comp_candidates (
        ID *ids,
        ID *tmp,
        ID *stack);
+
+static int
+ava_comp_candidates (
+               Operation *op,
+               AttributeAssertion *ava,
+               AttributeAliasing *aa,
+               ID *ids,
+               ID *tmp,
+               ID *stack);
 #endif
 
 int
@@ -85,6 +97,9 @@ bdb_filter_candidates(
        ID *stack )
 {
        int rc = 0;
+#ifdef LDAP_COMP_MATCH
+       AttributeAliasing *aa;
+#endif
        Debug( LDAP_DEBUG_FILTER, "=> bdb_filter_candidates\n", 0, 0, 0 );
 
        switch ( f->f_choice ) {
@@ -114,7 +129,15 @@ bdb_filter_candidates(
 
        case LDAP_FILTER_EQUALITY:
                Debug( LDAP_DEBUG_FILTER, "\tEQUALITY\n", 0, 0, 0 );
-               rc = equality_candidates( op, f->f_ava, ids, tmp );
+#ifdef LDAP_COMP_MATCH
+               if ( is_aliased_attribute && ( aa = is_aliased_attribute ( f->f_ava->aa_desc ) ) ) {
+                       rc = ava_comp_candidates ( op, f->f_ava, aa, ids, tmp, stack );
+               }
+               else
+#endif
+               {
+                       rc = equality_candidates( op, f->f_ava, ids, tmp );
+               }
                break;
 
        case LDAP_FILTER_APPROX:
@@ -361,6 +384,29 @@ comp_equality_candidates (
         return( rc );
 }
 
+static int
+ava_comp_candidates (
+       Operation *op,
+       AttributeAssertion *ava,
+       AttributeAliasing *aa,
+       ID *ids,
+       ID *tmp,
+       ID *stack )
+{
+       MatchingRuleAssertion mra;
+       
+       mra.ma_rule = ava->aa_desc->ad_type->sat_equality;
+       if ( !mra.ma_rule ) {
+               struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
+               BDB_IDL_ALL( bdb, ids );
+               return 0;
+       }
+       mra.ma_desc = aa->aa_aliased_ad;
+       mra.ma_rule = ava->aa_desc->ad_type->sat_equality;
+       
+       return comp_candidates ( op, &mra, ava->aa_cf, ids, tmp, stack );
+}
+
 static int
 comp_candidates (
        Operation *op,
index 7d74c191117517165366d6db370c2b0367f62629..bb66c4cee7bc23a1f230db690e5f664bf5a3c3bd 100644 (file)
@@ -298,6 +298,26 @@ dup_comp_filter (
        return( rc );
 }
 
+int
+get_aliased_filter_aa ( Operation* op, AttributeAssertion* a_assert, AttributeAliasing* aa, const char** text )
+{
+       int rc;
+       struct berval assert_bv;
+       ComponentAssertion* ca;
+
+       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,
@@ -1369,4 +1389,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
index 005c6f7aa44ae4553e6e99961893000052118b98..fe8a9f66f8e217b6ea7e9377c76f8e251415864d 100644 (file)
 #include <ac/socket.h>
 #include <ac/string.h>
 
-
 #include "slap.h"
 
+#ifdef LDAP_COMP_MATCH
+#include "component.h"
+#endif
+
 static int     test_filter_and( Operation *op, Entry *e, Filter *flist );
 static int     test_filter_or( Operation *op, Entry *e, Filter *flist );
 static int     test_substrings_filter( Operation *op, Entry *e, Filter *f);
@@ -500,6 +503,10 @@ test_ava_filter(
 {
        int rc;
        Attribute       *a;
+#ifdef LDAP_COMP_MATCH
+       int i, num_attr_vals;
+       AttributeAliasing *a_alias = NULL;
+#endif
 
        if ( !access_allowed( op, e,
                ava->aa_desc, &ava->aa_value, ACL_SEARCH, NULL ) )
@@ -565,6 +572,17 @@ test_ava_filter(
 
        rc = LDAP_COMPARE_FALSE;
 
+#ifdef LDAP_COMP_MATCH
+       if ( is_aliased_attribute && ava->aa_cf )
+       {
+               a_alias = is_aliased_attribute ( ava->aa_desc );
+               if ( a_alias )
+                       ava->aa_desc = a_alias->aa_aliased_ad;
+               else
+                       ava->aa_cf = NULL;
+       }
+#endif
+
        for(a = attrs_find( e->e_attrs, ava->aa_desc );
                a != NULL;
                a = attrs_find( a->a_next, ava->aa_desc ) )
@@ -604,12 +622,76 @@ test_ava_filter(
                        continue;
                }
 
+#ifdef LDAP_COMP_MATCH
+               if ( nibble_mem_allocator && ava->aa_cf && !a->a_comp_data ) {
+                       /* Component Matching */
+                       for ( num_attr_vals = 0; a->a_vals[num_attr_vals].bv_val != NULL; num_attr_vals++ );
+                       if ( num_attr_vals <= 0 )/* no attribute value */
+                               return LDAP_INAPPROPRIATE_MATCHING;
+                       num_attr_vals++;/* for NULL termination */
+
+                       /* following malloced will be freed by comp_tree_free () */
+                       a->a_comp_data = malloc( sizeof( ComponentData ) + sizeof( ComponentSyntaxInfo* )*num_attr_vals );
+
+                       if ( !a->a_comp_data ) {
+                               return LDAP_NO_MEMORY;
+                       }
+
+                       a->a_comp_data->cd_tree = (ComponentSyntaxInfo**)((char*)a->a_comp_data + sizeof(ComponentData));
+                       i = num_attr_vals;
+                       for ( ; i ; i-- ) {
+                               a->a_comp_data->cd_tree[ i-1 ] = (ComponentSyntaxInfo*)NULL;
+                       }
+
+                       a->a_comp_data->cd_mem_op = nibble_mem_allocator ( 1024*10*(num_attr_vals-1), 1024 );
+                       if ( a->a_comp_data->cd_mem_op == NULL ) {
+                               fprintf(stderr,"nibble mem allocation error\n");
+                               free ( a->a_comp_data );
+                               a->a_comp_data = NULL;
+                               return LDAP_OPERATIONS_ERROR;
+                       }
+               }
+
+               i = 0;
+#endif
+
                for ( bv = a->a_nvals; !BER_BVISNULL( bv ); bv++ ) {
                        int ret, match;
                        const char *text;
 
-                       ret = value_match( &match, a->a_desc, mr, 0,
-                               bv, &ava->aa_value, &text );
+#ifdef LDAP_COMP_MATCH
+                       if( attr_converter && ava->aa_cf && a->a_comp_data ) {
+                               /* Check if decoded component trees are already linked */
+                               struct berval cf_bv = { 20, "componentFilterMatch" };
+                               MatchingRule* cf_mr = mr_bvfind( &cf_bv );
+                               MatchingRuleAssertion mra;
+                               mra.ma_cf = ava->aa_cf;
+
+                               if ( a->a_comp_data->cd_tree[i] == NULL )
+                                       a->a_comp_data->cd_tree[i] = attr_converter (a, a->a_desc->ad_type->sat_syntax, (a->a_vals + i));
+                               /* decoding error */
+                               if ( !a->a_comp_data->cd_tree[i] ) {
+                                       free_ComponentData ( a );
+                                       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 );
+                               if ( ret == LDAP_INAPPROPRIATE_MATCHING ) {
+                                       /* cached component tree is broken, just remove it */
+                                       free_ComponentData ( a );
+                                       return ret;
+                               }
+                               if ( a_alias )
+                                       ava->aa_desc = a_alias->aa_aliasing_ad;
+                       }
+                       else 
+#endif
+                       {
+
+                               ret = value_match( &match, a->a_desc, mr, 0,
+                                       bv, &ava->aa_value, &text );
+                       }
 
                        if( ret != LDAP_SUCCESS ) {
                                rc = ret;
@@ -633,6 +715,11 @@ test_ava_filter(
                }
        }
 
+#ifdef LDAP_COMP_MATCH
+       if ( a_alias )
+               ava->aa_desc = a_alias->aa_aliasing_ad;
+#endif
+
        return rc;
 }
 
index 7e79c0a28c2a5676b676ea282748a46eb0d7e962..568cdd2334f4f7cbccbca6fbcec59291fc67a094 100644 (file)
@@ -903,6 +903,9 @@ struct slap_internal_schema {
 typedef struct slap_attr_assertion {
        AttributeDescription    *aa_desc;
        struct berval aa_value;
+#ifdef LDAP_COMP_MATCH
+       struct slap_component_filter *aa_cf;/* for attribute aliasing */
+#endif
 } AttributeAssertion;
 
 typedef struct slap_ss_assertion {