3 * Copyright 1998-2002 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 #ifndef SLAP_X_MRA_MATCH_DNATTRS
175 * Let's try to implement it
177 if( ma->ma_dnattrs ) {
178 *text = "matching with \":dn\" not supported";
179 return LDAP_INAPPROPRIATE_MATCHING;
181 #endif /* !SLAP_X_MRA_MATCH_DNATTRS */
183 if( type.bv_val != NULL ) {
184 rc = slap_bv2ad( &type, &ma->ma_desc, text );
185 if( rc != LDAP_SUCCESS ) {
190 #ifndef SLAP_X_MRA_MATCH_DNATTRS
192 *text = "matching without attribute description rule not supported";
193 return LDAP_INAPPROPRIATE_MATCHING;
194 #endif /* !SLAP_X_MRA_MATCH_DNATTRS */
197 if( ma->ma_rule_text.bv_val != NULL ) {
198 ma->ma_rule = mr_bvfind( &ma->ma_rule_text );
199 if( ma->ma_rule == NULL ) {
201 *text = "matching rule not recognized";
202 return LDAP_INAPPROPRIATE_MATCHING;
207 * FIXME: is it correct that ma->ma_rule_text, if present,
208 * is looked-up, checked, and then replaced by the sat_equality
209 * of the given attribute? I'd rather do smtg like use
210 * the attribute's equality rule only if no matching rule
211 * was given, otherwise I don't see any extension ...
215 if ( ma->ma_rule == NULL ) {
216 #ifdef SLAP_X_MRA_MATCH_DNATTRS
218 * Need either type or rule ...
220 if ( ma->ma_desc == NULL ) {
222 *text = "matching rule not recognized";
223 return LDAP_INAPPROPRIATE_MATCHING;
225 #endif /* !SLAP_X_MRA_MATCH_DNATTRS */
227 if ( ma->ma_desc->ad_type->sat_equality != NULL &&
228 ma->ma_desc->ad_type->sat_equality->smr_usage & SLAP_MR_EXT )
230 /* no matching rule was provided, use the attribute's
231 equality rule if it supports extensible matching. */
232 ma->ma_rule = ma->ma_desc->ad_type->sat_equality;
236 return LDAP_INAPPROPRIATE_MATCHING;
240 if( ma->ma_desc != NULL &&
241 ma->ma_desc->ad_type->sat_equality != NULL &&
242 ma->ma_desc->ad_type->sat_equality->smr_usage & SLAP_MR_EXT )
244 /* no matching rule was provided, use the attribute's
245 equality rule if it supports extensible matching. */
246 ma->ma_rule = ma->ma_desc->ad_type->sat_equality;
250 return LDAP_INAPPROPRIATE_MATCHING;
254 #ifdef SLAP_X_MRA_MATCH_DNATTRS
255 if ( ma->ma_desc != NULL ) {
256 #endif /* SLAP_X_MRA_MATCH_DNATTRS */
257 /* check to see if the matching rule is appropriate for
258 the syntax of the attribute. This check will need
259 to be extended to support other kinds of extensible
261 if( strcmp( ma->ma_rule->smr_syntax->ssyn_oid,
262 ma->ma_desc->ad_type->sat_syntax->ssyn_oid ) != 0 )
265 return LDAP_INAPPROPRIATE_MATCHING;
269 * OK, if no matching rule, normalize for equality, otherwise
270 * normalize for the matching rule.
272 rc = value_validate_normalize( ma->ma_desc, SLAP_MR_EQUALITY,
273 &value, &ma->ma_value, text );
274 #ifdef SLAP_X_MRA_MATCH_DNATTRS
277 * Need to normalize, but how?
279 rc = value_validate( ma->ma_rule, &value, text );
280 if ( rc == LDAP_SUCCESS ) {
281 ber_dupbv( &ma->ma_value, &value );
285 #endif /* SLAP_X_MRA_MATCH_DNATTRS */
287 if( rc != LDAP_SUCCESS ) {