]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
Fixed back-ldbm/modify mutlivalued indexing bug
authorKurt Zeilenga <kurt@openldap.org>
Fri, 17 Mar 2000 19:41:22 +0000 (19:41 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Fri, 17 Mar 2000 19:41:22 +0000 (19:41 +0000)
Fixed -llber seqorset buffer overrun bug (ITS#479)

CHANGES
include/lber.h
libraries/liblber/encode.c
libraries/liblber/io.c
servers/slapd/back-ldbm/index.c
servers/slapd/back-ldbm/modify.c
servers/slapd/back-ldbm/proto-back-ldbm.h

diff --git a/CHANGES b/CHANGES
index 8c4b78bd1c5ee89dc76d1cb6040e0406e2db2e2a..9a7cbc3d6f048b0b193fbfc7489fbe439be3c03c 100644 (file)
--- 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
 
index f4816426f0b96be80f33eb9fba0437651ded55b0..9bb98cd4691b07bab329cdb4e53417372a4ae78f 100644 (file)
@@ -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,
index 24d8bc3c7ddad3ec67a482d82ab739f6ecb34ad1..b73ae6de6176e186f8d1968959df453dde4df440 100644 (file)
@@ -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 );
index 105046d28509b52b7d7edfaac5f80bc8fea33881..a60983bef9b2bc338bd24081ae9b9abd304fb3da 100644 (file)
@@ -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;
index f0e892726d673ba208cf4ee4c146014856a83ec3..3d65d99cd1482edf8d2e787b8fe647cdc164f5f2 100644 (file)
@@ -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,
index 2f3191308025a15786607387337049a8e23058e8..daf4056384694b117d4bf4f8bfd2c37951a80fea 100644 (file)
@@ -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;
 }
index 0dd972fc4a2a0c6ee91539df13605d04d8811195..b16819043168ac226f101dbfb963f5002d2300de 100644 (file)
@@ -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