OpenWrt – Blame information for rev 4
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
4 | office | 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 | } |