mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-20 07:17:32 +09:00
Issue #1258 - Part 2: Use binoc-central version of ldap
This commit is contained in:
parent
e400f4130a
commit
deb86ab699
94 changed files with 44 additions and 18 deletions
559
ldap/c-sdk/libldap/control.c
Normal file
559
ldap/c-sdk/libldap/control.c
Normal file
|
|
@ -0,0 +1,559 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code, released
|
||||
* March 31, 1998.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998-1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/* control.c - routines to handle ldapv3 controls */
|
||||
|
||||
#include "ldap-int.h"
|
||||
|
||||
static LDAPControl *ldap_control_dup( LDAPControl *ctrl );
|
||||
static int ldap_control_copy_contents( LDAPControl *ctrl_dst,
|
||||
LDAPControl *ctrl_src );
|
||||
|
||||
/*
|
||||
* Append a list of LDAPv3 controls to ber. If ctrls is NULL, use default
|
||||
* set of controls from ld.
|
||||
* Return an LDAP error code (LDAP_SUCCESS if all goes well).
|
||||
* If closeseq is non-zero, we do an extra ber_put_seq() as well.
|
||||
*/
|
||||
int
|
||||
nsldapi_put_controls( LDAP *ld, LDAPControl **ctrls, int closeseq,
|
||||
BerElement *ber )
|
||||
{
|
||||
LDAPControl *c;
|
||||
int rc, i;
|
||||
|
||||
rc = LDAP_ENCODING_ERROR; /* the most popular error */
|
||||
|
||||
/* if no controls were passed in, use global list from LDAP * */
|
||||
LDAP_MUTEX_LOCK( ld, LDAP_CTRL_LOCK );
|
||||
if ( ctrls == NULL ) {
|
||||
ctrls = ld->ld_servercontrols;
|
||||
}
|
||||
|
||||
/* if there are no controls then we are done */
|
||||
if ( ctrls == NULL || ctrls[ 0 ] == NULL ) {
|
||||
goto clean_exit;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we're using LDAPv2 or earlier we can't send any controls, so
|
||||
* we just ignore them unless one is marked critical, in which case
|
||||
* we return an error.
|
||||
*/
|
||||
if ( NSLDAPI_LDAP_VERSION( ld ) < LDAP_VERSION3 ) {
|
||||
for ( i = 0; ctrls != NULL && ctrls[i] != NULL; i++ ) {
|
||||
if ( ctrls[i]->ldctl_iscritical ) {
|
||||
rc = LDAP_NOT_SUPPORTED;
|
||||
goto error_exit;
|
||||
}
|
||||
}
|
||||
goto clean_exit;
|
||||
}
|
||||
|
||||
/*
|
||||
* encode the controls as a Sequence of Sequence
|
||||
*/
|
||||
if ( ber_printf( ber, "t{", LDAP_TAG_CONTROLS ) == -1 ) {
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
for ( i = 0; ctrls[i] != NULL; i++ ) {
|
||||
c = ctrls[i];
|
||||
|
||||
if ( ber_printf( ber, "{s", c->ldctl_oid ) == -1 ) {
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
/* criticality is "BOOLEAN DEFAULT FALSE" */
|
||||
/* therefore, it should only be encoded if it exists AND is TRUE */
|
||||
if ( c->ldctl_iscritical ) {
|
||||
if ( ber_printf( ber, "b", (int)c->ldctl_iscritical )
|
||||
== -1 ) {
|
||||
goto error_exit;
|
||||
}
|
||||
}
|
||||
|
||||
if ( c->ldctl_value.bv_val != NULL ) {
|
||||
if ( ber_printf( ber, "o", c->ldctl_value.bv_val,
|
||||
c->ldctl_value.bv_len )
|
||||
== -1 ) {
|
||||
goto error_exit;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ber_put_seq( ber ) == -1 ) {
|
||||
goto error_exit;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ber_put_seq( ber ) == -1 ) {
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
clean_exit:
|
||||
LDAP_MUTEX_UNLOCK( ld, LDAP_CTRL_LOCK );
|
||||
if ( closeseq && ber_put_seq( ber ) == -1 ) {
|
||||
goto error_exit;
|
||||
}
|
||||
return( LDAP_SUCCESS );
|
||||
|
||||
error_exit:
|
||||
LDAP_MUTEX_UNLOCK( ld, LDAP_CTRL_LOCK );
|
||||
LDAP_SET_LDERRNO( ld, rc, NULL, NULL );
|
||||
return( rc );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Pull controls out of "ber" (if any present) and return them in "controlsp."
|
||||
* Returns an LDAP error code.
|
||||
*/
|
||||
int
|
||||
nsldapi_get_controls( BerElement *ber, LDAPControl ***controlsp )
|
||||
{
|
||||
LDAPControl *newctrl;
|
||||
ber_tag_t tag;
|
||||
ber_len_t len;
|
||||
int rc, maxcontrols, curcontrols;
|
||||
char *last;
|
||||
|
||||
/*
|
||||
* Each LDAPMessage can have a set of controls appended
|
||||
* to it. Controls are used to extend the functionality
|
||||
* of an LDAP operation (e.g., add an attribute size limit
|
||||
* to the search operation). These controls look like this:
|
||||
*
|
||||
* Controls ::= SEQUENCE OF Control
|
||||
*
|
||||
* Control ::= SEQUENCE {
|
||||
* controlType LDAPOID,
|
||||
* criticality BOOLEAN DEFAULT FALSE,
|
||||
* controlValue OCTET STRING
|
||||
* }
|
||||
*/
|
||||
LDAPDebug( LDAP_DEBUG_TRACE, "=> nsldapi_get_controls\n", 0, 0, 0 );
|
||||
|
||||
*controlsp = NULL;
|
||||
|
||||
/*
|
||||
* check to see if controls were included
|
||||
*/
|
||||
if ( ber_get_option( ber, LBER_OPT_REMAINING_BYTES, &len ) != 0 ) {
|
||||
return( LDAP_DECODING_ERROR ); /* unexpected error */
|
||||
}
|
||||
if ( len == 0 ) {
|
||||
LDAPDebug( LDAP_DEBUG_TRACE,
|
||||
"<= nsldapi_get_controls no controls\n", 0, 0, 0 );
|
||||
return( LDAP_SUCCESS ); /* no controls */
|
||||
}
|
||||
if (( tag = ber_peek_tag( ber, &len )) != LDAP_TAG_CONTROLS ) {
|
||||
if ( tag == LBER_ERROR ) {
|
||||
LDAPDebug( LDAP_DEBUG_TRACE,
|
||||
"<= nsldapi_get_controls LDAP_PROTOCOL_ERROR\n",
|
||||
0, 0, 0 );
|
||||
return( LDAP_DECODING_ERROR ); /* decoding error */
|
||||
}
|
||||
/*
|
||||
* We found something other than controls. This should never
|
||||
* happen in LDAPv3, but we don't treat this is a hard error --
|
||||
* we just ignore the extra stuff.
|
||||
*/
|
||||
LDAPDebug( LDAP_DEBUG_TRACE,
|
||||
"<= nsldapi_get_controls ignoring unrecognized data in message (tag 0x%x)\n",
|
||||
tag, 0, 0 );
|
||||
return( LDAP_SUCCESS );
|
||||
}
|
||||
|
||||
maxcontrols = curcontrols = 0;
|
||||
for ( tag = ber_first_element( ber, &len, &last );
|
||||
tag != LBER_ERROR && tag != LBER_END_OF_SEQORSET;
|
||||
tag = ber_next_element( ber, &len, last ) ) {
|
||||
if ( curcontrols >= maxcontrols - 1 ) {
|
||||
#define CONTROL_GRABSIZE 5
|
||||
maxcontrols += CONTROL_GRABSIZE;
|
||||
*controlsp = (struct ldapcontrol **)NSLDAPI_REALLOC(
|
||||
(char *)*controlsp, maxcontrols *
|
||||
sizeof(struct ldapcontrol *) );
|
||||
if ( *controlsp == NULL ) {
|
||||
rc = LDAP_NO_MEMORY;
|
||||
goto free_and_return;
|
||||
}
|
||||
}
|
||||
if (( newctrl = (struct ldapcontrol *)NSLDAPI_CALLOC( 1,
|
||||
sizeof(LDAPControl))) == NULL ) {
|
||||
rc = LDAP_NO_MEMORY;
|
||||
goto free_and_return;
|
||||
}
|
||||
|
||||
(*controlsp)[curcontrols++] = newctrl;
|
||||
(*controlsp)[curcontrols] = NULL;
|
||||
|
||||
if ( ber_scanf( ber, "{a", &newctrl->ldctl_oid )
|
||||
== LBER_ERROR ) {
|
||||
rc = LDAP_DECODING_ERROR;
|
||||
goto free_and_return;
|
||||
}
|
||||
|
||||
/* the criticality is optional */
|
||||
if ( ber_peek_tag( ber, &len ) == LBER_BOOLEAN ) {
|
||||
int aint;
|
||||
|
||||
if ( ber_scanf( ber, "b", &aint ) == LBER_ERROR ) {
|
||||
rc = LDAP_DECODING_ERROR;
|
||||
goto free_and_return;
|
||||
}
|
||||
newctrl->ldctl_iscritical = (char)aint; /* XXX lossy cast */
|
||||
} else {
|
||||
/* absent is synonomous with FALSE */
|
||||
newctrl->ldctl_iscritical = 0;
|
||||
}
|
||||
|
||||
/* the control value is optional */
|
||||
if ( ber_peek_tag( ber, &len ) == LBER_OCTETSTRING ) {
|
||||
if ( ber_scanf( ber, "o", &newctrl->ldctl_value )
|
||||
== LBER_ERROR ) {
|
||||
rc = LDAP_DECODING_ERROR;
|
||||
goto free_and_return;
|
||||
}
|
||||
} else {
|
||||
(newctrl->ldctl_value).bv_val = NULL;
|
||||
(newctrl->ldctl_value).bv_len = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( tag == LBER_ERROR ) {
|
||||
rc = LDAP_DECODING_ERROR;
|
||||
goto free_and_return;
|
||||
}
|
||||
|
||||
LDAPDebug( LDAP_DEBUG_TRACE,
|
||||
"<= nsldapi_get_controls found %d controls\n", curcontrols, 0, 0 );
|
||||
return( LDAP_SUCCESS );
|
||||
|
||||
free_and_return:;
|
||||
ldap_controls_free( *controlsp );
|
||||
*controlsp = NULL;
|
||||
LDAPDebug( LDAP_DEBUG_TRACE,
|
||||
"<= nsldapi_get_controls error 0x%x\n", rc, 0, 0 );
|
||||
return( rc );
|
||||
}
|
||||
|
||||
/*
|
||||
* Skips forward in a ber to find a control tag, then calls on
|
||||
* nsldapi_get_controls() to parse them into an LDAPControl list.
|
||||
* Returns an LDAP error code.
|
||||
*/
|
||||
int
|
||||
nsldapi_find_controls( BerElement *ber, LDAPControl ***controlsp )
|
||||
{
|
||||
ber_tag_t tag;
|
||||
ber_len_t len;
|
||||
|
||||
if ( ber == NULLBER ) {
|
||||
return( LDAP_DECODING_ERROR );
|
||||
}
|
||||
|
||||
tag = ber_peek_tag( ber, &len );
|
||||
|
||||
while( tag != LDAP_TAG_CONTROLS && tag != LBER_DEFAULT ) {
|
||||
tag = ber_skip_tag( ber, &len );
|
||||
/* Skip ahead to the next sequence */
|
||||
ber->ber_ptr += len;
|
||||
tag = ber_peek_tag( ber, &len );
|
||||
}
|
||||
|
||||
return( nsldapi_get_controls( ber, controlsp ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LDAP_CALL
|
||||
ldap_control_free( LDAPControl *ctrl )
|
||||
{
|
||||
if ( ctrl != NULL ) {
|
||||
if ( ctrl->ldctl_oid != NULL ) {
|
||||
NSLDAPI_FREE( ctrl->ldctl_oid );
|
||||
}
|
||||
if ( ctrl->ldctl_value.bv_val != NULL ) {
|
||||
NSLDAPI_FREE( ctrl->ldctl_value.bv_val );
|
||||
}
|
||||
NSLDAPI_FREE( (char *)ctrl );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LDAP_CALL
|
||||
ldap_controls_free( LDAPControl **ctrls )
|
||||
{
|
||||
int i;
|
||||
|
||||
if ( ctrls != NULL ) {
|
||||
for ( i = 0; ctrls[i] != NULL; i++ ) {
|
||||
ldap_control_free( ctrls[i] );
|
||||
}
|
||||
NSLDAPI_FREE( (char *)ctrls );
|
||||
}
|
||||
}
|
||||
|
||||
LDAPControl *
|
||||
LDAP_CALL
|
||||
ldap_find_control( const char *oid, LDAPControl **ctrls )
|
||||
{
|
||||
int i, foundControl;
|
||||
LDAPControl *Ctrlp = NULL;
|
||||
|
||||
/* find the control in the list of controls if it exists */
|
||||
if ( ctrls == NULL ) {
|
||||
return ( NULL );
|
||||
}
|
||||
foundControl = 0;
|
||||
for ( i = 0; (( ctrls[i] != NULL ) && ( !foundControl )); i++ ) {
|
||||
foundControl = !strcmp( ctrls[i]->ldctl_oid, oid );
|
||||
}
|
||||
if ( !foundControl ) {
|
||||
return ( NULL );
|
||||
} else {
|
||||
/* let local var point to the control */
|
||||
Ctrlp = ctrls[i-1];
|
||||
}
|
||||
|
||||
return( Ctrlp );
|
||||
}
|
||||
|
||||
#if 0
|
||||
LDAPControl **
|
||||
LDAP_CALL
|
||||
ldap_control_append( LDAPControl **ctrl_src, LDAPControl *ctrl )
|
||||
{
|
||||
int nctrls = 0;
|
||||
LDAPControl **ctrlp;
|
||||
int i;
|
||||
|
||||
if ( NULL == ctrl )
|
||||
return ( NULL );
|
||||
|
||||
/* Count the existing controls */
|
||||
if ( NULL != ctrl_src ) {
|
||||
while( NULL != ctrl_src[nctrls] ) {
|
||||
nctrls++;
|
||||
}
|
||||
}
|
||||
|
||||
/* allocate the new control structure */
|
||||
if ( ( ctrlp = (LDAPControl **)NSLDAPI_MALLOC( sizeof(LDAPControl *)
|
||||
* (nctrls + 2) ) ) == NULL ) {
|
||||
return( NULL );
|
||||
}
|
||||
memset( ctrlp, 0, sizeof(*ctrlp) * (nctrls + 2) );
|
||||
|
||||
for( i = 0; i < (nctrls + 1); i++ ) {
|
||||
if ( i < nctrls ) {
|
||||
ctrlp[i] = ldap_control_dup( ctrl_src[i] );
|
||||
} else {
|
||||
ctrlp[i] = ldap_control_dup( ctrl );
|
||||
}
|
||||
if ( NULL == ctrlp[i] ) {
|
||||
ldap_controls_free( ctrlp );
|
||||
return( NULL );
|
||||
}
|
||||
}
|
||||
return ctrlp;
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
|
||||
/*
|
||||
* Replace *ldctrls with a copy of newctrls.
|
||||
* returns 0 if successful.
|
||||
* return -1 if not and set error code inside LDAP *ld.
|
||||
*/
|
||||
int
|
||||
nsldapi_dup_controls( LDAP *ld, LDAPControl ***ldctrls, LDAPControl **newctrls )
|
||||
{
|
||||
int count;
|
||||
|
||||
if ( *ldctrls != NULL ) {
|
||||
ldap_controls_free( *ldctrls );
|
||||
}
|
||||
|
||||
if ( newctrls == NULL || newctrls[0] == NULL ) {
|
||||
*ldctrls = NULL;
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
for ( count = 0; newctrls[ count ] != NULL; ++count ) {
|
||||
;
|
||||
}
|
||||
|
||||
if (( *ldctrls = (LDAPControl **)NSLDAPI_MALLOC(( count + 1 ) *
|
||||
sizeof( LDAPControl *))) == NULL ) {
|
||||
LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
|
||||
return( -1 );
|
||||
}
|
||||
(*ldctrls)[ count ] = NULL;
|
||||
|
||||
for ( count = 0; newctrls[ count ] != NULL; ++count ) {
|
||||
if (( (*ldctrls)[ count ] =
|
||||
ldap_control_dup( newctrls[ count ] )) == NULL ) {
|
||||
ldap_controls_free( *ldctrls );
|
||||
*ldctrls = NULL;
|
||||
LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
|
||||
return( -1 );
|
||||
}
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* return a malloc'd copy of "ctrl" (NULL if memory allocation fails)
|
||||
*/
|
||||
static LDAPControl *
|
||||
/* LDAP_CALL */ /* keep this routine internal for now */
|
||||
ldap_control_dup( LDAPControl *ctrl )
|
||||
{
|
||||
LDAPControl *rctrl;
|
||||
|
||||
if (( rctrl = (LDAPControl *)NSLDAPI_MALLOC( sizeof( LDAPControl )))
|
||||
== NULL ) {
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
if ( ldap_control_copy_contents( rctrl, ctrl ) != LDAP_SUCCESS ) {
|
||||
NSLDAPI_FREE( rctrl );
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
return( rctrl );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* duplicate the contents of "ctrl_src" and place in "ctrl_dst"
|
||||
*/
|
||||
static int
|
||||
/* LDAP_CALL */ /* keep this routine internal for now */
|
||||
ldap_control_copy_contents( LDAPControl *ctrl_dst, LDAPControl *ctrl_src )
|
||||
{
|
||||
size_t len;
|
||||
|
||||
if ( NULL == ctrl_dst || NULL == ctrl_src ) {
|
||||
return( LDAP_PARAM_ERROR );
|
||||
}
|
||||
|
||||
ctrl_dst->ldctl_iscritical = ctrl_src->ldctl_iscritical;
|
||||
|
||||
/* fill in the fields of this new control */
|
||||
if (( ctrl_dst->ldctl_oid = nsldapi_strdup( ctrl_src->ldctl_oid ))
|
||||
== NULL ) {
|
||||
return( LDAP_NO_MEMORY );
|
||||
}
|
||||
|
||||
len = (size_t)(ctrl_src->ldctl_value).bv_len;
|
||||
if ( ctrl_src->ldctl_value.bv_val == NULL || len <= 0 ) {
|
||||
ctrl_dst->ldctl_value.bv_len = 0;
|
||||
ctrl_dst->ldctl_value.bv_val = NULL;
|
||||
} else {
|
||||
ctrl_dst->ldctl_value.bv_len = len;
|
||||
if (( ctrl_dst->ldctl_value.bv_val = NSLDAPI_MALLOC( len ))
|
||||
== NULL ) {
|
||||
NSLDAPI_FREE( ctrl_dst->ldctl_oid );
|
||||
return( LDAP_NO_MEMORY );
|
||||
}
|
||||
SAFEMEMCPY( ctrl_dst->ldctl_value.bv_val,
|
||||
ctrl_src->ldctl_value.bv_val, len );
|
||||
}
|
||||
|
||||
return ( LDAP_SUCCESS );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* build an allocated LDAPv3 control. Returns an LDAP error code.
|
||||
*/
|
||||
int
|
||||
nsldapi_build_control( char *oid, BerElement *ber, int freeber, char iscritical,
|
||||
LDAPControl **ctrlp )
|
||||
{
|
||||
int rc;
|
||||
struct berval *bvp;
|
||||
|
||||
if ( ber == NULL ) {
|
||||
bvp = NULL;
|
||||
} else {
|
||||
/* allocate struct berval with contents of the BER encoding */
|
||||
rc = ber_flatten( ber, &bvp );
|
||||
if ( freeber ) {
|
||||
ber_free( ber, 1 );
|
||||
}
|
||||
if ( rc == -1 ) {
|
||||
return( LDAP_NO_MEMORY );
|
||||
}
|
||||
}
|
||||
|
||||
/* allocate the new control structure */
|
||||
if (( *ctrlp = (LDAPControl *)NSLDAPI_MALLOC( sizeof(LDAPControl)))
|
||||
== NULL ) {
|
||||
if ( bvp != NULL ) {
|
||||
ber_bvfree( bvp );
|
||||
}
|
||||
return( LDAP_NO_MEMORY );
|
||||
}
|
||||
|
||||
/* fill in the fields of this new control */
|
||||
(*ctrlp)->ldctl_iscritical = iscritical;
|
||||
if (( (*ctrlp)->ldctl_oid = nsldapi_strdup( oid )) == NULL ) {
|
||||
NSLDAPI_FREE( *ctrlp );
|
||||
if ( bvp != NULL ) {
|
||||
ber_bvfree( bvp );
|
||||
}
|
||||
return( LDAP_NO_MEMORY );
|
||||
}
|
||||
|
||||
if ( bvp == NULL ) {
|
||||
(*ctrlp)->ldctl_value.bv_len = 0;
|
||||
(*ctrlp)->ldctl_value.bv_val = NULL;
|
||||
} else {
|
||||
(*ctrlp)->ldctl_value = *bvp; /* struct copy */
|
||||
NSLDAPI_FREE( bvp ); /* free container, not contents! */
|
||||
}
|
||||
|
||||
return( LDAP_SUCCESS );
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue