static int matchingRuleMatch( int *matchp, slap_mask_t flags, Syntax *syntax, MatchingRule *mr, struct berval *value, void *assertedValue ) { struct berval *a = (struct berval *) assertedValue; MatchingRule *mrv = mr_bvfind( value ); MatchingRule *asserted = mr_bvfind( a ); if( asserted == NULL ) { if( OID_LEADCHAR( *a->bv_val ) ) { /* OID form, return FALSE */ *matchp = 1; return LDAP_SUCCESS; } /* desc form, return undefined */ return LDAP_INVALID_SYNTAX; } if ( mrv == NULL ) { /* unrecognized stored value */ return LDAP_INVALID_SYNTAX; } *matchp = ( asserted != mrv ); 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; } }
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; }
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; }
static int test_ava_filter( Operation *op, Entry *e, AttributeAssertion *ava, int type ) { int rc; Attribute *a; #ifdef LDAP_COMP_MATCH int i, num_attr_vals = 0; AttributeAliasing *a_alias = NULL; #endif if ( !access_allowed( op, e, ava->aa_desc, &ava->aa_value, ACL_SEARCH, NULL ) ) { return LDAP_INSUFFICIENT_ACCESS; } if ( ava->aa_desc == slap_schema.si_ad_hasSubordinates && op && op->o_bd && op->o_bd->be_has_subordinates ) { int hasSubordinates; struct berval hs; if( type != LDAP_FILTER_EQUALITY && type != LDAP_FILTER_APPROX ) { /* No other match is allowed */ return LDAP_INAPPROPRIATE_MATCHING; } if ( op->o_bd->be_has_subordinates( op, e, &hasSubordinates ) != LDAP_SUCCESS ) { return LDAP_OTHER; } if ( hasSubordinates == LDAP_COMPARE_TRUE ) { hs = slap_true_bv; } else if ( hasSubordinates == LDAP_COMPARE_FALSE ) { hs = slap_false_bv; } else { return LDAP_OTHER; } if ( bvmatch( &ava->aa_value, &hs ) ) return LDAP_COMPARE_TRUE; return LDAP_COMPARE_FALSE; } if ( ava->aa_desc == slap_schema.si_ad_entryDN ) { MatchingRule *mr; int match; const char *text; if( type != LDAP_FILTER_EQUALITY && type != LDAP_FILTER_APPROX ) { /* No other match is allowed */ return LDAP_INAPPROPRIATE_MATCHING; } mr = slap_schema.si_ad_entryDN->ad_type->sat_equality; assert( mr != NULL ); rc = value_match( &match, slap_schema.si_ad_entryDN, mr, SLAP_MR_EXT, &e->e_nname, &ava->aa_value, &text ); if( rc != LDAP_SUCCESS ) return rc; if( match == 0 ) return LDAP_COMPARE_TRUE; return LDAP_COMPARE_FALSE; } rc = LDAP_COMPARE_FALSE; #ifdef LDAP_COMP_MATCH if ( is_aliased_attribute && ava->aa_cf ) { a_alias = is_aliased_attribute ( ava->aa_desc ); if ( a_alias ) ava->aa_desc = a_alias->aa_aliased_ad; else ava->aa_cf = NULL; } #endif for(a = attrs_find( e->e_attrs, ava->aa_desc ); a != NULL; a = attrs_find( a->a_next, ava->aa_desc ) ) { int use; MatchingRule *mr; struct berval *bv; if (( ava->aa_desc != a->a_desc ) && !access_allowed( op, e, a->a_desc, &ava->aa_value, ACL_SEARCH, NULL )) { rc = LDAP_INSUFFICIENT_ACCESS; continue; } use = SLAP_MR_EQUALITY; switch ( type ) { case LDAP_FILTER_APPROX: use = SLAP_MR_EQUALITY_APPROX; mr = a->a_desc->ad_type->sat_approx; if( mr != NULL ) break; /* fallthru: use EQUALITY matching rule if no APPROX rule */ case LDAP_FILTER_EQUALITY: /* use variable set above so fall thru use is not clobbered */ mr = a->a_desc->ad_type->sat_equality; break; case LDAP_FILTER_GE: case LDAP_FILTER_LE: use = SLAP_MR_ORDERING; mr = a->a_desc->ad_type->sat_ordering; break; default: mr = NULL; } if( mr == NULL ) { rc = LDAP_INAPPROPRIATE_MATCHING; continue; } /* We have no Sort optimization for Approx matches */ if (( a->a_flags & SLAP_ATTR_SORTED_VALS ) && type != LDAP_FILTER_APPROX ) { unsigned slot; int ret; /* For Ordering matches, we just need to do one comparison with * either the first (least) or last (greatest) value. */ if ( use == SLAP_MR_ORDERING ) { const char *text; int match, which; which = (type == LDAP_FILTER_LE) ? 0 : a->a_numvals-1; ret = value_match( &match, a->a_desc, mr, use, &a->a_nvals[which], &ava->aa_value, &text ); if ( ret != LDAP_SUCCESS ) return ret; if (( type == LDAP_FILTER_LE && match <= 0 ) || ( type == LDAP_FILTER_GE && match >= 0 )) return LDAP_COMPARE_TRUE; continue; } /* Only Equality will get here */ ret = attr_valfind( a, use | SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH | SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH, &ava->aa_value, &slot, NULL ); if ( ret == LDAP_SUCCESS ) return LDAP_COMPARE_TRUE; else if ( ret != LDAP_NO_SUCH_ATTRIBUTE ) return ret; #if 0 /* The following is useful if we want to know which values * matched an ordering test. But here we don't care, we just * want to know if any value did, and that is checked above. */ if ( ret == LDAP_NO_SUCH_ATTRIBUTE ) { /* If insertion point is not the end of the list, there was * at least one value greater than the assertion. */ if ( type == LDAP_FILTER_GE && slot < a->a_numvals ) return LDAP_COMPARE_TRUE; /* Likewise, if insertion point is not the head of the list, * there was at least one value less than the assertion. */ if ( type == LDAP_FILTER_LE && slot > 0 ) return LDAP_COMPARE_TRUE; return LDAP_COMPARE_FALSE; } #endif continue; } #ifdef LDAP_COMP_MATCH if ( nibble_mem_allocator && ava->aa_cf && !a->a_comp_data ) { /* Component Matching */ for ( num_attr_vals = 0; a->a_vals[num_attr_vals].bv_val != NULL; num_attr_vals++ ); if ( num_attr_vals <= 0 )/* no attribute value */ return LDAP_INAPPROPRIATE_MATCHING; num_attr_vals++;/* for NULL termination */ /* following malloced will be freed by comp_tree_free () */ a->a_comp_data = SLAP_MALLOC( sizeof( ComponentData ) + sizeof( ComponentSyntaxInfo* )*num_attr_vals ); if ( !a->a_comp_data ) { return LDAP_NO_MEMORY; } a->a_comp_data->cd_tree = (ComponentSyntaxInfo**)((char*)a->a_comp_data + sizeof(ComponentData)); i = num_attr_vals; for ( ; i ; i-- ) { a->a_comp_data->cd_tree[ i-1 ] = (ComponentSyntaxInfo*)NULL; } a->a_comp_data->cd_mem_op = nibble_mem_allocator ( 1024*10*(num_attr_vals-1), 1024 ); if ( a->a_comp_data->cd_mem_op == NULL ) { free ( a->a_comp_data ); a->a_comp_data = NULL; return LDAP_OPERATIONS_ERROR; } } i = 0; #endif for ( bv = a->a_nvals; !BER_BVISNULL( bv ); bv++ ) { int ret, match; const char *text; #ifdef LDAP_COMP_MATCH if( attr_converter && ava->aa_cf && a->a_comp_data ) { /* Check if decoded component trees are already linked */ struct berval cf_bv = { 20, "componentFilterMatch" }; MatchingRule* cf_mr = mr_bvfind( &cf_bv ); MatchingRuleAssertion mra; mra.ma_cf = ava->aa_cf; if ( a->a_comp_data->cd_tree[i] == NULL ) a->a_comp_data->cd_tree[i] = attr_converter (a, a->a_desc->ad_type->sat_syntax, (a->a_vals + i)); /* decoding error */ if ( !a->a_comp_data->cd_tree[i] ) { free_ComponentData ( a ); return LDAP_OPERATIONS_ERROR; } ret = value_match( &match, a->a_desc, cf_mr, SLAP_MR_COMPONENT, (struct berval*)a->a_comp_data->cd_tree[i++], (void*)&mra, &text ); if ( ret == LDAP_INAPPROPRIATE_MATCHING ) { /* cached component tree is broken, just remove it */ free_ComponentData ( a ); return ret; } if ( a_alias ) ava->aa_desc = a_alias->aa_aliasing_ad; } else #endif { ret = ordered_value_match( &match, a->a_desc, mr, use, bv, &ava->aa_value, &text ); } if( ret != LDAP_SUCCESS ) { rc = ret; break; } switch ( type ) { case LDAP_FILTER_EQUALITY: case LDAP_FILTER_APPROX: if ( match == 0 ) return LDAP_COMPARE_TRUE; break; case LDAP_FILTER_GE: if ( match >= 0 ) return LDAP_COMPARE_TRUE; break; case LDAP_FILTER_LE: if ( match <= 0 ) return LDAP_COMPARE_TRUE; break; } } } #ifdef LDAP_COMP_MATCH if ( a_alias ) ava->aa_desc = a_alias->aa_aliasing_ad; #endif return rc; }
int get_mra( Operation *op, BerElement *ber, Filter *f, const char **text ) { int rc; ber_tag_t tag, rtag; ber_len_t length; struct berval type = BER_BVNULL; struct berval value = BER_BVNULL; struct berval rule_text = BER_BVNULL; MatchingRuleAssertion ma = { 0 }; #ifdef LDAP_COMP_MATCH AttributeAliasing* aa = NULL; #endif rtag = ber_scanf( ber, "{t" /*"}"*/, &tag ); if( rtag == LBER_ERROR ) { Debug( LDAP_DEBUG_ANY, " get_mra ber_scanf\n", 0, 0, 0 ); *text = "Error parsing matching rule assertion"; return SLAPD_DISCONNECT; } if ( tag == LDAP_FILTER_EXT_OID ) { rtag = ber_scanf( ber, "m", &rule_text ); if ( rtag == LBER_ERROR ) { Debug( LDAP_DEBUG_ANY, " get_mra ber_scanf for mr\n", 0, 0, 0 ); *text = "Error parsing matching rule in matching rule assertion"; return SLAPD_DISCONNECT; } rtag = ber_scanf( ber, "t", &tag ); if( rtag == LBER_ERROR ) { Debug( LDAP_DEBUG_ANY, " get_mra ber_scanf\n", 0, 0, 0 ); *text = "Error parsing matching rule assertion"; return SLAPD_DISCONNECT; } } if ( tag == LDAP_FILTER_EXT_TYPE ) { rtag = ber_scanf( ber, "m", &type ); if ( rtag == LBER_ERROR ) { Debug( LDAP_DEBUG_ANY, " get_mra ber_scanf for ad\n", 0, 0, 0 ); *text = "Error parsing attribute description in matching rule assertion"; return SLAPD_DISCONNECT; } rtag = ber_scanf( ber, "t", &tag ); if( rtag == LBER_ERROR ) { Debug( LDAP_DEBUG_ANY, " get_mra ber_scanf\n", 0, 0, 0 ); *text = "Error parsing matching rule assertion"; return SLAPD_DISCONNECT; } } if ( tag != LDAP_FILTER_EXT_VALUE ) { Debug( LDAP_DEBUG_ANY, " get_mra ber_scanf missing value\n", 0, 0, 0 ); *text = "Missing value in matching rule assertion"; return SLAPD_DISCONNECT; } rtag = ber_scanf( ber, "m", &value ); if( rtag == LBER_ERROR ) { Debug( LDAP_DEBUG_ANY, " get_mra ber_scanf\n", 0, 0, 0 ); *text = "Error decoding value in matching rule assertion"; return SLAPD_DISCONNECT; } tag = ber_peek_tag( ber, &length ); if ( tag == LDAP_FILTER_EXT_DNATTRS ) { rtag = ber_scanf( ber, /*"{"*/ "b}", &ma.ma_dnattrs ); } else { rtag = ber_scanf( ber, /*"{"*/ "}" ); } if( rtag == LBER_ERROR ) { Debug( LDAP_DEBUG_ANY, " get_mra ber_scanf\n", 0, 0, 0 ); *text = "Error decoding dnattrs matching rule assertion"; return SLAPD_DISCONNECT; } if( type.bv_val != NULL ) { rc = slap_bv2ad( &type, &ma.ma_desc, text ); if( rc != LDAP_SUCCESS ) { f->f_choice |= SLAPD_FILTER_UNDEFINED; rc = slap_bv2undef_ad( &type, &ma.ma_desc, text, SLAP_AD_PROXIED|SLAP_AD_NOINSERT ); if( rc != LDAP_SUCCESS ) { ma.ma_desc = slap_bv2tmp_ad( &type, op->o_tmpmemctx ); rc = LDAP_SUCCESS; } } } if( rule_text.bv_val != NULL ) { ma.ma_rule = mr_bvfind( &rule_text ); if( ma.ma_rule == NULL ) { *text = "matching rule not recognized"; return LDAP_INAPPROPRIATE_MATCHING; } } if ( ma.ma_rule == NULL ) { /* * Need either type or rule ... */ if ( ma.ma_desc == NULL ) { *text = "no matching rule or type"; return LDAP_INAPPROPRIATE_MATCHING; } if ( ma.ma_desc->ad_type->sat_equality != NULL && ma.ma_desc->ad_type->sat_equality->smr_usage & SLAP_MR_EXT ) { /* no matching rule was provided, use the attribute's equality rule if it supports extensible matching. */ ma.ma_rule = ma.ma_desc->ad_type->sat_equality; } else { *text = "no appropriate rule to use for type"; return LDAP_INAPPROPRIATE_MATCHING; } } if ( ma.ma_desc != NULL ) { if( !mr_usable_with_at( ma.ma_rule, ma.ma_desc->ad_type ) ) { *text = "matching rule use with this attribute not appropriate"; return LDAP_INAPPROPRIATE_MATCHING; } } /* * Normalize per matching rule */ rc = asserted_value_validate_normalize( ma.ma_desc, ma.ma_rule, SLAP_MR_EXT|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX, &value, &ma.ma_value, text, op->o_tmpmemctx ); if( rc != LDAP_SUCCESS ) return rc; #ifdef LDAP_COMP_MATCH /* Check If this attribute is aliased */ if ( is_aliased_attribute && ma.ma_desc && ( aa = is_aliased_attribute ( ma.ma_desc ) ) ) { rc = get_aliased_filter ( op, &ma, aa, text ); if ( rc != LDAP_SUCCESS ) return rc; } else if ( ma.ma_rule && ma.ma_rule->smr_usage & SLAP_MR_COMPONENT ) { /* Matching Rule for Component Matching */ rc = get_comp_filter( op, &ma.ma_value, &ma.ma_cf, text ); if ( rc != LDAP_SUCCESS ) return rc; } #endif length = sizeof(ma); /* Append rule_text to end of struct */ if (rule_text.bv_val) length += rule_text.bv_len + 1; f->f_mra = op->o_tmpalloc( length, op->o_tmpmemctx ); *f->f_mra = ma; if (rule_text.bv_val) { f->f_mra->ma_rule_text.bv_len = rule_text.bv_len; f->f_mra->ma_rule_text.bv_val = (char *)(f->f_mra+1); AC_MEMCPY(f->f_mra->ma_rule_text.bv_val, rule_text.bv_val, rule_text.bv_len+1); } return LDAP_SUCCESS; }