3 * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
4 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
7 * Portions Copyright (C) The Internet Society (1997)
8 * ASN.1 fragments are from RFC 2251; see RFC for full legal notices.
11 /* LDAPv3 Controls (RFC2251)
13 * Controls ::= SEQUENCE OF Control
15 * Control ::= SEQUENCE {
16 * controlType LDAPOID,
17 * criticality BOOLEAN DEFAULT FALSE,
18 * controlValue OCTET STRING OPTIONAL
24 #include <ac/stdlib.h>
27 #include <ac/string.h>
33 * ldap_int_put_controls
37 ldap_int_put_controls(
39 LDAPControl *const *ctrls,
42 LDAPControl *const *c;
45 assert( LDAP_VALID(ld) );
46 assert( ber != NULL );
49 /* use default server controls */
50 ctrls = ld->ld_sctrls;
53 if( ctrls == NULL || *ctrls == NULL ) {
57 if ( ld->ld_version < LDAP_VERSION3 ) {
58 /* LDAPv2 doesn't support controls,
59 * error if any control is critical
61 for( c = ctrls ; *c != NULL; c++ ) {
62 if( (*c)->ldctl_iscritical ) {
63 ld->ld_errno = LDAP_NOT_SUPPORTED;
71 /* Controls are encoded as a sequence of sequences */
72 if( ber_printf( ber, "t{"/*}*/, LDAP_TAG_CONTROLS ) == -1 ) {
73 ld->ld_errno = LDAP_ENCODING_ERROR;
77 for( c = ctrls ; *c != NULL; c++ ) {
78 if ( ber_printf( ber, "{s" /*}*/,
79 (*c)->ldctl_oid ) == -1 )
81 ld->ld_errno = LDAP_ENCODING_ERROR;
85 if( (*c)->ldctl_iscritical /* only if true */
86 && ( ber_printf( ber, "b",
87 (ber_int_t) (*c)->ldctl_iscritical ) == -1 ) )
89 ld->ld_errno = LDAP_ENCODING_ERROR;
93 if( (*c)->ldctl_value.bv_val != NULL /* only if we have a value */
94 && ( ber_printf( ber, "O",
95 &((*c)->ldctl_value) ) == -1 ) )
97 ld->ld_errno = LDAP_ENCODING_ERROR;
102 if( ber_printf( ber, /*{*/"N}" ) == -1 ) {
103 ld->ld_errno = LDAP_ENCODING_ERROR;
109 if( ber_printf( ber, /*{*/ "}" ) == -1 ) {
110 ld->ld_errno = LDAP_ENCODING_ERROR;
117 int ldap_int_get_controls(
119 LDAPControl ***ctrls )
126 assert( ber != NULL );
128 if( ctrls == NULL ) {
133 len = ber_pvt_ber_remaining( ber );
140 if(( tag = ber_peek_tag( ber, &len )) != LDAP_TAG_CONTROLS ) {
141 if( tag == LBER_ERROR ) {
143 return LDAP_DECODING_ERROR;
146 /* ignore unexpected input */
150 /* set through each element */
152 *ctrls = LDAP_MALLOC( 1 * sizeof(LDAPControl *) );
154 if( *ctrls == NULL ) {
155 return LDAP_NO_MEMORY;
158 *ctrls[nctrls] = NULL;
160 for( tag = ber_first_element( ber, &len, &opaque );
162 tag = ber_next_element( ber, &len, opaque ) )
165 LDAPControl **tctrls;
167 tctrl = LDAP_CALLOC( 1, sizeof(LDAPControl) );
169 /* allocate pointer space for current controls (nctrls)
170 * + this control + extra NULL
172 tctrls = (tctrl == NULL) ? NULL :
173 LDAP_REALLOC(*ctrls, (nctrls+2) * sizeof(LDAPControl *));
175 if( tctrls == NULL ) {
176 /* one of the above allocation failed */
178 if( tctrl != NULL ) {
182 ldap_controls_free(*ctrls);
185 return LDAP_NO_MEMORY;
189 tctrls[nctrls++] = tctrl;
190 tctrls[nctrls] = NULL;
192 tag = ber_scanf( ber, "{a" /*}*/, &tctrl->ldctl_oid );
194 if( tag == LBER_ERROR ) {
196 ldap_controls_free( tctrls );
197 return LDAP_DECODING_ERROR;
200 tag = ber_peek_tag( ber, &len );
202 if( tag == LBER_BOOLEAN ) {
204 tag = ber_scanf( ber, "b", &crit );
205 tctrl->ldctl_iscritical = crit ? (char) 0 : (char) ~0;
206 tag = ber_peek_tag( ber, &len );
209 if( tag == LBER_OCTETSTRING ) {
210 tag = ber_scanf( ber, "o", &tctrl->ldctl_value );
212 tctrl->ldctl_value.bv_val = NULL;
225 ldap_control_free( LDAPControl *c )
227 #ifdef LDAP_MEMORY_DEBUG
232 if( c->ldctl_oid != NULL) {
233 LDAP_FREE( c->ldctl_oid );
236 if( c->ldctl_value.bv_val != NULL ) {
237 LDAP_FREE( c->ldctl_value.bv_val );
245 * Free an array of LDAPControl's
248 ldap_controls_free( LDAPControl **controls )
250 #ifdef LDAP_MEMORY_DEBUG
251 assert( controls != NULL );
254 if ( controls != NULL ) {
257 for( i=0; controls[i] != NULL; i++) {
258 ldap_control_free( controls[i] );
261 LDAP_FREE( controls );
266 * Duplicate an array of LDAPControl
269 ldap_controls_dup( LDAPControl *const *controls )
274 if ( controls == NULL ) {
278 /* count the controls */
279 for(i=0; controls[i] != NULL; i++) /* empty */ ;
282 /* no controls to duplicate */
286 new = (LDAPControl **) LDAP_MALLOC( (i+1) * sizeof(LDAPControl *) );
289 /* memory allocation failure */
293 /* duplicate the controls */
294 for(i=0; controls[i] != NULL; i++) {
295 new[i] = ldap_control_dup( controls[i] );
297 if( new[i] == NULL ) {
298 ldap_controls_free( new );
309 * Duplicate a LDAPControl
312 ldap_control_dup( const LDAPControl *c )
320 new = (LDAPControl *) LDAP_MALLOC( sizeof(LDAPControl) );
326 if( c->ldctl_oid != NULL ) {
327 new->ldctl_oid = LDAP_STRDUP( c->ldctl_oid );
329 if(new->ldctl_oid == NULL) {
335 new->ldctl_oid = NULL;
338 if( c->ldctl_value.bv_val != NULL ) {
339 new->ldctl_value.bv_val =
340 (char *) LDAP_MALLOC( c->ldctl_value.bv_len + 1 );
342 if(new->ldctl_value.bv_val == NULL) {
343 if(new->ldctl_oid != NULL) {
344 LDAP_FREE( new->ldctl_oid );
350 new->ldctl_value.bv_len = c->ldctl_value.bv_len;
352 AC_MEMCPY( new->ldctl_value.bv_val, c->ldctl_value.bv_val,
353 c->ldctl_value.bv_len );
355 new->ldctl_value.bv_val[new->ldctl_value.bv_len] = '\0';
358 new->ldctl_value.bv_len = 0;
359 new->ldctl_value.bv_val = NULL;
362 new->ldctl_iscritical = c->ldctl_iscritical;
367 * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
368 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
370 /* Adapted for inclusion into OpenLDAP by Kurt D. Zeilenga */
372 * This notice applies to changes, created by or for Novell, Inc.,
373 * to preexisting works for which notices appear elsewhere in this file.
375 * Copyright (C) 1999, 2000 Novell, Inc. All Rights Reserved.
377 * THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND TREATIES.
378 * USE, MODIFICATION, AND REDISTRIBUTION OF THIS WORK IS SUBJECT TO VERSION
379 * 2.0.1 OF THE OPENLDAP PUBLIC LICENSE, A COPY OF WHICH IS AVAILABLE AT
380 * HTTP://WWW.OPENLDAP.ORG/LICENSE.HTML OR IN THE FILE "LICENSE" IN THE
381 * TOP-LEVEL DIRECTORY OF THE DISTRIBUTION. ANY USE OR EXPLOITATION OF THIS
382 * WORK OTHER THAN AS AUTHORIZED IN VERSION 2.0.1 OF THE OPENLDAP PUBLIC
383 * LICENSE, OR OTHER PRIOR WRITTEN CONSENT FROM NOVELL, COULD SUBJECT THE
384 * PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY.
386 * Modification to OpenLDAP source by Novell, Inc.
387 * June 2000 sfs Added control utilities
389 /* Note: A verbatim copy of version 2.0.1 of the OpenLDAP Public License
390 * can be found in the file "build/LICENSE-2.0.1" in this distribution
391 * of OpenLDAP Software.
396 Internal function to create an LDAP control from the encoded BerElement.
398 requestOID (IN) The OID to use in creating the control.
400 ber (IN) The encoded BerElement to use in creating the control.
402 iscritical (IN) 0 - Indicates the control is not critical to the operation.
403 non-zero - The control is critical to the operation.
405 ctrlp (OUT) Returns a pointer to the LDAPControl created. This control
406 SHOULD be freed by calling ldap_control_free() when done.
411 LDAP_CONST char *requestOID,
414 LDAPControl **ctrlp )
418 assert( requestOID != NULL );
419 assert( ber != NULL );
420 assert( ctrlp != NULL );
422 ctrl = (LDAPControl *) LDAP_MALLOC( sizeof(LDAPControl) );
423 if ( ctrl == NULL ) {
424 return LDAP_NO_MEMORY;
427 if ( ber_flatten2( ber, &ctrl->ldctl_value, 1 ) == -1 ) {
429 return LDAP_NO_MEMORY;
432 ctrl->ldctl_oid = LDAP_STRDUP( requestOID );
433 ctrl->ldctl_iscritical = iscritical;
435 if ( requestOID != NULL && ctrl->ldctl_oid == NULL ) {
436 ldap_control_free( ctrl );
437 return LDAP_NO_MEMORY;
445 * check for critical client controls and bitch if present
446 * if we ever support critical controls, we'll have to
447 * find a means for maintaining per API call control
450 int ldap_int_client_controls( LDAP *ld, LDAPControl **ctrls )
452 LDAPControl *const *c;
454 assert( ld != NULL );
455 assert( LDAP_VALID(ld) );
457 if( ctrls == NULL ) {
458 /* use default server controls */
459 ctrls = ld->ld_cctrls;
462 if( ctrls == NULL || *ctrls == NULL ) {
466 for( c = ctrls ; *c != NULL; c++ ) {
467 if( (*c)->ldctl_iscritical ) {
468 ld->ld_errno = LDAP_NOT_SUPPORTED;