]> git.sur5r.net Git - openldap/blob - servers/slapd/mra.c
Fix pkiUser
[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
18 void
19 mra_free(
20         MatchingRuleAssertion *mra,
21         int     freeit
22 )
23 {
24         ch_free( mra->ma_value.bv_val );
25         if ( freeit ) {
26                 ch_free( (char *) mra );
27         }
28 }
29
30 int
31 get_mra(
32         BerElement      *ber,
33         MatchingRuleAssertion   **mra,
34         const char **text
35 )
36 {
37         int rc;
38         ber_tag_t tag, rtag;
39         ber_len_t length;
40         struct berval type = { 0, NULL }, value;
41         MatchingRuleAssertion *ma;
42
43         ma = ch_malloc( sizeof( MatchingRuleAssertion ) );
44         ma->ma_rule = NULL;
45         ma->ma_rule_text.bv_len = 0;
46         ma->ma_rule_text.bv_val = NULL;
47         ma->ma_desc = NULL;
48         ma->ma_dnattrs = 0;
49         ma->ma_value.bv_len = 0;
50         ma->ma_value.bv_val = NULL;
51
52         rtag = ber_scanf( ber, "{t", &tag );
53
54         if( rtag == LBER_ERROR ) {
55 #ifdef NEW_LOGGING
56                 LDAP_LOG(( "operation", LDAP_LEVEL_ERR,
57                            "get_mra: ber_scanf (\"{t\") failure\n" ));
58 #else
59                 Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf\n", 0, 0, 0 );
60 #endif
61
62                 *text = "Error parsing matching rule assertion";
63                 mra_free( ma, 1 );
64                 return SLAPD_DISCONNECT;
65         }
66
67         if ( tag == LDAP_FILTER_EXT_OID ) {
68                 rtag = ber_scanf( ber, "m", &ma->ma_rule_text );
69                 if ( rtag == LBER_ERROR ) {
70 #ifdef NEW_LOGGING
71                         LDAP_LOG(( "operation", LDAP_LEVEL_ERR,
72                                    "get_mra: ber_scanf(\"o\") failure.\n" ));
73 #else
74                         Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf for mr\n", 0, 0, 0 );
75 #endif
76
77                         *text = "Error parsing matching rule in matching rule assertion";
78                         mra_free( ma, 1 );
79                         return SLAPD_DISCONNECT;
80                 }
81
82                 rtag = ber_scanf( ber, "t", &tag );
83                 if( rtag == LBER_ERROR ) {
84 #ifdef NEW_LOGGING
85                         LDAP_LOG(( "operation", LDAP_LEVEL_ERR,
86                                    "get_mra: ber_scanf (\"t\") failure\n" ));
87 #else
88                         Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf\n", 0, 0, 0 );
89 #endif
90
91                         *text = "Error parsing matching rule assertion";
92                         mra_free( ma, 1 );
93                         return SLAPD_DISCONNECT;
94                 }
95         }
96
97         if ( tag == LDAP_FILTER_EXT_TYPE ) {
98                 rtag = ber_scanf( ber, "m", &type );
99                 if ( rtag == LBER_ERROR ) {
100 #ifdef NEW_LOGGING
101                         LDAP_LOG(( "operation", LDAP_LEVEL_ERR,
102                                    "get_mra: ber_scanf (\"o\") failure.\n" ));
103 #else
104                         Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf for ad\n", 0, 0, 0 );
105 #endif
106
107                         *text = "Error parsing attribute description in matching rule assertion";
108                         return SLAPD_DISCONNECT;
109                 }
110
111                 rtag = ber_scanf( ber, "t", &tag );
112                 if( rtag == LBER_ERROR ) {
113 #ifdef NEW_LOGGING
114                         LDAP_LOG(( "operation", LDAP_LEVEL_ERR,
115                                    "get_mra: ber_scanf (\"t\") failure.\n" ));
116 #else
117                         Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf\n", 0, 0, 0 );
118 #endif
119
120                         *text = "Error parsing matching rule assertion";
121                         mra_free( ma, 1 );
122                         return SLAPD_DISCONNECT;
123                 }
124         }
125
126         if ( tag != LDAP_FILTER_EXT_VALUE ) {
127 #ifdef NEW_LOGGING
128                 LDAP_LOG(( "operation", LDAP_LEVEL_ERR,
129                            "get_mra: ber_scanf missing value\n" ));
130 #else
131                 Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf missing value\n", 0, 0, 0 );
132 #endif
133
134                 *text = "Missing value in matching rule assertion";
135                 mra_free( ma, 1 );
136                 return SLAPD_DISCONNECT;
137         }
138
139         rtag = ber_scanf( ber, "m", &value );
140
141         if( rtag == LBER_ERROR ) {
142 #ifdef NEW_LOGGING
143                 LDAP_LOG(( "operation", LDAP_LEVEL_ERR,
144                            "get_mra: ber_scanf (\"o\") failure.\n" ));
145 #else
146                 Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf\n", 0, 0, 0 );
147 #endif
148
149                 *text = "Error decoding value in matching rule assertion";
150                 mra_free( ma, 1 );
151                 return SLAPD_DISCONNECT;
152         }
153
154         tag = ber_peek_tag( ber, &length );
155
156         if ( tag == LDAP_FILTER_EXT_DNATTRS ) {
157                 rtag = ber_scanf( ber, "b}", &ma->ma_dnattrs );
158         } else {
159                 rtag = ber_scanf( ber, "}" );
160         }
161
162         if( rtag == LBER_ERROR ) {
163 #ifdef NEW_LOGGING
164                 LDAP_LOG(( "operation", LDAP_LEVEL_ERR,
165                            "get_mra: ber_scanf failure\n"));
166 #else
167                 Debug( LDAP_DEBUG_ANY, "  get_mra ber_scanf\n", 0, 0, 0 );
168 #endif
169
170                 *text = "Error decoding dnattrs matching rule assertion";
171                 mra_free( ma, 1 );
172                 return SLAPD_DISCONNECT;
173         }
174
175         if( ma->ma_dnattrs ) {
176                 *text = "matching with \":dn\" not supported";
177                 return LDAP_INAPPROPRIATE_MATCHING;
178         }
179
180         if( type.bv_val != NULL ) {
181                 rc = slap_bv2ad( &type, &ma->ma_desc, text );
182                 if( rc != LDAP_SUCCESS ) {
183                         mra_free( ma, 1 );
184                         return rc;
185                 }
186
187         } else {
188                 *text = "matching without attribute description rule not supported";
189                 return LDAP_INAPPROPRIATE_MATCHING;
190         }
191
192         if( ma->ma_rule_text.bv_val != NULL ) {
193                 ma->ma_rule = mr_bvfind( &ma->ma_rule_text );
194                 if( ma->ma_rule == NULL ) {
195                         mra_free( ma, 1 );
196                         *text = "matching rule not recognized";
197                         return LDAP_INAPPROPRIATE_MATCHING;
198                 }
199         }
200
201         if( ma->ma_desc != NULL &&
202                 ma->ma_desc->ad_type->sat_equality != NULL &&
203                 ma->ma_desc->ad_type->sat_equality->smr_usage & SLAP_MR_EXT )
204         {
205                 /* no matching rule was provided, use the attribute's
206                    equality rule if it supports extensible matching. */
207                 ma->ma_rule = ma->ma_desc->ad_type->sat_equality;
208
209         } else {
210                 mra_free( ma, 1 );
211                 return LDAP_INAPPROPRIATE_MATCHING;
212         }
213
214         /* check to see if the matching rule is appropriate for
215            the syntax of the attribute.  This check will need
216            to be extended to support other kinds of extensible
217            matching rules */
218         if( strcmp( ma->ma_rule->smr_syntax->ssyn_oid,
219                 ma->ma_desc->ad_type->sat_syntax->ssyn_oid ) != 0 )
220         {
221                 mra_free( ma, 1 );
222                 return LDAP_INAPPROPRIATE_MATCHING;
223         }
224
225         /*
226          * OK, if no matching rule, normalize for equality, otherwise
227          * normalize for the matching rule.
228          */
229         rc = value_validate_normalize( ma->ma_desc, SLAP_MR_EQUALITY,
230                 &value, &ma->ma_value, text );
231
232         if( rc != LDAP_SUCCESS ) {
233                 mra_free( ma, 1 );
234                 return rc;
235         }
236
237         *mra = ma;
238         return LDAP_SUCCESS;
239 }
240