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