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