]> git.sur5r.net Git - openldap/blob - servers/slapd/controls.c
Bring nadf back from attic, but note that it is obsolete
[openldap] / servers / slapd / controls.c
1 /* $OpenLDAP$ */
2 /* 
3  * Copyright 1999-2002 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         LDAP_CONTROL_SUBENTRIES,
25         NULL
26 };
27
28 int get_ctrls(
29         Connection *conn,
30         Operation *op,
31         int sendres )
32 {
33         int nctrls = 0;
34         ber_tag_t tag;
35         ber_len_t len;
36         char *opaque;
37         BerElement *ber = op->o_ber;
38         LDAPControl ***ctrls = &op->o_ctrls;
39         int rc = LDAP_SUCCESS;
40         char *errmsg = NULL;
41
42         len = ber_pvt_ber_remaining(ber);
43
44         if( len == 0) {
45                 /* no controls */
46                 rc = LDAP_SUCCESS;
47                 return rc;
48         }
49
50         if(( tag = ber_peek_tag( ber, &len )) != LDAP_TAG_CONTROLS ) {
51                 if( tag == LBER_ERROR ) {
52                         rc = SLAPD_DISCONNECT;
53                         errmsg = "unexpected data in PDU";
54                 }
55
56                 goto return_results;
57         }
58
59 #ifdef NEW_LOGGING
60         LDAP_LOG(( "operation", LDAP_LEVEL_ENTRY,
61                 "get_ctrls: conn %d\n", conn->c_connid ));
62 #else
63         Debug( LDAP_DEBUG_TRACE, "=> get_ctrls\n", 0, 0, 0 );
64 #endif
65         if( op->o_protocol < LDAP_VERSION3 ) {
66                 rc = SLAPD_DISCONNECT;
67                 errmsg = "controls require LDAPv3";
68                 goto return_results;
69         }
70
71         /* set through each element */
72         *ctrls = ch_malloc( 1 * sizeof(LDAPControl *) );
73
74 #if 0
75         if( *ctrls == NULL ) {
76                 rc = LDAP_NO_MEMORY;
77                 errmsg = "no memory";
78                 goto return_results;
79         }
80 #endif
81
82         *ctrls[nctrls] = NULL;
83
84         for( tag = ber_first_element( ber, &len, &opaque );
85                 tag != LBER_ERROR;
86                 tag = ber_next_element( ber, &len, opaque ) )
87         {
88                 LDAPControl *tctrl;
89                 LDAPControl **tctrls;
90
91                 tctrl = ch_calloc( 1, sizeof(LDAPControl) );
92                 tctrl->ldctl_oid = NULL;
93                 tctrl->ldctl_value.bv_val = NULL;
94
95                 /* allocate pointer space for current controls (nctrls)
96                  * + this control + extra NULL
97                  */
98                 tctrls = (tctrl == NULL) ? NULL :
99                         ch_realloc(*ctrls, (nctrls+2) * sizeof(LDAPControl *));
100
101 #if 0
102                 if( tctrls == NULL ) {
103                         /* one of the above allocation failed */
104
105                         if( tctrl != NULL ) {
106                                 ch_free( tctrl );
107                         }
108
109                         ldap_controls_free(*ctrls);
110                         *ctrls = NULL;
111
112                         rc = LDAP_NO_MEMORY;
113                         errmsg = "no memory";
114                         goto return_results;
115                 }
116 #endif
117
118                 tctrls[nctrls++] = tctrl;
119                 tctrls[nctrls] = NULL;
120
121                 tag = ber_scanf( ber, "{a" /*}*/, &tctrl->ldctl_oid );
122
123                 if( tag == LBER_ERROR ) {
124 #ifdef NEW_LOGGING
125                         LDAP_LOG(( "operation", LDAP_LEVEL_INFO,
126                                 "get_ctrls: conn %d  get OID failed.\n",
127                                 conn->c_connid ));
128 #else
129                         Debug( LDAP_DEBUG_TRACE, "=> get_ctrls: get oid failed.\n",
130                                 0, 0, 0 );
131 #endif
132                         *ctrls = NULL;
133                         ldap_controls_free( tctrls );
134                         rc = SLAPD_DISCONNECT;
135                         errmsg = "decoding controls error";
136                         goto return_results;
137                 }
138
139                 tag = ber_peek_tag( ber, &len );
140
141                 if( tag == LBER_BOOLEAN ) {
142                         ber_int_t crit;
143                         tag = ber_scanf( ber, "b", &crit );
144
145                         if( tag == LBER_ERROR ) {
146 #ifdef NEW_LOGGING
147                                 LDAP_LOG(( "operation", LDAP_LEVEL_INFO,
148                                         "get_ctrls: conn %d  get crit failed.\n",
149                                         conn->c_connid ));
150 #else
151                                 Debug( LDAP_DEBUG_TRACE, "=> get_ctrls: get crit failed.\n",
152                                         0, 0, 0 );
153 #endif
154                                 *ctrls = NULL;
155                                 ldap_controls_free( tctrls );
156                                 rc = SLAPD_DISCONNECT;
157                                 errmsg = "decoding controls error";
158                                 goto return_results;
159                         }
160
161                         tctrl->ldctl_iscritical = (crit != 0);
162                         tag = ber_peek_tag( ber, &len );
163                 }
164
165 #ifdef NEW_LOGGING
166                 LDAP_LOG(( "operation", LDAP_LEVEL_INFO,
167                         "get_ctrls: conn %d oid=\"%s\" (%scritical)\n",
168                         conn->c_connid, tctrl->ldctl_oid,
169                         tctrl->ldctl_iscritical ? "" : "non" ));
170 #else
171                 Debug( LDAP_DEBUG_TRACE, "=> get_ctrls: oid=\"%s\" (%scritical)\n",
172                         tctrl->ldctl_oid, 
173                         tctrl->ldctl_iscritical ? "" : "non",
174                         0 );
175 #endif
176                 if( tag == LBER_OCTETSTRING ) {
177                         tag = ber_scanf( ber, "o", &tctrl->ldctl_value );
178
179                         if( tag == LBER_ERROR ) {
180 #ifdef NEW_LOGGING
181                                 LDAP_LOG(( "operation", LDAP_LEVEL_INFO,
182                                         "get_ctrls: conn %d  get value failed.\n", conn->c_connid ));
183 #else
184                                 Debug( LDAP_DEBUG_TRACE, "=> get_ctrls: get value failed.\n",
185                                         0, 0, 0 );
186 #endif
187                                 *ctrls = NULL;
188                                 ldap_controls_free( tctrls );
189                                 rc = SLAPD_DISCONNECT;
190                                 errmsg = "decoding controls error";
191                                 goto return_results;
192                         }
193                 }
194
195                 if( tctrl->ldctl_iscritical &&
196                         !charray_inlist( supportedControls, tctrl->ldctl_oid ) )
197                 {
198                         rc = LDAP_UNAVAILABLE_CRITICAL_EXTENSION;
199                         errmsg = "critical extension is unavailable ";
200                         goto return_results;
201                 }
202
203                 *ctrls = tctrls;
204         }
205
206 return_results:
207 #ifdef NEW_LOGGING
208         LDAP_LOG(( "operation", LDAP_LEVEL_RESULTS,
209                 "get_ctrls: conn %d     %d %d %s\n",
210                 conn->c_connid, nctrls, rc, errmsg ? errmsg : "" ));
211 #else
212         Debug( LDAP_DEBUG_TRACE, "<= get_ctrls: %d %d %s\n",
213                 nctrls, rc, errmsg ? errmsg : "");
214 #endif
215
216         if( sendres && rc != LDAP_SUCCESS ) {
217                 if( rc == SLAPD_DISCONNECT ) {
218                         send_ldap_disconnect( conn, op, LDAP_PROTOCOL_ERROR, errmsg );
219                 } else {
220                         send_ldap_result( conn, op, rc,
221                                 NULL, errmsg, NULL, NULL );
222                 }
223         }
224
225         return rc;
226 }
227
228
229 int get_manageDSAit( Operation *op )
230 {
231         int i;
232         if( op == NULL || op->o_ctrls == NULL ) {
233                 return SLAP_NO_CONTROL;
234         }
235
236         for( i=0; op->o_ctrls[i] != NULL; i++ ) {
237                 if( strcmp( LDAP_CONTROL_MANAGEDSAIT,
238                         op->o_ctrls[i]->ldctl_oid )     == 0 )
239                 {
240                         return op->o_ctrls[i]->ldctl_iscritical
241                                 ? SLAP_CRITICAL_CONTROL
242                                 : SLAP_NONCRITICAL_CONTROL;
243                 }
244         }
245
246         return SLAP_NO_CONTROL;
247 }
248
249 int get_subentries( Operation *op, int *visibility )
250 {
251         int i;
252         if( op == NULL || op->o_ctrls == NULL ) {
253                 return SLAP_NO_CONTROL;
254         }
255
256         for( i=0; op->o_ctrls[i] != NULL; i++ ) {
257                 if( strcmp( LDAP_CONTROL_SUBENTRIES,
258                         op->o_ctrls[i]->ldctl_oid )     == 0 )
259                 {
260                         /* need to parse the value */
261                         *visibility = 0;
262
263                         return op->o_ctrls[i]->ldctl_iscritical
264                                 ? SLAP_CRITICAL_CONTROL
265                                 : SLAP_NONCRITICAL_CONTROL;
266                 }
267         }
268
269         return SLAP_NO_CONTROL;
270 }