smbd-server: Use MSG_SMB_IP_DROPPED
authorVinit Agnihotri <vagnihotri@ddn.com>
Thu, 29 Feb 2024 08:52:08 +0000 (00:52 -0800)
committerMartin Schwenke <martins@samba.org>
Tue, 16 Apr 2024 23:51:45 +0000 (23:51 +0000)
Signed-off-by: Vinit Agnihotri <vagnihotri@ddn.com>
Reviewed-by: Martin Schwenke <mschwenke@ddn.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
source3/smbd/server.c
source3/smbd/smb2_process.c

index aba980e9375d100b29ca4fa28e27e32a52b21ef1..e2d6c8c0be1802a59eb57ddac0922dbbac7022ce 100644 (file)
@@ -1284,6 +1284,13 @@ static bool open_sockets_smbd(struct smbd_parent_context *parent,
        messaging_register(msg_ctx, NULL, MSG_SMB_NOTIFY_STARTED,
                           smb_parent_send_to_children);
 
+       if (lp_interfaces() && lp_bind_interfaces_only()) {
+               messaging_register(msg_ctx,
+                                  NULL,
+                                  MSG_SMB_IP_DROPPED,
+                                  smb_parent_send_to_children);
+       }
+
 #ifdef DEVELOPER
        messaging_register(msg_ctx, NULL, MSG_SMB_INJECT_FAULT,
                           msg_inject_fault);
@@ -1640,6 +1647,7 @@ static void smbd_init_addrchange(TALLOC_CTX *mem_ctx,
 }
 
 static void smbd_close_socket_for_ip(struct smbd_parent_context *parent,
+                                    struct messaging_context *msg_ctx,
                                     struct sockaddr_storage *addr)
 {
        struct smbd_open_socket *s = NULL;
@@ -1655,12 +1663,25 @@ static void smbd_close_socket_for_ip(struct smbd_parent_context *parent,
                if (sockaddr_equal((struct sockaddr *)&a,
                                   (struct sockaddr *)addr)) {
                        char addrstr[INET6_ADDRSTRLEN];
+                       DATA_BLOB blob;
+                       NTSTATUS status;
 
                        DLIST_REMOVE(parent->sockets, s);
                        TALLOC_FREE(s);
                        print_sockaddr(addrstr, sizeof(addrstr), addr);
                        DBG_NOTICE("smbd: Closed listening socket for %s\n",
                                   addrstr);
+
+                       blob = data_blob_const(addrstr, strlen(addrstr)+1);
+                       status = messaging_send(msg_ctx,
+                                               messaging_server_id(msg_ctx),
+                                               MSG_SMB_IP_DROPPED,
+                                               &blob);
+                       if (!NT_STATUS_IS_OK(status)) {
+                               DBG_NOTICE(
+                                       "messaging_send failed: %s - ignoring\n",
+                                       nt_errstr(status));
+                       }
                        return;
                }
        }
@@ -1693,7 +1714,7 @@ static void smbd_addr_changed(struct tevent_req *req)
                           "on if_index %u\n",
                           addrstr, if_index);
 
-               smbd_close_socket_for_ip(state->parent, &addr);
+               smbd_close_socket_for_ip(state->parent, state->msg_ctx, &addr);
 
                goto rearm;
        }
index 482c448e81b386e386cb55dd77a181a5df88db20..4a6cda39a2f47af2618a1deb2f65cbee7912f123 100644 (file)
@@ -1565,6 +1565,38 @@ static void msg_kill_client_ip(struct messaging_context *msg_ctx,
        TALLOC_FREE(client_ip);
 }
 
+static void msg_kill_client_with_server_ip(struct messaging_context *msg_ctx,
+                                     void *private_data,
+                                     uint32_t msg_type,
+                                     struct server_id server_id,
+                                     DATA_BLOB *data)
+{
+       struct smbd_server_connection *sconn = talloc_get_type_abort(
+               private_data, struct smbd_server_connection);
+       const char *ip = (char *) data->data;
+       char *server_ip = NULL;
+       TALLOC_CTX *ctx = NULL;
+
+       DBG_NOTICE("Got kill request for source IP %s\n", ip);
+       ctx = talloc_stackframe();
+
+       server_ip = tsocket_address_inet_addr_string(sconn->local_address, ctx);
+       if (server_ip == NULL) {
+               goto out_free;
+       }
+
+       if (strequal(ip, server_ip)) {
+               DBG_NOTICE(
+                       "Got ip dropped message for %s - exiting immediately\n",
+                       ip);
+               TALLOC_FREE(ctx);
+               exit_server_cleanly("Forced disconnect for client");
+       }
+
+out_free:
+       TALLOC_FREE(ctx);
+}
+
 /*
  * Do the recurring check if we're idle
  */
@@ -2019,6 +2051,12 @@ void smbd_process(struct tevent_context *ev_ctx,
        messaging_register(sconn->msg_ctx, NULL,
                           MSG_DEBUG, debug_message);
 
+       messaging_deregister(sconn->msg_ctx, MSG_SMB_IP_DROPPED, NULL);
+       messaging_register(sconn->msg_ctx,
+                          sconn,
+                          MSG_SMB_IP_DROPPED,
+                          msg_kill_client_with_server_ip);
+
 #if defined(WITH_SMB1SERVER)
        if ((lp_keepalive() != 0) &&
            !(event_add_idle(ev_ctx,