]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/component.c
declare oc_bvfind_undef()
[openldap] / servers / slapd / component.c
index 9e006e21982d2a5e4f0cdd173175b6a3abbf8f22..9b76edfa1b1db5dfb622f6d9059c06a9fd5b0020 100644 (file)
 #include <ac/string.h>
 #include <ac/socket.h>
 
-#include "ldap_pvt.h"
 #include "lutil.h"
 #include <ldap.h>
 #include "slap.h"
 
 #ifdef LDAP_COMP_MATCH
 
-#include "asn.h"
+#include "component.h"
+
+/*
+ * This three function pointers are initialized
+ * when a component module is loaded
+ */
+alloc_nibble_func* nibble_mem_allocator = NULL;
+free_nibble_func* nibble_mem_free = NULL;
+convert_attr_to_comp_func* attr_converter = NULL ;
+convert_assert_to_comp_func* assert_converter = NULL ;
+free_component_func* component_destructor = NULL ;
+test_component_func* test_one_component = NULL;
+test_component_func* test_all_components = NULL;
+
+#define OID_ALL_COMP_MATCH "1.2.36.79672281.1.13.6"
+#define OID_COMP_FILTER_MATCH "1.2.36.79672281.1.13.2"
+#define MAX_LDAP_STR_LEN 128
 
 static int
 peek_componentId_type( ComponentAssertionValue* cav );
@@ -42,10 +57,21 @@ static int
 parse_comp_filter( Operation* op, ComponentAssertionValue* cav,
                                ComponentFilter** filt, const char** text );
 
+static void
+free_comp_filter( ComponentFilter* f );
+
 static int
