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 };
40 struct berval value = { 0, NULL };
41 struct berval rule_text = { 0, NULL };
42 MatchingRuleAssertion ma;
44 memset( &ma, 0, sizeof ma);
46 rtag = ber_scanf( ber, "{t" /*"}"*/, &tag );
48 if( rtag == LBER_ERROR ) {
50 LDAP_LOG( OPERATION, ERR,
51 "get_mra: ber_scanf (\"{t\") failure\n", 0, 0, 0 );
53 Debug( LDAP_DEBUG_ANY, " get_mra ber_scanf\n", 0, 0, 0 );
56 *text = "Error parsing matching rule assertion";
57 return SLAPD_DISCONNECT;
60 if ( tag == LDAP_FILTER_EXT_OID ) {
61 rtag = ber_scanf( ber, "m", &rule_text );
62 if ( rtag == LBER_ERROR ) {
64 LDAP_LOG( OPERATION, ERR,
65 "get_mra: ber_scanf(\"o\") failure.\n", 0, 0, 0 );
67 Debug( LDAP_DEBUG_ANY, " get_mra ber_scanf for mr\n", 0, 0, 0 );
70 *text = "Error parsing matching rule in matching rule assertion";
71 return SLAPD_DISCONNECT;
74 rtag = ber_scanf( ber, "t", &tag );
75 if( rtag == LBER_ERROR ) {
77 LDAP_LOG( OPERATION, ERR,
78 "get_mra: ber_scanf (\"t\") failure\n", 0, 0, 0 );
80 Debug( LDAP_DEBUG_ANY, " get_mra ber_scanf\n", 0, 0, 0 );
83 *text = "Error parsing matching rule assertion";
84 return SLAPD_DISCONNECT;
88 if ( tag == LDAP_FILTER_EXT_TYPE ) {
89 rtag = ber_scanf( ber, "m", &type );
90 if ( rtag == LBER_ERROR ) {
92 LDAP_LOG( OPERATION, ERR,
93 "get_mra: ber_scanf (\"o\") failure.\n", 0, 0, 0 );
95 Debug( LDAP_DEBUG_ANY, " get_mra ber_scanf for ad\n", 0, 0, 0 );
98 *text = "Error parsing attribute description in matching rule assertion";
99 return SLAPD_DISCONNECT;
102 rtag = ber_scanf( ber, "t", &tag );
103 if( rtag == LBER_ERROR ) {
105 LDAP_LOG( OPERATION, ERR,
106 "get_mra: ber_scanf (\"t\") failure.\n", 0, 0, 0 );
108 Debug( LDAP_DEBUG_ANY, " get_mra ber_scanf\n", 0, 0, 0 );
111 *text = "Error parsing matching rule assertion";
112 return SLAPD_DISCONNECT;
116 if ( tag != LDAP_FILTER_EXT_VALUE ) {
118 LDAP_LOG( OPERATION, ERR,
119 "get_mra: ber_scanf missing value\n", 0, 0, 0 );
121 Debug( LDAP_DEBUG_ANY, " get_mra ber_scanf missing value\n", 0, 0, 0 );
124 *text = "Missing value in matching rule assertion";
125 return SLAPD_DISCONNECT;
128 rtag = ber_scanf( ber, "m", &value );
130 if( rtag == LBER_ERROR ) {
132 LDAP_LOG( OPERATION, ERR,
133 "get_mra: ber_scanf (\"o\") failure.\n", 0, 0, 0 );
135 Debug( LDAP_DEBUG_ANY, " get_mra ber_scanf\n", 0, 0, 0 );
138 *text = "Error decoding value in matching rule assertion";
139 return SLAPD_DISCONNECT;
142 tag = ber_peek_tag( ber, &length );
144 if ( tag == LDAP_FILTER_EXT_DNATTRS ) {
145 rtag = ber_scanf( ber, /*"{"*/ "b}", &ma.ma_dnattrs );
147 rtag = ber_scanf( ber, /*"{"*/ "}" );
150 if( rtag == LBER_ERROR ) {
152 LDAP_LOG( OPERATION, ERR, "get_mra: ber_scanf failure\n", 0, 0, 0);
154 Debug( LDAP_DEBUG_ANY, " get_mra ber_scanf\n", 0, 0, 0 );
157 *text = "Error decoding dnattrs matching rule assertion";
158 return SLAPD_DISCONNECT;
161 if( type.bv_val != NULL ) {
162 rc = slap_bv2ad( &type, &ma.ma_desc, text );
163 if( rc != LDAP_SUCCESS ) {
168 if( rule_text.bv_val != NULL ) {
169 ma.ma_rule = mr_bvfind( &rule_text );
170 if( ma.ma_rule == NULL ) {
171 *text = "matching rule not recognized";
172 return LDAP_INAPPROPRIATE_MATCHING;
176 if ( ma.ma_rule == NULL ) {
178 * Need either type or rule ...
180 if ( ma.ma_desc == NULL ) {
181 *text = "no matching rule or type";
182 return LDAP_INAPPROPRIATE_MATCHING;
185 if ( ma.ma_desc->ad_type->sat_equality != NULL &&
186 ma.ma_desc->ad_type->sat_equality->smr_usage & SLAP_MR_EXT )
188 /* no matching rule was provided, use the attribute's
189 equality rule if it supports extensible matching. */
190 ma.ma_rule = ma.ma_desc->ad_type->sat_equality;
193 *text = "no appropriate rule to use for type";
194 return LDAP_INAPPROPRIATE_MATCHING;
198 if ( ma.ma_desc != NULL ) {
199 if( !mr_usable_with_at( ma.ma_rule, ma.ma_desc->ad_type ) ) {
200 *text = "matching rule use with this attribute not appropriate";
201 return LDAP_INAPPROPRIATE_MATCHING;
207 * Normalize per matching rule
209 rc = asserted_value_validate_normalize( ma.ma_desc,
211 SLAP_MR_EXT|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX,
212 &value, &ma.ma_value, text );
214 if( rc != LDAP_SUCCESS ) {
219 /* Append rule_text to end of struct */
220 if (rule_text.bv_val) length += rule_text.bv_len + 1;
221 *mra = ch_malloc( length );
223 if (rule_text.bv_val) {
224 (*mra)->ma_rule_text.bv_len = rule_text.bv_len;
225 (*mra)->ma_rule_text.bv_val = (char *)(*mra+1);
226 AC_MEMCPY((*mra)->ma_rule_text.bv_val, rule_text.bv_val,