]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
ldb: Reject a possible future ldb_mdb with the index in a sub-database
authorAndrew Bartlett <abartlet@samba.org>
Fri, 18 May 2018 19:10:15 +0000 (07:10 +1200)
committerAndrew Bartlett <abartlet@samba.org>
Wed, 23 May 2018 00:27:12 +0000 (02:27 +0200)
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 <abartlet@samba.org>
Reviewed-by: Garming Sam <garming@catalyst.net.nz>
lib/ldb/ldb_tdb/ldb_cache.c
lib/ldb/ldb_tdb/ldb_tdb.h
lib/ldb/tests/python/index.py

index a9d2113e707b783e48d2a999caf9e77df0cddc98..1856fb13877635298c8e9b0067618826fa8f2205 100644 (file)
@@ -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;
 }
 
index dfc0d5e3299e2d6a9e89327d40add57ae5cc7fec..46af8a1d8369cd77a644393cc5dc21d2c7e6423d 100644 (file)
@@ -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"
index 3379fb9374f431f0ba83b92596bbe0a41e11801b..2613a4dbeddbab4a0373ab0a51a3ceeecd76dfd0 100755 (executable)
@@ -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()