s3: smbd: Now we've proved dst_dirfsp parameter is always NULL, remove the parameter...
[Samba.git] / source3 / smbd / smb1_negprot.c
blob7171c663f41b5fc14791bff20783c19c2af4373c
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"
31 #include "source3/lib/substitute.h"
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
38 #define NO_PROTOCOL_CHOSEN 0xffff
40 static void get_challenge(struct smbXsrv_connection *xconn, uint8_t buff[8])
42 NTSTATUS nt_status;
44 /* We might be called more than once, multiple negprots are
45 * permitted */
46 if (xconn->smb1.negprot.auth_context) {
47 DEBUG(3, ("get challenge: is this a secondary negprot? "
48 "sconn->negprot.auth_context is non-NULL!\n"));
49 TALLOC_FREE(xconn->smb1.negprot.auth_context);
52 DEBUG(10, ("get challenge: creating negprot_global_auth_context\n"));
53 nt_status = make_auth4_context(
54 xconn, &xconn->smb1.negprot.auth_context);
55 if (!NT_STATUS_IS_OK(nt_status)) {
56 DEBUG(0, ("make_auth_context_subsystem returned %s\n",
57 nt_errstr(nt_status)));
58 smb_panic("cannot make_negprot_global_auth_context!");
60 DEBUG(10, ("get challenge: getting challenge\n"));
61 xconn->smb1.negprot.auth_context->get_ntlm_challenge(
62 xconn->smb1.negprot.auth_context, buff);
65 /****************************************************************************
66 Reply for the lanman 1.0 protocol.
67 ****************************************************************************/
69 static NTSTATUS reply_lanman1(struct smb_request *req, uint16_t choice)
71 int secword=0;
72 time_t t = time(NULL);
73 struct smbXsrv_connection *xconn = req->xconn;
74 uint16_t raw;
75 NTSTATUS status;
77 if (lp_async_smb_echo_handler()) {
78 raw = 0;
79 } else {
80 raw = (lp_read_raw()?1:0) | (lp_write_raw()?2:0);
83 xconn->smb1.negprot.encrypted_passwords = lp_encrypt_passwords();
85 secword |= NEGOTIATE_SECURITY_USER_LEVEL;
86 if (xconn->smb1.negprot.encrypted_passwords) {
87 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
90 reply_smb1_outbuf(req, 13, xconn->smb1.negprot.encrypted_passwords?8:0);
92 SSVAL(req->outbuf,smb_vwv0,choice);
93 SSVAL(req->outbuf,smb_vwv1,secword);
94 /* Create a token value and add it to the outgoing packet. */
95 if (xconn->smb1.negprot.encrypted_passwords) {
96 get_challenge(xconn, (uint8_t *)smb_buf(req->outbuf));
97 SSVAL(req->outbuf,smb_vwv11, 8);
100 status = smbXsrv_connection_init_tables(xconn, PROTOCOL_LANMAN1);
101 if (!NT_STATUS_IS_OK(status)) {
102 reply_nterror(req, status);
103 return status;
106 /* Reply, SMBlockread, SMBwritelock supported. */
107 SCVAL(req->outbuf,smb_flg, FLAG_REPLY|FLAG_SUPPORT_LOCKREAD);
108 SSVAL(req->outbuf,smb_vwv2, xconn->smb1.negprot.max_recv);
109 SSVAL(req->outbuf,smb_vwv3, lp_max_mux()); /* maxmux */
110 SSVAL(req->outbuf,smb_vwv4, 1);
111 SSVAL(req->outbuf,smb_vwv5, raw); /* tell redirector we support
112 readbraw writebraw (possibly) */
113 SIVAL(req->outbuf,smb_vwv6, getpid());
114 SSVAL(req->outbuf,smb_vwv10, set_server_zone_offset(t)/60);
116 srv_put_dos_date((char *)req->outbuf,smb_vwv8,t);
118 return NT_STATUS_OK;
121 /****************************************************************************
122 Reply for the lanman 2.0 protocol.
123 ****************************************************************************/
125 static NTSTATUS reply_lanman2(struct smb_request *req, uint16_t choice)
127 int secword=0;
128 time_t t = time(NULL);
129 struct smbXsrv_connection *xconn = req->xconn;
130 uint16_t raw;
131 NTSTATUS status;
133 if (lp_async_smb_echo_handler()) {
134 raw = 0;
135 } else {
136 raw = (lp_read_raw()?1:0) | (lp_write_raw()?2:0);
139 xconn->smb1.negprot.encrypted_passwords = lp_encrypt_passwords();
141 secword |= NEGOTIATE_SECURITY_USER_LEVEL;
142 if (xconn->smb1.negprot.encrypted_passwords) {
143 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
146 reply_smb1_outbuf(req, 13, xconn->smb1.negprot.encrypted_passwords?8:0);
148 SSVAL(req->outbuf,smb_vwv0, choice);
149 SSVAL(req->outbuf,smb_vwv1, secword);
150 SIVAL(req->outbuf,smb_vwv6, getpid());
152 /* Create a token value and add it to the outgoing packet. */
153 if (xconn->smb1.negprot.encrypted_passwords) {
154 get_challenge(xconn, (uint8_t *)smb_buf(req->outbuf));
155 SSVAL(req->outbuf,smb_vwv11, 8);
158 status = smbXsrv_connection_init_tables(xconn, PROTOCOL_LANMAN2);
159 if (!NT_STATUS_IS_OK(status)) {
160 reply_nterror(req, status);
161 return status;
164 /* Reply, SMBlockread, SMBwritelock supported. */
165 SCVAL(req->outbuf,smb_flg,FLAG_REPLY|FLAG_SUPPORT_LOCKREAD);
166 SSVAL(req->outbuf,smb_vwv2,xconn->smb1.negprot.max_recv);
167 SSVAL(req->outbuf,smb_vwv3,lp_max_mux());
168 SSVAL(req->outbuf,smb_vwv4,1);
169 SSVAL(req->outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
170 SSVAL(req->outbuf,smb_vwv10, set_server_zone_offset(t)/60);
171 srv_put_dos_date((char *)req->outbuf,smb_vwv8,t);
172 return NT_STATUS_OK;
175 /****************************************************************************
176 Reply for the nt protocol.
177 ****************************************************************************/
179 static NTSTATUS reply_nt1(struct smb_request *req, uint16_t choice)
181 /* dual names + lock_and_read + nt SMBs + remote API calls */
182 int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ|
183 CAP_LEVEL_II_OPLOCKS;
185 int secword=0;
186 bool negotiate_spnego = False;
187 struct timespec ts;
188 ssize_t ret;
189 struct smbXsrv_connection *xconn = req->xconn;
190 bool signing_desired = false;
191 bool signing_required = false;
192 NTSTATUS status;
194 xconn->smb1.negprot.encrypted_passwords = lp_encrypt_passwords();
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. */
200 if ( (req->flags2 & FLAGS2_EXTENDED_SECURITY) &&
201 ((req->flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED) == 0) )
203 if ((get_remote_arch() != RA_SAMBA) &&
204 (get_remote_arch() != RA_CIFSFS)) {
205 set_remote_arch( RA_VISTA );
209 reply_smb1_outbuf(req,17,0);
211 /* do spnego in user level security if the client
212 supports it and we can do encrypted passwords */
214 if (xconn->smb1.negprot.encrypted_passwords &&
215 (req->flags2 & FLAGS2_EXTENDED_SECURITY)) {
216 negotiate_spnego = True;
217 capabilities |= CAP_EXTENDED_SECURITY;
218 add_to_common_flags2(FLAGS2_EXTENDED_SECURITY);
219 /* Ensure FLAGS2_EXTENDED_SECURITY gets set in this reply
220 (already partially constructed. */
221 SSVAL(req->outbuf, smb_flg2,
222 req->flags2 | FLAGS2_EXTENDED_SECURITY);
225 capabilities |= CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
227 if (lp_unicode()) {
228 capabilities |= CAP_UNICODE;
231 if (lp_smb1_unix_extensions()) {
232 capabilities |= CAP_UNIX;
235 if (lp_large_readwrite())
236 capabilities |= CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_W2K_SMBS;
238 capabilities |= CAP_LARGE_FILES;
240 if (!lp_async_smb_echo_handler() && lp_read_raw() && lp_write_raw())
241 capabilities |= CAP_RAW_MODE;
243 if (lp_nt_status_support())
244 capabilities |= CAP_STATUS32;
246 if (lp_host_msdfs())
247 capabilities |= CAP_DFS;
249 secword |= NEGOTIATE_SECURITY_USER_LEVEL;
250 if (xconn->smb1.negprot.encrypted_passwords) {
251 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
254 signing_desired = smb1_signing_is_desired(xconn->smb1.signing_state);
255 signing_required = smb1_signing_is_mandatory(xconn->smb1.signing_state);
257 if (signing_desired) {
258 secword |= NEGOTIATE_SECURITY_SIGNATURES_ENABLED;
259 /* No raw mode with smb signing. */
260 capabilities &= ~CAP_RAW_MODE;
261 if (signing_required) {
262 secword |=NEGOTIATE_SECURITY_SIGNATURES_REQUIRED;
266 SSVAL(req->outbuf,smb_vwv0,choice);
267 SCVAL(req->outbuf,smb_vwv1,secword);
269 status = smbXsrv_connection_init_tables(xconn, PROTOCOL_NT1);
270 if (!NT_STATUS_IS_OK(status)) {
271 reply_nterror(req, status);
272 return status;
275 SSVAL(req->outbuf,smb_vwv1+1, lp_max_mux()); /* maxmpx */
276 SSVAL(req->outbuf,smb_vwv2+1, 1); /* num vcs */
277 SIVAL(req->outbuf,smb_vwv3+1,
278 xconn->smb1.negprot.max_recv); /* max buffer. LOTS! */
279 SIVAL(req->outbuf,smb_vwv5+1, 0x10000); /* raw size. full 64k */
280 SIVAL(req->outbuf,smb_vwv7+1, getpid()); /* session key */
281 SIVAL(req->outbuf,smb_vwv9+1, capabilities); /* capabilities */
282 clock_gettime(CLOCK_REALTIME,&ts);
283 put_long_date_full_timespec(TIMESTAMP_SET_NT_OR_BETTER,(char *)req->outbuf+smb_vwv11+1,&ts);
284 SSVALS(req->outbuf,smb_vwv15+1,set_server_zone_offset(ts.tv_sec)/60);
286 if (!negotiate_spnego) {
287 /* Create a token value and add it to the outgoing packet. */
288 if (xconn->smb1.negprot.encrypted_passwords) {
289 uint8_t chal[8];
290 /* note that we do not send a challenge at all if
291 we are using plaintext */
292 get_challenge(xconn, chal);
293 ret = message_push_blob(
294 &req->outbuf, data_blob_const(chal, sizeof(chal)));
295 if (ret == -1) {
296 DEBUG(0, ("Could not push challenge\n"));
297 reply_nterror(req, NT_STATUS_NO_MEMORY);
298 return NT_STATUS_NO_MEMORY;
300 SCVAL(req->outbuf, smb_vwv16+1, ret);
302 ret = message_push_string(&req->outbuf, lp_workgroup(),
303 STR_UNICODE|STR_TERMINATE
304 |STR_NOALIGN);
305 if (ret == -1) {
306 DEBUG(0, ("Could not push workgroup string\n"));
307 reply_nterror(req, NT_STATUS_NO_MEMORY);
308 return NT_STATUS_NO_MEMORY;
310 ret = message_push_string(&req->outbuf, lp_netbios_name(),
311 STR_UNICODE|STR_TERMINATE
312 |STR_NOALIGN);
313 if (ret == -1) {
314 DEBUG(0, ("Could not push netbios name string\n"));
315 reply_nterror(req, NT_STATUS_NO_MEMORY);
316 return NT_STATUS_NO_MEMORY;
318 DEBUG(3,("not using SPNEGO\n"));
319 } else {
320 DATA_BLOB spnego_blob = negprot_spnego(req, xconn);
322 if (spnego_blob.data == NULL) {
323 reply_nterror(req, NT_STATUS_NO_MEMORY);
324 return NT_STATUS_NO_MEMORY;
327 ret = message_push_blob(&req->outbuf, spnego_blob);
328 if (ret == -1) {
329 DEBUG(0, ("Could not push spnego blob\n"));
330 reply_nterror(req, NT_STATUS_NO_MEMORY);
331 return NT_STATUS_NO_MEMORY;
333 data_blob_free(&spnego_blob);
335 SCVAL(req->outbuf,smb_vwv16+1, 0);
336 DEBUG(3,("using SPNEGO\n"));
339 return NT_STATUS_OK;
342 /* these are the protocol lists used for auto architecture detection:
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]
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]
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]
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]
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]
388 OSX:
389 protocol [NT LM 0.12]
390 protocol [SMB 2.002]
391 protocol [SMB 2.???]
395 * Modified to recognize the architecture of the remote machine better.
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
415 * tim@fsg.com 09/29/95
416 * Win2K added by matty 17/7/99
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
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 )
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},
470 /****************************************************************************
471 Reply to a negprot.
472 conn POINTER CAN BE NULL HERE !
473 ****************************************************************************/
475 void reply_negprot(struct smb_request *req)
477 size_t choice = 0;
478 int chosen_level = -1;
479 bool choice_set = false;
480 int protocol;
481 const char *p;
482 int protocols = 0;
483 int num_cliprotos;
484 char **cliprotos;
485 size_t i;
486 size_t converted_size;
487 struct smbXsrv_connection *xconn = req->xconn;
488 struct smbd_server_connection *sconn = req->sconn;
489 bool signing_required = true;
490 int max_proto;
491 int min_proto;
492 NTSTATUS status;
494 START_PROFILE(SMBnegprot);
496 if (xconn->smb1.negprot.done) {
497 END_PROFILE(SMBnegprot);
498 exit_server_cleanly("multiple negprot's are not permitted");
501 if (req->buflen == 0) {
502 DEBUG(0, ("negprot got no protocols\n"));
503 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
504 END_PROFILE(SMBnegprot);
505 return;
508 if (req->buf[req->buflen-1] != '\0') {
509 DEBUG(0, ("negprot protocols not 0-terminated\n"));
510 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
511 END_PROFILE(SMBnegprot);
512 return;
515 p = (const char *)req->buf + 1;
517 num_cliprotos = 0;
518 cliprotos = NULL;
520 while (smbreq_bufrem(req, p) > 0) {
522 char **tmp;
524 tmp = talloc_realloc(talloc_tos(), cliprotos, char *,
525 num_cliprotos+1);
526 if (tmp == NULL) {
527 DEBUG(0, ("talloc failed\n"));
528 TALLOC_FREE(cliprotos);
529 reply_nterror(req, NT_STATUS_NO_MEMORY);
530 END_PROFILE(SMBnegprot);
531 return;
534 cliprotos = tmp;
536 if (!pull_ascii_talloc(cliprotos, &cliprotos[num_cliprotos], p,
537 &converted_size)) {
538 DEBUG(0, ("pull_ascii_talloc failed\n"));
539 TALLOC_FREE(cliprotos);
540 reply_nterror(req, NT_STATUS_NO_MEMORY);
541 END_PROFILE(SMBnegprot);
542 return;
545 DEBUG(3, ("Requested protocol [%s]\n",
546 cliprotos[num_cliprotos]));
548 num_cliprotos += 1;
549 p += strlen(p) + 2;
552 for (i=0; i<num_cliprotos; i++) {
553 if (strcsequal(cliprotos[i], "Windows for Workgroups 3.1a")) {
554 protocols |= PROT_WFWG;
555 } else if (strcsequal(cliprotos[i], "DOS LM1.2X002")) {
556 protocols |= PROT_DOS_LM1_2X002;
557 } else if (strcsequal(cliprotos[i], "DOS LANMAN2.1")) {
558 protocols |= PROT_DOS_LANMAN2_1;
559 } else if (strcsequal(cliprotos[i], "LANMAN1.0")) {
560 protocols |= PROT_LANMAN1_0;
561 } else if (strcsequal(cliprotos[i], "NT LM 0.12")) {
562 protocols |= PROT_NT_LM_0_12;
563 } else if (strcsequal(cliprotos[i], "SMB 2.001")) {
564 protocols |= PROT_SMB_2_001;
565 } else if (strcsequal(cliprotos[i], "SMB 2.002")) {
566 protocols |= PROT_SMB_2_002;
567 } else if (strcsequal(cliprotos[i], "SMB 2.???")) {
568 protocols |= PROT_SMB_2_FF;
569 } else if (strcsequal(cliprotos[i], "LANMAN2.1")) {
570 protocols |= PROT_LANMAN2_1;
571 } else if (strcsequal(cliprotos[i], "LM1.2X002")) {
572 protocols |= PROT_LM1_2X002;
573 } else if (strcsequal(cliprotos[i], "MICROSOFT NETWORKS 1.03")) {
574 protocols |= PROT_MICROSOFT_NETWORKS_1_03;
575 } else if (strcsequal(cliprotos[i], "MICROSOFT NETWORKS 3.0")) {
576 protocols |= PROT_MICROSOFT_NETWORKS_3_0;
577 } else if (strcsequal(cliprotos[i], "PC NETWORK PROGRAM 1.0")) {
578 protocols |= PROT_PC_NETWORK_PROGRAM_1_0;
579 } else if (strcsequal(cliprotos[i], "XENIX CORE")) {
580 protocols |= PROT_XENIX_CORE;
581 } else if (strcsequal(cliprotos[i], "Samba")) {
582 protocols = PROT_SAMBA;
583 break;
584 } else if (strcsequal(cliprotos[i], "POSIX 2")) {
585 protocols = PROT_POSIX_2;
586 break;
590 switch ( protocols ) {
591 /* Old CIFSFS can send one arch only, NT LM 0.12. */
592 case PROT_NT_LM_0_12:
593 case ARCH_CIFSFS:
594 set_remote_arch(RA_CIFSFS);
595 break;
596 case ARCH_SAMBA:
597 set_remote_arch(RA_SAMBA);
598 break;
599 case ARCH_WFWG:
600 set_remote_arch(RA_WFWG);
601 break;
602 case ARCH_WIN95:
603 set_remote_arch(RA_WIN95);
604 break;
605 case ARCH_WINNT:
606 set_remote_arch(RA_WINNT);
607 break;
608 case ARCH_WIN2K:
609 set_remote_arch(RA_WIN2K);
610 break;
611 case ARCH_VISTA:
612 set_remote_arch(RA_VISTA);
613 break;
614 case ARCH_OS2:
615 set_remote_arch(RA_OS2);
616 break;
617 case ARCH_OSX:
618 set_remote_arch(RA_OSX);
619 break;
620 default:
621 set_remote_arch(RA_UNKNOWN);
622 break;
625 /* possibly reload - change of architecture */
626 reload_services(sconn, conn_snum_used, true);
629 * Anything higher than PROTOCOL_SMB2_10 still
630 * needs to go via "SMB 2.???", which is marked
631 * as PROTOCOL_SMB2_10.
633 * The real negotiation happens via reply_smb20ff()
634 * using SMB2 Negotiation.
636 max_proto = lp_server_max_protocol();
637 if (max_proto > PROTOCOL_SMB2_10) {
638 max_proto = PROTOCOL_SMB2_10;
640 min_proto = lp_server_min_protocol();
641 if (min_proto > PROTOCOL_SMB2_10) {
642 min_proto = PROTOCOL_SMB2_10;
645 /* Check for protocols, most desirable first */
646 for (protocol = 0; supported_protocols[protocol].proto_name; protocol++) {
647 i = 0;
648 if ((supported_protocols[protocol].protocol_level <= max_proto) &&
649 (supported_protocols[protocol].protocol_level >= min_proto))
650 while (i < num_cliprotos) {
651 if (strequal(cliprotos[i],supported_protocols[protocol].proto_name)) {
652 choice = i;
653 chosen_level = supported_protocols[protocol].protocol_level;
654 choice_set = true;
656 i++;
658 if (choice_set) {
659 break;
663 if (!choice_set) {
664 bool ok;
666 DBG_NOTICE("No protocol supported !\n");
667 reply_smb1_outbuf(req, 1, 0);
668 SSVAL(req->outbuf, smb_vwv0, NO_PROTOCOL_CHOSEN);
670 ok = smb1_srv_send(xconn, (char *)req->outbuf, false, 0, false);
671 if (!ok) {
672 DBG_NOTICE("smb1_srv_send failed\n");
674 exit_server_cleanly("no protocol supported\n");
677 set_remote_proto(supported_protocols[protocol].short_name);
678 reload_services(sconn, conn_snum_used, true);
679 status = supported_protocols[protocol].proto_reply_fn(req, choice);
680 if (!NT_STATUS_IS_OK(status)) {
681 exit_server_cleanly("negprot function failed\n");
684 DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
686 DBG_INFO("negprot index=%zu\n", choice);
688 xconn->smb1.negprot.done = true;
690 /* We always have xconn->smb1.signing_state also for >= SMB2_02 */
691 signing_required = smb1_signing_is_mandatory(xconn->smb1.signing_state);
692 if (signing_required && (chosen_level < PROTOCOL_NT1)) {
693 exit_server_cleanly("SMB signing is required and "
694 "client negotiated a downlevel protocol");
697 TALLOC_FREE(cliprotos);
699 if (lp_async_smb_echo_handler() && (chosen_level < PROTOCOL_SMB2_02) &&
700 !fork_echo_handler(xconn)) {
701 exit_server("Failed to fork echo handler");
704 END_PROFILE(SMBnegprot);
705 return;