1
0

027-CVE-2016-2118-v3-6.patch 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. From d68424b5ef92f5810760f90e9eeb664572a61e4e Mon Sep 17 00:00:00 2001
  2. From: Stefan Metzmacher <metze@samba.org>
  3. Date: Tue, 15 Dec 2015 14:49:36 +0100
  4. Subject: [PATCH 01/10] CVE-2016-2118: s3: rpcclient: change the default auth
  5. level from DCERPC_AUTH_LEVEL_CONNECT to DCERPC_AUTH_LEVEL_INTEGRITY
  6. ncacn_ip_tcp:server should get the same protection as ncacn_np:server
  7. if authentication and smb signing is used.
  8. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616
  9. Signed-off-by: Stefan Metzmacher <metze@samba.org>
  10. (cherry picked from commit dab41dee8a4fb27dbf3913b0e44a4cc726e3ac98)
  11. ---
  12. source3/rpcclient/rpcclient.c | 5 ++---
  13. 1 file changed, 2 insertions(+), 3 deletions(-)
  14. --- a/source3/rpcclient/rpcclient.c
  15. +++ b/source3/rpcclient/rpcclient.c
  16. @@ -1062,10 +1062,9 @@ out_free:
  17. }
  18. }
  19. if (pipe_default_auth_type != DCERPC_AUTH_TYPE_NONE) {
  20. - /* If neither Integrity or Privacy are requested then
  21. - * Use just Connect level */
  22. + /* If nothing is requested then default to integrity */
  23. if (pipe_default_auth_level == DCERPC_AUTH_LEVEL_NONE) {
  24. - pipe_default_auth_level = DCERPC_AUTH_LEVEL_CONNECT;
  25. + pipe_default_auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
  26. }
  27. }
  28. --- a/source4/librpc/rpc/dcerpc_util.c
  29. +++ b/source4/librpc/rpc/dcerpc_util.c
  30. @@ -593,15 +593,15 @@ struct composite_context *dcerpc_pipe_au
  31. /* Perform an authenticated DCE-RPC bind
  32. */
  33. - if (!(conn->flags & (DCERPC_SIGN|DCERPC_SEAL))) {
  34. + if (!(conn->flags & (DCERPC_CONNECT|DCERPC_SEAL))) {
  35. /*
  36. we are doing an authenticated connection,
  37. - but not using sign or seal. We must force
  38. - the CONNECT dcerpc auth type as a NONE auth
  39. - type doesn't allow authentication
  40. - information to be passed.
  41. + which needs to use [connect], [sign] or [seal].
  42. + If nothing is specified, we default to [sign] now.
  43. + This give roughly the same protection as
  44. + ncacn_np with smb signing.
  45. */
  46. - conn->flags |= DCERPC_CONNECT;
  47. + conn->flags |= DCERPC_SIGN;
  48. }
  49. if (s->binding->flags & DCERPC_AUTH_SPNEGO) {
  50. --- /dev/null
  51. +++ b/docs-xml/smbdotconf/security/allowdcerpcauthlevelconnect.xml
  52. @@ -0,0 +1,22 @@
  53. +<samba:parameter name="allow dcerpc auth level connect"
  54. + context="G"
  55. + type="boolean"
  56. + xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
  57. +<description>
  58. + <para>This option controls whether DCERPC services are allowed to
  59. + be used with DCERPC_AUTH_LEVEL_CONNECT, which provides authentication,
  60. + but no per message integrity nor privacy protection.</para>
  61. +
  62. + <para>The behavior can be controlled per interface name (e.g. lsarpc, netlogon, samr, srvsvc,
  63. + winreg, wkssvc ...) by using 'allow dcerpc auth level connect:interface = no' as option.</para>
  64. +
  65. + <para>This option yields precedence to the implentation specific restrictions.
  66. + E.g. the drsuapi and backupkey protocols require DCERPC_AUTH_LEVEL_PRIVACY.
  67. + While others like samr and lsarpc have a hardcoded default of <constant>no</constant>.
  68. + </para>
  69. +</description>
  70. +
  71. +<value type="default">no</value>
  72. +<value type="example">yes</value>
  73. +
  74. +</samba:parameter>
  75. --- a/source3/include/proto.h
  76. +++ b/source3/include/proto.h
  77. @@ -1821,6 +1821,7 @@ char* lp_perfcount_module(void);
  78. void lp_set_passdb_backend(const char *backend);
  79. void widelinks_warning(int snum);
  80. char *lp_ncalrpc_dir(void);
  81. +bool lp_allow_dcerpc_auth_level_connect(void);
  82. /* The following definitions come from param/loadparm_server_role.c */
  83. --- a/source3/param/loadparm.c
  84. +++ b/source3/param/loadparm.c
  85. @@ -355,6 +355,7 @@ struct global {
  86. bool bUseMmap;
  87. bool bHostnameLookups;
  88. bool bUnixExtensions;
  89. + bool bAllowDcerpcAuthLevelConnect;
  90. bool bDisableNetbios;
  91. char * szDedicatedKeytabFile;
  92. int iKerberosMethod;
  93. @@ -2303,6 +2304,15 @@ static struct parm_struct parm_table[] =
  94. .flags = FLAG_ADVANCED,
  95. },
  96. {
  97. + .label = "allow dcerpc auth level connect",
  98. + .type = P_BOOL,
  99. + .p_class = P_GLOBAL,
  100. + .ptr = &Globals.bAllowDcerpcAuthLevelConnect,
  101. + .special = NULL,
  102. + .enum_list = NULL,
  103. + .flags = FLAG_ADVANCED,
  104. + },
  105. + {
  106. .label = "use spnego",
  107. .type = P_BOOL,
  108. .p_class = P_GLOBAL,
  109. @@ -5371,6 +5381,8 @@ static void init_globals(bool reinit_glo
  110. Globals.bClientNTLMv2Auth = True; /* Client should always use use NTLMv2, as we can't tell that the server supports it, but most modern servers do */
  111. /* Note, that we will also use NTLM2 session security (which is different), if it is available */
  112. + Globals.bAllowDcerpcAuthLevelConnect = false; /* we don't allow this by default */
  113. +
  114. Globals.map_to_guest = 0; /* By Default, "Never" */
  115. Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
  116. Globals.enhanced_browsing = true;
  117. @@ -5745,6 +5757,7 @@ FN_GLOBAL_INTEGER(lp_username_map_cache_
  118. FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
  119. +FN_GLOBAL_BOOL(lp_allow_dcerpc_auth_level_connect, &Globals.bAllowDcerpcAuthLevelConnect)
  120. FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
  121. FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
  122. FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
  123. --- a/source3/include/ntdomain.h
  124. +++ b/source3/include/ntdomain.h
  125. @@ -89,6 +89,10 @@ typedef struct pipe_rpc_fns {
  126. uint32 context_id;
  127. struct ndr_syntax_id syntax;
  128. + /*
  129. + * shall we allow "connect" auth level for this interface ?
  130. + */
  131. + bool allow_connect;
  132. } PIPE_RPC_FNS;
  133. /*
  134. --- a/source3/rpc_server/srv_pipe.c
  135. +++ b/source3/rpc_server/srv_pipe.c
  136. @@ -44,6 +44,11 @@
  137. #include "rpc_server/srv_pipe.h"
  138. #include "../librpc/gen_ndr/ndr_dcerpc.h"
  139. #include "../librpc/ndr/ndr_dcerpc.h"
  140. +#include "../librpc/gen_ndr/ndr_samr.h"
  141. +#include "../librpc/gen_ndr/ndr_lsa.h"
  142. +#include "../librpc/gen_ndr/ndr_netlogon.h"
  143. +#include "../librpc/gen_ndr/ndr_epmapper.h"
  144. +#include "../librpc/gen_ndr/ndr_echo.h"
  145. #undef DBGC_CLASS
  146. #define DBGC_CLASS DBGC_RPC_SRV
  147. @@ -340,6 +345,8 @@ static bool check_bind_req(struct pipes_
  148. uint32 context_id)
  149. {
  150. struct pipe_rpc_fns *context_fns;
  151. + const char *interface_name = NULL;
  152. + bool ok;
  153. DEBUG(3,("check_bind_req for %s\n",
  154. get_pipe_name_from_syntax(talloc_tos(), abstract)));
  155. @@ -390,12 +397,57 @@ static bool check_bind_req(struct pipes_
  156. return False;
  157. }
  158. + interface_name = get_pipe_name_from_syntax(talloc_tos(),
  159. + abstract);
  160. +
  161. + SMB_ASSERT(interface_name != NULL);
  162. +
  163. context_fns->next = context_fns->prev = NULL;
  164. context_fns->n_cmds = rpc_srv_get_pipe_num_cmds(abstract);
  165. context_fns->cmds = rpc_srv_get_pipe_cmds(abstract);
  166. context_fns->context_id = context_id;
  167. context_fns->syntax = *abstract;
  168. + context_fns->allow_connect = lp_allow_dcerpc_auth_level_connect();
  169. + /*
  170. + * for the samr and the lsarpc interfaces we don't allow "connect"
  171. + * auth_level by default.
  172. + */
  173. + ok = ndr_syntax_id_equal(abstract, &ndr_table_samr.syntax_id);
  174. + if (ok) {
  175. + context_fns->allow_connect = false;
  176. + }
  177. + ok = ndr_syntax_id_equal(abstract, &ndr_table_lsarpc.syntax_id);
  178. + if (ok) {
  179. + context_fns->allow_connect = false;
  180. + }
  181. + ok = ndr_syntax_id_equal(abstract, &ndr_table_netlogon.syntax_id);
  182. + if (ok) {
  183. + context_fns->allow_connect = false;
  184. + }
  185. + /*
  186. + * for the epmapper and echo interfaces we allow "connect"
  187. + * auth_level by default.
  188. + */
  189. + ok = ndr_syntax_id_equal(abstract, &ndr_table_epmapper.syntax_id);
  190. + if (ok) {
  191. + context_fns->allow_connect = true;
  192. + }
  193. + ok = ndr_syntax_id_equal(abstract, &ndr_table_rpcecho.syntax_id);
  194. + if (ok) {
  195. + context_fns->allow_connect = true;
  196. + }
  197. + /*
  198. + * every interface can be modified to allow "connect" auth_level by
  199. + * using a parametric option like:
  200. + * allow dcerpc auth level connect:<interface>
  201. + * e.g.
  202. + * allow dcerpc auth level connect:samr = yes
  203. + */
  204. + context_fns->allow_connect = lp_parm_bool(-1,
  205. + "allow dcerpc auth level connect",
  206. + interface_name, context_fns->allow_connect);
  207. +
  208. /* add to the list of open contexts */
  209. DLIST_ADD( p->contexts, context_fns );
  210. @@ -1736,6 +1788,7 @@ static bool api_pipe_request(struct pipe
  211. TALLOC_CTX *frame = talloc_stackframe();
  212. bool ret = False;
  213. PIPE_RPC_FNS *pipe_fns;
  214. + const char *interface_name = NULL;
  215. if (!p->pipe_bound) {
  216. DEBUG(1, ("Pipe not bound!\n"));
  217. @@ -1757,8 +1810,36 @@ static bool api_pipe_request(struct pipe
  218. return false;
  219. }
  220. + interface_name = get_pipe_name_from_syntax(talloc_tos(),
  221. + &pipe_fns->syntax);
  222. +
  223. + SMB_ASSERT(interface_name != NULL);
  224. +
  225. DEBUG(5, ("Requested \\PIPE\\%s\n",
  226. - get_pipe_name_from_syntax(talloc_tos(), &pipe_fns->syntax)));
  227. + interface_name));
  228. +
  229. + switch (p->auth.auth_level) {
  230. + case DCERPC_AUTH_LEVEL_NONE:
  231. + case DCERPC_AUTH_LEVEL_INTEGRITY:
  232. + case DCERPC_AUTH_LEVEL_PRIVACY:
  233. + break;
  234. + default:
  235. + if (!pipe_fns->allow_connect) {
  236. + DEBUG(1, ("%s: restrict auth_level_connect access "
  237. + "to [%s] with auth[type=0x%x,level=0x%x] "
  238. + "on [%s] from [%s]\n",
  239. + __func__, interface_name,
  240. + p->auth.auth_type,
  241. + p->auth.auth_level,
  242. + derpc_transport_string_by_transport(p->transport),
  243. + p->client_id->name));
  244. +
  245. + setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_ACCESS_DENIED));
  246. + TALLOC_FREE(frame);
  247. + return true;
  248. + }
  249. + break;
  250. + }
  251. if (!srv_pipe_check_verification_trailer(p, pkt, pipe_fns)) {
  252. DEBUG(1, ("srv_pipe_check_verification_trailer: failed\n"));
  253. --- a/source3/selftest/knownfail
  254. +++ b/source3/selftest/knownfail
  255. @@ -18,3 +18,5 @@ samba3.posix_s3.nbt.dgram.*netlogon2
  256. samba3.*rap.sam.*.useradd # Not provided by Samba 3
  257. samba3.*rap.sam.*.userdelete # Not provided by Samba 3
  258. samba3.*rap.basic.*.netsessiongetinfo # Not provided by Samba 3
  259. +samba3.blackbox.rpcclient.over.ncacn_np.with.*connect.* # we don't allow auth_level_connect anymore
  260. +samba3.posix_s3.rpc.lsa.lookupsids.*ncacn_ip_tcp.*connect.* # we don't allow auth_level_connect anymore
  261. --- a/source3/selftest/tests.py
  262. +++ b/source3/selftest/tests.py
  263. @@ -201,6 +201,8 @@ if sub.returncode == 0:
  264. plansmbtorturetestsuite(t, "s3dc", '//$SERVER_IP/tmpguest -U$USERNAME%$PASSWORD')
  265. elif t == "raw.samba3posixtimedlock":
  266. plansmbtorturetestsuite(t, "s3dc", '//$SERVER_IP/tmpguest -U$USERNAME%$PASSWORD --option=torture:localdir=$SELFTEST_PREFIX/dc/share')
  267. + elif t == "rpc.samr.passwords.validate":
  268. + plansmbtorturetestsuite(t, "s3dc", 'ncacn_np:$SERVER_IP[seal] -U$USERNAME%$PASSWORD', 'over ncacn_np ')
  269. else:
  270. plansmbtorturetestsuite(t, "s3dc", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD')
  271. --- a/source3/rpc_server/samr/srv_samr_nt.c
  272. +++ b/source3/rpc_server/samr/srv_samr_nt.c
  273. @@ -6628,6 +6628,11 @@ NTSTATUS _samr_ValidatePassword(struct p
  274. struct samr_GetDomPwInfo pw;
  275. struct samr_PwInfo dom_pw_info;
  276. + if (p->auth.auth_level != DCERPC_AUTH_LEVEL_PRIVACY) {
  277. + p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
  278. + return NT_STATUS_ACCESS_DENIED;
  279. + }
  280. +
  281. if (r->in.level < 1 || r->in.level > 3) {
  282. return NT_STATUS_INVALID_INFO_CLASS;
  283. }