]> git.sur5r.net Git - openldap/blob - servers/slapd/controls.c
More changes to let BDB build without LDBM.
[openldap] / servers / slapd / controls.c
1 /* $OpenLDAP$ */
2 /* 
3  * Copyright 1999-2000 The OpenLDAP Foundation.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms are permitted only
7  * as authorized by the OpenLDAP Public License.  A copy of this
8  * license is available at http://www.OpenLDAP.org/license.html or
9  * in file LICENSE in the top-level directory of the distribution.
10  */
11 #include "portable.h"
12
13 #include <stdio.h>
14
15 #include <ac/string.h>
16 #include <ac/socket.h>
17
18 #include "slap.h"
19
20 #include "../../libraries/liblber/lber-int.h"
21
22 char *supportedControls[] = {
23         LDAP_CONTROL_MANAGEDSAIT,
24         NULL
25 };
26
27 int get_ctrls(
28         Connection *conn,
29         Operation *op,
30         int sendres )
31 {
32         int nctrls = 0;
33         ber_tag_t tag;
34         ber_len_t len;
35         char *opaque;
36         BerElement *ber = op->o_ber;
37         LDAPControl ***ctrls = &op->o_ctrls;
38         int rc = LDAP_SUCCESS;
39         char *errmsg = NULL;
40
41         len = ber_pvt_ber_remaining(ber);
42
43         if( len == 0) {
44                 /* no controls */
45                 rc = LDAP_SUCCESS;
46                 return rc;
47         }
48
49         if(( tag = ber_peek_tag( ber, &len )) != LDAP_TAG_CONTROLS ) {
50                 if( tag == LBER_ERROR ) {
51                         rc = SLAPD_DISCONNECT;
52                         errmsg = "unexpected data in PDU";
53                 }
54
55                 goto return_results;
56         }
57
58 #ifdef NEW_LOGGING
59         LDAP_LOG(( "operation", LDAP_LEVEL_ENTRY,
60                    "get_ctrls: conn %d\n", conn->c_connid ));
61 #else
62         Debug( LDAP_DEBUG_TRACE, "=> get_ctrls\n", 0, 0, 0 );
63 #endif
64         if( op->o_protocol < LDAP_VERSION3 ) {
65                 rc = SLAPD_DISCONNECT;
66                 errmsg = "controls require LDAPv3";
67                 goto return_results;
68         }
69
70         /* set through each element */
71         *ctrls = ch_malloc( 1 * sizeof(LDAPControl *) );
72
73 #if 0
74         if( *ctrls == NULL ) {
75                 rc = LDAP_NO_MEMORY;
76                 errmsg = "no memory";
77                 goto return_results;
78         }
79 #endif
80
81         *ctrls[nctrls] = NULL;
82
83         for( tag = ber_first_element( ber, &len, &opaque );
84                 tag != LBER_ERROR;
85                 tag = ber_next_element( ber, &len, opaque ) )
86         {
87                 LDAPControl *tctrl;
88                 LDAPControl **tctrls;
89
90                 tctrl = ch_calloc( 1, sizeof(LDAPControl) );
91                 tctrl->ldctl_oid = NULL;
92                 tctrl->ldctl_value.bv_val = NULL;
93
94                 /* allocate pointer space for current controls (nctrls)
95                  * + this control + extra NULL
96                  */
97                 tctrls = (tctrl == NULL) ? NULL :
98                         ch_realloc(*ctrls, (nctrls+2) * sizeof(LDAPControl *));
99
100 #if 0
101                 if( tctrls == NULL ) {
102                         /* one of the above allocation failed */
103
104                         if( tctrl != NULL ) {
105                                 ch_free( tctrl );
106                         }
107
108                         ldap_controls_free(*ctrls);
109                         *ctrls = NULL;
110
111                         rc = LDAP_NO_MEMORY;
112                         errmsg = "no memory";
113                         goto return_results;
114                 }
115 #endif
116
117                 tctrls[nctrls++] = tctrl;
118                 tctrls[nctrls] = NULL;
119
120                 tag = ber_scanf( ber, "{a" /*}*/, &tctrl->ldctl_oid );
121
122                 if( tag == LBER_ERROR ) {
123 #ifdef NEW_LOGGING
124                         LDAP_LOG(( "operation", LDAP_LEVEL_INFO,
125                                    "get_ctrls: conn %d  get OID failed.\n",
126                                    conn->c_connid ));
127 #else
128                         Debug( LDAP_DEBUG_TRACE, "=> get_ctrls: get oid failed.\n",
129                                 0, 0, 0 );
130 #endif
131                         *ctrls = NULL;
132                         ldap_controls_free( tctrls );
133                         rc = SLAPD_DISCONNECT;
134                         errmsg = "decoding controls error";
135                         goto return_results;
136                 }
137
138                 tag = ber_peek_tag( ber, &len );
139
140                 if( tag == LBER_BOOLEAN ) {
141                         ber_int_t crit;
142                         tag = ber_scanf( ber, "b", &crit );
143
144                         if( tag == LBER_ERROR ) {
145 #ifdef NEW_LOGGING
146                                 LDAP_LOG(( "operation", LDAP_LEVEL_INFO,
147                                            "get_ctrls: conn %d  get crit failed.\n",
148                                            conn->c_connid ));
149 #else
150                                 Debug( LDAP_DEBUG_TRACE, "=> get_ctrls: get crit failed.\n",
151                                         0, 0, 0 );
152 #endif
153                                 *ctrls = NULL;
154                                 ldap_controls_free( tctrls );
155                                 rc = SLAPD_DISCONNECT;
156                                 errmsg = "decoding controls error";
157                                 goto return_results;
158                         }
159
160                         tctrl->ldctl_iscritical = (crit != 0);
161                         tag = ber_peek_tag( ber, &len );
162                 }
163
164 #ifdef NEW_LOGGING
165                 LDAP_LOG(( "operation", LDAP_LEVEL_INFO,
166                            "get_ctrls: conn %d oid=\"%s\" (%scritical)\n",
167                            conn->c_connid, tctrl->ldctl_oid,
168                            tctrl->ldctl_iscritical ? "" : "non" ));
169 #else
170                 Debug( LDAP_DEBUG_TRACE, "=> get_ctrls: oid=\"%s\" (%scritical)\n",
171                         tctrl->ldctl_oid, 
172                         tctrl->ldctl_iscritical ? "" : "non",
173                         0 );
174 #endif
175                 if( tag == LBER_OCTETSTRING ) {
176                         tag = ber_scanf( ber, "o", &tctrl->ldctl_value );
177
178                         if( tag == LBER_ERROR ) {
179 #ifdef NEW_LOGGING
180                                 LDAP_LOG(( "operation", LDAP_LEVEL_INFO,
181                                            "get_ctrls: conn %d  get value failed.\n", conn->c_connid ));
182 #else
183                                 Debug( LDAP_DEBUG_TRACE, "=> get_ctrls: get value failed.\n",
184                                         0, 0, 0 );
185 #endif
186                                 *ctrls = NULL;
187                                 ldap_controls_free( tctrls );
188                                 rc = SLAPD_DISCONNECT;
189                                 errmsg = "decoding controls error";
190                                 goto return_results;
191                         }
192                 }
193
194                 if( tctrl->ldctl_iscritical &&
195                         !charray_inlist( supportedControls, tctrl->ldctl_oid ) )
196                 {
197                         rc = LDAP_UNAVAILABLE_CRITICAL_EXTENSION;
198                         errmsg = "critical extension is unavailable ";
199                         goto return_results;
200                 }
201
202                 *ctrls = tctrls;
203         }
204
205 return_results:
206 #ifdef NEW_LOGGING
207         LDAP_LOG(( "operation", LDAP_LEVEL_RESULTS,
208                    "get_ctrls: conn %d  %d %d %s\n",
209                    conn->c_connid, nctrls, rc, errmsg ? errmsg : "" ));
210 #else
211         Debug( LDAP_DEBUG_TRACE, "<= get_ctrls: %d %d %s\n",
212                 nctrls, rc, errmsg ? errmsg : "");
213 #endif
214
215         if( sendres && rc != LDAP_SUCCESS ) {
216                 if( rc == SLAPD_DISCONNECT ) {
217                         send_ldap_disconnect( conn, op, LDAP_PROTOCOL_ERROR, errmsg );
218                 } else {
219                         send_ldap_result( conn, op, rc,
220                                 NULL, errmsg, NULL, NULL );
221                 }
222         }
223
224         return rc;
225 }
226
227
228 int get_manageDSAit( Operation *op )
229 {
230         int i;
231         if( op == NULL || op->o_ctrls == NULL ) {
232                 return 0;
233         }
234
235         for( i=0; op->o_ctrls[i] != NULL; i++ ) {
236                 if( strcmp( LDAP_CONTROL_MANAGEDSAIT, op->o_ctrls[i]->ldctl_oid )
237                         == 0 )
238                 {
239                         return 1;
240                 }
241         }
242
243         return 0;
244 }