summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2018-03-26 16:01:13 +1300
committerStefan Metzmacher <metze@samba.org>2018-05-02 14:18:11 +0200
commit7f70fcd8baa82ae13ce1a29fc493643bbe29c6b7 (patch)
tree78012e8c69101fe077685599b515591176fc643a
parent3f15f1c63b994066e4ea9bc5e407c1d182511918 (diff)
downloadsamba-7f70fcd8baa82ae13ce1a29fc493643bbe29c6b7.tar.gz
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 <abartlet@samba.org> Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> (cherry picked from commit e481e4f30f4dc540f6f129b4f2faea48ee195673)
-rw-r--r--lib/ldb/ldb_tdb/ldb_tdb.c30
-rw-r--r--lib/ldb/ldb_tdb/ldb_tdb.h2
2 files changed, 32 insertions, 0 deletions
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;
};