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 (*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 LDAP_P((
112 LDAPControl ***ctrls ))
115 unsigned long tag, len;
118 assert( ber != NULL );
119 assert( ctrls != NULL );
123 len = ber_pvt_ber_remaining(ber);
130 if(( tag = ber_peek_tag( ber, &len )) != LDAP_TAG_CONTROLS ) {
131 if( tag == LBER_ERROR ) {
133 return LDAP_DECODING_ERROR;
136 /* ignore unexpected input */
140 /* set through each element */
142 *ctrls = LDAP_MALLOC( 1 * sizeof(LDAPControl *) );
144 if( *ctrls == NULL ) {
145 return LDAP_NO_MEMORY;
148 ctrls[nctrls] = NULL;
150 for( tag = ber_first_element( ber, &len, &opaque );
152 tag = ber_next_element( ber, &len, opaque ) )
155 LDAPControl **tctrls;
157 tctrl = LDAP_CALLOC( 1, sizeof(LDAPControl) );
159 /* allocate pointer space for current controls (nctrls)
160 * + this control + extra NULL
162 tctrls = (tctrl == NULL) ? NULL :
163 LDAP_REALLOC(*ctrls, (nctrls+2) * sizeof(LDAPControl *));
165 if( tctrls == NULL ) {
166 /* one of the above allocation failed */
168 if( tctrl != NULL ) {
172 ldap_controls_free(*ctrls);
175 return LDAP_NO_MEMORY;
179 tctrls[nctrls++] = tctrl;
180 tctrls[nctrls] = NULL;
182 tag = ber_scanf( ber, "{a", &tctrl->ldctl_oid );
184 if( tag != LBER_ERROR ) {
185 tag = ber_peek_tag( ber, &len );
188 if( tag == LBER_BOOLEAN ) {
189 tag = ber_scanf( ber, "b", &tctrl->ldctl_iscritical );
192 if( tag != LBER_ERROR ) {
193 tag = ber_peek_tag( ber, &len );
196 if( tag == LBER_OCTETSTRING ) {
197 tag = ber_scanf( ber, "o", &tctrl->ldctl_value );
200 tctrl->ldctl_value.bv_val = NULL;
203 if( tag == LBER_ERROR ) {
205 ldap_controls_free( tctrls );
206 return LDAP_DECODING_ERROR;
219 ldap_control_free( LDAPControl *c )
224 if( c->ldctl_oid != NULL) {
225 LDAP_FREE( c->ldctl_oid );
228 if( c->ldctl_value.bv_val != NULL ) {
229 LDAP_FREE( c->ldctl_value.bv_val );
237 * Free an array of LDAPControl's
240 ldap_controls_free( LDAPControl **controls )
242 assert( controls != NULL );
244 if ( controls != NULL ) {
247 for(c = *controls; c != NULL; c++) {
248 ldap_control_free( c );
251 LDAP_FREE( controls );
256 * Duplicate an array of LDAPControl
258 LDAPControl **ldap_controls_dup( const LDAPControl **controls )
263 if ( controls == NULL ) {
267 /* count the controls */
268 for(i=0; controls[i] != NULL; i++) /* empty */ ;
271 /* no controls to duplicate */
275 new = (LDAPControl **) LDAP_MALLOC( i * sizeof(LDAPControl *) );
278 /* memory allocation failure */
282 /* duplicate the controls */
283 for(i=0; controls[i] != NULL; i++) {
284 new[i] = ldap_control_dup( controls[i] );
286 if( new[i] == NULL ) {
287 ldap_controls_free( new );
298 * Duplicate a LDAPControl
300 LDAPControl *ldap_control_dup( const LDAPControl *c )
308 new = (LDAPControl *) LDAP_MALLOC( sizeof(LDAPControl) );
314 if( c->ldctl_oid != NULL ) {
315 new->ldctl_oid = LDAP_STRDUP( c->ldctl_oid );
317 if(new->ldctl_oid == NULL) {
323 new->ldctl_oid = NULL;
326 if( c->ldctl_value.bv_len > 0 ) {
327 new->ldctl_value.bv_val = (char *) LDAP_MALLOC( c->ldctl_value.bv_len );
329 if(new->ldctl_value.bv_val == NULL) {
330 if(new->ldctl_oid != NULL) {
331 LDAP_FREE( new->ldctl_oid );
337 SAFEMEMCPY( new->ldctl_value.bv_val, c->ldctl_value.bv_val,
338 c->ldctl_value.bv_len );
340 new->ldctl_value.bv_len = c->ldctl_value.bv_len;
343 new->ldctl_value.bv_len = 0;
344 new->ldctl_value.bv_val = NULL;
347 new->ldctl_iscritical = c->ldctl_iscritical;