/* Copyright 2004 IBM Corporation * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted only as authorized by the OpenLDAP * Public License. */ /* ACKNOWLEDGEMENTS * This work originally developed by Sang Seok Lim * 2004/06/18 03:20:00 slim@OpenLDAP.org */ #include "portable.h" #include #include #include #include "lutil.h" #include #include "slap.h" #include "component.h" #include "componentlib.h" #include "asn.h" #include #include #ifndef SLAPD_COMP_MATCH #define SLAPD_COMP_MATCH SLAPD_MOD_DYNAMIC #endif /* * Attribute and MatchingRule aliasing table */ AttributeAliasing aa_table [ MAX_ALIASING_ENTRY ]; MatchingRuleAliasing mra_table [ MAX_ALIASING_ENTRY ]; OD_entry* gOD_table = NULL; AsnTypetoMatchingRuleTable* gATMR_table = NULL; int load_derived_matching_rule ( char* cfg_path ){ } AttributeAliasing* comp_is_aliased_attribute( void *in ) { AttributeAliasing* curr_aa; int i; AttributeDescription *ad = (AttributeDescription*)in; for ( i = 0; aa_table[i].aa_aliasing_ad && i < MAX_ALIASING_ENTRY; i++ ) { if ( strncmp(aa_table[i].aa_aliasing_ad->ad_cname.bv_val , ad->ad_cname.bv_val, ad->ad_cname.bv_len) == 0 ) return &aa_table[i]; } return NULL; } static int add_aa_entry( int index, char* aliasing_at_name, char* aliased_at_name, char* mr_name, char* component_filter ) { char text[1][128]; int rc; struct berval type; /* get and store aliasing AttributeDescription */ type.bv_val = aliasing_at_name; type.bv_len = strlen ( aliasing_at_name ); rc = slap_bv2ad ( &type, &aa_table[index].aa_aliasing_ad,(const char**)text ); if ( rc != LDAP_SUCCESS ) return rc; /* get and store aliased AttributeDescription */ type.bv_val = aliased_at_name; type.bv_len = strlen ( aliased_at_name ); rc = slap_bv2ad ( &type, &aa_table[index].aa_aliased_ad,(const char**)text ); if ( rc != LDAP_SUCCESS ) return rc; /* get and store componentFilterMatch */ type.bv_val = mr_name; type.bv_len = strlen ( mr_name); aa_table[index].aa_mr = mr_bvfind ( &type ); /* get and store a component filter */ type.bv_val = component_filter; type.bv_len = strlen ( component_filter ); rc = get_comp_filter( NULL, &type, &aa_table[index].aa_cf,(const char**)text); aa_table[index].aa_cf_str = component_filter; return rc; } /* * Initialize attribute aliasing table when this module is loaded * add_aa_entry ( index for the global table, * name of the aliasing attribute, * component filter with filling value parts "xxx" * ) * "xxx" will be replaced with effective values later. * See RFC3687 to understand the content of a component filter. */ char* pre_processed_comp_filter[] = { /*1*/"item:{ component \"toBeSigned.issuer.rdnSequence\", rule distinguishedNameMatch, value xxx }", /*2*/"item:{ component \"toBeSigned.serialNumber\", rule integerMatch, value xxx }", /*3*/"and:{ item:{ component \"toBeSigned.serialNumber\", rule integerMatch, value xxx }, item:{ component \"toBeSigned.issuer.rdnSequence\", rule distinguishedNameMatch, value xxx } }" }; static int init_attribute_aliasing_table () { int rc; int index = 0 ; rc = add_aa_entry ( index, "x509CertificateIssuer", "userCertificate","componentFilterMatch", pre_processed_comp_filter[index] ); if ( rc != LDAP_SUCCESS ) return LDAP_PARAM_ERROR; index++; rc = add_aa_entry ( index, "x509CertificateSerial","userCertificate", "componentFilterMatch", pre_processed_comp_filter[index] ); if ( rc != LDAP_SUCCESS ) return LDAP_PARAM_ERROR; index++; rc = add_aa_entry ( index, "x509CertificateSerialAndIssuer", "userCertificate", "componentFilterMatch", pre_processed_comp_filter[index] ); if ( rc != LDAP_SUCCESS ) return LDAP_PARAM_ERROR; index++; return LDAP_SUCCESS; } void init_component_description_table () { AsnTypeId id; struct berval mr; AsnTypetoSyntax* asn_to_syn; Syntax* syn; for ( id = BASICTYPE_BOOLEAN; id != ASNTYPE_END ; id++ ) { asntype_to_compType_mapping_tbl[id].ac_comp_type.ct_subtypes = NULL; asntype_to_compType_mapping_tbl[id].ac_comp_type.ct_syntax = NULL; /* Equality Matching Rule */ if ( asntype_to_compMR_mapping_tbl[id].atc_equality ) { mr.bv_val = asntype_to_compMR_mapping_tbl[id].atc_equality; mr.bv_len = strlen(asntype_to_compMR_mapping_tbl[id].atc_equality); asntype_to_compType_mapping_tbl[id].ac_comp_type.ct_equality = mr_bvfind( &mr ); } /* Approx Matching Rule */ if ( asntype_to_compMR_mapping_tbl[id].atc_approx ) { mr.bv_val = asntype_to_compMR_mapping_tbl[id].atc_approx; mr.bv_len = strlen(asntype_to_compMR_mapping_tbl[id].atc_approx); asntype_to_compType_mapping_tbl[id].ac_comp_type.ct_approx = mr_bvfind( &mr ); } /* Ordering Matching Rule */ if ( asntype_to_compMR_mapping_tbl[id].atc_ordering ) { mr.bv_val = asntype_to_compMR_mapping_tbl[id].atc_ordering; mr.bv_len = strlen(asntype_to_compMR_mapping_tbl[id].atc_ordering); asntype_to_compType_mapping_tbl[id].ac_comp_type.ct_ordering= mr_bvfind( &mr ); } /* Substr Matching Rule */ if ( asntype_to_compMR_mapping_tbl[id].atc_substr ) { mr.bv_val = asntype_to_compMR_mapping_tbl[id].atc_substr; mr.bv_len = strlen(asntype_to_compMR_mapping_tbl[id].atc_substr); asntype_to_compType_mapping_tbl[id].ac_comp_type.ct_substr = mr_bvfind( &mr ); } /* Syntax */ asn_to_syn = &asn_to_syntax_mapping_tbl[ id ]; if ( asn_to_syn->ats_syn_oid ) syn = syn_find ( asn_to_syn->ats_syn_oid ); else syn = NULL; asntype_to_compType_mapping_tbl[id].ac_comp_type.ct_syntax = syn; /* Initialize Component Descriptions of primitive ASN.1 types */ asntype_to_compdesc_mapping_tbl[id].atcd_cd.cd_comp_type = (AttributeType*)&asntype_to_compType_mapping_tbl[id].ac_comp_type; } } MatchingRule* retrieve_matching_rule( char* mr_oid, AsnTypeId type ) { char* tmp; struct berval mr_name = BER_BVNULL; AsnTypetoMatchingRuleTable* atmr; for ( atmr = gATMR_table ; atmr ; atmr = atmr->atmr_table_next ) { if ( strcmp( atmr->atmr_oid, mr_oid ) == 0 ) { tmp = atmr->atmr_table[type].atmr_mr_name; if ( tmp ) { mr_name.bv_val = tmp; mr_name.bv_len = strlen( tmp ); return mr_bvfind ( &mr_name ); } } } return (MatchingRule*)NULL; } void* comp_convert_attr_to_comp LDAP_P (( Attribute* a, Syntax *syn, struct berval* bv )) { char* peek_head; int mode, bytesDecoded, size, rc; void* component; char* oid = a->a_desc->ad_type->sat_atype.at_oid ; GenBuf* b = NULL; ExpBuf* buf = NULL; OidDecoderMapping* odm; /* look for the decoder registered for the given attribute */ odm = RetrieveOidDecoderMappingbyOid( oid, strlen(oid) ); if ( !odm || (!odm->BER_Decode && !odm->GSER_Decode) ) return (void*)NULL; buf = ExpBufAllocBuf(); ExpBuftoGenBuf( buf, &b ); ExpBufInstallDataInBuf ( buf, bv->bv_val, bv->bv_len ); BufResetInReadMode( b ); mode = DEC_ALLOC_MODE_2; /* * How can we decide which decoder will be called, GSER or BER? * Currently BER decoder is called for a certificate. * The flag of Attribute will say something about it in the future */ if ( syn && slap_syntax_is_ber ( syn ) ) { #if 0 rc =BDecComponentTop(odm->BER_Decode, a->a_comp_data->cd_mem_op, b, 0,0, &component,&bytesDecoded,mode ) ; #endif rc = odm->BER_Decode ( a->a_comp_data->cd_mem_op, b, (ComponentSyntaxInfo*)&component, &bytesDecoded, mode ); } else { rc = odm->GSER_Decode( a->a_comp_data->cd_mem_op, b, (ComponentSyntaxInfo**)component, &bytesDecoded, mode); } ExpBufFreeBuf( buf ); GenBufFreeBuf( b ); if ( rc == -1 ) { #if 0 ShutdownNibbleMemLocal ( a->a_comp_data->cd_mem_op ); free ( a->a_comp_data ); a->a_comp_data = NULL; #endif return (void*)NULL; } else { return component; } } #include void comp_free_component ( void* mem_op ) { ShutdownNibbleMemLocal( (NibbleMem*)mem_op ); return; } void comp_convert_assert_to_comp ( void* mem_op, ComponentSyntaxInfo *csi_attr, struct berval* bv, ComponentSyntaxInfo** csi, int* len, int mode ) { int rc; GenBuf* genBuf; ExpBuf* buf; gser_decoder_func *decoder = csi_attr->csi_comp_desc->cd_gser_decoder; buf = ExpBufAllocBuf(); ExpBuftoGenBuf( buf, &genBuf ); ExpBufInstallDataInBuf ( buf, bv->bv_val, bv->bv_len ); BufResetInReadMode( genBuf ); if ( csi_attr->csi_comp_desc->cd_type_id == BASICTYPE_ANY ) decoder = ((ComponentAny*)csi_attr)->cai->GSER_Decode; rc = (*decoder)( mem_op, genBuf, csi, len, mode ); ExpBufFreeBuf ( buf ); GenBufFreeBuf( genBuf ); } int intToAscii( int value, char* buf ) { int minus=0,i,temp; int total_num_digits; if ( value == 0 ){ buf[0] = '0'; return 1; } if ( value < 0 ){ minus = 1; value = value*(-1); buf[0] = '-'; } /* How many digits */ for ( temp = value, total_num_digits=0 ; temp ; total_num_digits++ ) temp = temp/10; total_num_digits += minus; for ( i = minus ; value ; i++ ) { buf[ total_num_digits - i - 1 ]= (char)(value%10 + '0'); value = value/10; } return i; } int comp_convert_asn_to_ldap ( MatchingRule* mr, ComponentSyntaxInfo* csi, struct berval* bv, int *allocated ) { int rc; struct berval prettied; Syntax* syn; AsnTypetoSyntax* asn_to_syn = &asn_to_syntax_mapping_tbl[csi->csi_comp_desc->cd_type_id]; if ( asn_to_syn->ats_syn_oid ) csi->csi_syntax = syn_find ( asn_to_syn->ats_syn_oid ); else csi->csi_syntax = NULL; switch ( csi->csi_comp_desc->cd_type_id ) { case BASICTYPE_BOOLEAN : bv->bv_val = (char*)malloc( 5 ); *allocated = 1; bv->bv_len = 5; if ( ((ComponentBool*)csi)->value > 0 ) { strcpy ( bv->bv_val , "TRUE" ); bv->bv_len = 4; } else { strcpy ( bv->bv_val , "FALSE" ); bv->bv_len = 5; } break ; case BASICTYPE_NULL : bv->bv_len = 0; break; case BASICTYPE_INTEGER : bv->bv_val = (char*)malloc( INITIAL_ATTR_SIZE ); *allocated = 1; bv->bv_len = INITIAL_ATTR_SIZE; bv->bv_len = intToAscii(((ComponentInt*)csi)->value, bv->bv_val ); if ( bv->bv_len <= 0 ) return LDAP_INVALID_SYNTAX; break; case BASICTYPE_REAL : return LDAP_INVALID_SYNTAX; case BASICTYPE_ENUMERATED : bv->bv_val = (char*)malloc( INITIAL_ATTR_SIZE ); *allocated = 1; bv->bv_len = INITIAL_ATTR_SIZE; bv->bv_len = intToAscii(((ComponentEnum*)csi)->value, bv->bv_val ); if ( bv->bv_len <= 0 ) return LDAP_INVALID_SYNTAX; break; case BASICTYPE_OID : case BASICTYPE_OCTETSTRING : case BASICTYPE_BITSTRING : case BASICTYPE_NUMERIC_STR : case BASICTYPE_PRINTABLE_STR : case BASICTYPE_UNIVERSAL_STR : case BASICTYPE_IA5_STR : case BASICTYPE_BMP_STR : case BASICTYPE_UTF8_STR : case BASICTYPE_UTCTIME : case BASICTYPE_GENERALIZEDTIME : case BASICTYPE_GRAPHIC_STR : case BASICTYPE_VISIBLE_STR : case BASICTYPE_GENERAL_STR : case BASICTYPE_OBJECTDESCRIPTOR : case BASICTYPE_VIDEOTEX_STR : case BASICTYPE_T61_STR : case BASICTYPE_OCTETCONTAINING : case BASICTYPE_BITCONTAINING : case BASICTYPE_RELATIVE_OID : bv->bv_val = ((ComponentOcts*)csi)->value.octs; bv->bv_len = ((ComponentOcts*)csi)->value.octetLen; break; case BASICTYPE_ANY : csi = ((ComponentAny*)csi)->value; if ( csi->csi_comp_desc->cd_type != ASN_BASIC || csi->csi_comp_desc->cd_type_id == BASICTYPE_ANY ) return LDAP_INVALID_SYNTAX; return comp_convert_asn_to_ldap( mr, csi, bv, allocated ); case COMPOSITE_ASN1_TYPE : break; case RDNSequence : /*dnMatch*/ if( strncmp( mr->smr_mrule.mr_oid, DN_MATCH_OID, strlen(DN_MATCH_OID) ) != 0 ) return LDAP_INVALID_SYNTAX; *allocated = 1; rc = ConvertRDNSequence2RFC2253( (irRDNSequence*)csi, bv ); if ( rc != LDAP_SUCCESS ) return rc; break; case RelativeDistinguishedName : /*rdnMatch*/ if( strncmp( mr->smr_mrule.mr_oid, RDN_MATCH_OID, strlen(RDN_MATCH_OID) ) != 0 ) return LDAP_INVALID_SYNTAX; *allocated = 1; rc = ConvertRDN2RFC2253((irRelativeDistinguishedName*)csi,bv); if ( rc != LDAP_SUCCESS ) return rc; break; case TelephoneNumber : case FacsimileTelephoneNumber__telephoneNumber : break; case DirectoryString : return LDAP_INVALID_SYNTAX; case ASN_COMP_CERTIFICATE : case ASNTYPE_END : break; default : /*Only ASN Basic Type can be converted into LDAP string*/ return LDAP_INVALID_SYNTAX; } if ( csi->csi_syntax ) { if ( csi->csi_syntax->ssyn_validate ) { rc = csi->csi_syntax->ssyn_validate(csi->csi_syntax, bv); if ( rc != LDAP_SUCCESS ) return LDAP_INVALID_SYNTAX; } if ( csi->csi_syntax->ssyn_pretty ) { rc = csi->csi_syntax->ssyn_pretty(csi->csi_syntax, bv, &prettied , NULL ); if ( rc != LDAP_SUCCESS ) return LDAP_INVALID_SYNTAX; #if 0 free ( bv->bv_val );/*potential memory leak?*/ #endif bv->bv_val = prettied.bv_val; bv->bv_len = prettied.bv_len; } } return LDAP_SUCCESS; } /* * If type component referenced is used * more than one component will be tested */ #define IS_TERMINAL_COMPREF(cr) (cr->cr_curr->ci_next == NULL) int comp_test_all_components ( void* attr_mem_op, void* assert_mem_op, ComponentSyntaxInfo *csi_attr, ComponentAssertion* ca ) { int rc; ComponentSyntaxInfo *csi_temp = NULL, *csi_assert = NULL, *comp_elmt = NULL; ComponentReference *cr = ca->ca_comp_ref; struct berval *ca_val = &ca->ca_ma_value; switch ( cr->cr_curr->ci_type ) { case LDAP_COMPREF_ALL: if ( IS_TERMINAL_COMPREF(cr) ) { FOR_EACH_LIST_ELMT( comp_elmt, &((ComponentList*)csi_attr)->comp_list ) { rc = comp_test_one_component( attr_mem_op, assert_mem_op, comp_elmt, ca ); if ( rc == LDAP_COMPARE_TRUE ) { break; } } } else { ComponentId *start_compid = ca->ca_comp_ref->cr_curr->ci_next; FOR_EACH_LIST_ELMT( comp_elmt, &((ComponentList*)csi_attr)->comp_list ) { cr->cr_curr = start_compid; rc = comp_test_components ( attr_mem_op, assert_mem_op, comp_elmt, ca ); if ( rc != LDAP_COMPARE_FALSE ) { break; } #if 0 if ( rc == LDAP_COMPARE_TRUE ) { break; } #endif } } break; case LDAP_COMPREF_CONTENT: case LDAP_COMPREF_SELECT: case LDAP_COMPREF_DEFINED: case LDAP_COMPREF_UNDEFINED: case LDAP_COMPREF_IDENTIFIER: case LDAP_COMPREF_FROM_BEGINNING: case LDAP_COMPREF_FROM_END: case LDAP_COMPREF_COUNT: rc = LDAP_OPERATIONS_ERROR; break; default: rc = LDAP_OPERATIONS_ERROR; } return rc; } void eat_bv_whsp ( struct berval* in ) { char* end = in->bv_val + in->bv_len; for ( ; ( *in->bv_val == ' ' ) && ( in->bv_val < end ) ; ) { in->bv_val++; } } /* * Perform matching one referenced component against assertion * If the matching rule in a component filter is allComponentsMatch * or its derivatives the extracted component's ASN.1 specification * is applied to the assertion value as its syntax * Otherwise, the matching rule's syntax is applied to the assertion value * By RFC 3687 */ int comp_test_one_component ( void* attr_mem_op, void* assert_mem_op, ComponentSyntaxInfo *csi_attr, ComponentAssertion *ca ) { int len, rc; ComponentSyntaxInfo *csi_assert = NULL; char* oid = NULL; MatchingRule* mr = ca->ca_ma_rule; if ( mr->smr_usage & SLAP_MR_COMPONENT ) { /* If allComponentsMatch or its derivatives */ if ( !ca->ca_comp_data.cd_tree ) { comp_convert_assert_to_comp( assert_mem_op, csi_attr, &ca->ca_ma_value, &csi_assert, &len, DEC_ALLOC_MODE_0 ); ca->ca_comp_data.cd_tree = (void*)csi_assert; } else { csi_assert = ca->ca_comp_data.cd_tree; } if ( !csi_assert ) return LDAP_PROTOCOL_ERROR; if ( strcmp( mr->smr_mrule.mr_oid, OID_ALL_COMP_MATCH ) != 0 ) { /* allComponentMatch's derivatives */ oid = mr->smr_mrule.mr_oid; } return csi_attr->csi_comp_desc->cd_all_match( oid, csi_attr, csi_assert ); } else { /* LDAP existing matching rules */ struct berval attr_bv = BER_BVNULL; struct berval n_attr_bv = BER_BVNULL; struct berval* assert_bv = &ca->ca_ma_value; int allocated = 0; /*Attribute is converted to compatible LDAP encodings*/ if ( comp_convert_asn_to_ldap( mr, csi_attr, &attr_bv, &allocated ) != LDAP_SUCCESS ) return LDAP_INAPPROPRIATE_MATCHING; /* extracted component value is not normalized */ if ( ca->ca_ma_rule->smr_normalize ) { rc = ca->ca_ma_rule->smr_normalize ( SLAP_MR_VALUE_OF_ASSERTION_SYNTAX, NULL, ca->ca_ma_rule, &attr_bv, &n_attr_bv, NULL ); if ( rc != LDAP_SUCCESS ) return rc; if ( allocated && attr_bv.bv_val ) free (attr_bv.bv_val); } else { n_attr_bv = attr_bv; } #if 0 /*Assertion value is validated by MR's syntax*/ if ( !ca->ca_comp_data.cd_tree ) { ca->ca_comp_data.cd_tree = assert_bv; } else { assert_bv = ca->ca_comp_data.cd_tree; } #endif if ( !n_attr_bv.bv_val ) return LDAP_COMPARE_FALSE; rc = csi_value_match( mr, &n_attr_bv, assert_bv ); if ( n_attr_bv.bv_val ) free ( n_attr_bv.bv_val ); return rc; } } int comp_test_components( void* attr_nm, void* assert_nm, ComponentSyntaxInfo* csi_attr, ComponentAssertion* ca) { char* peek_head; int mode, bytesDecoded = 0, rc; GenBuf* b; ExpBuf* buf; OidDecoderMapping* odm; struct berval bv; char oid[MAX_OID_LEN]; void* contained_comp, *anytype_comp; ComponentReference* cr = ca->ca_comp_ref; if ( !cr ) return comp_test_one_component ( attr_nm, assert_nm, csi_attr, ca ); /* Extracting the component referenced by ca->ca_comp_ref */ csi_attr = (ComponentSyntaxInfo*)csi_attr->csi_comp_desc->cd_extract_i( attr_nm, cr, csi_attr ); if ( !csi_attr ) return LDAP_INVALID_SYNTAX; /* perform matching, considering the type of a Component Reference(CR)*/ switch( cr->cr_curr->ci_type ) { case LDAP_COMPREF_IDENTIFIER: case LDAP_COMPREF_FROM_BEGINNING: case LDAP_COMPREF_FROM_END: case LDAP_COMPREF_COUNT: /* * Exactly one component is referenced * Fast Path for matching for this case */ rc = comp_test_one_component ( attr_nm, assert_nm, csi_attr, ca ); break; case LDAP_COMPREF_ALL: /* * If type CR is used * more than one component will be tested */ rc = comp_test_all_components ( attr_nm, assert_nm, csi_attr, ca ); break; case LDAP_COMPREF_CONTENT: /* * type CR is used * check if it is followed by * and then decode the OCTET/BIT STRING with the decoder * Finally, extract the target component with the remaining CR. * 2) If not, just return the current component, It SHOULD not be * extracted further, because the component MUST be BIT/OCTET * string. */ cr->cr_curr = cr->cr_curr->ci_next; if ( !cr->cr_curr ) { /* case 2) in above description */ rc = comp_test_one_component ( attr_nm, assert_nm, csi_attr, ca ); break; } if ( cr->cr_curr->ci_type == LDAP_COMPREF_SELECT ) { /* Look up OID mapping table */ odm = RetrieveOidDecoderMappingbyBV( &cr->cr_curr->ci_val.ci_select_value ); if ( !odm || !odm->BER_Decode ) return LDAP_PROTOCOL_ERROR; /* current component MUST be either BIT or OCTET STRING */ if ( csi_attr->csi_comp_desc->cd_type_id != BASICTYPE_BITSTRING ) { bv.bv_val = ((ComponentBits*)csi_attr)->value.bits; bv.bv_len = ((ComponentBits*)csi_attr)->value.bitLen; } else if ( csi_attr->csi_comp_desc->cd_type_id != BASICTYPE_BITSTRING ) { bv.bv_val = ((ComponentOcts*)csi_attr)->value.octs; bv.bv_len = ((ComponentOcts*)csi_attr)->value.octetLen; } else return LDAP_PROTOCOL_ERROR; buf = ExpBufAllocBuf(); ExpBuftoGenBuf( buf, &b ); ExpBufInstallDataInBuf ( buf, bv.bv_val, bv.bv_len ); BufResetInReadMode( b ); mode = DEC_ALLOC_MODE_2; /* Try to decode with BER/DER decoder */ rc = odm->BER_Decode ( attr_nm, b, (ComponentSyntaxInfo*)&contained_comp, &bytesDecoded, mode ); ExpBufFreeBuf( buf ); GenBufFreeBuf( b ); if ( rc != LDAP_SUCCESS ) return LDAP_PROTOCOL_ERROR; /* xxx.content.(x.xy.xyz).rfc822Name */ /* In the aboe Ex. move CR to the right to (x.xy.xyz)*/ cr->cr_curr = cr->cr_curr->ci_next; if (!cr->cr_curr ) rc = comp_test_one_component ( attr_nm, assert_nm, csi_attr, ca ); else rc = comp_test_components( attr_nm, assert_nm, contained_comp, ca ); } else { /* Invalid Component reference */ rc = LDAP_PROTOCOL_ERROR; } break; case LDAP_COMPREF_SELECT: if (csi_attr->csi_comp_desc->cd_type_id != BASICTYPE_ANY ) return LDAP_INVALID_SYNTAX; rc = CheckSelectTypeCorrect( attr_nm, ((ComponentAny*)csi_attr)->cai, &cr->cr_curr->ci_val.ci_select_value ); if ( rc < 0 ) return LDAP_INVALID_SYNTAX; /* point to the real component, not any type component */ csi_attr = ((ComponentAny*)csi_attr)->value; cr->cr_curr = cr->cr_curr->ci_next; if ( cr->cr_curr ) rc = comp_test_components( attr_nm, assert_nm, csi_attr, ca); else rc = comp_test_one_component( attr_nm, assert_nm, csi_attr, ca); break; default: rc = LDAP_INVALID_SYNTAX; } return rc; } void* comp_nibble_memory_allocator ( int init_mem, int inc_mem ) { void* nm; nm = (void*)InitNibbleMemLocal( (unsigned long)init_mem, (unsigned long)inc_mem ); if ( !nm ) return NULL; else return (void*)nm; } void comp_nibble_memory_free ( void* nm ) { ShutdownNibbleMemLocal( nm ); } void* comp_get_component_description ( int id ) { if ( asntype_to_compdesc_mapping_tbl[id].atcd_typeId == id ) return &asntype_to_compdesc_mapping_tbl[id].atcd_cd; else return NULL; } int comp_component_encoder ( void* mem_op, ComponentSyntaxInfo* csi , struct berval* nval ) { int size, rc; GenBuf* b; ExpBuf* buf; struct berval bv; buf = ExpBufAllocBufAndData(); ExpBufResetInWriteRvsMode(buf); ExpBuftoGenBuf( buf, &b ); if ( !csi->csi_comp_desc->cd_gser_encoder && !csi->csi_comp_desc->cd_ldap_encoder ) return (-1); /* * if an LDAP specific encoder is provided : * dn and rdn have their LDAP specific encoder */ if ( csi->csi_comp_desc->cd_ldap_encoder ) { rc = csi->csi_comp_desc->cd_ldap_encoder( csi, &bv ); if ( rc != LDAP_SUCCESS ) return rc; if ( mem_op ) nval->bv_val = CompAlloc( mem_op, bv.bv_len ); else nval->bv_val = malloc( size ); memcpy( nval->bv_val, bv.bv_val, bv.bv_len ); nval->bv_len = bv.bv_len; /* * This free will be eliminated by making ldap_encoder * use nibble memory in it */ free ( bv.bv_val ); GenBufFreeBuf( b ); BufFreeBuf( buf ); return LDAP_SUCCESS; } rc = csi->csi_comp_desc->cd_gser_encoder( b, csi ); if ( rc < 0 ) { GenBufFreeBuf( b ); BufFreeBuf( buf ); return rc; } size = ExpBufDataSize( buf ); if ( size > 0 ) { if ( mem_op ) nval->bv_val = CompAlloc ( mem_op, size ); else nval->bv_val = malloc( size ); nval->bv_len = size; BufResetInReadMode(b); BufCopy( nval->bv_val, b, size ); } ExpBufFreeBuf( buf ); GenBufFreeBuf( b ); return LDAP_SUCCESS; } #if SLAPD_COMP_MATCH == SLAPD_MOD_DYNAMIC #include "certificate.h" extern convert_attr_to_comp_func* attr_converter; extern convert_assert_to_comp_func* assert_converter; extern convert_asn_to_ldap_func* csi_converter; extern free_component_func* component_destructor; extern test_component_func* test_components; extern alloc_nibble_func* nibble_mem_allocator; extern free_nibble_func* nibble_mem_free; extern test_membership_func* is_aliased_attribute; extern get_component_info_func* get_component_description; extern component_encoder_func* component_encoder; int init_module(int argc, char *argv[]) { /* * Initialize function pointers in slapd */ attr_converter = (convert_attr_to_comp_func*)comp_convert_attr_to_comp; assert_converter = (convert_assert_to_comp_func*)comp_convert_assert_to_comp; component_destructor = (free_component_func*)comp_free_component; test_components = (test_component_func*)comp_test_components; nibble_mem_allocator = (free_nibble_func*)comp_nibble_memory_allocator; nibble_mem_free = (free_nibble_func*)comp_nibble_memory_free; is_aliased_attribute = (test_membership_func*)comp_is_aliased_attribute; get_component_description = (get_component_info_func*)comp_get_component_description; component_encoder = (component_encoder_func*)comp_component_encoder; /* file path needs to be */ load_derived_matching_rule ("derived_mr.cfg"); /* the initialization for example X.509 certificate */ init_module_AuthenticationFramework(); init_module_AuthorityKeyIdentifierDefinition(); init_module_CertificateRevokationList(); init_attribute_aliasing_table (); init_component_description_table (); return 0; } #endif /* SLAPD_PASSWD */