3 * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
4 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
6 /* mra.c - routines for dealing with extensible matching rule assertions */
12 #include <ac/string.h>
13 #include <ac/socket.h>
19 MatchingRuleAssertion *mra,
23 ch_free( mra->ma_value.bv_val );
25 ch_free( (char *) mra );
32 MatchingRuleAssertion **mra,
39 struct berval type = { 0, NULL }, value;
40 MatchingRuleAssertion *ma;
42 ma = ch_malloc( sizeof( MatchingRuleAssertion ) );
44 ma->ma_rule_text.bv_len = 0;
45 ma->ma_rule_text.bv_val = NULL;
48 ma->ma_value.bv_len = 0;
49 ma->ma_value.bv_val = NULL;
51 rtag = ber_scanf( ber, "{t", &tag );
53 if( rtag == LBER_ERROR ) {
55 LDAP_LOG( OPERATION, ERR,
56 "get_mra: ber_scanf (\"{t\") failure\n", 0, 0, 0 );
58 Debug( LDAP_DEBUG_ANY, " get_mra ber_scanf\n", 0, 0, 0 );
61 *text = "Error parsing matching rule assertion";
63 return SLAPD_DISCONNECT;
66 if ( tag == LDAP_FILTER_EXT_OID ) {
67 rtag = ber_scanf( ber, "m", &ma->ma_rule_text );
68 if ( rtag == LBER_ERROR ) {
70 LDAP_LOG( OPERATION, ERR,
71 "get_mra: ber_scanf(\"o\") failure.\n", 0, 0, 0 );
73 Debug( LDAP_DEBUG_ANY, " get_mra ber_scanf for mr\n", 0, 0, 0 );
76 *text = "Error parsing matching rule in matching rule assertion";
78 return SLAPD_DISCONNECT;
81 rtag = ber_scanf( ber, "t", &tag );
82 if( rtag == LBER_ERROR ) {
84 LDAP_LOG( OPERATION, ERR,
85 "get_mra: ber_scanf (\"t\") failure\n", 0, 0, 0 );
87 Debug( LDAP_DEBUG_ANY, " get_mra ber_scanf\n", 0, 0, 0 );
90 *text = "Error parsing matching rule assertion";
92 return SLAPD_DISCONNECT;
96 if ( tag == LDAP_FILTER_EXT_TYPE ) {
97 rtag = ber_scanf( ber, "m", &type );
98 if ( rtag == LBER_ERROR ) {
100 LDAP_LOG( OPERATION, ERR,
101 "get_mra: ber_scanf (\"o\") failure.\n", 0, 0, 0 );
103 Debug( LDAP_DEBUG_ANY, " get_mra ber_scanf for ad\n", 0, 0, 0 );
106 *text = "Error parsing attribute description in matching rule assertion";
107 return SLAPD_DISCONNECT;
110 rtag = ber_scanf( ber, "t", &tag );
111 if( rtag == LBER_ERROR ) {
113 LDAP_LOG( OPERATION, ERR,
114 "get_mra: ber_scanf (\"t\") failure.\n", 0, 0, 0 );
116 Debug( LDAP_DEBUG_ANY, " get_mra ber_scanf\n", 0, 0, 0 );
119 *text = "Error parsing matching rule assertion";
121 return SLAPD_DISCONNECT;
125 if ( tag != LDAP_FILTER_EXT_VALUE ) {
127 LDAP_LOG( OPERATION, ERR,
128 "get_mra: ber_scanf missing value\n", 0, 0, 0 );
130 Debug( LDAP_DEBUG_ANY, " get_mra ber_scanf missing value\n", 0, 0, 0 );
133 *text = "Missing value in matching rule assertion";
135 return SLAPD_DISCONNECT;
138 rtag = ber_scanf( ber, "m", &value );
140 if( rtag == LBER_ERROR ) {
142 LDAP_LOG( OPERATION, ERR,
143 "get_mra: ber_scanf (\"o\") failure.\n", 0, 0, 0 );
145 Debug( LDAP_DEBUG_ANY, " get_mra ber_scanf\n", 0, 0, 0 );
148 *text = "Error decoding value in matching rule assertion";
150 return SLAPD_DISCONNECT;
153 tag = ber_peek_tag( ber, &length );
155 if ( tag == LDAP_FILTER_EXT_DNATTRS ) {
156 rtag = ber_scanf( ber, "b}", &ma->ma_dnattrs );
158 rtag = ber_scanf( ber, "}" );
161 if( rtag == LBER_ERROR ) {
163 LDAP_LOG( OPERATION, ERR, "get_mra: ber_scanf failure\n", 0, 0, 0);
165 Debug( LDAP_DEBUG_ANY, " get_mra ber_scanf\n", 0, 0, 0 );
168 *text = "Error decoding dnattrs matching rule assertion";
170 return SLAPD_DISCONNECT;
173 if( type.bv_val != NULL ) {
174 rc = slap_bv2ad( &type, &ma->ma_desc, text );
175 if( rc != LDAP_SUCCESS ) {
181 if( ma->ma_rule_text.bv_val != NULL ) {
182 ma->ma_rule = mr_bvfind( &ma->ma_rule_text );
183 if( ma->ma_rule == NULL ) {
185 *text = "matching rule not recognized";
186 return LDAP_INAPPROPRIATE_MATCHING;
190 if ( ma->ma_rule == NULL ) {
192 * Need either type or rule ...
194 if ( ma->ma_desc == NULL ) {
196 *text = "no matching rule or type";
197 return LDAP_INAPPROPRIATE_MATCHING;
200 if ( ma->ma_desc->ad_type->sat_equality != NULL &&
201 ma->ma_desc->ad_type->sat_equality->smr_usage & SLAP_MR_EXT )
203 /* no matching rule was provided, use the attribute's
204 equality rule if it supports extensible matching. */
205 ma->ma_rule = ma->ma_desc->ad_type->sat_equality;
208 *text = "no appropriate rule to use for type";
210 return LDAP_INAPPROPRIATE_MATCHING;
214 if ( ma->ma_desc != NULL ) {
215 if( !mr_usable_with_at( ma->ma_rule, ma->ma_desc->ad_type ) ) {
217 *text = "matching rule use with this attribute not appropriate";
218 return LDAP_INAPPROPRIATE_MATCHING;
223 * OK, if no matching rule, normalize for equality, otherwise
224 * normalize for the matching rule.
226 rc = value_validate_normalize( ma->ma_desc, SLAP_MR_EQUALITY,
227 &value, &ma->ma_value, text );
230 * Need to normalize, but how?
232 rc = value_validate( ma->ma_rule, &value, text );
233 if ( rc == LDAP_SUCCESS ) {
234 ber_dupbv( &ma->ma_value, &value );
241 * Normalize per matching rule
243 rc = asserted_value_validate_normalize( ma->ma_desc,
245 SLAP_MR_EXT|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX,
246 &ma->ma_value, &value, text );
247 if ( rc == LDAP_SUCCESS ) {
248 ber_dupbv( &ma->ma_value, &value );
252 if( rc != LDAP_SUCCESS ) {