s3:smbd: split out smbXsrv_connection_disconnect_transport()
authorStefan Metzmacher <metze@samba.org>
Fri, 4 Oct 2019 12:26:20 +0000 (14:26 +0200)
committerGünther Deschner <gd@samba.org>
Fri, 15 May 2020 09:04:36 +0000 (09:04 +0000)
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 <metze@samba.org>
Reviewed-by: Guenther Deschner <gd@samba.org>
source3/smbd/globals.h
source3/smbd/server_exit.c
source3/smbd/smb2_server.c

index 77911f051dfa0656099246fd81925258f97c1d4f..2d40f0802604e1c0be07559ba3280e6b499fbf15 100644 (file)
@@ -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);
index f361aaf0bb78411aef4bd2e1122f44b86caf28d6..e3efa993159fcdaa30eb78afb843ee8bac67c554 100644 (file)
@@ -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();
index 718f094153262a69eae1c1e87a4b2f06dded8810..de3eb9d22ce4cc8372665d00a4ec03c51c507208 100644 (file)
@@ -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)