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