1 /* mra.c - routines for dealing with extensible matching rule assertions */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 1998-2004 The OpenLDAP Foundation.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted only as authorized by the OpenLDAP
12 * A copy of this license is available in the file LICENSE in the
13 * top-level directory of the distribution or, alternatively, at
14 * <http://www.OpenLDAP.org/license.html>.
21 #include <ac/string.h>
22 #include <ac/socket.h>
29 MatchingRuleAssertion *mra,
32 /* op->o_tmpfree( mra->ma_value.bv_val, op->o_tmpmemctx ); */
33 ch_free( mra->ma_value.bv_val );
34 if ( freeit ) op->o_tmpfree( (char *) mra, op->o_tmpmemctx );
41 MatchingRuleAssertion **mra,
47 struct berval type = BER_BVNULL;
48 struct berval value = BER_BVNULL;
49 struct berval rule_text = BER_BVNULL;
50 MatchingRuleAssertion ma;
52 memset( &ma, 0, sizeof ma);
54 rtag = ber_scanf( ber, "{t" /*"}"*/, &tag );
56 if( rtag == LBER_ERROR ) {
58 LDAP_LOG( OPERATION, ERR,
59 "get_mra: ber_scanf (\"{t\") failure\n", 0, 0, 0 );
61 Debug( LDAP_DEBUG_ANY, " get_mra ber_scanf\n", 0, 0, 0 );
64 *text = "Error parsing matching rule assertion";
65 return SLAPD_DISCONNECT;
68 if ( tag == LDAP_FILTER_EXT_OID ) {
69 rtag = ber_scanf( ber, "m", &rule_text );
70 if ( rtag == LBER_ERROR ) {
72 LDAP_LOG( OPERATION, ERR,
73 "get_mra: ber_scanf(\"o\") failure.\n", 0, 0, 0 );
75 Debug( LDAP_DEBUG_ANY, " get_mra ber_scanf for mr\n", 0, 0, 0 );
78 *text = "Error parsing matching rule in matching rule assertion";
79 return SLAPD_DISCONNECT;
82 rtag = ber_scanf( ber, "t", &tag );
83 if( rtag == LBER_ERROR ) {
85 LDAP_LOG( OPERATION, ERR,
86 "get_mra: ber_scanf (\"t\") failure\n", 0, 0, 0 );
88 Debug( LDAP_DEBUG_ANY, " get_mra ber_scanf\n", 0, 0, 0 );
91 *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";
120 return SLAPD_DISCONNECT;
124 if ( tag != LDAP_FILTER_EXT_VALUE ) {
126 LDAP_LOG( OPERATION, ERR,
127 "get_mra: ber_scanf missing value\n", 0, 0, 0 );
129 Debug( LDAP_DEBUG_ANY, " get_mra ber_scanf missing value\n", 0, 0, 0 );
132 *text = "Missing value in matching rule assertion";
133 return SLAPD_DISCONNECT;
136 rtag = ber_scanf( ber, "m", &value );
138 if( rtag == LBER_ERROR ) {
140 LDAP_LOG( OPERATION, ERR,
141 "get_mra: ber_scanf (\"o\") failure.\n", 0, 0, 0 );
143 Debug( LDAP_DEBUG_ANY, " get_mra ber_scanf\n", 0, 0, 0 );
146 *text = "Error decoding value in matching rule assertion";
147 return SLAPD_DISCONNECT;
150 tag = ber_peek_tag( ber, &length );
152 if ( tag == LDAP_FILTER_EXT_DNATTRS ) {
153 rtag = ber_scanf( ber, /*"{"*/ "b}", &ma.ma_dnattrs );
155 rtag = ber_scanf( ber, /*"{"*/ "}" );
158 if( rtag == LBER_ERROR ) {
160 LDAP_LOG( OPERATION, ERR, "get_mra: ber_scanf failure\n", 0, 0, 0);
162 Debug( LDAP_DEBUG_ANY, " get_mra ber_scanf\n", 0, 0, 0 );
165 *text = "Error decoding dnattrs matching rule assertion";
166 return SLAPD_DISCONNECT;
169 if( type.bv_val != NULL ) {
170 rc = slap_bv2ad( &type, &ma.ma_desc, text );
171 if( rc != LDAP_SUCCESS ) {
176 if( rule_text.bv_val != NULL ) {
177 ma.ma_rule = mr_bvfind( &rule_text );
178 if( ma.ma_rule == NULL ) {
179 *text = "matching rule not recognized";
180 return LDAP_INAPPROPRIATE_MATCHING;
184 if ( ma.ma_rule == NULL ) {
186 * Need either type or rule ...
188 if ( ma.ma_desc == NULL ) {
189 *text = "no matching rule or type";
190 return LDAP_INAPPROPRIATE_MATCHING;
193 if ( ma.ma_desc->ad_type->sat_equality != NULL &&
194 ma.ma_desc->ad_type->sat_equality->smr_usage & SLAP_MR_EXT )
196 /* no matching rule was provided, use the attribute's
197 equality rule if it supports extensible matching. */
198 ma.ma_rule = ma.ma_desc->ad_type->sat_equality;
201 *text = "no appropriate rule to use for type";
202 return LDAP_INAPPROPRIATE_MATCHING;
206 if ( ma.ma_desc != NULL ) {
207 if( !mr_usable_with_at( ma.ma_rule, ma.ma_desc->ad_type ) ) {
208 *text = "matching rule use with this attribute not appropriate";
209 return LDAP_INAPPROPRIATE_MATCHING;
215 * Normalize per matching rule
217 rc = asserted_value_validate_normalize( ma.ma_desc,
219 SLAP_MR_EXT|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX,
220 &value, &ma.ma_value, text, op->o_tmpmemctx );
222 if( rc != LDAP_SUCCESS ) {
226 #ifdef LDAP_COMP_MATCH
227 /* Matching Rule for Component Matching */
228 Debug( LDAP_DEBUG_FILTER, "matchingrule %s\n",ma.ma_rule->smr_mrule.mr_oid,0,0);
229 if( ma.ma_rule && ma.ma_rule->smr_usage & SLAP_MR_COMPONENT )
230 rc = get_comp_filter( op, &ma.ma_value, &ma.cf, text );
231 if ( rc != LDAP_SUCCESS ) return rc;
234 /* Append rule_text to end of struct */
235 if (rule_text.bv_val) length += rule_text.bv_len + 1;
236 *mra = op->o_tmpalloc( length, op->o_tmpmemctx );
238 if (rule_text.bv_val) {
239 (*mra)->ma_rule_text.bv_len = rule_text.bv_len;
240 (*mra)->ma_rule_text.bv_val = (char *)(*mra+1);
241 AC_MEMCPY((*mra)->ma_rule_text.bv_val, rule_text.bv_val,