]> git.sur5r.net Git - openldap/blob - contrib/slapd-modules/comp_match/init.c
Fix memory leak in a component encoder
[openldap] / contrib / slapd-modules / comp_match / init.c
1 /* Copyright 2004 IBM Corporation
2  * All rights reserved.
3  * Redisribution and use in source and binary forms, with or without
4  * modification, are permitted only as authorizd by the OpenLADP
5  * Public License.
6  */
7 /* ACKNOWLEDGEMENTS
8  * This work originally developed by Sang Seok Lim
9  * 2004/06/18   03:20:00        slim@OpenLDAP.org
10  */
11
12 #include "portable.h"
13 #include <ac/string.h>
14 #include <ac/socket.h>
15 #include <ldap_pvt.h>
16 #include "lutil.h"
17 #include <ldap.h>
18 #include "slap.h"
19 #include "component.h"
20
21 #include "componentlib.h"
22 #include "asn.h"
23 #include <asn-gser.h>
24
25 #include <string.h>
26
27 #ifndef SLAPD_COMP_MATCH
28 #define SLAPD_COMP_MATCH SLAPD_MOD_DYNAMIC
29 #endif
30
31 /*
32  * Attribute and MatchingRule aliasing table
33  */
34 AttributeAliasing aa_table [ MAX_ALIASING_ENTRY ];
35 MatchingRuleAliasing mra_table [ MAX_ALIASING_ENTRY ];
36
37 OD_entry* gOD_table = NULL;
38 AsnTypetoMatchingRuleTable* gATMR_table = NULL;
39
40 int
41 load_derived_matching_rule ( char* cfg_path ){
42 }
43
44 AttributeAliasing*
45 comp_is_aliased_attribute( void *in  )
46 {
47         AttributeAliasing* curr_aa;
48         int i;
49         AttributeDescription *ad = (AttributeDescription*)in;
50
51         for ( i = 0; aa_table[i].aa_aliasing_ad && i < MAX_ALIASING_ENTRY; i++ ) {
52                 if ( strncmp(aa_table[i].aa_aliasing_ad->ad_cname.bv_val , ad->ad_cname.bv_val, ad->ad_cname.bv_len) == 0 )
53                         return &aa_table[i];
54         }
55         return NULL;
56 }
57
58 static int
59 add_aa_entry( int index, char* aliasing_at_name, char* aliased_at_name, char* mr_name, char* component_filter )
60 {
61         char text[1][128];
62         int rc;
63         struct berval type;
64
65         /* get and store aliasing AttributeDescription */
66         type.bv_val = aliasing_at_name;
67         type.bv_len = strlen ( aliasing_at_name );
68         rc = slap_bv2ad ( &type, &aa_table[index].aa_aliasing_ad,(const char**)text );
69         if ( rc != LDAP_SUCCESS ) return rc;
70
71         /* get and store aliased AttributeDescription */
72         type.bv_val = aliased_at_name;
73         type.bv_len = strlen ( aliased_at_name );
74         rc = slap_bv2ad ( &type, &aa_table[index].aa_aliased_ad,(const char**)text );
75         if ( rc != LDAP_SUCCESS ) return rc;
76
77         /* get and store componentFilterMatch */
78         type.bv_val = mr_name;
79         type.bv_len = strlen ( mr_name);
80         aa_table[index].aa_mr = mr_bvfind ( &type );
81
82         /* get and store a component filter */
83         type.bv_val = component_filter;
84         type.bv_len = strlen ( component_filter );
85         rc = get_comp_filter( NULL, &type, &aa_table[index].aa_cf,(const char**)text);
86
87         aa_table[index].aa_cf_str = component_filter;
88
89         return rc;
90 }
91
92 /*
93  * Initialize attribute aliasing table when this module is loaded
94  * add_aa_entry ( index for the global table,
95  *                name of the aliasing attribute,
96  *                component filter with filling value parts "xxx"
97  *              )
98  * "xxx" will be replaced with effective values later.
99  * See RFC3687 to understand the content of a component filter.
100  */
101 char* pre_processed_comp_filter[] = {
102 /*1*/"item:{ component \"toBeSigned.issuer.rdnSequence\", rule distinguishedNameMatch, value xxx }",
103 /*2*/"item:{ component \"toBeSigned.serialNumber\", rule integerMatch, value xxx }",
104 /*3*/"and:{ item:{ component \"toBeSigned.serialNumber\", rule integerMatch, value xxx }, item:{ component \"toBeSigned.issuer.rdnSequence\", rule distinguishedNameMatch, value xxx } }"
105 };
106
107 static int
108 init_attribute_aliasing_table ()
109 {
110         int rc;
111         int index = 0 ;
112
113         rc = add_aa_entry ( index, "x509CertificateIssuer", "userCertificate","componentFilterMatch", pre_processed_comp_filter[index] );
114         if ( rc != LDAP_SUCCESS ) return LDAP_PARAM_ERROR;
115         index++;
116
117         rc = add_aa_entry ( index, "x509CertificateSerial","userCertificate", "componentFilterMatch", pre_processed_comp_filter[index] );
118         if ( rc != LDAP_SUCCESS ) return LDAP_PARAM_ERROR;
119         index++;
120
121         rc = add_aa_entry ( index, "x509CertificateSerialAndIssuer", "userCertificate", "componentFilterMatch", pre_processed_comp_filter[index] );
122         if ( rc != LDAP_SUCCESS ) return LDAP_PARAM_ERROR;
123         index++;
124
125         return LDAP_SUCCESS;
126 }
127
128 void
129 init_component_description_table () {
130         AsnTypeId id;
131         struct berval mr;
132         AsnTypetoSyntax* asn_to_syn;
133         Syntax* syn;
134
135         for ( id = BASICTYPE_BOOLEAN; id != ASNTYPE_END ; id++ ) {
136                 asntype_to_compType_mapping_tbl[id].ac_comp_type.ct_subtypes = NULL;
137                 asntype_to_compType_mapping_tbl[id].ac_comp_type.ct_syntax =  NULL;
138
139                 /* Equality Matching Rule */
140                 if ( asntype_to_compMR_mapping_tbl[id].atc_equality ) {
141                         mr.bv_val = asntype_to_compMR_mapping_tbl[id].atc_equality;
142                         mr.bv_len = strlen(asntype_to_compMR_mapping_tbl[id].atc_equality);
143                         asntype_to_compType_mapping_tbl[id].ac_comp_type.ct_equality = mr_bvfind( &mr );
144                 }
145                 /* Approx Matching Rule */
146                 if ( asntype_to_compMR_mapping_tbl[id].atc_approx ) {
147                         mr.bv_val = asntype_to_compMR_mapping_tbl[id].atc_approx;
148                         mr.bv_len = strlen(asntype_to_compMR_mapping_tbl[id].atc_approx);
149                         asntype_to_compType_mapping_tbl[id].ac_comp_type.ct_approx = mr_bvfind( &mr );
150                 }
151
152                 /* Ordering Matching Rule */
153                 if ( asntype_to_compMR_mapping_tbl[id].atc_ordering ) {
154                         mr.bv_val = asntype_to_compMR_mapping_tbl[id].atc_ordering;
155                         mr.bv_len = strlen(asntype_to_compMR_mapping_tbl[id].atc_ordering);
156                         asntype_to_compType_mapping_tbl[id].ac_comp_type.ct_ordering= mr_bvfind( &mr );
157                 }
158
159                 /* Substr Matching Rule */
160                 if ( asntype_to_compMR_mapping_tbl[id].atc_substr ) {
161                         mr.bv_val = asntype_to_compMR_mapping_tbl[id].atc_substr;
162                         mr.bv_len = strlen(asntype_to_compMR_mapping_tbl[id].atc_substr);
163                         asntype_to_compType_mapping_tbl[id].ac_comp_type.ct_substr = mr_bvfind( &mr );
164                 }
165                 /* Syntax */
166
167                 asn_to_syn = &asn_to_syntax_mapping_tbl[ id ];
168                 if ( asn_to_syn->ats_syn_oid )
169                         syn = syn_find ( asn_to_syn->ats_syn_oid );
170                 else 
171                         syn = NULL;
172                 asntype_to_compType_mapping_tbl[id].ac_comp_type.ct_syntax = syn;
173
174                 /* Initialize Component Descriptions of primitive ASN.1 types */
175                 asntype_to_compdesc_mapping_tbl[id].atcd_cd.cd_comp_type = (AttributeType*)&asntype_to_compType_mapping_tbl[id].ac_comp_type;
176         }
177 }
178
179 MatchingRule*
180 retrieve_matching_rule( char* mr_oid, AsnTypeId type ) {
181         char* tmp;
182         struct berval mr_name = BER_BVNULL;
183         AsnTypetoMatchingRuleTable* atmr;
184
185         for ( atmr = gATMR_table ; atmr ; atmr = atmr->atmr_table_next ) {
186                 if ( strcmp( atmr->atmr_oid, mr_oid ) == 0 ) {
187                         tmp = atmr->atmr_table[type].atmr_mr_name;
188                         if ( tmp ) {
189                                 mr_name.bv_val = tmp;
190                                 mr_name.bv_len = strlen( tmp );
191                                 return mr_bvfind ( &mr_name );
192                         }
193                 }
194         }
195         return (MatchingRule*)NULL;
196 }
197
198 void* 
199 comp_convert_attr_to_comp LDAP_P (( Attribute* a, Syntax *syn, struct berval* bv ))
200 {
201         char* peek_head;
202         int mode, bytesDecoded, size, rc;
203         void* component;
204         char* oid = a->a_desc->ad_type->sat_atype.at_oid ;
205         GenBuf* b = NULL;
206         ExpBuf* buf = NULL;
207         OidDecoderMapping* odm;
208         
209         /* look for the decoder registered for the given attribute */
210         odm = RetrieveOidDecoderMappingbyOid( oid, strlen(oid) );
211
212         if ( !odm || (!odm->BER_Decode && !odm->GSER_Decode) )
213                 return (void*)NULL;
214
215         buf = ExpBufAllocBuf();
216         ExpBuftoGenBuf( buf, &b );
217         ExpBufInstallDataInBuf ( buf, bv->bv_val, bv->bv_len );
218         BufResetInReadMode( b );
219
220         mode = DEC_ALLOC_MODE_2;
221         /*
222          * How can we decide which decoder will be called, GSER or BER?
223          * Currently BER decoder is called for a certificate.
224          * The flag of Attribute will say something about it in the future
225          */
226         if ( syn && slap_syntax_is_ber ( syn ) ) {
227 #if 0
228                 rc =BDecComponentTop(odm->BER_Decode, a->a_comp_data->cd_mem_op, b, 0,0, &component,&bytesDecoded,mode ) ;
229 #endif
230                 rc = odm->BER_Decode ( a->a_comp_data->cd_mem_op, b, (ComponentSyntaxInfo*)&component, &bytesDecoded, mode );
231         }
232         else {
233                 rc = odm->GSER_Decode( a->a_comp_data->cd_mem_op, b, (ComponentSyntaxInfo**)component, &bytesDecoded, mode);
234         }
235
236         ExpBufFreeBuf( buf );
237         GenBufFreeBuf( b );
238         if ( rc == -1 ) {
239                 ShutdownNibbleMemLocal ( a->a_comp_data->cd_mem_op );
240                 free ( a->a_comp_data );
241                 a->a_comp_data = NULL;
242                 return (void*)NULL;
243         }
244         else {
245                 return component;
246         }
247 }
248
249 #include <nibble-alloc.h>
250 void
251 comp_free_component ( void* mem_op ) {
252         ShutdownNibbleMemLocal( (NibbleMem*)mem_op );
253         return;
254 }
255
256 void
257 comp_convert_assert_to_comp (
258         void* mem_op,
259         ComponentSyntaxInfo *csi_attr,
260         struct berval* bv,
261         ComponentSyntaxInfo** csi, int* len, int mode )
262 {
263         int rc;
264         GenBuf* genBuf;
265         ExpBuf* buf;
266         gser_decoder_func *decoder = csi_attr->csi_comp_desc->cd_gser_decoder;
267
268         buf = ExpBufAllocBuf();
269         ExpBuftoGenBuf( buf, &genBuf );
270         ExpBufInstallDataInBuf ( buf, bv->bv_val, bv->bv_len );
271         BufResetInReadMode( genBuf );
272
273         if ( csi_attr->csi_comp_desc->cd_type_id == BASICTYPE_ANY )
274                 decoder = ((ComponentAny*)csi_attr)->cai->GSER_Decode;
275
276         rc = (*decoder)( mem_op, genBuf, csi, len, mode );
277         ExpBufFreeBuf ( buf );
278         GenBufFreeBuf( genBuf );
279 }
280
281 int intToAscii( int value, char* buf ) {
282         int minus=0,i,temp;
283         int total_num_digits;
284
285         if ( value == 0 ){
286                 buf[0] = '0';
287                 return 1;
288         }
289
290         if ( value < 0 ){
291                 minus = 1;
292                 value = value*(-1);
293                 buf[0] = '-';
294         }
295         
296         /* How many digits */
297         for ( temp = value, total_num_digits=0 ; temp ; total_num_digits++ )
298                 temp = temp/10;
299
300         total_num_digits += minus;
301
302         for ( i = minus ; value ; i++ ) {
303                 buf[ total_num_digits - i - 1 ]= (char)(value%10 + '0');
304                 value = value/10;
305         }
306         return i;
307 }
308
309 int
310 comp_convert_asn_to_ldap ( MatchingRule* mr, ComponentSyntaxInfo* csi, struct berval* bv, int *allocated )
311 {
312         int rc;
313         struct berval prettied;
314         Syntax* syn;
315
316         AsnTypetoSyntax* asn_to_syn =
317                 &asn_to_syntax_mapping_tbl[csi->csi_comp_desc->cd_type_id];
318         if ( asn_to_syn->ats_syn_oid )
319                 csi->csi_syntax = syn_find ( asn_to_syn->ats_syn_oid );
320         else 
321                 csi->csi_syntax = NULL;
322
323
324         switch ( csi->csi_comp_desc->cd_type_id ) {
325           case BASICTYPE_BOOLEAN :
326                 bv->bv_val = (char*)malloc( 5 );
327                 *allocated = 1;
328                 bv->bv_len = 5;
329                 if ( ((ComponentBool*)csi)->value > 0 ) {
330                         strcpy ( bv->bv_val , "TRUE" );
331                         bv->bv_len = 4;
332                 }
333                 else {
334                         strcpy ( bv->bv_val , "FALSE" );
335                         bv->bv_len = 5;
336                 }
337                 break ;
338           case BASICTYPE_NULL :
339                 bv->bv_len = 0;
340                 break;
341           case BASICTYPE_INTEGER :
342                 bv->bv_val = (char*)malloc( INITIAL_ATTR_SIZE );
343                 *allocated = 1;
344                 bv->bv_len = INITIAL_ATTR_SIZE;
345                 bv->bv_len = intToAscii(((ComponentInt*)csi)->value, bv->bv_val );
346                 if ( bv->bv_len <= 0 )
347                         return LDAP_INVALID_SYNTAX;
348                 break;
349           case BASICTYPE_REAL :
350                 return LDAP_INVALID_SYNTAX;
351           case BASICTYPE_ENUMERATED :
352                 bv->bv_val = (char*)malloc( INITIAL_ATTR_SIZE );
353                 *allocated = 1;
354                 bv->bv_len = INITIAL_ATTR_SIZE;
355                 bv->bv_len = intToAscii(((ComponentEnum*)csi)->value, bv->bv_val );
356                 if ( bv->bv_len <= 0 )
357                         return LDAP_INVALID_SYNTAX;
358                 break;
359           case BASICTYPE_OID :
360           case BASICTYPE_OCTETSTRING :
361           case BASICTYPE_BITSTRING :
362           case BASICTYPE_NUMERIC_STR :
363           case BASICTYPE_PRINTABLE_STR :
364           case BASICTYPE_UNIVERSAL_STR :
365           case BASICTYPE_IA5_STR :
366           case BASICTYPE_BMP_STR :
367           case BASICTYPE_UTF8_STR :
368           case BASICTYPE_UTCTIME :
369           case BASICTYPE_GENERALIZEDTIME :
370           case BASICTYPE_GRAPHIC_STR :
371           case BASICTYPE_VISIBLE_STR :
372           case BASICTYPE_GENERAL_STR :
373           case BASICTYPE_OBJECTDESCRIPTOR :
374           case BASICTYPE_VIDEOTEX_STR :
375           case BASICTYPE_T61_STR :
376           case BASICTYPE_OCTETCONTAINING :
377           case BASICTYPE_BITCONTAINING :
378           case BASICTYPE_RELATIVE_OID :
379                 bv->bv_val = ((ComponentOcts*)csi)->value.octs;
380                 bv->bv_len = ((ComponentOcts*)csi)->value.octetLen;
381                 break;
382           case BASICTYPE_ANY :
383                 csi = ((ComponentAny*)csi)->value;
384                 if ( csi->csi_comp_desc->cd_type != ASN_BASIC ||
385                         csi->csi_comp_desc->cd_type_id == BASICTYPE_ANY )
386                         return LDAP_INVALID_SYNTAX;
387                 return comp_convert_asn_to_ldap( mr, csi, bv, allocated );
388           case COMPOSITE_ASN1_TYPE :
389                 break;
390           case RDNSequence :
391                 /*dnMatch*/
392                 if( strncmp( mr->smr_mrule.mr_oid, DN_MATCH_OID, strlen(DN_MATCH_OID) ) != 0 )
393                         return LDAP_INVALID_SYNTAX;
394                 *allocated = 1;
395                 rc = ConvertRDNSequence2RFC2253( (irRDNSequence*)csi, bv );
396                 if ( rc != LDAP_SUCCESS ) return rc;
397                 break;
398           case RelativeDistinguishedName :
399                 /*rdnMatch*/
400                 if( strncmp( mr->smr_mrule.mr_oid, RDN_MATCH_OID, strlen(RDN_MATCH_OID) ) != 0 )
401                         return LDAP_INVALID_SYNTAX;
402                 *allocated = 1;
403                 rc = ConvertRDN2RFC2253((irRelativeDistinguishedName*)csi,bv);
404                 if ( rc != LDAP_SUCCESS ) return rc;
405                 break;
406           case TelephoneNumber :
407           case FacsimileTelephoneNumber__telephoneNumber :
408                 break;
409           case DirectoryString :
410                 return LDAP_INVALID_SYNTAX;
411           case ASN_COMP_CERTIFICATE :
412           case ASNTYPE_END :
413                 break;
414           default :
415                 /*Only ASN Basic Type can be converted into LDAP string*/
416                 return LDAP_INVALID_SYNTAX;
417         }
418
419         if ( csi->csi_syntax ) {
420                 if ( csi->csi_syntax->ssyn_validate ) {
421                         rc = csi->csi_syntax->ssyn_validate(csi->csi_syntax, bv);
422                         if ( rc != LDAP_SUCCESS )
423                                 return LDAP_INVALID_SYNTAX;
424                 }
425                 if ( csi->csi_syntax->ssyn_pretty ) {
426                         rc = csi->csi_syntax->ssyn_pretty(csi->csi_syntax, bv, &prettied , NULL );
427                         if ( rc != LDAP_SUCCESS )
428                                 return LDAP_INVALID_SYNTAX;
429 #if 0
430                         free ( bv->bv_val );/*potential memory leak?*/
431 #endif
432                         bv->bv_val = prettied.bv_val;
433                         bv->bv_len = prettied.bv_len;
434                 }
435         }
436
437         return LDAP_SUCCESS;
438 }
439
440 /*
441  * If <all> type component referenced is used
442  * more than one component will be tested
443  */
444 #define IS_TERMINAL_COMPREF(cr) (cr->cr_curr->ci_next == NULL)
445 int
446 comp_test_all_components (
447         void* attr_mem_op,
448         void* assert_mem_op,
449         ComponentSyntaxInfo *csi_attr,
450         ComponentAssertion* ca )
451 {
452         int rc;
453         ComponentSyntaxInfo *csi_temp = NULL, *csi_assert = NULL, *comp_elmt = NULL;
454         ComponentReference *cr = ca->ca_comp_ref;
455         struct berval *ca_val = &ca->ca_ma_value;
456
457         switch ( cr->cr_curr->ci_type ) {
458             case LDAP_COMPREF_ALL:
459                 if ( IS_TERMINAL_COMPREF(cr) ) {
460                         FOR_EACH_LIST_ELMT( comp_elmt, &((ComponentList*)csi_attr)->comp_list )
461                         {
462                                 rc = comp_test_one_component( attr_mem_op, assert_mem_op, comp_elmt, ca );
463                                 if ( rc == LDAP_COMPARE_TRUE ) {
464                                         break;
465                                 }
466                         }
467                 } else {
468                         ComponentId *start_compid = ca->ca_comp_ref->cr_curr->ci_next;
469                         FOR_EACH_LIST_ELMT( comp_elmt, &((ComponentList*)csi_attr)->comp_list )
470                         {
471                                 cr->cr_curr = start_compid;
472                                 rc = comp_test_components ( attr_mem_op, assert_mem_op, comp_elmt, ca );
473                                 
474                                 if ( rc == LDAP_COMPARE_TRUE ) {
475                                         break;
476                                 }
477                         }
478                 }
479                 break;
480             case LDAP_COMPREF_CONTENT:
481             case LDAP_COMPREF_SELECT:
482             case LDAP_COMPREF_DEFINED:
483             case LDAP_COMPREF_UNDEFINED:
484             case LDAP_COMPREF_IDENTIFIER:
485             case LDAP_COMPREF_FROM_BEGINNING:
486             case LDAP_COMPREF_FROM_END:
487             case LDAP_COMPREF_COUNT:
488                 rc = LDAP_OPERATIONS_ERROR;
489                 break;
490             default:
491                 rc = LDAP_OPERATIONS_ERROR;
492         }
493         return rc;
494 }
495
496 void
497 eat_bv_whsp ( struct berval* in )
498 {
499         char* end = in->bv_val + in->bv_len;
500         for ( ; ( *in->bv_val == ' ' ) && ( in->bv_val < end ) ; ) {
501                 in->bv_val++;
502         }
503 }
504
505 /*
506  * Perform matching one referenced component against assertion
507  * If the matching rule in a component filter is allComponentsMatch
508  * or its derivatives the extracted component's ASN.1 specification
509  * is applied to the assertion value as its syntax
510  * Otherwise, the matching rule's syntax is applied to the assertion value
511  * By RFC 3687
512  */
513 int
514 comp_test_one_component (
515         void* attr_mem_op,
516         void* assert_mem_op,
517         ComponentSyntaxInfo *csi_attr,
518         ComponentAssertion *ca )
519 {
520         int len, rc;
521         ComponentSyntaxInfo *csi_assert = NULL;
522         char* oid = NULL;
523         MatchingRule* mr = ca->ca_ma_rule;
524
525         if ( mr->smr_usage & SLAP_MR_COMPONENT ) {
526                 /* If allComponentsMatch or its derivatives */
527                 if ( !ca->ca_comp_data.cd_tree ) {
528                         comp_convert_assert_to_comp( assert_mem_op, csi_attr, &ca->ca_ma_value, &csi_assert, &len, DEC_ALLOC_MODE_0 );
529                         ca->ca_comp_data.cd_tree = (void*)csi_assert;
530                 } else {
531                         csi_assert = ca->ca_comp_data.cd_tree;
532                 }
533
534                 if ( !csi_assert )
535                         return LDAP_PROTOCOL_ERROR;
536
537                 if ( strcmp( mr->smr_mrule.mr_oid, OID_ALL_COMP_MATCH ) != 0 )
538                 {
539                         /* allComponentMatch's derivatives */
540                         oid =  mr->smr_mrule.mr_oid;
541                 }
542                         return csi_attr->csi_comp_desc->cd_all_match(
543                                                  oid, csi_attr, csi_assert );
544
545         } else {
546                 /* LDAP existing matching rules */
547                 struct berval attr_bv = BER_BVNULL;
548                 struct berval n_attr_bv = BER_BVNULL;
549                 struct berval* assert_bv = &ca->ca_ma_value;
550                 int allocated = 0;
551                 /*Attribute is converted to compatible LDAP encodings*/
552                 if ( comp_convert_asn_to_ldap( mr, csi_attr, &attr_bv, &allocated ) != LDAP_SUCCESS )
553                         return LDAP_INAPPROPRIATE_MATCHING;
554                 /* extracted component value is not normalized */
555                 if ( ca->ca_ma_rule->smr_normalize ) {
556                         rc = ca->ca_ma_rule->smr_normalize (
557                                 SLAP_MR_VALUE_OF_ASSERTION_SYNTAX,
558                                 NULL, ca->ca_ma_rule,
559                                 &attr_bv, &n_attr_bv, NULL );
560                         if ( rc != LDAP_SUCCESS )
561                                 return rc;
562                         if ( allocated && attr_bv.bv_val )
563                                 free (attr_bv.bv_val);
564                 } else {
565                         n_attr_bv = attr_bv;
566                 }
567 #if 0
568                 /*Assertion value is validated by MR's syntax*/
569                 if ( !ca->ca_comp_data.cd_tree ) {
570                         ca->ca_comp_data.cd_tree = assert_bv;
571                 }
572                 else {
573                         assert_bv = ca->ca_comp_data.cd_tree;
574                 }
575 #endif
576                 if ( !n_attr_bv.bv_val )
577                         return LDAP_COMPARE_FALSE;
578                 rc = csi_value_match( mr, &n_attr_bv, assert_bv );
579                 if ( n_attr_bv.bv_val )
580                         free ( n_attr_bv.bv_val );
581                 return rc;
582         }
583 }
584
585 int
586 comp_test_components( void* attr_nm, void* assert_nm, ComponentSyntaxInfo* csi_attr, ComponentAssertion* ca) {
587         char* peek_head;
588         int mode, bytesDecoded = 0, rc;
589         GenBuf* b;
590         ExpBuf* buf;
591         OidDecoderMapping* odm;
592         struct berval bv;
593         char oid[MAX_OID_LEN];
594         void* contained_comp, *anytype_comp;
595         ComponentReference* cr = ca->ca_comp_ref;
596
597         if ( !cr )
598                 return comp_test_one_component ( attr_nm, assert_nm, csi_attr, ca );
599         /* Extracting the component refrenced by ca->ca_comp_ref */
600         csi_attr = (ComponentSyntaxInfo*)csi_attr->csi_comp_desc->cd_extract_i( attr_nm, cr, csi_attr );
601         if ( !csi_attr ) return LDAP_INVALID_SYNTAX;
602         /* perform matching, considering the type of a Component Reference(CR)*/
603         switch( cr->cr_curr->ci_type ) {
604            case LDAP_COMPREF_IDENTIFIER:
605            case LDAP_COMPREF_FROM_BEGINNING:
606            case LDAP_COMPREF_FROM_END:
607            case LDAP_COMPREF_COUNT:
608                 /*
609                  * Exactly one component is referenced
610                  * Fast Path for matching for this case
611                  */
612                 rc = comp_test_one_component ( attr_nm, assert_nm, csi_attr, ca );
613                 break;
614            case LDAP_COMPREF_ALL:
615                 /*
616                  * If <all> type CR is used
617                  * more than one component will be tested
618                  */
619                 rc = comp_test_all_components ( attr_nm, assert_nm, csi_attr, ca );
620                 break;
621
622            case LDAP_COMPREF_CONTENT:
623                 /*
624                  * <content> type CR is used
625                  * check if it is followed by <select> type CR.
626                  * 1) If so, look up the corresponding decoder  in the mapping
627                  * table(OID to decoder) by <select>
628                  * and then decode the OCTET/BIT STRING with the decoder
629                  * Finially, extreact the target component with the remaining CR.
630                  * 2) If not, just return the current component, It SHOULD not be
631                  * extracted further, because the component MUST be BIT/OCTET
632                  * string.
633                  */
634
635                 cr->cr_curr = cr->cr_curr->ci_next;
636                 if ( !cr->cr_curr ) {
637                         /* case 2) in above description */
638                         rc = comp_test_one_component ( attr_nm, assert_nm, csi_attr, ca );
639                         break;
640                 }
641
642                 if ( cr->cr_curr->ci_type == LDAP_COMPREF_SELECT ) {
643                         /* Look up OID mapping table */ 
644                         odm = RetrieveOidDecoderMappingbyBV( &cr->cr_curr->ci_val.ci_select_value );
645                         
646                         if ( !odm || !odm->BER_Decode )
647                                 return  LDAP_PROTOCOL_ERROR;
648
649                         /* current componet MUST be either BIT or OCTET STRING */
650                         if ( csi_attr->csi_comp_desc->cd_type_id != BASICTYPE_BITSTRING ) {
651                                 bv.bv_val = ((ComponentBits*)csi_attr)->value.bits;
652                                 bv.bv_len = ((ComponentBits*)csi_attr)->value.bitLen;
653                         }
654                         else if ( csi_attr->csi_comp_desc->cd_type_id != BASICTYPE_BITSTRING ) {
655                                 bv.bv_val = ((ComponentOcts*)csi_attr)->value.octs;
656                                 bv.bv_len = ((ComponentOcts*)csi_attr)->value.octetLen;
657                         }
658                         else
659                                 return LDAP_PROTOCOL_ERROR;
660
661                         buf = ExpBufAllocBuf();
662                         ExpBuftoGenBuf( buf, &b );
663                         ExpBufInstallDataInBuf ( buf, bv.bv_val, bv.bv_len );
664                         BufResetInReadMode( b );
665                         mode = DEC_ALLOC_MODE_2;
666
667                         /* Try to decode with BER/DER decoder */
668                         rc = odm->BER_Decode ( attr_nm, b, (ComponentSyntaxInfo*)&contained_comp, &bytesDecoded, mode );
669
670                         ExpBufFreeBuf( buf );
671                         GenBufFreeBuf( b );
672
673                         if ( rc != LDAP_SUCCESS ) return LDAP_PROTOCOL_ERROR;
674
675                         /* xxx.content.(x.xy.xyz).rfc822Name */
676                         /* In the aboe Ex. move CR to the right to (x.xy.xyz)*/
677                         cr->cr_curr = cr->cr_curr->ci_next;
678                         if (!cr->cr_curr )
679                                 rc = comp_test_one_component ( attr_nm, assert_nm, csi_attr, ca );
680                         else
681                                 rc = comp_test_components( attr_nm, assert_nm, contained_comp, ca );
682                 }
683                 else {
684                         /* Ivalid Component reference */
685                         rc = LDAP_PROTOCOL_ERROR;
686                 }
687                 break;
688            case LDAP_COMPREF_SELECT:
689                 if (csi_attr->csi_comp_desc->cd_type_id != BASICTYPE_ANY )
690                         return LDAP_INVALID_SYNTAX;
691                 rc = CheckSelectTypeCorrect( attr_nm, ((ComponentAny*)csi_attr)->cai, &cr->cr_curr->ci_val.ci_select_value );
692                 if ( rc < 0 ) return LDAP_INVALID_SYNTAX;
693
694                 /* point to the real component, not any type component */
695                 csi_attr = ((ComponentAny*)csi_attr)->value;
696                 cr->cr_curr = cr->cr_curr->ci_next;
697                 if ( cr->cr_curr )
698                         rc =  comp_test_components( attr_nm, assert_nm, csi_attr, ca);
699                 else
700                         rc =  comp_test_one_component( attr_nm, assert_nm, csi_attr, ca);
701                 break;
702            default:
703                 rc = LDAP_INVALID_SYNTAX;
704         }
705         return rc;
706 }
707
708
709 void*
710 comp_nibble_memory_allocator ( int init_mem, int inc_mem ) {
711         void* nm;
712         nm = (void*)InitNibbleMemLocal( (unsigned long)init_mem, (unsigned long)inc_mem );
713         if ( !nm ) return NULL;
714         else return (void*)nm;
715 }
716
717 void
718 comp_nibble_memory_free ( void* nm ) {
719         ShutdownNibbleMemLocal( nm );
720 }
721
722 void*
723 comp_get_component_description ( int id ) {
724         if ( asntype_to_compdesc_mapping_tbl[id].atcd_typeId == id )
725                 return &asntype_to_compdesc_mapping_tbl[id].atcd_cd;
726         else
727                 return NULL;
728 }
729
730 int
731 comp_component_encoder ( void* mem_op, ComponentSyntaxInfo* csi , struct berval* nval ) {
732         int size, rc;
733         GenBuf* b;
734         ExpBuf* buf;
735         struct berval bv;
736         
737         buf = ExpBufAllocBufAndData();
738         ExpBufResetInWriteRvsMode(buf);
739         ExpBuftoGenBuf( buf, &b );
740
741         if ( !csi->csi_comp_desc->cd_gser_encoder && !csi->csi_comp_desc->cd_ldap_encoder )
742                 return (-1);
743
744         /*
745          * if an LDAP specific encoder is provided :
746          * dn and rdn have their LDAP specific encoder
747          */
748         if ( csi->csi_comp_desc->cd_ldap_encoder ) {
749                 rc = csi->csi_comp_desc->cd_ldap_encoder( csi, &bv );
750                 if ( rc != LDAP_SUCCESS )
751                         return rc;
752                 if ( mem_op )
753                         nval->bv_val = CompAlloc( mem_op, bv.bv_len );
754                 else
755                         nval->bv_val = malloc( size );
756                 memcpy( nval->bv_val, bv.bv_val, bv.bv_len );
757                 nval->bv_len = bv.bv_len;
758                 /*
759                  * This free will be eliminated by making ldap_encoder
760                  * use nibble memory in it 
761                  */
762                 free ( bv.bv_val );
763                 GenBufFreeBuf( b );
764                 BufFreeBuf( buf );
765                 return LDAP_SUCCESS;
766         }
767
768         rc = csi->csi_comp_desc->cd_gser_encoder( b, csi );
769         if ( rc < 0 ) {
770                 GenBufFreeBuf( b );
771                 BufFreeBuf( buf );
772                 return rc;
773         }
774
775         size = ExpBufDataSize( buf );
776         if ( size > 0 ) {
777                 if ( mem_op )
778                         nval->bv_val = CompAlloc ( mem_op, size );
779                 else
780                         nval->bv_val = malloc( size );
781                 nval->bv_len = size;
782                 BufResetInReadMode(b);
783                 BufCopy( nval->bv_val, b, size );
784         }
785         ExpBufFreeBuf( buf );
786         GenBufFreeBuf( b );
787
788         return LDAP_SUCCESS;
789 }
790
791 #if SLAPD_COMP_MATCH == SLAPD_MOD_DYNAMIC
792
793 #include "certificate.h"
794
795 extern convert_attr_to_comp_func* attr_converter;
796 extern convert_assert_to_comp_func* assert_converter;
797 extern convert_asn_to_ldap_func* csi_converter;
798 extern free_component_func* component_destructor;
799 extern test_component_func* test_components;
800 extern alloc_nibble_func* nibble_mem_allocator;
801 extern free_nibble_func* nibble_mem_free;
802 extern test_membership_func* is_aliased_attribute;
803 extern get_component_info_func* get_component_description;
804 extern component_encoder_func* component_encoder;
805
806
807 int init_module(int argc, char *argv[]) {
808         /*
809          * Initialize function pointers in slapd
810          */
811         attr_converter = (convert_attr_to_comp_func*)comp_convert_attr_to_comp;
812         assert_converter = (convert_assert_to_comp_func*)comp_convert_assert_to_comp;
813         component_destructor = (free_component_func*)comp_free_component;
814         test_components = (test_component_func*)comp_test_components;
815         nibble_mem_allocator = (free_nibble_func*)comp_nibble_memory_allocator;
816         nibble_mem_free = (free_nibble_func*)comp_nibble_memory_free;
817         is_aliased_attribute = (test_membership_func*)comp_is_aliased_attribute;
818         get_component_description = (get_component_info_func*)comp_get_component_description;
819         component_encoder = (component_encoder_func*)comp_component_encoder;
820
821         /* file path needs to be */
822         load_derived_matching_rule ("derived_mr.cfg");
823
824         /* the initialization for example X.509 certificate */
825         init_module_AuthenticationFramework();
826         init_module_AuthorityKeyIdentifierDefinition();
827         init_attribute_aliasing_table ();
828         init_component_description_table ();
829         return 0;
830 }
831
832 #endif /* SLAPD_PASSWD */