3 * Copyright 1998-1999 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, /*{*/"}" ) == -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;