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