]> git.sur5r.net Git - openldap/blob - servers/slapd/controls.c
Use "uri" directive (instead of "server") to specify server. Add "bin
[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 /*      LDAP_CONTROL_X_CHANGE_PASSWD, */
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         Debug( LDAP_DEBUG_TRACE, "=> get_ctrls\n", 0, 0, 0 );
60
61         if( op->o_protocol < LDAP_VERSION3 ) {
62                 rc = SLAPD_DISCONNECT;
63                 errmsg = "controls require LDAPv3";
64                 goto return_results;
65         }
66
67         /* set through each element */
68         *ctrls = ch_malloc( 1 * sizeof(LDAPControl *) );
69
70 #if 0
71         if( *ctrls == NULL ) {
72                 rc = LDAP_NO_MEMORY;
73                 errmsg = "no memory";
74                 goto return_results;
75         }
76 #endif
77
78         *ctrls[nctrls] = NULL;
79
80         for( tag = ber_first_element( ber, &len, &opaque );
81                 tag != LBER_ERROR;
82                 tag = ber_next_element( ber, &len, opaque ) )
83         {
84                 LDAPControl *tctrl;
85                 LDAPControl **tctrls;
86
87                 tctrl = ch_calloc( 1, sizeof(LDAPControl) );
88                 tctrl->ldctl_oid = NULL;
89                 tctrl->ldctl_value.bv_val = NULL;
90
91                 /* allocate pointer space for current controls (nctrls)
92                  * + this control + extra NULL
93                  */
94                 tctrls = (tctrl == NULL) ? NULL :
95                         ch_realloc(*ctrls, (nctrls+2) * sizeof(LDAPControl *));
96
97 #if 0
98                 if( tctrls == NULL ) {
99                         /* one of the above allocation failed */
100
101                         if( tctrl != NULL ) {
102                                 ch_free( tctrl );
103                         }
104
105                         ldap_controls_free(*ctrls);
106                         *ctrls = NULL;
107
108                         rc = LDAP_NO_MEMORY;
109                         errmsg = "no memory";
110                         goto return_results;
111                 }
112 #endif
113
114                 tctrls[nctrls++] = tctrl;
115                 tctrls[nctrls] = NULL;
116
117                 tag = ber_scanf( ber, "{a" /*}*/, &tctrl->ldctl_oid );
118
119                 if( tag == LBER_ERROR ) {
120                         Debug( LDAP_DEBUG_TRACE, "=> get_ctrls: get oid failed.\n",
121                                 0, 0, 0 );
122                         *ctrls = NULL;
123                         ldap_controls_free( tctrls );
124                         rc = SLAPD_DISCONNECT;
125                         errmsg = "decoding controls error";
126                         goto return_results;
127                 }
128
129                 tag = ber_peek_tag( ber, &len );
130
131                 if( tag == LBER_BOOLEAN ) {
132                         ber_int_t crit;
133                         tag = ber_scanf( ber, "b", &crit );
134
135                         if( tag == LBER_ERROR ) {
136                                 Debug( LDAP_DEBUG_TRACE, "=> get_ctrls: get crit failed.\n",
137                                         0, 0, 0 );
138                                 *ctrls = NULL;
139                                 ldap_controls_free( tctrls );
140                                 rc = SLAPD_DISCONNECT;
141                                 errmsg = "decoding controls error";
142                                 goto return_results;
143                         }
144
145                         tctrl->ldctl_iscritical = (crit != 0);
146                         tag = ber_peek_tag( ber, &len );
147                 }
148
149                 Debug( LDAP_DEBUG_TRACE, "=> get_ctrls: oid=\"%s\" (%scritical)\n",
150                         tctrl->ldctl_oid, 
151                         tctrl->ldctl_iscritical ? "" : "non",
152                         0 );
153
154                 if( tag == LBER_OCTETSTRING ) {
155                         tag = ber_scanf( ber, "o", &tctrl->ldctl_value );
156
157                         if( tag == LBER_ERROR ) {
158                                 Debug( LDAP_DEBUG_TRACE, "=> get_ctrls: get value failed.\n",
159                                         0, 0, 0 );
160                                 *ctrls = NULL;
161                                 ldap_controls_free( tctrls );
162                                 rc = SLAPD_DISCONNECT;
163                                 errmsg = "decoding controls error";
164                                 goto return_results;
165                         }
166                 }
167
168                 if( tctrl->ldctl_iscritical &&
169                         !charray_inlist( supportedControls, tctrl->ldctl_oid ) )
170                 {
171                         rc = LDAP_UNAVAILABLE_CRITICAL_EXTENSION;
172                         errmsg = "critical extension is unavailable ";
173                         goto return_results;
174                 }
175
176                 *ctrls = tctrls;
177         }
178
179 return_results:
180         Debug( LDAP_DEBUG_TRACE, "<= get_ctrls: %d %d %s\n",
181                 nctrls, rc, errmsg ? errmsg : "");
182
183         if( sendres && rc != LDAP_SUCCESS ) {
184                 if( rc == SLAPD_DISCONNECT ) {
185                         send_ldap_disconnect( conn, op, rc, errmsg );
186                 } else {
187                         send_ldap_result( conn, op, rc,
188                                 NULL, errmsg, NULL, NULL );
189                 }
190         }
191
192         return rc;
193 }
194
195
196 int get_manageDSAit( Operation *op )
197 {
198         int i;
199         if( op == NULL || op->o_ctrls == NULL ) {
200                 return 0;
201         }
202
203         for( i=0; op->o_ctrls[i] != NULL; i++ ) {
204                 if( strcmp( LDAP_CONTROL_MANAGEDSAIT, op->o_ctrls[i]->ldctl_oid )
205                         == 0 )
206                 {
207                         return 1;
208                 }
209         }
210
211         return 0;
212 }