a3a04f
From 1f192fad31923af2bec692ded84e46add5bde76b Mon Sep 17 00:00:00 2001
a3a04f
From: Andreas Schneider <asn@samba.org>
a3a04f
Date: Mon, 16 Jan 2017 11:43:12 +0100
a3a04f
Subject: [PATCH 1/2] rpc_server: Use the RPC TCPIP ports of Windows
a3a04f
a3a04f
Since Windows Server 2008 Microsoft uses a different port range for RPC
a3a04f
services. Before it was 1024-65535 and they changed it to 49152-65535.
a3a04f
a3a04f
We should use the same range as these are the ports the firewall in AD
a3a04f
networks normally allow.
a3a04f
a3a04f
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12521
a3a04f
a3a04f
Signed-off-by: Andreas Schneider <asn@samba.org>
a3a04f
Reviewed-by: Stefan Metzmacher <metze@samba.org>
a3a04f
(cherry picked from commit 35dfa5c6e2bf60f8f1efda5eb7026cabe8bf5ba3)
a3a04f
---
a3a04f
 source3/rpc_server/rpc_server.c | 4 ++--
a3a04f
 source4/smbd/service_stream.c   | 4 ++--
a3a04f
 2 files changed, 4 insertions(+), 4 deletions(-)
a3a04f
a3a04f
diff --git a/source3/rpc_server/rpc_server.c b/source3/rpc_server/rpc_server.c
a3a04f
index 5effe66d9bb..37fe68fc36d 100644
a3a04f
--- a/source3/rpc_server/rpc_server.c
a3a04f
+++ b/source3/rpc_server/rpc_server.c
a3a04f
@@ -34,8 +34,8 @@
a3a04f
 #include "rpc_server/srv_pipe_hnd.h"
a3a04f
 #include "rpc_server/srv_pipe.h"
a3a04f
 
a3a04f
-#define SERVER_TCP_LOW_PORT  1024
a3a04f
-#define SERVER_TCP_HIGH_PORT 1300
a3a04f
+#define SERVER_TCP_LOW_PORT  49152
a3a04f
+#define SERVER_TCP_HIGH_PORT 65535
a3a04f
 
a3a04f
 /* Creates a pipes_struct and initializes it with the information
a3a04f
  * sent from the client */
a3a04f
diff --git a/source4/smbd/service_stream.c b/source4/smbd/service_stream.c
a3a04f
index f0a379acf6a..96a303fc6a9 100644
a3a04f
--- a/source4/smbd/service_stream.c
a3a04f
+++ b/source4/smbd/service_stream.c
a3a04f
@@ -30,8 +30,8 @@
a3a04f
 #include "lib/util/util_net.h"
a3a04f
 
a3a04f
 /* the range of ports to try for dcerpc over tcp endpoints */
a3a04f
-#define SERVER_TCP_LOW_PORT  1024
a3a04f
-#define SERVER_TCP_HIGH_PORT 1300
a3a04f
+#define SERVER_TCP_LOW_PORT  49152
a3a04f
+#define SERVER_TCP_HIGH_PORT 65535
a3a04f
 
a3a04f
 /* size of listen() backlog in smbd */
a3a04f
 #define SERVER_LISTEN_BACKLOG 10
a3a04f
-- 
a3a04f
2.11.0
a3a04f
a3a04f
a3a04f
From a48a358caa69d42191f285c1b28ba52b00d4e230 Mon Sep 17 00:00:00 2001
a3a04f
From: Andreas Schneider <asn@samba.org>
a3a04f
Date: Mon, 16 Jan 2017 12:05:09 +0100
a3a04f
Subject: [PATCH 2/2] rpc_server: Allow to configure the port range for RPC
a3a04f
 services
a3a04f
a3a04f
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12521
a3a04f
a3a04f
Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>
a3a04f
a3a04f
Signed-off-by: Andreas Schneider <asn@samba.org>
a3a04f
Signed-off-by: Stefan Metzmacher <metze@samba.org>
a3a04f
(cherry picked from commit 9d60ad53b809281a5a6f6ad82a0daea99c989f2d)
a3a04f
---
a3a04f
 docs-xml/smbdotconf/protocol/rpcserverport.xml     | 14 +++++--
