From: Kurt Zeilenga Date: Fri, 17 Mar 2000 19:41:22 +0000 (+0000) Subject: Fixed back-ldbm/modify mutlivalued indexing bug X-Git-Tag: OPENLDAP_REL_ENG_1_2_10~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d697f1588caf34878fe3024a8cbf4befd786e742;p=thirdparty%2Fopenldap.git Fixed back-ldbm/modify mutlivalued indexing bug Fixed -llber seqorset buffer overrun bug (ITS#479) --- diff --git a/CHANGES b/CHANGES index 8c4b78bd1c..9a7cbc3d6f 100644 --- a/CHANGES +++ b/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 diff --git a/include/lber.h b/include/lber.h index f4816426f0..9bb98cd469 100644 --- a/include/lber.h +++ b/include/lber.h @@ -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, diff --git a/libraries/liblber/encode.c b/libraries/liblber/encode.c index 24d8bc3c7d..b73ae6de61 100644 --- a/libraries/liblber/encode.c +++ b/libraries/liblber/encode.c @@ -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 ); diff --git a/libraries/liblber/io.c b/libraries/liblber/io.c index 105046d285..a60983bef9 100644 --- a/libraries/liblber/io.c +++ b/libraries/liblber/io.c @@ -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; diff --git a/servers/slapd/back-ldbm/index.c b/servers/slapd/back-ldbm/index.c index f0e892726d..3d65d99cd1 100644 --- a/servers/slapd/back-ldbm/index.c +++ b/servers/slapd/back-ldbm/index.c @@ -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, diff --git a/servers/slapd/back-ldbm/modify.c b/servers/slapd/back-ldbm/modify.c index 2f31913080..daf4056384 100644 --- a/servers/slapd/back-ldbm/modify.c +++ b/servers/slapd/back-ldbm/modify.c @@ -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; } diff --git a/servers/slapd/back-ldbm/proto-back-ldbm.h b/servers/slapd/back-ldbm/proto-back-ldbm.h index 0dd972fc4a..b168190431 100644 --- a/servers/slapd/back-ldbm/proto-back-ldbm.h +++ b/servers/slapd/back-ldbm/proto-back-ldbm.h @@ -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