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