a3a04f
 .../smbdotconf/rpc/rpcserverdynamicportrange.xml   | 22 ++++++++++
a3a04f
 lib/param/loadparm.c                               | 47 ++++++++++++++++++++++
a3a04f
 lib/param/loadparm.h                               |  9 ++++-
a3a04f
 lib/param/param.h                                  |  3 ++
a3a04f
 python/samba/tests/docs.py                         | 11 +++--
a3a04f
 source3/include/proto.h                            |  2 +
a3a04f
 source3/param/loadparm.c                           | 16 ++++++++
a3a04f
 source3/rpc_server/rpc_server.c                    |  5 +--
a3a04f
 source4/smbd/service_stream.c                      |  8 ++--
a3a04f
 10 files changed, 120 insertions(+), 17 deletions(-)
a3a04f
 create mode 100644 docs-xml/smbdotconf/rpc/rpcserverdynamicportrange.xml
a3a04f
a3a04f
diff --git a/docs-xml/smbdotconf/protocol/rpcserverport.xml b/docs-xml/smbdotconf/protocol/rpcserverport.xml
a3a04f
index 8a70835612f..0fd87d69212 100644
a3a04f
--- a/docs-xml/smbdotconf/protocol/rpcserverport.xml
a3a04f
+++ b/docs-xml/smbdotconf/protocol/rpcserverport.xml
a3a04f
@@ -4,11 +4,19 @@
a3a04f
                  xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
a3a04f
 <description>
a3a04f
 	<para>Specifies which port the server should listen on for DCE/RPC over TCP/IP traffic.</para>
a3a04f
-	<para>This controls default port for all protocols, except for NETLOGON.  If unset, the first available port after 1024 is used.</para>
a3a04f
-	<para>The NETLOGON server will use the next available port, eg 1025.  To change this port use (eg) rpc server port:netlogon = 4000.</para>
a3a04f
+	<para>This controls the default port for all protocols, except for NETLOGON.</para>
a3a04f
+	<para>If unset, the first available port from <smbconfoption name="rpc server dynamic port range"/> is used, e.g. 49152.</para>
a3a04f
+	<para>The NETLOGON server will use the next available port, e.g. 49153.  To change this port use (eg) rpc server port:netlogon = 4000.</para>
a3a04f
 	<para>Furthermore, all RPC servers can have the port they use specified independenty, with (for example) rpc server port:drsuapi = 5000.</para>
a3a04f
 
a3a04f
+	<para>This option applies currently only when
a3a04f
+	<citerefentry><refentrytitle>samba</refentrytitle> <manvolnum>8</manvolnum></citerefentry>
a3a04f
+	runs as an active directory domain controller.</para>
a3a04f
+
a3a04f
+	<para>The default value 0 causes Samba to select the first available port from <smbconfoption name="rpc server dynamic port range"/>.</para>
a3a04f
 </description>
a3a04f
-<para>The default value 0 causes Samba to select the first available port after 1024.</para>
a3a04f
+
a3a04f
+<related>rpc server dynamic port range</related>
a3a04f
+
a3a04f
 <value type="default">0</value>
a3a04f
 </samba:parameter>
