ITS#9091 drop attr mappings added in an aborted txn

If a txn is aborted in id2entry_put, attribute index mappings
added during that txn must also be dropped from memory.
This commit is contained in:
Howard Chu 2019-10-14 18:34:07 +01:00
parent 4bc333c5e7
commit 379f138098
3 changed files with 28 additions and 7 deletions

View File

@ -811,3 +811,14 @@ int mdb_ad_get( struct mdb_info *mdb, MDB_txn *txn, AttributeDescription *ad )
return rc;
}
void mdb_ad_unwind( struct mdb_info *mdb, int prev_ads )
{
int i;
for (i=mdb->mi_numads; i>prev_ads; i--) {
mdb->mi_adxs[mdb->mi_ads[i]->ad_index] = 0;
mdb->mi_ads[i] = NULL;
}
mdb->mi_numads = i;
}

View File

@ -272,7 +272,7 @@ static int mdb_id2entry_put(
struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
Ecount ec;
MDB_val key, data;
int rc, adding = flag;
int rc, adding = flag, prev_ads = mdb->mi_numads;
/* We only store rdns, and they go in the dn2id database. */
@ -280,16 +280,20 @@ static int mdb_id2entry_put(
key.mv_size = sizeof(ID);
rc = mdb_entry_partsize( mdb, txn, e, &ec );
if (rc)
return LDAP_OTHER;
if (rc) {
rc = LDAP_OTHER;
goto fail;
}
flag |= MDB_RESERVE;
if (e->e_id < mdb->mi_nextid)
flag &= ~MDB_APPEND;
if (mdb->mi_maxentrysize && ec.len > mdb->mi_maxentrysize)
return LDAP_ADMINLIMIT_EXCEEDED;
if (mdb->mi_maxentrysize && ec.len > mdb->mi_maxentrysize) {
rc = LDAP_ADMINLIMIT_EXCEEDED;
goto fail;
}
again:
data.mv_size = ec.dlen;
@ -300,7 +304,7 @@ again:
if (rc == MDB_SUCCESS) {
rc = mdb_entry_encode( op, e, &data, &ec );
if( rc != LDAP_SUCCESS )
return rc;
goto fail;
/* Handle adds of large multi-valued attrs here.
* Modifies handle them directly.
*/
@ -323,7 +327,8 @@ again:
"mdb_id2entry_put: mdb_mval_put failed: %s(%d) \"%s\"\n",
mdb_strerror(rc), rc,
e->e_nname.bv_val );
return LDAP_OTHER;
rc = LDAP_OTHER;
goto fail;
}
}
}
@ -340,6 +345,10 @@ again:
if ( rc != MDB_KEYEXIST )
rc = LDAP_OTHER;
}
fail:
if (rc) {
mdb_ad_unwind( mdb, prev_ads );
}
return rc;
}

View File

@ -57,6 +57,7 @@ void mdb_attr_info_free( AttrInfo *ai );
int mdb_ad_read( struct mdb_info *mdb, MDB_txn *txn );
int mdb_ad_get( struct mdb_info *mdb, MDB_txn *txn, AttributeDescription *ad );
void mdb_ad_unwind( struct mdb_info *mdb, int prev_ads );
/*
* config.c