From f7968c22b2fa371622fcadad392f2c66df0590ab Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 12 Feb 2026 13:21:06 +0100 Subject: [PATCH] s3:smb2_server: failing lease/oplock breaks should call smbd_server_connection_terminate() If there's a problem sending a lease break we need to call smbd_server_connection_terminate(xconn). Currently we only called smbXsrv_connection_disconnect_transport(), which only closes the low level socket, but it doesn't cleanup smbXsrv_connection and in case of the last connection for the smbXsrv_client, so we leave the stale structures and the stale process behind. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15995 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 734481e2aa9c9bb20fc9bc8734eba85d2f61be72) --- source3/smbd/smb2_server.c | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c index dd5196e7fd01..1d830d30175c 100644 --- a/source3/smbd/smb2_server.c +++ b/source3/smbd/smb2_server.c @@ -4314,7 +4314,15 @@ static struct tevent_req *smbd_smb2_break_send(TALLOC_CTX *mem_ctx, xconn->smb2.send_queue_len++; status = smbd_smb2_flush_send_queue(xconn); - if (tevent_req_nterror(req, status)) { + if (!NT_STATUS_IS_OK(status)) { + if (tevent_req_is_in_progress(req)) { + /* + * most likely tevent_req_nterror() + * was already called on + * state->queue_entry.ack.req + */ + tevent_req_nterror(req, status); + } return tevent_req_post(req, ev); } @@ -4512,6 +4520,33 @@ static void smbXsrv_pending_break_done(struct tevent_req *subreq) status = smbd_smb2_break_recv(subreq); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { + struct smbXsrv_connection *xconn = NULL; + + /* + * smbXsrv_connection_disconnect_transport() + * was already called, but in order to + * avoid stale xconn structures and in + * case of only one xconn a stale process + * we need to call smbd_server_connection_terminate() + * + * So we search if the xconn related to the + * last_channel_id is still there and + * start the cleanup, which most likely + * happens in an async fashion + */ + for (xconn = client->connections; + xconn != NULL; + xconn = xconn->next) + { + if (xconn->channel_id != pb->last_channel_id) { + continue; + } + + smbd_server_connection_terminate(xconn, + nt_errstr(status)); + break; + } + status = smbXsrv_pending_break_submit(pb); if (NT_STATUS_EQUAL(status, NT_STATUS_ABANDONED)) { /* -- 2.43.0