]> git.sur5r.net Git - openldap/blob - servers/slapd/mra.c
cleanup comments
[openldap] / servers / slapd / mra.c
1 /* $OpenLDAP$ */
2 /*
3  * Copyright 1998-2002 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 }, value;
40         MatchingRuleAssertion *ma;
41
42         ma = ch_malloc( sizeof( MatchingRuleAssertion ) );
43         ma->ma_rule = NULL;
44         ma->ma_rule_text.bv_len = 0;
45         ma->ma_rule_text.bv_val = NULL;
46         ma->ma_desc = NULL;
47         ma->ma_dnattrs = 0;
48         ma->ma_value.bv_len = 0;
49         ma->ma_value.bv_val = NULL;
50
51         rtag = ber_scanf( ber, "{t", &tag );
52
53         if( rtag == LBER_ERROR ) {
54 #ifdef NEW_LOGGING
55                 LDAP_LOG( OPERATION, ERR, 
56                         "get_mra: ber_scanf (\"{t\") failure\n", 0, 0, 0 );
57 #else
58                 Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf\n", 0, 0, 0 );
59 #endif
60
61                 *text = "Error parsing matching rule assertion";
62                 mra_free( ma, 1 );
63                 return SLAPD_DISCONNECT;
64         }
65
66         if ( tag == LDAP_FILTER_EXT_OID ) {
67                 rtag = ber_scanf( ber, "m", &ma->ma_rule_text );
68                 if ( rtag == LBER_ERROR ) {
69 #ifdef NEW_LOGGING
70                         LDAP_LOG( OPERATION, ERR,
71                            "get_mra: ber_scanf(\"o\") failure.\n", 0, 0, 0 );
72 #else
73                         Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf for mr\n", 0, 0, 0 );
74 #endif
75
76                         *text = "Error parsing matching rule in matching rule assertion";
77                         mra_free( ma, 1 );
78                         return SLAPD_DISCONNECT;
79                 }
80
81                 rtag = ber_scanf( ber, "t", &tag );
82                 if( rtag == LBER_ERROR ) {
83 #ifdef NEW_LOGGING
84                         LDAP_LOG( OPERATION, ERR,
85                            "get_mra: ber_scanf (\"t\") failure\n", 0, 0, 0 );
86 #else
87                         Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf\n", 0, 0, 0 );
88 #endif
89
90                         *text = "Error parsing matching rule assertion";
91                         mra_free( ma, 1 );
92                         return SLAPD_DISCONNECT;
93                 }
94         }
95
96         if ( tag == LDAP_FILTER_EXT_TYPE ) {
97                 rtag = ber_scanf( ber, "m", &type );
98                 if ( rtag == LBER_ERROR ) {
99 #ifdef NEW_LOGGING
100                         LDAP_LOG( OPERATION, ERR,
101                            "get_mra: ber_scanf (\"o\") failure.\n", 0, 0, 0 );
102 #else
103                         Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf for ad\n", 0, 0, 0 );
104 #endif
105
106                         *text = "Error parsing attribute description in matching rule assertion";
107                         return SLAPD_DISCONNECT;
108                 }
109
110                 rtag = ber_scanf( ber, "t", &tag );
111                 if( rtag == LBER_ERROR ) {
112 #ifdef NEW_LOGGING
113                         LDAP_LOG( OPERATION, ERR,
114                            "get_mra: ber_scanf (\"t\") failure.\n", 0, 0, 0 );
115 #else
116                         Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf\n", 0, 0, 0 );
117 #endif
118
119                         *text = "Error parsing matching rule assertion";
120                         mra_free( ma, 1 );
121                         return SLAPD_DISCONNECT;
122                 }
123         }
124
125         if ( tag != LDAP_FILTER_EXT_VALUE ) {
126 #ifdef NEW_LOGGING
127                 LDAP_LOG( OPERATION, ERR, 
128                         "get_mra: ber_scanf missing value\n", 0, 0, 0 );
129 #else
130                 Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf missing value\n", 0, 0, 0 );
131 #endif
132
133                 *text = "Missing value in matching rule assertion";
134                 mra_free( ma, 1 );
135                 return SLAPD_DISCONNECT;
136         }
137
138         rtag = ber_scanf( ber, "m", &value );
139
140         if( rtag == LBER_ERROR ) {
141 #ifdef NEW_LOGGING
142                 LDAP_LOG( OPERATION, ERR, 
143                         "get_mra: ber_scanf (\"o\") failure.\n", 0, 0, 0 );
144 #else
145                 Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf\n", 0, 0, 0 );
146 #endif
147
148                 *text = "Error decoding value in matching rule assertion";
149                 mra_free( ma, 1 );
150                 return SLAPD_DISCONNECT;
151         }
152
153         tag = ber_peek_tag( ber, &length );
154
155         if ( tag == LDAP_FILTER_EXT_DNATTRS ) {
156                 rtag = ber_scanf( ber, "b}", &ma->ma_dnattrs );
157         } else {
158                 rtag = ber_scanf( ber, "}" );
159         }
160
161         if( rtag == LBER_ERROR ) {
162 #ifdef NEW_LOGGING
163                 LDAP_LOG( OPERATION, ERR, "get_mra: ber_scanf failure\n", 0, 0, 0);
164 #else
165                 Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf\n", 0, 0, 0 );
166 #endif
167
168                 *text = "Error decoding dnattrs matching rule assertion";
169                 mra_free( ma, 1 );
170                 return SLAPD_DISCONNECT;
171         }
172
173 #ifndef SLAP_X_MRA_MATCH_DNATTRS
174         /*
175          * Let's try to implement it
176          */
177         if( ma->ma_dnattrs ) {
178                 *text = "matching with \":dn\" not supported";
179                 return LDAP_INAPPROPRIATE_MATCHING;
180         }
181 #endif /* !SLAP_X_MRA_MATCH_DNATTRS */
182
183         if( type.bv_val != NULL ) {
184                 rc = slap_bv2ad( &type, &ma->ma_desc, text );
185                 if( rc != LDAP_SUCCESS ) {
186                         mra_free( ma, 1 );
187                         return rc;
188                 }
189
190 #ifndef SLAP_X_MRA_MATCH_DNATTRS
191         } else {
192                 *text = "matching without attribute description rule not supported";
193                 return LDAP_INAPPROPRIATE_MATCHING;
194 #endif /* !SLAP_X_MRA_MATCH_DNATTRS */
195         }
196
197         if( ma->ma_rule_text.bv_val != NULL ) {
198                 ma->ma_rule = mr_bvfind( &ma->ma_rule_text );
199                 if( ma->ma_rule == NULL ) {
200                         mra_free( ma, 1 );
201                         *text = "matching rule not recognized";
202                         return LDAP_INAPPROPRIATE_MATCHING;
203                 }
204         }
205
206         /*
207          * FIXME: is it correct that ma->ma_rule_text, if present,
208          * is looked-up, checked, and then replaced by the sat_equality
209          * of the given attribute?  I'd rather do smtg like use
210          * the attribute's equality rule only if no matching rule
211          * was given, otherwise I don't see any extension ...
212          */
213
214 #if 1
215         if ( ma->ma_rule == NULL ) {
216 #ifdef SLAP_X_MRA_MATCH_DNATTRS
217                 /*
218                  * Need either type or rule ...
219                  */
220                 if ( ma->ma_desc == NULL ) {
221                         mra_free( ma, 1 );
222                         *text = "matching rule not recognized";
223                         return LDAP_INAPPROPRIATE_MATCHING;
224                 }
225 #endif /* !SLAP_X_MRA_MATCH_DNATTRS */
226
227                 if ( ma->ma_desc->ad_type->sat_equality != NULL &&
228                         ma->ma_desc->ad_type->sat_equality->smr_usage & SLAP_MR_EXT )
229                 {
230                         /* no matching rule was provided, use the attribute's
231                            equality rule if it supports extensible matching. */
232                         ma->ma_rule = ma->ma_desc->ad_type->sat_equality;
233
234                 } else {
235                         mra_free( ma, 1 );
236                         return LDAP_INAPPROPRIATE_MATCHING;
237                 }
238         }
239 #else
240         if( ma->ma_desc != NULL &&
241                 ma->ma_desc->ad_type->sat_equality != NULL &&
242                 ma->ma_desc->ad_type->sat_equality->smr_usage & SLAP_MR_EXT )
243         {
244                 /* no matching rule was provided, use the attribute's
245                    equality rule if it supports extensible matching. */
246                 ma->ma_rule = ma->ma_desc->ad_type->sat_equality;
247
248         } else {
249                 mra_free( ma, 1 );
250                 return LDAP_INAPPROPRIATE_MATCHING;
251         }
252 #endif
253
254 #ifdef SLAP_X_MRA_MATCH_DNATTRS
255         if ( ma->ma_desc != NULL ) {
256 #endif /* SLAP_X_MRA_MATCH_DNATTRS */
257                 /* check to see if the matching rule is appropriate for
258                   the syntax of the attribute.  This check will need
259                    to be extended to support other kinds of extensible
260                    matching rules */
261                 if( strcmp( ma->ma_rule->smr_syntax->ssyn_oid,
262                         ma->ma_desc->ad_type->sat_syntax->ssyn_oid ) != 0 )
263                 {
264                         mra_free( ma, 1 );
265                         return LDAP_INAPPROPRIATE_MATCHING;
266                 }
267
268                 /*
269                  * OK, if no matching rule, normalize for equality, otherwise
270                  * normalize for the matching rule.
271                  */
272                 rc = value_validate_normalize( ma->ma_desc, SLAP_MR_EQUALITY,
273                         &value, &ma->ma_value, text );
274 #ifdef SLAP_X_MRA_MATCH_DNATTRS
275         } else {
276                 /*
277                  * Need to normalize, but how?
278                  */
279                 rc = value_validate( ma->ma_rule, &value, text );
280                 if ( rc == LDAP_SUCCESS ) {
281                         ber_dupbv( &ma->ma_value, &value );
282                 }
283
284         }
285 #endif /* SLAP_X_MRA_MATCH_DNATTRS */
286
287         if( rc != LDAP_SUCCESS ) {
288                 mra_free( ma, 1 );
289                 return rc;
290         }
291
292         *mra = ma;
293         return LDAP_SUCCESS;
294 }
295