s4: torture: Add an async SMB2_OP_FLUSH + SMB2_OP_CLOSE test to smb2.compound_async.
[Samba.git] / source3 / smbd / smb1_negprot.c
blob45d991b0dcd7227582db002e9c53a122bde743b8
1 /*
2 Unix SMB/CIFS implementation.
3 negprot reply code
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Volker Lendecke 2007
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.
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.
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/>.
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"
33 * MS-CIFS, 2.2.4.52.2 SMB_COM_NEGOTIATE Response:
34 * If the server does not support any of the listed dialects, it MUST return a
35 * DialectIndex of 0XFFFF
37 #define NO_PROTOCOL_CHOSEN 0xffff
39 extern fstring remote_proto;
41 static void get_challenge(struct smbXsrv_connection *xconn, uint8_t buff[8])
43 NTSTATUS nt_status;
45 /* We might be called more than once, multiple negprots are
46 * permitted */
47 if (xconn->smb1.negprot.auth_context) {
48 DEBUG(3, ("get challenge: is this a secondary negprot? "
49 "sconn->negprot.auth_context is non-NULL!\n"));
50 TALLOC_FREE(xconn->smb1.negprot.auth_context);
53 DEBUG(10, ("get challenge: creating negprot_global_auth_context\n"));
54 nt_status = make_auth4_context(
55 xconn, &xconn->smb1.negprot.auth_context);
56 if (!NT_STATUS_IS_OK(nt_status)) {
57 DEBUG(0, ("make_auth_context_subsystem returned %s",
58 nt_errstr(nt_status)));
59 smb_panic("cannot make_negprot_global_auth_context!");
61 DEBUG(10, ("get challenge: getting challenge\n"));
62 xconn->smb1.negprot.auth_context->get_ntlm_challenge(
63 xconn->smb1.negprot.auth_context, buff);
66 /****************************************************************************
67 Reply for the lanman 1.0 protocol.
68 ****************************************************************************/
70 static NTSTATUS reply_lanman1(struct smb_request *req, uint16_t choice)
72 int secword=0;
73 time_t t = time(NULL);
74 struct smbXsrv_connection *xconn = req->xconn;
75 uint16_t raw;
76 NTSTATUS status;
78 if (lp_async_smb_echo_handler()) {
79 raw = 0;
80 } else {
81 raw = (lp_read_raw()?1:0) | (lp_write_raw()?2:0);
84 xconn->smb1.negprot.encrypted_passwords = lp_encrypt_passwords();
86 secword |= NEGOTIATE_SECURITY_USER_LEVEL;
87 if (xconn->smb1.negprot.encrypted_passwords) {
88 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
91 reply_smb1_outbuf(req, 13, xconn->smb1.negprot.encrypted_passwords?8:0);
93 SSVAL(req->outbuf,smb_vwv0,choice);
94 SSVAL(req->outbuf,smb_vwv1,secword);
95 /* Create a token value and add it to the outgoing packet. */
96 if (xconn->smb1.negprot.encrypted_passwords) {
97 get_challenge(xconn, (uint8_t *)smb_buf(req->outbuf));
98 SSVAL(req->outbuf,smb_vwv11, 8);
101 status = smbXsrv_connection_init_tables(xconn, PROTOCOL_LANMAN1);
102 if (!NT_STATUS_IS_OK(status)) {
103 reply_nterror(req, status);
104 return status;
107 /* Reply, SMBlockread, SMBwritelock supported. */
108 SCVAL(req->outbuf,smb_flg, FLAG_REPLY|FLAG_SUPPORT_LOCKREAD);
109 SSVAL(req->outbuf,smb_vwv2, xconn->smb1.negprot.max_recv);
110 SSVAL(req->outbuf,smb_vwv3, lp_max_mux()); /* maxmux */
111 SSVAL(req->outbuf,smb_vwv4, 1);
112 SSVAL(req->outbuf,smb_vwv5, raw); /* tell redirector we support
113 readbraw writebraw (possibly) */
114 SIVAL(req->outbuf,smb_vwv6, getpid());
115 SSVAL(req->outbuf,smb_vwv10, set_server_zone_offset(t)/60);
117 srv_put_dos_date((char *)req->outbuf,smb_vwv8,t);
119 return NT_STATUS_OK;
122 /****************************************************************************
123 Reply for the lanman 2.0 protocol.
124 ****************************************************************************/
126 static NTSTATUS reply_lanman2(struct smb_request *req, uint16_t choice)
128 int secword=0;
129 time_t t = time(NULL);
130 struct smbXsrv_connection *xconn = req->xconn;
131 uint16_t raw;
132 NTSTATUS status;
134 if (lp_async_smb_echo_handler()) {
135 raw = 0;
136 } else {
137 raw = (lp_read_raw()?1:0) | (lp_write_raw()?2:0);
140 xconn->smb1.negprot.encrypted_passwords = lp_encrypt_passwords();
142 secword |= NEGOTIATE_SECURITY_USER_LEVEL;
143 if (xconn->smb1.negprot.encrypted_passwords) {
144 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
147 reply_smb1_outbuf(req, 13, xconn->smb1.negprot.encrypted_passwords?8:0);
149 SSVAL(req->outbuf,smb_vwv0, choice);
150 SSVAL(req->outbuf,smb_vwv1, secword);
151 SIVAL(req->outbuf,smb_vwv6, getpid());
153 /* Create a token value and add it to the outgoing packet. */
154 if (xconn->smb1.negprot.encrypted_passwords) {
155 get_challenge(xconn, (uint8_t *)smb_buf(req->outbuf));
156 SSVAL(req->outbuf,smb_vwv11, 8);
159 status = smbXsrv_connection_init_tables(xconn, PROTOCOL_LANMAN2);
160 if (!NT_STATUS_IS_OK(status)) {
161 reply_nterror(req, status);
162 return status;
165 /* Reply, SMBlockread, SMBwritelock supported. */
166 SCVAL(req->outbuf,smb_flg,FLAG_REPLY|FLAG_SUPPORT_LOCKREAD);
167 SSVAL(req->outbuf,smb_vwv2,xconn->smb1.negprot.max_recv);
168 SSVAL(req->outbuf,smb_vwv3,lp_max_mux());
169 SSVAL(req->outbuf,smb_vwv4,1);
170 SSVAL(req->outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
171 SSVAL(req->outbuf,smb_vwv10, set_server_zone_offset(t)/60);
172 srv_put_dos_date((char *)req->outbuf,smb_vwv8,t);
173 return NT_STATUS_OK;
176 /****************************************************************************
177 Reply for the nt protocol.
178 ****************************************************************************/
180 static NTSTATUS reply_nt1(struct smb_request *req, uint16_t choice)
182 /* dual names + lock_and_read + nt SMBs + remote API calls */
183 int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ|
184 CAP_LEVEL_II_OPLOCKS;
186 int secword=0;
187 bool negotiate_spnego = False;
188 struct timespec ts;
189 ssize_t ret;
190 struct smbXsrv_connection *xconn = req->xconn;
191 bool signing_desired = false;
192 bool signing_required = false;
193 NTSTATUS status;
195 xconn->smb1.negprot.encrypted_passwords = lp_encrypt_passwords();
197 /* Check the flags field to see if this is Vista.
198 WinXP sets it and Vista does not. But we have to
199 distinguish from NT which doesn't set it either. */
201 if ( (req->flags2 & FLAGS2_EXTENDED_SECURITY) &&
202 ((req->flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED) == 0) )
204 if ((get_remote_arch() != RA_SAMBA) &&
205 (get_remote_arch() != RA_CIFSFS)) {
206 set_remote_arch( RA_VISTA );
210 reply_smb1_outbuf(req,17,0);
212 /* do spnego in user level security if the client
213 supports it and we can do encrypted passwords */
215 if (xconn->smb1.negprot.encrypted_passwords &&
216 (req->flags2 & FLAGS2_EXTENDED_SECURITY)) {
217 negotiate_spnego = True;
218 capabilities |= CAP_EXTENDED_SECURITY;
219 add_to_common_flags2(FLAGS2_EXTENDED_SECURITY);
220 /* Ensure FLAGS2_EXTENDED_SECURITY gets set in this reply
221 (already partially constructed. */
222 SSVAL(req->outbuf, smb_flg2,
223 req->flags2 | FLAGS2_EXTENDED_SECURITY);
226 capabilities |= CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
228 if (lp_unicode()) {
229 capabilities |= CAP_UNICODE;
232 if (lp_smb1_unix_extensions()) {
233 capabilities |= CAP_UNIX;
236 if (lp_large_readwrite())
237 capabilities |= CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_W2K_SMBS;
239 capabilities |= CAP_LARGE_FILES;
241 if (!lp_async_smb_echo_handler() && lp_read_raw() && lp_write_raw())
242 capabilities |= CAP_RAW_MODE;
244 if (lp_nt_status_support())
245 capabilities |= CAP_STATUS32;
247 if (lp_host_msdfs())
248 capabilities |= CAP_DFS;
250 secword |= NEGOTIATE_SECURITY_USER_LEVEL;
251 if (xconn->smb1.negprot.encrypted_passwords) {
252 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
255 signing_desired = smb1_signing_is_desired(xconn->smb1.signing_state);
256 signing_required = smb1_signing_is_mandatory(xconn->smb1.signing_state);
258 if (signing_desired) {
259 secword |= NEGOTIATE_SECURITY_SIGNATURES_ENABLED;
260 /* No raw mode with smb signing. */
261 capabilities &= ~CAP_RAW_MODE;
262 if (signing_required) {
263 secword |=NEGOTIATE_SECURITY_SIGNATURES_REQUIRED;
267 SSVAL(req->outbuf,smb_vwv0,choice);
268 SCVAL(req->outbuf,smb_vwv1,secword);
270 status = smbXsrv_connection_init_tables(xconn, PROTOCOL_NT1);
271 if (!NT_STATUS_IS_OK(status)) {
272 reply_nterror(req, status);
273 return status;
276 SSVAL(req->outbuf,smb_vwv1+1, lp_max_mux()); /* maxmpx */
277 SSVAL(req->outbuf,smb_vwv2+1, 1); /* num vcs */
278 SIVAL(req->outbuf,smb_vwv3+1,
279 xconn->smb1.negprot.max_recv); /* max buffer. LOTS! */
280 SIVAL(req->outbuf,smb_vwv5+1, 0x10000); /* raw size. full 64k */
281 SIVAL(req->outbuf,smb_vwv7+1, getpid()); /* session key */
282 SIVAL(req->outbuf,smb_vwv9+1, capabilities); /* capabilities */
283 clock_gettime(CLOCK_REALTIME,&ts);
284 put_long_date_full_timespec(TIMESTAMP_SET_NT_OR_BETTER,(char *)req->outbuf+smb_vwv11+1,&ts);
285 SSVALS(req->outbuf,smb_vwv15+1,set_server_zone_offset(ts.tv_sec)/60);
287 if (!negotiate_spnego) {
288 /* Create a token value and add it to the outgoing packet. */
289 if (xconn->smb1.negprot.encrypted_passwords) {
290 uint8_t chal[8];
291 /* note that we do not send a challenge at all if
292 we are using plaintext */
293 get_challenge(xconn, chal);
294 ret = message_push_blob(
295 &req->outbuf, data_blob_const(chal, sizeof(chal)));
296 if (ret == -1) {
297 DEBUG(0, ("Could not push challenge\n"));
298 reply_nterror(req, NT_STATUS_NO_MEMORY);
299 return NT_STATUS_NO_MEMORY;
301 SCVAL(req->outbuf, smb_vwv16+1, ret);
303 ret = message_push_string(&req->outbuf, lp_workgroup(),
304 STR_UNICODE|STR_TERMINATE
305 |STR_NOALIGN);
306 if (ret == -1) {
307 DEBUG(0, ("Could not push workgroup string\n"));
308 reply_nterror(req, NT_STATUS_NO_MEMORY);
309 return NT_STATUS_NO_MEMORY;
311 ret = message_push_string(&req->outbuf, lp_netbios_name(),
312 STR_UNICODE|STR_TERMINATE
313 |STR_NOALIGN);
314 if (ret == -1) {
315 DEBUG(0, ("Could not push netbios name string\n"));
316 reply_nterror(req, NT_STATUS_NO_MEMORY);
317 return NT_STATUS_NO_MEMORY;
319 DEBUG(3,("not using SPNEGO\n"));
320 } else {
321 DATA_BLOB spnego_blob = negprot_spnego(req, xconn);
323 if (spnego_blob.data == NULL) {
324 reply_nterror(req, NT_STATUS_NO_MEMORY);
325 return NT_STATUS_NO_MEMORY;
328 ret = message_push_blob(&req->outbuf, spnego_blob);
329 if (ret == -1) {
330 DEBUG(0, ("Could not push spnego blob\n"));
331 reply_nterror(req, NT_STATUS_NO_MEMORY);
332 return NT_STATUS_NO_MEMORY;
334 data_blob_free(&spnego_blob);
336 SCVAL(req->outbuf,smb_vwv16+1, 0);
337 DEBUG(3,("using SPNEGO\n"));
340 return NT_STATUS_OK;
343 /* these are the protocol lists used for auto architecture detection:
345 WinNT 3.51:
346 protocol [PC NETWORK PROGRAM 1.0]
347 protocol [XENIX CORE]
348 protocol [MICROSOFT NETWORKS 1.03]
349 protocol [LANMAN1.0]
350 protocol [Windows for Workgroups 3.1a]
351 protocol [LM1.2X002]
352 protocol [LANMAN2.1]
353 protocol [NT LM 0.12]
355 Win95:
356 protocol [PC NETWORK PROGRAM 1.0]
357 protocol [XENIX CORE]
358 protocol [MICROSOFT NETWORKS 1.03]
359 protocol [LANMAN1.0]
360 protocol [Windows for Workgroups 3.1a]
361 protocol [LM1.2X002]
362 protocol [LANMAN2.1]
363 protocol [NT LM 0.12]
365 Win2K:
366 protocol [PC NETWORK PROGRAM 1.0]
367 protocol [LANMAN1.0]
368 protocol [Windows for Workgroups 3.1a]
369 protocol [LM1.2X002]
370 protocol [LANMAN2.1]
371 protocol [NT LM 0.12]
373 Vista:
374 protocol [PC NETWORK PROGRAM 1.0]
375 protocol [LANMAN1.0]
376 protocol [Windows for Workgroups 3.1a]
377 protocol [LM1.2X002]
378 protocol [LANMAN2.1]
379 protocol [NT LM 0.12]
380 protocol [SMB 2.001]
382 OS/2:
383 protocol [PC NETWORK PROGRAM 1.0]
384 protocol [XENIX CORE]
385 protocol [LANMAN1.0]
386 protocol [LM1.2X002]
387 protocol [LANMAN2.1]
389 OSX:
390 protocol [NT LM 0.12]
391 protocol [SMB 2.002]
392 protocol [SMB 2.???]
396 * Modified to recognize the architecture of the remote machine better.
398 * This appears to be the matrix of which protocol is used by which
399 * product.
400 Protocol WfWg Win95 WinNT Win2K OS/2 Vista OSX
401 PC NETWORK PROGRAM 1.0 1 1 1 1 1 1
402 XENIX CORE 2 2
403 MICROSOFT NETWORKS 3.0 2 2
404 DOS LM1.2X002 3 3
405 MICROSOFT NETWORKS 1.03 3
406 DOS LANMAN2.1 4 4
407 LANMAN1.0 4 2 3 2
408 Windows for Workgroups 3.1a 5 5 5 3 3
409 LM1.2X002 6 4 4 4
410 LANMAN2.1 7 5 5 5
411 NT LM 0.12 6 8 6 6 6 1
412 SMB 2.001 7
413 SMB 2.002 2
414 SMB 2.??? 3
416 * tim@fsg.com 09/29/95
417 * Win2K added by matty 17/7/99
420 #define PROT_PC_NETWORK_PROGRAM_1_0 0x0001
421 #define PROT_XENIX_CORE 0x0002
422 #define PROT_MICROSOFT_NETWORKS_3_0 0x0004
423 #define PROT_DOS_LM1_2X002 0x0008
424 #define PROT_MICROSOFT_NETWORKS_1_03 0x0010
425 #define PROT_DOS_LANMAN2_1 0x0020
426 #define PROT_LANMAN1_0 0x0040
427 #define PROT_WFWG 0x0080
428 #define PROT_LM1_2X002 0x0100
429 #define PROT_LANMAN2_1 0x0200
430 #define PROT_NT_LM_0_12 0x0400
431 #define PROT_SMB_2_001 0x0800
432 #define PROT_SMB_2_002 0x1000
433 #define PROT_SMB_2_FF 0x2000
434 #define PROT_SAMBA 0x4000
435 #define PROT_POSIX_2 0x8000
437 #define ARCH_WFWG ( PROT_PC_NETWORK_PROGRAM_1_0 | PROT_MICROSOFT_NETWORKS_3_0 | \
438 PROT_DOS_LM1_2X002 | PROT_DOS_LANMAN2_1 | PROT_WFWG )
439 #define ARCH_WIN95 ( ARCH_WFWG | PROT_NT_LM_0_12 )
440 #define ARCH_WINNT ( PROT_PC_NETWORK_PROGRAM_1_0 | PROT_XENIX_CORE | \
441 PROT_MICROSOFT_NETWORKS_1_03 | PROT_LANMAN1_0 | PROT_WFWG | \
442 PROT_LM1_2X002 | PROT_LANMAN2_1 | PROT_NT_LM_0_12 )
443 #define ARCH_WIN2K ( ARCH_WINNT & ~(PROT_XENIX_CORE | PROT_MICROSOFT_NETWORKS_1_03) )
444 #define ARCH_OS2 ( ARCH_WINNT & ~(PROT_MICROSOFT_NETWORKS_1_03 | PROT_WFWG) )
445 #define ARCH_VISTA ( ARCH_WIN2K | PROT_SMB_2_001 )
446 #define ARCH_SAMBA ( PROT_SAMBA )
447 #define ARCH_CIFSFS ( PROT_POSIX_2 )
448 #define ARCH_OSX ( PROT_NT_LM_0_12 | PROT_SMB_2_002 | PROT_SMB_2_FF )
450 /* List of supported protocols, most desired first */
451 static const struct {
452 const char *proto_name;
453 const char *short_name;
454 NTSTATUS (*proto_reply_fn)(struct smb_request *req, uint16_t choice);
455 int protocol_level;
456 } supported_protocols[] = {
457 {"SMB 2.???", "SMB2_FF", reply_smb20ff, PROTOCOL_SMB2_10},
458 {"SMB 2.002", "SMB2_02", reply_smb2002, PROTOCOL_SMB2_02},
459 {"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1},
460 {"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1},
461 {"POSIX 2", "NT1", reply_nt1, PROTOCOL_NT1},
462 {"LANMAN2.1", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
463 {"LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
464 {"Samba", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
465 {"DOS LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
466 {"LANMAN1.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
467 {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
468 {NULL,NULL,NULL,0},
471 /****************************************************************************
472 Reply to a negprot.
473 conn POINTER CAN BE NULL HERE !
474 ****************************************************************************/
476 void reply_negprot(struct smb_request *req)
478 size_t choice = 0;
479 int chosen_level = -1;
480 bool choice_set = false;
481 int protocol;
482 const char *p;
483 int protocols = 0;
484 int num_cliprotos;
485 char **cliprotos;
486 size_t i;
487 size_t converted_size;
488 struct smbXsrv_connection *xconn = req->xconn;
489 struct smbd_server_connection *sconn = req->sconn;
490 bool signing_required = true;
491 int max_proto;
492 int min_proto;
493 NTSTATUS status;
495 START_PROFILE(SMBnegprot);
497 if (xconn->smb1.negprot.done) {
498 END_PROFILE(SMBnegprot);
499 exit_server_cleanly("multiple negprot's are not permitted");
502 if (req->buflen == 0) {
503 DEBUG(0, ("negprot got no protocols\n"));
504 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
505 END_PROFILE(SMBnegprot);
506 return;
509 if (req->buf[req->buflen-1] != '\0') {
510 DEBUG(0, ("negprot protocols not 0-terminated\n"));
511 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
512 END_PROFILE(SMBnegprot);
513 return;
516 p = (const char *)req->buf + 1;
518 num_cliprotos = 0;
519 cliprotos = NULL;
521 while (smbreq_bufrem(req, p) > 0) {
523 char **tmp;
525 tmp = talloc_realloc(talloc_tos(), cliprotos, char *,
526 num_cliprotos+1);
527 if (tmp == NULL) {
528 DEBUG(0, ("talloc failed\n"));
529 TALLOC_FREE(cliprotos);
530 reply_nterror(req, NT_STATUS_NO_MEMORY);
531 END_PROFILE(SMBnegprot);
532 return;
535 cliprotos = tmp;
537 if (!pull_ascii_talloc(cliprotos, &cliprotos[num_cliprotos], p,
538 &converted_size)) {
539 DEBUG(0, ("pull_ascii_talloc failed\n"));
540 TALLOC_FREE(cliprotos);
541 reply_nterror(req, NT_STATUS_NO_MEMORY);
542 END_PROFILE(SMBnegprot);
543 return;
546 DEBUG(3, ("Requested protocol [%s]\n",
547 cliprotos[num_cliprotos]));
549 num_cliprotos += 1;
550 p += strlen(p) + 2;
553 for (i=0; i<num_cliprotos; i++) {
554 if (strcsequal(cliprotos[i], "Windows for Workgroups 3.1a")) {
555 protocols |= PROT_WFWG;
556 } else if (strcsequal(cliprotos[i], "DOS LM1.2X002")) {
557 protocols |= PROT_DOS_LM1_2X002;
558 } else if (strcsequal(cliprotos[i], "DOS LANMAN2.1")) {
559 protocols |= PROT_DOS_LANMAN2_1;
560 } else if (strcsequal(cliprotos[i], "LANMAN1.0")) {
561 protocols |= PROT_LANMAN1_0;
562 } else if (strcsequal(cliprotos[i], "NT LM 0.12")) {
563 protocols |= PROT_NT_LM_0_12;
564 } else if (strcsequal(cliprotos[i], "SMB 2.001")) {
565 protocols |= PROT_SMB_2_001;
566 } else if (strcsequal(cliprotos[i], "SMB 2.002")) {
567 protocols |= PROT_SMB_2_002;
568 } else if (strcsequal(cliprotos[i], "SMB 2.???")) {
569 protocols |= PROT_SMB_2_FF;
570 } else if (strcsequal(cliprotos[i], "LANMAN2.1")) {
571 protocols |= PROT_LANMAN2_1;
572 } else if (strcsequal(cliprotos[i], "LM1.2X002")) {
573 protocols |= PROT_LM1_2X002;
574 } else if (strcsequal(cliprotos[i], "MICROSOFT NETWORKS 1.03")) {
575 protocols |= PROT_MICROSOFT_NETWORKS_1_03;
576 } else if (strcsequal(cliprotos[i], "MICROSOFT NETWORKS 3.0")) {
577 protocols |= PROT_MICROSOFT_NETWORKS_3_0;
578 } else if (strcsequal(cliprotos[i], "PC NETWORK PROGRAM 1.0")) {
579 protocols |= PROT_PC_NETWORK_PROGRAM_1_0;
580 } else if (strcsequal(cliprotos[i], "XENIX CORE")) {
581 protocols |= PROT_XENIX_CORE;
582 } else if (strcsequal(cliprotos[i], "Samba")) {
583 protocols = PROT_SAMBA;
584 break;
585 } else if (strcsequal(cliprotos[i], "POSIX 2")) {
586 protocols = PROT_POSIX_2;
587 break;
591 switch ( protocols ) {
592 /* Old CIFSFS can send one arch only, NT LM 0.12. */
593 case PROT_NT_LM_0_12:
594 case ARCH_CIFSFS:
595 set_remote_arch(RA_CIFSFS);
596 break;
597 case ARCH_SAMBA:
598 set_remote_arch(RA_SAMBA);
599 break;
600 case ARCH_WFWG:
601 set_remote_arch(RA_WFWG);
602 break;
603 case ARCH_WIN95:
604 set_remote_arch(RA_WIN95);
605 break;
606 case ARCH_WINNT:
607 set_remote_arch(RA_WINNT);
608 break;
609 case ARCH_WIN2K:
610 set_remote_arch(RA_WIN2K);
611 break;
612 case ARCH_VISTA:
613 set_remote_arch(RA_VISTA);
614 break;
615 case ARCH_OS2:
616 set_remote_arch(RA_OS2);
617 break;
618 case ARCH_OSX:
619 set_remote_arch(RA_OSX);
620 break;
621 default:
622 set_remote_arch(RA_UNKNOWN);
623 break;
626 /* possibly reload - change of architecture */
627 reload_services(sconn, conn_snum_used, true);
630 * Anything higher than PROTOCOL_SMB2_10 still
631 * needs to go via "SMB 2.???", which is marked
632 * as PROTOCOL_SMB2_10.
634 * The real negotiation happens via reply_smb20ff()
635 * using SMB2 Negotiation.
637 max_proto = lp_server_max_protocol();
638 if (max_proto > PROTOCOL_SMB2_10) {
639 max_proto = PROTOCOL_SMB2_10;
641 min_proto = lp_server_min_protocol();
642 if (min_proto > PROTOCOL_SMB2_10) {
643 min_proto = PROTOCOL_SMB2_10;
646 /* Check for protocols, most desirable first */
647 for (protocol = 0; supported_protocols[protocol].proto_name; protocol++) {
648 i = 0;
649 if ((supported_protocols[protocol].protocol_level <= max_proto) &&
650 (supported_protocols[protocol].protocol_level >= min_proto))
651 while (i < num_cliprotos) {
652 if (strequal(cliprotos[i],supported_protocols[protocol].proto_name)) {
653 choice = i;
654 chosen_level = supported_protocols[protocol].protocol_level;
655 choice_set = true;
657 i++;
659 if (choice_set) {
660 break;
664 if (!choice_set) {
665 bool ok;
667 DBG_NOTICE("No protocol supported !\n");
668 reply_smb1_outbuf(req, 1, 0);
669 SSVAL(req->outbuf, smb_vwv0, NO_PROTOCOL_CHOSEN);
671 ok = smb1_srv_send(xconn, (char *)req->outbuf,
672 false, 0, false, NULL);
673 if (!ok) {
674 DBG_NOTICE("smb1_srv_send failed\n");
676 exit_server_cleanly("no protocol supported\n");
679 fstrcpy(remote_proto,supported_protocols[protocol].short_name);
680 reload_services(sconn, conn_snum_used, true);
681 status = supported_protocols[protocol].proto_reply_fn(req, choice);
682 if (!NT_STATUS_IS_OK(status)) {
683 exit_server_cleanly("negprot function failed\n");
686 DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
688 DBG_INFO("negprot index=%zu\n", choice);
690 xconn->smb1.negprot.done = true;
692 /* We always have xconn->smb1.signing_state also for >= SMB2_02 */
693 signing_required = smb1_signing_is_mandatory(xconn->smb1.signing_state);
694 if (signing_required && (chosen_level < PROTOCOL_NT1)) {
695 exit_server_cleanly("SMB signing is required and "
696 "client negotiated a downlevel protocol");
699 TALLOC_FREE(cliprotos);
701 if (lp_async_smb_echo_handler() && (chosen_level < PROTOCOL_SMB2_02) &&
702 !fork_echo_handler(xconn)) {
703 exit_server("Failed to fork echo handler");
706 END_PROFILE(SMBnegprot);
707 return;