a3a04f
diff --git a/docs-xml/smbdotconf/rpc/rpcserverdynamicportrange.xml b/docs-xml/smbdotconf/rpc/rpcserverdynamicportrange.xml
a3a04f
new file mode 100644
a3a04f
index 00000000000..a9c51d2fe41
a3a04f
--- /dev/null
a3a04f
+++ b/docs-xml/smbdotconf/rpc/rpcserverdynamicportrange.xml
a3a04f
@@ -0,0 +1,22 @@
a3a04f
+
a3a04f
+                 context="G"
a3a04f
+                 type="string"
a3a04f
+                 handler="handle_rpc_server_dynamic_port_range"
a3a04f
+                 xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
a3a04f
+<description>
a3a04f
+	<para>
a3a04f
+		This parameter tells the RPC server which port range it is
a3a04f
+		allowed to use to create a listening socket for LSA, SAM,
a3a04f
+		Netlogon and others without wellknown tcp ports.
a3a04f
+		The first value is the lowest number of the port
a3a04f
+		range and the second the hightest.
a3a04f
+	</para>
a3a04f
+	<para>
a3a04f
+		This applies to RPC servers in all server roles.
a3a04f
+	</para>
a3a04f
+</description>
a3a04f
+
a3a04f
+<related>rpc server port</related>
a3a04f
+
a3a04f
+<value type="default">49152-65535</value>
a3a04f
+</samba:parameter>
a3a04f
diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c
a3a04f
index 6aa757f7c6b..3b54ff232aa 100644
a3a04f
--- a/lib/param/loadparm.c
a3a04f
+++ b/lib/param/loadparm.c
a3a04f
@@ -83,6 +83,16 @@ struct loadparm_service *lpcfg_default_service(struct loadparm_context *lp_ctx)
a3a04f
 	return lp_ctx->sDefault;
a3a04f
 }
a3a04f
 
a3a04f
+int lpcfg_rpc_low_port(struct loadparm_context *lp_ctx)
a3a04f
+{
a3a04f
+	return lp_ctx->globals->rpc_low_port;
a3a04f
+}
a3a04f
+
a3a04f
+int lpcfg_rpc_high_port(struct loadparm_context *lp_ctx)
a3a04f
+{
a3a04f
+	return lp_ctx->globals->rpc_high_port;
a3a04f
+}
a3a04f
+
a3a04f
 /**
a3a04f
  * Convenience routine to grab string parameters into temporary memory
a3a04f
  * and run standard_sub_basic on them.
a3a04f
@@ -1435,6 +1445,37 @@ bool handle_smb_ports(struct loadparm_context *lp_ctx, struct loadparm_service *
a3a04f
 	return true;
a3a04f
 }
a3a04f
 
a3a04f
+bool handle_rpc_server_dynamic_port_range(struct loadparm_context *lp_ctx,
a3a04f
+					  struct loadparm_service *service,
a3a04f
+					  const char *pszParmValue,
a3a04f
+					  char **ptr)
a3a04f
+{
a3a04f
+	int low_port = -1, high_port = -1;
a3a04f
+	int rc;
a3a04f
+
a3a04f
+	if (pszParmValue == NULL || pszParmValue[0] == '\0') {
a3a04f
+		return false;
a3a04f
+	}
a3a04f
+
a3a04f
+	rc = sscanf(pszParmValue, "%d - %d", &low_port, &high_port);
a3a04f
+	if (rc != 2) {
a3a04f
+		return false;
a3a04f
+	}
a3a04f
+
a3a04f
+	if (low_port > high_port) {
a3a04f
+		return false;
a3a04f
+	}
a3a04f
+
a3a04f
+	if (low_port < SERVER_TCP_PORT_MIN|| high_port > SERVER_TCP_PORT_MAX) {
a3a04f
+		return false;
a3a04f
+	}
a3a04f
+
a3a04f
+	lp_ctx->globals->rpc_low_port = low_port;
a3a04f
+	lp_ctx->globals->rpc_high_port = high_port;
a3a04f
+
a3a04f
+	return true;
a3a04f
+}
a3a04f
+
a3a04f
 bool handle_smb2_max_credits(struct loadparm_context *lp_ctx,
a3a04f
 			     struct loadparm_service *service,
a3a04f
 			     const char *pszParmValue, char **ptr)
a3a04f
@@ -2498,6 +2539,8 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx)
a3a04f
 	lp_ctx->globals = talloc_zero(lp_ctx, struct loadparm_global);
a3a04f
 	/* This appears odd, but globals in s3 isn't a pointer */
a3a04f
 	lp_ctx->globals->ctx = lp_ctx->globals;
