s3:smbd: disconnect the all client connections if a ctdb public ip dropped
authorStefan Metzmacher <metze@samba.org>
Thu, 25 Jun 2020 13:59:42 +0000 (15:59 +0200)
committerStefan Metzmacher <metze@samba.org>
Wed, 8 Jul 2020 15:54:41 +0000 (15:54 +0000)
For now we keep it simple and any disconnect on a connection that
used a ctdb public address, will disconnect all other remaining
connections.

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

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Günther Deschner <gd@samba.org>
source3/smbd/globals.h
source3/smbd/process.c
source3/smbd/smb2_server.c

index 968a6a5cab8bb668db2ffc96fb0ce75ee4266bc0..fcf33a699c684c5eb33d728c01f7957c742717e4 100644 (file)
@@ -361,6 +361,7 @@ struct smbXsrv_connection {
        const struct tsocket_address *local_address;
        const struct tsocket_address *remote_address;
        const char *remote_hostname;
+       bool has_ctdb_public_ip;
 
        enum protocol_types protocol;
 
index 011d87022913de9b33a708848a07be123e17770c..2bff5bf5a8f9c2148d2bdc7cb0fcdfad49ba4cfe 100644 (file)
@@ -2802,6 +2802,25 @@ static NTSTATUS smbd_register_ips(struct smbXsrv_connection *xconn,
                return NT_STATUS_NO_MEMORY;
        }
 
+       if (xconn->client->server_multi_channel_enabled) {
+               struct ctdb_public_ip_list_old *ips = NULL;
+
+               ret = ctdbd_control_get_public_ips(cconn,
+                                                  0, /* flags */
+                                                  state,
+                                                  &ips);
+               if (ret != 0) {
+                       return NT_STATUS_INTERNAL_ERROR;
+               }
+
+               xconn->has_ctdb_public_ip = ctdbd_find_in_public_ips(ips, srv);
+               TALLOC_FREE(ips);
+               if (xconn->has_ctdb_public_ip) {
+                       DBG_DEBUG("CTDB public ip on %s\n",
+                                 smbXsrv_connection_dbg(xconn));
+               }
+       }
+
        ret = ctdbd_register_ips(cconn, srv, clnt, release_ip, state);
        if (ret != 0) {
                return map_nt_error_from_unix(ret);
index 20ac3da34c6f50f73f7e16e6b296f47cb494c30c..cf9de185c1f40b504a11138b8fc56b4a017696cf 100644 (file)
@@ -1635,6 +1635,22 @@ void smbd_server_connection_terminate_ex(struct smbXsrv_connection *xconn,
                  smbXsrv_connection_dbg(xconn), num_ok,
                  reason, location);
 
+       if (xconn->has_ctdb_public_ip) {
+               /*
+                * If the connection has a ctdb public address
+                * we disconnect all client connections,
+                * as the public address might be moved to
+                * a different node.
+                *
+                * In future we may recheck which node currently
+                * holds this address, but for now we keep it simple.
+                */
+               smbd_server_disconnect_client_ex(xconn->client,
+                                                reason,
+                                                location);
+               return;
+       }
+
        if (num_ok != 0) {
                struct tevent_req *subreq = NULL;