]> git.sur5r.net Git - openldap/blob - contrib/slapd-modules/comp_match/init.c
return value mising
[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                 asntype_to_compdesc_mapping_tbl[id].atcd_cd.cd_comp_type = (AttributeType*)&asntype_to_compType_mapping_tbl[id].ac_comp_type;
175         }
176 }
177
178 MatchingRule*
179 retrieve_matching_rule( char* mr_oid, AsnTypeId type ) {
180         char* tmp;
181         struct berval mr_name = BER_BVNULL;
182         AsnTypetoMatchingRuleTable* atmr;
183
184         for ( atmr = gATMR_table ; atmr ; atmr = atmr->atmr_table_next ) {
185                 if ( strcmp( atmr->atmr_oid, mr_oid ) == 0 ) {
186                         tmp = atmr->atmr_table[type].atmr_mr_name;
187                         if ( tmp ) {
188                                 mr_name.bv_val = tmp;
189                                 mr_name.bv_len = strlen( tmp );
190                                 return mr_bvfind ( &mr_name );
191                         }
192                 }
193         }
194         return (MatchingRule*)NULL;
195 }
196
197 void* 
198 comp_convert_attr_to_comp LDAP_P (( Attribute* a, Syntax *syn, struct berval* bv ))
199 {
200         char* peek_head;
201         int mode, bytesDecoded, size, rc;
202         void* component;
203         char* oid = a->a_desc->ad_type->sat_atype.at_oid ;
204         GenBuf* b;
205         ExpBuf* buf;
206         OidDecoderMapping* odm;
207         
208         /* look for the decoder registered for the given attribute */
209         odm = RetrieveOidDecoderMappingbyOid( oid, strlen(oid) );
210
211         if ( !odm || (!odm->BER_Decode && !odm->GSER_Decode) )
212                 return (void*)NULL;
213
214         buf = ExpBufAllocBuf();
215         ExpBuftoGenBuf( buf, &b );
216         ExpBufInstallDataInBuf ( buf, bv->bv_val, bv->bv_len );
217         BufResetInReadMode( b );
218
219         mode = DEC_ALLOC_MODE_2;
220         /*
221          * How can we decide which decoder will be called, GSER or BER?
222          * Currently BER decoder is called for a certificate.
223          * The flag of Attribute will say something about it in the future
224          */
225         if ( syn && slap_syntax_is_ber ( syn ) ) {
226 #if 0
227                 rc =BDecComponentTop(odm->BER_Decode, a->a_comp_data->cd_mem_op, b, 0,0, &component,&bytesDecoded,mode ) ;
228 #endif
229                 rc = odm->BER_Decode ( a->a_comp_data->cd_mem_op, b, (ComponentSyntaxInfo*)&component, &bytesDecoded, mode );
230         }
231         else {
232                 rc = odm->GSER_Decode( a->a_comp_data->cd_mem_op, b, (ComponentSyntaxInfo**)component, &bytesDecoded, mode);
233         }
234
235         ExpBufFreeBuf( buf );
236         if ( rc == -1 ) {
237                 ShutdownNibbleMemLocal ( a->a_comp_data->cd_mem_op );
238                 free ( a->a_comp_data );
239                 a->a_comp_data = NULL;
240                 return (void*)NULL;
241         }
242         else {
243                 return component;
244         }
245 }
246
247 #include <nibble-alloc.h>
248 void
249 comp_free_component ( void* mem_op ) {
250         ShutdownNibbleMemLocal( (NibbleMem*)mem_op );
251         return;
252 }
253
254 void
255 comp_convert_assert_to_comp (
256         void* mem_op,
257         ComponentSyntaxInfo *csi_attr,
258         struct berval* bv,
259         ComponentSyntaxInfo** csi, int* len, int mode )
260 {
261         int rc;
262         GenBuf* genBuf;
263         ExpBuf* buf;
264         gser_decoder_func *decoder = csi_attr->csi_comp_desc->cd_gser_decoder;
265
266         buf = ExpBufAllocBuf();
267         ExpBuftoGenBuf( buf, &genBuf );
268         ExpBufInstallDataInBuf ( buf, bv->bv_val, bv->bv_len );
269         BufResetInReadMode( genBuf );
270
271         if ( csi_attr->csi_comp_desc->cd_type_id == BASICTYPE_ANY )
272                 decoder = ((ComponentAny*)csi_attr)->cai->GSER_Decode;
273
274         rc = (*decoder)( mem_op, genBuf, csi, len, mode );
275         ExpBufFreeBuf ( buf );
276 }
277
278 int intToAscii( int value, char* buf ) {
279         int minus=0,i,temp;
280         int total_num_digits;
281
282         if ( value == 0 ){
283                 buf[0] = '0';
284                 return 1;
285         }
286
287         if ( value < 0 ){
288                 minus = 1;
289                 value = value*(-1);
290                 buf[0] = '-';
291         }
292         
293         /* How many digits */
294         for ( temp = value, total_num_digits=0 ; temp ; total_num_digits++ )
295                 temp = temp/10;
296
297         total_num_digits += minus;
298
299         for ( i = minus ; value ; i++ ) {
300                 buf[ total_num_digits - i - 1 ]= (char)(value%10 + '0');
301                 value = value/10;
302         }
303         return i;
304 }
305
306 int
307 comp_convert_asn_to_ldap ( MatchingRule* mr, ComponentSyntaxInfo* csi, struct berval* bv, int *allocated )
308 {
309         int rc;
310         struct berval prettied;
311         Syntax* syn;
312
313         AsnTypetoSyntax* asn_to_syn =
314                 &asn_to_syntax_mapping_tbl[csi->csi_comp_desc->cd_type_id];
315         if ( asn_to_syn->ats_syn_oid )
316                 csi->csi_syntax = syn_find ( asn_to_syn->ats_syn_oid );
317         else 
318                 csi->csi_syntax = NULL;
319
320
321         switch ( csi->csi_comp_desc->cd_type_id ) {
322           case BASICTYPE_BOOLEAN :
323                 bv->bv_val = (char*)malloc( 5 );
324                 *allocated = 1;
325                 bv->bv_len = 5;
326                 if ( ((ComponentBool*)csi)->value > 0 ) {
327                         strcpy ( bv->bv_val , "TRUE" );
328                         bv->bv_len = 4;
329                 }
330                 else {
331                         strcpy ( bv->bv_val , "FALSE" );
332                         bv->bv_len = 5;
333                 }
334                 break ;
335           case BASICTYPE_NULL :
336                 bv->bv_len = 0;
337                 break;
338           case BASICTYPE_INTEGER :
339                 bv->bv_val = (char*)malloc( INITIAL_ATTR_SIZE );
340                 *allocated = 1;
341                 bv->bv_len = INITIAL_ATTR_SIZE;
342                 bv->bv_len = intToAscii(((ComponentInt*)csi)->value, bv->bv_val );
343                 if ( bv->bv_len <= 0 )
344                         return LDAP_INVALID_SYNTAX;
345                 break;
346           case BASICTYPE_REAL :
347                 return LDAP_INVALID_SYNTAX;
348           case BASICTYPE_ENUMERATED :
349                 bv->bv_val = (char*)malloc( INITIAL_ATTR_SIZE );
350                 *allocated = 1;
351                 bv->bv_len = INITIAL_ATTR_SIZE;
352                 bv->bv_len = intToAscii(((ComponentEnum*)csi)->value, bv->bv_val );
353                 if ( bv->bv_len <= 0 )
354                         return LDAP_INVALID_SYNTAX;
355                 break;
356           case BASICTYPE_OID :
357           case BASICTYPE_OCTETSTRING :
358           case BASICTYPE_BITSTRING :
359           case BASICTYPE_NUMERIC_STR :
360           case BASICTYPE_PRINTABLE_STR :
361           case BASICTYPE_UNIVERSAL_STR :
362           case BASICTYPE_IA5_STR :
363           case BASICTYPE_BMP_STR :
364           case BASICTYPE_UTF8_STR :
365           case BASICTYPE_UTCTIME :
366           case BASICTYPE_GENERALIZEDTIME :
367           case BASICTYPE_GRAPHIC_STR :
368           case BASICTYPE_VISIBLE_STR :
369           case BASICTYPE_GENERAL_STR :
370           case BASICTYPE_OBJECTDESCRIPTOR :
371           case BASICTYPE_VIDEOTEX_STR :
372           case BASICTYPE_T61_STR :
373           case BASICTYPE_OCTETCONTAINING :
374           case BASICTYPE_BITCONTAINING :
375           case BASICTYPE_RELATIVE_OID :
376                 bv->bv_val = ((ComponentOcts*)csi)->value.octs;
377                 bv->bv_len = ((ComponentOcts*)csi)->value.octetLen;
378                 break;
379           case BASICTYPE_ANY :
380                 csi = ((ComponentAny*)csi)->value;
381                 if ( csi->csi_comp_desc->cd_type != ASN_BASIC ||
382                         csi->csi_comp_desc->cd_type_id == BASICTYPE_ANY )
383                         return LDAP_INVALID_SYNTAX;
384                 return comp_convert_asn_to_ldap( mr, csi, bv, allocated );
385           case COMPOSITE_ASN1_TYPE :
386                 break;
387           case RDNSequence :
388                 /*dnMatch*/
389                 if( strncmp( mr->smr_mrule.mr_oid, DN_MATCH_OID, strlen(DN_MATCH_OID) ) != 0 )
390                         return LDAP_INVALID_SYNTAX;
391                 *allocated = 1;
392                 rc = ConvertRDNSequence2RFC2253( (irRDNSequence*)csi, bv );
393                 if ( rc != LDAP_SUCCESS ) return rc;
394                 break;
395           case RelativeDistinguishedName :
396                 /*rdnMatch*/
397                 if( strncmp( mr->smr_mrule.mr_oid, RDN_MATCH_OID, strlen(RDN_MATCH_OID) ) != 0 )
398                         return LDAP_INVALID_SYNTAX;
399                 *allocated = 1;
400                 rc = ConvertRDN2RFC2253((irRelativeDistinguishedName*)csi,bv);
401                 if ( rc != LDAP_SUCCESS ) return rc;
402                 break;
403           case TelephoneNumber :
404           case FacsimileTelephoneNumber__telephoneNumber :
405                 break;
406           case DirectoryString :
407                 return LDAP_INVALID_SYNTAX;
408           case ASN_COMP_CERTIFICATE :
409           case ASNTYPE_END :
410                 break;
411           default :
412                 /*Only ASN Basic Type can be converted into LDAP string*/
413                 return LDAP_INVALID_SYNTAX;
414         }
415
416         if ( csi->csi_syntax ) {
417                 if ( csi->csi_syntax->ssyn_validate ) {
418                         rc = csi->csi_syntax->ssyn_validate(csi->csi_syntax, bv);
419                         if ( rc != LDAP_SUCCESS )
420                                 return LDAP_INVALID_SYNTAX;
421                 }
422                 if ( csi->csi_syntax->ssyn_pretty ) {
423                         rc = csi->csi_syntax->ssyn_pretty(csi->csi_syntax, bv, &prettied , NULL );
424                         if ( rc != LDAP_SUCCESS )
425                                 return LDAP_INVALID_SYNTAX;
426 #if 0
427                         free ( bv->bv_val );/*potential memory leak?*/
428 #endif
429                         bv->bv_val = prettied.bv_val;
430                         bv->bv_len = prettied.bv_len;
431                 }
432         }
433
434         return LDAP_SUCCESS;
435 }
436
437 /*
438  * If <all> type component referenced is used
439  * more than one component will be tested
440  */
441 #define IS_TERMINAL_COMPREF(cr) (cr->cr_curr->ci_next == NULL)
442 int
443 comp_test_all_components (
444         void* attr_mem_op,
445         void* assert_mem_op,
446         ComponentSyntaxInfo *csi_attr,
447         ComponentAssertion* ca )
448 {
449         int rc;
450         ComponentSyntaxInfo *csi_temp = NULL, *csi_assert = NULL, *comp_elmt = NULL;
451         ComponentReference *cr = ca->ca_comp_ref;
452         struct berval *ca_val = &ca->ca_ma_value;
453
454         switch ( cr->cr_curr->ci_type ) {
455             case LDAP_COMPREF_ALL:
456                 if ( IS_TERMINAL_COMPREF(cr) ) {
457                         FOR_EACH_LIST_ELMT( comp_elmt, &((ComponentList*)csi_attr)->comp_list )
458                         {
459                                 rc = comp_test_one_component( attr_mem_op, assert_mem_op, comp_elmt, ca );
460                                 if ( rc == LDAP_COMPARE_TRUE ) {
461                                         break;
462                                 }
463                         }
464                 } else {
465                         ComponentId *start_compid = ca->ca_comp_ref->cr_curr->ci_next;
466                         FOR_EACH_LIST_ELMT( comp_elmt, &((ComponentList*)csi_attr)->comp_list )
467                         {
468                                 cr->cr_curr = start_compid;
469                                 rc = comp_test_components ( attr_mem_op, assert_mem_op, comp_elmt, ca );
470                                 
471                                 if ( rc == LDAP_COMPARE_TRUE ) {
472                                         break;
473                                 }
474                         }
475                 }
476                 break;
477             case LDAP_COMPREF_CONTENT:
478             case LDAP_COMPREF_SELECT:
479             case LDAP_COMPREF_DEFINED:
480             case LDAP_COMPREF_UNDEFINED:
481             case LDAP_COMPREF_IDENTIFIER:
482             case LDAP_COMPREF_FROM_BEGINNING:
483             case LDAP_COMPREF_FROM_END:
484             case LDAP_COMPREF_COUNT:
485                 rc = LDAP_OPERATIONS_ERROR;
486                 break;
487             default:
488                 rc = LDAP_OPERATIONS_ERROR;
489         }
490         return rc;
491 }
492
493 void
494 eat_bv_whsp ( struct berval* in )
495 {
496         char* end = in->bv_val + in->bv_len;
497         for ( ; ( *in->bv_val == ' ' ) && ( in->bv_val < end ) ; ) {
498                 in->bv_val++;
499         }
500 }
501
502 /*
503  * Perform matching one referenced component against assertion
504  * If the matching rule in a component filter is allComponentsMatch
505  * or its derivatives the extracted component's ASN.1 specification
506  * is applied to the assertion value as its syntax
507  * Otherwise, the matching rule's syntax is applied to the assertion value
508  * By RFC 3687
509  */
510 int
511 comp_test_one_component (
512         void* attr_mem_op,
513         void* assert_mem_op,
514         ComponentSyntaxInfo *csi_attr,
515         ComponentAssertion *ca )
516 {
517         int len, rc;
518         ComponentSyntaxInfo *csi_assert = NULL;
519         char* oid = NULL;
520         MatchingRule* mr = ca->ca_ma_rule;
521
522         if ( mr->smr_usage & SLAP_MR_COMPONENT ) {
523                 /* If allComponentsMatch or its derivatives */
524                 if ( !ca->ca_comp_data.cd_tree ) {
525                         comp_convert_assert_to_comp( assert_mem_op, csi_attr, &ca->ca_ma_value, &csi_assert, &len, DEC_ALLOC_MODE_0 );
526                         ca->ca_comp_data.cd_tree = (void*)csi_assert;
527                 } else {
528                         csi_assert = ca->ca_comp_data.cd_tree;
529                 }
530
531                 if ( !csi_assert )
532                         return LDAP_PROTOCOL_ERROR;
533
534                 if ( strcmp( mr->smr_mrule.mr_oid, OID_ALL_COMP_MATCH ) != 0 )
535                 {
536                         /* allComponentMatch's derivatives */
537                         oid =  mr->smr_mrule.mr_oid;
538                 }
539                         return csi_attr->csi_comp_desc->cd_all_match(
540                                                  oid, csi_attr, csi_assert );
541
542         } else {
543                 /* LDAP existing matching rules */
544                 struct berval attr_bv = BER_BVNULL;
545                 struct berval n_attr_bv = BER_BVNULL;
546                 struct berval* assert_bv = &ca->ca_ma_value;
547                 int allocated = 0;
548                 /*Attribute is converted to compatible LDAP encodings*/
549                 if ( comp_convert_asn_to_ldap( mr, csi_attr, &attr_bv, &allocated ) != LDAP_SUCCESS )
550                         return LDAP_INAPPROPRIATE_MATCHING;
551                 /* extracted component value is not normalized */
552                 if ( ca->ca_ma_rule->smr_normalize ) {
553                         rc = ca->ca_ma_rule->smr_normalize (
554                                 SLAP_MR_VALUE_OF_ASSERTION_SYNTAX,
555                                 NULL, ca->ca_ma_rule,
556                                 &attr_bv, &n_attr_bv, NULL );
557                         if ( rc != LDAP_SUCCESS )
558                                 return rc;
559                         if ( allocated && attr_bv.bv_val )
560                                 free (attr_bv.bv_val);
561                 } else {
562                         n_attr_bv = attr_bv;
563                 }
564 #if 0
565                 /*Assertion value is validated by MR's syntax*/
566                 if ( !ca->ca_comp_data.cd_tree ) {
567                         ca->ca_comp_data.cd_tree = assert_bv;
568                 }
569                 else {
570                         assert_bv = ca->ca_comp_data.cd_tree;
571                 }
572 #endif
573                 if ( !n_attr_bv.bv_val )
574                         return LDAP_COMPARE_FALSE;
575                 rc = csi_value_match( mr, &n_attr_bv, assert_bv );
576                 if ( n_attr_bv.bv_val )
577                         free ( n_attr_bv.bv_val );
578                 return rc;
579         }
580 }
581
582 int
583 comp_test_components( void* attr_nm, void* assert_nm, ComponentSyntaxInfo* csi_attr, ComponentAssertion* ca) {
584         char* peek_head;
585         int mode, bytesDecoded = 0, rc;
586         GenBuf* b;
587         ExpBuf* buf;
588         OidDecoderMapping* odm;
589         struct berval bv;
590         char oid[MAX_OID_LEN];
591         void* contained_comp, *anytype_comp;
592         ComponentReference* cr = ca->ca_comp_ref;
593
594         if ( !cr )
595                 return comp_test_one_component ( attr_nm, assert_nm, csi_attr, ca );
596         /* Extracting the component refrenced by ca->ca_comp_ref */
597         csi_attr = (ComponentSyntaxInfo*)csi_attr->csi_comp_desc->cd_extract_i( attr_nm, cr, csi_attr );
598         if ( !csi_attr ) return LDAP_INVALID_SYNTAX;
599         /* perform matching, considering the type of a Component Reference(CR)*/
600         switch( cr->cr_curr->ci_type ) {
601            case LDAP_COMPREF_IDENTIFIER:
602            case LDAP_COMPREF_FROM_BEGINNING:
603            case LDAP_COMPREF_FROM_END:
604            case LDAP_COMPREF_COUNT:
605                 /*
606                  * Exactly one component is referenced
607                  * Fast Path for matching for this case
608                  */
609                 rc = comp_test_one_component ( attr_nm, assert_nm, csi_attr, ca );
610                 break;
611            case LDAP_COMPREF_ALL:
612                 /*
613                  * If <all> type CR is used
614                  * more than one component will be tested
615                  */
616                 rc = comp_test_all_components ( attr_nm, assert_nm, csi_attr, ca );
617                 break;
618
619            case LDAP_COMPREF_CONTENT:
620                 /*
621                  * <content> type CR is used
622                  * check if it is followed by <select> type CR.
623                  * 1) If so, look up the corresponding decoder  in the mapping
624                  * table(OID to decoder) by <select>
625                  * and then decode the OCTET/BIT STRING with the decoder
626                  * Finially, extreact the target component with the remaining CR.
627                  * 2) If not, just return the current component, It SHOULD not be
628                  * extracted further, because the component MUST be BIT/OCTET
629                  * string.
630                  */
631
632                 cr->cr_curr = cr->cr_curr->ci_next;
633                 if ( !cr->cr_curr ) {
634                         /* case 2) in above description */
635                         rc = comp_test_one_component ( attr_nm, assert_nm, csi_attr, ca );
636                         break;
637                 }
638
639                 if ( cr->cr_curr->ci_type == LDAP_COMPREF_SELECT ) {
640                         /* Look up OID mapping table */ 
641                         odm = RetrieveOidDecoderMappingbyBV( &cr->cr_curr->ci_val.ci_select_value );
642                         
643                         if ( !odm || !odm->BER_Decode )
644                                 return  LDAP_PROTOCOL_ERROR;
645
646                         /* current componet MUST be either BIT or OCTET STRING */
647                         if ( csi_attr->csi_comp_desc->cd_type_id != BASICTYPE_BITSTRING ) {
648                                 bv.bv_val = ((ComponentBits*)csi_attr)->value.bits;
649                                 bv.bv_len = ((ComponentBits*)csi_attr)->value.bitLen;
650                         }
651                         else if ( csi_attr->csi_comp_desc->cd_type_id != BASICTYPE_BITSTRING ) {
652                                 bv.bv_val = ((ComponentOcts*)csi_attr)->value.octs;
653                                 bv.bv_len = ((ComponentOcts*)csi_attr)->value.octetLen;
654                         }
655                         else
656                                 return LDAP_PROTOCOL_ERROR;
657
658                         buf = ExpBufAllocBuf();
659                         ExpBuftoGenBuf( buf, &b );
660                         ExpBufInstallDataInBuf ( buf, bv.bv_val, bv.bv_len );
661                         BufResetInReadMode( b );
662                         mode = DEC_ALLOC_MODE_2;
663
664                         /* Try to decode with BER/DER decoder */
665 #if 0
666                         rc =BDecComponentTop( odm->BER_Decode, attr_nm, b, 0,0, &contained_comp,&bytesDecoded, mode );
667 #endif
668                         rc = odm->BER_Decode ( attr_nm, b, (ComponentSyntaxInfo*)&contained_comp, &bytesDecoded, mode );
669
670 #if 0
671                         if ( rc != LDAP_SUCCESS ) {
672                                 /* If fails with BER/DER decoder, try with GSER */
673                                 bytesDecoded = 0;
674                                 BufResetInReadMode( b );
675                                 rc = odm->GSER_decoder( attr_nm, b, contained_comp, &bytesDecoded, mode);
676                         }
677 #endif
678                         ExpBufFreeBuf( buf );
679
680                         if ( rc != LDAP_SUCCESS ) return LDAP_PROTOCOL_ERROR;
681
682                         /* xxx.content.(x.xy.xyz).rfc822Name */
683                         /* In the aboe Ex. move CR to the right to (x.xy.xyz)*/
684                         cr->cr_curr = cr->cr_curr->ci_next;
685                         if (!cr->cr_curr )
686                                 rc = comp_test_one_component ( attr_nm, assert_nm, csi_attr, ca );
687                         else
688                                 rc = comp_test_components( attr_nm, assert_nm, contained_comp, ca );
689                 }
690                 else {
691                         /* Ivalid Component reference */
692                         rc = LDAP_PROTOCOL_ERROR;
693                 }
694                 break;
695            case LDAP_COMPREF_SELECT:
696                 if (csi_attr->csi_comp_desc->cd_type_id != BASICTYPE_ANY )
697                         return LDAP_INVALID_SYNTAX;
698                 rc = CheckSelectTypeCorrect( attr_nm, ((ComponentAny*)csi_attr)->cai, &cr->cr_curr->ci_val.ci_select_value );
699                 if ( rc < 0 ) return LDAP_INVALID_SYNTAX;
700
701                 /* point to the real component, not any type component */
702                 csi_attr = ((ComponentAny*)csi_attr)->value;
703                 cr->cr_curr = cr->cr_curr->ci_next;
704                 if ( cr->cr_curr )
705                         rc =  comp_test_components( attr_nm, assert_nm, csi_attr, ca);
706                 else
707                         rc =  comp_test_one_component( attr_nm, assert_nm, csi_attr, ca);
708                 break;
709            default:
710                 rc = LDAP_INVALID_SYNTAX;
711         }
712         return rc;
713 }
714
715
716 void*
717 comp_nibble_memory_allocator ( int init_mem, int inc_mem ) {
718         void* nm;
719         nm = (void*)InitNibbleMemLocal( (unsigned long)init_mem, (unsigned long)inc_mem );
720         if ( !nm ) return NULL;
721         else return (void*)nm;
722 }
723
724 void
725 comp_nibble_memory_free ( void* nm ) {
726         ShutdownNibbleMemLocal( nm );
727 }
728
729 void*
730 comp_get_component_description ( int id ) {
731         if ( asntype_to_compdesc_mapping_tbl[id].atcd_typeId == id )
732                 return &asntype_to_compdesc_mapping_tbl[id].atcd_cd;
733         else
734                 return NULL;
735 }
736
737 int
738 comp_component_encoder ( void* mem_op, ComponentSyntaxInfo* csi , struct berval* nval ) {
739         int size, rc;
740         GenBuf* b;
741         ExpBuf* buf;
742         struct berval bv;
743         
744         buf = ExpBufAllocBufAndData();
745         ExpBufResetInWriteRvsMode(buf);
746         ExpBuftoGenBuf( buf, &b );
747
748         if ( !csi->csi_comp_desc->cd_gser_encoder && !csi->csi_comp_desc->cd_ldap_encoder )
749                 return (-1);
750
751         /*
752          * if an LDAP specific encoder is provided :
753          * dn and rdn have their LDAP specific encoder
754          */
755         if ( csi->csi_comp_desc->cd_ldap_encoder ) {
756                 rc = csi->csi_comp_desc->cd_ldap_encoder( csi, &bv );
757                 if ( rc != LDAP_SUCCESS )
758                         return rc;
759                 if ( mem_op )
760                         nval->bv_val = CompAlloc( mem_op, bv.bv_len );
761                 else
762                         nval->bv_val = malloc( size );
763                 memcpy( nval->bv_val, bv.bv_val, bv.bv_len );
764                 nval->bv_len = bv.bv_len;
765                 /*
766                  * This free will be eliminated by making ldap_encoder
767                  * use nibble memory in it 
768                  */
769                 free ( bv.bv_val );
770                 return LDAP_SUCCESS;
771         }
772
773         rc = csi->csi_comp_desc->cd_gser_encoder( b, csi );
774         if ( rc < 0 ) {
775                 BufFreeBuf( buf );
776                 return rc;
777         }
778
779         size = ExpBufDataSize( buf );
780         if ( size > 0 ) {
781                 if ( mem_op )
782                         nval->bv_val = CompAlloc ( mem_op, size );
783                 else
784                         nval->bv_val = malloc( size );
785                 nval->bv_len = size;
786                 BufResetInReadMode(b);
787                 BufCopy( nval->bv_val, b, size );
788         }
789         ExpBufFreeBuf( buf );
790
791         return LDAP_SUCCESS;
792 }
793
794 #if SLAPD_COMP_MATCH == SLAPD_MOD_DYNAMIC
795
796 #include "certificate.h"
797
798 extern convert_attr_to_comp_func* attr_converter;
799 extern convert_assert_to_comp_func* assert_converter;
800 extern convert_asn_to_ldap_func* csi_converter;
801 extern free_component_func* component_destructor;
802 extern test_component_func* test_components;
803 extern alloc_nibble_func* nibble_mem_allocator;
804 extern free_nibble_func* nibble_mem_free;
805 extern test_membership_func* is_aliased_attribute;
806 extern get_component_info_func* get_component_description;
807 extern component_encoder_func* component_encoder;
808
809
810 int init_module(int argc, char *argv[]) {
811         /*
812          * Initialize function pointers in slapd
813          */
814         attr_converter = comp_convert_attr_to_comp;
815         assert_converter = comp_convert_assert_to_comp;
816         component_destructor = comp_free_component;
817         test_components = comp_test_components;
818         nibble_mem_allocator = (free_nibble_func*)comp_nibble_memory_allocator;
819         nibble_mem_free = comp_nibble_memory_free;
820         is_aliased_attribute = (test_membership_func*)comp_is_aliased_attribute;
821         get_component_description = (get_component_info_func*)comp_get_component_description;
822         component_encoder = (component_encoder_func*)comp_component_encoder;
823
824         /* file path needs to be */
825         load_derived_matching_rule ("derived_mr.cfg");
826
827         /* the initialization for example X.509 certificate */
828         init_module_AuthenticationFramework();
829         init_module_AuthorityKeyIdentifierDefinition();
830         init_attribute_aliasing_table ();
831         init_component_description_table ();
832         return 0;
833 }
834
835 #endif /* SLAPD_PASSWD */