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 ) {
191 tag = ber_peek_tag( ber, &len );
194 if( tag == LBER_BOOLEAN ) {
196 tag = ber_scanf( ber, "b", &crit );
197 tctrl->ldctl_iscritical = crit ? (char) 0 : (char) ~0;
200 if( tag != LBER_ERROR ) {
201 tag = ber_peek_tag( ber, &len );
204 if( tag == LBER_OCTETSTRING ) {
205 tag = ber_scanf( ber, "o", &tctrl->ldctl_value );
208 tctrl->ldctl_value.bv_val = NULL;
211 if( tag == LBER_ERROR ) {
213 ldap_controls_free( tctrls );
214 return LDAP_DECODING_ERROR;
227 ldap_control_free( LDAPControl *c )
229 #ifdef LDAP_MEMORY_DEBUG
234 if( c->ldctl_oid != NULL) {
235 LDAP_FREE( c->ldctl_oid );
238 if( c->ldctl_value.bv_val != NULL ) {
239 LDAP_FREE( c->ldctl_value.bv_val );
247 * Free an array of LDAPControl's
250 ldap_controls_free( LDAPControl **controls )
252 #ifdef LDAP_MEMORY_DEBUG
253 assert( controls != NULL );
256 if ( controls != NULL ) {
259 for( i=0; controls[i] != NULL; i++) {
260 ldap_control_free( controls[i] );
263 LDAP_FREE( controls );
268 * Duplicate an array of LDAPControl
271 ldap_controls_dup( LDAPControl *const *controls )
276 if ( controls == NULL ) {
280 /* count the controls */
281 for(i=0; controls[i] != NULL; i++) /* empty */ ;
284 /* no controls to duplicate */
288 new = (LDAPControl **) LDAP_MALLOC( (i+1) * sizeof(LDAPControl *) );
291 /* memory allocation failure */
295 /* duplicate the controls */
296 for(i=0; controls[i] != NULL; i++) {
297 new[i] = ldap_control_dup( controls[i] );
299 if( new[i] == NULL ) {
300 ldap_controls_free( new );
311 * Duplicate a LDAPControl
314 ldap_control_dup( const LDAPControl *c )
322 new = (LDAPControl *) LDAP_MALLOC( sizeof(LDAPControl) );
328 if( c->ldctl_oid != NULL ) {
329 new->ldctl_oid = LDAP_STRDUP( c->ldctl_oid );
331 if(new->ldctl_oid == NULL) {
337 new->ldctl_oid = NULL;
340 if( c->ldctl_value.bv_val != NULL ) {
341 new->ldctl_value.bv_val =
342 (char *) LDAP_MALLOC( c->ldctl_value.bv_len + 1 );
344 if(new->ldctl_value.bv_val == NULL) {
345 if(new->ldctl_oid != NULL) {
346 LDAP_FREE( new->ldctl_oid );
352 new->ldctl_value.bv_len = c->ldctl_value.bv_len;
354 AC_MEMCPY( new->ldctl_value.bv_val, c->ldctl_value.bv_val,
355 c->ldctl_value.bv_len );
357 new->ldctl_value.bv_val[new->ldctl_value.bv_len] = '\0';
360 new->ldctl_value.bv_len = 0;
361 new->ldctl_value.bv_val = NULL;
364 new->ldctl_iscritical = c->ldctl_iscritical;
369 * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
370 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
372 /* Adapted for inclusion into OpenLDAP by Kurt D. Zeilenga */
374 * This notice applies to changes, created by or for Novell, Inc.,
375 * to preexisting works for which notices appear elsewhere in this file.
377 * Copyright (C) 1999, 2000 Novell, Inc. All Rights Reserved.
379 * THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND TREATIES.
380 * USE, MODIFICATION, AND REDISTRIBUTION OF THIS WORK IS SUBJECT TO VERSION
381 * 2.0.1 OF THE OPENLDAP PUBLIC LICENSE, A COPY OF WHICH IS AVAILABLE AT
382 * HTTP://WWW.OPENLDAP.ORG/LICENSE.HTML OR IN THE FILE "LICENSE" IN THE
383 * TOP-LEVEL DIRECTORY OF THE DISTRIBUTION. ANY USE OR EXPLOITATION OF THIS
384 * WORK OTHER THAN AS AUTHORIZED IN VERSION 2.0.1 OF THE OPENLDAP PUBLIC
385 * LICENSE, OR OTHER PRIOR WRITTEN CONSENT FROM NOVELL, COULD SUBJECT THE
386 * PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY.
388 * Modification to OpenLDAP source by Novell, Inc.
389 * June 2000 sfs Added control utilities
394 Internal function to create an LDAP control from the encoded BerElement.
396 requestOID (IN) The OID to use in creating the control.
398 ber (IN) The encoded BerElement to use in creating the control.
400 iscritical (IN) 0 - Indicates the control is not critical to the operation.
401 non-zero - The control is critical to the operation.
403 ctrlp (OUT) Returns a pointer to the LDAPControl created. This control
404 SHOULD be freed by calling ldap_control_free() when done.
409 LDAP_CONST char *requestOID,
412 LDAPControl **ctrlp )
415 struct berval *bvalp;
417 assert( requestOID != NULL );
418 assert( ber != NULL );
419 assert( ctrlp != NULL );
421 ctrl = (LDAPControl *) LDAP_MALLOC( sizeof(LDAPControl) );
422 if ( ctrl == NULL ) {
423 return LDAP_NO_MEMORY;
426 if ( ber_flatten( ber, &bvalp ) == -1 ) {
428 return LDAP_NO_MEMORY;
431 ctrl->ldctl_value = *bvalp;
432 ber_memfree( bvalp );
434 ctrl->ldctl_oid = LDAP_STRDUP( requestOID );
435 ctrl->ldctl_iscritical = iscritical;
437 if ( requestOID != NULL && ctrl->ldctl_oid == NULL ) {
438 ldap_control_free( ctrl );
439 return LDAP_NO_MEMORY;
447 * check for critical client controls and bitch if present
448 * if we ever support critical controls, we'll have to
449 * find a means for maintaining per API call control
452 int ldap_int_client_controls( LDAP *ld, LDAPControl **ctrls )
454 LDAPControl *const *c;
456 assert( ld != NULL );
457 assert( LDAP_VALID(ld) );
459 if( ctrls == NULL ) {
460 /* use default server controls */
461 ctrls = ld->ld_cctrls;
464 if( ctrls == NULL || *ctrls == NULL ) {
468 for( c = ctrls ; *c != NULL; c++ ) {
469 if( (*c)->ldctl_iscritical ) {
470 ld->ld_errno = LDAP_NOT_SUPPORTED;