Back to index

openldap  2.4.31
component.c
Go to the documentation of this file.
00001 /* component.c -- Component Filter Match Routines */
00002 /* $OpenLDAP$ */
00003 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
00004  *
00005  * Copyright 2003-2012 The OpenLDAP Foundation.
00006  * Portions Copyright 2004 by IBM Corporation.
00007  * All rights reserved.
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted only as authorized by the OpenLDAP
00011  * Public License.
00012  *
00013  * A copy of this license is available in the file LICENSE in the
00014  * top-level directory of the distribution or, alternatively, at
00015  * <http://www.OpenLDAP.org/license.html>.
00016  */
00017 
00018 #include "portable.h"
00019 
00020 #include <ac/string.h>
00021 #include <ac/socket.h>
00022 
00023 #include "lutil.h"
00024 #include <ldap.h>
00025 #include "slap.h"
00026 
00027 #ifdef LDAP_COMP_MATCH
00028 
00029 #include "component.h"
00030 
00031 /*
00032  * Following function pointers are initialized
00033  * when a component module is loaded
00034  */
00035 alloc_nibble_func* nibble_mem_allocator = NULL;
00036 free_nibble_func* nibble_mem_free = NULL;
00037 convert_attr_to_comp_func* attr_converter = NULL;
00038 convert_assert_to_comp_func* assert_converter = NULL ;
00039 free_component_func* component_destructor = NULL ;
00040 test_component_func* test_components = NULL;
00041 test_membership_func* is_aliased_attribute = NULL;
00042 component_encoder_func* component_encoder = NULL;
00043 get_component_info_func* get_component_description = NULL;
00044 #define OID_ALL_COMP_MATCH "1.2.36.79672281.1.13.6"
00045 #define OID_COMP_FILTER_MATCH "1.2.36.79672281.1.13.2"
00046 #define MAX_LDAP_STR_LEN 128
00047 
00048 static int
00049 peek_componentId_type( ComponentAssertionValue* cav );
00050 
00051 static int
00052 strip_cav_str( ComponentAssertionValue* cav, char* str);
00053 
00054 static int
00055 peek_cav_str( ComponentAssertionValue* cav, char* str );
00056 
00057 static int
00058 parse_comp_filter( Operation* op, ComponentAssertionValue* cav,
00059                             ComponentFilter** filt, const char** text );
00060 
00061 static void
00062 free_comp_filter( ComponentFilter* f );
00063 
00064 static int
00065 test_comp_filter( Syntax *syn, ComponentSyntaxInfo *a, ComponentFilter *f );
00066 
00067 int
00068 componentCertificateValidate(
00069        Syntax *syntax,
00070        struct berval *val )
00071 {
00072        return LDAP_SUCCESS;
00073 }
00074 
00075 int
00076 componentFilterValidate(
00077        Syntax *syntax,
00078        struct berval *val )
00079 {
00080        return LDAP_SUCCESS;
00081 }
00082 
00083 int
00084 allComponentsValidate(
00085        Syntax *syntax,
00086        struct berval *val )
00087 {
00088        return LDAP_SUCCESS;
00089 }
00090 
00091 int
00092 componentFilterMatch ( 
00093        int *matchp, 
00094        slap_mask_t flags, 
00095        Syntax *syntax, 
00096        MatchingRule *mr,
00097        struct berval *value, 
00098        void *assertedValue )
00099 {
00100        ComponentSyntaxInfo *csi_attr = (ComponentSyntaxInfo*)value;
00101        MatchingRuleAssertion * ma = (MatchingRuleAssertion*)assertedValue;
00102        int rc;
00103 
00104        if ( !mr || !ma->ma_cf ) return LDAP_INAPPROPRIATE_MATCHING;
00105 
00106        /* Check if the component module is loaded */
00107        if ( !attr_converter || !nibble_mem_allocator ) {
00108               return LDAP_OTHER;
00109        }
00110 
00111        rc = test_comp_filter( syntax, csi_attr, ma->ma_cf );
00112 
00113        if ( rc == LDAP_COMPARE_TRUE ) {
00114               *matchp = 0;
00115               return LDAP_SUCCESS;
00116        }
00117        else if ( rc == LDAP_COMPARE_FALSE ) {
00118               *matchp = 1;
00119               return LDAP_SUCCESS;
00120        }
00121        else {
00122               return LDAP_INAPPROPRIATE_MATCHING;
00123        }
00124 }
00125 
00126 int
00127 directoryComponentsMatch( 
00128        int *matchp, 
00129        slap_mask_t flags, 
00130        Syntax *syntax, 
00131        MatchingRule *mr,
00132        struct berval *value, 
00133        void *assertedValue )
00134 {
00135        /* Only for registration */
00136        *matchp = 0;
00137        return LDAP_SUCCESS;
00138 }
00139 
00140 int
00141 allComponentsMatch( 
00142        int *matchp, 
00143        slap_mask_t flags, 
00144        Syntax *syntax, 
00145        MatchingRule *mr,
00146        struct berval *value, 
00147        void *assertedValue )
00148 {
00149        /* Only for registration */
00150        *matchp = 0;
00151        return LDAP_SUCCESS;
00152 }
00153 
00154 static int
00155 slapd_ber2cav( struct berval* bv, ComponentAssertionValue* cav )
00156 {
00157        cav->cav_ptr = cav->cav_buf = bv->bv_val;
00158        cav->cav_end = bv->bv_val + bv->bv_len;
00159 
00160        return LDAP_SUCCESS;
00161 }
00162 
00163 ComponentReference*
00164 dup_comp_ref ( Operation* op, ComponentReference* cr )
00165 {
00166        ComponentReference* dup_cr;
00167        ComponentId* ci_curr;
00168        ComponentId** ci_temp;
00169 
00170        dup_cr = op->o_tmpalloc( sizeof( ComponentReference ), op->o_tmpmemctx );
00171 
00172        dup_cr->cr_len = cr->cr_len;
00173        dup_cr->cr_string = cr->cr_string;
00174 
00175        ci_temp = &dup_cr->cr_list;
00176        ci_curr = cr->cr_list;
00177 
00178        for ( ; ci_curr != NULL ;
00179               ci_curr = ci_curr->ci_next, ci_temp = &(*ci_temp)->ci_next )
00180        {
00181               *ci_temp = op->o_tmpalloc( sizeof( ComponentId ), op->o_tmpmemctx );
00182               if ( !*ci_temp ) return NULL;
00183               **ci_temp = *ci_curr;
00184        }
00185 
00186        dup_cr->cr_curr = dup_cr->cr_list;
00187 
00188        return dup_cr;
00189 }
00190 
00191 static int
00192 dup_comp_filter_list (
00193        Operation *op,
00194        struct berval *bv,
00195        ComponentFilter* in_f,
00196        ComponentFilter** out_f )
00197 {
00198        ComponentFilter **new, *f;
00199        int           rc;
00200 
00201        new = out_f;
00202        for ( f = in_f; f != NULL; f = f->cf_next ) {
00203               rc = dup_comp_filter( op, bv, f, new );
00204               if ( rc != LDAP_SUCCESS ) {
00205                      return rc;
00206               }
00207               new = &(*new)->cf_next;
00208        }
00209        return LDAP_SUCCESS;
00210 }
00211 
00212 int
00213 get_len_of_next_assert_value ( struct berval* bv, char separator )
00214 {
00215        ber_len_t i = 0;
00216        while (1) {
00217               if ( (bv->bv_val[ i ] == separator) || ( i >= bv->bv_len) )
00218                      break;
00219               i++;
00220        }
00221        bv->bv_val += (i + 1);
00222        bv->bv_len -= (i + 1);
00223        return i;
00224 }
00225 
00226 int
00227 dup_comp_filter_item (
00228        Operation *op,
00229        struct berval* assert_bv,
00230        ComponentAssertion* in_ca,
00231        ComponentAssertion** out_ca )
00232 {
00233        int len;
00234 
00235        if ( !in_ca->ca_comp_ref ) return SLAPD_DISCONNECT;
00236 
00237        *out_ca = op->o_tmpalloc( sizeof( ComponentAssertion ), op->o_tmpmemctx );
00238        if ( !(*out_ca) ) return LDAP_NO_MEMORY;
00239 
00240        (*out_ca)->ca_comp_data.cd_tree = NULL;
00241        (*out_ca)->ca_comp_data.cd_mem_op = NULL;
00242 
00243        (*out_ca)->ca_comp_ref = dup_comp_ref ( op, in_ca->ca_comp_ref );
00244        (*out_ca)->ca_use_def = 0;
00245        (*out_ca)->ca_ma_rule = in_ca->ca_ma_rule;
00246 
00247        (*out_ca)->ca_ma_value.bv_val = assert_bv->bv_val;
00248        len = get_len_of_next_assert_value ( assert_bv, '$' );
00249        if ( len <= 0 ) return SLAPD_DISCONNECT;
00250        (*out_ca)->ca_ma_value.bv_len = len;
00251        
00252        return LDAP_SUCCESS;
00253 }
00254 
00255 int
00256 dup_comp_filter (
00257        Operation* op,
00258        struct berval *bv,
00259        ComponentFilter *in_f,
00260        ComponentFilter **out_f )
00261 {
00262        int    rc;
00263        ComponentFilter dup_f = {0};
00264 
00265        if ( !in_f ) return LDAP_PROTOCOL_ERROR;
00266 
00267        switch ( in_f->cf_choice ) {
00268        case LDAP_COMP_FILTER_AND:
00269               rc = dup_comp_filter_list( op, bv, in_f->cf_and, &dup_f.cf_and);
00270               dup_f.cf_choice = LDAP_COMP_FILTER_AND;
00271               break;
00272        case LDAP_COMP_FILTER_OR:
00273               rc = dup_comp_filter_list( op, bv, in_f->cf_or, &dup_f.cf_or);
00274               dup_f.cf_choice = LDAP_COMP_FILTER_OR;
00275               break;
00276        case LDAP_COMP_FILTER_NOT:
00277               rc = dup_comp_filter( op, bv, in_f->cf_not, &dup_f.cf_not);
00278               dup_f.cf_choice = LDAP_COMP_FILTER_NOT;
00279               break;
00280        case LDAP_COMP_FILTER_ITEM:
00281               rc = dup_comp_filter_item( op, bv, in_f->cf_ca ,&dup_f.cf_ca );
00282               dup_f.cf_choice = LDAP_COMP_FILTER_ITEM;
00283               break;
00284        default:
00285               rc = LDAP_PROTOCOL_ERROR;
00286        }
00287 
00288        if ( rc == LDAP_SUCCESS ) {
00289               *out_f = op->o_tmpalloc( sizeof(dup_f), op->o_tmpmemctx );
00290               **out_f = dup_f;
00291        }
00292 
00293        return( rc );
00294 }
00295 
00296 int
00297 get_aliased_filter_aa ( Operation* op, AttributeAssertion* a_assert, AttributeAliasing* aa, const char** text )
00298 {
00299        struct berval assert_bv;
00300 
00301        Debug( LDAP_DEBUG_FILTER, "get_aliased_filter\n", 0, 0, 0 );
00302 
00303        if ( !aa->aa_cf  )
00304               return LDAP_PROTOCOL_ERROR;
00305 
00306        assert_bv = a_assert->aa_value;
00307        /*
00308         * Duplicate aa->aa_cf to ma->ma_cf by replacing the
00309         * the component assertion value in assert_bv
00310         * Multiple values may be separated with '$'
00311         */
00312        return dup_comp_filter ( op, &assert_bv, aa->aa_cf, &a_assert->aa_cf );
00313 }
00314 
00315 int
00316 get_aliased_filter( Operation* op,
00317        MatchingRuleAssertion* ma, AttributeAliasing* aa,
00318        const char** text )
00319 {
00320        struct berval assert_bv;
00321 
00322        Debug( LDAP_DEBUG_FILTER, "get_aliased_filter\n", 0, 0, 0 );
00323 
00324        if ( !aa->aa_cf  ) return LDAP_PROTOCOL_ERROR;
00325 
00326        assert_bv = ma->ma_value;
00327        /* Attribute Description is replaced with aliased one */
00328        ma->ma_desc = aa->aa_aliased_ad;
00329        ma->ma_rule = aa->aa_mr;
00330        /*
00331         * Duplicate aa->aa_cf to ma->ma_cf by replacing the
00332         * the component assertion value in assert_bv
00333         * Multiple values may be separated with '$'
00334         */
00335        return dup_comp_filter ( op, &assert_bv, aa->aa_cf, &ma->ma_cf );
00336 }
00337 
00338 int
00339 get_comp_filter( Operation* op, struct berval* bv,
00340        ComponentFilter** filt, const char **text )
00341 {
00342        ComponentAssertionValue cav;
00343        int rc;
00344 
00345        Debug( LDAP_DEBUG_FILTER, "get_comp_filter\n", 0, 0, 0 );
00346        if ( (rc = slapd_ber2cav(bv, &cav) ) != LDAP_SUCCESS ) {
00347               return rc;
00348        }
00349        rc = parse_comp_filter( op, &cav, filt, text );
00350        bv->bv_val = cav.cav_ptr;
00351 
00352        return rc;
00353 }
00354 
00355 static void
00356 eat_whsp( ComponentAssertionValue* cav )
00357 {
00358        for ( ; ( *cav->cav_ptr == ' ' ) && ( cav->cav_ptr < cav->cav_end ) ; ) {
00359               cav->cav_ptr++;
00360        }
00361 }
00362 
00363 static int
00364 cav_cur_len( ComponentAssertionValue* cav )
00365 {
00366        return cav->cav_end - cav->cav_ptr;
00367 }
00368 
00369 static ber_tag_t
00370 comp_first_element( ComponentAssertionValue* cav )
00371 {
00372        eat_whsp( cav );
00373        if ( cav_cur_len( cav ) >= 8 && strncmp( cav->cav_ptr, "item", 4 ) == 0 ) {
00374               return LDAP_COMP_FILTER_ITEM;
00375 
00376        } else if ( cav_cur_len( cav ) >= 7 &&
00377               strncmp( cav->cav_ptr, "and", 3 ) == 0 )
00378        {
00379               return LDAP_COMP_FILTER_AND;
00380 
00381        } else if ( cav_cur_len( cav ) >= 6 &&
00382               strncmp( cav->cav_ptr, "or" , 2 ) == 0 )
00383        {
00384               return LDAP_COMP_FILTER_OR;
00385 
00386        } else if ( cav_cur_len( cav ) >= 7 &&
00387               strncmp( cav->cav_ptr, "not", 3 ) == 0 )
00388        {
00389               return LDAP_COMP_FILTER_NOT;
00390 
00391        } else {
00392               return LDAP_COMP_FILTER_UNDEFINED;
00393        }
00394 }
00395 
00396 static ber_tag_t
00397 comp_next_element( ComponentAssertionValue* cav )
00398 {
00399        eat_whsp( cav );
00400        if ( *(cav->cav_ptr) == ',' ) {
00401               /* move pointer to the next CA */
00402               cav->cav_ptr++;
00403               return comp_first_element( cav );
00404        }
00405        else return LDAP_COMP_FILTER_UNDEFINED;
00406 }
00407 
00408 static int
00409 get_comp_filter_list( Operation *op, ComponentAssertionValue *cav,
00410        ComponentFilter** f, const char** text )
00411 {
00412        ComponentFilter **new;
00413        int           err;
00414        ber_tag_t     tag;
00415 
00416        Debug( LDAP_DEBUG_FILTER, "get_comp_filter_list\n", 0, 0, 0 );
00417        new = f;
00418        for ( tag = comp_first_element( cav );
00419               tag != LDAP_COMP_FILTER_UNDEFINED;
00420               tag = comp_next_element( cav ) )
00421        {
00422               err = parse_comp_filter( op, cav, new, text );
00423               if ( err != LDAP_SUCCESS ) return ( err );
00424               new = &(*new)->cf_next;
00425        }
00426        *new = NULL;
00427 
00428        return( LDAP_SUCCESS );
00429 }
00430 
00431 static int
00432 get_componentId( Operation *op, ComponentAssertionValue* cav,
00433        ComponentId ** cid, const char** text )
00434 {
00435        ber_tag_t type;
00436        ComponentId _cid;
00437        int len;
00438 
00439        type = peek_componentId_type( cav );
00440 
00441        Debug( LDAP_DEBUG_FILTER, "get_compId [%lu]\n",
00442               (unsigned long) type, 0, 0 );
00443        len = 0;
00444        _cid.ci_type = type;
00445        _cid.ci_next = NULL;
00446        switch ( type ) {
00447        case LDAP_COMPREF_IDENTIFIER :
00448               _cid.ci_val.ci_identifier.bv_val = cav->cav_ptr;
00449               for( ;cav->cav_ptr[len] != ' ' && cav->cav_ptr[len] != '\0' &&
00450                      cav->cav_ptr[len] != '.' && cav->cav_ptr[len] != '\"' ; len++ );
00451               _cid.ci_val.ci_identifier.bv_len = len;
00452               cav->cav_ptr += len;
00453               break;
00454        case LDAP_COMPREF_FROM_BEGINNING :
00455               for( ;cav->cav_ptr[len] != ' ' && cav->cav_ptr[len] != '\0' &&
00456                      cav->cav_ptr[len] != '.' && cav->cav_ptr[len] != '\"' ; len++ );
00457               _cid.ci_val.ci_from_beginning = strtol( cav->cav_ptr, NULL, 0 );
00458               cav->cav_ptr += len;
00459               break;
00460        case LDAP_COMPREF_FROM_END :
00461               for( ;cav->cav_ptr[len] != ' ' && cav->cav_ptr[len] != '\0' &&
00462                      cav->cav_ptr[len] != '.' && cav->cav_ptr[len] != '\"' ; len++ );
00463               _cid.ci_val.ci_from_end = strtol( cav->cav_ptr, NULL, 0 );
00464               cav->cav_ptr += len;
00465               break;
00466        case LDAP_COMPREF_COUNT :
00467               _cid.ci_val.ci_count = 0;
00468               cav->cav_ptr++;
00469               break;
00470        case LDAP_COMPREF_CONTENT :
00471               _cid.ci_val.ci_content = 1;
00472               cav->cav_ptr += strlen("content");
00473               break;
00474        case LDAP_COMPREF_SELECT :
00475               if ( cav->cav_ptr[len] != '(' ) return LDAP_COMPREF_UNDEFINED;
00476               for( ;cav->cav_ptr[len] != ' ' && cav->cav_ptr[len] != '\0' &&
00477                     cav->cav_ptr[len] != '\"' && cav->cav_ptr[len] != ')'
00478                      ; len++ );
00479               _cid.ci_val.ci_select_value.bv_val = cav->cav_ptr + 1;
00480               _cid.ci_val.ci_select_value.bv_len = len - 1 ;
00481               cav->cav_ptr += len + 1;
00482               break;
00483        case LDAP_COMPREF_ALL :
00484               _cid.ci_val.ci_all = '*';
00485               cav->cav_ptr++;
00486               break;
00487        default :
00488               return LDAP_COMPREF_UNDEFINED;
00489        }
00490 
00491        if ( op ) {
00492               *cid = op->o_tmpalloc( sizeof( ComponentId ), op->o_tmpmemctx );
00493        } else {
00494               *cid = SLAP_MALLOC( sizeof( ComponentId ) );
00495        }
00496        if (*cid == NULL) {
00497               return LDAP_NO_MEMORY;
00498        }
00499        **cid = _cid;
00500        return LDAP_SUCCESS;
00501 }
00502 
00503 static int
00504 peek_componentId_type( ComponentAssertionValue* cav )
00505 {
00506        eat_whsp( cav );
00507 
00508        if ( cav->cav_ptr[0] == '-' ) {
00509               return LDAP_COMPREF_FROM_END;
00510 
00511        } else if ( cav->cav_ptr[0] == '(' ) {
00512               return LDAP_COMPREF_SELECT;
00513 
00514        } else if ( cav->cav_ptr[0] == '*' ) {
00515               return LDAP_COMPREF_ALL;
00516 
00517        } else if ( cav->cav_ptr[0] == '0' ) {
00518               return LDAP_COMPREF_COUNT;
00519 
00520        } else if ( cav->cav_ptr[0] > '0' && cav->cav_ptr[0] <= '9' ) {
00521               return LDAP_COMPREF_FROM_BEGINNING;
00522 
00523        } else if ( (cav->cav_end - cav->cav_ptr) >= 7 &&
00524               strncmp(cav->cav_ptr,"content",7) == 0 )
00525        {
00526               return LDAP_COMPREF_CONTENT;
00527        } else if ( (cav->cav_ptr[0] >= 'a' && cav->cav_ptr[0] <= 'z') ||
00528                      (cav->cav_ptr[0] >= 'A' && cav->cav_ptr[0] <= 'Z') )
00529        {
00530               return LDAP_COMPREF_IDENTIFIER;
00531        }
00532 
00533        return LDAP_COMPREF_UNDEFINED;
00534 }
00535 
00536 static ber_tag_t
00537 comp_next_id( ComponentAssertionValue* cav )
00538 {
00539        if ( *(cav->cav_ptr) == '.' ) {
00540               cav->cav_ptr++;
00541               return LDAP_COMPREF_DEFINED;
00542        }
00543 
00544        return LDAP_COMPREF_UNDEFINED;
00545 }
00546 
00547 
00548 
00549 static int
00550 get_component_reference(
00551        Operation *op,
00552        ComponentAssertionValue* cav,
00553        ComponentReference** cr,
00554        const char** text )
00555 {
00556        int rc, count = 0;
00557        ber_int_t type;
00558        ComponentReference* ca_comp_ref;
00559        ComponentId** cr_list;
00560        char* start, *end;
00561 
00562        eat_whsp( cav );
00563 
00564        start = cav->cav_ptr;
00565        if ( ( rc = strip_cav_str( cav,"\"") ) != LDAP_SUCCESS ) return rc;
00566        if ( op ) {
00567               ca_comp_ref = op->o_tmpalloc( sizeof( ComponentReference ),
00568                      op->o_tmpmemctx );
00569        } else {
00570               ca_comp_ref = SLAP_MALLOC( sizeof( ComponentReference ) );
00571        }
00572 
00573        if ( !ca_comp_ref ) return LDAP_NO_MEMORY;
00574 
00575        cr_list = &ca_comp_ref->cr_list;
00576 
00577        for ( type = peek_componentId_type( cav ) ; type != LDAP_COMPREF_UNDEFINED
00578               ; type = comp_next_id( cav ), count++ )
00579        {
00580               rc = get_componentId( op, cav, cr_list, text );
00581               if ( rc == LDAP_SUCCESS ) {
00582                      if ( count == 0 ) ca_comp_ref->cr_curr = ca_comp_ref->cr_list;
00583                      cr_list = &(*cr_list)->ci_next;
00584 
00585               } else if ( rc == LDAP_COMPREF_UNDEFINED ) {
00586                      if ( op ) {
00587                             op->o_tmpfree( ca_comp_ref , op->o_tmpmemctx );
00588                      } else {
00589                             free( ca_comp_ref );
00590                      }
00591                      return rc;
00592               }
00593        }
00594        ca_comp_ref->cr_len = count;
00595        end = cav->cav_ptr;
00596        if ( ( rc = strip_cav_str( cav,"\"") ) != LDAP_SUCCESS ) {
00597               if ( op ) {
00598                      op->o_tmpfree( ca_comp_ref , op->o_tmpmemctx );
00599               } else {
00600                      free( ca_comp_ref );
00601               }
00602               return rc;
00603        }
00604 
00605        *cr = ca_comp_ref;
00606        **cr = *ca_comp_ref; 
00607 
00608        (*cr)->cr_string.bv_val = start;
00609        (*cr)->cr_string.bv_len = end - start + 1;
00610        
00611        return rc;
00612 }
00613 
00614 int
00615 insert_component_reference(
00616        ComponentReference *cr,
00617        ComponentReference** cr_list)
00618 {
00619        if ( !cr ) return LDAP_PARAM_ERROR;
00620 
00621        if ( !(*cr_list) ) {
00622               *cr_list = cr;
00623               cr->cr_next = NULL;
00624        } else {
00625               cr->cr_next = *cr_list;
00626               *cr_list = cr;
00627        }
00628        return LDAP_SUCCESS;
00629 }
00630 
00631 /*
00632  * If there is '.' in the name of a given attribute
00633  * the first '.'- following characters are considered
00634  * as a component reference of the attribute
00635  * EX) userCertificate.toBeSigned.serialNumber
00636  * attribute : userCertificate
00637  * component reference : toBeSigned.serialNumber
00638  */
00639 int
00640 is_component_reference( char* attr ) {
00641        int i;
00642        for ( i=0; attr[i] != '\0' ; i++ ) {
00643               if ( attr[i] == '.' ) return (1);
00644        }
00645        return (0);
00646 }
00647 
00648 int
00649 extract_component_reference(
00650        char* attr,
00651        ComponentReference** cr )
00652 {
00653        int i, rc;
00654        char* cr_ptr;
00655        int cr_len;
00656        ComponentAssertionValue cav;
00657        char text[1][128];
00658 
00659        for ( i=0; attr[i] != '\0' ; i++ ) {
00660               if ( attr[i] == '.' ) break;
00661        }
00662 
00663        if (attr[i] != '.' ) return LDAP_PARAM_ERROR;
00664        attr[i] = '\0';
00665 
00666        cr_ptr = attr + i + 1 ;
00667        cr_len = strlen ( cr_ptr );
00668        if ( cr_len <= 0 ) return LDAP_PARAM_ERROR;
00669 
00670        /* enclosed between double quotes*/
00671        cav.cav_ptr = cav.cav_buf = ch_malloc (cr_len+2);
00672        memcpy( cav.cav_buf+1, cr_ptr, cr_len );
00673        cav.cav_buf[0] = '"';
00674        cav.cav_buf[cr_len+1] = '"';
00675        cav.cav_end = cr_ptr + cr_len + 2;
00676 
00677        rc = get_component_reference ( NULL, &cav, cr, (const char**)text );
00678        if ( rc != LDAP_SUCCESS ) return rc;
00679        (*cr)->cr_string.bv_val = cav.cav_buf;
00680        (*cr)->cr_string.bv_len = cr_len + 2;
00681 
00682        return LDAP_SUCCESS;
00683 }
00684 
00685 static int
00686 get_ca_use_default( Operation *op,
00687        ComponentAssertionValue* cav,
00688        int* ca_use_def, const char**  text )
00689 {
00690        strip_cav_str( cav, "useDefaultValues" );
00691 
00692        if ( peek_cav_str( cav, "TRUE" ) == LDAP_SUCCESS ) {
00693               strip_cav_str( cav, "TRUE" );
00694               *ca_use_def = 1;
00695 
00696        } else if ( peek_cav_str( cav, "FALSE" ) == LDAP_SUCCESS ) {
00697               strip_cav_str( cav, "FALSE" );
00698               *ca_use_def = 0;
00699 
00700        } else {
00701               return LDAP_INVALID_SYNTAX;
00702        }
00703 
00704        return LDAP_SUCCESS;
00705 }
00706 
00707 static int
00708 get_matching_rule( Operation *op, ComponentAssertionValue* cav,
00709               MatchingRule** mr, const char**  text )
00710 {
00711        int count = 0;
00712        struct berval rule_text = { 0L, NULL };
00713 
00714        eat_whsp( cav );
00715 
00716        for ( ; ; count++ ) {
00717               if ( cav->cav_ptr[count] == ' ' || cav->cav_ptr[count] == ',' ||
00718                      cav->cav_ptr[count] == '\0' || cav->cav_ptr[count] == '{' ||
00719                      cav->cav_ptr[count] == '}' || cav->cav_ptr[count] == '\n' )
00720               {
00721                      break;
00722               }
00723        }
00724 
00725        if ( count == 0 ) {
00726               *text = "component matching rule not recognized";
00727               return LDAP_INAPPROPRIATE_MATCHING;
00728        }
00729        
00730        rule_text.bv_len = count;
00731        rule_text.bv_val = cav->cav_ptr;
00732        *mr = mr_bvfind( &rule_text );
00733        cav->cav_ptr += count;
00734        Debug( LDAP_DEBUG_FILTER, "get_matching_rule: %s\n",
00735               (*mr)->smr_mrule.mr_oid, 0, 0 );
00736        if ( *mr == NULL ) {
00737               *text = "component matching rule not recognized";
00738               return LDAP_INAPPROPRIATE_MATCHING;
00739        }
00740        return LDAP_SUCCESS;
00741 }
00742 
00743 static int
00744 get_GSER_value( ComponentAssertionValue* cav, struct berval* bv )
00745 {
00746        int count, sequent_dquote, unclosed_brace, succeed;
00747 
00748        eat_whsp( cav );
00749        /*
00750         * Four cases of GSER <Values>
00751         * 1) "..." :
00752         *     StringVal, GeneralizedTimeVal, UTCTimeVal, ObjectDescriptorVal
00753         * 2) '...'B or '...'H :
00754         *     BitStringVal, OctetStringVal
00755         * 3) {...} :
00756         *     SEQUENCE, SEQUENCEOF, SETOF, SET, CHOICE
00757         * 4) Between two white spaces
00758         *     INTEGER, BOOLEAN, NULL,ENUMERATE, etc
00759         */
00760 
00761        succeed = 0;
00762        if ( cav->cav_ptr[0] == '"' ) {
00763               for( count = 1, sequent_dquote = 0 ; ; count++ ) {
00764                      /* In order to find escaped double quote */
00765                      if ( cav->cav_ptr[count] == '"' ) sequent_dquote++;
00766                      else sequent_dquote = 0;
00767 
00768                      if ( cav->cav_ptr[count] == '\0' ||
00769                             (cav->cav_ptr+count) > cav->cav_end )
00770                      {
00771                             break;
00772                      }
00773                             
00774                      if ( ( cav->cav_ptr[count] == '"' &&
00775                             cav->cav_ptr[count-1] != '"') ||
00776                             ( sequent_dquote > 2 && (sequent_dquote%2) == 1 ) )
00777                      {
00778                             succeed = 1;
00779                             break;
00780                      }
00781               }
00782               
00783               if ( !succeed || cav->cav_ptr[count] != '"' ) {
00784                      return LDAP_FILTER_ERROR;
00785               }
00786 
00787               bv->bv_val = cav->cav_ptr + 1;
00788               bv->bv_len = count - 1; /* exclude '"' */
00789 
00790        } else if ( cav->cav_ptr[0] == '\'' ) {
00791               for( count = 1 ; ; count++ ) {
00792                      if ( cav->cav_ptr[count] == '\0' ||
00793                             (cav->cav_ptr+count) > cav->cav_end )
00794                      {
00795                             break;
00796                      }
00797                      if ((cav->cav_ptr[count-1] == '\'' && cav->cav_ptr[count] == 'B') ||
00798                             (cav->cav_ptr[count-1] == '\'' && cav->cav_ptr[count] == 'H') )
00799                      {
00800                             succeed = 1;
00801                             break;
00802                      }
00803               }
00804 
00805               if ( !succeed ||
00806                      !(cav->cav_ptr[count] == 'H' || cav->cav_ptr[count] == 'B') )
00807               {
00808                      return LDAP_FILTER_ERROR;
00809               }
00810 
00811               bv->bv_val = cav->cav_ptr + 1;/*the next to '"' */
00812               bv->bv_len = count - 2;/* exclude "'H" or "'B" */
00813                             
00814        } else if ( cav->cav_ptr[0] == '{' ) {
00815               for( count = 1, unclosed_brace = 1 ; ; count++ ) {
00816                      if ( cav->cav_ptr[count] == '{' ) unclosed_brace++;
00817                      if ( cav->cav_ptr[count] == '}' ) unclosed_brace--;
00818 
00819                      if ( cav->cav_ptr[count] == '\0' ||
00820                             (cav->cav_ptr+count) > cav->cav_end )
00821                      {
00822                             break;
00823                      }
00824                      if ( unclosed_brace == 0 ) {
00825                             succeed = 1;
00826                             break;
00827                      }
00828               }
00829 
00830               if ( !succeed || cav->cav_ptr[count] != '}' ) return LDAP_FILTER_ERROR;
00831 
00832               bv->bv_val = cav->cav_ptr + 1;/*the next to '"' */
00833               bv->bv_len = count - 1;/* exclude  "'B" */
00834 
00835        } else {
00836               succeed = 1;
00837               /*Find  following white space where the value is ended*/
00838               for( count = 1 ; ; count++ ) {
00839                      if ( cav->cav_ptr[count] == '\0' ||
00840                             cav->cav_ptr[count] == ' ' || cav->cav_ptr[count] == '}' ||
00841                             cav->cav_ptr[count] == '{' ||
00842                             (cav->cav_ptr+count) > cav->cav_end )
00843                      {
00844                             break;
00845                      }
00846               }
00847               bv->bv_val = cav->cav_ptr;
00848               bv->bv_len = count;
00849        }
00850 
00851        cav->cav_ptr += bv->bv_len;
00852        return LDAP_SUCCESS;
00853 }
00854 
00855 static int
00856 get_matching_value( Operation *op, ComponentAssertion* ca,
00857        ComponentAssertionValue* cav, struct berval* bv,
00858        const char**  text )
00859 {
00860        if ( !(ca->ca_ma_rule->smr_usage & (SLAP_MR_COMPONENT)) ) {
00861               if ( get_GSER_value( cav, bv ) != LDAP_SUCCESS ) {
00862                      return LDAP_FILTER_ERROR;
00863               }
00864 
00865        } else {
00866               /* embeded componentFilterMatch Description */
00867               bv->bv_val = cav->cav_ptr;
00868               bv->bv_len = cav_cur_len( cav );
00869        }
00870 
00871        return LDAP_SUCCESS;
00872 }
00873 
00874 /* Don't move the position pointer, just peek given string */
00875 static int
00876 peek_cav_str( ComponentAssertionValue* cav, char* str )
00877 {
00878        eat_whsp( cav );
00879        if ( cav_cur_len( cav ) >= strlen( str ) &&
00880               strncmp( cav->cav_ptr, str, strlen( str ) ) == 0 )
00881        {
00882               return LDAP_SUCCESS;
00883        }
00884 
00885        return LDAP_INVALID_SYNTAX;
00886 }
00887 
00888 static int
00889 strip_cav_str( ComponentAssertionValue* cav, char* str)
00890 {
00891        eat_whsp( cav );
00892        if ( cav_cur_len( cav ) >= strlen( str ) &&
00893               strncmp( cav->cav_ptr, str, strlen( str ) ) == 0 )
00894        {
00895               cav->cav_ptr += strlen( str );
00896               return LDAP_SUCCESS;
00897        }
00898 
00899        return LDAP_INVALID_SYNTAX;
00900 }
00901 
00902 /*
00903  * TAG : "item", "and", "or", "not"
00904  */
00905 static ber_tag_t
00906 strip_cav_tag( ComponentAssertionValue* cav )
00907 {
00908 
00909        eat_whsp( cav );
00910        if ( cav_cur_len( cav ) >= 8 && strncmp( cav->cav_ptr, "item", 4 ) == 0 ) {
00911               strip_cav_str( cav , "item:" );
00912               return LDAP_COMP_FILTER_ITEM;
00913 
00914        } else if ( cav_cur_len( cav ) >= 7 &&
00915               strncmp( cav->cav_ptr, "and", 3 ) == 0 )
00916        {
00917               strip_cav_str( cav , "and:" );
00918               return LDAP_COMP_FILTER_AND;
00919 
00920        } else if ( cav_cur_len( cav ) >= 6 &&
00921               strncmp( cav->cav_ptr, "or" , 2 ) == 0 )
00922        {
00923               strip_cav_str( cav , "or:" );
00924               return LDAP_COMP_FILTER_OR;
00925 
00926        } else if ( cav_cur_len( cav ) >= 7 &&
00927               strncmp( cav->cav_ptr, "not", 3 ) == 0 )
00928        {
00929               strip_cav_str( cav , "not:" );
00930               return LDAP_COMP_FILTER_NOT;
00931        }
00932 
00933        return LBER_ERROR;
00934 }
00935 
00936 /*
00937  * when encoding, "item" is denotation of ComponentAssertion
00938  * ComponentAssertion :: SEQUENCE {
00939  *     component            ComponentReference (SIZE(1..MAX)) OPTIONAL,
00940  *     useDefaultValues     BOOLEAN DEFAULT TRUE,
00941  *     rule                 MATCHING-RULE.&id,
00942  *     value                MATCHING-RULE.&AssertionType }
00943  */
00944 static int
00945 get_item( Operation *op, ComponentAssertionValue* cav, ComponentAssertion** ca,
00946               const char** text )
00947 {
00948        int rc;
00949        ComponentAssertion* _ca;
00950        struct berval value;
00951        MatchingRule* mr;
00952 
00953        Debug( LDAP_DEBUG_FILTER, "get_item \n", 0, 0, 0 );
00954        if ( op )
00955               _ca = op->o_tmpalloc( sizeof( ComponentAssertion ), op->o_tmpmemctx );
00956        else
00957               _ca = SLAP_MALLOC( sizeof( ComponentAssertion ) );
00958 
00959        if ( !_ca ) return LDAP_NO_MEMORY;
00960 
00961        _ca->ca_comp_data.cd_tree = NULL;
00962        _ca->ca_comp_data.cd_mem_op = NULL;
00963 
00964        rc = peek_cav_str( cav, "component" );
00965        if ( rc == LDAP_SUCCESS ) {
00966               strip_cav_str( cav, "component" );
00967               rc = get_component_reference( op, cav, &_ca->ca_comp_ref, text );
00968               if ( rc != LDAP_SUCCESS ) {
00969                      if ( op )
00970                             op->o_tmpfree( _ca, op->o_tmpmemctx );
00971                      else
00972                             free( _ca );
00973                      return LDAP_INVALID_SYNTAX;
00974               }
00975               if ( ( rc = strip_cav_str( cav,",") ) != LDAP_SUCCESS )
00976                      return rc;
00977        } else {
00978               _ca->ca_comp_ref = NULL;
00979        }
00980 
00981        rc = peek_cav_str( cav, "useDefaultValues");
00982        if ( rc == LDAP_SUCCESS ) {
00983               rc = get_ca_use_default( op, cav, &_ca->ca_use_def, text );
00984               if ( rc != LDAP_SUCCESS ) {
00985                      if ( op )
00986                             op->o_tmpfree( _ca, op->o_tmpmemctx );
00987                      else
00988                             free( _ca );
00989                      return LDAP_INVALID_SYNTAX;
00990               }
00991               if ( ( rc = strip_cav_str( cav,",") ) != LDAP_SUCCESS )
00992                      return rc;
00993        }
00994        else _ca->ca_use_def = 1;
00995 
00996        if ( !( strip_cav_str( cav, "rule" ) == LDAP_SUCCESS &&
00997               get_matching_rule( op, cav , &_ca->ca_ma_rule, text ) == LDAP_SUCCESS )) {
00998               if ( op )
00999                      op->o_tmpfree( _ca, op->o_tmpmemctx );
01000               else
01001                      free( _ca );
01002               return LDAP_INAPPROPRIATE_MATCHING;
01003        }
01004        
01005        if ( ( rc = strip_cav_str( cav,",") ) != LDAP_SUCCESS )
01006               return rc;
01007        if ( !(strip_cav_str( cav, "value" ) == LDAP_SUCCESS &&
01008               get_matching_value( op, _ca, cav,&value ,text ) == LDAP_SUCCESS )) {
01009               if ( op )
01010                      op->o_tmpfree( _ca, op->o_tmpmemctx );
01011               else
01012                      free( _ca );
01013               return LDAP_INVALID_SYNTAX;
01014        }
01015 
01016        /*
01017         * Normalize the value of this component assertion when the matching
01018         * rule is one of existing matching rules
01019         */
01020        mr = _ca->ca_ma_rule;
01021        if ( op && !(mr->smr_usage & (SLAP_MR_COMPONENT)) && mr->smr_normalize ) {
01022 
01023               value.bv_val[value.bv_len] = '\0';
01024               rc = mr->smr_normalize (
01025                      SLAP_MR_VALUE_OF_ASSERTION_SYNTAX,
01026                      NULL, mr,
01027                      &value, &_ca->ca_ma_value, op->o_tmpmemctx );
01028               if ( rc != LDAP_SUCCESS )
01029                      return rc;
01030        }
01031        else
01032               _ca->ca_ma_value = value;
01033        /*
01034         * Validate the value of this component assertion
01035         */
01036        if ( op && mr->smr_syntax->ssyn_validate( mr->smr_syntax, &_ca->ca_ma_value) != LDAP_SUCCESS ) {
01037               return LDAP_INVALID_SYNTAX;
01038        }
01039 
01040 
01041        /* componentFilterMatch contains componentFilterMatch in it */
01042        if ( strcmp(_ca->ca_ma_rule->smr_mrule.mr_oid, OID_COMP_FILTER_MATCH ) == 0) {
01043               struct berval bv;
01044               bv.bv_val = cav->cav_ptr;
01045               bv.bv_len = cav_cur_len( cav );
01046               rc = get_comp_filter( op, &bv,(ComponentFilter**)&_ca->ca_cf, text );
01047               if ( rc != LDAP_SUCCESS ) {
01048                      if ( op )
01049                             op->o_tmpfree( _ca, op->o_tmpmemctx );
01050                      else
01051                             free( _ca );
01052                      return rc;
01053               }
01054               cav->cav_ptr = bv.bv_val;
01055               assert( cav->cav_end >= bv.bv_val );
01056        }
01057 
01058        *ca = _ca;
01059        return LDAP_SUCCESS;
01060 }
01061 
01062 static int
01063 parse_comp_filter( Operation* op, ComponentAssertionValue* cav,
01064                             ComponentFilter** filt, const char** text )
01065 {
01066        /*
01067         * A component filter looks like this coming in:
01068         *     Filter ::= CHOICE {
01069         *            item   [0]    ComponentAssertion,
01070         *            and    [1]    SEQUENCE OF ComponentFilter,
01071         *            or     [2]    SEQUENCE OF ComponentFilter,
01072         *            not    [3]    ComponentFilter,
01073         *     }
01074         */
01075 
01076        ber_tag_t     tag;
01077        int           err;
01078        ComponentFilter      f;
01079        /* TAG : item, and, or, not in RFC 4515 */
01080        tag = strip_cav_tag( cav );
01081 
01082        if ( tag == LBER_ERROR ) {
01083               *text = "error decoding comp filter";
01084               return LDAP_PROTOCOL_ERROR;
01085        }
01086 
01087        if ( tag != LDAP_COMP_FILTER_NOT )
01088               strip_cav_str( cav, "{");
01089 
01090        err = LDAP_SUCCESS;
01091 
01092        f.cf_next = NULL;
01093        f.cf_choice = tag; 
01094 
01095        switch ( f.cf_choice ) {
01096        case LDAP_COMP_FILTER_AND:
01097        Debug( LDAP_DEBUG_FILTER, "LDAP_COMP_FILTER_AND\n", 0, 0, 0 );
01098               err = get_comp_filter_list( op, cav, &f.cf_and, text );
01099               if ( err != LDAP_SUCCESS ) {
01100                      break;
01101               }
01102               if ( f.cf_and == NULL ) {
01103                      f.cf_choice = SLAPD_FILTER_COMPUTED;
01104                      f.cf_result = LDAP_COMPARE_TRUE;
01105               }
01106               break;
01107 
01108        case LDAP_COMP_FILTER_OR:
01109        Debug( LDAP_DEBUG_FILTER, "LDAP_COMP_FILTER_OR\n", 0, 0, 0 );
01110               err = get_comp_filter_list( op, cav, &f.cf_or, text );
01111               if ( err != LDAP_SUCCESS ) {
01112                      break;
01113               }
01114               if ( f.cf_or == NULL ) {
01115                      f.cf_choice = SLAPD_FILTER_COMPUTED;
01116                      f.cf_result = LDAP_COMPARE_FALSE;
01117               }
01118               /* no assert - list could be empty */
01119               break;
01120 
01121        case LDAP_COMP_FILTER_NOT:
01122        Debug( LDAP_DEBUG_FILTER, "LDAP_COMP_FILTER_NOT\n", 0, 0, 0 );
01123               err = parse_comp_filter( op, cav, &f.cf_not, text );
01124               if ( err != LDAP_SUCCESS ) {
01125                      break;
01126               }
01127 
01128               assert( f.cf_not != NULL );
01129               if ( f.cf_not->cf_choice == SLAPD_FILTER_COMPUTED ) {
01130                      int fresult = f.cf_not->cf_result;
01131                      f.cf_choice = SLAPD_FILTER_COMPUTED;
01132                      op->o_tmpfree( f.cf_not, op->o_tmpmemctx );
01133                      f.cf_not = NULL;
01134 
01135                      switch ( fresult ) {
01136                      case LDAP_COMPARE_TRUE:
01137                             f.cf_result = LDAP_COMPARE_FALSE;
01138                             break;
01139                      case LDAP_COMPARE_FALSE:
01140                             f.cf_result = LDAP_COMPARE_TRUE;
01141                             break;
01142                      default: ;
01143                             /* (!Undefined) is Undefined */
01144                      }
01145               }
01146               break;
01147 
01148        case LDAP_COMP_FILTER_ITEM:
01149        Debug( LDAP_DEBUG_FILTER, "LDAP_COMP_FILTER_ITEM\n", 0, 0, 0 );
01150               err = get_item( op, cav, &f.cf_ca, text );
01151               if ( err != LDAP_SUCCESS ) {
01152                      break;
01153               }
01154 
01155               assert( f.cf_ca != NULL );
01156               break;
01157 
01158        default:
01159               f.cf_choice = SLAPD_FILTER_COMPUTED;
01160               f.cf_result = SLAPD_COMPARE_UNDEFINED;
01161               break;
01162        }
01163 
01164        if ( err != LDAP_SUCCESS && err != SLAPD_DISCONNECT ) {
01165               *text = "Component Filter Syntax Error";
01166               return err;
01167        }
01168 
01169        if ( tag != LDAP_COMP_FILTER_NOT )
01170               strip_cav_str( cav, "}");
01171 
01172        if ( err == LDAP_SUCCESS ) {
01173               if ( op ) {
01174                      *filt = op->o_tmpalloc( sizeof(f), op->o_tmpmemctx );
01175               } else {
01176                      *filt = SLAP_MALLOC( sizeof(f) );
01177               }
01178               if ( *filt == NULL ) {
01179                      return LDAP_NO_MEMORY;
01180               }
01181               **filt = f;
01182        }
01183 
01184        return( err );
01185 }
01186 
01187 static int
01188 test_comp_filter_and(
01189        Syntax *syn,
01190        ComponentSyntaxInfo *a,
01191        ComponentFilter *flist )
01192 {
01193        ComponentFilter *f;
01194        int rtn = LDAP_COMPARE_TRUE;
01195 
01196        for ( f = flist ; f != NULL; f = f->cf_next ) {
01197               int rc = test_comp_filter( syn, a, f );
01198               if ( rc == LDAP_COMPARE_FALSE ) {
01199                      rtn = rc;
01200                      break;
01201               }
01202        
01203               if ( rc != LDAP_COMPARE_TRUE ) {
01204                      rtn = rc;
01205               }
01206        }
01207 
01208        return rtn;
01209 }
01210 
01211 static int
01212 test_comp_filter_or(
01213        Syntax *syn,
01214        ComponentSyntaxInfo *a,
01215        ComponentFilter *flist )
01216 {
01217        ComponentFilter *f;
01218        int rtn = LDAP_COMPARE_TRUE;
01219 
01220        for ( f = flist ; f != NULL; f = f->cf_next ) {
01221               int rc = test_comp_filter( syn, a, f );
01222               if ( rc == LDAP_COMPARE_TRUE ) {
01223                      rtn = rc;
01224                      break;
01225               }
01226        
01227               if ( rc != LDAP_COMPARE_FALSE ) {
01228                      rtn = rc;
01229               }
01230        }
01231 
01232        return rtn;
01233 }
01234 
01235 int
01236 csi_value_match( MatchingRule *mr, struct berval* bv_attr,
01237        struct berval* bv_assert )
01238 {
01239        int rc;
01240        int match;
01241 
01242        assert( mr != NULL );
01243        assert( !(mr->smr_usage & SLAP_MR_COMPONENT) );
01244 
01245        if( !mr->smr_match ) return LDAP_INAPPROPRIATE_MATCHING;
01246 
01247        rc = (mr->smr_match)( &match, 0, NULL /*ad->ad_type->sat_syntax*/,
01248               mr, bv_attr, bv_assert );
01249 
01250        if ( rc != LDAP_SUCCESS ) return rc;
01251 
01252        return match ? LDAP_COMPARE_FALSE : LDAP_COMPARE_TRUE;
01253 }
01254 
01255 /*
01256  * return codes : LDAP_COMPARE_TRUE, LDAP_COMPARE_FALSE
01257  */
01258 static int
01259 test_comp_filter_item(
01260        Syntax *syn,
01261        ComponentSyntaxInfo *csi_attr,
01262        ComponentAssertion *ca )
01263 {
01264        int rc;
01265        void *attr_nm, *assert_nm;
01266 
01267        if ( strcmp(ca->ca_ma_rule->smr_mrule.mr_oid,
01268               OID_COMP_FILTER_MATCH ) == 0 && ca->ca_cf ) {
01269               /* componentFilterMatch inside of componentFilterMatch */
01270               rc = test_comp_filter( syn, csi_attr, ca->ca_cf );
01271               return rc;
01272        }
01273 
01274        /* Memory for storing will-be-extracted attribute values */
01275        attr_nm = nibble_mem_allocator ( 1024*4 , 1024 );
01276        if ( !attr_nm ) return LDAP_PROTOCOL_ERROR;
01277 
01278        /* Memory for storing component assertion values */
01279        if( !ca->ca_comp_data.cd_mem_op ) {
01280               assert_nm = nibble_mem_allocator ( 256, 64 );
01281               if ( !assert_nm ) {
01282                      nibble_mem_free ( attr_nm );
01283                      return LDAP_PROTOCOL_ERROR;
01284               }
01285               ca->ca_comp_data.cd_mem_op = assert_nm;
01286 
01287        } else {
01288               assert_nm = ca->ca_comp_data.cd_mem_op;
01289        }
01290 
01291        /* component reference initialization */
01292        if ( ca->ca_comp_ref ) {
01293               ca->ca_comp_ref->cr_curr = ca->ca_comp_ref->cr_list;
01294        }
01295        rc = test_components( attr_nm, assert_nm, csi_attr, ca );
01296 
01297        /* free memory used for storing extracted attribute value */
01298        nibble_mem_free ( attr_nm );
01299        return rc;
01300 }
01301 
01302 static int
01303 test_comp_filter(
01304     Syntax *syn,
01305     ComponentSyntaxInfo *a,
01306     ComponentFilter *f )
01307 {
01308        int    rc;
01309 
01310        if ( !f ) return LDAP_PROTOCOL_ERROR;
01311 
01312        Debug( LDAP_DEBUG_FILTER, "test_comp_filter\n", 0, 0, 0 );
01313        switch ( f->cf_choice ) {
01314        case SLAPD_FILTER_COMPUTED:
01315               rc = f->cf_result;
01316               break;
01317        case LDAP_COMP_FILTER_AND:
01318               rc = test_comp_filter_and( syn, a, f->cf_and );
01319               break;
01320        case LDAP_COMP_FILTER_OR:
01321               rc = test_comp_filter_or( syn, a, f->cf_or );
01322               break;
01323        case LDAP_COMP_FILTER_NOT:
01324               rc = test_comp_filter( syn, a, f->cf_not );
01325 
01326               switch ( rc ) {
01327               case LDAP_COMPARE_TRUE:
01328                      rc = LDAP_COMPARE_FALSE;
01329                      break;
01330               case LDAP_COMPARE_FALSE:
01331                      rc = LDAP_COMPARE_TRUE;
01332                      break;
01333               }
01334               break;
01335        case LDAP_COMP_FILTER_ITEM:
01336               rc = test_comp_filter_item( syn, a, f->cf_ca );
01337               break;
01338        default:
01339               rc = LDAP_PROTOCOL_ERROR;
01340        }
01341 
01342        return( rc );
01343 }
01344 
01345 static void
01346 free_comp_filter_list( ComponentFilter* f )
01347 {
01348        ComponentFilter* tmp;
01349        for ( tmp = f; tmp; tmp = tmp->cf_next ) {
01350               free_comp_filter( tmp );
01351        }
01352 }
01353 
01354 static void
01355 free_comp_filter( ComponentFilter* f )
01356 {
01357        if ( !f ) {
01358               Debug( LDAP_DEBUG_FILTER,
01359                      "free_comp_filter: Invalid filter so failed to release memory\n",
01360                      0, 0, 0 );
01361               return;
01362        }
01363        switch ( f->cf_choice ) {
01364        case LDAP_COMP_FILTER_AND:
01365        case LDAP_COMP_FILTER_OR:
01366               free_comp_filter_list( f->cf_any );
01367               break;
01368        case LDAP_COMP_FILTER_NOT:
01369               free_comp_filter( f->cf_any );
01370               break;
01371        case LDAP_COMP_FILTER_ITEM:
01372               if ( nibble_mem_free && f->cf_ca->ca_comp_data.cd_mem_op ) {
01373                      nibble_mem_free( f->cf_ca->ca_comp_data.cd_mem_op );
01374               }
01375               break;
01376        default:
01377               break;
01378        }
01379 }
01380 
01381 void
01382 component_free( ComponentFilter *f ) {
01383        free_comp_filter( f );
01384 }
01385 
01386 void
01387 free_ComponentData( Attribute *a ) {
01388        if ( a->a_comp_data->cd_mem_op )
01389               component_destructor( a->a_comp_data->cd_mem_op );
01390        free ( a->a_comp_data );
01391        a->a_comp_data = NULL;
01392 }
01393 #endif