a3a04f
+	lp_ctx->globals->rpc_low_port = SERVER_TCP_LOW_PORT;
a3a04f
+	lp_ctx->globals->rpc_high_port = SERVER_TCP_HIGH_PORT;
a3a04f
 	lp_ctx->sDefault = talloc_zero(lp_ctx, struct loadparm_service);
a3a04f
 	lp_ctx->flags = talloc_zero_array(lp_ctx, unsigned int, num_parameters());
a3a04f
 
a3a04f
@@ -2902,6 +2945,10 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx)
a3a04f
 
a3a04f
 	lpcfg_do_global_parameter(lp_ctx, "kerberos encryption types", "all");
a3a04f
 
a3a04f
+	lpcfg_do_global_parameter(lp_ctx,
a3a04f
+				  "rpc server dynamic port range",
a3a04f
+				  "49152-65535");
a3a04f
+
a3a04f
 	/* Allow modules to adjust defaults */
a3a04f
 	for (defaults_hook = defaults_hooks; defaults_hook;
a3a04f
 		 defaults_hook = defaults_hook->next) {
a3a04f
diff --git a/lib/param/loadparm.h b/lib/param/loadparm.h
a3a04f
index f9fb7d8d804..c63683d6b66 100644
a3a04f
--- a/lib/param/loadparm.h
a3a04f
+++ b/lib/param/loadparm.h
a3a04f
@@ -194,6 +194,11 @@ enum printing_types {PRINT_BSD,PRINT_SYSV,PRINT_AIX,PRINT_HPUX,
a3a04f
 #endif /* DEVELOPER */
a3a04f
 };
a3a04f
 
a3a04f
+#define SERVER_TCP_LOW_PORT  49152
a3a04f
+#define SERVER_TCP_HIGH_PORT 65535
a3a04f
+
a3a04f
+#define SERVER_TCP_PORT_MIN 1024
a3a04f
+#define SERVER_TCP_PORT_MAX 65535
a3a04f
 
a3a04f
 
a3a04f
 
a3a04f
@@ -272,7 +277,9 @@ enum inheritowner_options {
a3a04f
 #define LOADPARM_EXTRA_GLOBALS \
a3a04f
 	struct parmlist_entry *param_opt;				\
a3a04f
 	char *dnsdomain;						\
a3a04f
-	char *realm_original;
a3a04f
+	char *realm_original;						\
a3a04f
+	int rpc_low_port;						\
a3a04f
+	int rpc_high_port;
a3a04f
 
a3a04f
 const char* server_role_str(uint32_t role);
a3a04f
 int lp_find_server_role(int server_role, int security, int domain_logons, int domain_master);
a3a04f
diff --git a/lib/param/param.h b/lib/param/param.h
a3a04f
index 66037e2ef1b..e123e67a990 100644
a3a04f
--- a/lib/param/param.h
a3a04f
+++ b/lib/param/param.h
a3a04f
@@ -313,6 +313,9 @@ void lpcfg_default_kdc_policy(struct loadparm_context *lp_ctx,
a3a04f
 				time_t *usr_tkt_lifetime,
a3a04f
 				time_t *renewal_lifetime);
a3a04f
 
a3a04f
+int lpcfg_rpc_port_low(struct loadparm_context *lp_ctx);
a3a04f
+int lpcfg_rpc_port_high(struct loadparm_context *lp_ctx);
a3a04f
+
a3a04f
 /* The following definitions come from lib/version.c  */
a3a04f
 
a3a04f
 const char *samba_version_string(void);
a3a04f
diff --git a/python/samba/tests/docs.py b/python/samba/tests/docs.py
a3a04f
index 22e022583f6..65df573a350 100644
a3a04f
--- a/python/samba/tests/docs.py
a3a04f
+++ b/python/samba/tests/docs.py
a3a04f
@@ -108,7 +108,7 @@ class SmbDotConfTests(TestCase):
a3a04f
                          'lprm command', 'lpq command', 'print command', 'template homedir',
a3a04f
                          'spoolss: os_major', 'spoolss: os_minor', 'spoolss: os_build',
a3a04f
                          'max open files', 'fss: prune stale', 'fss: sequence timeout',
a3a04f
-                         'include system krb5 conf'])
a3a04f
+                         'include system krb5 conf', 'rpc server dynamic port range'])
a3a04f
 
