2 * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
3 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
6 /* LDAPv3 Controls (RFC2251)
8 * Controls ::= SEQUENCE OF Control
10 * Control ::= SEQUENCE {
11 * controlType LDAPOID,
12 * criticality BOOLEAN DEFAULT FALSE,
13 * controlValue OCTET STRING OPTIONAL
19 #include <ac/stdlib.h>
22 #include <ac/string.h>
28 * ldap_int_put_controls
31 int ldap_int_put_controls(
39 assert( ber != NULL );
42 /* use default server controls */
43 ctrls = ld->ld_sctrls;
46 if( ctrls == NULL || *ctrls == NULL ) {
50 if ( ld->ld_version < LDAP_VERSION3 ) {
51 /* LDAPv2 doesn't support controls,
52 * error if any control is critical
54 for( c = ctrls ; *c != NULL; c++ ) {
55 if( (*c)->ldctl_iscritical ) {
56 ld->ld_errno = LDAP_NOT_SUPPORTED;
64 /* Controls are encoded as a sequence of sequences */
65 if( ber_printf( ber, "t{"/*}*/, LDAP_TAG_CONTROLS ) == -1 ) {
66 ld->ld_errno = LDAP_ENCODING_ERROR;
70 for( c = ctrls ; *c != NULL; c++ ) {
71 if ( ber_printf( ber, "{s" /*}*/,
72 (*c)->ldctl_oid ) == -1 )
74 ld->ld_errno = LDAP_ENCODING_ERROR;
78 if( (*c)->ldctl_iscritical /* only if true */
79 && ( ber_printf( ber, "b",
80 (ber_int_t) (*c)->ldctl_iscritical ) == -1 ) )
82 ld->ld_errno = LDAP_ENCODING_ERROR;
86 if( (*c)->ldctl_value.bv_val != NULL /* only if we have a value */
87 && ( ber_printf( ber, "O",
88 &((*c)->ldctl_value) ) == -1 ) )
90 ld->ld_errno = LDAP_ENCODING_ERROR;
95 if( ber_printf( ber, /*{*/"}" ) == -1 ) {
96 ld->ld_errno = LDAP_ENCODING_ERROR;
102 if( ber_printf( ber, /*{*/"}" ) == -1 ) {
103 ld->ld_errno = LDAP_ENCODING_ERROR;
110 int ldap_int_get_controls(
112 LDAPControl ***ctrls )
119 assert( ber != NULL );
121 if( ctrls == NULL ) {
126 len = ber_pvt_ber_remaining(ber);
134 if(( tag = ber_peek_tag( ber, &len )) != LDAP_TAG_CONTROLS ) {
135 if( tag == LBER_ERROR ) {
137 return LDAP_DECODING_ERROR;
140 /* ignore unexpected input */
144 /* set through each element */
146 *ctrls = LDAP_MALLOC( 1 * sizeof(LDAPControl *) );
148 if( *ctrls == NULL ) {
149 return LDAP_NO_MEMORY;
152 ctrls[nctrls] = NULL;
154 for( tag = ber_first_element( ber, &len, &opaque );
156 tag = ber_next_element( ber, &len, opaque ) )
159 LDAPControl **tctrls;
161 tctrl = LDAP_CALLOC( 1, sizeof(LDAPControl) );
163 /* allocate pointer space for current controls (nctrls)
164 * + this control + extra NULL
166 tctrls = (tctrl == NULL) ? NULL :
167 LDAP_REALLOC(*ctrls, (nctrls+2) * sizeof(LDAPControl *));
169 if( tctrls == NULL ) {
170 /* one of the above allocation failed */
172 if( tctrl != NULL ) {
176 ldap_controls_free(*ctrls);
179 return LDAP_NO_MEMORY;
183 tctrls[nctrls++] = tctrl;
184 tctrls[nctrls] = NULL;
186 tag = ber_scanf( ber, "{a" /*}*/, &tctrl->ldctl_oid );
188 if( tag != LBER_ERROR ) {
189 tag = ber_peek_tag( ber, &len );
192 if( tag == LBER_BOOLEAN ) {
194 tag = ber_scanf( ber, "b", &crit );
195 tctrl->ldctl_iscritical = crit ? (char) 0 : (char) ~0;
198 if( tag != LBER_ERROR ) {
199 tag = ber_peek_tag( ber, &len );
202 if( tag == LBER_OCTETSTRING ) {
203 tag = ber_scanf( ber, "o", &tctrl->ldctl_value );
206 tctrl->ldctl_value.bv_val = NULL;
209 if( tag == LBER_ERROR ) {
211 ldap_controls_free( tctrls );
212 return LDAP_DECODING_ERROR;
225 ldap_control_free( LDAPControl *c )
230 if( c->ldctl_oid != NULL) {
231 LDAP_FREE( c->ldctl_oid );
234 if( c->ldctl_value.bv_val != NULL ) {
235 LDAP_FREE( c->ldctl_value.bv_val );
243 * Free an array of LDAPControl's
246 ldap_controls_free( LDAPControl **controls )
248 assert( controls != NULL );
250 if ( controls != NULL ) {
253 for(c = *controls; c != NULL; c++) {
254 ldap_control_free( c );
257 LDAP_FREE( controls );
262 * Duplicate an array of LDAPControl
264 LDAPControl **ldap_controls_dup( LDAPControl **controls )
269 if ( controls == NULL ) {
273 /* count the controls */
274 for(i=0; controls[i] != NULL; i++) /* empty */ ;
277 /* no controls to duplicate */
281 new = (LDAPControl **) LDAP_MALLOC( i * sizeof(LDAPControl *) );
284 /* memory allocation failure */
288 /* duplicate the controls */
289 for(i=0; controls[i] != NULL; i++) {
290 new[i] = ldap_control_dup( controls[i] );
292 if( new[i] == NULL ) {
293 ldap_controls_free( new );
304 * Duplicate a LDAPControl
306 LDAPControl *ldap_control_dup( LDAPControl *c )
314 new = (LDAPControl *) LDAP_MALLOC( sizeof(LDAPControl) );
320 if( c->ldctl_oid != NULL ) {
321 new->ldctl_oid = LDAP_STRDUP( c->ldctl_oid );
323 if(new->ldctl_oid == NULL) {
329 new->ldctl_oid = NULL;
332 if( c->ldctl_value.bv_len > 0 ) {
333 new->ldctl_value.bv_val = (char *) LDAP_MALLOC( c->ldctl_value.bv_len );
335 if(new->ldctl_value.bv_val == NULL) {
336 if(new->ldctl_oid != NULL) {
337 LDAP_FREE( new->ldctl_oid );
343 SAFEMEMCPY( new->ldctl_value.bv_val, c->ldctl_value.bv_val,
344 c->ldctl_value.bv_len );
346 new->ldctl_value.bv_len = c->ldctl_value.bv_len;
349 new->ldctl_value.bv_len = 0;
350 new->ldctl_value.bv_val = NULL;
353 new->ldctl_iscritical = c->ldctl_iscritical;