diff options
author | Aaron Haslett <aaronhaslett@catalyst.net.nz> | 2018-05-01 15:48:38 +1200 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2018-06-28 03:34:26 +0200 |
commit | f0aad4a18736cbcbb3c87dd03cf24ae190fe8b4f (patch) | |
tree | 5756c6c1fb6eaeacc4fb7f2c9c2b788d8d1cdcc5 /source4/smbd | |
parent | 8e58954f2f4a41baaf4007dc09b7cf9349e98077 (diff) | |
download | samba-f0aad4a18736cbcbb3c87dd03cf24ae190fe8b4f.tar.gz |
samba: read backup date field on init and fail if present
This prevents a backup tar file, created with the new official
backup tools, from being extracted and replicated.
This is done here to ensure that samba-tool and ldbsearch can
still operate on the backup (eg for forensics) but starting
Samba as an AD DC will fail.
Signed-off-by: Aaron Haslett <aaronhaslett@catalyst.net.nz>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Diffstat (limited to 'source4/smbd')
-rw-r--r-- | source4/smbd/server.c | 83 |
1 files changed, 68 insertions, 15 deletions
diff --git a/source4/smbd/server.c b/source4/smbd/server.c index ed81c01afc1..5eca0b9e869 100644 --- a/source4/smbd/server.c +++ b/source4/smbd/server.c @@ -44,6 +44,7 @@ #include "nsswitch/winbind_client.h" #include "libds/common/roles.h" #include "lib/util/tfork.h" +#include "dsdb/samdb/ldb_modules/util.h" #ifdef HAVE_PTHREAD #include <pthread.h> @@ -232,23 +233,63 @@ _NORETURN_ static void max_runtime_handler(struct tevent_context *ev, pre-open the key databases. This saves a lot of time in child processes */ -static void prime_ldb_databases(struct tevent_context *event_ctx) +static int prime_ldb_databases(struct tevent_context *event_ctx, bool *am_backup) { - TALLOC_CTX *db_context; - db_context = talloc_new(event_ctx); - - samdb_connect(db_context, - event_ctx, - cmdline_lp_ctx, - system_session(cmdline_lp_ctx), - NULL, - 0); - privilege_connect(db_context, cmdline_lp_ctx); - - /* we deliberately leave these open, which allows them to be + struct ldb_result *res = NULL; + struct ldb_dn *samba_dsdb_dn = NULL; + struct ldb_context *ldb_ctx = NULL; + struct ldb_context *pdb = NULL; + static const char *attrs[] = { "backupDate", NULL }; + const char *msg = NULL; + int ret; + TALLOC_CTX *db_context = talloc_new(event_ctx); + if (db_context == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + *am_backup = false; + + /* note we deliberately leave these open, which allows them to be * re-used in ldb_wrap_connect() */ -} + ldb_ctx = samdb_connect(db_context, + event_ctx, + cmdline_lp_ctx, + system_session(cmdline_lp_ctx), + NULL, + 0); + if (ldb_ctx == NULL) { + talloc_free(db_context); + return LDB_ERR_OPERATIONS_ERROR; + } + pdb = privilege_connect(db_context, cmdline_lp_ctx); + if (pdb == NULL) { + talloc_free(db_context); + return LDB_ERR_OPERATIONS_ERROR; + } + /* check the root DB object to see if it's marked as a backup */ + samba_dsdb_dn = ldb_dn_new(db_context, ldb_ctx, "@SAMBA_DSDB"); + if (!samba_dsdb_dn) { + talloc_free(db_context); + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = dsdb_search_dn(ldb_ctx, db_context, &res, samba_dsdb_dn, attrs, + DSDB_FLAG_AS_SYSTEM); + if (ret != LDB_SUCCESS) { + talloc_free(db_context); + return ret; + } + + if (res->count > 0) { + msg = ldb_msg_find_attr_as_string(res->msgs[0], "backupDate", + NULL); + if (msg != NULL) { + *am_backup = true; + } + } + return LDB_SUCCESS; +} /* called when a fatal condition occurs in a child task @@ -366,7 +407,9 @@ static int binary_smbd_main(const char *binary_name, bool opt_fork = true; bool opt_interactive = false; bool opt_no_process_group = false; + bool db_is_backup = false; int opt; + int ret; poptContext pc; #define _MODULE_PROTO(init) extern NTSTATUS init(TALLOC_CTX *); STATIC_service_MODULES_PROTO; @@ -631,7 +674,17 @@ static int binary_smbd_main(const char *binary_name, "and exited. Check logs for details", EINVAL); }; - prime_ldb_databases(state->event_ctx); + ret = prime_ldb_databases(state->event_ctx, &db_is_backup); + if (ret != LDB_SUCCESS) { + TALLOC_FREE(state); + exit_daemon("Samba failed to prime database", EINVAL); + } + + if (db_is_backup) { + TALLOC_FREE(state); + exit_daemon("Database is a backup. Please run samba-tool domain" + " backup restore", EINVAL); + } status = setup_parent_messaging(state, cmdline_lp_ctx); if (!NT_STATUS_IS_OK(status)) { |