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