From: Stefan Metzmacher Date: Fri, 4 Oct 2019 12:26:20 +0000 (+0200) Subject: s3:smbd: split out smbXsrv_connection_disconnect_transport() X-Git-Url: http://git.samba.org/samba.git/?p=gd%2Fsamba-autobuild%2F.git;a=commitdiff_plain;h=d8ab88e77f8bbd29d9222348eb4f9a290a4f3694 s3:smbd: split out smbXsrv_connection_disconnect_transport() It's good to have an isolated function that just disconnects the lower layer transport and remembers the first error status. This will be used in more placed in the following commits. Signed-off-by: Stefan Metzmacher Reviewed-by: Guenther Deschner --- diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h index 77911f051df..2d40f080260 100644 --- a/source3/smbd/globals.h +++ b/source3/smbd/globals.h @@ -220,6 +220,8 @@ NTSTATUS smbd_calculate_access_mask(connection_struct *conn, void smbd_notify_cancel_by_smbreq(const struct smb_request *smbreq); +void smbXsrv_connection_disconnect_transport(struct smbXsrv_connection *xconn, + NTSTATUS status); void smbd_server_connection_terminate_ex(struct smbXsrv_connection *xconn, const char *reason, const char *location); diff --git a/source3/smbd/server_exit.c b/source3/smbd/server_exit.c index f361aaf0bb7..e3efa993159 100644 --- a/source3/smbd/server_exit.c +++ b/source3/smbd/server_exit.c @@ -81,6 +81,17 @@ static void exit_server_common(enum server_exit_reason how, struct smbXsrv_connection *xconn = NULL; struct smbd_server_connection *sconn = NULL; struct messaging_context *msg_ctx = global_messaging_context(); + NTSTATUS disconnect_status; + + switch (how) { + case SERVER_EXIT_NORMAL: + disconnect_status = NT_STATUS_LOCAL_DISCONNECT; + break; + case SERVER_EXIT_ABNORMAL: + default: + disconnect_status = NT_STATUS_INTERNAL_ERROR; + break; + } if (client != NULL) { sconn = client->sconn; @@ -100,19 +111,12 @@ static void exit_server_common(enum server_exit_reason how, for (; xconn != NULL; xconn = xconn->next) { /* * This is typically the disconnect for the only - * (or with multi-channel last) connection of the client + * (or with multi-channel last) connection of the client. + * + * smbXsrv_connection_disconnect_transport() might be called already, + * but calling it again is a no-op. */ - if (NT_STATUS_IS_OK(xconn->transport.status)) { - switch (how) { - case SERVER_EXIT_ABNORMAL: - xconn->transport.status = NT_STATUS_INTERNAL_ERROR; - break; - case SERVER_EXIT_NORMAL: - xconn->transport.status = NT_STATUS_LOCAL_DISCONNECT; - break; - } - } - DO_PROFILE_INC(disconnect); + smbXsrv_connection_disconnect_transport(xconn, disconnect_status); } change_to_root_user(); diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c index 718f0941532..de3eb9d22ce 100644 --- a/source3/smbd/smb2_server.c +++ b/source3/smbd/smb2_server.c @@ -1106,6 +1106,21 @@ static NTSTATUS smbd_smb2_request_setup_out(struct smbd_smb2_request *req) return NT_STATUS_OK; } +void smbXsrv_connection_disconnect_transport(struct smbXsrv_connection *xconn, + NTSTATUS status) +{ + if (!NT_STATUS_IS_OK(xconn->transport.status)) { + return; + } + + xconn->transport.status = status; + TALLOC_FREE(xconn->transport.fde); + if (xconn->transport.sock != -1) { + xconn->transport.sock = -1; + } + DO_PROFILE_INC(disconnect); +} + void smbd_server_connection_terminate_ex(struct smbXsrv_connection *xconn, const char *reason, const char *location)