]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
smbd: let smbd_server_connection_terminate_ex() always go through smbXsrv_connection_...
authorRalph Boehme <slow@samba.org>
Sat, 28 Sep 2024 14:44:31 +0000 (16:44 +0200)
committerRalph Boehme <slow@samba.org>
Tue, 5 Nov 2024 14:39:30 +0000 (14:39 +0000)
This ensures common cleanup code via

  smbXsrv_connection_shutdown_send() ->
  -> smbXsrv_session_disconnect_xconn()
  -> smbXsrv_session_remove_channel()
  -> smb2srv_session_shutdown_send()

is used if the last (only) connection goes away as well. In the future this
should be implemented for the

  xconn->has_cluster_movable_ip

case.

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

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
selftest/knownfail.d/samba3.smb2.lease
source3/smbd/smb2_server.c

index f3b57214ad663e4827c040985b40356956a10935..e9147609a5ff50254d6f0ff610fe68f1e32e28fb 100644 (file)
@@ -1,2 +1 @@
-^samba3.smb2.lease.initial_delete_disconnect\(fileserver\)
 ^samba3.smb2.lease.initial_delete_tdis\(fileserver\)
index 287d9844e842c71de2692433cc3b208705530af1..610d79e5760dda44f321e224fd39efa071e90f12 100644 (file)
@@ -1721,12 +1721,21 @@ static NTSTATUS smbXsrv_connection_shutdown_recv(struct tevent_req *req)
        return tevent_req_simple_recv_ntstatus(req);
 }
 
+struct smbd_server_connection_terminate_state {
+       struct smbXsrv_connection *xconn;
+       char *reason;
+};
+
 static void smbd_server_connection_terminate_done(struct tevent_req *subreq)
 {
-       struct smbXsrv_connection *xconn =
-               tevent_req_callback_data(subreq,
-               struct smbXsrv_connection);
+       struct smbd_server_connection_terminate_state *state =
+               tevent_req_callback_data(
+                       subreq,
+                       struct smbd_server_connection_terminate_state);
+       struct smbXsrv_connection *xconn = state->xconn;
        struct smbXsrv_client *client = xconn->client;
+       const char *reason = state->reason;
+       size_t num_ok;
        NTSTATUS status;
 
        status = smbXsrv_connection_shutdown_recv(subreq);
@@ -1737,15 +1746,37 @@ static void smbd_server_connection_terminate_done(struct tevent_req *subreq)
 
        DLIST_REMOVE(client->connections, xconn);
        TALLOC_FREE(xconn);
+
+       num_ok = smbXsrv_client_valid_connections(client);
+       if (num_ok > 0) {
+               return;
+       }
+
+       /*
+        * The last connection was disconnected
+        */
+       exit_server_cleanly(reason);
 }
 
 void smbd_server_connection_terminate_ex(struct smbXsrv_connection *xconn,
                                         const char *reason,
                                         const char *location)
 {
+       struct smbd_server_connection_terminate_state *state = NULL;
        struct smbXsrv_client *client = xconn->client;
+       struct tevent_req *subreq = NULL;
        size_t num_ok = 0;
 
+       state = talloc_zero(xconn, struct smbd_server_connection_terminate_state);
+       if (state == NULL) {
+               exit_server("smbXsrv_connection_shutdown_send failed");
+       }
+       state->xconn = xconn;
+       state->reason = talloc_strdup(state, reason);
+       if (state->reason == NULL) {
+               exit_server("talloc_strdup failed");
+       }
+
        /*
         * Make sure that no new request will be able to use this session.
         *
@@ -1785,25 +1816,16 @@ void smbd_server_connection_terminate_ex(struct smbXsrv_connection *xconn,
                return;
        }
 
-       if (num_ok != 0) {
-               struct tevent_req *subreq = NULL;
-
-               subreq = smbXsrv_connection_shutdown_send(client,
-                                                         client->raw_ev_ctx,
-                                                         xconn);
-               if (subreq == NULL) {
-                       exit_server("smbXsrv_connection_shutdown_send failed");
-               }
-               tevent_req_set_callback(subreq,
-                                       smbd_server_connection_terminate_done,
-                                       xconn);
-               return;
+       subreq = smbXsrv_connection_shutdown_send(client,
+                                                 client->raw_ev_ctx,
+                                                 xconn);
+       if (subreq == NULL) {
+               exit_server("smbXsrv_connection_shutdown_send failed");
        }
-
-       /*
-        * The last connection was disconnected
-        */
-       exit_server_cleanly(reason);
+       tevent_req_set_callback(subreq,
+                               smbd_server_connection_terminate_done,
+                               state);
+       return;
 }
 
 void smbd_server_disconnect_client_ex(struct smbXsrv_client *client,