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 */ 39AttributeAliasing aa_table [ MAX_ALIASING_ENTRY ]; 40MatchingRuleAliasing mra_table [ MAX_ALIASING_ENTRY ]; 41 42OD_entry* gOD_table = NULL; 43AsnTypetoMatchingRuleTable* gATMR_table = NULL; 44 45int 46load_derived_matching_rule ( char* cfg_path ){ 47} 48 49AttributeAliasing* 50comp_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 63static int 64add_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 */ 106char* 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 112static int 113init_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 133void 134init_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 184MatchingRule* 185retrieve_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 203void* 204comp_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> 257void 258comp_free_component ( void* mem_op ) { 259 ShutdownNibbleMemLocal( (NibbleMem*)mem_op ); 260 return; 261} 262 263void 264comp_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 288int 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 316int 317comp_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) 452int 453comp_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 507void 508eat_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 */ 524int 525comp_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 596int 597comp_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 720void* 721comp_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 728void 729comp_nibble_memory_free ( void* nm ) { 730 ShutdownNibbleMemLocal( nm ); 731} 732 733void* 734comp_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 741int 742comp_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 806extern convert_attr_to_comp_func* attr_converter; 807extern convert_assert_to_comp_func* assert_converter; 808extern convert_asn_to_ldap_func* csi_converter; 809extern free_component_func* component_destructor; 810extern test_component_func* test_components; 811extern alloc_nibble_func* nibble_mem_allocator; 812extern free_nibble_func* nibble_mem_free; 813extern test_membership_func* is_aliased_attribute; 814extern get_component_info_func* get_component_description; 815extern component_encoder_func* component_encoder; 816 817 818int 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