3 * Copyright 1999-2002 The OpenLDAP Foundation.
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.
15 #include <ac/string.h>
16 #include <ac/socket.h>
20 #include "../../libraries/liblber/lber-int.h"
22 char *supportedControls[] = {
23 LDAP_CONTROL_MANAGEDSAIT,
24 LDAP_CONTROL_SUBENTRIES,
37 BerElement *ber = op->o_ber;
38 LDAPControl ***ctrls = &op->o_ctrls;
39 int rc = LDAP_SUCCESS;
42 len = ber_pvt_ber_remaining(ber);
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";
60 LDAP_LOG(( "operation", LDAP_LEVEL_ENTRY,
61 "get_ctrls: conn %d\n", conn->c_connid ));
63 Debug( LDAP_DEBUG_TRACE, "=> get_ctrls\n", 0, 0, 0 );
65 if( op->o_protocol < LDAP_VERSION3 ) {
66 rc = SLAPD_DISCONNECT;
67 errmsg = "controls require LDAPv3";
71 /* set through each element */
72 *ctrls = ch_malloc( 1 * sizeof(LDAPControl *) );
75 if( *ctrls == NULL ) {
82 *ctrls[nctrls] = NULL;
84 for( tag = ber_first_element( ber, &len, &opaque );
86 tag = ber_next_element( ber, &len, opaque ) )
91 tctrl = ch_calloc( 1, sizeof(LDAPControl) );
92 tctrl->ldctl_oid = NULL;
93 tctrl->ldctl_value.bv_val = NULL;
95 /* allocate pointer space for current controls (nctrls)
96 * + this control + extra NULL
98 tctrls = (tctrl == NULL) ? NULL :
99 ch_realloc(*ctrls, (nctrls+2) * sizeof(LDAPControl *));
102 if( tctrls == NULL ) {
103 /* one of the above allocation failed */
105 if( tctrl != NULL ) {
109 ldap_controls_free(*ctrls);
113 errmsg = "no memory";
118 tctrls[nctrls++] = tctrl;
119 tctrls[nctrls] = NULL;
121 tag = ber_scanf( ber, "{a" /*}*/, &tctrl->ldctl_oid );
123 if( tag == LBER_ERROR ) {
125 LDAP_LOG(( "operation", LDAP_LEVEL_INFO,
126 "get_ctrls: conn %d get OID failed.\n",
129 Debug( LDAP_DEBUG_TRACE, "=> get_ctrls: get oid failed.\n",
133 ldap_controls_free( tctrls );
134 rc = SLAPD_DISCONNECT;
135 errmsg = "decoding controls error";
139 tag = ber_peek_tag( ber, &len );
141 if( tag == LBER_BOOLEAN ) {
143 tag = ber_scanf( ber, "b", &crit );
145 if( tag == LBER_ERROR ) {
147 LDAP_LOG(( "operation", LDAP_LEVEL_INFO,
148 "get_ctrls: conn %d get crit failed.\n",
151 Debug( LDAP_DEBUG_TRACE, "=> get_ctrls: get crit failed.\n",
155 ldap_controls_free( tctrls );
156 rc = SLAPD_DISCONNECT;
157 errmsg = "decoding controls error";
161 tctrl->ldctl_iscritical = (crit != 0);
162 tag = ber_peek_tag( ber, &len );
166 LDAP_LOG(( "operation", LDAP_LEVEL_INFO,
167 "get_ctrls: conn %d oid=\"%s\" (%scritical)\n",
168 conn->c_connid, tctrl->ldctl_oid,
169 tctrl->ldctl_iscritical ? "" : "non" ));
171 Debug( LDAP_DEBUG_TRACE, "=> get_ctrls: oid=\"%s\" (%scritical)\n",
173 tctrl->ldctl_iscritical ? "" : "non",
176 if( tag == LBER_OCTETSTRING ) {
177 tag = ber_scanf( ber, "o", &tctrl->ldctl_value );
179 if( tag == LBER_ERROR ) {
181 LDAP_LOG(( "operation", LDAP_LEVEL_INFO,
182 "get_ctrls: conn %d get value failed.\n", conn->c_connid ));
184 Debug( LDAP_DEBUG_TRACE, "=> get_ctrls: get value failed.\n",
188 ldap_controls_free( tctrls );
189 rc = SLAPD_DISCONNECT;
190 errmsg = "decoding controls error";
195 if( tctrl->ldctl_iscritical &&
196 !charray_inlist( supportedControls, tctrl->ldctl_oid ) )
198 rc = LDAP_UNAVAILABLE_CRITICAL_EXTENSION;
199 errmsg = "critical extension is unavailable ";
208 LDAP_LOG(( "operation", LDAP_LEVEL_RESULTS,
209 "get_ctrls: conn %d %d %d %s\n",
210 conn->c_connid, nctrls, rc, errmsg ? errmsg : "" ));
212 Debug( LDAP_DEBUG_TRACE, "<= get_ctrls: %d %d %s\n",
213 nctrls, rc, errmsg ? errmsg : "");
216 if( sendres && rc != LDAP_SUCCESS ) {
217 if( rc == SLAPD_DISCONNECT ) {
218 send_ldap_disconnect( conn, op, LDAP_PROTOCOL_ERROR, errmsg );
220 send_ldap_result( conn, op, rc,
221 NULL, errmsg, NULL, NULL );
229 int get_manageDSAit( Operation *op )
232 if( op == NULL || op->o_ctrls == NULL ) {
233 return SLAP_NO_CONTROL;
236 for( i=0; op->o_ctrls[i] != NULL; i++ ) {
237 if( strcmp( LDAP_CONTROL_MANAGEDSAIT,
238 op->o_ctrls[i]->ldctl_oid ) == 0 )
240 return op->o_ctrls[i]->ldctl_iscritical
241 ? SLAP_CRITICAL_CONTROL
242 : SLAP_NONCRITICAL_CONTROL;
246 return SLAP_NO_CONTROL;
249 int get_subentries( Operation *op, int *visibility )
252 if( op == NULL || op->o_ctrls == NULL ) {
253 return SLAP_NO_CONTROL;
256 for( i=0; op->o_ctrls[i] != NULL; i++ ) {
257 if( strcmp( LDAP_CONTROL_SUBENTRIES,
258 op->o_ctrls[i]->ldctl_oid ) == 0 )
260 /* need to parse the value */
263 return op->o_ctrls[i]->ldctl_iscritical
264 ? SLAP_CRITICAL_CONTROL
265 : SLAP_NONCRITICAL_CONTROL;
269 return SLAP_NO_CONTROL;