]> git.sur5r.net Git - openldap/blob - servers/slapd/controls.c
74fadeabba7dbc8654376f2b9379add800e95fb1
[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 #include <ac/socket.h>
14
15 #include "slap.h"
16
17 #include "../../libraries/liblber/lber-int.h"
18
19 char *supportedControls[] = {
20         NULL
21 };
22
23 int get_ctrls(
24         Connection *conn,
25         Operation *op,
26         int sendres )
27 {
28         int nctrls;
29         ber_tag_t tag;
30         ber_len_t len;
31         char *opaque;
32         BerElement *ber = op->o_ber;
33         LDAPControl ***ctrls = &op->o_ctrls;
34         int rc = LDAP_SUCCESS;
35
36         len = ber_pvt_ber_remaining(ber);
37
38         if( len == 0) {
39                 /* no controls */
40                 rc = LDAP_SUCCESS;
41                 goto return_results;
42         }
43
44         if(( tag = ber_peek_tag( ber, &len )) != LDAP_TAG_CONTROLS ) {
45                 if( tag == LBER_ERROR ) {
46                         rc = LDAP_PROTOCOL_ERROR;
47                 }
48
49                 goto return_results;
50         }
51
52         if( op->o_protocol < LDAP_VERSION3 ) {
53                 rc = LDAP_PROTOCOL_ERROR;
54                 goto return_results;
55         }
56
57         /* set through each element */
58         nctrls = 0;
59         *ctrls = ch_malloc( 1 * sizeof(LDAPControl *) );
60
61 #if 0
62         if( *ctrls == NULL ) {
63                 rc = LDAP_NO_MEMORY;
64                 goto return_results;
65         }
66 #endif
67
68         ctrls[nctrls] = NULL;
69
70         for( tag = ber_first_element( ber, &len, &opaque );
71                 tag != LBER_ERROR;
72                 tag = ber_next_element( ber, &len, opaque ) )
73         {
74                 LDAPControl *tctrl;
75                 LDAPControl **tctrls;
76
77                 tctrl = ch_calloc( 1, sizeof(LDAPControl) );
78
79                 /* allocate pointer space for current controls (nctrls)
80                  * + this control + extra NULL
81                  */
82                 tctrls = (tctrl == NULL) ? NULL :
83                         ch_realloc(*ctrls, (nctrls+2) * sizeof(LDAPControl *));
84
85 #if 0
86                 if( tctrls == NULL ) {
87                         /* one of the above allocation failed */
88
89                         if( tctrl != NULL ) {
90                                 ch_free( tctrl );
91                         }
92
93                         ldap_controls_free(*ctrls);
94                         *ctrls = NULL;
95
96                         rc = LDAP_NO_MEMORY;
97                         goto return_results;
98                 }
99 #endif
100
101
102                 tctrls[nctrls++] = tctrl;
103                 tctrls[nctrls] = NULL;
104
105                 tag = ber_scanf( ber, "{a" /*}*/, &tctrl->ldctl_oid );
106
107                 if( tag != LBER_ERROR ) {
108                         tag = ber_peek_tag( ber, &len );
109                 }
110
111                 if( tag == LBER_BOOLEAN ) {
112                         ber_int_t crit;
113                         tag = ber_scanf( ber, "b", &crit );
114                         tctrl->ldctl_iscritical = crit ? (char) 0 : (char) ~0;
115                 }
116
117                 if( tag != LBER_ERROR ) {
118                         tag = ber_peek_tag( ber, &len );
119                 }
120
121                 if( tag == LBER_OCTETSTRING ) {
122                         tag = ber_scanf( ber, "o", &tctrl->ldctl_value );
123
124                 } else {
125                         tctrl->ldctl_value.bv_val = NULL;
126                 }
127
128                 if( tag == LBER_ERROR ) {
129                         *ctrls = NULL;
130                         ldap_controls_free( tctrls );
131                         rc = LDAP_DECODING_ERROR;
132                         goto return_results;
133                 }
134
135                 if( tctrl->ldctl_iscritical &&
136                         !charray_inlist( supportedControls, tctrl->ldctl_oid ) )
137                 {
138                         rc = LDAP_UNAVAILABLE_CRITICIAL_EXTENSION;
139                         goto return_results;
140                 }
141
142                 *ctrls = tctrls;
143         }
144
145 return_results:
146         if( sendres && rc != LDAP_SUCCESS ) {
147                 send_ldap_result( conn, op, rc, NULL, NULL );
148         }
149
150         return rc;
151 }