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_len > 0 ) {
340 new->ldctl_value.bv_val = (char *) LDAP_MALLOC( c->ldctl_value.bv_len );
342 if(new->ldctl_value.bv_val == NULL) {
343 if(new->ldctl_oid != NULL) {
344 LDAP_FREE( new->ldctl_oid );
350 AC_MEMCPY( new->ldctl_value.bv_val, c->ldctl_value.bv_val,
351 c->ldctl_value.bv_len );
353 new->ldctl_value.bv_len = c->ldctl_value.bv_len;
356 new->ldctl_value.bv_len = 0;
357 new->ldctl_value.bv_val = NULL;
360 new->ldctl_iscritical = c->ldctl_iscritical;
365 * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
366 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
368 /* Adapted for inclusion into OpenLDAP by Kurt D. Zeilenga */
370 * This notice applies to changes, created by or for Novell, Inc.,
371 * to preexisting works for which notices appear elsewhere in this file.
373 * Copyright (C) 1999, 2000 Novell, Inc. All Rights Reserved.
375 * THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND TREATIES.
376 * USE, MODIFICATION, AND REDISTRIBUTION OF THIS WORK IS SUBJECT TO VERSION
377 * 2.0.1 OF THE OPENLDAP PUBLIC LICENSE, A COPY OF WHICH IS AVAILABLE AT
378 * HTTP://WWW.OPENLDAP.ORG/LICENSE.HTML OR IN THE FILE "LICENSE" IN THE
379 * TOP-LEVEL DIRECTORY OF THE DISTRIBUTION. ANY USE OR EXPLOITATION OF THIS
380 * WORK OTHER THAN AS AUTHORIZED IN VERSION 2.0.1 OF THE OPENLDAP PUBLIC
381 * LICENSE, OR OTHER PRIOR WRITTEN CONSENT FROM NOVELL, COULD SUBJECT THE
382 * PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY.
384 * Modification to OpenLDAP source by Novell, Inc.
385 * June 2000 sfs Added control utilities
390 Internal function to create an LDAP control from the encoded BerElement.
392 requestOID (IN) The OID to use in creating the control.
394 ber (IN) The encoded BerElement to use in creating the control.
396 iscritical (IN) 0 - Indicates the control is not critical to the operation.
397 non-zero - The control is critical to the operation.
399 ctrlp (OUT) Returns a pointer to the LDAPControl created. This control
400 SHOULD be freed by calling ldap_control_free() when done.
405 LDAP_CONST char *requestOID,
408 LDAPControl **ctrlp )
411 struct berval *bvalp;
413 if ( requestOID == NULL || ber == NULL || ctrlp == NULL ) {
414 return LDAP_PARAM_ERROR;
417 ctrl = (LDAPControl *) LDAP_MALLOC( sizeof(LDAPControl) );
418 if ( ctrl == NULL ) {
419 return LDAP_NO_MEMORY;
422 if ( ber_flatten( ber, &bvalp ) == LBER_ERROR ) {
424 return LDAP_NO_MEMORY;
427 ctrl->ldctl_value = *bvalp;
428 ber_memfree( bvalp );
430 ctrl->ldctl_oid = LDAP_STRDUP( requestOID );
431 ctrl->ldctl_iscritical = iscritical;
433 if ( requestOID != NULL && ctrl->ldctl_oid == NULL ) {
434 ldap_control_free( ctrl );
435 return LDAP_NO_MEMORY;