diff options
Diffstat (limited to 'package/network/services/samba36/patches/027-CVE-2016-2118-v3-6.patch')
-rw-r--r-- | package/network/services/samba36/patches/027-CVE-2016-2118-v3-6.patch | 308 |
1 files changed, 308 insertions, 0 deletions
diff --git a/package/network/services/samba36/patches/027-CVE-2016-2118-v3-6.patch b/package/network/services/samba36/patches/027-CVE-2016-2118-v3-6.patch new file mode 100644 index 0000000000..06c1b0b521 --- /dev/null +++ b/package/network/services/samba36/patches/027-CVE-2016-2118-v3-6.patch @@ -0,0 +1,308 @@ +From d68424b5ef92f5810760f90e9eeb664572a61e4e Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher <metze@samba.org> +Date: Tue, 15 Dec 2015 14:49:36 +0100 +Subject: [PATCH 01/10] CVE-2016-2118: s3: rpcclient: change the default auth + level from DCERPC_AUTH_LEVEL_CONNECT to DCERPC_AUTH_LEVEL_INTEGRITY + +ncacn_ip_tcp:server should get the same protection as ncacn_np:server +if authentication and smb signing is used. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616 + +Signed-off-by: Stefan Metzmacher <metze@samba.org> + +(cherry picked from commit dab41dee8a4fb27dbf3913b0e44a4cc726e3ac98) +--- + source3/rpcclient/rpcclient.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/source3/rpcclient/rpcclient.c ++++ b/source3/rpcclient/rpcclient.c +@@ -1062,10 +1062,9 @@ out_free: + } + } + if (pipe_default_auth_type != DCERPC_AUTH_TYPE_NONE) { +- /* If neither Integrity or Privacy are requested then +- * Use just Connect level */ ++ /* If nothing is requested then default to integrity */ + if (pipe_default_auth_level == DCERPC_AUTH_LEVEL_NONE) { +- pipe_default_auth_level = DCERPC_AUTH_LEVEL_CONNECT; ++ pipe_default_auth_level = DCERPC_AUTH_LEVEL_INTEGRITY; + } + } + +--- a/source4/librpc/rpc/dcerpc_util.c ++++ b/source4/librpc/rpc/dcerpc_util.c +@@ -593,15 +593,15 @@ struct composite_context *dcerpc_pipe_au + + /* Perform an authenticated DCE-RPC bind + */ +- if (!(conn->flags & (DCERPC_SIGN|DCERPC_SEAL))) { ++ if (!(conn->flags & (DCERPC_CONNECT|DCERPC_SEAL))) { + /* + we are doing an authenticated connection, +- but not using sign or seal. We must force +- the CONNECT dcerpc auth type as a NONE auth +- type doesn't allow authentication +- information to be passed. ++ which needs to use [connect], [sign] or [seal]. ++ If nothing is specified, we default to [sign] now. ++ This give roughly the same protection as ++ ncacn_np with smb signing. + */ +- conn->flags |= DCERPC_CONNECT; ++ conn->flags |= DCERPC_SIGN; + } + + if (s->binding->flags & DCERPC_AUTH_SPNEGO) { +--- /dev/null ++++ b/docs-xml/smbdotconf/security/allowdcerpcauthlevelconnect.xml +@@ -0,0 +1,22 @@ ++<samba:parameter name="allow dcerpc auth level connect" ++ context="G" ++ type="boolean" ++ xmlns:samba="http://www.samba.org/samba/DTD/samba-doc"> ++<description> ++ <para>This option controls whether DCERPC services are allowed to ++ be used with DCERPC_AUTH_LEVEL_CONNECT, which provides authentication, ++ but no per message integrity nor privacy protection.</para> ++ ++ <para>The behavior can be controlled per interface name (e.g. lsarpc, netlogon, samr, srvsvc, ++ winreg, wkssvc ...) by using 'allow dcerpc auth level connect:interface = no' as option.</para> ++ ++ <para>This option yields precedence to the implentation specific restrictions. ++ E.g. the drsuapi and backupkey protocols require DCERPC_AUTH_LEVEL_PRIVACY. ++ While others like samr and lsarpc have a hardcoded default of <constant>no</constant>. ++ </para> ++</description> ++ ++<value type="default">no</value> ++<value type="example">yes</value> ++ ++</samba:parameter> +--- a/source3/include/proto.h ++++ b/source3/include/proto.h +@@ -1821,6 +1821,7 @@ char* lp_perfcount_module(void); + void lp_set_passdb_backend(const char *backend); + void widelinks_warning(int snum); + char *lp_ncalrpc_dir(void); ++bool lp_allow_dcerpc_auth_level_connect(void); + + /* The following definitions come from param/loadparm_server_role.c */ + +--- a/source3/param/loadparm.c ++++ b/source3/param/loadparm.c +@@ -355,6 +355,7 @@ struct global { + bool bUseMmap; + bool bHostnameLookups; + bool bUnixExtensions; ++ bool bAllowDcerpcAuthLevelConnect; + bool bDisableNetbios; + char * szDedicatedKeytabFile; + int iKerberosMethod; +@@ -2303,6 +2304,15 @@ static struct parm_struct parm_table[] = + .flags = FLAG_ADVANCED, + }, + { ++ .label = "allow dcerpc auth level connect", ++ .type = P_BOOL, ++ .p_class = P_GLOBAL, ++ .ptr = &Globals.bAllowDcerpcAuthLevelConnect, ++ .special = NULL, ++ .enum_list = NULL, ++ .flags = FLAG_ADVANCED, ++ }, ++ { + .label = "use spnego", + .type = P_BOOL, + .p_class = P_GLOBAL, +@@ -5371,6 +5381,8 @@ static void init_globals(bool reinit_glo + Globals.bClientNTLMv2Auth = True; /* Client should always use use NTLMv2, as we can't tell that the server supports it, but most modern servers do */ + /* Note, that we will also use NTLM2 session security (which is different), if it is available */ + ++ Globals.bAllowDcerpcAuthLevelConnect = false; /* we don't allow this by default */ ++ + Globals.map_to_guest = 0; /* By Default, "Never" */ + Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */ + Globals.enhanced_browsing = true; +@@ -5745,6 +5757,7 @@ FN_GLOBAL_INTEGER(lp_username_map_cache_ + + FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript) + ++FN_GLOBAL_BOOL(lp_allow_dcerpc_auth_level_connect, &Globals.bAllowDcerpcAuthLevelConnect) + FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook) + FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir) + FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell) +--- a/source3/include/ntdomain.h ++++ b/source3/include/ntdomain.h +@@ -89,6 +89,10 @@ typedef struct pipe_rpc_fns { + uint32 context_id; + struct ndr_syntax_id syntax; + ++ /* ++ * shall we allow "connect" auth level for this interface ? ++ */ ++ bool allow_connect; + } PIPE_RPC_FNS; + + /* +--- a/source3/rpc_server/srv_pipe.c ++++ b/source3/rpc_server/srv_pipe.c +@@ -44,6 +44,11 @@ + #include "rpc_server/srv_pipe.h" + #include "../librpc/gen_ndr/ndr_dcerpc.h" + #include "../librpc/ndr/ndr_dcerpc.h" ++#include "../librpc/gen_ndr/ndr_samr.h" ++#include "../librpc/gen_ndr/ndr_lsa.h" ++#include "../librpc/gen_ndr/ndr_netlogon.h" ++#include "../librpc/gen_ndr/ndr_epmapper.h" ++#include "../librpc/gen_ndr/ndr_echo.h" + + #undef DBGC_CLASS + #define DBGC_CLASS DBGC_RPC_SRV +@@ -340,6 +345,8 @@ static bool check_bind_req(struct pipes_ + uint32 context_id) + { + struct pipe_rpc_fns *context_fns; ++ const char *interface_name = NULL; ++ bool ok; + + DEBUG(3,("check_bind_req for %s\n", + get_pipe_name_from_syntax(talloc_tos(), abstract))); +@@ -390,12 +397,57 @@ static bool check_bind_req(struct pipes_ + return False; + } + ++ interface_name = get_pipe_name_from_syntax(talloc_tos(), ++ abstract); ++ ++ SMB_ASSERT(interface_name != NULL); ++ + context_fns->next = context_fns->prev = NULL; + context_fns->n_cmds = rpc_srv_get_pipe_num_cmds(abstract); + context_fns->cmds = rpc_srv_get_pipe_cmds(abstract); + context_fns->context_id = context_id; + context_fns->syntax = *abstract; + ++ context_fns->allow_connect = lp_allow_dcerpc_auth_level_connect(); ++ /* ++ * for the samr and the lsarpc interfaces we don't allow "connect" ++ * auth_level by default. ++ */ ++ ok = ndr_syntax_id_equal(abstract, &ndr_table_samr.syntax_id); ++ if (ok) { ++ context_fns->allow_connect = false; ++ } ++ ok = ndr_syntax_id_equal(abstract, &ndr_table_lsarpc.syntax_id); ++ if (ok) { ++ context_fns->allow_connect = false; ++ } ++ ok = ndr_syntax_id_equal(abstract, &ndr_table_netlogon.syntax_id); ++ if (ok) { ++ context_fns->allow_connect = false; ++ } ++ /* ++ * for the epmapper and echo interfaces we allow "connect" ++ * auth_level by default. ++ */ ++ ok = ndr_syntax_id_equal(abstract, &ndr_table_epmapper.syntax_id); ++ if (ok) { ++ context_fns->allow_connect = true; ++ } ++ ok = ndr_syntax_id_equal(abstract, &ndr_table_rpcecho.syntax_id); ++ if (ok) { ++ context_fns->allow_connect = true; ++ } ++ /* ++ * every interface can be modified to allow "connect" auth_level by ++ * using a parametric option like: ++ * allow dcerpc auth level connect:<interface> ++ * e.g. ++ * allow dcerpc auth level connect:samr = yes ++ */ ++ context_fns->allow_connect = lp_parm_bool(-1, ++ "allow dcerpc auth level connect", ++ interface_name, context_fns->allow_connect); ++ + /* add to the list of open contexts */ + + DLIST_ADD( p->contexts, context_fns ); +@@ -1736,6 +1788,7 @@ static bool api_pipe_request(struct pipe + TALLOC_CTX *frame = talloc_stackframe(); + bool ret = False; + PIPE_RPC_FNS *pipe_fns; ++ const char *interface_name = NULL; + + if (!p->pipe_bound) { + DEBUG(1, ("Pipe not bound!\n")); +@@ -1757,8 +1810,36 @@ static bool api_pipe_request(struct pipe + return false; + } + ++ interface_name = get_pipe_name_from_syntax(talloc_tos(), ++ &pipe_fns->syntax); ++ ++ SMB_ASSERT(interface_name != NULL); ++ + DEBUG(5, ("Requested \\PIPE\\%s\n", +- get_pipe_name_from_syntax(talloc_tos(), &pipe_fns->syntax))); ++ interface_name)); ++ ++ switch (p->auth.auth_level) { ++ case DCERPC_AUTH_LEVEL_NONE: ++ case DCERPC_AUTH_LEVEL_INTEGRITY: ++ case DCERPC_AUTH_LEVEL_PRIVACY: ++ break; ++ default: ++ if (!pipe_fns->allow_connect) { ++ DEBUG(1, ("%s: restrict auth_level_connect access " ++ "to [%s] with auth[type=0x%x,level=0x%x] " ++ "on [%s] from [%s]\n", ++ __func__, interface_name, ++ p->auth.auth_type, ++ p->auth.auth_level, ++ derpc_transport_string_by_transport(p->transport), ++ p->client_id->name)); ++ ++ setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_ACCESS_DENIED)); ++ TALLOC_FREE(frame); ++ return true; ++ } ++ break; ++ } + + if (!srv_pipe_check_verification_trailer(p, pkt, pipe_fns)) { + DEBUG(1, ("srv_pipe_check_verification_trailer: failed\n")); +--- a/source3/selftest/knownfail ++++ b/source3/selftest/knownfail +@@ -18,3 +18,5 @@ samba3.posix_s3.nbt.dgram.*netlogon2 + samba3.*rap.sam.*.useradd # Not provided by Samba 3 + samba3.*rap.sam.*.userdelete # Not provided by Samba 3 + samba3.*rap.basic.*.netsessiongetinfo # Not provided by Samba 3 ++samba3.blackbox.rpcclient.over.ncacn_np.with.*connect.* # we don't allow auth_level_connect anymore ++samba3.posix_s3.rpc.lsa.lookupsids.*ncacn_ip_tcp.*connect.* # we don't allow auth_level_connect anymore +--- a/source3/selftest/tests.py ++++ b/source3/selftest/tests.py +@@ -201,6 +201,8 @@ if sub.returncode == 0: + plansmbtorturetestsuite(t, "s3dc", '//$SERVER_IP/tmpguest -U$USERNAME%$PASSWORD') + elif t == "raw.samba3posixtimedlock": + plansmbtorturetestsuite(t, "s3dc", '//$SERVER_IP/tmpguest -U$USERNAME%$PASSWORD --option=torture:localdir=$SELFTEST_PREFIX/dc/share') ++ elif t == "rpc.samr.passwords.validate": ++ plansmbtorturetestsuite(t, "s3dc", 'ncacn_np:$SERVER_IP[seal] -U$USERNAME%$PASSWORD', 'over ncacn_np ') + else: + plansmbtorturetestsuite(t, "s3dc", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD') + +--- a/source3/rpc_server/samr/srv_samr_nt.c ++++ b/source3/rpc_server/samr/srv_samr_nt.c +@@ -6628,6 +6628,11 @@ NTSTATUS _samr_ValidatePassword(struct p + struct samr_GetDomPwInfo pw; + struct samr_PwInfo dom_pw_info; + ++ if (p->auth.auth_level != DCERPC_AUTH_LEVEL_PRIVACY) { ++ p->fault_state = DCERPC_FAULT_ACCESS_DENIED; ++ return NT_STATUS_ACCESS_DENIED; ++ } ++ + if (r->in.level < 1 || r->in.level > 3) { + return NT_STATUS_INVALID_INFO_CLASS; + } |