]> git.sur5r.net Git - openldap/blob - servers/slapd/controls.c
Import experimental referral implementation from OPENLDAP_DEVEL_REFERRALS.
[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         LDAP_CONTROL_MANAGEDSAIT,
21         NULL
22 };
23
24 int get_ctrls(
25         Connection *conn,
26         Operation *op,
27         int sendres )
28 {
29         int nctrls;
30         ber_tag_t tag;
31         ber_len_t len;
32         char *opaque;
33         BerElement *ber = op->o_ber;
34         LDAPControl ***ctrls = &op->o_ctrls;
35         int rc = LDAP_SUCCESS;
36         char *errmsg = NULL;
37
38         len = ber_pvt_ber_remaining(ber);
39
40         if( len == 0) {
41                 /* no controls */
42                 rc = LDAP_SUCCESS;
43                 goto return_results;
44         }
45
46         if(( tag = ber_peek_tag( ber, &len )) != LDAP_TAG_CONTROLS ) {
47                 if( tag == LBER_ERROR ) {
48                         rc = -1;
49                         errmsg = "unexpected data in PDU";
50                 }
51
52                 goto return_results;
53         }
54
55         if( op->o_protocol < LDAP_VERSION3 ) {
56                 rc = -1;
57                 errmsg = "controls require LDAPv3";
58                 goto return_results;
59         }
60
61         /* set through each element */
62         nctrls = 0;
63         *ctrls = ch_malloc( 1 * sizeof(LDAPControl *) );
64
65 #if 0
66         if( *ctrls == NULL ) {
67                 rc = LDAP_NO_MEMORY;
68                 errmsg = "no memory";
69                 goto return_results;
70         }
71 #endif
72
73         ctrls[nctrls] = NULL;
74
75         for( tag = ber_first_element( ber, &len, &opaque );
76                 tag != LBER_ERROR;
77                 tag = ber_next_element( ber, &len, opaque ) )
78         {
79                 LDAPControl *tctrl;
80                 LDAPControl **tctrls;
81
82                 tctrl = ch_calloc( 1, sizeof(LDAPControl) );
83
84                 /* allocate pointer space for current controls (nctrls)
85                  * + this control + extra NULL
86                  */
87                 tctrls = (tctrl == NULL) ? NULL :
88                         ch_realloc(*ctrls, (nctrls+2) * sizeof(LDAPControl *));
89
90 #if 0
91                 if( tctrls == NULL ) {
92                         /* one of the above allocation failed */
93
94                         if( tctrl != NULL ) {
95                                 ch_free( tctrl );
96                         }
97
98                         ldap_controls_free(*ctrls);
99                         *ctrls = NULL;
100
101                         rc = LDAP_NO_MEMORY;
102                         errmsg = "no memory";
103                         goto return_results;
104                 }
105 #endif
106
107
108                 tctrls[nctrls++] = tctrl;
109                 tctrls[nctrls] = NULL;
110
111                 tag = ber_scanf( ber, "{a" /*}*/, &tctrl->ldctl_oid );
112
113                 if( tag != LBER_ERROR ) {
114                         tag = ber_peek_tag( ber, &len );
115                 }
116
117                 if( tag == LBER_BOOLEAN ) {
118                         ber_int_t crit;
119                         tag = ber_scanf( ber, "b", &crit );
120                         tctrl->ldctl_iscritical = crit ? (char) 0 : (char) ~0;
121                 }
122
123                 if( tag != LBER_ERROR ) {
124                         tag = ber_peek_tag( ber, &len );
125                 }
126
127                 if( tag == LBER_OCTETSTRING ) {
128                         tag = ber_scanf( ber, "o", &tctrl->ldctl_value );
129
130                 } else {
131                         tctrl->ldctl_value.bv_val = NULL;
132                 }
133
134                 if( tag == LBER_ERROR ) {
135                         *ctrls = NULL;
136                         ldap_controls_free( tctrls );
137                         rc = -1;
138                         errmsg = "decoding controls error";
139                         goto return_results;
140                 }
141
142                 if( tctrl->ldctl_iscritical &&
143                         !charray_inlist( supportedControls, tctrl->ldctl_oid ) )
144                 {
145                         rc = LDAP_UNAVAILABLE_CRITICAL_EXTENSION;
146                         errmsg = "critical extension is unavailable ";
147                         goto return_results;
148                 }
149
150                 *ctrls = tctrls;
151         }
152
153 return_results:
154         if( sendres && rc != LDAP_SUCCESS ) {
155                 if( rc == -1 ) {
156                         send_ldap_disconnect( conn, op, rc, errmsg );
157                 } else {
158                         send_ldap_result( conn, op, rc,
159                                 NULL, errmsg, NULL, NULL );
160                 }
161         }
162
163         return rc;
164 }
165
166
167 int get_manageDSAit( Operation *op )
168 {
169         int i;
170         if( op == NULL || op->o_ctrls == NULL ) {
171                 return 0;
172         }
173
174         for( i=0; op->o_ctrls[i] != NULL; i++ ) {
175                 if( strcmp( LDAP_CONTROL_MANAGEDSAIT, op->o_ctrls[i]->ldctl_oid )
176                         == 0 )
177                 {
178                         return 1;
179                 }
180         }
181
182         return 0;
183 }