1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-12 09:18:10 +03:00

smbd: make sure that xconn is alive for the lifetime of smbXsrv_connection_shutdown_send/recv

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

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
This commit is contained in:
Stefan Metzmacher 2020-09-23 13:07:20 +02:00 committed by Jeremy Allison
parent 2a0626c32a
commit f1f5c36581
3 changed files with 32 additions and 1 deletions

View File

@ -1 +0,0 @@
^samba3.smb2.lease.timeout-disconnect

View File

@ -367,6 +367,7 @@ struct smbXsrv_connection {
struct {
NTSTATUS status;
bool terminating;
int sock;
struct tevent_fd *fde;

View File

@ -1500,6 +1500,7 @@ size_t smbXsrv_client_valid_connections(struct smbXsrv_client *client)
struct smbXsrv_connection_shutdown_state {
struct tevent_queue *wait_queue;
struct smbXsrv_connection *xconn;
};
static void smbXsrv_connection_shutdown_wait_done(struct tevent_req *subreq);
@ -1520,6 +1521,7 @@ static struct tevent_req *smbXsrv_connection_shutdown_send(TALLOC_CTX *mem_ctx,
* smbXsrv_connection_disconnect_transport() before.
*/
SMB_ASSERT(!NT_STATUS_IS_OK(xconn->transport.status));
SMB_ASSERT(xconn->transport.terminating);
req = tevent_req_create(mem_ctx, &state,
struct smbXsrv_connection_shutdown_state);
@ -1527,6 +1529,9 @@ static struct tevent_req *smbXsrv_connection_shutdown_send(TALLOC_CTX *mem_ctx,
return NULL;
}
state->xconn = xconn;
tevent_req_defer_callback(req, ev);
status = smbXsrv_session_disconnect_xconn(xconn);
if (tevent_req_nterror(req, status)) {
return tevent_req_post(req, ev);
@ -1590,15 +1595,33 @@ static void smbXsrv_connection_shutdown_wait_done(struct tevent_req *subreq)
struct tevent_req *req =
tevent_req_callback_data(subreq,
struct tevent_req);
struct smbXsrv_connection_shutdown_state *state =
tevent_req_data(req,
struct smbXsrv_connection_shutdown_state);
struct smbXsrv_connection *xconn = state->xconn;
tevent_queue_wait_recv(subreq);
TALLOC_FREE(subreq);
tevent_req_done(req);
/*
* make sure the xconn pointer is still valid,
* it should as we used tevent_req_defer_callback()
*/
SMB_ASSERT(xconn->transport.terminating);
}
static NTSTATUS smbXsrv_connection_shutdown_recv(struct tevent_req *req)
{
struct smbXsrv_connection_shutdown_state *state =
tevent_req_data(req,
struct smbXsrv_connection_shutdown_state);
struct smbXsrv_connection *xconn = state->xconn;
/*
* make sure the xconn pointer is still valid,
* it should as we used tevent_req_defer_callback()
*/
SMB_ASSERT(xconn->transport.terminating);
return tevent_req_simple_recv_ntstatus(req);
}
@ -1637,6 +1660,14 @@ void smbd_server_connection_terminate_ex(struct smbXsrv_connection *xconn,
num_ok = smbXsrv_client_valid_connections(client);
if (xconn->transport.terminating) {
DBG_DEBUG("skip recursion conn[%s] num_ok[%zu] reason[%s] at %s\n",
smbXsrv_connection_dbg(xconn), num_ok,
reason, location);
return;
}
xconn->transport.terminating = true;
DBG_DEBUG("conn[%s] num_ok[%zu] reason[%s] at %s\n",
smbXsrv_connection_dbg(xconn), num_ok,
reason, location);