From f9240ed08b80806b2040114e3c41ae7187f9e11b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 5 Mar 2019 01:38:41 +0000 Subject: [PATCH] s4-server: Open and close a transaction on sam.ldb at startup 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 Reviewed-by: Tim Beale Reviewed-by: Gary Lockyer Autobuild-User(master): Andrew Bartlett Autobuild-Date(master): Thu Mar 7 04:58:42 UTC 2019 on sn-devel-144 (cherry picked from commit 8b18da27cf261b0283fe66d2b827cab542488ac7) --- source4/smbd/server.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/source4/smbd/server.c b/source4/smbd/server.c index db570710ca9..e0255523824 100644 --- a/source4/smbd/server.c +++ b/source4/smbd/server.c @@ -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); -- 2.20.1