From 0f832b824b9a9a68b78efa508923c5f78654b917 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 26 Mar 2018 16:01:13 +1300 Subject: [PATCH] ldb_tdb: Ensure we can not commit an index that is corrupt due to partial re-index The re-index traverse can abort part-way though and we need to ensure that the transaction is never committed as that will leave an un-useable db. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13335 Signed-off-by: Andrew Bartlett Reviewed-by: Gary Lockyer (cherry picked from commit e481e4f30f4dc540f6f129b4f2faea48ee195673) --- lib/ldb/ldb_tdb/ldb_tdb.c | 30 ++++++++++++++++++++++++++++++ lib/ldb/ldb_tdb/ldb_tdb.h | 2 ++ 2 files changed, 32 insertions(+) diff --git a/lib/ldb/ldb_tdb/ldb_tdb.c b/lib/ldb/ldb_tdb/ldb_tdb.c index 16e4b8ea26e..a530a454b29 100644 --- a/lib/ldb/ldb_tdb/ldb_tdb.c +++ b/lib/ldb/ldb_tdb/ldb_tdb.c @@ -410,6 +410,10 @@ static int ltdb_modified(struct ldb_module *module, struct ldb_dn *dn) ret = ltdb_cache_reload(module); } + if (ret != LDB_SUCCESS) { + ltdb->reindex_failed = true; + } + return ret; } @@ -1404,9 +1408,17 @@ static int ltdb_start_trans(struct ldb_module *module) ltdb_index_transaction_start(module); + ltdb->reindex_failed = false; + return LDB_SUCCESS; } +/* + * Forward declaration to allow prepare_commit to in fact abort the + * transaction + */ +static int ltdb_del_trans(struct ldb_module *module); + static int ltdb_prepare_commit(struct ldb_module *module) { int ret; @@ -1417,6 +1429,24 @@ static int ltdb_prepare_commit(struct ldb_module *module) return LDB_SUCCESS; } + /* + * Check if the last re-index failed. + * + * This can happen if for example a duplicate value was marked + * unique. We must not write a partial re-index into the DB. + */ + if (ltdb->reindex_failed) { + /* + * We must instead abort the transaction so we get the + * old values and old index back + */ + ltdb_del_trans(module); + ldb_set_errstring(ldb_module_get_ctx(module), + "Failure during re-index, so " + "transaction must be aborted."); + return LDB_ERR_OPERATIONS_ERROR; + } + ret = ltdb_index_transaction_commit(module); if (ret != LDB_SUCCESS) { tdb_transaction_cancel(ltdb->tdb); diff --git a/lib/ldb/ldb_tdb/ldb_tdb.h b/lib/ldb/ldb_tdb/ldb_tdb.h index 7e182495928..9591ee59bf1 100644 --- a/lib/ldb/ldb_tdb/ldb_tdb.h +++ b/lib/ldb/ldb_tdb/ldb_tdb.h @@ -37,6 +37,8 @@ struct ltdb_private { bool read_only; + bool reindex_failed; + const struct ldb_schema_syntax *GUID_index_syntax; }; -- 2.34.1