s4-server: Open and close a transaction on sam.ldb at startup
authorAndrew Bartlett <abartlet@samba.org>
Tue, 5 Mar 2019 01:38:41 +0000 (01:38 +0000)
committerAndrew Bartlett <abartlet@samba.org>
Thu, 7 Mar 2019 04:58:42 +0000 (04:58 +0000)
This fixes upgrading from 4.7 and earlier releases, and makes the DB
reindexing more transparent. It should also make it easier to handle
future normalisation rule changes, e.g. if we change the pack-format
of integer indexes in a future release.

Without this change, the  should have still handled reindexing the
database. We don't know why exactly this wasn't happening correctly,
but opening a transaction early in the samba process startup should
now guarantee that the DB is correctly reindexed by the time the main
samba code runs.

An alternative fix would have been to open a transaction in the the
DSDB module stack every time we connect to the database. However, this
would add an extra write lock every time we open the DB, whereas
starting samba happens much more infrequently.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=13760

Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Tim Beale <timbeale@catalyst.net.nz>
Reviewed-by: Gary Lockyer <gary@catalyst.net.nz>
Autobuild-User(master): Andrew Bartlett <abartlet@samba.org>
Autobuild-Date(master): Thu Mar  7 04:58:42 UTC 2019 on sn-devel-144

source4/smbd/server.c

index ea421b3bd68811ed8e4fe4163b6241a7e2946061..badc21270c08b90081719b7981676bd09abaad9c 100644 (file)
@@ -230,6 +230,41 @@ _NORETURN_ static void max_runtime_handler(struct tevent_context *ev,
        exit(0);
 }
 
+/*
+ * When doing an in-place upgrade of Samba, the database format may have
+ * changed between versions. E.g. between 4.7 and 4.8 the DB changed from
+ * DN-based indexes to GUID-based indexes, so we have to re-index the DB after
+ * upgrading.
+ * This function handles migrating an older samba DB to a new Samba release.
+ * Note that we have to maintain DB compatibility between *all* older versions
+ * of Samba, not just the ones still under maintenance support.
+ */
+static int handle_inplace_db_upgrade(struct ldb_context *ldb_ctx)
+{
+       int ret;
+
+       /*
+        * The DSDB stack will handle reindexing the DB (if needed) upon the first
+        * DB write. Open and close a transaction on the DB now to trigger a
+        * reindex if required, rather than waiting for the first write.
+        * We do this here to guarantee that the DB will have been re-indexed by
+        * the time the main samba code runs.
+        * Refer to dsdb_schema_set_indices_and_attributes() for the actual reindexing
+        * code, called from
+        * source4/dsdb/samdb/ldb_modules/schema_load.c:schema_load_start_transaction()
+        */
+       ret = ldb_transaction_start(ldb_ctx);
+       if (ret != LDB_SUCCESS) {
+               return ret;
+       }
+
+       ret = ldb_transaction_commit(ldb_ctx);
+       if (ret != LDB_SUCCESS) {
+               return ret;
+       }
+       return LDB_SUCCESS;
+}
+
 /*
   pre-open the key databases. This saves a lot of time in child
   processes
@@ -262,6 +297,13 @@ static int prime_ldb_databases(struct tevent_context *event_ctx, bool *am_backup
                talloc_free(db_context);
                return LDB_ERR_OPERATIONS_ERROR;
        }
+
+       ret = handle_inplace_db_upgrade(ldb_ctx);
+       if (ret != LDB_SUCCESS) {
+               talloc_free(db_context);
+               return ret;
+       }
+
        pdb = privilege_connect(db_context, cmdline_lp_ctx);
        if (pdb == NULL) {
                talloc_free(db_context);