From cb5da7a5c610875297a90be7f0b8bcde620990f1 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 19 May 2018 07:10:15 +1200 Subject: [PATCH] ldb: Reject a possible future ldb_mdb with the index in a sub-database This ensures we do not corrupt such an index by making changes to the main database without knowing that the index values are now in a sub-database. Signed-off-by: Andrew Bartlett Reviewed-by: Garming Sam --- lib/ldb/ldb_tdb/ldb_cache.c | 16 +++++++++++++++- lib/ldb/ldb_tdb/ldb_tdb.h | 9 +++++++++ lib/ldb/tests/python/index.py | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 1 deletion(-) diff --git a/lib/ldb/ldb_tdb/ldb_cache.c b/lib/ldb/ldb_tdb/ldb_cache.c index a9d2113e707..1856fb13877 100644 --- a/lib/ldb/ldb_tdb/ldb_cache.c +++ b/lib/ldb/ldb_tdb/ldb_cache.c @@ -238,7 +238,7 @@ static int ltdb_index_load(struct ldb_module *module, { struct ldb_context *ldb = ldb_module_get_ctx(module); struct ldb_dn *indexlist_dn; - int r; + int r, lmdb_subdb_version; if (ldb->schema.index_handler_override) { /* @@ -291,6 +291,20 @@ static int ltdb_index_load(struct ldb_module *module, = ldb_msg_find_attr_as_string(ltdb->cache->indexlist, LTDB_IDX_DN_GUID, NULL); + lmdb_subdb_version + = ldb_msg_find_attr_as_int(ltdb->cache->indexlist, + LTDB_IDX_LMDB_SUBDB, 0); + + if (lmdb_subdb_version != 0) { + ldb_set_errstring(ldb, + "FATAL: This ldb_mdb database has " + "been written in a new verson of LDB " + "using a sub-database index that " + "is not understood by ldb " + LDB_VERSION); + return -1; + } + return 0; } diff --git a/lib/ldb/ldb_tdb/ldb_tdb.h b/lib/ldb/ldb_tdb/ldb_tdb.h index dfc0d5e3299..46af8a1d836 100644 --- a/lib/ldb/ldb_tdb/ldb_tdb.h +++ b/lib/ldb/ldb_tdb/ldb_tdb.h @@ -120,6 +120,15 @@ struct ltdb_reindex_context { #define LTDB_IDXDN "@IDXDN" #define LTDB_IDXGUID "@IDXGUID" #define LTDB_IDX_DN_GUID "@IDX_DN_GUID" + +/* + * This will be used to indicate when a new, yet to be developed + * sub-database version of the indicies are in use, to ensure we do + * not load future databases unintentionally. + */ + +#define LTDB_IDX_LMDB_SUBDB "@IDX_LMDB_SUBDB" + #define LTDB_BASEINFO "@BASEINFO" #define LTDB_OPTIONS "@OPTIONS" #define LTDB_ATTRIBUTES "@ATTRIBUTES" diff --git a/lib/ldb/tests/python/index.py b/lib/ldb/tests/python/index.py index 3379fb9374f..2613a4dbedd 100755 --- a/lib/ldb/tests/python/index.py +++ b/lib/ldb/tests/python/index.py @@ -1291,6 +1291,38 @@ class MaxIndexKeyLengthTestsLmdb(MaxIndexKeyLengthTests): def tearDown(self): super(MaxIndexKeyLengthTestsLmdb, self).tearDown() + +# Run the index truncation tests against an lmdb backend +class RejectSubDBIndex(LdbBaseTest): + + def setUp(self): + self.prefix = MDB_PREFIX + super(RejectSubDBIndex, self).setUp() + self.testdir = tempdir() + self.filename = os.path.join(self.testdir, + "reject_subidx_test.ldb") + self.l = ldb.Ldb(self.url(), + options=[ + "modules:rdn_name"]) + + def tearDown(self): + super(RejectSubDBIndex, self).tearDown() + + def test_try_subdb_index(self): + try: + self.l.add({"dn": "@INDEXLIST", + "@IDX_LMDB_SUBDB": [b"1"], + "@IDXONE": [b"1"], + "@IDXONE": [b"1"], + "@IDXGUID": [b"objectUUID"], + "@IDX_DN_GUID": [b"GUID"], + }) + except ldb.LdbError as e: + code = e.args[0] + string = e.args[1] + self.assertEqual(ldb.ERR_OPERATIONS_ERROR, code) + self.assertIn("sub-database index", string) + if __name__ == '__main__': import unittest unittest.TestProgram() -- 2.47.2