Beispiel #1
0
static int
test_mra_vrFilter(
	Operation	*op,
	Attribute	*a,
	MatchingRuleAssertion *mra,
	char 		***e_flags )
{
	int	i, j;

	for ( i = 0; a != NULL; a = a->a_next, i++ ) {
		struct berval	*bv, assertedValue;
		int		normalize_attribute = 0;

		if ( mra->ma_desc ) {
			if ( !is_ad_subtype( a->a_desc, mra->ma_desc ) ) {
				continue;
			}
			assertedValue = mra->ma_value;

		} else {
			int rc;
			const char	*text = NULL;

			/* check if matching is appropriate */
			if ( !mr_usable_with_at( mra->ma_rule, a->a_desc->ad_type ) ) {
				continue;
			}

			rc = asserted_value_validate_normalize( a->a_desc, mra->ma_rule,
				SLAP_MR_EXT|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX,
				&mra->ma_value, &assertedValue, &text, op->o_tmpmemctx );

			if ( rc != LDAP_SUCCESS ) continue;
		}

		/* check match */
		if ( mra->ma_rule == a->a_desc->ad_type->sat_equality ) {
			bv = a->a_nvals;

		} else {
			bv = a->a_vals;
			normalize_attribute = 1;
		}

		for ( j = 0; !BER_BVISNULL( bv ); bv++, j++ ) {
			int		rc, match;
			const char	*text;
			struct berval	nbv = BER_BVNULL;

			if ( normalize_attribute && mra->ma_rule->smr_normalize ) {
				/* see comment in filterentry.c */
				if ( mra->ma_rule->smr_normalize(
						SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
						mra->ma_rule->smr_syntax,
						mra->ma_rule,
						bv, &nbv, op->o_tmpmemctx ) != LDAP_SUCCESS )
				{
					/* FIXME: stop processing? */
					continue;
				}

			} else {
				nbv = *bv;
			}

			rc = value_match( &match, a->a_desc, mra->ma_rule, 0,
				&nbv, &assertedValue, &text );

			if ( nbv.bv_val != bv->bv_val ) {
				op->o_tmpfree( nbv.bv_val, op->o_tmpmemctx );
			}

			if ( rc != LDAP_SUCCESS ) return rc;

			if ( match == 0 ) {
				(*e_flags)[i][j] = 1;
			}
		}
	}

	return LDAP_SUCCESS;
}
Beispiel #2
0
static int test_mra_filter(
	Operation *op,
	Entry *e,
	MatchingRuleAssertion *mra )
{
	Attribute	*a;
	void		*memctx;
	BER_MEMFREE_FN	*memfree;
#ifdef LDAP_COMP_MATCH
	int i, num_attr_vals = 0;
#endif

	if ( op == NULL ) {
		memctx = NULL;
		memfree = slap_sl_free;
	} else {
		memctx = op->o_tmpmemctx;
		memfree = op->o_tmpfree;
	}

	if ( mra->ma_desc ) {
		/*
		 * if ma_desc is available, then we're filtering for
		 * one attribute, and SEARCH permissions can be checked
		 * directly.
		 */
		if ( !access_allowed( op, e,
			mra->ma_desc, &mra->ma_value, ACL_SEARCH, NULL ) )
		{
			return LDAP_INSUFFICIENT_ACCESS;
		}

		if ( mra->ma_desc == slap_schema.si_ad_entryDN ) {
			int ret, rc;
			const char *text;

			rc = value_match( &ret, slap_schema.si_ad_entryDN, mra->ma_rule,
				SLAP_MR_EXT, &e->e_nname, &mra->ma_value, &text );
	
	
			if( rc != LDAP_SUCCESS ) return rc;
			if ( ret == 0 ) return LDAP_COMPARE_TRUE;
			return LDAP_COMPARE_FALSE;
		}

		for ( a = attrs_find( e->e_attrs, mra->ma_desc );
			a != NULL;
			a = attrs_find( a->a_next, mra->ma_desc ) )
		{
			struct berval	*bv;
			int		normalize_attribute = 0;

#ifdef LDAP_COMP_MATCH
			/* Component Matching */
			if ( mra->ma_cf && mra->ma_rule->smr_usage & SLAP_MR_COMPONENT ) {
				num_attr_vals = 0;
				if ( !a->a_comp_data ) {
					num_attr_vals = a->a_numvals;
					if ( num_attr_vals <= 0 ) {
						/* no attribute value */
						return LDAP_INAPPROPRIATE_MATCHING;
					}
					num_attr_vals++;

					/* 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));
					a->a_comp_data->cd_tree[num_attr_vals - 1] =
						(ComponentSyntaxInfo*) NULL;
					a->a_comp_data->cd_mem_op =
						nibble_mem_allocator( 1024*16, 1024 );
				}
			}
#endif

			/* If ma_rule is not the same as the attribute's
			 * normal rule, then we can't use the a_nvals.
			 */
			if ( mra->ma_rule == a->a_desc->ad_type->sat_equality ) {
				bv = a->a_nvals;

			} else {
				bv = a->a_vals;
				normalize_attribute = 1;
			}
#ifdef LDAP_COMP_MATCH
			i = 0;
#endif
			for ( ; !BER_BVISNULL( bv ); bv++ ) {
				int ret;
				int rc;
				const char *text;
	
#ifdef LDAP_COMP_MATCH
				if ( mra->ma_cf &&
					mra->ma_rule->smr_usage & SLAP_MR_COMPONENT )
				{
					/* Check if decoded component trees are already linked */
					if ( num_attr_vals ) {
						a->a_comp_data->cd_tree[i] = attr_converter(
							a, a->a_desc->ad_type->sat_syntax, bv );
					}
					/* decoding error */
					if ( !a->a_comp_data->cd_tree[i] ) {
						return LDAP_OPERATIONS_ERROR;
					}
					rc = value_match( &ret, a->a_desc, mra->ma_rule,
						SLAP_MR_COMPONENT,
						(struct berval*)a->a_comp_data->cd_tree[i++],
						(void*)mra, &text );
				} else 
#endif
				{
					struct berval	nbv = BER_BVNULL;

					if ( normalize_attribute && mra->ma_rule->smr_normalize ) {
						/*
				
				Document: RFC 4511

				    4.5.1. Search Request 
				        ...
				    If the type field is present and the matchingRule is present, 
			            the matchValue is compared against entry attributes of the 
			            specified type. In this case, the matchingRule MUST be one 
				    suitable for use with the specified type (see [RFC4517]), 
				    otherwise the filter item is Undefined.  


				In this case, since the matchingRule requires the assertion
				value to be normalized, we normalize the attribute value
				according to the syntax of the matchingRule.

				This should likely be done inside value_match(), by passing
				the appropriate flags, but this is not done at present.
				See ITS#3406.
						 */
						if ( mra->ma_rule->smr_normalize(
								SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
								mra->ma_rule->smr_syntax,
								mra->ma_rule,
								bv, &nbv, memctx ) != LDAP_SUCCESS )
						{
							/* FIXME: stop processing? */
							continue;
						}

					} else {
						nbv = *bv;
					}

					rc = value_match( &ret, a->a_desc, mra->ma_rule,
						SLAP_MR_EXT, &nbv, &mra->ma_value, &text );

					if ( nbv.bv_val != bv->bv_val ) {
						memfree( nbv.bv_val, memctx );
					}
				}

				if ( rc != LDAP_SUCCESS ) return rc;
				if ( ret == 0 ) return LDAP_COMPARE_TRUE;
			}
		}

	} else {
		/*
		 * No attribute description: test all
		 */
		for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
			struct berval	*bv, value;
			const char	*text = NULL;
			int		rc;
			int		normalize_attribute = 0;

			/* check if matching is appropriate */
			if ( !mr_usable_with_at( mra->ma_rule, a->a_desc->ad_type ) ) {
				continue;
			}

			/* normalize for equality */
			rc = asserted_value_validate_normalize( a->a_desc, mra->ma_rule,
				SLAP_MR_EXT|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX,
				&mra->ma_value, &value, &text, memctx );
			if ( rc != LDAP_SUCCESS ) continue;

			/* check search access */
			if ( !access_allowed( op, e,
				a->a_desc, &value, ACL_SEARCH, NULL ) )
			{
				memfree( value.bv_val, memctx );
				continue;
			}
#ifdef LDAP_COMP_MATCH
			/* Component Matching */
			if ( mra->ma_cf &&
				mra->ma_rule->smr_usage & SLAP_MR_COMPONENT )
			{
				int ret;

				rc = value_match( &ret, a->a_desc, mra->ma_rule,
					SLAP_MR_COMPONENT,
					(struct berval*)a, (void*)mra, &text );
				if ( rc != LDAP_SUCCESS ) break;
	
				if ( ret == 0 ) {
					rc = LDAP_COMPARE_TRUE;
					break;
				}

			}
#endif

			/* check match */
			if ( mra->ma_rule == a->a_desc->ad_type->sat_equality ) {
				bv = a->a_nvals;

			} else {
				bv = a->a_vals;
				normalize_attribute = 1;
			}

			for ( ; !BER_BVISNULL( bv ); bv++ ) {
				int		ret;
				struct berval	nbv = BER_BVNULL;

				if ( normalize_attribute && mra->ma_rule->smr_normalize ) {
					/* see comment above */
					if ( mra->ma_rule->smr_normalize(
							SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
							mra->ma_rule->smr_syntax,
							mra->ma_rule,
							bv, &nbv, memctx ) != LDAP_SUCCESS )
					{
						/* FIXME: stop processing? */
						continue;
					}

				} else {
					nbv = *bv;
				}

				rc = value_match( &ret, a->a_desc, mra->ma_rule,
					SLAP_MR_EXT, &nbv, &value, &text );

				if ( nbv.bv_val != bv->bv_val ) {
					memfree( nbv.bv_val, memctx );
				}

				if ( rc != LDAP_SUCCESS ) break;
	
				if ( ret == 0 ) {
					rc = LDAP_COMPARE_TRUE;
					break;
				}
			}
			memfree( value.bv_val, memctx );
			if ( rc != LDAP_SUCCESS ) return rc;
		}
	}

	/* check attrs in DN AVAs if required */
	if ( mra->ma_dnattrs && !BER_BVISEMPTY( &e->e_nname ) ) {
		LDAPDN		dn = NULL;
		int		iRDN, iAVA;
		int		rc;

		/* parse and pretty the dn */
		rc = dnPrettyDN( NULL, &e->e_name, &dn, memctx );
		if ( rc != LDAP_SUCCESS ) {
			return LDAP_INVALID_SYNTAX;
		}

		/* for each AVA of each RDN ... */
		for ( iRDN = 0; dn[ iRDN ]; iRDN++ ) {
			LDAPRDN		rdn = dn[ iRDN ];

			for ( iAVA = 0; rdn[ iAVA ]; iAVA++ ) {
				LDAPAVA		*ava = rdn[ iAVA ];
				struct berval	*bv = &ava->la_value,
						value = BER_BVNULL,
						nbv = BER_BVNULL;
				AttributeDescription *ad =
					(AttributeDescription *)ava->la_private;
				int		ret;
				const char	*text;

				assert( ad != NULL );

				if ( mra->ma_desc ) {
					/* have a mra type? check for subtype */
					if ( !is_ad_subtype( ad, mra->ma_desc ) ) {
						continue;
					}
					value = mra->ma_value;

				} else {
					const char	*text = NULL;

					/* check if matching is appropriate */
					if ( !mr_usable_with_at( mra->ma_rule, ad->ad_type ) ) {
						continue;
					}

					/* normalize for equality */
					rc = asserted_value_validate_normalize( ad,
						mra->ma_rule,
						SLAP_MR_EXT|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX,
						&mra->ma_value, &value, &text, memctx );
					if ( rc != LDAP_SUCCESS ) continue;

					/* check search access */
					if ( !access_allowed( op, e,
						ad, &value, ACL_SEARCH, NULL ) )
					{
						memfree( value.bv_val, memctx );
						continue;
					}
				}

				if ( mra->ma_rule->smr_normalize ) {
					/* see comment above */
					if ( mra->ma_rule->smr_normalize(
							SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
							mra->ma_rule->smr_syntax,
							mra->ma_rule,
							bv, &nbv, memctx ) != LDAP_SUCCESS )
					{
						/* FIXME: stop processing? */
						rc = LDAP_SUCCESS;
						ret = -1;
						goto cleanup;
					}

				} else {
					nbv = *bv;
				}

				/* check match */
				rc = value_match( &ret, ad, mra->ma_rule, SLAP_MR_EXT,
					&nbv, &value, &text );

cleanup:;
				if ( !BER_BVISNULL( &value ) && value.bv_val != mra->ma_value.bv_val ) {
					memfree( value.bv_val, memctx );
				}

				if ( !BER_BVISNULL( &nbv ) && nbv.bv_val != bv->bv_val ) {
					memfree( nbv.bv_val, memctx );
				}

				if ( rc == LDAP_SUCCESS && ret == 0 ) rc = LDAP_COMPARE_TRUE;

				if ( rc != LDAP_SUCCESS ) {
					ldap_dnfree_x( dn, memctx );
					return rc;
				}
			}
		}
		ldap_dnfree_x( dn, memctx );
	}

	return LDAP_COMPARE_FALSE;
}
Beispiel #3
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;
}