s3:smbd multichannel: always allow multichannel to the ip of the queried connection
authorStefan Metzmacher <metze@samba.org>
Fri, 29 Dec 2023 12:09:32 +0000 (13:09 +0100)
committerStefan Metzmacher <metze@samba.org>
Tue, 9 Jan 2024 10:21:34 +0000 (10:21 +0000)
We can announce the ip of the current connection even if it's
a moveable cluster address... as the client is already connected to it.

This change means in a typical ctdb cluster, where we only have public
addresses, the client can at least have more than one multichannel'ed
connection to the public ip.

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Günther Deschner <gd@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
source3/smbd/smb2_ioctl_network_fs.c

index 9ef99dca90f318a45e343467ccd4954999bc7e97..bcfa37fdf978e45440394bc7c3d0d46f8ef12777 100644 (file)
@@ -362,6 +362,7 @@ static NTSTATUS fsctl_network_iface_info(TALLOC_CTX *mem_ctx,
                                         uint32_t in_max_output,
                                         DATA_BLOB *out_output)
 {
+       struct samba_sockaddr xconn_srv_addr = { .sa_socklen = 0, };
        struct fsctl_net_iface_info *array = NULL;
        struct fsctl_net_iface_info *first = NULL;
        struct fsctl_net_iface_info *last = NULL;
@@ -369,6 +370,7 @@ static NTSTATUS fsctl_network_iface_info(TALLOC_CTX *mem_ctx,
        size_t num_ifaces;
        enum ndr_err_code ndr_err;
        struct cluster_movable_ips *cluster_movable_ips = NULL;
+       ssize_t sret;
        int ret;
 
        if (in_input->length != 0) {
@@ -410,6 +412,14 @@ static NTSTATUS fsctl_network_iface_info(TALLOC_CTX *mem_ctx,
                }
        }
 
+       sret = tsocket_address_bsd_sockaddr(xconn->local_address,
+                                           &xconn_srv_addr.u.sa,
+                                           sizeof(xconn_srv_addr.u.ss));
+       if (sret < 0) {
+               return NT_STATUS_INTERNAL_ERROR;
+       }
+       xconn_srv_addr.sa_socklen = sret;
+
        for (i=0; i < num_ifaces; i++) {
                struct fsctl_net_iface_info *cur = &array[i];
                const struct interface *iface = get_interface(i);
@@ -440,7 +450,18 @@ static NTSTATUS fsctl_network_iface_info(TALLOC_CTX *mem_ctx,
                        return NT_STATUS_NO_MEMORY;
                }
 
-               if (cluster_movable_ips != NULL) {
+               if (sockaddr_equal(ifsa, &xconn_srv_addr.u.sa)) {
+                       /*
+                        * We can announce the ip of the current connection even
+                        * if it is a moveable cluster address... as the client
+                        * is already connected to it.
+                        *
+                        * It means in a typical ctdb cluster, where we
+                        * only have public addresses, the client can at least
+                        * have more than one multichannel'ed connection to the
+                        * public ip.
+                        */
+               } else if (cluster_movable_ips != NULL) {
                        bool is_movable_ip = find_in_cluster_movable_ips(
                                                cluster_movable_ips,
                                                ifss);