Back to index

openldap  2.4.31
init.c
Go to the documentation of this file.
00001 /* Copyright 2004 IBM Corporation
00002  * All rights reserved.
00003  * Redisribution and use in source and binary forms, with or without
00004  * modification, are permitted only as authorizd by the OpenLADP
00005  * Public License.
00006  */
00007 /* ACKNOWLEDGEMENTS
00008  * This work originally developed by Sang Seok Lim
00009  * 2004/06/18 03:20:00      slim@OpenLDAP.org
00010  */
00011 
00012 #include "portable.h"
00013 #include <ac/string.h>
00014 #include <ac/socket.h>
00015 #include <ldap_pvt.h>
00016 #include "lutil.h"
00017 #include <ldap.h>
00018 #include "slap.h"
00019 #include "component.h"
00020 
00021 #include "componentlib.h"
00022 #include "asn.h"
00023 #include <asn-gser.h>
00024 
00025 #include <string.h>
00026 
00027 #ifndef SLAPD_COMP_MATCH
00028 #define SLAPD_COMP_MATCH SLAPD_MOD_DYNAMIC
00029 #endif
00030 
00031 /*
00032  * Attribute and MatchingRule aliasing table
00033  */
00034 AttributeAliasing aa_table [ MAX_ALIASING_ENTRY ];
00035 MatchingRuleAliasing mra_table [ MAX_ALIASING_ENTRY ];
00036 
00037 OD_entry* gOD_table = NULL;
00038 AsnTypetoMatchingRuleTable* gATMR_table = NULL;
00039 
00040 int
00041 load_derived_matching_rule ( char* cfg_path ){
00042 }
00043 
00044 AttributeAliasing*
00045 comp_is_aliased_attribute( void *in  )
00046 {
00047        AttributeAliasing* curr_aa;
00048        int i;
00049        AttributeDescription *ad = (AttributeDescription*)in;
00050 
00051        for ( i = 0; aa_table[i].aa_aliasing_ad && i < MAX_ALIASING_ENTRY; i++ ) {
00052               if ( strncmp(aa_table[i].aa_aliasing_ad->ad_cname.bv_val , ad->ad_cname.bv_val, ad->ad_cname.bv_len) == 0 )
00053                      return &aa_table[i];
00054        }
00055        return NULL;
00056 }
00057 
00058 static int
00059 add_aa_entry( int index, char* aliasing_at_name, char* aliased_at_name, char* mr_name, char* component_filter )
00060 {
00061        char text[1][128];
00062        int rc;
00063        struct berval type;
00064 
00065        /* get and store aliasing AttributeDescription */
00066        type.bv_val = aliasing_at_name;
00067        type.bv_len = strlen ( aliasing_at_name );
00068        rc = slap_bv2ad ( &type, &aa_table[index].aa_aliasing_ad,(const char**)text );
00069        if ( rc != LDAP_SUCCESS ) return rc;
00070 
00071        /* get and store aliased AttributeDescription */
00072        type.bv_val = aliased_at_name;
00073        type.bv_len = strlen ( aliased_at_name );
00074        rc = slap_bv2ad ( &type, &aa_table[index].aa_aliased_ad,(const char**)text );
00075        if ( rc != LDAP_SUCCESS ) return rc;
00076 
00077        /* get and store componentFilterMatch */
00078        type.bv_val = mr_name;
00079        type.bv_len = strlen ( mr_name);
00080        aa_table[index].aa_mr = mr_bvfind ( &type );
00081 
00082        /* get and store a component filter */
00083        type.bv_val = component_filter;
00084        type.bv_len = strlen ( component_filter );
00085        rc = get_comp_filter( NULL, &type, &aa_table[index].aa_cf,(const char**)text);
00086 
00087        aa_table[index].aa_cf_str = component_filter;
00088 
00089        return rc;
00090 }
00091 
00092 /*
00093  * Initialize attribute aliasing table when this module is loaded
00094  * add_aa_entry ( index for the global table,
00095  *                name of the aliasing attribute,
00096  *                component filter with filling value parts "xxx"
00097  *              )
00098  * "xxx" will be replaced with effective values later.
00099  * See RFC3687 to understand the content of a component filter.
00100  */
00101 char* pre_processed_comp_filter[] = {
00102 /*1*/"item:{ component \"toBeSigned.issuer.rdnSequence\", rule distinguishedNameMatch, value xxx }",
00103 /*2*/"item:{ component \"toBeSigned.serialNumber\", rule integerMatch, value xxx }",
00104 /*3*/"and:{ item:{ component \"toBeSigned.serialNumber\", rule integerMatch, value xxx }, item:{ component \"toBeSigned.issuer.rdnSequence\", rule distinguishedNameMatch, value xxx } }"
00105 };
00106 
00107 static int
00108 init_attribute_aliasing_table ()
00109 {
00110        int rc;
00111        int index = 0 ;
00112 
00113        rc = add_aa_entry ( index, "x509CertificateIssuer", "userCertificate","componentFilterMatch", pre_processed_comp_filter[index] );
00114        if ( rc != LDAP_SUCCESS ) return LDAP_PARAM_ERROR;
00115        index++;
00116 
00117        rc = add_aa_entry ( index, "x509CertificateSerial","userCertificate", "componentFilterMatch", pre_processed_comp_filter[index] );
00118        if ( rc != LDAP_SUCCESS ) return LDAP_PARAM_ERROR;
00119        index++;
00120 
00121        rc = add_aa_entry ( index, "x509CertificateSerialAndIssuer", "userCertificate", "componentFilterMatch", pre_processed_comp_filter[index] );
00122        if ( rc != LDAP_SUCCESS ) return LDAP_PARAM_ERROR;
00123        index++;
00124 
00125        return LDAP_SUCCESS;
00126 }
00127 
00128 void
00129 init_component_description_table () {
00130        AsnTypeId id;
00131        struct berval mr;
00132        AsnTypetoSyntax* asn_to_syn;
00133        Syntax* syn;
00134 
00135        for ( id = BASICTYPE_BOOLEAN; id != ASNTYPE_END ; id++ ) {
00136               asntype_to_compType_mapping_tbl[id].ac_comp_type.ct_subtypes = NULL;
00137               asntype_to_compType_mapping_tbl[id].ac_comp_type.ct_syntax =  NULL;
00138 
00139               /* Equality Matching Rule */
00140               if ( asntype_to_compMR_mapping_tbl[id].atc_equality ) {
00141                      mr.bv_val = asntype_to_compMR_mapping_tbl[id].atc_equality;
00142                      mr.bv_len = strlen(asntype_to_compMR_mapping_tbl[id].atc_equality);
00143                      asntype_to_compType_mapping_tbl[id].ac_comp_type.ct_equality = mr_bvfind( &mr );
00144               }
00145               /* Approx Matching Rule */
00146               if ( asntype_to_compMR_mapping_tbl[id].atc_approx ) {
00147                      mr.bv_val = asntype_to_compMR_mapping_tbl[id].atc_approx;
00148                      mr.bv_len = strlen(asntype_to_compMR_mapping_tbl[id].atc_approx);
00149                      asntype_to_compType_mapping_tbl[id].ac_comp_type.ct_approx = mr_bvfind( &mr );
00150               }
00151 
00152               /* Ordering Matching Rule */
00153               if ( asntype_to_compMR_mapping_tbl[id].atc_ordering ) {
00154                      mr.bv_val = asntype_to_compMR_mapping_tbl[id].atc_ordering;
00155                      mr.bv_len = strlen(asntype_to_compMR_mapping_tbl[id].atc_ordering);
00156                      asntype_to_compType_mapping_tbl[id].ac_comp_type.ct_ordering= mr_bvfind( &mr );
00157               }
00158 
00159               /* Substr Matching Rule */
00160               if ( asntype_to_compMR_mapping_tbl[id].atc_substr ) {
00161                      mr.bv_val = asntype_to_compMR_mapping_tbl[id].atc_substr;
00162                      mr.bv_len = strlen(asntype_to_compMR_mapping_tbl[id].atc_substr);
00163                      asntype_to_compType_mapping_tbl[id].ac_comp_type.ct_substr = mr_bvfind( &mr );
00164               }
00165               /* Syntax */
00166 
00167               asn_to_syn = &asn_to_syntax_mapping_tbl[ id ];
00168               if ( asn_to_syn->ats_syn_oid )
00169                      syn = syn_find ( asn_to_syn->ats_syn_oid );
00170               else 
00171                      syn = NULL;
00172               asntype_to_compType_mapping_tbl[id].ac_comp_type.ct_syntax = syn;
00173 
00174               /* Initialize Component Descriptions of primitive ASN.1 types */
00175               asntype_to_compdesc_mapping_tbl[id].atcd_cd.cd_comp_type = (AttributeType*)&asntype_to_compType_mapping_tbl[id].ac_comp_type;
00176        }
00177 }
00178 
00179 MatchingRule*
00180 retrieve_matching_rule( char* mr_oid, AsnTypeId type ) {
00181        char* tmp;
00182        struct berval mr_name = BER_BVNULL;
00183        AsnTypetoMatchingRuleTable* atmr;
00184 
00185        for ( atmr = gATMR_table ; atmr ; atmr = atmr->atmr_table_next ) {
00186               if ( strcmp( atmr->atmr_oid, mr_oid ) == 0 ) {
00187                      tmp = atmr->atmr_table[type].atmr_mr_name;
00188                      if ( tmp ) {
00189                             mr_name.bv_val = tmp;
00190                             mr_name.bv_len = strlen( tmp );
00191                             return mr_bvfind ( &mr_name );
00192                      }
00193               }
00194        }
00195        return (MatchingRule*)NULL;
00196 }
00197 
00198 void* 
00199 comp_convert_attr_to_comp LDAP_P (( Attribute* a, Syntax *syn, struct berval* bv ))
00200 {
00201        char* peek_head;
00202         int mode, bytesDecoded, size, rc;
00203         void* component;
00204        char* oid = a->a_desc->ad_type->sat_atype.at_oid ;
00205         GenBuf* b = NULL;
00206         ExpBuf* buf = NULL;
00207        OidDecoderMapping* odm;
00208        
00209        /* look for the decoder registered for the given attribute */
00210        odm = RetrieveOidDecoderMappingbyOid( oid, strlen(oid) );
00211 
00212        if ( !odm || (!odm->BER_Decode && !odm->GSER_Decode) )
00213               return (void*)NULL;
00214 
00215        buf = ExpBufAllocBuf();
00216        ExpBuftoGenBuf( buf, &b );
00217        ExpBufInstallDataInBuf ( buf, bv->bv_val, bv->bv_len );
00218        BufResetInReadMode( b );
00219 
00220        mode = DEC_ALLOC_MODE_2;
00221        /*
00222         * How can we decide which decoder will be called, GSER or BER?
00223         * Currently BER decoder is called for a certificate.
00224         * The flag of Attribute will say something about it in the future
00225         */
00226        if ( syn && slap_syntax_is_ber ( syn ) ) {
00227 #if 0
00228               rc =BDecComponentTop(odm->BER_Decode, a->a_comp_data->cd_mem_op, b, 0,0, &component,&bytesDecoded,mode ) ;
00229 #endif
00230               rc = odm->BER_Decode ( a->a_comp_data->cd_mem_op, b, (ComponentSyntaxInfo*)&component, &bytesDecoded, mode );
00231        }
00232        else {
00233               rc = odm->GSER_Decode( a->a_comp_data->cd_mem_op, b, (ComponentSyntaxInfo**)component, &bytesDecoded, mode);
00234        }
00235 
00236        ExpBufFreeBuf( buf );
00237        GenBufFreeBuf( b );
00238        if ( rc == -1 ) {
00239 #if 0
00240               ShutdownNibbleMemLocal ( a->a_comp_data->cd_mem_op );
00241               free ( a->a_comp_data );
00242               a->a_comp_data = NULL;
00243 #endif
00244               return (void*)NULL;
00245        }
00246        else {
00247               return component;
00248        }
00249 }
00250 
00251 #include <nibble-alloc.h>
00252 void
00253 comp_free_component ( void* mem_op ) {
00254        ShutdownNibbleMemLocal( (NibbleMem*)mem_op );
00255        return;
00256 }
00257 
00258 void
00259 comp_convert_assert_to_comp (
00260        void* mem_op,
00261        ComponentSyntaxInfo *csi_attr,
00262        struct berval* bv,
00263        ComponentSyntaxInfo** csi, int* len, int mode )
00264 {
00265        int rc;
00266        GenBuf* genBuf;
00267        ExpBuf* buf;
00268        gser_decoder_func *decoder = csi_attr->csi_comp_desc->cd_gser_decoder;
00269 
00270        buf = ExpBufAllocBuf();
00271        ExpBuftoGenBuf( buf, &genBuf );
00272        ExpBufInstallDataInBuf ( buf, bv->bv_val, bv->bv_len );
00273        BufResetInReadMode( genBuf );
00274 
00275        if ( csi_attr->csi_comp_desc->cd_type_id == BASICTYPE_ANY )
00276               decoder = ((ComponentAny*)csi_attr)->cai->GSER_Decode;
00277 
00278        rc = (*decoder)( mem_op, genBuf, csi, len, mode );
00279        ExpBufFreeBuf ( buf );
00280        GenBufFreeBuf( genBuf );
00281 }
00282 
00283 int intToAscii( int value, char* buf ) {
00284        int minus=0,i,temp;
00285        int total_num_digits;
00286 
00287        if ( value == 0 ){
00288               buf[0] = '0';
00289               return 1;
00290        }
00291 
00292        if ( value < 0 ){
00293               minus = 1;
00294               value = value*(-1);
00295               buf[0] = '-';
00296        }
00297        
00298        /* How many digits */
00299        for ( temp = value, total_num_digits=0 ; temp ; total_num_digits++ )
00300               temp = temp/10;
00301 
00302        total_num_digits += minus;
00303 
00304        for ( i = minus ; value ; i++ ) {
00305               buf[ total_num_digits - i - 1 ]= (char)(value%10 + '0');
00306               value = value/10;
00307        }
00308        return i;
00309 }
00310 
00311 int
00312 comp_convert_asn_to_ldap ( MatchingRule* mr, ComponentSyntaxInfo* csi, struct berval* bv, int *allocated )
00313 {
00314        int rc;
00315        struct berval prettied;
00316        Syntax* syn;
00317 
00318        AsnTypetoSyntax* asn_to_syn =
00319               &asn_to_syntax_mapping_tbl[csi->csi_comp_desc->cd_type_id];
00320        if ( asn_to_syn->ats_syn_oid )
00321               csi->csi_syntax = syn_find ( asn_to_syn->ats_syn_oid );
00322        else 
00323               csi->csi_syntax = NULL;
00324 
00325 
00326         switch ( csi->csi_comp_desc->cd_type_id ) {
00327           case BASICTYPE_BOOLEAN :
00328               bv->bv_val = (char*)malloc( 5 );
00329               *allocated = 1;
00330               bv->bv_len = 5;
00331               if ( ((ComponentBool*)csi)->value > 0 ) {
00332                      strcpy ( bv->bv_val , "TRUE" );
00333                      bv->bv_len = 4;
00334               }
00335               else {
00336                      strcpy ( bv->bv_val , "FALSE" );
00337                      bv->bv_len = 5;
00338               }
00339                 break ;
00340           case BASICTYPE_NULL :
00341                 bv->bv_len = 0;
00342                 break;
00343           case BASICTYPE_INTEGER :
00344               bv->bv_val = (char*)malloc( INITIAL_ATTR_SIZE );
00345               *allocated = 1;
00346               bv->bv_len = INITIAL_ATTR_SIZE;
00347               bv->bv_len = intToAscii(((ComponentInt*)csi)->value, bv->bv_val );
00348               if ( bv->bv_len <= 0 )
00349                      return LDAP_INVALID_SYNTAX;
00350                 break;
00351           case BASICTYPE_REAL :
00352               return LDAP_INVALID_SYNTAX;
00353           case BASICTYPE_ENUMERATED :
00354               bv->bv_val = (char*)malloc( INITIAL_ATTR_SIZE );
00355               *allocated = 1;
00356               bv->bv_len = INITIAL_ATTR_SIZE;
00357               bv->bv_len = intToAscii(((ComponentEnum*)csi)->value, bv->bv_val );
00358               if ( bv->bv_len <= 0 )
00359                      return LDAP_INVALID_SYNTAX;
00360                 break;
00361           case BASICTYPE_OID :
00362           case BASICTYPE_OCTETSTRING :
00363           case BASICTYPE_BITSTRING :
00364           case BASICTYPE_NUMERIC_STR :
00365           case BASICTYPE_PRINTABLE_STR :
00366           case BASICTYPE_UNIVERSAL_STR :
00367           case BASICTYPE_IA5_STR :
00368           case BASICTYPE_BMP_STR :
00369           case BASICTYPE_UTF8_STR :
00370           case BASICTYPE_UTCTIME :
00371           case BASICTYPE_GENERALIZEDTIME :
00372           case BASICTYPE_GRAPHIC_STR :
00373           case BASICTYPE_VISIBLE_STR :
00374           case BASICTYPE_GENERAL_STR :
00375           case BASICTYPE_OBJECTDESCRIPTOR :
00376           case BASICTYPE_VIDEOTEX_STR :
00377           case BASICTYPE_T61_STR :
00378           case BASICTYPE_OCTETCONTAINING :
00379           case BASICTYPE_BITCONTAINING :
00380           case BASICTYPE_RELATIVE_OID :
00381               bv->bv_val = ((ComponentOcts*)csi)->value.octs;
00382               bv->bv_len = ((ComponentOcts*)csi)->value.octetLen;
00383                 break;
00384          case BASICTYPE_ANY :
00385               csi = ((ComponentAny*)csi)->value;
00386               if ( csi->csi_comp_desc->cd_type != ASN_BASIC ||
00387                      csi->csi_comp_desc->cd_type_id == BASICTYPE_ANY )
00388                      return LDAP_INVALID_SYNTAX;
00389               return comp_convert_asn_to_ldap( mr, csi, bv, allocated );
00390           case COMPOSITE_ASN1_TYPE :
00391               break;
00392           case RDNSequence :
00393               /*dnMatch*/
00394               if( strncmp( mr->smr_mrule.mr_oid, DN_MATCH_OID, strlen(DN_MATCH_OID) ) != 0 )
00395                      return LDAP_INVALID_SYNTAX;
00396               *allocated = 1;
00397               rc = ConvertRDNSequence2RFC2253( (irRDNSequence*)csi, bv );
00398               if ( rc != LDAP_SUCCESS ) return rc;
00399               break;
00400           case RelativeDistinguishedName :
00401               /*rdnMatch*/
00402               if( strncmp( mr->smr_mrule.mr_oid, RDN_MATCH_OID, strlen(RDN_MATCH_OID) ) != 0 )
00403                      return LDAP_INVALID_SYNTAX;
00404               *allocated = 1;
00405               rc = ConvertRDN2RFC2253((irRelativeDistinguishedName*)csi,bv);
00406               if ( rc != LDAP_SUCCESS ) return rc;
00407               break;
00408           case TelephoneNumber :
00409           case FacsimileTelephoneNumber__telephoneNumber :
00410               break;
00411           case DirectoryString :
00412               return LDAP_INVALID_SYNTAX;
00413           case ASN_COMP_CERTIFICATE :
00414           case ASNTYPE_END :
00415               break;
00416           default :
00417                 /*Only ASN Basic Type can be converted into LDAP string*/
00418               return LDAP_INVALID_SYNTAX;
00419         }
00420 
00421        if ( csi->csi_syntax ) {
00422               if ( csi->csi_syntax->ssyn_validate ) {
00423                      rc = csi->csi_syntax->ssyn_validate(csi->csi_syntax, bv);
00424                      if ( rc != LDAP_SUCCESS )
00425                             return LDAP_INVALID_SYNTAX;
00426               }
00427               if ( csi->csi_syntax->ssyn_pretty ) {
00428                      rc = csi->csi_syntax->ssyn_pretty(csi->csi_syntax, bv, &prettied , NULL );
00429                      if ( rc != LDAP_SUCCESS )
00430                             return LDAP_INVALID_SYNTAX;
00431 #if 0
00432                      free ( bv->bv_val );/*potential memory leak?*/
00433 #endif
00434                      bv->bv_val = prettied.bv_val;
00435                      bv->bv_len = prettied.bv_len;
00436               }
00437        }
00438 
00439        return LDAP_SUCCESS;
00440 }
00441 
00442 /*
00443  * If <all> type component referenced is used
00444  * more than one component will be tested
00445  */
00446 #define IS_TERMINAL_COMPREF(cr) (cr->cr_curr->ci_next == NULL)
00447 int
00448 comp_test_all_components (
00449        void* attr_mem_op,
00450        void* assert_mem_op,
00451        ComponentSyntaxInfo *csi_attr,
00452        ComponentAssertion* ca )
00453 {
00454        int rc;
00455        ComponentSyntaxInfo *csi_temp = NULL, *csi_assert = NULL, *comp_elmt = NULL;
00456        ComponentReference *cr = ca->ca_comp_ref;
00457        struct berval *ca_val = &ca->ca_ma_value;
00458 
00459        switch ( cr->cr_curr->ci_type ) {
00460            case LDAP_COMPREF_ALL:
00461               if ( IS_TERMINAL_COMPREF(cr) ) {
00462                      FOR_EACH_LIST_ELMT( comp_elmt, &((ComponentList*)csi_attr)->comp_list )
00463                      {
00464                             rc = comp_test_one_component( attr_mem_op, assert_mem_op, comp_elmt, ca );
00465                             if ( rc == LDAP_COMPARE_TRUE ) {
00466                                    break;
00467                             }
00468                      }
00469               } else {
00470                      ComponentId *start_compid = ca->ca_comp_ref->cr_curr->ci_next;
00471                      FOR_EACH_LIST_ELMT( comp_elmt, &((ComponentList*)csi_attr)->comp_list )
00472                      {
00473                             cr->cr_curr = start_compid;
00474                             rc = comp_test_components ( attr_mem_op, assert_mem_op, comp_elmt, ca );
00475                             if ( rc != LDAP_COMPARE_FALSE ) {
00476                                    break;
00477                             }
00478 #if 0                       
00479                             if ( rc == LDAP_COMPARE_TRUE ) {
00480                                    break;
00481                             }
00482 #endif
00483                      }
00484               }
00485               break;
00486            case LDAP_COMPREF_CONTENT:
00487            case LDAP_COMPREF_SELECT:
00488            case LDAP_COMPREF_DEFINED:
00489            case LDAP_COMPREF_UNDEFINED:
00490            case LDAP_COMPREF_IDENTIFIER:
00491            case LDAP_COMPREF_FROM_BEGINNING:
00492            case LDAP_COMPREF_FROM_END:
00493            case LDAP_COMPREF_COUNT:
00494               rc = LDAP_OPERATIONS_ERROR;
00495               break;
00496            default:
00497               rc = LDAP_OPERATIONS_ERROR;
00498        }
00499        return rc;
00500 }
00501 
00502 void
00503 eat_bv_whsp ( struct berval* in )
00504 {
00505        char* end = in->bv_val + in->bv_len;
00506         for ( ; ( *in->bv_val == ' ' ) && ( in->bv_val < end ) ; ) {
00507                 in->bv_val++;
00508         }
00509 }
00510 
00511 /*
00512  * Perform matching one referenced component against assertion
00513  * If the matching rule in a component filter is allComponentsMatch
00514  * or its derivatives the extracted component's ASN.1 specification
00515  * is applied to the assertion value as its syntax
00516  * Otherwise, the matching rule's syntax is applied to the assertion value
00517  * By RFC 3687
00518  */
00519 int
00520 comp_test_one_component (
00521        void* attr_mem_op,
00522        void* assert_mem_op,
00523        ComponentSyntaxInfo *csi_attr,
00524        ComponentAssertion *ca )
00525 {
00526        int len, rc;
00527        ComponentSyntaxInfo *csi_assert = NULL;
00528        char* oid = NULL;
00529        MatchingRule* mr = ca->ca_ma_rule;
00530 
00531        if ( mr->smr_usage & SLAP_MR_COMPONENT ) {
00532               /* If allComponentsMatch or its derivatives */
00533               if ( !ca->ca_comp_data.cd_tree ) {
00534                      comp_convert_assert_to_comp( assert_mem_op, csi_attr, &ca->ca_ma_value, &csi_assert, &len, DEC_ALLOC_MODE_0 );
00535                      ca->ca_comp_data.cd_tree = (void*)csi_assert;
00536               } else {
00537                      csi_assert = ca->ca_comp_data.cd_tree;
00538               }
00539 
00540               if ( !csi_assert )
00541                      return LDAP_PROTOCOL_ERROR;
00542 
00543               if ( strcmp( mr->smr_mrule.mr_oid, OID_ALL_COMP_MATCH ) != 0 )
00544                 {
00545                         /* allComponentMatch's derivatives */
00546                      oid =  mr->smr_mrule.mr_oid;
00547                 }
00548                         return csi_attr->csi_comp_desc->cd_all_match(
00549                                                   oid, csi_attr, csi_assert );
00550 
00551        } else {
00552               /* LDAP existing matching rules */
00553               struct berval attr_bv = BER_BVNULL;
00554               struct berval n_attr_bv = BER_BVNULL;
00555               struct berval* assert_bv = &ca->ca_ma_value;
00556               int allocated = 0;
00557               /*Attribute is converted to compatible LDAP encodings*/
00558               if ( comp_convert_asn_to_ldap( mr, csi_attr, &attr_bv, &allocated ) != LDAP_SUCCESS )
00559                      return LDAP_INAPPROPRIATE_MATCHING;
00560               /* extracted component value is not normalized */
00561               if ( ca->ca_ma_rule->smr_normalize ) {
00562                      rc = ca->ca_ma_rule->smr_normalize (
00563                             SLAP_MR_VALUE_OF_ASSERTION_SYNTAX,
00564                             NULL, ca->ca_ma_rule,
00565                             &attr_bv, &n_attr_bv, NULL );
00566                      if ( rc != LDAP_SUCCESS )
00567                             return rc;
00568                      if ( allocated && attr_bv.bv_val )
00569                             free (attr_bv.bv_val);
00570               } else {
00571                      n_attr_bv = attr_bv;
00572               }
00573 #if 0
00574               /*Assertion value is validated by MR's syntax*/
00575               if ( !ca->ca_comp_data.cd_tree ) {
00576                      ca->ca_comp_data.cd_tree = assert_bv;
00577               }
00578               else {
00579                      assert_bv = ca->ca_comp_data.cd_tree;
00580               }
00581 #endif
00582               if ( !n_attr_bv.bv_val )
00583                      return LDAP_COMPARE_FALSE;
00584               rc = csi_value_match( mr, &n_attr_bv, assert_bv );
00585               if ( n_attr_bv.bv_val )
00586                      free ( n_attr_bv.bv_val );
00587               return rc;
00588        }
00589 }
00590 
00591 int
00592 comp_test_components( void* attr_nm, void* assert_nm, ComponentSyntaxInfo* csi_attr, ComponentAssertion* ca) {
00593        char* peek_head;
00594        int mode, bytesDecoded = 0, rc;
00595        GenBuf* b;
00596        ExpBuf* buf;
00597        OidDecoderMapping* odm;
00598        struct berval bv;
00599        char oid[MAX_OID_LEN];
00600        void* contained_comp, *anytype_comp;
00601        ComponentReference* cr = ca->ca_comp_ref;
00602 
00603        if ( !cr )
00604               return comp_test_one_component ( attr_nm, assert_nm, csi_attr, ca );
00605        /* Extracting the component refrenced by ca->ca_comp_ref */
00606        csi_attr = (ComponentSyntaxInfo*)csi_attr->csi_comp_desc->cd_extract_i( attr_nm, cr, csi_attr );
00607        if ( !csi_attr ) return LDAP_INVALID_SYNTAX;
00608        /* perform matching, considering the type of a Component Reference(CR)*/
00609        switch( cr->cr_curr->ci_type ) {
00610           case LDAP_COMPREF_IDENTIFIER:
00611           case LDAP_COMPREF_FROM_BEGINNING:
00612           case LDAP_COMPREF_FROM_END:
00613           case LDAP_COMPREF_COUNT:
00614               /*
00615                * Exactly one component is referenced
00616                * Fast Path for matching for this case
00617                */
00618               rc = comp_test_one_component ( attr_nm, assert_nm, csi_attr, ca );
00619               break;
00620           case LDAP_COMPREF_ALL:
00621               /*
00622                * If <all> type CR is used
00623                * more than one component will be tested
00624                */
00625               rc = comp_test_all_components ( attr_nm, assert_nm, csi_attr, ca );
00626               break;
00627 
00628           case LDAP_COMPREF_CONTENT:
00629               /*
00630                * <content> type CR is used
00631                * check if it is followed by <select> type CR.
00632                * 1) If so, look up the corresponding decoder  in the mapping
00633                * table(OID to decoder) by <select>
00634                * and then decode the OCTET/BIT STRING with the decoder
00635                * Finially, extreact the target component with the remaining CR.
00636                * 2) If not, just return the current component, It SHOULD not be
00637                * extracted further, because the component MUST be BIT/OCTET
00638                  * string.
00639                  */
00640 
00641               cr->cr_curr = cr->cr_curr->ci_next;
00642               if ( !cr->cr_curr ) {
00643                      /* case 2) in above description */
00644                      rc = comp_test_one_component ( attr_nm, assert_nm, csi_attr, ca );
00645                      break;
00646               }
00647 
00648               if ( cr->cr_curr->ci_type == LDAP_COMPREF_SELECT ) {
00649                      /* Look up OID mapping table */    
00650                      odm = RetrieveOidDecoderMappingbyBV( &cr->cr_curr->ci_val.ci_select_value );
00651                      
00652                      if ( !odm || !odm->BER_Decode )
00653                             return  LDAP_PROTOCOL_ERROR;
00654 
00655                      /* current componet MUST be either BIT or OCTET STRING */
00656                      if ( csi_attr->csi_comp_desc->cd_type_id != BASICTYPE_BITSTRING ) {
00657                             bv.bv_val = ((ComponentBits*)csi_attr)->value.bits;
00658                             bv.bv_len = ((ComponentBits*)csi_attr)->value.bitLen;
00659                      }
00660                      else if ( csi_attr->csi_comp_desc->cd_type_id != BASICTYPE_BITSTRING ) {
00661                             bv.bv_val = ((ComponentOcts*)csi_attr)->value.octs;
00662                             bv.bv_len = ((ComponentOcts*)csi_attr)->value.octetLen;
00663                      }
00664                      else
00665                             return LDAP_PROTOCOL_ERROR;
00666 
00667                      buf = ExpBufAllocBuf();
00668                      ExpBuftoGenBuf( buf, &b );
00669                      ExpBufInstallDataInBuf ( buf, bv.bv_val, bv.bv_len );
00670                      BufResetInReadMode( b );
00671                      mode = DEC_ALLOC_MODE_2;
00672 
00673                      /* Try to decode with BER/DER decoder */
00674                      rc = odm->BER_Decode ( attr_nm, b, (ComponentSyntaxInfo*)&contained_comp, &bytesDecoded, mode );
00675 
00676                      ExpBufFreeBuf( buf );
00677                      GenBufFreeBuf( b );
00678 
00679                      if ( rc != LDAP_SUCCESS ) return LDAP_PROTOCOL_ERROR;
00680 
00681                      /* xxx.content.(x.xy.xyz).rfc822Name */
00682                      /* In the aboe Ex. move CR to the right to (x.xy.xyz)*/
00683                      cr->cr_curr = cr->cr_curr->ci_next;
00684                      if (!cr->cr_curr )
00685                             rc = comp_test_one_component ( attr_nm, assert_nm, csi_attr, ca );
00686                      else
00687                             rc = comp_test_components( attr_nm, assert_nm, contained_comp, ca );
00688               }
00689               else {
00690                      /* Ivalid Component reference */
00691                      rc = LDAP_PROTOCOL_ERROR;
00692               }
00693               break;
00694           case LDAP_COMPREF_SELECT:
00695               if (csi_attr->csi_comp_desc->cd_type_id != BASICTYPE_ANY )
00696                      return LDAP_INVALID_SYNTAX;
00697               rc = CheckSelectTypeCorrect( attr_nm, ((ComponentAny*)csi_attr)->cai, &cr->cr_curr->ci_val.ci_select_value );
00698               if ( rc < 0 ) return LDAP_INVALID_SYNTAX;
00699 
00700               /* point to the real component, not any type component */
00701               csi_attr = ((ComponentAny*)csi_attr)->value;
00702               cr->cr_curr = cr->cr_curr->ci_next;
00703               if ( cr->cr_curr )
00704                      rc =  comp_test_components( attr_nm, assert_nm, csi_attr, ca);
00705               else
00706                      rc =  comp_test_one_component( attr_nm, assert_nm, csi_attr, ca);
00707               break;
00708           default:
00709               rc = LDAP_INVALID_SYNTAX;
00710        }
00711        return rc;
00712 }
00713 
00714 
00715 void*
00716 comp_nibble_memory_allocator ( int init_mem, int inc_mem ) {
00717        void* nm;
00718        nm = (void*)InitNibbleMemLocal( (unsigned long)init_mem, (unsigned long)inc_mem );
00719        if ( !nm ) return NULL;
00720        else return (void*)nm;
00721 }
00722 
00723 void
00724 comp_nibble_memory_free ( void* nm ) {
00725        ShutdownNibbleMemLocal( nm );
00726 }
00727 
00728 void*
00729 comp_get_component_description ( int id ) {
00730        if ( asntype_to_compdesc_mapping_tbl[id].atcd_typeId == id )
00731               return &asntype_to_compdesc_mapping_tbl[id].atcd_cd;
00732        else
00733               return NULL;
00734 }
00735 
00736 int
00737 comp_component_encoder ( void* mem_op, ComponentSyntaxInfo* csi , struct berval* nval ) {
00738         int size, rc;
00739         GenBuf* b;
00740         ExpBuf* buf;
00741        struct berval bv;
00742        
00743        buf = ExpBufAllocBufAndData();
00744        ExpBufResetInWriteRvsMode(buf);
00745        ExpBuftoGenBuf( buf, &b );
00746 
00747        if ( !csi->csi_comp_desc->cd_gser_encoder && !csi->csi_comp_desc->cd_ldap_encoder )
00748               return (-1);
00749 
00750        /*
00751         * if an LDAP specific encoder is provided :
00752         * dn and rdn have their LDAP specific encoder
00753         */
00754        if ( csi->csi_comp_desc->cd_ldap_encoder ) {
00755               rc = csi->csi_comp_desc->cd_ldap_encoder( csi, &bv );
00756               if ( rc != LDAP_SUCCESS )
00757                      return rc;
00758               if ( mem_op )
00759                      nval->bv_val = CompAlloc( mem_op, bv.bv_len );
00760               else
00761                      nval->bv_val = malloc( size );
00762               memcpy( nval->bv_val, bv.bv_val, bv.bv_len );
00763               nval->bv_len = bv.bv_len;
00764               /*
00765                * This free will be eliminated by making ldap_encoder
00766                * use nibble memory in it 
00767                */
00768               free ( bv.bv_val );
00769               GenBufFreeBuf( b );
00770               BufFreeBuf( buf );
00771               return LDAP_SUCCESS;
00772        }
00773 
00774        rc = csi->csi_comp_desc->cd_gser_encoder( b, csi );
00775        if ( rc < 0 ) {
00776               GenBufFreeBuf( b );
00777               BufFreeBuf( buf );
00778               return rc;
00779        }
00780 
00781        size = ExpBufDataSize( buf );
00782        if ( size > 0 ) {
00783               if ( mem_op )
00784                      nval->bv_val = CompAlloc ( mem_op, size );
00785               else
00786                      nval->bv_val = malloc( size );
00787               nval->bv_len = size;
00788               BufResetInReadMode(b);
00789               BufCopy( nval->bv_val, b, size );
00790        }
00791        ExpBufFreeBuf( buf );
00792        GenBufFreeBuf( b );
00793 
00794        return LDAP_SUCCESS;
00795 }
00796 
00797 #if SLAPD_COMP_MATCH == SLAPD_MOD_DYNAMIC
00798 
00799 #include "certificate.h"
00800 
00801 extern convert_attr_to_comp_func* attr_converter;
00802 extern convert_assert_to_comp_func* assert_converter;
00803 extern convert_asn_to_ldap_func* csi_converter;
00804 extern free_component_func* component_destructor;
00805 extern test_component_func* test_components;
00806 extern alloc_nibble_func* nibble_mem_allocator;
00807 extern free_nibble_func* nibble_mem_free;
00808 extern test_membership_func* is_aliased_attribute;
00809 extern get_component_info_func* get_component_description;
00810 extern component_encoder_func* component_encoder;
00811 
00812 
00813 int init_module(int argc, char *argv[]) {
00814        /*
00815         * Initialize function pointers in slapd
00816         */
00817        attr_converter = (convert_attr_to_comp_func*)comp_convert_attr_to_comp;
00818        assert_converter = (convert_assert_to_comp_func*)comp_convert_assert_to_comp;
00819        component_destructor = (free_component_func*)comp_free_component;
00820        test_components = (test_component_func*)comp_test_components;
00821        nibble_mem_allocator = (free_nibble_func*)comp_nibble_memory_allocator;
00822        nibble_mem_free = (free_nibble_func*)comp_nibble_memory_free;
00823        is_aliased_attribute = (test_membership_func*)comp_is_aliased_attribute;
00824        get_component_description = (get_component_info_func*)comp_get_component_description;
00825        component_encoder = (component_encoder_func*)comp_component_encoder;
00826 
00827        /* file path needs to be */
00828        load_derived_matching_rule ("derived_mr.cfg");
00829 
00830        /* the initialization for example X.509 certificate */
00831        init_module_AuthenticationFramework();
00832        init_module_AuthorityKeyIdentifierDefinition();
00833        init_module_CertificateRevokationList();
00834        init_attribute_aliasing_table ();
00835        init_component_description_table ();
00836        return 0;
00837 }
00838 
00839 #endif /* SLAPD_PASSWD */