]> git.sur5r.net Git - openldap/blob - servers/slapd/mra.c
a92f87bee907a60ac6102dbbf8dc527fde7cd0fe
[openldap] / servers / slapd / mra.c
1 /* $OpenLDAP$ */
2 /*
3  * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
4  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
5  */
6 /* mra.c - routines for dealing with extensible matching rule assertions */
7
8 #include "portable.h"
9
10 #include <stdio.h>
11
12 #include <ac/string.h>
13 #include <ac/socket.h>
14
15 #include "slap.h"
16
17 void
18 mra_free(
19         MatchingRuleAssertion *mra,
20         int     freeit
21 )
22 {
23         ch_free( mra->ma_value.bv_val );
24         if ( freeit ) {
25                 ch_free( (char *) mra );
26         }
27 }
28
29 int
30 get_mra(
31         BerElement      *ber,
32         MatchingRuleAssertion   **mra,
33         const char **text
34 )
35 {
36         int rc;
37         ber_tag_t tag, rtag;
38         ber_len_t length;
39         struct berval type = { 0, NULL };
40         struct berval value = { 0, NULL };
41         struct berval tmp = { 0, NULL };
42         MatchingRuleAssertion ma;
43
44         memset( &ma, 0, sizeof ma);
45
46         rtag = ber_scanf( ber, "{t" /*"}"*/, &tag );
47
48         if( rtag == LBER_ERROR ) {
49 #ifdef NEW_LOGGING
50                 LDAP_LOG( OPERATION, ERR, 
51                         "get_mra: ber_scanf (\"{t\") failure\n", 0, 0, 0 );
52 #else
53                 Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf\n", 0, 0, 0 );
54 #endif
55
56                 *text = "Error parsing matching rule assertion";
57                 return SLAPD_DISCONNECT;
58         }
59
60         if ( tag == LDAP_FILTER_EXT_OID ) {
61                 rtag = ber_scanf( ber, "m", &tmp );
62                 if ( rtag == LBER_ERROR ) {
63 #ifdef NEW_LOGGING
64                         LDAP_LOG( OPERATION, ERR,
65                            "get_mra: ber_scanf(\"o\") failure.\n", 0, 0, 0 );
66 #else
67                         Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf for mr\n", 0, 0, 0 );
68 #endif
69
70                         *text = "Error parsing matching rule in matching rule assertion";
71                         return SLAPD_DISCONNECT;
72                 }
73                 ber_dupbv( &ma.ma_rule_text, &tmp );
74
75                 rtag = ber_scanf( ber, "t", &tag );
76                 if( rtag == LBER_ERROR ) {
77 #ifdef NEW_LOGGING
78                         LDAP_LOG( OPERATION, ERR,
79                            "get_mra: ber_scanf (\"t\") failure\n", 0, 0, 0 );
80 #else
81                         Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf\n", 0, 0, 0 );
82 #endif
83
84                         *text = "Error parsing matching rule assertion";
85                         return SLAPD_DISCONNECT;
86                 }
87         }
88
89         if ( tag == LDAP_FILTER_EXT_TYPE ) {
90                 rtag = ber_scanf( ber, "m", &type );
91                 if ( rtag == LBER_ERROR ) {
92 #ifdef NEW_LOGGING
93                         LDAP_LOG( OPERATION, ERR,
94                            "get_mra: ber_scanf (\"o\") failure.\n", 0, 0, 0 );
95 #else
96                         Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf for ad\n", 0, 0, 0 );
97 #endif
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 #ifdef NEW_LOGGING
106                         LDAP_LOG( OPERATION, ERR,
107                            "get_mra: ber_scanf (\"t\") failure.\n", 0, 0, 0 );
108 #else
109                         Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf\n", 0, 0, 0 );
110 #endif
111
112                         *text = "Error parsing matching rule assertion";
113                         return SLAPD_DISCONNECT;
114                 }
115         }
116
117         if ( tag != LDAP_FILTER_EXT_VALUE ) {
118 #ifdef NEW_LOGGING
119                 LDAP_LOG( OPERATION, ERR, 
120                         "get_mra: ber_scanf missing value\n", 0, 0, 0 );
121 #else
122                 Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf missing value\n", 0, 0, 0 );
123 #endif
124
125                 *text = "Missing value in matching rule assertion";
126                 return SLAPD_DISCONNECT;
127         }
128
129         rtag = ber_scanf( ber, "m", &value );
130
131         if( rtag == LBER_ERROR ) {
132 #ifdef NEW_LOGGING
133                 LDAP_LOG( OPERATION, ERR, 
134                         "get_mra: ber_scanf (\"o\") failure.\n", 0, 0, 0 );
135 #else
136                 Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf\n", 0, 0, 0 );
137 #endif
138
139                 *text = "Error decoding value in matching rule assertion";
140                 return SLAPD_DISCONNECT;
141         }
142
143         tag = ber_peek_tag( ber, &length );
144
145         if ( tag == LDAP_FILTER_EXT_DNATTRS ) {
146                 rtag = ber_scanf( ber, /*"{"*/ "b}", &ma.ma_dnattrs );
147         } else {
148                 rtag = ber_scanf( ber, /*"{"*/ "}" );
149         }
150
151         if( rtag == LBER_ERROR ) {
152 #ifdef NEW_LOGGING
153                 LDAP_LOG( OPERATION, ERR, "get_mra: ber_scanf failure\n", 0, 0, 0);
154 #else
155                 Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf\n", 0, 0, 0 );
156 #endif
157
158                 *text = "Error decoding dnattrs matching rule assertion";
159                 return SLAPD_DISCONNECT;
160         }
161
162         if( type.bv_val != NULL ) {
163                 rc = slap_bv2ad( &type, &ma.ma_desc, text );
164                 if( rc != LDAP_SUCCESS ) {
165                         return rc;
166                 }
167         }
168
169         if( ma.ma_rule_text.bv_val != NULL ) {
170                 ma.ma_rule = mr_bvfind( &ma.ma_rule_text );
171                 if( ma.ma_rule == NULL ) {
172                         *text = "matching rule not recognized";
173                         return LDAP_INAPPROPRIATE_MATCHING;
174                 }
175         }
176
177         if ( ma.ma_rule == NULL ) {
178                 /*
179                  * Need either type or rule ...
180                  */
181                 if ( ma.ma_desc == NULL ) {
182                         *text = "no matching rule or type";
183                         return LDAP_INAPPROPRIATE_MATCHING;
184                 }
185
186                 if ( ma.ma_desc->ad_type->sat_equality != NULL &&
187                         ma.ma_desc->ad_type->sat_equality->smr_usage & SLAP_MR_EXT )
188                 {
189                         /* no matching rule was provided, use the attribute's
190                            equality rule if it supports extensible matching. */
191                         ma.ma_rule = ma.ma_desc->ad_type->sat_equality;
192
193                 } else {
194                         *text = "no appropriate rule to use for type";
195                         return LDAP_INAPPROPRIATE_MATCHING;
196                 }
197         }
198
199         if ( ma.ma_desc != NULL ) {
200                 if( !mr_usable_with_at( ma.ma_rule, ma.ma_desc->ad_type ) ) {
201                         *text = "matching rule use with this attribute not appropriate";
202                         return LDAP_INAPPROPRIATE_MATCHING;
203                 }
204
205 #ifndef SLAP_NVALUES
206                 /*
207                  * OK, if no matching rule, normalize for equality, otherwise
208                  * normalize for the matching rule.
209                  */
210                 rc = value_validate_normalize( ma.ma_desc, SLAP_MR_EQUALITY,
211                         &value, &ma.ma_value, text );
212         } else {
213                 /*
214                  * Need to normalize, but how?
215                  */
216                 rc = value_validate( ma.ma_rule, &value, text );
217                 if ( rc == LDAP_SUCCESS ) {
218                         ber_dupbv( &ma.ma_value, &value );
219                 }
220 #endif
221         }
222
223 #ifdef SLAP_NVALUES
224         /*
225          * Normalize per matching rule
226          */
227         rc = asserted_value_validate_normalize( ma.ma_desc,
228                 ma.ma_rule,
229                 SLAP_MR_EXT|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX,
230                 &value, &ma.ma_value, text );
231 #endif
232
233         if( rc != LDAP_SUCCESS ) {
234                 return rc;
235         }
236
237         *mra = ch_malloc( sizeof ma );
238         **mra = ma;
239
240         return LDAP_SUCCESS;
241 }
242