a3a04f
     def setUp(self):
a3a04f
         super(SmbDotConfTests, self).setUp()
a3a04f
@@ -162,14 +162,16 @@ class SmbDotConfTests(TestCase):
a3a04f
             exceptions = ['client lanman auth',
a3a04f
                           'client plaintext auth',
a3a04f
                           'registry shares',
a3a04f
-                          'smb ports'])
a3a04f
+                          'smb ports',
a3a04f
+                          'rpc server dynamic port range'])
a3a04f
         self._test_empty(['bin/testparm'])
a3a04f
 
a3a04f
     def test_default_s4(self):
a3a04f
         self._test_default(['bin/samba-tool', 'testparm'])
a3a04f
         self._set_defaults(['bin/samba-tool', 'testparm'])
a3a04f
         self._set_arbitrary(['bin/samba-tool', 'testparm'],
a3a04f
-            exceptions = ['smb ports'])
a3a04f
+            exceptions = ['smb ports',
a3a04f
+                          'rpc server dynamic port range'])
a3a04f
         self._test_empty(['bin/samba-tool', 'testparm'])
a3a04f
 
a3a04f
     def _test_default(self, program):
a3a04f
@@ -178,6 +180,7 @@ class SmbDotConfTests(TestCase):
a3a04f
 
a3a04f
         for tuples in self.defaults:
a3a04f
             param, default, context, param_type = tuples
a3a04f
+
a3a04f
             if param in self.special_cases:
a3a04f
                 continue
a3a04f
             section = None
a3a04f
@@ -206,7 +209,7 @@ class SmbDotConfTests(TestCase):
a3a04f
         for tuples in self.defaults:
a3a04f
             param, default, context, param_type = tuples
a3a04f
 
a3a04f
-            if param in ['printing']:
a3a04f
+            if param in ['printing', 'rpc server dynamic port range']:
a3a04f
                 continue
a3a04f
 
a3a04f
             section = None
a3a04f
diff --git a/source3/include/proto.h b/source3/include/proto.h
a3a04f
index 642900ed67c..b3d3ca0e5d1 100644
a3a04f
--- a/source3/include/proto.h
a3a04f
+++ b/source3/include/proto.h
a3a04f
@@ -889,6 +889,8 @@ int lp_client_ipc_signing(void);
a3a04f
 int lp_smb2_max_credits(void);
a3a04f
 int lp_cups_encrypt(void);
a3a04f
 bool lp_widelinks(int );
a3a04f
+int lp_rpc_low_port(void);
a3a04f
+int lp_rpc_high_port(void);
a3a04f
 
a3a04f
 int lp_wi_scan_global_parametrics(
a3a04f
 	const char *regex, size_t max_matches,
a3a04f
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
a3a04f
index d8da749ccba..2c8380067f6 100644
a3a04f
--- a/source3/param/loadparm.c
a3a04f
+++ b/source3/param/loadparm.c
a3a04f
@@ -933,6 +933,12 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
a3a04f
 
a3a04f
 	Globals.aio_max_threads = 100;
a3a04f
 
a3a04f
+	lpcfg_string_set(Globals.ctx,
a3a04f
+			 &Globals.rpc_server_dynamic_port_range,
a3a04f
+			 "49152-65535");
a3a04f
+	Globals.rpc_low_port = SERVER_TCP_LOW_PORT;
a3a04f
+	Globals.rpc_high_port = SERVER_TCP_HIGH_PORT;
a3a04f
+
a3a04f
 	/* Now put back the settings that were set with lp_set_cmdline() */
a3a04f
 	apply_lp_set_cmdline();
a3a04f
 }
a3a04f
@@ -4552,6 +4558,16 @@ int lp_client_ipc_signing(void)
a3a04f
 	return client_ipc_signing;
a3a04f
 }
a3a04f
 
a3a04f
+int lp_rpc_low_port(void)
a3a04f
+{
a3a04f
+	return Globals.rpc_low_port;
a3a04f
+}
a3a04f
+
a3a04f
+int lp_rpc_high_port(void)
a3a04f
+{
a3a04f
+	return Globals.rpc_high_port;
a3a04f
+}
a3a04f
+
a3a04f
 struct loadparm_global * get_globals(void)
a3a04f
 {
a3a04f
 	return &Globals;
a3a04f
diff --git a/source3/rpc_server/rpc_server.c b/source3/rpc_server/rpc_server.c
a3a04f
index 37fe68fc36d..f7fb8ef5207 100644
a3a04f
--- a/source3/rpc_server/rpc_server.c
a3a04f
+++ b/source3/rpc_server/rpc_server.c
a3a04f
@@ -34,9 +34,6 @@
a3a04f
 #include "rpc_server/srv_pipe_hnd.h"
a3a04f
 #include "rpc_server/srv_pipe.h"
a3a04f
 
a3a04f
-#define SERVER_TCP_LOW_PORT  49152
a3a04f
-#define SERVER_TCP_HIGH_PORT 65535
a3a04f
-
a3a04f
 /* Creates a pipes_struct and initializes it with the information
a3a04f
  * sent from the client */
a3a04f
 int make_server_pipes_struct(TALLOC_CTX *mem_ctx,
a3a04f
@@ -608,7 +605,7 @@ int create_tcpip_socket(const struct sockaddr_storage *ifss, uint16_t *port)
a3a04f
 	if (*port == 0) {
a3a04f
 		uint16_t i;
a3a04f
 
a3a04f
-		for (i = SERVER_TCP_LOW_PORT; i <= SERVER_TCP_HIGH_PORT; i++) {
a3a04f
+		for (i = lp_rpc_low_port(); i <= lp_rpc_high_port(); i++) {
a3a04f
 			fd = open_socket_in(SOCK_STREAM,
a3a04f
 					    i,
a3a04f
 					    0,
a3a04f
diff --git a/source4/smbd/service_stream.c b/source4/smbd/service_stream.c
a3a04f
index 96a303fc6a9..deb96d8d69d 100644
a3a04f
--- a/source4/smbd/service_stream.c
a3a04f
+++ b/source4/smbd/service_stream.c
a3a04f
@@ -29,10 +29,6 @@
a3a04f
 #include "../lib/tsocket/tsocket.h"
a3a04f
 #include "lib/util/util_net.h"
a3a04f
 
a3a04f
-/* the range of ports to try for dcerpc over tcp endpoints */
a3a04f
-#define SERVER_TCP_LOW_PORT  49152
a3a04f
-#define SERVER_TCP_HIGH_PORT 65535
a3a04f
-
a3a04f
 /* size of listen() backlog in smbd */
a3a04f
 #define SERVER_LISTEN_BACKLOG 10
a3a04f
 
a3a04f
@@ -331,7 +327,9 @@ NTSTATUS stream_setup_socket(TALLOC_CTX *mem_ctx,
a3a04f
 	if (!port) {
a3a04f
 		status = socket_listen(stream_socket->sock, socket_address, SERVER_LISTEN_BACKLOG, 0);
a3a04f
 	} else if (*port == 0) {
a3a04f
-		for (i=SERVER_TCP_LOW_PORT;i<= SERVER_TCP_HIGH_PORT;i++) {
a3a04f
+		for (i = lpcfg_rpc_low_port(lp_ctx);
a3a04f
+		     i <= lpcfg_rpc_high_port(lp_ctx);
a3a04f
+		     i++) {
a3a04f
 			socket_address->port = i;
a3a04f
 			status = socket_listen(stream_socket->sock, socket_address, 
a3a04f
 					       SERVER_LISTEN_BACKLOG, 0);
a3a04f
-- 
a3a04f
2.11.0
a3a04f