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