3 * Copyright 1998-2000 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-2000 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 if ( requestOID == NULL || ctrlp == NULL ) {
417 return LDAP_PARAM_ERROR;
420 ctrl = (LDAPControl *) LDAP_MALLOC( sizeof(LDAPControl) );
421 if ( ctrl == NULL ) {
422 return LDAP_NO_MEMORY;
425 if ( ber_flatten( ber, &bvalp ) == LBER_ERROR ) {
427 return LDAP_NO_MEMORY;
430 ctrl->ldctl_value = *bvalp;
431 ber_memfree( bvalp );
433 ctrl->ldctl_oid = LDAP_STRDUP( requestOID );
434 ctrl->ldctl_iscritical = iscritical;
436 if ( requestOID != NULL && ctrl->ldctl_oid == NULL ) {
437 ldap_control_free( ctrl );
438 return LDAP_NO_MEMORY;