]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/component.c
minor naming cleanup; improvements to DN mapping layer; major docs update
[openldap] / servers / slapd / component.c
index 6166db0c071895b6348c39b28b010981d6c6c433..2a88ae62d89540cdc181d4ed4f15985f9aa176aa 100644 (file)
@@ -2,7 +2,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 2003-2004 The OpenLDAP Foundation.
+ * Copyright 2003-2005 The OpenLDAP Foundation.
  * Portions Copyright 2004 by IBM Corporation.
  * All rights reserved.
  *
  */
 alloc_nibble_func* nibble_mem_allocator = NULL;
 free_nibble_func* nibble_mem_free = NULL;
-convert_attr_to_comp_func* attr_converter = 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_components = NULL;
 test_membership_func* is_aliased_attribute = NULL;
-
+component_encoder_func* component_encoder = NULL;
+get_component_info_func* get_component_description = 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
@@ -61,7 +62,7 @@ static void
 free_comp_filter( ComponentFilter* f );
 
 static int
-test_comp_filter( Syntax *syn, Attribute       *a, struct berval *bv,
+test_comp_filter( Syntax *syn, ComponentSyntaxInfo *a, struct berval *bv,
                        ComponentFilter *f );
 
 int
@@ -97,29 +98,61 @@ componentFilterMatch (
        struct berval *value, 
        void *assertedValue )
 {
+       struct berval* bv;
        Attribute *a = (Attribute*)value;
        MatchingRuleAssertion * ma = (MatchingRuleAssertion*)assertedValue;
+       void* assert_nm;
+       int num_attr, rc, i;
 
-       int rc;
-
-       if ( !(mr && mr->smr_usage & SLAP_MR_COMPONENT) || !ma->ma_cf )
+       if ( !mr || !ma->ma_cf )
+               return LDAP_INAPPROPRIATE_MATCHING;
+       /* Check if the component module is loaded */
+       if ( !attr_converter || !nibble_mem_allocator )
                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;
+       /* Check if decoded component trees are already linked */
+       num_attr = 0;
+       if ( !a->a_comp_data ) {
+               for ( ; a->a_vals[num_attr].bv_val != NULL; num_attr++ );
+               if ( num_attr <= 0 )/* no attribute value */
+                       return LDAP_INAPPROPRIATE_MATCHING;
+               num_attr++;
+               /* following malloced will be freed by comp_tree_free () */
+               a->a_comp_data = malloc( sizeof( ComponentData ) + sizeof( ComponentSyntaxInfo* )*num_attr );
+               if ( !a->a_comp_data )
+                       return LDAP_NO_MEMORY;
+               a->a_comp_data->cd_tree = (ComponentSyntaxInfo**)((char*)a->a_comp_data + sizeof(ComponentData));
+               a->a_comp_data->cd_tree[ num_attr - 1] = (ComponentSyntaxInfo*)NULL;
+               a->a_comp_data->cd_mem_op = nibble_mem_allocator ( 1024*16, 1024 );
        }
-       else {
-               return LDAP_INAPPROPRIATE_MATCHING;
+
+       for ( bv = a->a_vals, i = 0 ; bv->bv_val != NULL; bv++, i++ ) {
+               /* decodes current attribute into components */
+               if ( num_attr != 0 ) {
+                       a->a_comp_data->cd_tree[i] = attr_converter (a, syntax, bv);
+               }
+               /* decoding error */
+               if ( !a->a_comp_data->cd_tree[i] )
+                       return LDAP_OPERATIONS_ERROR;
+
+               rc = test_comp_filter( syntax, a->a_comp_data->cd_tree[i], bv, ma->ma_cf );
+
+               if ( rc == LDAP_COMPARE_TRUE ) {
+                       *matchp = 0;
+                       return LDAP_SUCCESS;
+               }
+               else if ( rc == LDAP_COMPARE_FALSE ) {
+                       continue;
+               }
+               else {
+                       return LDAP_INAPPROPRIATE_MATCHING;
+               }
        }
+       *matchp = 1;
+       return LDAP_SUCCESS;
        
 }
+
 int
 directoryComponentsMatch( 
        int *matchp, 
@@ -159,7 +192,7 @@ slapd_ber2cav( struct berval* bv, ComponentAssertionValue* cav )
        return LDAP_SUCCESS;
 }
 
-static ComponentReference*
+ComponentReference*
 dup_comp_ref ( Operation* op, ComponentReference* cr )
 {
        int rc, count = 0;
@@ -317,7 +350,7 @@ get_aliased_filter ( Operation* op, MatchingRuleAssertion* ma, AttributeAliasing
         * the component assertion value in assert_bv
         * Multiple values may be separated with '$'
         */
-       rc = dup_comp_filter ( op, &assert_bv, aa->aa_cf, &ma->ma_cf );
+       return dup_comp_filter ( op, &assert_bv, aa->aa_cf, &ma->ma_cf );
 }
 
 int
@@ -511,6 +544,8 @@ comp_next_id( ComponentAssertionValue* cav )
        else return LDAP_COMPREF_UNDEFINED;
 }
 
+
+
 static int
 get_component_reference( Operation *op, ComponentAssertionValue* cav,
                        ComponentReference** cr, const char** text )
@@ -519,12 +554,13 @@ get_component_reference( Operation *op, ComponentAssertionValue* cav,
        ber_int_t type;
        ComponentReference* ca_comp_ref;
        ComponentId** cr_list;
+       char* start, *end;
 
        eat_whsp( cav );
 
+       start = cav->cav_ptr;
        if ( ( rc = strip_cav_str( cav,"\"") ) != LDAP_SUCCESS )
                return rc;
-
        if ( op )
                ca_comp_ref = op->o_tmpalloc( sizeof( ComponentReference ), op->o_tmpmemctx );
        else
@@ -545,7 +581,7 @@ get_component_reference( Operation *op, ComponentAssertionValue* cav,
                        return rc;
        }
        ca_comp_ref->cr_len = count;
-
+       end = cav->cav_ptr;
        if ( ( rc = strip_cav_str( cav,"\"") ) != LDAP_SUCCESS ) {
                if ( op )
                        op->o_tmpfree( ca_comp_ref , op->o_tmpmemctx );
@@ -563,9 +599,80 @@ get_component_reference( Operation *op, ComponentAssertionValue* cav,
        else
                 free( ca_comp_ref ) ;
 
+       (*cr)->cr_string.bv_val = start;
+       (*cr)->cr_string.bv_len = end - start + 1;
+       
        return rc;
 }
 
+int
+insert_component_reference( ComponentReference *cr, ComponentReference** cr_list) {
+       if ( !cr )
+               return LDAP_PARAM_ERROR;
+       if ( !(*cr_list) ) {
+               *cr_list = cr;
+               cr->cr_next = NULL;
+       } else {
+               cr->cr_next = *cr_list;
+               *cr_list = cr;
+       }
+       return LDAP_SUCCESS;
+}
+
+/*
+ * If there is '.' in the name of a given attribute
+ * the first '.'- following characters are considered
+ * as a component reference of the attribute
+ * EX) userCertificate.toBeSigned.serialNumber
+ * attribute : userCertificate
+ * component reference : toBeSigned.serialNumber
+ */
+int
+is_component_reference( char* attr ) {
+       int i;
+       for ( i=0; attr[i] != '\0' ; i++ ) {
+               if ( attr[i] == '.' )
+                       return (1);
+       }
+       return (0);
+}
+
+int
+extract_component_reference( char* attr, ComponentReference** cr ) {
+        int i, rc;
+        char* cr_ptr;
+        int cr_len;
+        ComponentAssertionValue cav;
+       char text[1][128];
+
+        for ( i=0; attr[i] != '\0' ; i++ ) {
+                if ( attr[i] == '.' ) break;
+        }
+
+        if (attr[i] != '.' )
+                return LDAP_PARAM_ERROR;
+        else
+                attr[i] = '\0';
+        cr_ptr = attr + i + 1 ;
+        cr_len = strlen ( cr_ptr );
+        if ( cr_len <= 0 )
+                return LDAP_PARAM_ERROR;
+
+       /* enclosed between double quotes*/
+       cav.cav_ptr = cav.cav_buf = ch_malloc (cr_len+2);
+       memcpy( cav.cav_buf+1, cr_ptr, cr_len );
+       cav.cav_buf[0] = '"';
+       cav.cav_buf[cr_len+1] = '"';
+        cav.cav_end = cr_ptr + cr_len + 2;
+
+        rc = get_component_reference ( NULL, &cav, cr, (const char**)text );
+       if ( rc != LDAP_SUCCESS )
+               return rc;
+       (*cr)->cr_string.bv_val = cav.cav_buf;
+       (*cr)->cr_string.bv_len = cr_len + 2;
+
+       return LDAP_SUCCESS;
+}
 static int
 get_ca_use_default( Operation *op, ComponentAssertionValue* cav,
                int* ca_use_def, const char**  text )
@@ -701,7 +808,7 @@ get_GSER_value( ComponentAssertionValue* cav, struct berval* bv )
                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 ) {
+                       if ( cav->cav_ptr[count] == '\0' || cav->cav_ptr[count] == ' ' || cav->cav_ptr[count] == '}' || cav->cav_ptr[count] == '{' || (cav->cav_ptr+count) > cav->cav_end ) {
                                break;
                        }
                }
@@ -826,11 +933,12 @@ get_item( Operation *op, ComponentAssertionValue* cav, ComponentAssertion** ca,
                                free( _ca );
                        return LDAP_INVALID_SYNTAX;
                }
+               if ( ( rc = strip_cav_str( cav,",") ) != LDAP_SUCCESS )
+                       return rc;
+       } else {
+               _ca->ca_comp_ref = NULL;
        }
 
-       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 );
@@ -875,9 +983,9 @@ get_item( Operation *op, ComponentAssertionValue* cav, ComponentAssertion** ca,
 
                value.bv_val[value.bv_len] = '\0';
                rc = mr->smr_normalize (
-               SLAP_MR_VALUE_OF_ASSERTION_SYNTAX,
-               NULL, mr,
-               &value, &_ca->ca_ma_value, op->o_tmpmemctx );
+                       SLAP_MR_VALUE_OF_ASSERTION_SYNTAX,
+                       NULL, mr,
+                       &value, &_ca->ca_ma_value, op->o_tmpmemctx );
                if ( rc != LDAP_SUCCESS )
                        return rc;
        }
