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( ber != NULL );
44 /* use default server controls */
45 ctrls = ld->ld_sctrls;
48 if( ctrls == NULL || *ctrls == NULL ) {
52 if ( ld->ld_version < LDAP_VERSION3 ) {
53 /* LDAPv2 doesn't support controls,
54 * error if any control is critical
56 for( c = ctrls ; *c != NULL; c++ ) {
57 if( (*c)->ldctl_iscritical ) {
58 ld->ld_errno = LDAP_NOT_SUPPORTED;
66 /* Controls are encoded as a sequence of sequences */
67 if( ber_printf( ber, "t{"/*}*/, LDAP_TAG_CONTROLS ) == -1 ) {
68 ld->ld_errno = LDAP_ENCODING_ERROR;
72 for( c = ctrls ; *c != NULL; c++ ) {
73 if ( ber_printf( ber, "{s" /*}*/,
74 (*c)->ldctl_oid ) == -1 )
76 ld->ld_errno = LDAP_ENCODING_ERROR;
80 if( (*c)->ldctl_iscritical /* only if true */
81 && ( ber_printf( ber, "b",
82 (ber_int_t) (*c)->ldctl_iscritical ) == -1 ) )
84 ld->ld_errno = LDAP_ENCODING_ERROR;
88 if( (*c)->ldctl_value.bv_val != NULL /* only if we have a value */
89 && ( ber_printf( ber, "O",
90 &((*c)->ldctl_value) ) == -1 ) )
92 ld->ld_errno = LDAP_ENCODING_ERROR;
97 if( ber_printf( ber, /*{*/"N}" ) == -1 ) {
98 ld->ld_errno = LDAP_ENCODING_ERROR;
104 if( ber_printf( ber, /*{*/ "}" ) == -1 ) {
105 ld->ld_errno = LDAP_ENCODING_ERROR;
112 int ldap_int_get_controls(
114 LDAPControl ***ctrls )
121 assert( ber != NULL );
123 if( ctrls == NULL ) {
128 len = ber_pvt_ber_remaining( ber );
135 if(( tag = ber_peek_tag( ber, &len )) != LDAP_TAG_CONTROLS ) {
136 if( tag == LBER_ERROR ) {
138 return LDAP_DECODING_ERROR;
141 /* ignore unexpected input */
145 /* set through each element */
147 *ctrls = LDAP_MALLOC( 1 * sizeof(LDAPControl *) );
149 if( *ctrls == NULL ) {
150 return LDAP_NO_MEMORY;
153 *ctrls[nctrls] = NULL;
155 for( tag = ber_first_element( ber, &len, &opaque );
157 tag = ber_next_element( ber, &len, opaque ) )
160 LDAPControl **tctrls;
162 tctrl = LDAP_CALLOC( 1, sizeof(LDAPControl) );
164 /* allocate pointer space for current controls (nctrls)
165 * + this control + extra NULL
167 tctrls = (tctrl == NULL) ? NULL :
168 LDAP_REALLOC(*ctrls, (nctrls+2) * sizeof(LDAPControl *));
170 if( tctrls == NULL ) {
171 /* one of the above allocation failed */
173 if( tctrl != NULL ) {
177 ldap_controls_free(*ctrls);
180 return LDAP_NO_MEMORY;
184 tctrls[nctrls++] = tctrl;
185 tctrls[nctrls] = NULL;
187 tag = ber_scanf( ber, "{a" /*}*/, &tctrl->ldctl_oid );
189 if( tag != LBER_ERROR ) {
190 tag = ber_peek_tag( ber, &len );
193 if( tag == LBER_BOOLEAN ) {
195 tag = ber_scanf( ber, "b", &crit );
196 tctrl->ldctl_iscritical = crit ? (char) 0 : (char) ~0;
199 if( tag != LBER_ERROR ) {
200 tag = ber_peek_tag( ber, &len );
203 if( tag == LBER_OCTETSTRING ) {
204 tag = ber_scanf( ber, "o", &tctrl->ldctl_value );
207 tctrl->ldctl_value.bv_val = NULL;
210 if( tag == LBER_ERROR ) {
212 ldap_controls_free( tctrls );
213 return LDAP_DECODING_ERROR;
226 ldap_control_free( LDAPControl *c )
228 #ifdef LDAP_MEMORY_DEBUG
233 if( c->ldctl_oid != NULL) {
234 LDAP_FREE( c->ldctl_oid );
237 if( c->ldctl_value.bv_val != NULL ) {
238 LDAP_FREE( c->ldctl_value.bv_val );
246 * Free an array of LDAPControl's
249 ldap_controls_free( LDAPControl **controls )
251 #ifdef LDAP_MEMORY_DEBUG
252 assert( controls != NULL );
255 if ( controls != NULL ) {
258 for( i=0; controls[i] != NULL; i++) {
259 ldap_control_free( controls[i] );
262 LDAP_FREE( controls );
267 * Duplicate an array of LDAPControl
270 ldap_controls_dup( LDAPControl *const *controls )
275 if ( controls == NULL ) {
279 /* count the controls */
280 for(i=0; controls[i] != NULL; i++) /* empty */ ;
283 /* no controls to duplicate */
287 new = (LDAPControl **) LDAP_MALLOC( i * sizeof(LDAPControl *) );
290 /* memory allocation failure */
294 /* duplicate the controls */
295 for(i=0; controls[i] != NULL; i++) {
296 new[i] = ldap_control_dup( controls[i] );
298 if( new[i] == NULL ) {
299 ldap_controls_free( new );
310 * Duplicate a LDAPControl
313 ldap_control_dup( const LDAPControl *c )
321 new = (LDAPControl *) LDAP_MALLOC( sizeof(LDAPControl) );
327 if( c->ldctl_oid != NULL ) {
328 new->ldctl_oid = LDAP_STRDUP( c->ldctl_oid );
330 if(new->ldctl_oid == NULL) {
336 new->ldctl_oid = NULL;
339 if( c->ldctl_value.bv_val != NULL ) {
340 new->ldctl_value.bv_val =
341 (char *) LDAP_MALLOC( c->ldctl_value.bv_len + 1 );
343 if(new->ldctl_value.bv_val == NULL) {
344 if(new->ldctl_oid != NULL) {
345 LDAP_FREE( new->ldctl_oid );
351 new->ldctl_value.bv_len = c->ldctl_value.bv_len;
353 AC_MEMCPY( new->ldctl_value.bv_val, c->ldctl_value.bv_val,
354 c->ldctl_value.bv_len );
356 new->ldctl_value.bv_val[new->ldctl_value.bv_len] = '\0';
359 new->ldctl_value.bv_len = 0;
360 new->ldctl_value.bv_val = NULL;
363 new->ldctl_iscritical = c->ldctl_iscritical;
368 * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
369 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
371 /* Adapted for inclusion into OpenLDAP by Kurt D. Zeilenga */
373 * This notice applies to changes, created by or for Novell, Inc.,
374 * to preexisting works for which notices appear elsewhere in this file.
376 * Copyright (C) 1999, 2000 Novell, Inc. All Rights Reserved.
378 * THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND TREATIES.
379 * USE, MODIFICATION, AND REDISTRIBUTION OF THIS WORK IS SUBJECT TO VERSION
380 * 2.0.1 OF THE OPENLDAP PUBLIC LICENSE, A COPY OF WHICH IS AVAILABLE AT
381 * HTTP://WWW.OPENLDAP.ORG/LICENSE.HTML OR IN THE FILE "LICENSE" IN THE
382 * TOP-LEVEL DIRECTORY OF THE DISTRIBUTION. ANY USE OR EXPLOITATION OF THIS
383 * WORK OTHER THAN AS AUTHORIZED IN VERSION 2.0.1 OF THE OPENLDAP PUBLIC
384 * LICENSE, OR OTHER PRIOR WRITTEN CONSENT FROM NOVELL, COULD SUBJECT THE
385 * PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY.
387 * Modification to OpenLDAP source by Novell, Inc.
388 * June 2000 sfs Added control utilities
393 Internal function to create an LDAP control from the encoded BerElement.
395 requestOID (IN) The OID to use in creating the control.
397 ber (IN) The encoded BerElement to use in creating the control.
399 iscritical (IN) 0 - Indicates the control is not critical to the operation.
400 non-zero - The control is critical to the operation.
402 ctrlp (OUT) Returns a pointer to the LDAPControl created. This control
403 SHOULD be freed by calling ldap_control_free() when done.
408 LDAP_CONST char *requestOID,
411 LDAPControl **ctrlp )
414 struct berval *bvalp;
416 assert( requestOID != NULL );
417 assert( ctrlp != NULL );
419 ctrl = (LDAPControl *) LDAP_MALLOC( sizeof(LDAPControl) );
420 if ( ctrl == NULL ) {
421 return LDAP_NO_MEMORY;
424 if ( ber_flatten( ber, &bvalp ) == -1 ) {
426 return LDAP_NO_MEMORY;
429 ctrl->ldctl_value = *bvalp;
430 ber_memfree( bvalp );
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 );
456 if( ctrls == NULL ) {
457 /* use default server controls */
458 ctrls = ld->ld_cctrls;
461 if( ctrls == NULL || *ctrls == NULL ) {
465 for( c = ctrls ; *c != NULL; c++ ) {
466 if( (*c)->ldctl_iscritical ) {
467 ld->ld_errno = LDAP_NOT_SUPPORTED;