+ 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 ) {
+ for ( ;
+ !BER_BVISNULL( &a->a_vals[num_attr_vals] );
+ num_attr_vals++ )
+ {
+ /* empty */;
+ }
+ 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 = 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: draft-ietf-ldapbis-protocol
+
+ 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 [Syntaxes]),
+ 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;
+ }
+ }