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
32 ldap_int_put_controls(
34 LDAPControl *const *ctrls,
37 LDAPControl *const *c;
40 assert( ber != NULL );
43 /* use default server controls */
44 ctrls = ld->ld_sctrls;
47 if( ctrls == NULL || *ctrls == NULL ) {
51 if ( ld->ld_version < LDAP_VERSION3 ) {
52 /* LDAPv2 doesn't support controls,
53 * error if any control is critical
55 for( c = ctrls ; *c != NULL; c++ ) {
56 if( (*c)->ldctl_iscritical ) {
57 ld->ld_errno = LDAP_NOT_SUPPORTED;
65 /* Controls are encoded as a sequence of sequences */
66 if( ber_printf( ber, "t{"/*}*/, LDAP_TAG_CONTROLS ) == -1 ) {
67 ld->ld_errno = LDAP_ENCODING_ERROR;
71 for( c = ctrls ; *c != NULL; c++ ) {
72 if ( ber_printf( ber, "{s" /*}*/,
73 (*c)->ldctl_oid ) == -1 )
75 ld->ld_errno = LDAP_ENCODING_ERROR;
79 if( (*c)->ldctl_iscritical /* only if true */
80 && ( ber_printf( ber, "b",
81 (ber_int_t) (*c)->ldctl_iscritical ) == -1 ) )
83 ld->ld_errno = LDAP_ENCODING_ERROR;
87 if( (*c)->ldctl_value.bv_val != NULL /* only if we have a value */
88 && ( ber_printf( ber, "O",
89 &((*c)->ldctl_value) ) == -1 ) )
91 ld->ld_errno = LDAP_ENCODING_ERROR;
96 if( ber_printf( ber, /*{*/"}" ) == -1 ) {
97 ld->ld_errno = LDAP_ENCODING_ERROR;
103 if( ber_printf( ber, /*{*/"}" ) == -1 ) {
104 ld->ld_errno = LDAP_ENCODING_ERROR;
111 int ldap_int_get_controls(
113 LDAPControl ***ctrls )
120 assert( ber != NULL );
122 if( ctrls == NULL ) {
127 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 )
231 if( c->ldctl_oid != NULL) {
232 LDAP_FREE( c->ldctl_oid );
235 if( c->ldctl_value.bv_val != NULL ) {
236 LDAP_FREE( c->ldctl_value.bv_val );
244 * Free an array of LDAPControl's
247 ldap_controls_free( LDAPControl **controls )
249 assert( controls != NULL );
251 if ( controls != NULL ) {
254 for( i=0; controls[i] != NULL; i++) {
255 ldap_control_free( controls[i] );
258 LDAP_FREE( controls );
263 * Duplicate an array of LDAPControl
266 ldap_controls_dup( LDAPControl *const *controls )
271 if ( controls == NULL ) {
275 /* count the controls */
276 for(i=0; controls[i] != NULL; i++) /* empty */ ;
279 /* no controls to duplicate */
283 new = (LDAPControl **) LDAP_MALLOC( i * sizeof(LDAPControl *) );
286 /* memory allocation failure */
290 /* duplicate the controls */
291 for(i=0; controls[i] != NULL; i++) {
292 new[i] = ldap_control_dup( controls[i] );
294 if( new[i] == NULL ) {
295 ldap_controls_free( new );
306 * Duplicate a LDAPControl
309 ldap_control_dup( const LDAPControl *c )
317 new = (LDAPControl *) LDAP_MALLOC( sizeof(LDAPControl) );
323 if( c->ldctl_oid != NULL ) {
324 new->ldctl_oid = LDAP_STRDUP( c->ldctl_oid );
326 if(new->ldctl_oid == NULL) {
332 new->ldctl_oid = NULL;
335 if( c->ldctl_value.bv_len > 0 ) {
336 new->ldctl_value.bv_val = (char *) LDAP_MALLOC( c->ldctl_value.bv_len );
338 if(new->ldctl_value.bv_val == NULL) {
339 if(new->ldctl_oid != NULL) {
340 LDAP_FREE( new->ldctl_oid );
346 SAFEMEMCPY( new->ldctl_value.bv_val, c->ldctl_value.bv_val,
347 c->ldctl_value.bv_len );
349 new->ldctl_value.bv_len = c->ldctl_value.bv_len;
352 new->ldctl_value.bv_len = 0;
353 new->ldctl_value.bv_val = NULL;
356 new->ldctl_iscritical = c->ldctl_iscritical;