From 9c8327e9843fac467e69ce07612e4696f7793be4 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 1b74e52559d5..9ac8735a7c6c 100644 --- a/source3/smbd/smb2_server.c +++ b/source3/smbd/smb2_server.c @@ -4284,7 +4284,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); } @@ -4482,6 +4490,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