-test_comp_filter_attr( Operation *op, Attribute        *a, struct berval *bv,
+test_comp_filter( Syntax *syn, Attribute       *a, struct berval *bv,
                        ComponentFilter *f );
 
+int
+componentCertificateValidate(
+       Syntax *syntax,
+       struct berval *val )
+{
+       return LDAP_SUCCESS;
+}
+
 int
 componentFilterValidate(
        Syntax *syntax,
@@ -54,6 +80,14 @@ componentFilterValidate(
        return LDAP_SUCCESS;
 }
 
+int
+allComponentsValidate(
+       Syntax *syntax,
+       struct berval *val )
+{
+       return LDAP_SUCCESS;
+}
+
 int
 componentFilterMatch ( 
        int *matchp, 
@@ -63,46 +97,90 @@ componentFilterMatch (
        struct berval *value, 
        void *assertedValue )
 {
-       /* FIXME: to be implemented */
+       Attribute *a = (Attribute*)value;
+       MatchingRuleAssertion * ma = (MatchingRuleAssertion*)assertedValue;
+
+       int rc;
+
+       if ( !(mr && mr->smr_usage & SLAP_MR_COMPONENT) || !ma->ma_cf )
+               return LDAP_INAPPROPRIATE_MATCHING;
+               
+       rc = test_comp_filter( syntax, a, a->a_vals, ma->ma_cf );
+
+       if ( rc == LDAP_COMPARE_TRUE ) {
+               *matchp = 0;
+               return LDAP_SUCCESS;
+       }
+       else if ( rc == LDAP_COMPARE_FALSE ) {
+               *matchp = 1;
+               return LDAP_SUCCESS;
+       }
+       else {
+               return LDAP_INAPPROPRIATE_MATCHING;
+       }
+       
+}
+int
+directoryComponentsMatch( 
+       int *matchp, 
+       slap_mask_t flags, 
+       Syntax *syntax, 
+       MatchingRule *mr,
+       struct berval *value, 
+       void *assertedValue )
+{
+       /* Only for Registeration */
        *matchp = 0;
        return LDAP_SUCCESS;
 }
 
+int
+allComponentsMatch( 
+       int *matchp, 
+       slap_mask_t flags, 
+       Syntax *syntax, 
+       MatchingRule *mr,
+       struct berval *value, 
+       void *assertedValue )
+{
+       /* Only for Registeration */
+       *matchp = 0;
+       return LDAP_SUCCESS;
+}
 
 static int
 slapd_ber2cav( struct berval* bv, ComponentAssertionValue* cav)
 {
        int len;
 
-       len = ldap_pvt_filter_value_unescape( bv->bv_val );
        cav->cav_ptr = cav->cav_buf = bv->bv_val;
-       cav->cav_end = bv->bv_val + len;
+       cav->cav_end = bv->bv_val + bv->bv_len;
+
+       return LDAP_SUCCESS;
 }
 
 int
-get_comp_filter ( Operation* op, struct berval* bv, ComponentFilter** filt,
-                                const char **text )
+get_comp_filter( Operation* op, struct berval* bv, ComponentFilter** filt,
+                const char **text )
 {
        ComponentAssertionValue cav;
-       int len, rc;
-#ifdef NEW_LOGGING
-       LDAP_LOG( FILTER, ENTRY, "get_comp_filter\n", 0, 0, 0 );
-#else
+       int rc;
+
        Debug( LDAP_DEBUG_FILTER, "get_comp_filter\n", 0, 0, 0 );
-#endif
-       slapd_ber2cav(bv, &cav);
+       if ( (rc = slapd_ber2cav(bv, &cav) ) != LDAP_SUCCESS ) {
+               return rc;
+       }
        rc = parse_comp_filter( op, &cav, filt, text );
        bv->bv_val = cav.cav_ptr;
+
        return rc;
 }
 
 static void
 eat_whsp( ComponentAssertionValue* cav )
 {
-       int count = 0;
-       for ( ; ; ) {
-               if ( cav->cav_ptr[count++] == ' ' ) cav->cav_ptr++;
-               else break;
+       for ( ; ( *cav->cav_ptr == ' ' ) && ( cav->cav_ptr < cav->cav_end ) ; ) {
+               cav->cav_ptr++;
        }
 }
 
@@ -152,14 +230,8 @@ get_comp_filter_list( Operation *op, ComponentAssertionValue *cav,
        ComponentFilter **new;
        int             err;
        ber_tag_t       tag;
-       ber_len_t       len;
-       char            *last;
 
-#ifdef NEW_LOGGING
-       LDAP_LOG( FILTER, ENTRY, "get_comp_filter_list\n", 0, 0, 0 );
-#else
        Debug( LDAP_DEBUG_FILTER, "get_comp_filter_list\n", 0, 0, 0 );
-#endif
        new = f;
        for ( tag = comp_first_element( cav ); tag != LDAP_COMP_FILTER_UNDEFINED;
                tag = comp_next_element( cav ) )
@@ -171,7 +243,6 @@ get_comp_filter_list( Operation *op, ComponentAssertionValue *cav,
        }
        *new = NULL;
 
-
        return( LDAP_SUCCESS );
 }
 
@@ -185,11 +256,7 @@ get_componentId( Operation *op, ComponentAssertionValue* cav,
 
        type = peek_componentId_type( cav );
 
-#ifdef NEW_LOGGING
-       LDAP_LOG( FILTER, ENTRY, "get_compId [%d]\n", type, 0, 0 );
-#else
        Debug( LDAP_DEBUG_FILTER, "get_compId [%d]\n", type, 0, 0 );
-#endif
        len = 0;
        _cid.ci_type = type;
        _cid.ci_next = NULL;
@@ -218,19 +285,22 @@ get_componentId( Operation *op, ComponentAssertionValue* cav,
                cav->cav_ptr++;
                break;
        case LDAP_COMPREF_CONTENT :
-               /* FIXEME: yet to be implemented */
+               _cid.ci_val.ci_content = 1;
+               cav->cav_ptr += strlen("content");
                break;
        case LDAP_COMPREF_SELECT :
-               /* FIXEME: yet to be implemented */
+               if ( cav->cav_ptr[len] != '(' )
+                       return LDAP_COMPREF_UNDEFINED;
+               for( ;cav->cav_ptr[len] != ' ' && cav->cav_ptr[len] != '\0' &&
+                     cav->cav_ptr[len] != '.' && cav->cav_ptr[len] != '\"' &&
+                     cav->cav_ptr[len] != ')' ; len++ );
+               _cid.ci_val.ci_select_value.bv_val = cav->cav_ptr + 1;
+               _cid.ci_val.ci_select_value.bv_len = len - 1 ;
+               cav->cav_ptr += len;
                break;
        case LDAP_COMPREF_ALL :
                _cid.ci_val.ci_all = '*';
                cav->cav_ptr++;
-#ifdef NEW_LOGGING
-       LDAP_LOG( FILTER, ENTRY, "get_compId : ALL\n", 0, 0, 0 );
-#else
-       Debug( LDAP_DEBUG_FILTER, "get_compId : ALL\n", 0, 0, 0 );
-#endif
                break;
        default :
                return LDAP_COMPREF_UNDEFINED;
@@ -251,6 +321,8 @@ peek_componentId_type( ComponentAssertionValue* cav )
                return LDAP_COMPREF_SELECT;
        else if ( cav->cav_ptr[0] == '*' )
                return LDAP_COMPREF_ALL;
+       else if ( strncmp(cav->cav_ptr,"all",3) == 0 )
+               return LDAP_COMPREF_ALL;
        else if ( cav->cav_ptr[0] == '0' )
                return LDAP_COMPREF_COUNT;
        else if ( cav->cav_ptr[0] > '0' && cav->cav_ptr[0] <= '9' )
@@ -258,7 +330,9 @@ peek_componentId_type( ComponentAssertionValue* cav )
        else if ( (cav->cav_end - cav->cav_ptr) >= 7 &&
                strncmp(cav->cav_ptr,"content",7) == 0 )
                return LDAP_COMPREF_CONTENT;
-       else if ( cav->cav_ptr[0] >= 'a' && cav->cav_ptr[0] <= 'z' )
+       else if ( (cav->cav_ptr[0] >= 'a' && cav->cav_ptr[0] <= 'z') ||
+                       (cav->cav_ptr[0] >= 'A' && cav->cav_ptr[0] <= 'Z') )
+                
                return LDAP_COMPREF_IDENTIFIER;
        else
                return LDAP_COMPREF_UNDEFINED;
@@ -285,11 +359,15 @@ get_component_reference( Operation *op, ComponentAssertionValue* cav,
        ComponentId** cr_list;
 
        eat_whsp( cav );
+
+       if ( ( rc = strip_cav_str( cav,"\"") ) != LDAP_SUCCESS )
+               return rc;
+
        ca_comp_ref =
                op->o_tmpalloc( sizeof( ComponentReference ), op->o_tmpmemctx );
 
        cr_list = &ca_comp_ref->cr_list;
-       strip_cav_str( cav, "\"");
+
        for ( type = peek_componentId_type( cav ) ; type != LDAP_COMPREF_UNDEFINED
                ; type = comp_next_id( cav ), count++ ) {
                rc = get_componentId( op, cav, cr_list, text );
@@ -297,9 +375,15 @@ get_component_reference( Operation *op, ComponentAssertionValue* cav,
                        if ( count == 0 ) ca_comp_ref->cr_curr = ca_comp_ref->cr_list;
                        cr_list = &(*cr_list)->ci_next;
                }
+               else if ( rc == LDAP_COMPREF_UNDEFINED )
+                       return rc;
        }
        ca_comp_ref->cr_len = count;
-       strip_cav_str( cav, "\"");
+
+       if ( ( rc = strip_cav_str( cav,"\"") ) != LDAP_SUCCESS ) {
+               op->o_tmpfree( ca_comp_ref , op->o_tmpmemctx );
+               return rc;
+       }
 
        if ( rc == LDAP_SUCCESS ) {     
                *cr = ca_comp_ref;
@@ -314,22 +398,17 @@ static int
 get_ca_use_default( Operation *op, ComponentAssertionValue* cav,
                int* ca_use_def, const char**  text )
 {
-       int rc;
-       if ( peek_cav_str( cav, "useDefaultValues" ) == LDAP_SUCCESS ) {
-               strip_cav_str( cav, "useDefaultValues" );
-               if ( peek_cav_str( cav, "TRUE" ) == LDAP_SUCCESS ) {
-                       strip_cav_str( cav, "TRUE" );
-                       *ca_use_def = 1;
-               }
-               else if ( peek_cav_str( cav, "FALSE" ) == LDAP_SUCCESS ) {
-                       strip_cav_str( cav, "FALSE" );
-                       *ca_use_def = 0;
-               }
-               else
-                       return LDAP_INVALID_SYNTAX;
-       }
-       else /* If not defined, default value is TRUE */
+       strip_cav_str( cav, "useDefaultValues" );
+       if ( peek_cav_str( cav, "TRUE" ) == LDAP_SUCCESS ) {
+               strip_cav_str( cav, "TRUE" );
                *ca_use_def = 1;
+       } else if ( peek_cav_str( cav, "FALSE" ) == LDAP_SUCCESS ) {
+               strip_cav_str( cav, "FALSE" );
+               *ca_use_def = 0;
+       } else {
+               return LDAP_INVALID_SYNTAX;
+       }
+
        return LDAP_SUCCESS;
 }
 
@@ -338,7 +417,6 @@ get_matching_rule( Operation *op, ComponentAssertionValue* cav,
                MatchingRule** mr, const char**  text )
 {
        int count = 0;
-       char temp;
        struct berval rule_text = { 0L, NULL };
 
        eat_whsp( cav );
@@ -359,11 +437,7 @@ get_matching_rule( Operation *op, ComponentAssertionValue* cav,
        rule_text.bv_val = cav->cav_ptr;
        *mr = mr_bvfind( &rule_text );
        cav->cav_ptr += count;
-#ifdef NEW_LOGGING
-       LDAP_LOG( FILTER, ENTRY,  "get_matching_rule: %s\n", (*mr)->smr_mrule.mr_oid, 0, 0 );
-#else
        Debug( LDAP_DEBUG_FILTER, "get_matching_rule: %s\n", (*mr)->smr_mrule.mr_oid, 0, 0 );
-#endif
        if ( *mr == NULL ) {
                *text = "component matching rule not recognized";
                return LDAP_INAPPROPRIATE_MATCHING;
@@ -371,10 +445,10 @@ get_matching_rule( Operation *op, ComponentAssertionValue* cav,
        return LDAP_SUCCESS;
 }
 
-static void
+static int
 get_GSER_value( ComponentAssertionValue* cav, struct berval* bv )
 {
-       int count;
+       int count, sequent_dquote, unclosed_brace, succeed;
 
        eat_whsp( cav );
        /*
@@ -389,39 +463,66 @@ get_GSER_value( ComponentAssertionValue* cav, struct berval* bv )
         *      INTEGER, BOOLEAN, NULL,ENUMERATE, etc
         */
 
+       succeed = 0;
        if ( cav->cav_ptr[0] == '"' ) {
-               for( count = 0 ; ; count++ ) {
-                       if ( cav->cav_ptr[count] == '\0' ||
-                       ( cav->cav_ptr[count] == '"' && cav->cav_ptr[count-1] != '"') )
+               for( count = 1, sequent_dquote = 0 ; ; count++ ) {
+                       /* In order to find escaped double quote */
+                       if ( cav->cav_ptr[count] == '"' ) sequent_dquote++;
+                       else sequent_dquote = 0;
+
+                       if ( cav->cav_ptr[count] == '\0' || (cav->cav_ptr+count) > cav->cav_end ) {
+                               break;
+                       }
+                               
+                       if ( ( cav->cav_ptr[count] == '"' && cav->cav_ptr[count-1] != '"') ||
+                       ( sequent_dquote > 2 && (sequent_dquote%2) == 1 ) ) {
+                               succeed = 1;
                                break;
+                       }
                }
        }
        else if ( cav->cav_ptr[0] == '\'' ) {
-               for( count = 0 ; ; count++ ) {
-                       if ( cav->cav_ptr[count] == '\0' ||
-                       (cav->cav_ptr[count] == '\'' && cav->cav_ptr[count] == 'B')||
-                       (cav->cav_ptr[count] == '\'' && cav->cav_ptr[count] == 'H') )
+               for( count = 1 ; ; count++ ) {
+                       if ( cav->cav_ptr[count] == '\0' || (cav->cav_ptr+count) > cav->cav_end ) {
                                break;
+                       }
+                       if ((cav->cav_ptr[count-1] == '\'' && cav->cav_ptr[count] == 'B')||
+                       (cav->cav_ptr[count-1] == '\'' && cav->cav_ptr[count] == 'H') ) {
+                               succeed = 1;
+                               break;
+                       }
                }
                                
        }
        else if ( cav->cav_ptr[0] == '{' ) {
-               for( count = 0 ; ; count++ ) {
-                       if ( cav->cav_ptr[count] == '\0' ||
-                       (cav->cav_ptr[count] == '}' && cav->cav_ptr[count] == ' ') )
+               for( count = 1, unclosed_brace = 1 ; ; count++ ) {
+                       if ( cav->cav_ptr[count] == '{' ) unclosed_brace++;
+                       if ( cav->cav_ptr[count] == '}' ) unclosed_brace--;
+
+                       if ( cav->cav_ptr[count] == '\0' || (cav->cav_ptr+count) > cav->cav_end )
+                               break;
+                       if ( unclosed_brace == 0 ) {
+                               succeed = 1;
                                break;
+                       }
                }
        }
        else {
-               for( count = 0 ; ; count++ ) {
-                       if ( cav->cav_ptr[count] == ' ')
+               succeed = 1;
+               /*Find  following white space where the value is ended*/
+               for( count = 1 ; ; count++ ) {
+                       if ( cav->cav_ptr[count] == '\0' || cav->cav_ptr[count] == ' ' || (cav->cav_ptr+count) > cav->cav_end ) {
                                break;
+                       }
                }
        }
 
+       if ( !succeed ) return LDAP_FILTER_ERROR;
+
        bv->bv_val = cav->cav_ptr;
-       bv->bv_len = count;
+       bv->bv_len = count ;
        cav->cav_ptr += count;
+       return LDAP_SUCCESS;
 }
 
 static int
@@ -429,13 +530,12 @@ get_matching_value( Operation *op, ComponentAssertion* ca,
                        ComponentAssertionValue* cav, struct berval* bv,
                        const char**  text )
 {
-       int count;
-       ber_tag_t tag;
-
        if ( !(ca->ca_ma_rule->smr_usage & (SLAP_MR_COMPONENT)) ) {
-               get_GSER_value( cav, bv );
-       }
-       else {
+               if ( get_GSER_value( cav, bv ) != LDAP_SUCCESS ) {
+                       return LDAP_FILTER_ERROR;
+               }
+
+       } else {
                /* embeded componentFilterMatch Description */
                bv->bv_val = cav->cav_ptr;
                bv->bv_len = cav_cur_len( cav );
@@ -512,13 +612,12 @@ get_item( Operation *op, ComponentAssertionValue* cav, ComponentAssertion** ca,
        int rc;
        ComponentAssertion* _ca;
 
-#ifdef NEW_LOGGING
-       LDAP_LOG( FILTER, ENTRY,  "get_item: %s\n", 0, 0, 0 );
-#else
        Debug( LDAP_DEBUG_FILTER, "get_item: %s\n", 0, 0, 0 );
-#endif
        _ca = op->o_tmpalloc( sizeof( ComponentAssertion ), op->o_tmpmemctx );
 
+       _ca->ca_comp_data.cd_tree = NULL;
+       _ca->ca_comp_data.cd_mem_op = NULL;
+
        rc = peek_cav_str( cav, "component" );
        if ( rc == LDAP_SUCCESS ) {
                strip_cav_str( cav, "component" );
@@ -530,7 +629,9 @@ get_item( Operation *op, ComponentAssertionValue* cav, ComponentAssertion** ca,
                }
        }
 
-       strip_cav_str( cav,",");
+       if ( ( rc = strip_cav_str( cav,",") ) != LDAP_SUCCESS )
+               return rc;
+
        rc = peek_cav_str( cav, "useDefaultValues");
        if ( rc == LDAP_SUCCESS ) {
                rc = get_ca_use_default( op, cav, &_ca->ca_use_def, text );
@@ -539,7 +640,10 @@ get_item( Operation *op, ComponentAssertionValue* cav, ComponentAssertion** ca,
                        op->o_tmpfree( _ca, op->o_tmpmemctx );
                        return rc;
                }
+               if ( ( rc = strip_cav_str( cav,",") ) != LDAP_SUCCESS )
+                       return rc;
        }
+       else _ca->ca_use_def = 1;
 
        if ( !( strip_cav_str( cav, "rule" ) == LDAP_SUCCESS &&
                get_matching_rule( op, cav , &_ca->ca_ma_rule, text ) == LDAP_SUCCESS )) {
@@ -548,7 +652,8 @@ get_item( Operation *op, ComponentAssertionValue* cav, ComponentAssertion** ca,
                return rc;
        }
        
-       strip_cav_str( cav,",");
+       if ( ( rc = strip_cav_str( cav,",") ) != LDAP_SUCCESS )
+               return rc;
        if ( !(strip_cav_str( cav, "value" ) == LDAP_SUCCESS &&
                get_matching_value( op, _ca, cav, &_ca->ca_ma_value,text ) == LDAP_SUCCESS )) {
                rc = LDAP_INVALID_SYNTAX;
@@ -557,7 +662,7 @@ get_item( Operation *op, ComponentAssertionValue* cav, ComponentAssertion** ca,
        }
 
        /* componentFilterMatch contains componentFilterMatch in it */
-       if ( _ca->ca_ma_rule->smr_usage & (SLAP_MR_COMPONENT) ) {
+       if ( strcmp(_ca->ca_ma_rule->smr_mrule.mr_oid, OID_COMP_FILTER_MATCH ) == 0) {
                struct berval bv;
                bv.bv_val = cav->cav_ptr;
                bv.bv_len = cav_cur_len( cav );
@@ -589,7 +694,6 @@ parse_comp_filter( Operation* op, ComponentAssertionValue* cav,
         */
 
        ber_tag_t       tag;
-       ber_len_t       len;
        int             err;
        ComponentFilter f;
        /* TAG : item, and, or, not in RFC 2254 */
@@ -610,11 +714,7 @@ parse_comp_filter( Operation* op, ComponentAssertionValue* cav,
 
        switch ( f.cf_choice ) {
        case LDAP_COMP_FILTER_AND:
-#ifdef NEW_LOGGING
-       LDAP_LOG( FILTER, ENTRY,  "LDAP_COMP_FILTER_AND\n", 0, 0, 0 );
-#else
        Debug( LDAP_DEBUG_FILTER, "LDAP_COMP_FILTER_AND\n", 0, 0, 0 );
-#endif
                err = get_comp_filter_list( op, cav, &f.cf_and, text );
                if ( err != LDAP_SUCCESS ) {
                        break;
@@ -626,11 +726,7 @@ parse_comp_filter( Operation* op, ComponentAssertionValue* cav,
                break;
 
        case LDAP_COMP_FILTER_OR:
-#ifdef NEW_LOGGING
-       LDAP_LOG( FILTER, ENTRY,  "LDAP_COMP_FILTER_OR\n", 0, 0, 0 );
-#else
        Debug( LDAP_DEBUG_FILTER, "LDAP_COMP_FILTER_OR\n", 0, 0, 0 );
-#endif
                err = get_comp_filter_list( op, cav, &f.cf_or, text );
                if ( err != LDAP_SUCCESS ) {
                        break;
@@ -643,11 +739,7 @@ parse_comp_filter( Operation* op, ComponentAssertionValue* cav,
                break;
 
        case LDAP_COMP_FILTER_NOT:
-#ifdef NEW_LOGGING
-       LDAP_LOG( FILTER, ENTRY,  "LDAP_COMP_FILTER_NOT\n", 0, 0, 0 );
-#else
        Debug( LDAP_DEBUG_FILTER, "LDAP_COMP_FILTER_NOT\n", 0, 0, 0 );
-#endif
                err = parse_comp_filter( op, cav, &f.cf_not, text );
                if ( err != LDAP_SUCCESS ) {
                        break;
@@ -674,11 +766,7 @@ parse_comp_filter( Operation* op, ComponentAssertionValue* cav,
                break;
 
        case LDAP_COMP_FILTER_ITEM:
-#ifdef NEW_LOGGING
-       LDAP_LOG( FILTER, ENTRY,  "LDAP_COMP_FILTER_ITEM\n", 0, 0, 0 );
-#else
        Debug( LDAP_DEBUG_FILTER, "LDAP_COMP_FILTER_ITEM\n", 0, 0, 0 );
-#endif
                err = get_item( op, cav, &f.cf_ca, text );
                if ( err != LDAP_SUCCESS ) {
                        break;
@@ -713,7 +801,7 @@ parse_comp_filter( Operation* op, ComponentAssertionValue* cav,
 
 static int
 test_comp_filter_and(
-       Operation *op,
+       Syntax *syn,
        Attribute *a,
        struct berval  *bv,
        ComponentFilter *flist )
@@ -722,7 +810,7 @@ test_comp_filter_and(
        int rtn = LDAP_COMPARE_TRUE;
 
        for ( f = flist ; f != NULL; f = f->cf_next ) {
-               int rc = test_comp_filter_attr( op, a, bv, f );
+               int rc = test_comp_filter( syn, a, bv, f );
                if ( rc == LDAP_COMPARE_FALSE ) {
                        rtn = rc;
                        break;
@@ -738,7 +826,7 @@ test_comp_filter_and(
 
 static int
 test_comp_filter_or(
-       Operation *op,
+       Syntax *syn,
        Attribute *a,
        struct berval     *bv,
        ComponentFilter *flist )
@@ -747,7 +835,7 @@ test_comp_filter_or(
        int rtn = LDAP_COMPARE_TRUE;
 
        for ( f = flist ; f != NULL; f = f->cf_next ) {
-               int rc = test_comp_filter_attr( op, a, bv, f );
+               int rc = test_comp_filter( syn, a, bv, f );
                if ( rc == LDAP_COMPARE_TRUE ) {
                        rtn = rc;
                        break;
@@ -761,144 +849,131 @@ test_comp_filter_or(
        return rtn;
 }
 
-/*
- * Convert attribute value to C internal data structure
- * This function has an associated ASN.1 type
- * bv must contain the value for the type( type name is T1 )
- * This function is linked to ssyn_attr2comp
- */
+int
+csi_value_match( MatchingRule *mr, struct berval* bv_attr,
+               struct berval* bv_assert )
+{
+       int rc;
+       int match;
+
+       assert( mr != NULL );
+       assert( !(mr->smr_usage & SLAP_MR_COMPONENT) );
+
+       if( !mr->smr_match ) {
+               return LDAP_INAPPROPRIATE_MATCHING;
+       }
+
+       rc = (mr->smr_match)( &match, 0, NULL /*ad->ad_type->sat_syntax*/,
+                               mr, bv_attr, bv_assert );
+       if ( rc == LDAP_SUCCESS )
+               return match? LDAP_COMPARE_FALSE:LDAP_COMPARE_TRUE;
+       else
+               return rc;
+}
 
 /*
  * return codes : LDAP_COMPARE_TRUE, LDAP_COMPARE_FALSE
  */
 static int
 test_comp_filter_item(
-       Operation       *op,
+       Syntax *syn,
        Attribute       *a,
        struct berval   *bv,
        ComponentAssertion *ca )
 {
-       int rc = LDAP_COMPARE_TRUE;
-       int len;
-       ComponentSyntaxInfo* csi_attr, *csi_assert;
+       int rc, len;
+       ComponentSyntaxInfo* csi_attr, *csi_assert=NULL;
+       void *attr_nm, *assert_nm;
 
-       if ( (ca->ca_ma_rule->smr_usage & SLAP_MR_COMPONENT) && ca->ca_cf ) {
+       if ( strcmp(ca->ca_ma_rule->smr_mrule.mr_oid,
+               OID_COMP_FILTER_MATCH ) == 0 && ca->ca_cf ) {
                /* componentFilterMatch inside of componentFilterMatch */
-               rc = test_comp_filter_attr( op, a, bv, ca->ca_cf );
+               rc = test_comp_filter( syn, a, bv, ca->ca_cf );
                return rc;
        }
 
-       assert( !(ca->ca_ma_rule->smr_usage & SLAP_MR_COMPONENT) );
-       /* FIXME : Return ALWAYS true */
-       return LDAP_COMPARE_TRUE;
-}
+       /* load attribute containg components */
+       if ( !a->a_comp_data && attr_converter && nibble_mem_allocator ) {
+               a->a_comp_data = malloc( sizeof( ComponentData ) );
+               /* Memory chunk pre-allocation for decoders */
+               a->a_comp_data->cd_mem_op = (void*) nibble_mem_allocator ( 1024, 128 );
+               a->a_comp_data->cd_tree = attr_converter (a, syn, bv);
+       }
 
-/*
- * If matched, LDAP_COMPARE_TRUE is returned
- */
-int
-test_comp_filter_entry(
-    Operation  *op,
-    Entry      *e,
-    MatchingRuleAssertion *mra )
-{
-       Attribute *a;
-       void    *memctx;
+       if ( a->a_comp_data->cd_tree == NULL ) {
+               free ( a->a_comp_data );
+               return LDAP_PROTOCOL_ERROR;
+       }
 
-       mra->cf->cf_ca->ca_mra = mra;
+       /* Memory for storing will-be-extracted attribute values */
+       attr_nm = nibble_mem_allocator ( 256, 64 );
+       if ( !attr_nm )return LDAP_PROTOCOL_ERROR;
+       /* component reference initialization */
+       ca->ca_comp_ref->cr_curr = ca->ca_comp_ref->cr_list;
+       /* load component containg the referenced component */
+       csi_attr = (((ComponentSyntaxInfo*)a->a_comp_data->cd_tree)->csi_comp_desc->cd_extract_i)( attr_nm, ca->ca_comp_ref, a->a_comp_data->cd_tree );
+       if ( !csi_attr )
+               return LDAP_PROTOCOL_ERROR;
 
-#ifdef NEW_LOGGING
-       LDAP_LOG( FILTER, ENTRY,  "test_comp_filter_entry\n", 0, 0, 0 );
-#else
-       Debug( LDAP_DEBUG_FILTER, "test_comp_filter_entry\n", 0, 0, 0 );
-#endif
-       if ( mra->ma_desc ) {
+       /* Memory for storing component assertion values */
+       if( !ca->ca_comp_data.cd_mem_op ) {
+               assert_nm = nibble_mem_allocator ( 256, 64 );
+               if ( !assert_nm )
+                       return LDAP_PROTOCOL_ERROR;
+               ca->ca_comp_data.cd_mem_op = assert_nm;
+       }
+       else {
+               assert_nm = ca->ca_comp_data.cd_mem_op;
+       }
+       /* perform matching */
+       if ( ca->ca_comp_ref->cr_curr->ci_type == LDAP_COMPREF_ALL ) {
                /*
-                * ma_desc is available, so filtering for one attribute
-                * SEARCH permissionc can be checked directly
+                * If <all> type component referenced is used
+                * more than one component will be tested
                 */
-               if ( !access_allowed( op, e, mra->ma_desc,
-                       &mra->ma_value, ACL_SEARCH, NULL ) )
-               {
-                       return LDAP_INSUFFICIENT_ACCESS;
-               }
-               /* Find attributes that componentFilter Match can be applied to */
-               for( a=attrs_find( e->e_attrs, mra->ma_desc );
-                       a != NULL ;
-                       a = attrs_find( a->a_next, mra->ma_desc ) )
-               {
-                       struct berval *bv = a->a_vals;
-
-                       for ( ; bv->bv_val != NULL ; bv++ ) {
-                               int ret, rc;
-                               const char *text;
-                               rc = test_comp_filter_attr( op, a, bv, mra->cf );
-                               if ( rc == LDAP_COMPARE_TRUE ) return rc;
-                       }
-               }
-
+               if ( test_all_components )
+                       rc = test_all_components ( assert_nm, csi_attr, ca );
+               else
+                       rc = LDAP_PROTOCOL_ERROR;
        } else {
                /*
-                * No attribute description : test all
+                * Exactly one component is referenced
+                * Fast Path for matching for this case
                 */
-                for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
-                        struct berval   *bv, value;
-                        const char      *text = NULL;
-                        int             rc;
-                                                                                  
-                        /* check if matching is appropriate */
-                        if ( !mr_usable_with_at( mra->ma_rule, a->a_desc->ad_type
-)) {
-                                continue;
-                        }
-                                                                                  
-                        /* check search access */
-                        if ( !access_allowed( op, e,
-                                a->a_desc, &value, ACL_SEARCH, NULL ) ) {
-                                continue;
-                        }
-                                                                                  
-                       bv = a->a_vals;
-
-                       for ( ; bv->bv_val != NULL ; bv++ ) {
-                               int ret, rc;
-                               const char *text;
-                               rc = test_comp_filter_attr( op, a, bv, mra->cf );
-                               if ( rc == LDAP_COMPARE_TRUE ) break;
-                       }
-                        if ( rc != LDAP_SUCCESS ) return rc;
-                }
+               if ( test_one_component )
+                       rc = test_one_component ( assert_nm, csi_attr, ca );
+               else
+                       rc = LDAP_PROTOCOL_ERROR;
        }
-
-       return LDAP_COMPARE_FALSE;
+       /* free memory used for storing extracted attribute value */
+       nibble_mem_free ( attr_nm );
+       return rc;
 }
 
 static int
-test_comp_filter_attr(
-    Operation  *op,
+test_comp_filter(
+    Syntax *syn,
     Attribute  *a,
     struct berval *bv,
     ComponentFilter *f )
 {
        int     rc;
 
-#ifdef NEW_LOGGING
-       LDAP_LOG( FILTER, ENTRY,  "test_comp_filter_attr\n", 0, 0, 0 );
-#else
-       Debug( LDAP_DEBUG_FILTER, "test_comp_filter_attr\n", 0, 0, 0 );
-#endif
+       if ( !f ) return LDAP_PROTOCOL_ERROR;
+
+       Debug( LDAP_DEBUG_FILTER, "test_comp_filter\n", 0, 0, 0 );
        switch ( f->cf_choice ) {
        case SLAPD_FILTER_COMPUTED:
                rc = f->cf_result;
                break;
        case LDAP_COMP_FILTER_AND:
-               rc = test_comp_filter_and( op, a, bv, f->cf_and );
+               rc = test_comp_filter_and( syn, a, bv, f->cf_and );
                break;
        case LDAP_COMP_FILTER_OR:
-               rc = test_comp_filter_or( op, a, bv, f->cf_or );
+               rc = test_comp_filter_or( syn, a, bv, f->cf_or );
                break;
        case LDAP_COMP_FILTER_NOT:
-               rc = test_comp_filter_attr( op, a, bv, f->cf_not );
+               rc = test_comp_filter( syn, a, bv, f->cf_not );
 
                switch ( rc ) {
                case LDAP_COMPARE_TRUE:
@@ -910,7 +985,7 @@ test_comp_filter_attr(
                }
                break;
        case LDAP_COMP_FILTER_ITEM:
-               rc = test_comp_filter_item( op, a, bv, f->cf_ca );
+               rc = test_comp_filter_item( syn, a, bv, f->cf_ca );
                break;
        default:
                rc = LDAP_PROTOCOL_ERROR;
@@ -918,4 +993,40 @@ test_comp_filter_attr(
 
        return( rc );
 }
+
+static void
+free_comp_filter_list( ComponentFilter* f )
+{
+       ComponentFilter* tmp;
+       for ( tmp = f ; tmp; tmp = tmp->cf_next );
+       {
+               free_comp_filter( tmp );
+       }
+}
+
+static void
+free_comp_filter( ComponentFilter* f )
+{
+       switch ( f->cf_choice ) {
+       case LDAP_COMP_FILTER_AND:
+       case LDAP_COMP_FILTER_OR:
+       case LDAP_COMP_FILTER_NOT:
+               free_comp_filter( f->cf_any );
+               break;
+
+       case LDAP_COMP_FILTER_ITEM:
+               if ( nibble_mem_free && f->cf_ca->ca_comp_data.cd_mem_op )
+                       nibble_mem_free( f->cf_ca->ca_comp_data.cd_mem_op );
+               break;
+
+       default:
+               break;
+       }
+}
+
+void
+component_free( ComponentFilter *f ) {
+       free_comp_filter( f );
+}
+
 #endif