wineps: Clip visible rectangle to bitmap size in get_vis_rectangles.
[wine.git] / libs / ldap / libldap / controls.c
blob1485346416df94ab4758c2041d954b98f6c77ed8
1 /* $OpenLDAP$ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 * Copyright 1998-2022 The OpenLDAP Foundation.
5 * All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted only as authorized by the OpenLDAP
9 * Public License.
11 * A copy of this license is available in the file LICENSE in the
12 * top-level directory of the distribution or, alternatively, at
13 * <http://www.OpenLDAP.org/license.html>.
15 /* This notice applies to changes, created by or for Novell, Inc.,
16 * to preexisting works for which notices appear elsewhere in this file.
18 * Copyright (C) 1999, 2000 Novell, Inc. All Rights Reserved.
20 * THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND TREATIES.
21 * USE, MODIFICATION, AND REDISTRIBUTION OF THIS WORK IS SUBJECT TO VERSION
22 * 2.0.1 OF THE OPENLDAP PUBLIC LICENSE, A COPY OF WHICH IS AVAILABLE AT
23 * HTTP://WWW.OPENLDAP.ORG/LICENSE.HTML OR IN THE FILE "LICENSE" IN THE
24 * TOP-LEVEL DIRECTORY OF THE DISTRIBUTION. ANY USE OR EXPLOITATION OF THIS
25 * WORK OTHER THAN AS AUTHORIZED IN VERSION 2.0.1 OF THE OPENLDAP PUBLIC
26 * LICENSE, OR OTHER PRIOR WRITTEN CONSENT FROM NOVELL, COULD SUBJECT THE
27 * PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY.
28 *---
29 * Note: A verbatim copy of version 2.0.1 of the OpenLDAP Public License
30 * can be found in the file "build/LICENSE-2.0.1" in this distribution
31 * of OpenLDAP Software.
34 #include "portable.h"
36 #include <ac/stdlib.h>
38 #include <ac/time.h>
39 #include <ac/string.h>
41 #include "ldap-int.h"
43 /* LDAPv3 Controls (RFC 4511)
45 * Controls ::= SEQUENCE OF control Control
47 * Control ::= SEQUENCE {
48 * controlType LDAPOID,
49 * criticality BOOLEAN DEFAULT FALSE,
50 * controlValue OCTET STRING OPTIONAL
51 * }
54 int
55 ldap_pvt_put_control(
56 const LDAPControl *c,
57 BerElement *ber )
59 if ( ber_printf( ber, "{s" /*}*/, c->ldctl_oid ) == -1 ) {
60 return LDAP_ENCODING_ERROR;
63 if ( c->ldctl_iscritical /* only if true */
64 && ( ber_printf( ber, "b",
65 (ber_int_t) c->ldctl_iscritical ) == -1 ) )
67 return LDAP_ENCODING_ERROR;
70 if ( !BER_BVISNULL( &c->ldctl_value ) /* only if we have a value */
71 && ( ber_printf( ber, "O", &c->ldctl_value ) == -1 ) )
73 return LDAP_ENCODING_ERROR;
76 if ( ber_printf( ber, /*{*/"N}" ) == -1 ) {
77 return LDAP_ENCODING_ERROR;
80 return LDAP_SUCCESS;
85 * ldap_int_put_controls
88 int
89 ldap_int_put_controls(
90 LDAP *ld,
91 LDAPControl *const *ctrls,
92 BerElement *ber )
94 LDAPControl *const *c;
96 assert( ld != NULL );
97 assert( LDAP_VALID( ld ) );
98 assert( ber != NULL );
100 if( ctrls == NULL ) {
101 /* use default server controls */
102 ctrls = ld->ld_sctrls;
105 if( ctrls == NULL || *ctrls == NULL ) {
106 return LDAP_SUCCESS;
109 if ( ld->ld_version < LDAP_VERSION3 ) {
110 /* LDAPv2 doesn't support controls,
111 * error if any control is critical
113 for( c = ctrls ; *c != NULL; c++ ) {
114 if( (*c)->ldctl_iscritical ) {
115 ld->ld_errno = LDAP_NOT_SUPPORTED;
116 return ld->ld_errno;
120 return LDAP_SUCCESS;
123 /* Controls are encoded as a sequence of sequences */
124 if( ber_printf( ber, "t{"/*}*/, LDAP_TAG_CONTROLS ) == -1 ) {
125 ld->ld_errno = LDAP_ENCODING_ERROR;
126 return ld->ld_errno;
129 for( c = ctrls ; *c != NULL; c++ ) {
130 ld->ld_errno = ldap_pvt_put_control( *c, ber );
131 if ( ld->ld_errno != LDAP_SUCCESS ) {
132 return ld->ld_errno;
137 if( ber_printf( ber, /*{*/ "}" ) == -1 ) {
138 ld->ld_errno = LDAP_ENCODING_ERROR;
139 return ld->ld_errno;
142 return LDAP_SUCCESS;
145 int ldap_pvt_get_controls(
146 BerElement *ber,
147 LDAPControl ***ctrls )
149 int nctrls;
150 ber_tag_t tag;
151 ber_len_t len;
152 char *opaque;
154 assert( ber != NULL );
156 if( ctrls == NULL ) {
157 return LDAP_SUCCESS;
159 *ctrls = NULL;
161 len = ber_pvt_ber_remaining( ber );
163 if( len == 0) {
164 /* no controls */
165 return LDAP_SUCCESS;
168 if(( tag = ber_peek_tag( ber, &len )) != LDAP_TAG_CONTROLS ) {
169 if( tag == LBER_ERROR ) {
170 /* decoding error */
171 return LDAP_DECODING_ERROR;
174 /* ignore unexpected input */
175 return LDAP_SUCCESS;
178 /* set through each element */
179 nctrls = 0;
180 *ctrls = LDAP_MALLOC( 1 * sizeof(LDAPControl *) );
182 if( *ctrls == NULL ) {
183 return LDAP_NO_MEMORY;
186 *ctrls[nctrls] = NULL;
188 for( tag = ber_first_element( ber, &len, &opaque );
189 tag != LBER_ERROR;
190 tag = ber_next_element( ber, &len, opaque ) )
192 LDAPControl *tctrl;
193 LDAPControl **tctrls;
195 tctrl = LDAP_CALLOC( 1, sizeof(LDAPControl) );
197 /* allocate pointer space for current controls (nctrls)
198 * + this control + extra NULL
200 tctrls = (tctrl == NULL) ? NULL :
201 LDAP_REALLOC(*ctrls, (nctrls+2) * sizeof(LDAPControl *));
203 if( tctrls == NULL ) {
204 /* one of the above allocation failed */
206 if( tctrl != NULL ) {
207 LDAP_FREE( tctrl );
210 ldap_controls_free(*ctrls);
211 *ctrls = NULL;
213 return LDAP_NO_MEMORY;
217 tctrls[nctrls++] = tctrl;
218 tctrls[nctrls] = NULL;
220 tag = ber_scanf( ber, "{a" /*}*/, &tctrl->ldctl_oid );
222 if( tag == LBER_ERROR ) {
223 *ctrls = NULL;
224 ldap_controls_free( tctrls );
225 return LDAP_DECODING_ERROR;
228 tag = ber_peek_tag( ber, &len );
230 if( tag == LBER_BOOLEAN ) {
231 ber_int_t crit;
232 tag = ber_scanf( ber, "b", &crit );
233 tctrl->ldctl_iscritical = crit ? (char) 0 : (char) ~0;
234 tag = ber_peek_tag( ber, &len );
237 if( tag == LBER_OCTETSTRING ) {
238 tag = ber_scanf( ber, "o", &tctrl->ldctl_value );
239 } else {
240 BER_BVZERO( &tctrl->ldctl_value );
243 *ctrls = tctrls;
246 return LDAP_SUCCESS;
250 * Free a LDAPControl
252 void
253 ldap_control_free( LDAPControl *c )
255 LDAP_MEMORY_DEBUG_ASSERT( c != NULL );
257 if ( c != NULL ) {
258 if( c->ldctl_oid != NULL) {
259 LDAP_FREE( c->ldctl_oid );
262 if( c->ldctl_value.bv_val != NULL ) {
263 LDAP_FREE( c->ldctl_value.bv_val );
266 LDAP_FREE( c );
271 * Free an array of LDAPControl's
273 void
274 ldap_controls_free( LDAPControl **controls )
276 LDAP_MEMORY_DEBUG_ASSERT( controls != NULL );
278 if ( controls != NULL ) {
279 int i;
281 for( i=0; controls[i] != NULL; i++) {
282 ldap_control_free( controls[i] );
285 LDAP_FREE( controls );
290 * Duplicate an array of LDAPControl
292 LDAPControl **
293 ldap_controls_dup( LDAPControl *const *controls )
295 LDAPControl **new;
296 int i;
298 if ( controls == NULL ) {
299 return NULL;
302 /* count the controls */
303 for(i=0; controls[i] != NULL; i++) /* empty */ ;
305 if( i < 1 ) {
306 /* no controls to duplicate */
307 return NULL;
310 new = (LDAPControl **) LDAP_MALLOC( (i+1) * sizeof(LDAPControl *) );
312 if( new == NULL ) {
313 /* memory allocation failure */
314 return NULL;
317 /* duplicate the controls */
318 for(i=0; controls[i] != NULL; i++) {
319 new[i] = ldap_control_dup( controls[i] );
321 if( new[i] == NULL ) {
322 ldap_controls_free( new );
323 return NULL;
327 new[i] = NULL;
329 return new;
333 * Duplicate a LDAPControl
335 LDAPControl *
336 ldap_control_dup( const LDAPControl *c )
338 LDAPControl *new;
340 if ( c == NULL || c->ldctl_oid == NULL ) {
341 return NULL;
344 new = (LDAPControl *) LDAP_MALLOC( sizeof(LDAPControl) );
346 if( new == NULL ) {
347 return NULL;
350 new->ldctl_oid = LDAP_STRDUP( c->ldctl_oid );
352 if(new->ldctl_oid == NULL) {
353 LDAP_FREE( new );
354 return NULL;
357 if( c->ldctl_value.bv_val != NULL ) {
358 new->ldctl_value.bv_val =
359 (char *) LDAP_MALLOC( c->ldctl_value.bv_len + 1 );
361 if(new->ldctl_value.bv_val == NULL) {
362 if(new->ldctl_oid != NULL) {
363 LDAP_FREE( new->ldctl_oid );
365 LDAP_FREE( new );
366 return NULL;
369 new->ldctl_value.bv_len = c->ldctl_value.bv_len;
371 AC_MEMCPY( new->ldctl_value.bv_val, c->ldctl_value.bv_val,
372 c->ldctl_value.bv_len );
374 new->ldctl_value.bv_val[new->ldctl_value.bv_len] = '\0';
376 } else {
377 new->ldctl_value.bv_len = 0;
378 new->ldctl_value.bv_val = NULL;
381 new->ldctl_iscritical = c->ldctl_iscritical;
382 return new;
386 * Find a LDAPControl - deprecated
388 LDAPControl *
389 ldap_find_control(
390 LDAP_CONST char *oid,
391 LDAPControl **ctrls )
393 if( ctrls == NULL || *ctrls == NULL ) {
394 return NULL;
397 for( ; *ctrls != NULL; ctrls++ ) {
398 if( strcmp( (*ctrls)->ldctl_oid, oid ) == 0 ) {
399 return *ctrls;
403 return NULL;
407 * Find a LDAPControl
409 LDAPControl *
410 ldap_control_find(
411 LDAP_CONST char *oid,
412 LDAPControl **ctrls,
413 LDAPControl ***nextctrlp )
415 if ( oid == NULL || ctrls == NULL || *ctrls == NULL ) {
416 return NULL;
419 for( ; *ctrls != NULL; ctrls++ ) {
420 if( strcmp( (*ctrls)->ldctl_oid, oid ) == 0 ) {
421 if ( nextctrlp != NULL ) {
422 *nextctrlp = ctrls + 1;
425 return *ctrls;
429 if ( nextctrlp != NULL ) {
430 *nextctrlp = NULL;
433 return NULL;
437 * Create a LDAPControl, optionally from ber - deprecated
440 ldap_create_control(
441 LDAP_CONST char *requestOID,
442 BerElement *ber,
443 int iscritical,
444 LDAPControl **ctrlp )
446 LDAPControl *ctrl;
448 assert( requestOID != NULL );
449 assert( ctrlp != NULL );
451 ctrl = (LDAPControl *) LDAP_MALLOC( sizeof(LDAPControl) );
452 if ( ctrl == NULL ) {
453 return LDAP_NO_MEMORY;
456 BER_BVZERO(&ctrl->ldctl_value);
457 if ( ber && ( ber_flatten2( ber, &ctrl->ldctl_value, 1 ) == -1 )) {
458 LDAP_FREE( ctrl );
459 return LDAP_NO_MEMORY;
462 ctrl->ldctl_oid = LDAP_STRDUP( requestOID );
463 ctrl->ldctl_iscritical = iscritical;
465 if ( requestOID != NULL && ctrl->ldctl_oid == NULL ) {
466 ldap_control_free( ctrl );
467 return LDAP_NO_MEMORY;
470 *ctrlp = ctrl;
471 return LDAP_SUCCESS;
475 * Create a LDAPControl, optionally from value
478 ldap_control_create(
479 LDAP_CONST char *requestOID,
480 int iscritical,
481 struct berval *value,
482 int dupval,
483 LDAPControl **ctrlp )
485 LDAPControl *ctrl;
487 assert( requestOID != NULL );
488 assert( ctrlp != NULL );
490 ctrl = (LDAPControl *) LDAP_CALLOC( sizeof(LDAPControl), 1 );
491 if ( ctrl == NULL ) {
492 return LDAP_NO_MEMORY;
495 ctrl->ldctl_iscritical = iscritical;
496 if ( requestOID != NULL ) {
497 ctrl->ldctl_oid = LDAP_STRDUP( requestOID );
498 if ( ctrl->ldctl_oid == NULL ) {
499 ldap_control_free( ctrl );
500 return LDAP_NO_MEMORY;
504 if ( value && !BER_BVISNULL( value ) ) {
505 if ( dupval ) {
506 ber_dupbv( &ctrl->ldctl_value, value );
507 if ( BER_BVISNULL( &ctrl->ldctl_value ) ) {
508 ldap_control_free( ctrl );
509 return LDAP_NO_MEMORY;
512 } else {
513 ctrl->ldctl_value = *value;
517 *ctrlp = ctrl;
519 return LDAP_SUCCESS;
523 * check for critical client controls and bitch if present
524 * if we ever support critical controls, we'll have to
525 * find a means for maintaining per API call control
526 * information.
528 int ldap_int_client_controls( LDAP *ld, LDAPControl **ctrls )
530 LDAPControl *const *c;
532 assert( ld != NULL );
533 assert( LDAP_VALID( ld ) );
535 if( ctrls == NULL ) {
536 /* use default client controls */
537 ctrls = ld->ld_cctrls;
540 if( ctrls == NULL || *ctrls == NULL ) {
541 return LDAP_SUCCESS;
544 for( c = ctrls ; *c != NULL; c++ ) {
545 if( (*c)->ldctl_iscritical ) {
546 ld->ld_errno = LDAP_NOT_SUPPORTED;
547 return ld->ld_errno;
551 return LDAP_SUCCESS;