@@ -1037,7 +1145,7 @@ parse_comp_filter( Operation* op, ComponentAssertionValue* cav,
 static int
 test_comp_filter_and(
        Syntax *syn,
-       Attribute *a,
+       ComponentSyntaxInfo *a,
        struct berval  *bv,
        ComponentFilter *flist )
 {
@@ -1062,7 +1170,7 @@ test_comp_filter_and(
 static int
 test_comp_filter_or(
        Syntax *syn,
-       Attribute *a,
+       ComponentSyntaxInfo *a,
        struct berval     *bv,
        ComponentFilter *flist )
 {
@@ -1112,39 +1220,23 @@ csi_value_match( MatchingRule *mr, struct berval* bv_attr,
 static int
 test_comp_filter_item(
        Syntax *syn,
-       Attribute       *a,
+       ComponentSyntaxInfo *csi_attr,
        struct berval   *bv,
        ComponentAssertion *ca )
 {
        int rc, len;
-       ComponentSyntaxInfo* csi_attr, *csi_assert=NULL;
        void *attr_nm, *assert_nm;
 
        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( syn, a, bv, ca->ca_cf );
+               rc = test_comp_filter( syn, csi_attr, bv, ca->ca_cf );
                return rc;
        }
 
-       /* 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 ( a->a_comp_data->cd_tree == NULL ) {
-               nibble_mem_free( a->a_comp_data->cd_mem_op );
-               free ( a->a_comp_data );
-               a->a_comp_data = NULL;
-               return LDAP_PROTOCOL_ERROR;
-       }
-
        /* Memory for storing will-be-extracted attribute values */
        attr_nm = nibble_mem_allocator ( 1024*4 , 1024 );
-       if ( !attr_nm )return LDAP_PROTOCOL_ERROR;
+       if ( !attr_nm ) return LDAP_PROTOCOL_ERROR;
 
        /* Memory for storing component assertion values */
        if( !ca->ca_comp_data.cd_mem_op ) {
@@ -1160,8 +1252,9 @@ test_comp_filter_item(
        }
 
        /* component reference initialization */
-       ca->ca_comp_ref->cr_curr = ca->ca_comp_ref->cr_list;
-       rc = test_components( attr_nm, assert_nm, (ComponentSyntaxInfo*)a->a_comp_data->cd_tree, ca );
+       if ( ca->ca_comp_ref )
+               ca->ca_comp_ref->cr_curr = ca->ca_comp_ref->cr_list;
+       rc = test_components( attr_nm, assert_nm, csi_attr, ca );
 
        /* free memory used for storing extracted attribute value */
        nibble_mem_free ( attr_nm );
@@ -1171,7 +1264,7 @@ test_comp_filter_item(
 static int
 test_comp_filter(
     Syntax *syn,
-    Attribute  *a,
+    ComponentSyntaxInfo *a,
     struct berval *bv,
     ComponentFilter *f )
 {
@@ -1216,7 +1309,7 @@ static void
 free_comp_filter_list( ComponentFilter* f )
 {
        ComponentFilter* tmp;
-       for ( tmp = f ; tmp; tmp = tmp->cf_next );
+       for ( tmp = f; tmp; tmp = tmp->cf_next )
        {
                free_comp_filter( tmp );
        }
@@ -1225,6 +1318,10 @@ free_comp_filter_list( ComponentFilter* f )
 static void
 free_comp_filter( ComponentFilter* f )
 {
+       if ( !f ) {
+               Debug( LDAP_DEBUG_FILTER, "free_comp_filter:Invalid filter so failed to release memory\n", 0, 0, 0 );
+               return;
+       }
        switch ( f->cf_choice ) {
        case LDAP_COMP_FILTER_AND:
        case LDAP_COMP_FILTER_OR: