CVE-2023-42670 s3-rpc_server: Strictly refuse to start RPC servers in conflict with...
authorAndrew Bartlett <abartlet@samba.org>
Tue, 12 Sep 2023 00:28:49 +0000 (12:28 +1200)
committerJule Anger <janger@samba.org>
Mon, 9 Oct 2023 20:14:05 +0000 (22:14 +0200)
Just as we refuse to start NETLOGON except on the DC, we must refuse
to start all of the RPC services that are provided by the AD DC.

Most critically of course this applies to netlogon, lsa and samr.

This avoids the supression of these services being the result of a
runtime epmapper lookup, as if that fails these services can disrupt
service to end users by listening on the same socket as the AD DC
servers.

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

Signed-off-by: Andrew Bartlett <abartlet@samba.org>
source3/rpc_server/rpcd_classic.c
source3/rpc_server/rpcd_epmapper.c
source3/rpc_server/rpcd_lsad.c
source3/rpc_server/rpcd_rpcecho.c

index 4f6164c814cd699d7d34da609e2f453f0a1a4979..8494af575ecbf6994980e88ffa6d6e501aba1a5e 100644 (file)
@@ -42,14 +42,34 @@ static size_t classic_interfaces(
        static const struct ndr_interface_table *ifaces[] = {
                &ndr_table_srvsvc,
                &ndr_table_netdfs,
-               &ndr_table_wkssvc,
+               &ndr_table_initshutdown,
                &ndr_table_svcctl,
                &ndr_table_ntsvcs,
                &ndr_table_eventlog,
-               &ndr_table_initshutdown,
+               /*
+                * This last item is truncated from the list by the
+                * num_ifaces -= 1 below.  Take care when adding new
+                * services.
+                */
+               &ndr_table_wkssvc,
        };
+       size_t num_ifaces = ARRAY_SIZE(ifaces);
+
+       switch(lp_server_role()) {
+       case ROLE_ACTIVE_DIRECTORY_DC:
+               /*
+                * On the AD DC wkssvc is provided by the 'samba'
+                * binary from source4/
+                */
+               num_ifaces -= 1;
+               break;
+       default:
+               break;
+       }
+
        *pifaces = ifaces;
-       return ARRAY_SIZE(ifaces);
+       return num_ifaces;
+
 }
 
 static size_t classic_servers(
@@ -58,15 +78,28 @@ static size_t classic_servers(
        void *private_data)
 {
        static const struct dcesrv_endpoint_server *ep_servers[7] = { NULL };
+       size_t num_servers = ARRAY_SIZE(ep_servers);
        bool ok;
 
        ep_servers[0] = srvsvc_get_ep_server();
        ep_servers[1] = netdfs_get_ep_server();
-       ep_servers[2] = wkssvc_get_ep_server();
+       ep_servers[2] = initshutdown_get_ep_server();
        ep_servers[3] = svcctl_get_ep_server();
        ep_servers[4] = ntsvcs_get_ep_server();
        ep_servers[5] = eventlog_get_ep_server();
-       ep_servers[6] = initshutdown_get_ep_server();
+       ep_servers[6] = wkssvc_get_ep_server();
+
+       switch(lp_server_role()) {
+       case ROLE_ACTIVE_DIRECTORY_DC:
+               /*
+                * On the AD DC wkssvc is provided by the 'samba'
+                * binary from source4/
+                */
+               num_servers -= 1;
+               break;
+       default:
+               break;
+       }
 
        ok = secrets_init();
        if (!ok) {
@@ -85,7 +118,7 @@ static size_t classic_servers(
        mangle_reset_cache();
 
        *_ep_servers = ep_servers;
-       return ARRAY_SIZE(ep_servers);
+       return num_servers;
 }
 
 int main(int argc, const char *argv[])
index 950ba7ec12a229eaf57cf7f8883cb2a14246f443..455179ccfba2f0a59b730f9d6aeee3a8873bcb4b 100644 (file)
@@ -19,6 +19,8 @@
 #include "rpc_worker.h"
 #include "librpc/gen_ndr/ndr_epmapper.h"
 #include "librpc/gen_ndr/ndr_epmapper_scompat.h"
+#include "param/loadparm.h"
+#include "libds/common/roles.h"
 
 static size_t epmapper_interfaces(
        const struct ndr_interface_table ***pifaces,
@@ -27,8 +29,22 @@ static size_t epmapper_interfaces(
        static const struct ndr_interface_table *ifaces[] = {
                &ndr_table_epmapper,
        };
+       size_t num_ifaces = ARRAY_SIZE(ifaces);
+
+       switch(lp_server_role()) {
+       case ROLE_ACTIVE_DIRECTORY_DC:
+               /*
+                * On the AD DC epmapper is provided by the 'samba'
+                * binary from source4/
+                */
+               num_ifaces = 0;
+               break;
+       default:
+               break;
+       }
+
        *pifaces = ifaces;
-       return ARRAY_SIZE(ifaces);
+       return num_ifaces;
 }
 
 static size_t epmapper_servers(
@@ -37,11 +53,24 @@ static size_t epmapper_servers(
        void *private_data)
 {
        static const struct dcesrv_endpoint_server *ep_servers[] = { NULL };
+       size_t num_servers = ARRAY_SIZE(ep_servers);
 
        ep_servers[0] = epmapper_get_ep_server();
 
+       switch(lp_server_role()) {
+       case ROLE_ACTIVE_DIRECTORY_DC:
+               /*
+                * On the AD DC epmapper is provided by the 'samba'
+                * binary from source4/
+                */
+               num_servers = 0;
+               break;
+       default:
+               break;
+       }
+
        *_ep_servers = ep_servers;
-       return ARRAY_SIZE(ep_servers);
+       return num_servers;
 }
 
 int main(int argc, const char *argv[])
index 3ca0ed43fdd6a470387988439fe623b765a137cf..b0e021493e7e834232a6ea49720db0e82ba89981 100644 (file)
@@ -36,6 +36,11 @@ static size_t lsad_interfaces(
                &ndr_table_lsarpc,
                &ndr_table_samr,
                &ndr_table_dssetup,
+               /*
+                * This last item is truncated from the list by the
+                * num_ifaces -= 1 below for the fileserver.  Take
+                * care when adding new services.
+                */
                &ndr_table_netlogon,
        };
        size_t num_ifaces = ARRAY_SIZE(ifaces);
@@ -46,6 +51,14 @@ static size_t lsad_interfaces(
                /* no netlogon for non-dc */
                num_ifaces -= 1;
                break;
+       case ROLE_ACTIVE_DIRECTORY_DC:
+               /*
+                * All these services are provided by the 'samba'
+                * binary from source4, not this code which is the
+                * source3 / NT4-like "classic" DC implementation
+                */
+               num_ifaces = 0;
+               break;
        default:
                break;
        }
@@ -80,6 +93,14 @@ static size_t lsad_servers(
                /* no netlogon for non-dc */
                num_servers -= 1;
                break;
+       case ROLE_ACTIVE_DIRECTORY_DC:
+               /*
+                * All these services are provided by the 'samba'
+                * binary from source4, not this code which is the
+                * source3 / NT4-like "classic" DC implementation
+                */
+               num_servers = 0;
+               break;
        default:
                break;
        }
index 9176039819f87b2699c019455dc08d689a5f1444..37391f563db8cd5f1fff11b7888b408a1fd3acbf 100644 (file)
@@ -19,6 +19,8 @@
 #include "rpc_worker.h"
 #include "librpc/gen_ndr/ndr_echo.h"
 #include "librpc/gen_ndr/ndr_echo_scompat.h"
+#include "param/loadparm.h"
+#include "libds/common/roles.h"
 
 static size_t rpcecho_interfaces(
        const struct ndr_interface_table ***pifaces,
@@ -27,8 +29,22 @@ static size_t rpcecho_interfaces(
        static const struct ndr_interface_table *ifaces[] = {
                &ndr_table_rpcecho,
        };
+       size_t num_ifaces = ARRAY_SIZE(ifaces);
+
+       switch(lp_server_role()) {
+       case ROLE_ACTIVE_DIRECTORY_DC:
+               /*
+                * On the AD DC rpcecho is provided by the 'samba'
+                * binary from source4/
+                */
+               num_ifaces = 0;
+               break;
+       default:
+               break;
+       }
+
        *pifaces = ifaces;
-       return ARRAY_SIZE(ifaces);
+       return num_ifaces;
 }
 
 static size_t rpcecho_servers(
@@ -37,11 +53,24 @@ static size_t rpcecho_servers(
        void *private_data)
 {
        static const struct dcesrv_endpoint_server *ep_servers[1] = { NULL };
+       size_t num_servers = ARRAY_SIZE(ep_servers);
 
        ep_servers[0] = rpcecho_get_ep_server();
 
+       switch(lp_server_role()) {
+       case ROLE_ACTIVE_DIRECTORY_DC:
+               /*
+                * On the AD DC rpcecho is provided by the 'samba'
+                * binary from source4/
+                */
+               num_servers = 0;
+               break;
+       default:
+               break;
+       }
+
        *_ep_servers = ep_servers;
-       return ARRAY_SIZE(ep_servers);
+       return num_servers;
 }
 
 int main(int argc, const char *argv[])