2 Unix SMB/CIFS implementation.
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/>.
22 #include "smbd/smbd.h"
23 #include "smbd/globals.h"
24 #include "../libcli/auth/spnego.h"
28 #include "smbprofile.h"
29 #include "auth/gensec/gensec.h"
30 #include "../libcli/smb/smb_signing.h"
32 extern fstring remote_proto
;
34 static void get_challenge(struct smbd_server_connection
*sconn
, uint8 buff
[8])
36 struct smbXsrv_connection
*xconn
= sconn
->conn
;
39 /* We might be called more than once, multiple negprots are
41 if (xconn
->smb1
.negprot
.auth_context
) {
42 DEBUG(3, ("get challenge: is this a secondary negprot? "
43 "sconn->negprot.auth_context is non-NULL!\n"));
44 TALLOC_FREE(xconn
->smb1
.negprot
.auth_context
);
47 DEBUG(10, ("get challenge: creating negprot_global_auth_context\n"));
48 nt_status
= make_auth4_context(
49 xconn
, &xconn
->smb1
.negprot
.auth_context
);
50 if (!NT_STATUS_IS_OK(nt_status
)) {
51 DEBUG(0, ("make_auth_context_subsystem returned %s",
52 nt_errstr(nt_status
)));
53 smb_panic("cannot make_negprot_global_auth_context!");
55 DEBUG(10, ("get challenge: getting challenge\n"));
56 xconn
->smb1
.negprot
.auth_context
->get_ntlm_challenge(
57 xconn
->smb1
.negprot
.auth_context
, buff
);
60 /****************************************************************************
61 Reply for the lanman 1.0 protocol.
62 ****************************************************************************/
64 static void reply_lanman1(struct smb_request
*req
, uint16 choice
)
67 time_t t
= time(NULL
);
68 struct smbd_server_connection
*sconn
= req
->sconn
;
69 struct smbXsrv_connection
*xconn
= sconn
->conn
;
71 if (lp_async_smb_echo_handler()) {
74 raw
= (lp_read_raw()?1:0) | (lp_write_raw()?2:0);
77 xconn
->smb1
.negprot
.encrypted_passwords
= lp_encrypt_passwords();
79 secword
|= NEGOTIATE_SECURITY_USER_LEVEL
;
80 if (xconn
->smb1
.negprot
.encrypted_passwords
) {
81 secword
|= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
;
84 reply_outbuf(req
, 13, xconn
->smb1
.negprot
.encrypted_passwords
?8:0);
86 SSVAL(req
->outbuf
,smb_vwv0
,choice
);
87 SSVAL(req
->outbuf
,smb_vwv1
,secword
);
88 /* Create a token value and add it to the outgoing packet. */
89 if (xconn
->smb1
.negprot
.encrypted_passwords
) {
90 get_challenge(sconn
, (uint8
*)smb_buf(req
->outbuf
));
91 SSVAL(req
->outbuf
,smb_vwv11
, 8);
94 smbXsrv_connection_init_tables(req
->sconn
->conn
, PROTOCOL_LANMAN1
);
96 /* Reply, SMBlockread, SMBwritelock supported. */
97 SCVAL(req
->outbuf
,smb_flg
, FLAG_REPLY
|FLAG_SUPPORT_LOCKREAD
);
98 SSVAL(req
->outbuf
,smb_vwv2
, xconn
->smb1
.negprot
.max_recv
);
99 SSVAL(req
->outbuf
,smb_vwv3
, lp_max_mux()); /* maxmux */
100 SSVAL(req
->outbuf
,smb_vwv4
, 1);
101 SSVAL(req
->outbuf
,smb_vwv5
, raw
); /* tell redirector we support
102 readbraw writebraw (possibly) */
103 SIVAL(req
->outbuf
,smb_vwv6
, getpid());
104 SSVAL(req
->outbuf
,smb_vwv10
, set_server_zone_offset(t
)/60);
106 srv_put_dos_date((char *)req
->outbuf
,smb_vwv8
,t
);
111 /****************************************************************************
112 Reply for the lanman 2.0 protocol.
113 ****************************************************************************/
115 static void reply_lanman2(struct smb_request
*req
, uint16 choice
)
118 time_t t
= time(NULL
);
119 struct smbd_server_connection
*sconn
= req
->sconn
;
120 struct smbXsrv_connection
*xconn
= sconn
->conn
;
122 if (lp_async_smb_echo_handler()) {
125 raw
= (lp_read_raw()?1:0) | (lp_write_raw()?2:0);
128 xconn
->smb1
.negprot
.encrypted_passwords
= lp_encrypt_passwords();
130 secword
|= NEGOTIATE_SECURITY_USER_LEVEL
;
131 if (xconn
->smb1
.negprot
.encrypted_passwords
) {
132 secword
|= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
;
135 reply_outbuf(req
, 13, xconn
->smb1
.negprot
.encrypted_passwords
?8:0);
137 SSVAL(req
->outbuf
,smb_vwv0
, choice
);
138 SSVAL(req
->outbuf
,smb_vwv1
, secword
);
139 SIVAL(req
->outbuf
,smb_vwv6
, getpid());
141 /* Create a token value and add it to the outgoing packet. */
142 if (xconn
->smb1
.negprot
.encrypted_passwords
) {
143 get_challenge(sconn
, (uint8
*)smb_buf(req
->outbuf
));
144 SSVAL(req
->outbuf
,smb_vwv11
, 8);
147 smbXsrv_connection_init_tables(req
->sconn
->conn
, PROTOCOL_LANMAN2
);
149 /* Reply, SMBlockread, SMBwritelock supported. */
150 SCVAL(req
->outbuf
,smb_flg
,FLAG_REPLY
|FLAG_SUPPORT_LOCKREAD
);
151 SSVAL(req
->outbuf
,smb_vwv2
,xconn
->smb1
.negprot
.max_recv
);
152 SSVAL(req
->outbuf
,smb_vwv3
,lp_max_mux());
153 SSVAL(req
->outbuf
,smb_vwv4
,1);
154 SSVAL(req
->outbuf
,smb_vwv5
,raw
); /* readbraw and/or writebraw */
155 SSVAL(req
->outbuf
,smb_vwv10
, set_server_zone_offset(t
)/60);
156 srv_put_dos_date((char *)req
->outbuf
,smb_vwv8
,t
);
159 /****************************************************************************
160 Generate the spnego negprot reply blob. Return the number of bytes used.
161 ****************************************************************************/
163 DATA_BLOB
negprot_spnego(TALLOC_CTX
*ctx
, struct smbd_server_connection
*sconn
)
165 struct smbXsrv_connection
*xconn
= sconn
->conn
;
166 DATA_BLOB blob
= data_blob_null
;
167 DATA_BLOB blob_out
= data_blob_null
;
174 struct gensec_security
*gensec_security
;
176 /* See if we can get an SPNEGO blob */
177 status
= auth_generic_prepare(talloc_tos(),
178 sconn
->remote_address
,
180 if (NT_STATUS_IS_OK(status
)) {
181 status
= gensec_start_mech_by_oid(gensec_security
, GENSEC_OID_SPNEGO
);
182 if (NT_STATUS_IS_OK(status
)) {
183 status
= gensec_update(gensec_security
, ctx
,
184 data_blob_null
, &blob
);
185 /* If we get the list of OIDs, the 'OK' answer
186 * is NT_STATUS_MORE_PROCESSING_REQUIRED */
187 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
188 DEBUG(0, ("Failed to start SPNEGO handler for negprot OID list!\n"));
189 blob
= data_blob_null
;
192 TALLOC_FREE(gensec_security
);
195 xconn
->smb1
.negprot
.spnego
= true;
197 /* strangely enough, NT does not sent the single OID NTLMSSP when
198 not a ADS member, it sends no OIDs at all
200 OLD COMMENT : "we can't do this until we teach our sesssion setup parser to know
201 about raw NTLMSSP (clients send no ASN.1 wrapping if we do this)"
203 Our sessionsetup code now handles raw NTLMSSP connects, so we can go
204 back to doing what W2K3 does here. This is needed to make PocketPC 2003
205 CIFS connections work with SPNEGO. See bugzilla bugs #1828 and #3133
210 if (blob
.length
== 0 || blob
.data
== NULL
) {
211 return data_blob_null
;
214 blob_out
= data_blob_talloc(ctx
, NULL
, 16 + blob
.length
);
215 if (blob_out
.data
== NULL
) {
216 data_blob_free(&blob
);
217 return data_blob_null
;
220 memset(blob_out
.data
, '\0', 16);
222 checked_strlcpy(unix_name
, lp_netbios_name(), sizeof(unix_name
));
223 (void)strlower_m(unix_name
);
224 push_ascii_nstring(dos_name
, unix_name
);
225 strlcpy((char *)blob_out
.data
, dos_name
, 17);
228 /* Fix valgrind 'uninitialized bytes' issue. */
229 slen
= strlen(dos_name
);
231 memset(blob_out
.data
+slen
, '\0', 16 - slen
);
235 memcpy(&blob_out
.data
[16], blob
.data
, blob
.length
);
237 data_blob_free(&blob
);
242 /****************************************************************************
243 Reply for the nt protocol.
244 ****************************************************************************/
246 static void reply_nt1(struct smb_request
*req
, uint16 choice
)
248 /* dual names + lock_and_read + nt SMBs + remote API calls */
249 int capabilities
= CAP_NT_FIND
|CAP_LOCK_AND_READ
|
250 CAP_LEVEL_II_OPLOCKS
;
253 bool negotiate_spnego
= False
;
256 struct smbd_server_connection
*sconn
= req
->sconn
;
257 struct smbXsrv_connection
*xconn
= sconn
->conn
;
258 bool signing_desired
= false;
259 bool signing_required
= false;
261 xconn
->smb1
.negprot
.encrypted_passwords
= lp_encrypt_passwords();
263 /* Check the flags field to see if this is Vista.
264 WinXP sets it and Vista does not. But we have to
265 distinguish from NT which doesn't set it either. */
267 if ( (req
->flags2
& FLAGS2_EXTENDED_SECURITY
) &&
268 ((req
->flags2
& FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED
) == 0) )
270 if ((get_remote_arch() != RA_SAMBA
) &&
271 (get_remote_arch() != RA_CIFSFS
)) {
272 set_remote_arch( RA_VISTA
);
276 reply_outbuf(req
,17,0);
278 /* do spnego in user level security if the client
279 supports it and we can do encrypted passwords */
281 if (xconn
->smb1
.negprot
.encrypted_passwords
&&
283 (req
->flags2
& FLAGS2_EXTENDED_SECURITY
)) {
284 negotiate_spnego
= True
;
285 capabilities
|= CAP_EXTENDED_SECURITY
;
286 add_to_common_flags2(FLAGS2_EXTENDED_SECURITY
);
287 /* Ensure FLAGS2_EXTENDED_SECURITY gets set in this reply
288 (already partially constructed. */
289 SSVAL(req
->outbuf
, smb_flg2
,
290 req
->flags2
| FLAGS2_EXTENDED_SECURITY
);
293 capabilities
|= CAP_NT_SMBS
|CAP_RPC_REMOTE_APIS
;
296 capabilities
|= CAP_UNICODE
;
299 if (lp_unix_extensions()) {
300 capabilities
|= CAP_UNIX
;
303 if (lp_large_readwrite())
304 capabilities
|= CAP_LARGE_READX
|CAP_LARGE_WRITEX
|CAP_W2K_SMBS
;
306 capabilities
|= CAP_LARGE_FILES
;
308 if (!lp_async_smb_echo_handler() && lp_read_raw() && lp_write_raw())
309 capabilities
|= CAP_RAW_MODE
;
311 if (lp_nt_status_support())
312 capabilities
|= CAP_STATUS32
;
315 capabilities
|= CAP_DFS
;
317 secword
|= NEGOTIATE_SECURITY_USER_LEVEL
;
318 if (xconn
->smb1
.negprot
.encrypted_passwords
) {
319 secword
|= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
;
322 signing_desired
= smb_signing_is_desired(xconn
->smb1
.signing_state
);
323 signing_required
= smb_signing_is_mandatory(xconn
->smb1
.signing_state
);
325 if (signing_desired
) {
326 secword
|= NEGOTIATE_SECURITY_SIGNATURES_ENABLED
;
327 /* No raw mode with smb signing. */
328 capabilities
&= ~CAP_RAW_MODE
;
329 if (signing_required
) {
330 secword
|=NEGOTIATE_SECURITY_SIGNATURES_REQUIRED
;
334 SSVAL(req
->outbuf
,smb_vwv0
,choice
);
335 SCVAL(req
->outbuf
,smb_vwv1
,secword
);
337 smbXsrv_connection_init_tables(req
->sconn
->conn
, PROTOCOL_NT1
);
339 SSVAL(req
->outbuf
,smb_vwv1
+1, lp_max_mux()); /* maxmpx */
340 SSVAL(req
->outbuf
,smb_vwv2
+1, 1); /* num vcs */
341 SIVAL(req
->outbuf
,smb_vwv3
+1,
342 xconn
->smb1
.negprot
.max_recv
); /* max buffer. LOTS! */
343 SIVAL(req
->outbuf
,smb_vwv5
+1, 0x10000); /* raw size. full 64k */
344 SIVAL(req
->outbuf
,smb_vwv7
+1, getpid()); /* session key */
345 SIVAL(req
->outbuf
,smb_vwv9
+1, capabilities
); /* capabilities */
346 clock_gettime(CLOCK_REALTIME
,&ts
);
347 put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER
,(char *)req
->outbuf
+smb_vwv11
+1,ts
);
348 SSVALS(req
->outbuf
,smb_vwv15
+1,set_server_zone_offset(ts
.tv_sec
)/60);
350 if (!negotiate_spnego
) {
351 /* Create a token value and add it to the outgoing packet. */
352 if (xconn
->smb1
.negprot
.encrypted_passwords
) {
354 /* note that we do not send a challenge at all if
355 we are using plaintext */
356 get_challenge(sconn
, chal
);
357 ret
= message_push_blob(
358 &req
->outbuf
, data_blob_const(chal
, sizeof(chal
)));
360 DEBUG(0, ("Could not push challenge\n"));
361 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
364 SCVAL(req
->outbuf
, smb_vwv16
+1, ret
);
366 ret
= message_push_string(&req
->outbuf
, lp_workgroup(),
367 STR_UNICODE
|STR_TERMINATE
370 DEBUG(0, ("Could not push workgroup string\n"));
371 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
374 ret
= message_push_string(&req
->outbuf
, lp_netbios_name(),
375 STR_UNICODE
|STR_TERMINATE
378 DEBUG(0, ("Could not push netbios name string\n"));
379 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
382 DEBUG(3,("not using SPNEGO\n"));
384 DATA_BLOB spnego_blob
= negprot_spnego(req
, req
->sconn
);
386 if (spnego_blob
.data
== NULL
) {
387 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
391 ret
= message_push_blob(&req
->outbuf
, spnego_blob
);
393 DEBUG(0, ("Could not push spnego blob\n"));
394 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
397 data_blob_free(&spnego_blob
);
399 SCVAL(req
->outbuf
,smb_vwv16
+1, 0);
400 DEBUG(3,("using SPNEGO\n"));
406 /* these are the protocol lists used for auto architecture detection:
409 protocol [PC NETWORK PROGRAM 1.0]
410 protocol [XENIX CORE]
411 protocol [MICROSOFT NETWORKS 1.03]
413 protocol [Windows for Workgroups 3.1a]
416 protocol [NT LM 0.12]
419 protocol [PC NETWORK PROGRAM 1.0]
420 protocol [XENIX CORE]
421 protocol [MICROSOFT NETWORKS 1.03]
423 protocol [Windows for Workgroups 3.1a]
426 protocol [NT LM 0.12]
429 protocol [PC NETWORK PROGRAM 1.0]
431 protocol [Windows for Workgroups 3.1a]
434 protocol [NT LM 0.12]
437 protocol [PC NETWORK PROGRAM 1.0]
439 protocol [Windows for Workgroups 3.1a]
442 protocol [NT LM 0.12]
446 protocol [PC NETWORK PROGRAM 1.0]
447 protocol [XENIX CORE]
454 * Modified to recognize the architecture of the remote machine better.
456 * This appears to be the matrix of which protocol is used by which
458 Protocol WfWg Win95 WinNT Win2K OS/2 Vista
459 PC NETWORK PROGRAM 1.0 1 1 1 1 1 1
461 MICROSOFT NETWORKS 3.0 2 2
463 MICROSOFT NETWORKS 1.03 3
466 Windows for Workgroups 3.1a 5 5 5 3 3
472 * tim@fsg.com 09/29/95
473 * Win2K added by matty 17/7/99
476 #define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
477 #define ARCH_WIN95 0x2
478 #define ARCH_WINNT 0x4
479 #define ARCH_WIN2K 0xC /* Win2K is like NT */
480 #define ARCH_OS2 0x14 /* Again OS/2 is like NT */
481 #define ARCH_SAMBA 0x20
482 #define ARCH_CIFSFS 0x40
483 #define ARCH_VISTA 0x8C /* Vista is like XP/2K */
485 #define ARCH_ALL 0x7F
487 /* List of supported protocols, most desired first */
488 static const struct {
489 const char *proto_name
;
490 const char *short_name
;
491 void (*proto_reply_fn
)(struct smb_request
*req
, uint16 choice
);
493 } supported_protocols
[] = {
494 {"SMB 2.???", "SMB2_FF", reply_smb20ff
, PROTOCOL_SMB2_10
},
495 {"SMB 2.002", "SMB2_02", reply_smb2002
, PROTOCOL_SMB2_02
},
496 {"NT LANMAN 1.0", "NT1", reply_nt1
, PROTOCOL_NT1
},
497 {"NT LM 0.12", "NT1", reply_nt1
, PROTOCOL_NT1
},
498 {"POSIX 2", "NT1", reply_nt1
, PROTOCOL_NT1
},
499 {"LANMAN2.1", "LANMAN2", reply_lanman2
, PROTOCOL_LANMAN2
},
500 {"LM1.2X002", "LANMAN2", reply_lanman2
, PROTOCOL_LANMAN2
},
501 {"Samba", "LANMAN2", reply_lanman2
, PROTOCOL_LANMAN2
},
502 {"DOS LM1.2X002", "LANMAN2", reply_lanman2
, PROTOCOL_LANMAN2
},
503 {"LANMAN1.0", "LANMAN1", reply_lanman1
, PROTOCOL_LANMAN1
},
504 {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1
, PROTOCOL_LANMAN1
},
508 /****************************************************************************
510 conn POINTER CAN BE NULL HERE !
511 ****************************************************************************/
513 void reply_negprot(struct smb_request
*req
)
516 int chosen_level
= -1;
523 size_t converted_size
;
524 struct smbd_server_connection
*sconn
= req
->sconn
;
525 struct smbXsrv_connection
*xconn
= sconn
->conn
;
527 START_PROFILE(SMBnegprot
);
529 if (xconn
->smb1
.negprot
.done
) {
530 END_PROFILE(SMBnegprot
);
531 exit_server_cleanly("multiple negprot's are not permitted");
533 xconn
->smb1
.negprot
.done
= true;
535 if (req
->buflen
== 0) {
536 DEBUG(0, ("negprot got no protocols\n"));
537 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
538 END_PROFILE(SMBnegprot
);
542 if (req
->buf
[req
->buflen
-1] != '\0') {
543 DEBUG(0, ("negprot protocols not 0-terminated\n"));
544 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
545 END_PROFILE(SMBnegprot
);
549 p
= (const char *)req
->buf
+ 1;
554 while (smbreq_bufrem(req
, p
) > 0) {
558 tmp
= talloc_realloc(talloc_tos(), cliprotos
, char *,
561 DEBUG(0, ("talloc failed\n"));
562 TALLOC_FREE(cliprotos
);
563 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
564 END_PROFILE(SMBnegprot
);
570 if (!pull_ascii_talloc(cliprotos
, &cliprotos
[num_cliprotos
], p
,
572 DEBUG(0, ("pull_ascii_talloc failed\n"));
573 TALLOC_FREE(cliprotos
);
574 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
575 END_PROFILE(SMBnegprot
);
579 DEBUG(3, ("Requested protocol [%s]\n",
580 cliprotos
[num_cliprotos
]));
586 for (i
=0; i
<num_cliprotos
; i
++) {
587 if (strcsequal(cliprotos
[i
], "Windows for Workgroups 3.1a"))
588 arch
&= ( ARCH_WFWG
| ARCH_WIN95
| ARCH_WINNT
590 else if (strcsequal(cliprotos
[i
], "DOS LM1.2X002"))
591 arch
&= ( ARCH_WFWG
| ARCH_WIN95
);
592 else if (strcsequal(cliprotos
[i
], "DOS LANMAN2.1"))
593 arch
&= ( ARCH_WFWG
| ARCH_WIN95
);
594 else if (strcsequal(cliprotos
[i
], "NT LM 0.12"))
595 arch
&= ( ARCH_WIN95
| ARCH_WINNT
| ARCH_WIN2K
597 else if (strcsequal(cliprotos
[i
], "SMB 2.001"))
599 else if (strcsequal(cliprotos
[i
], "LANMAN2.1"))
600 arch
&= ( ARCH_WINNT
| ARCH_WIN2K
| ARCH_OS2
);
601 else if (strcsequal(cliprotos
[i
], "LM1.2X002"))
602 arch
&= ( ARCH_WINNT
| ARCH_WIN2K
| ARCH_OS2
);
603 else if (strcsequal(cliprotos
[i
], "MICROSOFT NETWORKS 1.03"))
605 else if (strcsequal(cliprotos
[i
], "XENIX CORE"))
606 arch
&= ( ARCH_WINNT
| ARCH_OS2
);
607 else if (strcsequal(cliprotos
[i
], "Samba")) {
610 } else if (strcsequal(cliprotos
[i
], "POSIX 2")) {
616 /* CIFSFS can send one arch only, NT LM 0.12. */
617 if (i
== 1 && (arch
& ARCH_CIFSFS
)) {
623 set_remote_arch(RA_CIFSFS
);
626 set_remote_arch(RA_SAMBA
);
629 set_remote_arch(RA_WFWG
);
632 set_remote_arch(RA_WIN95
);
635 if(req
->flags2
== FLAGS2_WIN2K_SIGNATURE
)
636 set_remote_arch(RA_WIN2K
);
638 set_remote_arch(RA_WINNT
);
641 /* Vista may have been set in the negprot so don't
643 if ( get_remote_arch() != RA_VISTA
)
644 set_remote_arch(RA_WIN2K
);
647 set_remote_arch(RA_VISTA
);
650 set_remote_arch(RA_OS2
);
653 set_remote_arch(RA_UNKNOWN
);
657 /* possibly reload - change of architecture */
658 reload_services(sconn
, conn_snum_used
, true);
660 /* moved from the netbios session setup code since we don't have that
661 when the client connects to port 445. Of course there is a small
662 window where we are listening to messages -- jerry */
664 serverid_register(messaging_server_id(sconn
->msg_ctx
),
665 FLAG_MSG_GENERAL
|FLAG_MSG_SMBD
666 |FLAG_MSG_PRINT_GENERAL
);
668 /* Check for protocols, most desirable first */
669 for (protocol
= 0; supported_protocols
[protocol
].proto_name
; protocol
++) {
671 if ((supported_protocols
[protocol
].protocol_level
<= lp_server_max_protocol()) &&
672 (supported_protocols
[protocol
].protocol_level
>= lp_server_min_protocol()))
673 while (i
< num_cliprotos
) {
674 if (strequal(cliprotos
[i
],supported_protocols
[protocol
].proto_name
)) {
676 chosen_level
= supported_protocols
[protocol
].protocol_level
;
685 fstrcpy(remote_proto
,supported_protocols
[protocol
].short_name
);
686 reload_services(sconn
, conn_snum_used
, true);
687 supported_protocols
[protocol
].proto_reply_fn(req
, choice
);
688 DEBUG(3,("Selected protocol %s\n",supported_protocols
[protocol
].proto_name
));
690 DEBUG(0,("No protocol supported !\n"));
691 reply_outbuf(req
, 1, 0);
692 SSVAL(req
->outbuf
, smb_vwv0
, choice
);
695 DEBUG( 5, ( "negprot index=%d\n", choice
) );
697 if ((lp_server_signing() == SMB_SIGNING_REQUIRED
)
698 && (chosen_level
< PROTOCOL_NT1
)) {
699 exit_server_cleanly("SMB signing is required and "
700 "client negotiated a downlevel protocol");
703 TALLOC_FREE(cliprotos
);
705 if (lp_async_smb_echo_handler() && (chosen_level
< PROTOCOL_SMB2_02
) &&
706 !fork_echo_handler(sconn
)) {
707 exit_server("Failed to fork echo handler");
710 END_PROFILE(SMBnegprot
);