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