Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : negprot reply code
4 : Copyright (C) Andrew Tridgell 1992-1998
5 : Copyright (C) Volker Lendecke 2007
6 :
7 : This program is free software; you can redistribute it and/or modify
8 : it under the terms of the GNU General Public License as published by
9 : the Free Software Foundation; either version 3 of the License, or
10 : (at your option) any later version.
11 :
12 : This program is distributed in the hope that it will be useful,
13 : but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : GNU General Public License for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with this program. If not, see <http://www.gnu.org/licenses/>.
19 : */
20 :
21 : #include "includes.h"
22 : #include "smbd/smbd.h"
23 : #include "smbd/globals.h"
24 : #include "serverid.h"
25 : #include "auth.h"
26 : #include "messages.h"
27 : #include "smbprofile.h"
28 : #include "auth/gensec/gensec.h"
29 : #include "../libcli/smb/smb_signing.h"
30 : #include "lib/util/string_wrappers.h"
31 : #include "source3/lib/substitute.h"
32 :
33 : /*
34 : * MS-CIFS, 2.2.4.52.2 SMB_COM_NEGOTIATE Response:
35 : * If the server does not support any of the listed dialects, it MUST return a
36 : * DialectIndex of 0XFFFF
37 : */
38 : #define NO_PROTOCOL_CHOSEN 0xffff
39 :
40 98 : static void get_challenge(struct smbXsrv_connection *xconn, uint8_t buff[8])
41 : {
42 0 : NTSTATUS nt_status;
43 :
44 : /* We might be called more than once, multiple negprots are
45 : * permitted */
46 98 : if (xconn->smb1.negprot.auth_context) {
47 0 : DEBUG(3, ("get challenge: is this a secondary negprot? "
48 : "sconn->negprot.auth_context is non-NULL!\n"));
49 0 : TALLOC_FREE(xconn->smb1.negprot.auth_context);
50 : }
51 :
52 98 : DEBUG(10, ("get challenge: creating negprot_global_auth_context\n"));
53 98 : nt_status = make_auth4_context(
54 : xconn, &xconn->smb1.negprot.auth_context);
55 98 : if (!NT_STATUS_IS_OK(nt_status)) {
56 0 : DEBUG(0, ("make_auth_context_subsystem returned %s\n",
57 : nt_errstr(nt_status)));
58 0 : smb_panic("cannot make_negprot_global_auth_context!");
59 : }
60 98 : DEBUG(10, ("get challenge: getting challenge\n"));
61 98 : xconn->smb1.negprot.auth_context->get_ntlm_challenge(
62 : xconn->smb1.negprot.auth_context, buff);
63 98 : }
64 :
65 : /****************************************************************************
66 : Reply for the lanman 1.0 protocol.
67 : ****************************************************************************/
68 :
69 2 : static NTSTATUS reply_lanman1(struct smb_request *req, uint16_t choice)
70 : {
71 2 : int secword=0;
72 2 : time_t t = time(NULL);
73 2 : struct smbXsrv_connection *xconn = req->xconn;
74 0 : uint16_t raw;
75 0 : NTSTATUS status;
76 :
77 2 : if (lp_async_smb_echo_handler()) {
78 0 : raw = 0;
79 : } else {
80 2 : raw = (lp_read_raw()?1:0) | (lp_write_raw()?2:0);
81 : }
82 :
83 2 : xconn->smb1.negprot.encrypted_passwords = lp_encrypt_passwords();
84 :
85 2 : secword |= NEGOTIATE_SECURITY_USER_LEVEL;
86 2 : if (xconn->smb1.negprot.encrypted_passwords) {
87 2 : secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
88 : }
89 :
90 2 : reply_smb1_outbuf(req, 13, xconn->smb1.negprot.encrypted_passwords?8:0);
91 :
92 2 : SSVAL(req->outbuf,smb_vwv0,choice);
93 2 : SSVAL(req->outbuf,smb_vwv1,secword);
94 : /* Create a token value and add it to the outgoing packet. */
95 2 : if (xconn->smb1.negprot.encrypted_passwords) {
96 2 : get_challenge(xconn, (uint8_t *)smb_buf(req->outbuf));
97 2 : SSVAL(req->outbuf,smb_vwv11, 8);
98 : }
99 :
100 2 : status = smbXsrv_connection_init_tables(xconn, PROTOCOL_LANMAN1);
101 2 : if (!NT_STATUS_IS_OK(status)) {
102 0 : reply_nterror(req, status);
103 0 : return status;
104 : }
105 :
106 : /* Reply, SMBlockread, SMBwritelock supported. */
107 2 : SCVAL(req->outbuf,smb_flg, FLAG_REPLY|FLAG_SUPPORT_LOCKREAD);
108 2 : SSVAL(req->outbuf,smb_vwv2, xconn->smb1.negprot.max_recv);
109 2 : SSVAL(req->outbuf,smb_vwv3, lp_max_mux()); /* maxmux */
110 2 : SSVAL(req->outbuf,smb_vwv4, 1);
111 2 : SSVAL(req->outbuf,smb_vwv5, raw); /* tell redirector we support
112 : readbraw writebraw (possibly) */
113 2 : SIVAL(req->outbuf,smb_vwv6, getpid());
114 2 : SSVAL(req->outbuf,smb_vwv10, set_server_zone_offset(t)/60);
115 :
116 2 : srv_put_dos_date((char *)req->outbuf,smb_vwv8,t);
117 :
118 2 : return NT_STATUS_OK;
119 : }
120 :
121 : /****************************************************************************
122 : Reply for the lanman 2.0 protocol.
123 : ****************************************************************************/
124 :
125 22 : static NTSTATUS reply_lanman2(struct smb_request *req, uint16_t choice)
126 : {
127 22 : int secword=0;
128 22 : time_t t = time(NULL);
129 22 : struct smbXsrv_connection *xconn = req->xconn;
130 0 : uint16_t raw;
131 0 : NTSTATUS status;
132 :
133 22 : if (lp_async_smb_echo_handler()) {
134 0 : raw = 0;
135 : } else {
136 22 : raw = (lp_read_raw()?1:0) | (lp_write_raw()?2:0);
137 : }
138 :
139 22 : xconn->smb1.negprot.encrypted_passwords = lp_encrypt_passwords();
140 :
141 22 : secword |= NEGOTIATE_SECURITY_USER_LEVEL;
142 22 : if (xconn->smb1.negprot.encrypted_passwords) {
143 22 : secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
144 : }
145 :
146 22 : reply_smb1_outbuf(req, 13, xconn->smb1.negprot.encrypted_passwords?8:0);
147 :
148 22 : SSVAL(req->outbuf,smb_vwv0, choice);
149 22 : SSVAL(req->outbuf,smb_vwv1, secword);
150 22 : SIVAL(req->outbuf,smb_vwv6, getpid());
151 :
152 : /* Create a token value and add it to the outgoing packet. */
153 22 : if (xconn->smb1.negprot.encrypted_passwords) {
154 22 : get_challenge(xconn, (uint8_t *)smb_buf(req->outbuf));
155 22 : SSVAL(req->outbuf,smb_vwv11, 8);
156 : }
157 :
158 22 : status = smbXsrv_connection_init_tables(xconn, PROTOCOL_LANMAN2);
159 22 : if (!NT_STATUS_IS_OK(status)) {
160 0 : reply_nterror(req, status);
161 0 : return status;
162 : }
163 :
164 : /* Reply, SMBlockread, SMBwritelock supported. */
165 22 : SCVAL(req->outbuf,smb_flg,FLAG_REPLY|FLAG_SUPPORT_LOCKREAD);
166 22 : SSVAL(req->outbuf,smb_vwv2,xconn->smb1.negprot.max_recv);
167 22 : SSVAL(req->outbuf,smb_vwv3,lp_max_mux());
168 22 : SSVAL(req->outbuf,smb_vwv4,1);
169 22 : SSVAL(req->outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
170 22 : SSVAL(req->outbuf,smb_vwv10, set_server_zone_offset(t)/60);
171 22 : srv_put_dos_date((char *)req->outbuf,smb_vwv8,t);
172 22 : return NT_STATUS_OK;
173 : }
174 :
175 : /****************************************************************************
176 : Reply for the nt protocol.
177 : ****************************************************************************/
178 :
179 5753 : static NTSTATUS reply_nt1(struct smb_request *req, uint16_t choice)
180 : {
181 : /* dual names + lock_and_read + nt SMBs + remote API calls */
182 5753 : int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ|
183 : CAP_LEVEL_II_OPLOCKS;
184 :
185 5753 : int secword=0;
186 5753 : bool negotiate_spnego = False;
187 133 : struct timespec ts;
188 133 : ssize_t ret;
189 5753 : struct smbXsrv_connection *xconn = req->xconn;
190 5753 : bool signing_desired = false;
191 5753 : bool signing_required = false;
192 133 : NTSTATUS status;
193 :
194 5753 : xconn->smb1.negprot.encrypted_passwords = lp_encrypt_passwords();
195 :
196 : /* Check the flags field to see if this is Vista.
197 : WinXP sets it and Vista does not. But we have to
198 : distinguish from NT which doesn't set it either. */
199 :
200 5753 : if ( (req->flags2 & FLAGS2_EXTENDED_SECURITY) &&
201 5546 : ((req->flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED) == 0) )
202 : {
203 5759 : if ((get_remote_arch() != RA_SAMBA) &&
204 80 : (get_remote_arch() != RA_CIFSFS)) {
205 0 : set_remote_arch( RA_VISTA );
206 : }
207 : }
208 :
209 5753 : reply_smb1_outbuf(req,17,0);
210 :
211 : /* do spnego in user level security if the client
212 : supports it and we can do encrypted passwords */
213 :
214 5753 : if (xconn->smb1.negprot.encrypted_passwords &&
215 5753 : (req->flags2 & FLAGS2_EXTENDED_SECURITY)) {
216 5679 : negotiate_spnego = True;
217 5679 : capabilities |= CAP_EXTENDED_SECURITY;
218 5679 : add_to_common_flags2(FLAGS2_EXTENDED_SECURITY);
219 : /* Ensure FLAGS2_EXTENDED_SECURITY gets set in this reply
220 : (already partially constructed. */
221 5679 : SSVAL(req->outbuf, smb_flg2,
222 : req->flags2 | FLAGS2_EXTENDED_SECURITY);
223 : }
224 :
225 5753 : capabilities |= CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
226 :
227 5753 : if (lp_unicode()) {
228 5753 : capabilities |= CAP_UNICODE;
229 : }
230 :
231 5753 : if (lp_smb1_unix_extensions()) {
232 5753 : capabilities |= CAP_UNIX;
233 : }
234 :
235 5753 : if (lp_large_readwrite())
236 5753 : capabilities |= CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_W2K_SMBS;
237 :
238 5753 : capabilities |= CAP_LARGE_FILES;
239 :
240 5753 : if (!lp_async_smb_echo_handler() && lp_read_raw() && lp_write_raw())
241 5753 : capabilities |= CAP_RAW_MODE;
242 :
243 5753 : if (lp_nt_status_support())
244 5753 : capabilities |= CAP_STATUS32;
245 :
246 5753 : if (lp_host_msdfs())
247 5753 : capabilities |= CAP_DFS;
248 :
249 5753 : secword |= NEGOTIATE_SECURITY_USER_LEVEL;
250 5753 : if (xconn->smb1.negprot.encrypted_passwords) {
251 5753 : secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
252 : }
253 :
254 5753 : signing_desired = smb1_signing_is_desired(xconn->smb1.signing_state);
255 5753 : signing_required = smb1_signing_is_mandatory(xconn->smb1.signing_state);
256 :
257 5753 : if (signing_desired) {
258 811 : secword |= NEGOTIATE_SECURITY_SIGNATURES_ENABLED;
259 : /* No raw mode with smb signing. */
260 811 : capabilities &= ~CAP_RAW_MODE;
261 811 : if (signing_required) {
262 811 : secword |=NEGOTIATE_SECURITY_SIGNATURES_REQUIRED;
263 : }
264 : }
265 :
266 5753 : SSVAL(req->outbuf,smb_vwv0,choice);
267 5753 : SCVAL(req->outbuf,smb_vwv1,secword);
268 :
269 5753 : status = smbXsrv_connection_init_tables(xconn, PROTOCOL_NT1);
270 5753 : if (!NT_STATUS_IS_OK(status)) {
271 0 : reply_nterror(req, status);
272 0 : return status;
273 : }
274 :
275 5753 : SSVAL(req->outbuf,smb_vwv1+1, lp_max_mux()); /* maxmpx */
276 5753 : SSVAL(req->outbuf,smb_vwv2+1, 1); /* num vcs */
277 5753 : SIVAL(req->outbuf,smb_vwv3+1,
278 : xconn->smb1.negprot.max_recv); /* max buffer. LOTS! */
279 5753 : SIVAL(req->outbuf,smb_vwv5+1, 0x10000); /* raw size. full 64k */
280 5753 : SIVAL(req->outbuf,smb_vwv7+1, getpid()); /* session key */
281 5753 : SIVAL(req->outbuf,smb_vwv9+1, capabilities); /* capabilities */
282 5753 : clock_gettime(CLOCK_REALTIME,&ts);
283 5753 : put_long_date_full_timespec(TIMESTAMP_SET_NT_OR_BETTER,(char *)req->outbuf+smb_vwv11+1,&ts);
284 5753 : SSVALS(req->outbuf,smb_vwv15+1,set_server_zone_offset(ts.tv_sec)/60);
285 :
286 5753 : if (!negotiate_spnego) {
287 : /* Create a token value and add it to the outgoing packet. */
288 74 : if (xconn->smb1.negprot.encrypted_passwords) {
289 0 : uint8_t chal[8];
290 : /* note that we do not send a challenge at all if
291 : we are using plaintext */
292 74 : get_challenge(xconn, chal);
293 74 : ret = message_push_blob(
294 : &req->outbuf, data_blob_const(chal, sizeof(chal)));
295 74 : if (ret == -1) {
296 0 : DEBUG(0, ("Could not push challenge\n"));
297 0 : reply_nterror(req, NT_STATUS_NO_MEMORY);
298 0 : return NT_STATUS_NO_MEMORY;
299 : }
300 74 : SCVAL(req->outbuf, smb_vwv16+1, ret);
301 : }
302 74 : ret = message_push_string(&req->outbuf, lp_workgroup(),
303 : STR_UNICODE|STR_TERMINATE
304 : |STR_NOALIGN);
305 74 : if (ret == -1) {
306 0 : DEBUG(0, ("Could not push workgroup string\n"));
307 0 : reply_nterror(req, NT_STATUS_NO_MEMORY);
308 0 : return NT_STATUS_NO_MEMORY;
309 : }
310 74 : ret = message_push_string(&req->outbuf, lp_netbios_name(),
311 : STR_UNICODE|STR_TERMINATE
312 : |STR_NOALIGN);
313 74 : if (ret == -1) {
314 0 : DEBUG(0, ("Could not push netbios name string\n"));
315 0 : reply_nterror(req, NT_STATUS_NO_MEMORY);
316 0 : return NT_STATUS_NO_MEMORY;
317 : }
318 74 : DEBUG(3,("not using SPNEGO\n"));
319 : } else {
320 5679 : DATA_BLOB spnego_blob = negprot_spnego(req, xconn);
321 :
322 5679 : if (spnego_blob.data == NULL) {
323 0 : reply_nterror(req, NT_STATUS_NO_MEMORY);
324 0 : return NT_STATUS_NO_MEMORY;
325 : }
326 :
327 5679 : ret = message_push_blob(&req->outbuf, spnego_blob);
328 5679 : if (ret == -1) {
329 0 : DEBUG(0, ("Could not push spnego blob\n"));
330 0 : reply_nterror(req, NT_STATUS_NO_MEMORY);
331 0 : return NT_STATUS_NO_MEMORY;
332 : }
333 5679 : data_blob_free(&spnego_blob);
334 :
335 5679 : SCVAL(req->outbuf,smb_vwv16+1, 0);
336 5679 : DEBUG(3,("using SPNEGO\n"));
337 : }
338 :
339 5753 : return NT_STATUS_OK;
340 : }
341 :
342 : /* these are the protocol lists used for auto architecture detection:
343 :
344 : WinNT 3.51:
345 : protocol [PC NETWORK PROGRAM 1.0]
346 : protocol [XENIX CORE]
347 : protocol [MICROSOFT NETWORKS 1.03]
348 : protocol [LANMAN1.0]
349 : protocol [Windows for Workgroups 3.1a]
350 : protocol [LM1.2X002]
351 : protocol [LANMAN2.1]
352 : protocol [NT LM 0.12]
353 :
354 : Win95:
355 : protocol [PC NETWORK PROGRAM 1.0]
356 : protocol [XENIX CORE]
357 : protocol [MICROSOFT NETWORKS 1.03]
358 : protocol [LANMAN1.0]
359 : protocol [Windows for Workgroups 3.1a]
360 : protocol [LM1.2X002]
361 : protocol [LANMAN2.1]
362 : protocol [NT LM 0.12]
363 :
364 : Win2K:
365 : protocol [PC NETWORK PROGRAM 1.0]
366 : protocol [LANMAN1.0]
367 : protocol [Windows for Workgroups 3.1a]
368 : protocol [LM1.2X002]
369 : protocol [LANMAN2.1]
370 : protocol [NT LM 0.12]
371 :
372 : Vista:
373 : protocol [PC NETWORK PROGRAM 1.0]
374 : protocol [LANMAN1.0]
375 : protocol [Windows for Workgroups 3.1a]
376 : protocol [LM1.2X002]
377 : protocol [LANMAN2.1]
378 : protocol [NT LM 0.12]
379 : protocol [SMB 2.001]
380 :
381 : OS/2:
382 : protocol [PC NETWORK PROGRAM 1.0]
383 : protocol [XENIX CORE]
384 : protocol [LANMAN1.0]
385 : protocol [LM1.2X002]
386 : protocol [LANMAN2.1]
387 :
388 : OSX:
389 : protocol [NT LM 0.12]
390 : protocol [SMB 2.002]
391 : protocol [SMB 2.???]
392 : */
393 :
394 : /*
395 : * Modified to recognize the architecture of the remote machine better.
396 : *
397 : * This appears to be the matrix of which protocol is used by which
398 : * product.
399 : Protocol WfWg Win95 WinNT Win2K OS/2 Vista OSX
400 : PC NETWORK PROGRAM 1.0 1 1 1 1 1 1
401 : XENIX CORE 2 2
402 : MICROSOFT NETWORKS 3.0 2 2
403 : DOS LM1.2X002 3 3
404 : MICROSOFT NETWORKS 1.03 3
405 : DOS LANMAN2.1 4 4
406 : LANMAN1.0 4 2 3 2
407 : Windows for Workgroups 3.1a 5 5 5 3 3
408 : LM1.2X002 6 4 4 4
409 : LANMAN2.1 7 5 5 5
410 : NT LM 0.12 6 8 6 6 6 1
411 : SMB 2.001 7
412 : SMB 2.002 2
413 : SMB 2.??? 3
414 : *
415 : * tim@fsg.com 09/29/95
416 : * Win2K added by matty 17/7/99
417 : */
418 :
419 : #define PROT_PC_NETWORK_PROGRAM_1_0 0x0001
420 : #define PROT_XENIX_CORE 0x0002
421 : #define PROT_MICROSOFT_NETWORKS_3_0 0x0004
422 : #define PROT_DOS_LM1_2X002 0x0008
423 : #define PROT_MICROSOFT_NETWORKS_1_03 0x0010
424 : #define PROT_DOS_LANMAN2_1 0x0020
425 : #define PROT_LANMAN1_0 0x0040
426 : #define PROT_WFWG 0x0080
427 : #define PROT_LM1_2X002 0x0100
428 : #define PROT_LANMAN2_1 0x0200
429 : #define PROT_NT_LM_0_12 0x0400
430 : #define PROT_SMB_2_001 0x0800
431 : #define PROT_SMB_2_002 0x1000
432 : #define PROT_SMB_2_FF 0x2000
433 : #define PROT_SAMBA 0x4000
434 : #define PROT_POSIX_2 0x8000
435 :
436 : #define ARCH_WFWG ( PROT_PC_NETWORK_PROGRAM_1_0 | PROT_MICROSOFT_NETWORKS_3_0 | \
437 : PROT_DOS_LM1_2X002 | PROT_DOS_LANMAN2_1 | PROT_WFWG )
438 : #define ARCH_WIN95 ( ARCH_WFWG | PROT_NT_LM_0_12 )
439 : #define ARCH_WINNT ( PROT_PC_NETWORK_PROGRAM_1_0 | PROT_XENIX_CORE | \
440 : PROT_MICROSOFT_NETWORKS_1_03 | PROT_LANMAN1_0 | PROT_WFWG | \
441 : PROT_LM1_2X002 | PROT_LANMAN2_1 | PROT_NT_LM_0_12 )
442 : #define ARCH_WIN2K ( ARCH_WINNT & ~(PROT_XENIX_CORE | PROT_MICROSOFT_NETWORKS_1_03) )
443 : #define ARCH_OS2 ( ARCH_WINNT & ~(PROT_MICROSOFT_NETWORKS_1_03 | PROT_WFWG) )
444 : #define ARCH_VISTA ( ARCH_WIN2K | PROT_SMB_2_001 )
445 : #define ARCH_SAMBA ( PROT_SAMBA )
446 : #define ARCH_CIFSFS ( PROT_POSIX_2 )
447 : #define ARCH_OSX ( PROT_NT_LM_0_12 | PROT_SMB_2_002 | PROT_SMB_2_FF )
448 :
449 : /* List of supported protocols, most desired first */
450 : static const struct {
451 : const char *proto_name;
452 : const char *short_name;
453 : NTSTATUS (*proto_reply_fn)(struct smb_request *req, uint16_t choice);
454 : int protocol_level;
455 : } supported_protocols[] = {
456 : {"SMB 2.???", "SMB2_FF", reply_smb20ff, PROTOCOL_SMB2_10},
457 : {"SMB 2.002", "SMB2_02", reply_smb2002, PROTOCOL_SMB2_02},
458 : {"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1},
459 : {"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1},
460 : {"POSIX 2", "NT1", reply_nt1, PROTOCOL_NT1},
461 : {"LANMAN2.1", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
462 : {"LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
463 : {"Samba", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
464 : {"DOS LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
465 : {"LANMAN1.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
466 : {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
467 : {NULL,NULL,NULL,0},
468 : };
469 :
470 : /****************************************************************************
471 : Reply to a negprot.
472 : conn POINTER CAN BE NULL HERE !
473 : ****************************************************************************/
474 :
475 6126 : void reply_negprot(struct smb_request *req)
476 : {
477 6126 : size_t choice = 0;
478 6126 : int chosen_level = -1;
479 6126 : bool choice_set = false;
480 141 : int protocol;
481 141 : const char *p;
482 6126 : int protocols = 0;
483 141 : int num_cliprotos;
484 141 : char **cliprotos;
485 141 : size_t i;
486 141 : size_t converted_size;
487 6126 : struct smbXsrv_connection *xconn = req->xconn;
488 6126 : struct smbd_server_connection *sconn = req->sconn;
489 6126 : bool signing_required = true;
490 141 : int max_proto;
491 141 : int min_proto;
492 141 : NTSTATUS status;
493 :
494 6126 : START_PROFILE(SMBnegprot);
495 :
496 6126 : if (xconn->smb1.negprot.done) {
497 4 : END_PROFILE(SMBnegprot);
498 4 : exit_server_cleanly("multiple negprot's are not permitted");
499 : }
500 :
501 6122 : if (req->buflen == 0) {
502 0 : DEBUG(0, ("negprot got no protocols\n"));
503 0 : reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
504 0 : END_PROFILE(SMBnegprot);
505 0 : return;
506 : }
507 :
508 6122 : if (req->buf[req->buflen-1] != '\0') {
509 0 : DEBUG(0, ("negprot protocols not 0-terminated\n"));
510 0 : reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
511 0 : END_PROFILE(SMBnegprot);
512 0 : return;
513 : }
514 :
515 6122 : p = (const char *)req->buf + 1;
516 :
517 6122 : num_cliprotos = 0;
518 6122 : cliprotos = NULL;
519 :
520 66178 : while (smbreq_bufrem(req, p) > 0) {
521 :
522 1362 : char **tmp;
523 :
524 60056 : tmp = talloc_realloc(talloc_tos(), cliprotos, char *,
525 : num_cliprotos+1);
526 60056 : if (tmp == NULL) {
527 0 : DEBUG(0, ("talloc failed\n"));
528 0 : TALLOC_FREE(cliprotos);
529 0 : reply_nterror(req, NT_STATUS_NO_MEMORY);
530 0 : END_PROFILE(SMBnegprot);
531 0 : return;
532 : }
533 :
534 60056 : cliprotos = tmp;
535 :
536 60056 : if (!pull_ascii_talloc(cliprotos, &cliprotos[num_cliprotos], p,
537 : &converted_size)) {
538 0 : DEBUG(0, ("pull_ascii_talloc failed\n"));
539 0 : TALLOC_FREE(cliprotos);
540 0 : reply_nterror(req, NT_STATUS_NO_MEMORY);
541 0 : END_PROFILE(SMBnegprot);
542 0 : return;
543 : }
544 :
545 60056 : DEBUG(3, ("Requested protocol [%s]\n",
546 : cliprotos[num_cliprotos]));
547 :
548 60056 : num_cliprotos += 1;
549 60056 : p += strlen(p) + 2;
550 : }
551 :
552 48116 : for (i=0; i<num_cliprotos; i++) {
553 47890 : if (strcsequal(cliprotos[i], "Windows for Workgroups 3.1a")) {
554 0 : protocols |= PROT_WFWG;
555 47890 : } else if (strcsequal(cliprotos[i], "DOS LM1.2X002")) {
556 0 : protocols |= PROT_DOS_LM1_2X002;
557 47890 : } else if (strcsequal(cliprotos[i], "DOS LANMAN2.1")) {
558 5896 : protocols |= PROT_DOS_LANMAN2_1;
559 41994 : } else if (strcsequal(cliprotos[i], "LANMAN1.0")) {
560 5898 : protocols |= PROT_LANMAN1_0;
561 36096 : } else if (strcsequal(cliprotos[i], "NT LM 0.12")) {
562 222 : protocols |= PROT_NT_LM_0_12;
563 35874 : } else if (strcsequal(cliprotos[i], "SMB 2.001")) {
564 0 : protocols |= PROT_SMB_2_001;
565 35874 : } else if (strcsequal(cliprotos[i], "SMB 2.002")) {
566 134 : protocols |= PROT_SMB_2_002;
567 35740 : } else if (strcsequal(cliprotos[i], "SMB 2.???")) {
568 134 : protocols |= PROT_SMB_2_FF;
569 35606 : } else if (strcsequal(cliprotos[i], "LANMAN2.1")) {
570 5896 : protocols |= PROT_LANMAN2_1;
571 29710 : } else if (strcsequal(cliprotos[i], "LM1.2X002")) {
572 5896 : protocols |= PROT_LM1_2X002;
573 23814 : } else if (strcsequal(cliprotos[i], "MICROSOFT NETWORKS 1.03")) {
574 5898 : protocols |= PROT_MICROSOFT_NETWORKS_1_03;
575 17916 : } else if (strcsequal(cliprotos[i], "MICROSOFT NETWORKS 3.0")) {
576 5898 : protocols |= PROT_MICROSOFT_NETWORKS_3_0;
577 12018 : } else if (strcsequal(cliprotos[i], "PC NETWORK PROGRAM 1.0")) {
578 5900 : protocols |= PROT_PC_NETWORK_PROGRAM_1_0;
579 6118 : } else if (strcsequal(cliprotos[i], "XENIX CORE")) {
580 0 : protocols |= PROT_XENIX_CORE;
581 6118 : } else if (strcsequal(cliprotos[i], "Samba")) {
582 5763 : protocols = PROT_SAMBA;
583 5763 : break;
584 222 : } else if (strcsequal(cliprotos[i], "POSIX 2")) {
585 0 : protocols = PROT_POSIX_2;
586 0 : break;
587 : }
588 : }
589 :
590 6122 : switch ( protocols ) {
591 : /* Old CIFSFS can send one arch only, NT LM 0.12. */
592 88 : case PROT_NT_LM_0_12:
593 : case ARCH_CIFSFS:
594 88 : set_remote_arch(RA_CIFSFS);
595 88 : break;
596 5896 : case ARCH_SAMBA:
597 5896 : set_remote_arch(RA_SAMBA);
598 5896 : break;
599 0 : case ARCH_WFWG:
600 0 : set_remote_arch(RA_WFWG);
601 0 : break;
602 0 : case ARCH_WIN95:
603 0 : set_remote_arch(RA_WIN95);
604 0 : break;
605 0 : case ARCH_WINNT:
606 0 : set_remote_arch(RA_WINNT);
607 0 : break;
608 0 : case ARCH_WIN2K:
609 0 : set_remote_arch(RA_WIN2K);
610 0 : break;
611 0 : case ARCH_VISTA:
612 0 : set_remote_arch(RA_VISTA);
613 0 : break;
614 0 : case ARCH_OS2:
615 0 : set_remote_arch(RA_OS2);
616 0 : break;
617 134 : case ARCH_OSX:
618 134 : set_remote_arch(RA_OSX);
619 134 : break;
620 4 : default:
621 4 : set_remote_arch(RA_UNKNOWN);
622 4 : break;
623 : }
624 :
625 : /* possibly reload - change of architecture */
626 6122 : reload_services(sconn, conn_snum_used, true);
627 :
628 : /*
629 : * Anything higher than PROTOCOL_SMB2_10 still
630 : * needs to go via "SMB 2.???", which is marked
631 : * as PROTOCOL_SMB2_10.
632 : *
633 : * The real negotiation happens via reply_smb20ff()
634 : * using SMB2 Negotiation.
635 : */
636 6122 : max_proto = lp_server_max_protocol();
637 6122 : if (max_proto > PROTOCOL_SMB2_10) {
638 5981 : max_proto = PROTOCOL_SMB2_10;
639 : }
640 6122 : min_proto = lp_server_min_protocol();
641 6122 : if (min_proto > PROTOCOL_SMB2_10) {
642 0 : min_proto = PROTOCOL_SMB2_10;
643 : }
644 :
645 : /* Check for protocols, most desirable first */
646 17778 : for (protocol = 0; supported_protocols[protocol].proto_name; protocol++) {
647 17776 : i = 0;
648 17776 : if ((supported_protocols[protocol].protocol_level <= max_proto) &&
649 17369 : (supported_protocols[protocol].protocol_level >= min_proto))
650 192456 : while (i < num_cliprotos) {
651 174680 : if (strequal(cliprotos[i],supported_protocols[protocol].proto_name)) {
652 6120 : choice = i;
653 6120 : chosen_level = supported_protocols[protocol].protocol_level;
654 6120 : choice_set = true;
655 : }
656 174680 : i++;
657 : }
658 17776 : if (choice_set) {
659 5979 : break;
660 : }
661 : }
662 :
663 6122 : if (!choice_set) {
664 0 : bool ok;
665 :
666 2 : DBG_NOTICE("No protocol supported !\n");
667 2 : reply_smb1_outbuf(req, 1, 0);
668 2 : SSVAL(req->outbuf, smb_vwv0, NO_PROTOCOL_CHOSEN);
669 :
670 2 : ok = smb1_srv_send(xconn, (char *)req->outbuf, false, 0, false);
671 2 : if (!ok) {
672 0 : DBG_NOTICE("smb1_srv_send failed\n");
673 : }
674 2 : exit_server_cleanly("no protocol supported\n");
675 : }
676 :
677 6120 : set_remote_proto(supported_protocols[protocol].short_name);
678 6120 : reload_services(sconn, conn_snum_used, true);
679 6120 : status = supported_protocols[protocol].proto_reply_fn(req, choice);
680 6120 : if (!NT_STATUS_IS_OK(status)) {
681 0 : exit_server_cleanly("negprot function failed\n");
682 : }
683 :
684 6120 : DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
685 :
686 6120 : DBG_INFO("negprot index=%zu\n", choice);
687 :
688 6120 : xconn->smb1.negprot.done = true;
689 :
690 : /* We always have xconn->smb1.signing_state also for >= SMB2_02 */
691 6120 : signing_required = smb1_signing_is_mandatory(xconn->smb1.signing_state);
692 6120 : if (signing_required && (chosen_level < PROTOCOL_NT1)) {
693 0 : exit_server_cleanly("SMB signing is required and "
694 : "client negotiated a downlevel protocol");
695 : }
696 :
697 6120 : TALLOC_FREE(cliprotos);
698 :
699 6120 : if (lp_async_smb_echo_handler() && (chosen_level < PROTOCOL_SMB2_02) &&
700 0 : !fork_echo_handler(xconn)) {
701 0 : exit_server("Failed to fork echo handler");
702 : }
703 :
704 6120 : END_PROFILE(SMBnegprot);
705 5979 : return;
706 : }
|