Commit d697f158 authored by Kurt Zeilenga's avatar Kurt Zeilenga
Browse files

Fixed back-ldbm/modify mutlivalued indexing bug

Fixed -llber seqorset buffer overrun bug (ITS#479)
parent 1da71535
......@@ -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
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment