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);
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 * 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_len > 0 ) {
341 new->ldctl_value.bv_val = (char *) LDAP_MALLOC( c->ldctl_value.bv_len );
343 if(new->ldctl_value.bv_val == NULL) {
344 if(new->ldctl_oid != NULL) {
345 LDAP_FREE( new->ldctl_oid );
351 SAFEMEMCPY( new->ldctl_value.bv_val, c->ldctl_value.bv_val,
352 c->ldctl_value.bv_len );
354 new->ldctl_value.bv_len = c->ldctl_value.bv_len;
357 new->ldctl_value.bv_len = 0;
358 new->ldctl_value.bv_val = NULL;
361 new->ldctl_iscritical = c->ldctl_iscritical;
366 * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
367 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
369 /* Adapted for inclusion into OpenLDAP by Kurt D. Zeilenga */
371 * This notice applies to changes, created by or for Novell, Inc.,
372 * to preexisting works for which notices appear elsewhere in this file.
374 * Copyright (C) 1999, 2000 Novell, Inc. All Rights Reserved.
376 * THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND TREATIES.
377 * USE, MODIFICATION, AND REDISTRIBUTION OF THIS WORK IS SUBJECT TO VERSION
378 * 2.0.1 OF THE OPENLDAP PUBLIC LICENSE, A COPY OF WHICH IS AVAILABLE AT
379 * HTTP://WWW.OPENLDAP.ORG/LICENSE.HTML OR IN THE FILE "LICENSE" IN THE
380 * TOP-LEVEL DIRECTORY OF THE DISTRIBUTION. ANY USE OR EXPLOITATION OF THIS
381 * WORK OTHER THAN AS AUTHORIZED IN VERSION 2.0.1 OF THE OPENLDAP PUBLIC
382 * LICENSE, OR OTHER PRIOR WRITTEN CONSENT FROM NOVELL, COULD SUBJECT THE
383 * PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY.
385 * Modification to OpenLDAP source by Novell, Inc.
386 * June 2000 sfs Added control utilities
391 Internal function to create an LDAP control from the encoded BerElement.
393 requestOID (IN) The OID to use in creating the control.
395 ber (IN) The encoded BerElement to use in creating the control.
397 iscritical (IN) 0 - Indicates the control is not critical to the operation.
398 non-zero - The control is critical to the operation.
400 ctrlp (OUT) Returns a pointer to the LDAPControl created. This control
401 SHOULD be freed by calling ldap_control_free() when done.
406 LDAP_CONST char *requestOID,
409 LDAPControl **ctrlp )
412 struct berval *bvalp;
414 if ( requestOID == NULL || ber == NULL || ctrlp == NULL ) {
415 return LDAP_PARAM_ERROR;
418 ctrl = (LDAPControl *) LDAP_MALLOC( sizeof(LDAPControl) );
419 if ( ctrl == NULL ) {
420 return LDAP_NO_MEMORY;
423 if ( ber_flatten( ber, &bvalp ) == LBER_ERROR ) {
425 return LDAP_NO_MEMORY;
428 ctrl->ldctl_value = *bvalp;
429 ber_memfree( bvalp );
431 ctrl->ldctl_oid = LDAP_STRDUP( requestOID );
432 ctrl->ldctl_iscritical = iscritical;
434 if ( requestOID != NULL && ctrl->ldctl_oid == NULL ) {
435 ldap_control_free( ctrl );
436 return LDAP_NO_MEMORY;