summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2020-07-06 16:51:05 +0200
committerGünther Deschner <gd@samba.org>2020-07-14 14:59:18 +0000
commitd23e2678e93362b03df21b6fc26835ad8efdcc9f (patch)
tree8093a4a6bed33a0bba4839a8e02c415ef9c1663e /source3
parente5a8b16a11f7286b88e3ea2057c26aa558b9f74a (diff)
downloadsamba-d23e2678e93362b03df21b6fc26835ad8efdcc9f.tar.gz
s3:smbd: stop accepting multichannel connections early in exit_server_common()
This is just a step in the correct direction, but there's still a possible race... BUG: https://bugzilla.samba.org/show_bug.cgi?id=14433 Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Guenther Deschner <gd@samba.org> Autobuild-User(master): Günther Deschner <gd@samba.org> Autobuild-Date(master): Tue Jul 14 14:59:19 UTC 2020 on sn-devel-184
Diffstat (limited to 'source3')
-rw-r--r--source3/librpc/idl/smbXsrv.idl1
-rw-r--r--source3/smbd/server_exit.c17
-rw-r--r--source3/smbd/smbXsrv_client.c6
3 files changed, 23 insertions, 1 deletions
diff --git a/source3/librpc/idl/smbXsrv.idl b/source3/librpc/idl/smbXsrv.idl
index a74ac42b312..78fc3644d2f 100644
--- a/source3/librpc/idl/smbXsrv.idl
+++ b/source3/librpc/idl/smbXsrv.idl
@@ -142,6 +142,7 @@ interface smbXsrv
[ignore] struct smbXsrv_connection *connections;
boolean8 server_multi_channel_enabled;
hyper next_channel_id;
+ [ignore] struct tevent_req *connection_pass_subreq;
/*
* A List of pending breaks.
diff --git a/source3/smbd/server_exit.c b/source3/smbd/server_exit.c
index 01e3ef83f03..397ea810633 100644
--- a/source3/smbd/server_exit.c
+++ b/source3/smbd/server_exit.c
@@ -99,10 +99,25 @@ static void exit_server_common(enum server_exit_reason how,
}
if (client != NULL) {
+ NTSTATUS status;
+
sconn = client->sconn;
xconn = client->connections;
- }
+ /*
+ * Make sure we stop handling new multichannel
+ * connections early!
+ *
+ * From here, we're not able to handle them.
+ */
+ status = smbXsrv_client_remove(client);
+ if (!NT_STATUS_IS_OK(status)) {
+ D_ERR("Server exit (%s)\n",
+ (reason ? reason : "normal exit"));
+ DBG_ERR("smbXsrv_client_remove() failed (%s)\n",
+ nt_errstr(status));
+ }
+ }
change_to_root_user();
diff --git a/source3/smbd/smbXsrv_client.c b/source3/smbd/smbXsrv_client.c
index e0658d87969..fcfa225048a 100644
--- a/source3/smbd/smbXsrv_client.c
+++ b/source3/smbd/smbXsrv_client.c
@@ -568,6 +568,7 @@ NTSTATUS smbXsrv_client_create(TALLOC_CTX *mem_ctx,
return NT_STATUS_NO_MEMORY;
}
tevent_req_set_callback(subreq, smbXsrv_client_connection_pass_loop, client);
+ client->connection_pass_subreq = subreq;
*_client = client;
return NT_STATUS_OK;
@@ -607,6 +608,8 @@ static void smbXsrv_client_connection_pass_loop(struct tevent_req *subreq)
int sock_fd = -1;
uint64_t seq_low;
+ client->connection_pass_subreq = NULL;
+
ret = messaging_filtered_read_recv(subreq, talloc_tos(), &rec);
TALLOC_FREE(subreq);
if (ret != 0) {
@@ -731,6 +734,7 @@ next:
return;
}
tevent_req_set_callback(subreq, smbXsrv_client_connection_pass_loop, client);
+ client->connection_pass_subreq = subreq;
}
NTSTATUS smbXsrv_client_update(struct smbXsrv_client *client)
@@ -797,6 +801,8 @@ NTSTATUS smbXsrv_client_remove(struct smbXsrv_client *client)
return NT_STATUS_OK;
}
+ TALLOC_FREE(client->connection_pass_subreq);
+
client->global->db_rec = smbXsrv_client_global_fetch_locked(
table->global.db_ctx,
&client->global->client_guid,