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