X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libraries%2Flibldap%2Fcontrols.c;h=d61be4e43641df908ba0f9469385a437c1a90fef;hb=afa2cd1893875266c58677cc640514c1d9eef41f;hp=cab753e8810a00b3d20ccf2de46a485d66b16e5b;hpb=ed05ed8025184057098f18e63a86b5fc22f86138;p=openldap diff --git a/libraries/libldap/controls.c b/libraries/libldap/controls.c index cab753e881..d61be4e436 100644 --- a/libraries/libldap/controls.c +++ b/libraries/libldap/controls.c @@ -1,8 +1,12 @@ /* $OpenLDAP$ */ /* - * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved. + * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved. * COPYING RESTRICTIONS APPLY, see COPYRIGHT file */ +/* + * Portions Copyright (C) The Internet Society (1997) + * ASN.1 fragments are from RFC 2251; see RFC for full legal notices. + */ /* LDAPv3 Controls (RFC2251) * @@ -38,6 +42,7 @@ ldap_int_put_controls( LDAPControl *const *c; assert( ld != NULL ); + assert( LDAP_VALID(ld) ); assert( ber != NULL ); if( ctrls == NULL ) { @@ -94,14 +99,14 @@ 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; } @@ -125,14 +130,13 @@ int ldap_int_get_controls( } *ctrls = NULL; - len = ber_pvt_ber_remaining(ber); + len = ber_pvt_ber_remaining( ber ); if( len == 0) { /* no controls */ return LDAP_SUCCESS; } - if(( tag = ber_peek_tag( ber, &len )) != LDAP_TAG_CONTROLS ) { if( tag == LBER_ERROR ) { /* decoding error */ @@ -187,33 +191,27 @@ int ldap_int_get_controls( tag = ber_scanf( ber, "{a" /*}*/, &tctrl->ldctl_oid ); - if( tag != LBER_ERROR ) { - tag = ber_peek_tag( ber, &len ); + if( tag == LBER_ERROR ) { + *ctrls = NULL; + ldap_controls_free( tctrls ); + return LDAP_DECODING_ERROR; } + tag = ber_peek_tag( ber, &len ); + if( tag == LBER_BOOLEAN ) { ber_int_t crit; tag = ber_scanf( ber, "b", &crit ); tctrl->ldctl_iscritical = crit ? (char) 0 : (char) ~0; - } - - if( tag != LBER_ERROR ) { tag = ber_peek_tag( ber, &len ); } if( tag == LBER_OCTETSTRING ) { tag = ber_scanf( ber, "o", &tctrl->ldctl_value ); - } else { tctrl->ldctl_value.bv_val = NULL; } - if( tag == LBER_ERROR ) { - *ctrls = NULL; - ldap_controls_free( tctrls ); - return LDAP_DECODING_ERROR; - } - *ctrls = tctrls; } @@ -226,7 +224,9 @@ int ldap_int_get_controls( void ldap_control_free( LDAPControl *c ) { +#ifdef LDAP_MEMORY_DEBUG assert( c != NULL ); +#endif if ( c != NULL ) { if( c->ldctl_oid != NULL) { @@ -247,7 +247,9 @@ ldap_control_free( LDAPControl *c ) void ldap_controls_free( LDAPControl **controls ) { +#ifdef LDAP_MEMORY_DEBUG assert( controls != NULL ); +#endif if ( controls != NULL ) { int i; @@ -281,7 +283,7 @@ ldap_controls_dup( LDAPControl *const *controls ) return NULL; } - new = (LDAPControl **) LDAP_MALLOC( i * sizeof(LDAPControl *) ); + new = (LDAPControl **) LDAP_MALLOC( (i+1) * sizeof(LDAPControl *) ); if( new == NULL ) { /* memory allocation failure */ @@ -333,8 +335,9 @@ ldap_control_dup( const LDAPControl *c ) new->ldctl_oid = NULL; } - if( c->ldctl_value.bv_len > 0 ) { - new->ldctl_value.bv_val = (char *) LDAP_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) { @@ -344,10 +347,12 @@ ldap_control_dup( const LDAPControl *c ) 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; @@ -357,3 +362,113 @@ ldap_control_dup( const LDAPControl *c ) new->ldctl_iscritical = c->ldctl_iscritical; return new; } + +/* + * Copyright 1998-2003 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 + */ +/* Note: A verbatim copy of version 2.0.1 of the OpenLDAP Public License + * can be found in the file "build/LICENSE-2.0.1" in this distribution + * of OpenLDAP Software. + */ +/*--- + 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; + + assert( requestOID != NULL ); + assert( ber != NULL ); + assert( ctrlp != NULL ); + + ctrl = (LDAPControl *) LDAP_MALLOC( sizeof(LDAPControl) ); + if ( ctrl == NULL ) { + return LDAP_NO_MEMORY; + } + + if ( ber_flatten2( ber, &ctrl->ldctl_value, 1 ) == -1 ) { + LDAP_FREE( ctrl ); + return LDAP_NO_MEMORY; + } + + 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 ); + assert( LDAP_VALID(ld) ); + + 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; +}