]> git.sur5r.net Git - openldap/blob - servers/slapd/mra.c
ITS#3818 fix index_substr_any_step keyword
[openldap] / servers / slapd / mra.c
1 /* mra.c - routines for dealing with extensible matching rule assertions */
2 /* $OpenLDAP$ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4  *
5  * Copyright 1998-2005 The OpenLDAP Foundation.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted only as authorized by the OpenLDAP
10  * Public License.
11  *
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>.
15  */
16
17 #include "portable.h"
18
19 #include <stdio.h>
20
21 #include <ac/string.h>
22 #include <ac/socket.h>
23
24 #include "slap.h"
25
26 #ifdef LDAP_COMP_MATCH
27 #include "component.h"
28 #endif
29
30 void
31 mra_free(
32         Operation *op,
33         MatchingRuleAssertion *mra,
34         int     freeit )
35 {
36 #ifdef LDAP_COMP_MATCH
37         /* free component assertion */
38         if ( mra->ma_rule->smr_usage & SLAP_MR_COMPONENT && mra->ma_cf ) {
39                 component_free( mra->ma_cf );
40         }
41 #endif
42         /* op->o_tmpfree( mra->ma_value.bv_val, op->o_tmpmemctx ); */
43         ch_free( mra->ma_value.bv_val );
44         if ( freeit ) op->o_tmpfree( (char *) mra, op->o_tmpmemctx );
45 }
46
47 int
48 get_mra(
49         Operation *op,
50         BerElement      *ber,
51         MatchingRuleAssertion   **mra,
52         const char **text )
53 {
54         int rc;
55         ber_tag_t tag, rtag;
56         ber_len_t length;
57         struct berval type = BER_BVNULL;
58         struct berval value = BER_BVNULL;
59         struct berval rule_text = BER_BVNULL;
60         MatchingRuleAssertion ma;
61 #ifdef LDAP_COMP_MATCH
62         AttributeAliasing* aa = NULL;
63 #endif
64
65         memset( &ma, 0, sizeof ma);
66
67         rtag = ber_scanf( ber, "{t" /*"}"*/, &tag );
68
69         if( rtag == LBER_ERROR ) {
70                 Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf\n", 0, 0, 0 );
71
72                 *text = "Error parsing matching rule assertion";
73                 return SLAPD_DISCONNECT;
74         }
75
76         if ( tag == LDAP_FILTER_EXT_OID ) {
77                 rtag = ber_scanf( ber, "m", &rule_text );
78                 if ( rtag == LBER_ERROR ) {
79                         Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf for mr\n", 0, 0, 0 );
80
81                         *text = "Error parsing matching rule in matching rule assertion";
82                         return SLAPD_DISCONNECT;
83                 }
84
85                 rtag = ber_scanf( ber, "t", &tag );
86                 if( rtag == LBER_ERROR ) {
87                         Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf\n", 0, 0, 0 );
88
89                         *text = "Error parsing matching rule assertion";
90                         return SLAPD_DISCONNECT;
91                 }
92         }
93
94         if ( tag == LDAP_FILTER_EXT_TYPE ) {
95                 rtag = ber_scanf( ber, "m", &type );
96                 if ( rtag == LBER_ERROR ) {
97                         Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf for ad\n", 0, 0, 0 );
98
99                         *text = "Error parsing attribute description in matching rule assertion";
100                         return SLAPD_DISCONNECT;
101                 }
102
103                 rtag = ber_scanf( ber, "t", &tag );
104                 if( rtag == LBER_ERROR ) {
105                         Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf\n", 0, 0, 0 );
106
107                         *text = "Error parsing matching rule assertion";
108                         return SLAPD_DISCONNECT;
109                 }
110         }
111
112         if ( tag != LDAP_FILTER_EXT_VALUE ) {
113                 Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf missing value\n", 0, 0, 0 );
114
115                 *text = "Missing value in matching rule assertion";
116                 return SLAPD_DISCONNECT;
117         }
118
119         rtag = ber_scanf( ber, "m", &value );
120
121         if( rtag == LBER_ERROR ) {
122                 Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf\n", 0, 0, 0 );
123
124                 *text = "Error decoding value in matching rule assertion";
125                 return SLAPD_DISCONNECT;
126         }
127
128         tag = ber_peek_tag( ber, &length );
129
130         if ( tag == LDAP_FILTER_EXT_DNATTRS ) {
131                 rtag = ber_scanf( ber, /*"{"*/ "b}", &ma.ma_dnattrs );
132         } else {
133                 rtag = ber_scanf( ber, /*"{"*/ "}" );
134         }
135
136         if( rtag == LBER_ERROR ) {
137                 Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf\n", 0, 0, 0 );
138
139                 *text = "Error decoding dnattrs matching rule assertion";
140                 return SLAPD_DISCONNECT;
141         }
142
143         if( type.bv_val != NULL ) {
144                 rc = slap_bv2ad( &type, &ma.ma_desc, text );
145                 if( rc != LDAP_SUCCESS ) {
146                         return rc;
147                 }
148         }
149
150         if( rule_text.bv_val != NULL ) {
151                 ma.ma_rule = mr_bvfind( &rule_text );
152                 if( ma.ma_rule == NULL ) {
153                         *text = "matching rule not recognized";
154                         return LDAP_INAPPROPRIATE_MATCHING;
155                 }
156         }
157
158         if ( ma.ma_rule == NULL ) {
159                 /*
160                  * Need either type or rule ...
161                  */
162                 if ( ma.ma_desc == NULL ) {
163                         *text = "no matching rule or type";
164                         return LDAP_INAPPROPRIATE_MATCHING;
165                 }
166
167                 if ( ma.ma_desc->ad_type->sat_equality != NULL &&
168                         ma.ma_desc->ad_type->sat_equality->smr_usage & SLAP_MR_EXT )
169                 {
170                         /* no matching rule was provided, use the attribute's
171                            equality rule if it supports extensible matching. */
172                         ma.ma_rule = ma.ma_desc->ad_type->sat_equality;
173
174                 } else {
175                         *text = "no appropriate rule to use for type";
176                         return LDAP_INAPPROPRIATE_MATCHING;
177                 }
178         }
179
180         if ( ma.ma_desc != NULL ) {
181                 if( !mr_usable_with_at( ma.ma_rule, ma.ma_desc->ad_type ) ) {
182                         *text = "matching rule use with this attribute not appropriate";
183                         return LDAP_INAPPROPRIATE_MATCHING;
184                 }
185
186         }
187
188         /*
189          * Normalize per matching rule
190          */
191         rc = asserted_value_validate_normalize( ma.ma_desc,
192                 ma.ma_rule,
193                 SLAP_MR_EXT|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX,
194                 &value, &ma.ma_value, text, op->o_tmpmemctx );
195
196         if( rc != LDAP_SUCCESS ) return rc;
197
198 #ifdef LDAP_COMP_MATCH
199         /* Check If this attribute is aliased */
200         if ( is_aliased_attribute && ma.ma_desc && ( aa = is_aliased_attribute ( ma.ma_desc ) ) ) {
201                 rc = get_aliased_filter ( op, &ma, aa, text );
202                 if ( rc != LDAP_SUCCESS ) return rc;
203         }
204         else if ( ma.ma_rule && ma.ma_rule->smr_usage & SLAP_MR_COMPONENT ) {
205                 /* Matching Rule for Component Matching */
206                 rc = get_comp_filter( op, &ma.ma_value, &ma.ma_cf, text );
207                 if ( rc != LDAP_SUCCESS ) return rc;
208         }
209 #endif
210
211         length = sizeof(ma);
212         /* Append rule_text to end of struct */
213         if (rule_text.bv_val) length += rule_text.bv_len + 1;
214         *mra = op->o_tmpalloc( length, op->o_tmpmemctx );
215         **mra = ma;
216         if (rule_text.bv_val) {
217                 (*mra)->ma_rule_text.bv_len = rule_text.bv_len;
218                 (*mra)->ma_rule_text.bv_val = (char *)(*mra+1);
219                 AC_MEMCPY((*mra)->ma_rule_text.bv_val, rule_text.bv_val,
220                         rule_text.bv_len+1);
221         }
222
223         return LDAP_SUCCESS;
224 }