Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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;
	}
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
0
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;
}