X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libraries%2Flibldap%2Fcontrols.c;h=9925357b0c2065a50d6764155424bd0f5b47eea2;hb=b0b8546f054f31b1a080defede171f833d20b124;hp=e0fe87b1e74e962b7324dc5a7431909edfc4239c;hpb=2b9a296eb45305d4abd12f3633eac7f8b857fdd8;p=openldap diff --git a/libraries/libldap/controls.c b/libraries/libldap/controls.c index e0fe87b1e7..9925357b0c 100644 --- a/libraries/libldap/controls.c +++ b/libraries/libldap/controls.c @@ -1,14 +1,23 @@ +/* $OpenLDAP$ */ /* - * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved. + * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved. * COPYING RESTRICTIONS APPLY, see COPYRIGHT file */ -/* - * LDAP controls + +/* LDAPv3 Controls (RFC2251) + * + * Controls ::= SEQUENCE OF Control + * + * Control ::= SEQUENCE { + * controlType LDAPOID, + * criticality BOOLEAN DEFAULT FALSE, + * controlValue OCTET STRING OPTIONAL + * } */ #include "portable.h" -#include +#include #include #include @@ -20,12 +29,13 @@ * ldap_int_put_controls */ -int ldap_int_put_controls( +int +ldap_int_put_controls( LDAP *ld, - LDAPControl **ctrls, + LDAPControl *const *ctrls, BerElement *ber ) { - LDAPControl **c; + LDAPControl *const *c; assert( ld != NULL ); assert( ber != NULL ); @@ -54,13 +64,13 @@ int ldap_int_put_controls( } /* Controls are encoded as a sequence of sequences */ - if( ber_printf( ber, "t{", LDAP_TAG_CONTROLS ) == -1 ) { + if( ber_printf( ber, "t{"/*}*/, LDAP_TAG_CONTROLS ) == -1 ) { ld->ld_errno = LDAP_ENCODING_ERROR; return ld->ld_errno; } for( c = ctrls ; *c != NULL; c++ ) { - if ( ber_printf( ber, "{s", + if ( ber_printf( ber, "{s" /*}*/, (*c)->ldctl_oid ) == -1 ) { ld->ld_errno = LDAP_ENCODING_ERROR; @@ -69,7 +79,7 @@ int ldap_int_put_controls( if( (*c)->ldctl_iscritical /* only if true */ && ( ber_printf( ber, "b", - (*c)->ldctl_iscritical ) == -1 ) ) + (ber_int_t) (*c)->ldctl_iscritical ) == -1 ) ) { ld->ld_errno = LDAP_ENCODING_ERROR; return ld->ld_errno; @@ -84,14 +94,14 @@ int ldap_int_put_controls( } - if( ber_printf( ber, "}" ) == -1 ) { + if( ber_printf( ber, /*{*/"N}" ) == -1 ) { ld->ld_errno = LDAP_ENCODING_ERROR; return ld->ld_errno; } } - if( ber_printf( ber, "}" ) == -1 ) { + if( ber_printf( ber, /*{*/ "}" ) == -1 ) { ld->ld_errno = LDAP_ENCODING_ERROR; return ld->ld_errno; } @@ -99,20 +109,23 @@ int ldap_int_put_controls( return LDAP_SUCCESS; } -int ldap_int_get_controls LDAP_P(( +int ldap_int_get_controls( BerElement *ber, - LDAPControl ***ctrls )) + LDAPControl ***ctrls ) { int nctrls; - unsigned long tag, len; + ber_tag_t tag; + ber_len_t len; char *opaque; assert( ber != NULL ); - assert( ctrls != NULL ); + if( ctrls == NULL ) { + return LDAP_SUCCESS; + } *ctrls = NULL; - len = ber->ber_end - ber->ber_ptr; + len = ber_pvt_ber_remaining( ber ); if( len == 0) { /* no controls */ @@ -131,39 +144,34 @@ int ldap_int_get_controls LDAP_P(( /* set through each element */ nctrls = 0; - *ctrls = malloc( 1 * sizeof(LDAPControl *) ); + *ctrls = LDAP_MALLOC( 1 * sizeof(LDAPControl *) ); if( *ctrls == NULL ) { return LDAP_NO_MEMORY; } - ctrls[nctrls] = NULL; + *ctrls[nctrls] = NULL; for( tag = ber_first_element( ber, &len, &opaque ); - ( - tag != LBER_ERROR -#ifdef LDAP_END_SEQORSET - && tag != LBER_END_OF_SEQORSET -#endif - ); + tag != LBER_ERROR; tag = ber_next_element( ber, &len, opaque ) ) { LDAPControl *tctrl; LDAPControl **tctrls; - tctrl = calloc( 1, sizeof(LDAPControl) ); + tctrl = LDAP_CALLOC( 1, sizeof(LDAPControl) ); /* allocate pointer space for current controls (nctrls) * + this control + extra NULL */ tctrls = (tctrl == NULL) ? NULL : - realloc(*ctrls, (nctrls+2) * sizeof(LDAPControl *)); + LDAP_REALLOC(*ctrls, (nctrls+2) * sizeof(LDAPControl *)); if( tctrls == NULL ) { /* one of the above allocation failed */ if( tctrl != NULL ) { - free( tctrl ); + LDAP_FREE( tctrl ); } ldap_controls_free(*ctrls); @@ -176,14 +184,16 @@ int ldap_int_get_controls LDAP_P(( tctrls[nctrls++] = tctrl; tctrls[nctrls] = NULL; - tag = ber_scanf( ber, "{a", &tctrl->ldctl_oid ); + tag = ber_scanf( ber, "{a" /*}*/, &tctrl->ldctl_oid ); if( tag != LBER_ERROR ) { tag = ber_peek_tag( ber, &len ); } if( tag == LBER_BOOLEAN ) { - tag = ber_scanf( ber, "b", &tctrl->ldctl_iscritical ); + ber_int_t crit; + tag = ber_scanf( ber, "b", &crit ); + tctrl->ldctl_iscritical = crit ? (char) 0 : (char) ~0; } if( tag != LBER_ERROR ) { @@ -215,16 +225,20 @@ int ldap_int_get_controls LDAP_P(( void ldap_control_free( LDAPControl *c ) { +#ifdef LDAP_MEMORY_DEBUG + assert( c != NULL ); +#endif + if ( c != NULL ) { if( c->ldctl_oid != NULL) { - free( c->ldctl_oid ); + LDAP_FREE( c->ldctl_oid ); } if( c->ldctl_value.bv_val != NULL ) { - free( c->ldctl_value.bv_val ); + LDAP_FREE( c->ldctl_value.bv_val ); } - free( c ); + LDAP_FREE( c ); } } @@ -234,21 +248,26 @@ ldap_control_free( LDAPControl *c ) void ldap_controls_free( LDAPControl **controls ) { +#ifdef LDAP_MEMORY_DEBUG + assert( controls != NULL ); +#endif + if ( controls != NULL ) { - LDAPControl *c; + int i; - for(c = *controls; c != NULL; c++) { - ldap_control_free( c ); + for( i=0; controls[i] != NULL; i++) { + ldap_control_free( controls[i] ); } - free( controls ); + LDAP_FREE( controls ); } } /* * Duplicate an array of LDAPControl */ -LDAPControl **ldap_controls_dup( const LDAPControl **controls ) +LDAPControl ** +ldap_controls_dup( LDAPControl *const *controls ) { LDAPControl **new; int i; @@ -265,7 +284,7 @@ LDAPControl **ldap_controls_dup( const LDAPControl **controls ) return NULL; } - new = (LDAPControl **) malloc( i * sizeof(LDAPControl *) ); + new = (LDAPControl **) LDAP_MALLOC( i * sizeof(LDAPControl *) ); if( new == NULL ) { /* memory allocation failure */ @@ -290,7 +309,8 @@ LDAPControl **ldap_controls_dup( const LDAPControl **controls ) /* * Duplicate a LDAPControl */ -LDAPControl *ldap_control_dup( const LDAPControl *c ) +LDAPControl * +ldap_control_dup( const LDAPControl *c ) { LDAPControl *new; @@ -298,17 +318,17 @@ LDAPControl *ldap_control_dup( const LDAPControl *c ) return NULL; } - new = (LDAPControl *) malloc( sizeof(LDAPControl) ); + new = (LDAPControl *) LDAP_MALLOC( sizeof(LDAPControl) ); if( new == NULL ) { return NULL; } if( c->ldctl_oid != NULL ) { - new->ldctl_oid = strdup( c->ldctl_oid ); + new->ldctl_oid = LDAP_STRDUP( c->ldctl_oid ); if(new->ldctl_oid == NULL) { - free( new ); + LDAP_FREE( new ); return NULL; } @@ -316,21 +336,24 @@ LDAPControl *ldap_control_dup( const LDAPControl *c ) new->ldctl_oid = NULL; } - if( c->ldctl_value.bv_len > 0 ) { - new->ldctl_value.bv_val = (char *) malloc( c->ldctl_value.bv_len ); + if( c->ldctl_value.bv_val != NULL ) { + new->ldctl_value.bv_val = + (char *) LDAP_MALLOC( c->ldctl_value.bv_len + 1 ); if(new->ldctl_value.bv_val == NULL) { if(new->ldctl_oid != NULL) { - free( new->ldctl_oid ); + LDAP_FREE( new->ldctl_oid ); } - free( new ); + LDAP_FREE( new ); return NULL; } - SAFEMEMCPY( new->ldctl_value.bv_val, c->ldctl_value.bv_val, + new->ldctl_value.bv_len = c->ldctl_value.bv_len; + + AC_MEMCPY( new->ldctl_value.bv_val, c->ldctl_value.bv_val, c->ldctl_value.bv_len ); - new->ldctl_value.bv_len = c->ldctl_value.bv_len; + new->ldctl_value.bv_val[new->ldctl_value.bv_len] = '\0'; } else { new->ldctl_value.bv_len = 0; @@ -340,3 +363,112 @@ LDAPControl *ldap_control_dup( const LDAPControl *c ) new->ldctl_iscritical = c->ldctl_iscritical; return new; } + +/* + * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved. + * COPYING RESTRICTIONS APPLY, see COPYRIGHT file + */ +/* Adapted for inclusion into OpenLDAP by Kurt D. Zeilenga */ +/*--- + * This notice applies to changes, created by or for Novell, Inc., + * to preexisting works for which notices appear elsewhere in this file. + * + * Copyright (C) 1999, 2000 Novell, Inc. All Rights Reserved. + * + * THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND TREATIES. + * USE, MODIFICATION, AND REDISTRIBUTION OF THIS WORK IS SUBJECT TO VERSION + * 2.0.1 OF THE OPENLDAP PUBLIC LICENSE, A COPY OF WHICH IS AVAILABLE AT + * HTTP://WWW.OPENLDAP.ORG/LICENSE.HTML OR IN THE FILE "LICENSE" IN THE + * TOP-LEVEL DIRECTORY OF THE DISTRIBUTION. ANY USE OR EXPLOITATION OF THIS + * WORK OTHER THAN AS AUTHORIZED IN VERSION 2.0.1 OF THE OPENLDAP PUBLIC + * LICENSE, OR OTHER PRIOR WRITTEN CONSENT FROM NOVELL, COULD SUBJECT THE + * PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY. + *--- + * Modification to OpenLDAP source by Novell, Inc. + * June 2000 sfs Added control utilities + */ +/*--- + ldap_create_control + + Internal function to create an LDAP control from the encoded BerElement. + + requestOID (IN) The OID to use in creating the control. + + ber (IN) The encoded BerElement to use in creating the control. + + iscritical (IN) 0 - Indicates the control is not critical to the operation. + non-zero - The control is critical to the operation. + + ctrlp (OUT) Returns a pointer to the LDAPControl created. This control + SHOULD be freed by calling ldap_control_free() when done. +---*/ + +int +ldap_create_control( + LDAP_CONST char *requestOID, + BerElement *ber, + int iscritical, + LDAPControl **ctrlp ) +{ + LDAPControl *ctrl; + struct berval *bvalp; + + if ( requestOID == NULL || ctrlp == NULL ) { + return LDAP_PARAM_ERROR; + } + + ctrl = (LDAPControl *) LDAP_MALLOC( sizeof(LDAPControl) ); + if ( ctrl == NULL ) { + return LDAP_NO_MEMORY; + } + + if ( ber_flatten( ber, &bvalp ) == -1 ) { + LDAP_FREE( ctrl ); + return LDAP_NO_MEMORY; + } + + ctrl->ldctl_value = *bvalp; + ber_memfree( bvalp ); + + ctrl->ldctl_oid = LDAP_STRDUP( requestOID ); + ctrl->ldctl_iscritical = iscritical; + + if ( requestOID != NULL && ctrl->ldctl_oid == NULL ) { + ldap_control_free( ctrl ); + return LDAP_NO_MEMORY; + } + + *ctrlp = ctrl; + return LDAP_SUCCESS; +} + +/* + * check for critical client controls and bitch if present + * if we ever support critical controls, we'll have to + * find a means for maintaining per API call control + * information. + */ +int ldap_int_client_controls( LDAP *ld, LDAPControl **ctrls ) +{ + LDAPControl *const *c; + + assert( ld != NULL ); + + if( ctrls == NULL ) { + /* use default server controls */ + ctrls = ld->ld_cctrls; + } + + if( ctrls == NULL || *ctrls == NULL ) { + return LDAP_SUCCESS; + } + + for( c = ctrls ; *c != NULL; c++ ) { + if( (*c)->ldctl_iscritical ) { + ld->ld_errno = LDAP_NOT_SUPPORTED; + return ld->ld_errno; + } + } + + return LDAP_SUCCESS; +}