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