mirror of
https://git.openldap.org/openldap/openldap.git
synced 2026-02-18 18:18:06 -05:00
Fixed back-ldbm/modify mutlivalued indexing bug
Fixed -llber seqorset buffer overrun bug (ITS#479)
This commit is contained in:
parent
1da7153528
commit
d697f1588c
7 changed files with 72 additions and 80 deletions
2
CHANGES
2
CHANGES
|
|
@ -11,6 +11,8 @@ Changes included in OpenLDAP 1.2.10 Release Engineering
|
|||
Fixed -lldap chasing of delete referrals (ITS#471)
|
||||
Fixed back-ldbm/bind invalid credentials vs no such object bug
|
||||
Fixed slapd str2entry uninitialized varible bug (ITS#482)
|
||||
Fixed back-ldbm/modify mutlivalued indexing bug
|
||||
Fixed -llber seqorset buffer overrun bug (ITS#479)
|
||||
Build Environment
|
||||
Do not list unsupported LDBM API option NDBM
|
||||
|
||||
|
|
|
|||
|
|
@ -190,6 +190,7 @@ LDAP_F BerElement *ber_alloc LDAP_P(( void ));
|
|||
LDAP_F BerElement *der_alloc LDAP_P(( void ));
|
||||
LDAP_F BerElement *ber_alloc_t LDAP_P(( int options ));
|
||||
LDAP_F BerElement *ber_dup LDAP_P(( BerElement *ber ));
|
||||
LDAP_F int ber_realloc LDAP_P(( BerElement *ber, unsigned long len ));
|
||||
LDAP_F void ber_dump LDAP_P(( BerElement *ber, int inout ));
|
||||
LDAP_F void ber_sos_dump LDAP_P(( Seqorset *sos ));
|
||||
LDAP_F unsigned long ber_get_next LDAP_P(( Sockbuf *sb, unsigned long *len,
|
||||
|
|
|
|||
|
|
@ -442,6 +442,20 @@ ber_put_seqorset( BerElement *ber )
|
|||
} else {
|
||||
unsigned long ntag;
|
||||
|
||||
if ( ber->ber_sos->sos_ptr > ber->ber_ptr ) {
|
||||
/* The sos_ptr exceeds the end of the BerElement
|
||||
* this can happen, for example, when the sos_ptr
|
||||
* is near the end and no data was written for the
|
||||
* 'V'. We must realloc the BerElement to ensure
|
||||
* we don't overwrite the buffer when writing
|
||||
* the tag and length fields.
|
||||
*/
|
||||
unsigned long ext = ber->ber_sos->sos_ptr - ber->ber_end;
|
||||
if( ber_realloc( ber, ext ) != 0 ) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* the tag */
|
||||
taglen = ber_calc_taglen( (*sos)->sos_tag );
|
||||
ntag = AC_HTONL( (*sos)->sos_tag );
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@
|
|||
|
||||
#include "lber.h"
|
||||
|
||||
static int ber_realloc LDAP_P(( BerElement *ber, unsigned long len ));
|
||||
static int ber_filbuf LDAP_P(( Sockbuf *sb, long len ));
|
||||
static long BerRead LDAP_P(( Sockbuf *sb, char *buf, long len ));
|
||||
#ifdef PCNFS
|
||||
|
|
@ -214,7 +213,7 @@ ber_write( BerElement *ber, char *buf, unsigned long len, int nosos )
|
|||
}
|
||||
}
|
||||
|
||||
static int
|
||||
int
|
||||
ber_realloc( BerElement *ber, unsigned long len )
|
||||
{
|
||||
unsigned long need, have, total;
|
||||
|
|
|
|||
|
|
@ -66,48 +66,6 @@ index_add_entry(
|
|||
return( 0 );
|
||||
}
|
||||
|
||||
int
|
||||
index_add_mods(
|
||||
Backend *be,
|
||||
LDAPMod *mods,
|
||||
ID id
|
||||
)
|
||||
{
|
||||
int rc;
|
||||
|
||||
for ( ; mods != NULL; mods = mods->mod_next ) {
|
||||
switch ( mods->mod_op & ~LDAP_MOD_BVALUES ) {
|
||||
case LDAP_MOD_REPLACE:
|
||||
/* XXX: Delete old index data==>problem when this
|
||||
* gets called we lost values already!
|
||||
*/
|
||||
case LDAP_MOD_ADD:
|
||||
rc = index_change_values( be,
|
||||
mods->mod_type,
|
||||
mods->mod_bvalues,
|
||||
id,
|
||||
__INDEX_ADD_OP);
|
||||
break;
|
||||
case LDAP_MOD_DELETE:
|
||||
rc = index_change_values( be,
|
||||
mods->mod_type,
|
||||
mods->mod_bvalues,
|
||||
id,
|
||||
__INDEX_DEL_OP );
|
||||
break;
|
||||
case LDAP_MOD_SOFTADD: /* SOFTADD means index was there */
|
||||
rc = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( rc != 0 ) {
|
||||
return( rc );
|
||||
}
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
ID_BLOCK *
|
||||
index_read(
|
||||
Backend *be,
|
||||
|
|
|
|||
|
|
@ -58,16 +58,13 @@ int ldbm_internal_modify(
|
|||
break;
|
||||
|
||||
case LDAP_MOD_SOFTADD:
|
||||
/* Avoid problems in index_add_mods()
|
||||
/*
|
||||
* We need to add index if necessary.
|
||||
*/
|
||||
mod->mod_op = LDAP_MOD_ADD;
|
||||
if ( (err = add_values( e, mod, op->o_ndn ))
|
||||
== LDAP_TYPE_OR_VALUE_EXISTS ) {
|
||||
|
||||
err = add_values( e, mod, op->o_ndn );
|
||||
if ( err == LDAP_TYPE_OR_VALUE_EXISTS ) {
|
||||
err = LDAP_SUCCESS;
|
||||
mod->mod_op = LDAP_MOD_SOFTADD;
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -111,42 +108,64 @@ int ldbm_internal_modify(
|
|||
ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
|
||||
|
||||
/* remove old indices */
|
||||
if( save_attrs != NULL ) {
|
||||
for ( mod = mods; mod != NULL; mod = mod->mod_next ) {
|
||||
if( ( mod->mod_op & ~LDAP_MOD_BVALUES )
|
||||
== LDAP_MOD_REPLACE )
|
||||
{
|
||||
/* Need to remove all values from indexes */
|
||||
a = attr_find( save_attrs, mod->mod_type );
|
||||
|
||||
if( a != NULL ) {
|
||||
(void) index_change_values( be,
|
||||
mod->mod_type,
|
||||
a->a_vals,
|
||||
e->e_id,
|
||||
__INDEX_DEL_OP);
|
||||
}
|
||||
for ( mod = mods; mod != NULL; mod = mod->mod_next ) {
|
||||
switch( mod->mod_op & ~LDAP_MOD_BVALUES ) {
|
||||
case LDAP_MOD_REPLACE:
|
||||
/* Need to remove all values from indexes */
|
||||
a = save_attrs
|
||||
? attr_find( save_attrs, mod->mod_type )
|
||||
: NULL;
|
||||
|
||||
if( a != NULL ) {
|
||||
(void) index_change_values( be,
|
||||
mod->mod_type,
|
||||
a->a_vals,
|
||||
e->e_id,
|
||||
__INDEX_DEL_OP);
|
||||
}
|
||||
break;
|
||||
|
||||
case LDAP_MOD_DELETE:
|
||||
(void) index_change_values( be,
|
||||
mod->mod_type,
|
||||
mod->mod_bvalues,
|
||||
e->e_id,
|
||||
__INDEX_DEL_OP);
|
||||
break;
|
||||
}
|
||||
attrs_free( save_attrs );
|
||||
}
|
||||
|
||||
/* modify indexes */
|
||||
if ( index_add_mods( be, mods, e->e_id ) != 0 ) {
|
||||
/* our indices are likely hosed */
|
||||
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
|
||||
NULL, NULL );
|
||||
return -1;
|
||||
}
|
||||
attrs_free( save_attrs );
|
||||
|
||||
/* check for abandon */
|
||||
ldap_pvt_thread_mutex_lock( &op->o_abandonmutex );
|
||||
if ( op->o_abandon ) {
|
||||
ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
|
||||
return -1;
|
||||
/* add new indices */
|
||||
for ( mod = mods; mod != NULL; mod = mod->mod_next ) {
|
||||
switch( mod->mod_op & ~LDAP_MOD_BVALUES ) {
|
||||
case LDAP_MOD_ADD:
|
||||
case LDAP_MOD_REPLACE:
|
||||
(void) index_change_values( be,
|
||||
mod->mod_type,
|
||||
mod->mod_bvalues,
|
||||
e->e_id,
|
||||
__INDEX_ADD_OP);
|
||||
|
||||
break;
|
||||
|
||||
case LDAP_MOD_DELETE:
|
||||
/* Need to add all remaining values */
|
||||
a = e->e_attrs
|
||||
? attr_find( e->e_attrs, mod->mod_type )
|
||||
: NULL;
|
||||
|
||||
if( a != NULL ) {
|
||||
(void) index_change_values( be,
|
||||
mod->mod_type,
|
||||
a->a_vals,
|
||||
e->e_id,
|
||||
__INDEX_ADD_OP);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,7 +110,6 @@ ID idl_nextid LDAP_P(( ID_BLOCK *idl, ID id ));
|
|||
*/
|
||||
|
||||
int index_add_entry LDAP_P(( Backend *be, Entry *e ));
|
||||
int index_add_mods LDAP_P(( Backend *be, LDAPMod *mods, ID id ));
|
||||
ID_BLOCK * index_read LDAP_P(( Backend *be, char *type, int indextype, char *val ));
|
||||
|
||||
/* To keep index files up-to-date we needed a index_delete_values() but since
|
||||
|
|
|
|||
Loading…
Reference in a new issue