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 #ifdef LDAP_COMP_MATCH
33 /* free component assertion */
34 if ( mra->ma_rule->smr_usage & SLAP_MR_COMPONENT ) {
35 component_free( mra->ma_cf );
38 /* op->o_tmpfree( mra->ma_value.bv_val, op->o_tmpmemctx ); */
39 ch_free( mra->ma_value.bv_val );
40 if ( freeit ) op->o_tmpfree( (char *) mra, op->o_tmpmemctx );
47 MatchingRuleAssertion **mra,
53 struct berval type = BER_BVNULL;
54 struct berval value = BER_BVNULL;
55 struct berval rule_text = BER_BVNULL;
56 MatchingRuleAssertion ma;
58 memset( &ma, 0, sizeof ma);
60 rtag = ber_scanf( ber, "{t" /*"}"*/, &tag );
62 if( rtag == LBER_ERROR ) {
63 Debug( LDAP_DEBUG_ANY, " get_mra ber_scanf\n", 0, 0, 0 );
65 *text = "Error parsing matching rule assertion";
66 return SLAPD_DISCONNECT;
69 if ( tag == LDAP_FILTER_EXT_OID ) {
70 rtag = ber_scanf( ber, "m", &rule_text );
71 if ( rtag == LBER_ERROR ) {
72 Debug( LDAP_DEBUG_ANY, " get_mra ber_scanf for mr\n", 0, 0, 0 );
74 *text = "Error parsing matching rule in matching rule assertion";
75 return SLAPD_DISCONNECT;
78 rtag = ber_scanf( ber, "t", &tag );
79 if( rtag == LBER_ERROR ) {
80 Debug( LDAP_DEBUG_ANY, " get_mra ber_scanf\n", 0, 0, 0 );
82 *text = "Error parsing matching rule assertion";
83 return SLAPD_DISCONNECT;
87 if ( tag == LDAP_FILTER_EXT_TYPE ) {
88 rtag = ber_scanf( ber, "m", &type );
89 if ( rtag == LBER_ERROR ) {
90 Debug( LDAP_DEBUG_ANY, " get_mra ber_scanf for ad\n", 0, 0, 0 );
92 *text = "Error parsing attribute description in matching rule assertion";
93 return SLAPD_DISCONNECT;
96 rtag = ber_scanf( ber, "t", &tag );
97 if( rtag == LBER_ERROR ) {
98 Debug( LDAP_DEBUG_ANY, " get_mra ber_scanf\n", 0, 0, 0 );
100 *text = "Error parsing matching rule assertion";
101 return SLAPD_DISCONNECT;
105 if ( tag != LDAP_FILTER_EXT_VALUE ) {
106 Debug( LDAP_DEBUG_ANY, " get_mra ber_scanf missing value\n", 0, 0, 0 );
108 *text = "Missing value in matching rule assertion";
109 return SLAPD_DISCONNECT;
112 rtag = ber_scanf( ber, "m", &value );
114 if( rtag == LBER_ERROR ) {
115 Debug( LDAP_DEBUG_ANY, " get_mra ber_scanf\n", 0, 0, 0 );
117 *text = "Error decoding value in matching rule assertion";
118 return SLAPD_DISCONNECT;
121 tag = ber_peek_tag( ber, &length );
123 if ( tag == LDAP_FILTER_EXT_DNATTRS ) {
124 rtag = ber_scanf( ber, /*"{"*/ "b}", &ma.ma_dnattrs );
126 rtag = ber_scanf( ber, /*"{"*/ "}" );
129 if( rtag == LBER_ERROR ) {
130 Debug( LDAP_DEBUG_ANY, " get_mra ber_scanf\n", 0, 0, 0 );
132 *text = "Error decoding dnattrs matching rule assertion";
133 return SLAPD_DISCONNECT;
136 if( type.bv_val != NULL ) {
137 rc = slap_bv2ad( &type, &ma.ma_desc, text );
138 if( rc != LDAP_SUCCESS ) {
143 if( rule_text.bv_val != NULL ) {
144 ma.ma_rule = mr_bvfind( &rule_text );
145 if( ma.ma_rule == NULL ) {
146 *text = "matching rule not recognized";
147 return LDAP_INAPPROPRIATE_MATCHING;
151 if ( ma.ma_rule == NULL ) {
153 * Need either type or rule ...
155 if ( ma.ma_desc == NULL ) {
156 *text = "no matching rule or type";
157 return LDAP_INAPPROPRIATE_MATCHING;
160 if ( ma.ma_desc->ad_type->sat_equality != NULL &&
161 ma.ma_desc->ad_type->sat_equality->smr_usage & SLAP_MR_EXT )
163 /* no matching rule was provided, use the attribute's
164 equality rule if it supports extensible matching. */
165 ma.ma_rule = ma.ma_desc->ad_type->sat_equality;
168 *text = "no appropriate rule to use for type";
169 return LDAP_INAPPROPRIATE_MATCHING;
173 if ( ma.ma_desc != NULL ) {
174 if( !mr_usable_with_at( ma.ma_rule, ma.ma_desc->ad_type ) ) {
175 *text = "matching rule use with this attribute not appropriate";
176 return LDAP_INAPPROPRIATE_MATCHING;
182 * Normalize per matching rule
184 rc = asserted_value_validate_normalize( ma.ma_desc,
186 SLAP_MR_EXT|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX,
187 &value, &ma.ma_value, text, op->o_tmpmemctx );
189 if( rc != LDAP_SUCCESS ) return rc;
191 #ifdef LDAP_COMP_MATCH
192 /* Matching Rule for Component Matching */
193 Debug( LDAP_DEBUG_FILTER, "matchingrule %s\n",
194 ma.ma_rule->smr_mrule.mr_oid, 0, 0);
195 if( ma.ma_rule && ma.ma_rule->smr_usage & SLAP_MR_COMPONENT ) {
196 rc = get_comp_filter( op, &ma.ma_value, &ma.ma_cf, text );
197 if ( rc != LDAP_SUCCESS ) return rc;
202 /* Append rule_text to end of struct */
203 if (rule_text.bv_val) length += rule_text.bv_len + 1;
204 *mra = op->o_tmpalloc( length, op->o_tmpmemctx );
206 if (rule_text.bv_val) {
207 (*mra)->ma_rule_text.bv_len = rule_text.bv_len;
208 (*mra)->ma_rule_text.bv_val = (char *)(*mra+1);
209 AC_MEMCPY((*mra)->ma_rule_text.bv_val, rule_text.bv_val,