3 * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
4 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
7 /* LDAPv3 Controls (RFC2251)
9 * Controls ::= SEQUENCE OF Control
11 * Control ::= SEQUENCE {
12 * controlType LDAPOID,
13 * criticality BOOLEAN DEFAULT FALSE,
14 * controlValue OCTET STRING OPTIONAL
20 #include <ac/stdlib.h>
23 #include <ac/string.h>
29 * ldap_int_put_controls
33 ldap_int_put_controls(
35 LDAPControl *const *ctrls,
38 LDAPControl *const *c;
41 assert( LDAP_VALID(ld) );
42 assert( ber != NULL );
45 /* use default server controls */
46 ctrls = ld->ld_sctrls;
49 if( ctrls == NULL || *ctrls == NULL ) {
53 if ( ld->ld_version < LDAP_VERSION3 ) {
54 /* LDAPv2 doesn't support controls,
55 * error if any control is critical
57 for( c = ctrls ; *c != NULL; c++ ) {
58 if( (*c)->ldctl_iscritical ) {
59 ld->ld_errno = LDAP_NOT_SUPPORTED;
67 /* Controls are encoded as a sequence of sequences */
68 if( ber_printf( ber, "t{"/*}*/, LDAP_TAG_CONTROLS ) == -1 ) {
69 ld->ld_errno = LDAP_ENCODING_ERROR;
73 for( c = ctrls ; *c != NULL; c++ ) {
74 if ( ber_printf( ber, "{s" /*}*/,
75 (*c)->ldctl_oid ) == -1 )
77 ld->ld_errno = LDAP_ENCODING_ERROR;
81 if( (*c)->ldctl_iscritical /* only if true */
82 && ( ber_printf( ber, "b",
83 (ber_int_t) (*c)->ldctl_iscritical ) == -1 ) )
85 ld->ld_errno = LDAP_ENCODING_ERROR;
89 if( (*c)->ldctl_value.bv_val != NULL /* only if we have a value */
90 && ( ber_printf( ber, "O",
91 &((*c)->ldctl_value) ) == -1 ) )
93 ld->ld_errno = LDAP_ENCODING_ERROR;
98 if( ber_printf( ber, /*{*/"N}" ) == -1 ) {
99 ld->ld_errno = LDAP_ENCODING_ERROR;
105 if( ber_printf( ber, /*{*/ "}" ) == -1 ) {
106 ld->ld_errno = LDAP_ENCODING_ERROR;
113 int ldap_int_get_controls(
115 LDAPControl ***ctrls )
122 assert( ber != NULL );
124 if( ctrls == NULL ) {
129 len = ber_pvt_ber_remaining( ber );
136 if(( tag = ber_peek_tag( ber, &len )) != LDAP_TAG_CONTROLS ) {
137 if( tag == LBER_ERROR ) {
139 return LDAP_DECODING_ERROR;
142 /* ignore unexpected input */
146 /* set through each element */
148 *ctrls = LDAP_MALLOC( 1 * sizeof(LDAPControl *) );
150 if( *ctrls == NULL ) {
151 return LDAP_NO_MEMORY;
154 *ctrls[nctrls] = NULL;
156 for( tag = ber_first_element( ber, &len, &opaque );
158 tag = ber_next_element( ber, &len, opaque ) )
161 LDAPControl **tctrls;
163 tctrl = LDAP_CALLOC( 1, sizeof(LDAPControl) );
165 /* allocate pointer space for current controls (nctrls)
166 * + this control + extra NULL
168 tctrls = (tctrl == NULL) ? NULL :
169 LDAP_REALLOC(*ctrls, (nctrls+2) * sizeof(LDAPControl *));
171 if( tctrls == NULL ) {
172 /* one of the above allocation failed */
174 if( tctrl != NULL ) {
178 ldap_controls_free(*ctrls);
181 return LDAP_NO_MEMORY;
185 tctrls[nctrls++] = tctrl;
186 tctrls[nctrls] = NULL;
188 tag = ber_scanf( ber, "{a" /*}*/, &tctrl->ldctl_oid );
190 if( tag == LBER_ERROR ) {
192 ldap_controls_free( tctrls );
193 return LDAP_DECODING_ERROR;
196 tag = ber_peek_tag( ber, &len );
198 if( tag == LBER_BOOLEAN ) {
200 tag = ber_scanf( ber, "b", &crit );
201 tctrl->ldctl_iscritical = crit ? (char) 0 : (char) ~0;
202 tag = ber_peek_tag( ber, &len );
205 if( tag == LBER_OCTETSTRING ) {
206 tag = ber_scanf( ber, "o", &tctrl->ldctl_value );
208 tctrl->ldctl_value.bv_val = NULL;
221 ldap_control_free( LDAPControl *c )
223 #ifdef LDAP_MEMORY_DEBUG
228 if( c->ldctl_oid != NULL) {
229 LDAP_FREE( c->ldctl_oid );
232 if( c->ldctl_value.bv_val != NULL ) {
233 LDAP_FREE( c->ldctl_value.bv_val );
241 * Free an array of LDAPControl's
244 ldap_controls_free( LDAPControl **controls )
246 #ifdef LDAP_MEMORY_DEBUG
247 assert( controls != NULL );
250 if ( controls != NULL ) {
253 for( i=0; controls[i] != NULL; i++) {
254 ldap_control_free( controls[i] );
257 LDAP_FREE( controls );
262 * Duplicate an array of LDAPControl
265 ldap_controls_dup( LDAPControl *const *controls )
270 if ( controls == NULL ) {
274 /* count the controls */
275 for(i=0; controls[i] != NULL; i++) /* empty */ ;
278 /* no controls to duplicate */
282 new = (LDAPControl **) LDAP_MALLOC( (i+1) * sizeof(LDAPControl *) );
285 /* memory allocation failure */
289 /* duplicate the controls */
290 for(i=0; controls[i] != NULL; i++) {
291 new[i] = ldap_control_dup( controls[i] );
293 if( new[i] == NULL ) {
294 ldap_controls_free( new );
305 * Duplicate a LDAPControl
308 ldap_control_dup( const LDAPControl *c )
316 new = (LDAPControl *) LDAP_MALLOC( sizeof(LDAPControl) );
322 if( c->ldctl_oid != NULL ) {
323 new->ldctl_oid = LDAP_STRDUP( c->ldctl_oid );
325 if(new->ldctl_oid == NULL) {
331 new->ldctl_oid = NULL;
334 if( c->ldctl_value.bv_val != NULL ) {
335 new->ldctl_value.bv_val =
336 (char *) LDAP_MALLOC( c->ldctl_value.bv_len + 1 );
338 if(new->ldctl_value.bv_val == NULL) {
339 if(new->ldctl_oid != NULL) {
340 LDAP_FREE( new->ldctl_oid );
346 new->ldctl_value.bv_len = c->ldctl_value.bv_len;
348 AC_MEMCPY( new->ldctl_value.bv_val, c->ldctl_value.bv_val,
349 c->ldctl_value.bv_len );
351 new->ldctl_value.bv_val[new->ldctl_value.bv_len] = '\0';
354 new->ldctl_value.bv_len = 0;
355 new->ldctl_value.bv_val = NULL;
358 new->ldctl_iscritical = c->ldctl_iscritical;
363 * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
364 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
366 /* Adapted for inclusion into OpenLDAP by Kurt D. Zeilenga */
368 * This notice applies to changes, created by or for Novell, Inc.,
369 * to preexisting works for which notices appear elsewhere in this file.
371 * Copyright (C) 1999, 2000 Novell, Inc. All Rights Reserved.
373 * THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND TREATIES.
374 * USE, MODIFICATION, AND REDISTRIBUTION OF THIS WORK IS SUBJECT TO VERSION
375 * 2.0.1 OF THE OPENLDAP PUBLIC LICENSE, A COPY OF WHICH IS AVAILABLE AT
376 * HTTP://WWW.OPENLDAP.ORG/LICENSE.HTML OR IN THE FILE "LICENSE" IN THE
377 * TOP-LEVEL DIRECTORY OF THE DISTRIBUTION. ANY USE OR EXPLOITATION OF THIS
378 * WORK OTHER THAN AS AUTHORIZED IN VERSION 2.0.1 OF THE OPENLDAP PUBLIC
379 * LICENSE, OR OTHER PRIOR WRITTEN CONSENT FROM NOVELL, COULD SUBJECT THE
380 * PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY.
382 * Modification to OpenLDAP source by Novell, Inc.
383 * June 2000 sfs Added control utilities
385 /* Note: A verbatim copy of version 2.0.1 of the OpenLDAP Public License
386 * can be found in the file "build/LICENSE-2.0.1" in this distribution
387 * of OpenLDAP Software.
392 Internal function to create an LDAP control from the encoded BerElement.
394 requestOID (IN) The OID to use in creating the control.
396 ber (IN) The encoded BerElement to use in creating the control.
398 iscritical (IN) 0 - Indicates the control is not critical to the operation.
399 non-zero - The control is critical to the operation.
401 ctrlp (OUT) Returns a pointer to the LDAPControl created. This control
402 SHOULD be freed by calling ldap_control_free() when done.
407 LDAP_CONST char *requestOID,
410 LDAPControl **ctrlp )
414 assert( requestOID != NULL );
415 assert( ber != NULL );
416 assert( ctrlp != NULL );
418 ctrl = (LDAPControl *) LDAP_MALLOC( sizeof(LDAPControl) );
419 if ( ctrl == NULL ) {
420 return LDAP_NO_MEMORY;
423 if ( ber_flatten2( ber, &ctrl->ldctl_value, 1 ) == -1 ) {
425 return LDAP_NO_MEMORY;
428 ctrl->ldctl_oid = LDAP_STRDUP( requestOID );
429 ctrl->ldctl_iscritical = iscritical;
431 if ( requestOID != NULL && ctrl->ldctl_oid == NULL ) {
432 ldap_control_free( ctrl );
433 return LDAP_NO_MEMORY;
441 * check for critical client controls and bitch if present
442 * if we ever support critical controls, we'll have to
443 * find a means for maintaining per API call control
446 int ldap_int_client_controls( LDAP *ld, LDAPControl **ctrls )
448 LDAPControl *const *c;
450 assert( ld != NULL );
451 assert( LDAP_VALID(ld) );
453 if( ctrls == NULL ) {
454 /* use default server controls */
455 ctrls = ld->ld_cctrls;
458 if( ctrls == NULL || *ctrls == NULL ) {
462 for( c = ctrls ; *c != NULL; c++ ) {
463 if( (*c)->ldctl_iscritical ) {
464 ld->ld_errno = LDAP_NOT_SUPPORTED;