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
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,
} 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 );
#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
}
}
-static int
+int
ber_realloc( BerElement *ber, unsigned long len )
{
unsigned long need, have, total;
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,
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;
}
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;
}
*/
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