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"
27 #include "ntlmssp_wrap.h"
29 #include "smbprofile.h"
30 #include "auth/gensec/gensec.h"
31 #include "../libcli/smb/smb_signing.h"
33 extern fstring remote_proto
;
35 static void get_challenge(struct smbd_server_connection
*sconn
, uint8 buff
[8])
39 /* We might be called more than once, multiple negprots are
41 if (sconn
->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(sconn
->smb1
.negprot
.auth_context
);
47 DEBUG(10, ("get challenge: creating negprot_global_auth_context\n"));
48 nt_status
= make_auth_context_subsystem(
49 sconn
, &sconn
->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 sconn
->smb1
.negprot
.auth_context
->get_ntlm_challenge(
57 sconn
->smb1
.negprot
.auth_context
, buff
);
60 /****************************************************************************
61 Reply for the core protocol.
62 ****************************************************************************/
64 static void reply_corep(struct smb_request
*req
, uint16 choice
)
66 reply_outbuf(req
, 1, 0);
67 SSVAL(req
->outbuf
, smb_vwv0
, choice
);
69 set_Protocol(PROTOCOL_CORE
);
72 /****************************************************************************
73 Reply for the coreplus protocol.
74 ****************************************************************************/
76 static void reply_coreplus(struct smb_request
*req
, uint16 choice
)
78 int raw
= (lp_readraw()?1:0) | (lp_writeraw()?2:0);
80 reply_outbuf(req
, 13, 0);
82 SSVAL(req
->outbuf
,smb_vwv0
,choice
);
83 SSVAL(req
->outbuf
,smb_vwv5
,raw
); /* tell redirector we support
84 readbraw and writebraw (possibly) */
85 /* Reply, SMBlockread, SMBwritelock supported. */
86 SCVAL(req
->outbuf
,smb_flg
,FLAG_REPLY
|FLAG_SUPPORT_LOCKREAD
);
87 SSVAL(req
->outbuf
,smb_vwv1
,0x1); /* user level security, don't
89 set_Protocol(PROTOCOL_COREPLUS
);
92 /****************************************************************************
93 Reply for the lanman 1.0 protocol.
94 ****************************************************************************/
96 static void reply_lanman1(struct smb_request
*req
, uint16 choice
)
98 int raw
= (lp_readraw()?1:0) | (lp_writeraw()?2:0);
100 time_t t
= time(NULL
);
101 struct smbd_server_connection
*sconn
= req
->sconn
;
103 sconn
->smb1
.negprot
.encrypted_passwords
= lp_encrypted_passwords();
105 if (lp_security()>=SEC_USER
) {
106 secword
|= NEGOTIATE_SECURITY_USER_LEVEL
;
108 if (sconn
->smb1
.negprot
.encrypted_passwords
) {
109 secword
|= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
;
112 reply_outbuf(req
, 13, sconn
->smb1
.negprot
.encrypted_passwords
?8:0);
114 SSVAL(req
->outbuf
,smb_vwv0
,choice
);
115 SSVAL(req
->outbuf
,smb_vwv1
,secword
);
116 /* Create a token value and add it to the outgoing packet. */
117 if (sconn
->smb1
.negprot
.encrypted_passwords
) {
118 get_challenge(sconn
, (uint8
*)smb_buf(req
->outbuf
));
119 SSVAL(req
->outbuf
,smb_vwv11
, 8);
122 set_Protocol(PROTOCOL_LANMAN1
);
124 /* Reply, SMBlockread, SMBwritelock supported. */
125 SCVAL(req
->outbuf
,smb_flg
,FLAG_REPLY
|FLAG_SUPPORT_LOCKREAD
);
126 SSVAL(req
->outbuf
,smb_vwv2
,sconn
->smb1
.negprot
.max_recv
);
127 SSVAL(req
->outbuf
,smb_vwv3
,lp_maxmux()); /* maxmux */
128 SSVAL(req
->outbuf
,smb_vwv4
,1);
129 SSVAL(req
->outbuf
,smb_vwv5
,raw
); /* tell redirector we support
130 readbraw writebraw (possibly) */
131 SIVAL(req
->outbuf
,smb_vwv6
,sys_getpid());
132 SSVAL(req
->outbuf
,smb_vwv10
, set_server_zone_offset(t
)/60);
134 srv_put_dos_date((char *)req
->outbuf
,smb_vwv8
,t
);
139 /****************************************************************************
140 Reply for the lanman 2.0 protocol.
141 ****************************************************************************/
143 static void reply_lanman2(struct smb_request
*req
, uint16 choice
)
145 int raw
= (lp_readraw()?1:0) | (lp_writeraw()?2:0);
147 time_t t
= time(NULL
);
148 struct smbd_server_connection
*sconn
= req
->sconn
;
150 sconn
->smb1
.negprot
.encrypted_passwords
= lp_encrypted_passwords();
152 if (lp_security()>=SEC_USER
) {
153 secword
|= NEGOTIATE_SECURITY_USER_LEVEL
;
155 if (sconn
->smb1
.negprot
.encrypted_passwords
) {
156 secword
|= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
;
159 reply_outbuf(req
, 13, sconn
->smb1
.negprot
.encrypted_passwords
?8:0);
161 SSVAL(req
->outbuf
,smb_vwv0
,choice
);
162 SSVAL(req
->outbuf
,smb_vwv1
,secword
);
163 SIVAL(req
->outbuf
,smb_vwv6
,sys_getpid());
165 /* Create a token value and add it to the outgoing packet. */
166 if (sconn
->smb1
.negprot
.encrypted_passwords
) {
167 get_challenge(sconn
, (uint8
*)smb_buf(req
->outbuf
));
168 SSVAL(req
->outbuf
,smb_vwv11
, 8);
171 set_Protocol(PROTOCOL_LANMAN2
);
173 /* Reply, SMBlockread, SMBwritelock supported. */
174 SCVAL(req
->outbuf
,smb_flg
,FLAG_REPLY
|FLAG_SUPPORT_LOCKREAD
);
175 SSVAL(req
->outbuf
,smb_vwv2
,sconn
->smb1
.negprot
.max_recv
);
176 SSVAL(req
->outbuf
,smb_vwv3
,lp_maxmux());
177 SSVAL(req
->outbuf
,smb_vwv4
,1);
178 SSVAL(req
->outbuf
,smb_vwv5
,raw
); /* readbraw and/or writebraw */
179 SSVAL(req
->outbuf
,smb_vwv10
, set_server_zone_offset(t
)/60);
180 srv_put_dos_date((char *)req
->outbuf
,smb_vwv8
,t
);
183 /****************************************************************************
184 Generate the spnego negprot reply blob. Return the number of bytes used.
185 ****************************************************************************/
187 DATA_BLOB
negprot_spnego(TALLOC_CTX
*ctx
, struct smbd_server_connection
*sconn
)
189 DATA_BLOB blob
= data_blob_null
;
190 DATA_BLOB blob_out
= data_blob_null
;
197 const char *OIDs_krb5
[] = {OID_KERBEROS5
,
201 const char *OIDs_ntlm
[] = {OID_NTLMSSP
, NULL
};
202 struct auth_generic_state
*auth_ntlmssp_state
;
204 sconn
->use_gensec_hook
= false;
206 /* See if we can get an SPNEGO blob out of the gensec hook (if auth_samba4 is loaded) */
207 status
= auth_ntlmssp_prepare(sconn
->remote_address
,
208 &auth_ntlmssp_state
);
209 if (NT_STATUS_IS_OK(status
)) {
210 status
= auth_generic_start(auth_ntlmssp_state
, GENSEC_OID_SPNEGO
);
211 if (NT_STATUS_IS_OK(status
)) {
212 status
= gensec_update(auth_ntlmssp_state
->gensec_security
, ctx
,
213 NULL
, data_blob_null
, &blob
);
214 /* If we get the list of OIDs, the 'OK' answer
215 * is NT_STATUS_MORE_PROCESSING_REQUIRED */
216 if (NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
217 sconn
->use_gensec_hook
= true;
220 TALLOC_FREE(auth_ntlmssp_state
);
223 sconn
->smb1
.negprot
.spnego
= true;
225 /* strangely enough, NT does not sent the single OID NTLMSSP when
226 not a ADS member, it sends no OIDs at all
228 OLD COMMENT : "we can't do this until we teach our sesssion setup parser to know
229 about raw NTLMSSP (clients send no ASN.1 wrapping if we do this)"
231 Our sessionsetup code now handles raw NTLMSSP connects, so we can go
232 back to doing what W2K3 does here. This is needed to make PocketPC 2003
233 CIFS connections work with SPNEGO. See bugzilla bugs #1828 and #3133
238 if (sconn
->use_gensec_hook
) {
239 /* blob initialised above */
240 } else if (lp_security() != SEC_ADS
&& !USE_KERBEROS_KEYTAB
) {
242 /* Code for PocketPC client */
243 blob
= data_blob(guid
, 16);
245 /* Code for standalone WXP client */
246 blob
= spnego_gen_negTokenInit(ctx
, OIDs_ntlm
, NULL
, "NONE");
248 } else if (!lp_send_spnego_principal()) {
249 /* By default, Windows 2008 and later sends not_defined_in_RFC4178@please_ignore */
250 blob
= spnego_gen_negTokenInit(ctx
, OIDs_krb5
, NULL
, ADS_IGNORE_PRINCIPAL
);
253 char *host_princ_s
= NULL
;
254 name_to_fqdn(myname
, lp_netbios_name());
256 if (asprintf(&host_princ_s
, "cifs/%s@%s", myname
, lp_realm())
258 return data_blob_null
;
260 blob
= spnego_gen_negTokenInit(ctx
, OIDs_krb5
, NULL
, host_princ_s
);
261 SAFE_FREE(host_princ_s
);
264 if (blob
.length
== 0 || blob
.data
== NULL
) {
265 return data_blob_null
;
268 blob_out
= data_blob_talloc(ctx
, NULL
, 16 + blob
.length
);
269 if (blob_out
.data
== NULL
) {
270 data_blob_free(&blob
);
271 return data_blob_null
;
274 memset(blob_out
.data
, '\0', 16);
276 checked_strlcpy(unix_name
, lp_netbios_name(), sizeof(unix_name
));
277 strlower_m(unix_name
);
278 push_ascii_nstring(dos_name
, unix_name
);
279 strlcpy((char *)blob_out
.data
, dos_name
, 17);
282 /* Fix valgrind 'uninitialized bytes' issue. */
283 slen
= strlen(dos_name
);
285 memset(blob_out
.data
+slen
, '\0', 16 - slen
);
289 memcpy(&blob_out
.data
[16], blob
.data
, blob
.length
);
291 data_blob_free(&blob
);
296 /****************************************************************************
297 Reply for the nt protocol.
298 ****************************************************************************/
300 static void reply_nt1(struct smb_request
*req
, uint16 choice
)
302 /* dual names + lock_and_read + nt SMBs + remote API calls */
303 int capabilities
= CAP_NT_FIND
|CAP_LOCK_AND_READ
|
304 CAP_LEVEL_II_OPLOCKS
;
307 bool negotiate_spnego
= False
;
310 struct smbd_server_connection
*sconn
= req
->sconn
;
311 bool signing_enabled
= false;
312 bool signing_required
= false;
314 sconn
->smb1
.negprot
.encrypted_passwords
= lp_encrypted_passwords();
316 /* Check the flags field to see if this is Vista.
317 WinXP sets it and Vista does not. But we have to
318 distinguish from NT which doesn't set it either. */
320 if ( (req
->flags2
& FLAGS2_EXTENDED_SECURITY
) &&
321 ((req
->flags2
& FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED
) == 0) )
323 if (get_remote_arch() != RA_SAMBA
) {
324 set_remote_arch( RA_VISTA
);
328 reply_outbuf(req
,17,0);
330 /* do spnego in user level security if the client
331 supports it and we can do encrypted passwords */
333 if (sconn
->smb1
.negprot
.encrypted_passwords
&&
334 (lp_security() != SEC_SHARE
) &&
336 (req
->flags2
& FLAGS2_EXTENDED_SECURITY
)) {
337 negotiate_spnego
= True
;
338 capabilities
|= CAP_EXTENDED_SECURITY
;
339 add_to_common_flags2(FLAGS2_EXTENDED_SECURITY
);
340 /* Ensure FLAGS2_EXTENDED_SECURITY gets set in this reply
341 (already partially constructed. */
342 SSVAL(req
->outbuf
, smb_flg2
,
343 req
->flags2
| FLAGS2_EXTENDED_SECURITY
);
346 capabilities
|= CAP_NT_SMBS
|CAP_RPC_REMOTE_APIS
|CAP_UNICODE
;
348 if (lp_unix_extensions()) {
349 capabilities
|= CAP_UNIX
;
352 if (lp_large_readwrite() && (SMB_OFF_T_BITS
== 64))
353 capabilities
|= CAP_LARGE_READX
|CAP_LARGE_WRITEX
|CAP_W2K_SMBS
;
355 if (SMB_OFF_T_BITS
== 64)
356 capabilities
|= CAP_LARGE_FILES
;
358 if (lp_readraw() && lp_writeraw())
359 capabilities
|= CAP_RAW_MODE
;
361 if (lp_nt_status_support())
362 capabilities
|= CAP_STATUS32
;
365 capabilities
|= CAP_DFS
;
367 if (lp_security() >= SEC_USER
) {
368 secword
|= NEGOTIATE_SECURITY_USER_LEVEL
;
370 if (sconn
->smb1
.negprot
.encrypted_passwords
) {
371 secword
|= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
;
374 signing_enabled
= smb_signing_is_allowed(req
->sconn
->smb1
.signing_state
);
375 signing_required
= smb_signing_is_mandatory(req
->sconn
->smb1
.signing_state
);
377 if (signing_enabled
) {
378 if (lp_security() >= SEC_USER
) {
379 secword
|= NEGOTIATE_SECURITY_SIGNATURES_ENABLED
;
380 /* No raw mode with smb signing. */
381 capabilities
&= ~CAP_RAW_MODE
;
382 if (signing_required
) {
383 secword
|=NEGOTIATE_SECURITY_SIGNATURES_REQUIRED
;
386 DEBUG(0,("reply_nt1: smb signing is incompatible with share level security !\n"));
387 if (signing_required
) {
388 exit_server_cleanly("reply_nt1: smb signing required and share level security selected.");
393 SSVAL(req
->outbuf
,smb_vwv0
,choice
);
394 SCVAL(req
->outbuf
,smb_vwv1
,secword
);
396 set_Protocol(PROTOCOL_NT1
);
398 SSVAL(req
->outbuf
,smb_vwv1
+1,lp_maxmux()); /* maxmpx */
399 SSVAL(req
->outbuf
,smb_vwv2
+1,1); /* num vcs */
400 SIVAL(req
->outbuf
,smb_vwv3
+1,
401 sconn
->smb1
.negprot
.max_recv
); /* max buffer. LOTS! */
402 SIVAL(req
->outbuf
,smb_vwv5
+1,0x10000); /* raw size. full 64k */
403 SIVAL(req
->outbuf
,smb_vwv7
+1,sys_getpid()); /* session key */
404 SIVAL(req
->outbuf
,smb_vwv9
+1,capabilities
); /* capabilities */
405 clock_gettime(CLOCK_REALTIME
,&ts
);
406 put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER
,(char *)req
->outbuf
+smb_vwv11
+1,ts
);
407 SSVALS(req
->outbuf
,smb_vwv15
+1,set_server_zone_offset(ts
.tv_sec
)/60);
409 if (!negotiate_spnego
) {
410 /* Create a token value and add it to the outgoing packet. */
411 if (sconn
->smb1
.negprot
.encrypted_passwords
) {
413 /* note that we do not send a challenge at all if
414 we are using plaintext */
415 get_challenge(sconn
, chal
);
416 ret
= message_push_blob(
417 &req
->outbuf
, data_blob_const(chal
, sizeof(chal
)));
419 DEBUG(0, ("Could not push challenge\n"));
420 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
423 SCVAL(req
->outbuf
, smb_vwv16
+1, ret
);
425 ret
= message_push_string(&req
->outbuf
, lp_workgroup(),
426 STR_UNICODE
|STR_TERMINATE
429 DEBUG(0, ("Could not push workgroup string\n"));
430 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
433 ret
= message_push_string(&req
->outbuf
, lp_netbios_name(),
434 STR_UNICODE
|STR_TERMINATE
437 DEBUG(0, ("Could not push netbios name string\n"));
438 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
441 DEBUG(3,("not using SPNEGO\n"));
443 DATA_BLOB spnego_blob
= negprot_spnego(req
, req
->sconn
);
445 if (spnego_blob
.data
== NULL
) {
446 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
450 ret
= message_push_blob(&req
->outbuf
, spnego_blob
);
452 DEBUG(0, ("Could not push spnego blob\n"));
453 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
456 data_blob_free(&spnego_blob
);
458 SCVAL(req
->outbuf
,smb_vwv16
+1, 0);
459 DEBUG(3,("using SPNEGO\n"));
465 /* these are the protocol lists used for auto architecture detection:
468 protocol [PC NETWORK PROGRAM 1.0]
469 protocol [XENIX CORE]
470 protocol [MICROSOFT NETWORKS 1.03]
472 protocol [Windows for Workgroups 3.1a]
475 protocol [NT LM 0.12]
478 protocol [PC NETWORK PROGRAM 1.0]
479 protocol [XENIX CORE]
480 protocol [MICROSOFT NETWORKS 1.03]
482 protocol [Windows for Workgroups 3.1a]
485 protocol [NT LM 0.12]
488 protocol [PC NETWORK PROGRAM 1.0]
490 protocol [Windows for Workgroups 3.1a]
493 protocol [NT LM 0.12]
496 protocol [PC NETWORK PROGRAM 1.0]
498 protocol [Windows for Workgroups 3.1a]
501 protocol [NT LM 0.12]
505 protocol [PC NETWORK PROGRAM 1.0]
506 protocol [XENIX CORE]
513 * Modified to recognize the architecture of the remote machine better.
515 * This appears to be the matrix of which protocol is used by which
517 Protocol WfWg Win95 WinNT Win2K OS/2 Vista
518 PC NETWORK PROGRAM 1.0 1 1 1 1 1 1
520 MICROSOFT NETWORKS 3.0 2 2
522 MICROSOFT NETWORKS 1.03 3
525 Windows for Workgroups 3.1a 5 5 5 3 3
531 * tim@fsg.com 09/29/95
532 * Win2K added by matty 17/7/99
535 #define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
536 #define ARCH_WIN95 0x2
537 #define ARCH_WINNT 0x4
538 #define ARCH_WIN2K 0xC /* Win2K is like NT */
539 #define ARCH_OS2 0x14 /* Again OS/2 is like NT */
540 #define ARCH_SAMBA 0x20
541 #define ARCH_CIFSFS 0x40
542 #define ARCH_VISTA 0x8C /* Vista is like XP/2K */
544 #define ARCH_ALL 0x7F
546 /* List of supported protocols, most desired first */
547 static const struct {
548 const char *proto_name
;
549 const char *short_name
;
550 void (*proto_reply_fn
)(struct smb_request
*req
, uint16 choice
);
552 } supported_protocols
[] = {
553 {"SMB 2.???", "SMB2_FF", reply_smb20ff
, PROTOCOL_SMB2_10
},
554 {"SMB 2.002", "SMB2_02", reply_smb2002
, PROTOCOL_SMB2_02
},
555 {"NT LANMAN 1.0", "NT1", reply_nt1
, PROTOCOL_NT1
},
556 {"NT LM 0.12", "NT1", reply_nt1
, PROTOCOL_NT1
},
557 {"POSIX 2", "NT1", reply_nt1
, PROTOCOL_NT1
},
558 {"LANMAN2.1", "LANMAN2", reply_lanman2
, PROTOCOL_LANMAN2
},
559 {"LM1.2X002", "LANMAN2", reply_lanman2
, PROTOCOL_LANMAN2
},
560 {"Samba", "LANMAN2", reply_lanman2
, PROTOCOL_LANMAN2
},
561 {"DOS LM1.2X002", "LANMAN2", reply_lanman2
, PROTOCOL_LANMAN2
},
562 {"LANMAN1.0", "LANMAN1", reply_lanman1
, PROTOCOL_LANMAN1
},
563 {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1
, PROTOCOL_LANMAN1
},
564 {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus
, PROTOCOL_COREPLUS
},
565 {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep
, PROTOCOL_CORE
},
569 /****************************************************************************
571 conn POINTER CAN BE NULL HERE !
572 ****************************************************************************/
574 void reply_negprot(struct smb_request
*req
)
583 size_t converted_size
;
584 struct smbd_server_connection
*sconn
= req
->sconn
;
586 START_PROFILE(SMBnegprot
);
588 if (sconn
->smb1
.negprot
.done
) {
589 END_PROFILE(SMBnegprot
);
590 exit_server_cleanly("multiple negprot's are not permitted");
592 sconn
->smb1
.negprot
.done
= true;
594 if (req
->buflen
== 0) {
595 DEBUG(0, ("negprot got no protocols\n"));
596 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
597 END_PROFILE(SMBnegprot
);
601 if (req
->buf
[req
->buflen
-1] != '\0') {
602 DEBUG(0, ("negprot protocols not 0-terminated\n"));
603 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
604 END_PROFILE(SMBnegprot
);
608 p
= (const char *)req
->buf
+ 1;
613 while (smbreq_bufrem(req
, p
) > 0) {
617 tmp
= talloc_realloc(talloc_tos(), cliprotos
, char *,
620 DEBUG(0, ("talloc failed\n"));
621 TALLOC_FREE(cliprotos
);
622 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
623 END_PROFILE(SMBnegprot
);
629 if (!pull_ascii_talloc(cliprotos
, &cliprotos
[num_cliprotos
], p
,
631 DEBUG(0, ("pull_ascii_talloc failed\n"));
632 TALLOC_FREE(cliprotos
);
633 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
634 END_PROFILE(SMBnegprot
);
638 DEBUG(3, ("Requested protocol [%s]\n",
639 cliprotos
[num_cliprotos
]));
645 for (i
=0; i
<num_cliprotos
; i
++) {
646 if (strcsequal(cliprotos
[i
], "Windows for Workgroups 3.1a"))
647 arch
&= ( ARCH_WFWG
| ARCH_WIN95
| ARCH_WINNT
649 else if (strcsequal(cliprotos
[i
], "DOS LM1.2X002"))
650 arch
&= ( ARCH_WFWG
| ARCH_WIN95
);
651 else if (strcsequal(cliprotos
[i
], "DOS LANMAN2.1"))
652 arch
&= ( ARCH_WFWG
| ARCH_WIN95
);
653 else if (strcsequal(cliprotos
[i
], "NT LM 0.12"))
654 arch
&= ( ARCH_WIN95
| ARCH_WINNT
| ARCH_WIN2K
656 else if (strcsequal(cliprotos
[i
], "SMB 2.001"))
658 else if (strcsequal(cliprotos
[i
], "LANMAN2.1"))
659 arch
&= ( ARCH_WINNT
| ARCH_WIN2K
| ARCH_OS2
);
660 else if (strcsequal(cliprotos
[i
], "LM1.2X002"))
661 arch
&= ( ARCH_WINNT
| ARCH_WIN2K
| ARCH_OS2
);
662 else if (strcsequal(cliprotos
[i
], "MICROSOFT NETWORKS 1.03"))
664 else if (strcsequal(cliprotos
[i
], "XENIX CORE"))
665 arch
&= ( ARCH_WINNT
| ARCH_OS2
);
666 else if (strcsequal(cliprotos
[i
], "Samba")) {
669 } else if (strcsequal(cliprotos
[i
], "POSIX 2")) {
675 /* CIFSFS can send one arch only, NT LM 0.12. */
676 if (i
== 1 && (arch
& ARCH_CIFSFS
)) {
682 set_remote_arch(RA_CIFSFS
);
685 set_remote_arch(RA_SAMBA
);
688 set_remote_arch(RA_WFWG
);
691 set_remote_arch(RA_WIN95
);
694 if(req
->flags2
== FLAGS2_WIN2K_SIGNATURE
)
695 set_remote_arch(RA_WIN2K
);
697 set_remote_arch(RA_WINNT
);
700 /* Vista may have been set in the negprot so don't
702 if ( get_remote_arch() != RA_VISTA
)
703 set_remote_arch(RA_WIN2K
);
706 set_remote_arch(RA_VISTA
);
709 set_remote_arch(RA_OS2
);
712 set_remote_arch(RA_UNKNOWN
);
716 /* possibly reload - change of architecture */
717 reload_services(sconn
, conn_snum_used
, true);
719 /* moved from the netbios session setup code since we don't have that
720 when the client connects to port 445. Of course there is a small
721 window where we are listening to messages -- jerry */
723 serverid_register(messaging_server_id(sconn
->msg_ctx
),
724 FLAG_MSG_GENERAL
|FLAG_MSG_SMBD
725 |FLAG_MSG_PRINT_GENERAL
);
727 /* Check for protocols, most desirable first */
728 for (protocol
= 0; supported_protocols
[protocol
].proto_name
; protocol
++) {
730 if ((supported_protocols
[protocol
].protocol_level
<= lp_maxprotocol()) &&
731 (supported_protocols
[protocol
].protocol_level
>= lp_minprotocol()))
732 while (i
< num_cliprotos
) {
733 if (strequal(cliprotos
[i
],supported_protocols
[protocol
].proto_name
))
742 fstrcpy(remote_proto
,supported_protocols
[protocol
].short_name
);
743 reload_services(sconn
, conn_snum_used
, true);
744 supported_protocols
[protocol
].proto_reply_fn(req
, choice
);
745 DEBUG(3,("Selected protocol %s\n",supported_protocols
[protocol
].proto_name
));
747 DEBUG(0,("No protocol supported !\n"));
748 reply_outbuf(req
, 1, 0);
749 SSVAL(req
->outbuf
, smb_vwv0
, choice
);
752 DEBUG( 5, ( "negprot index=%d\n", choice
) );
754 if ((lp_server_signing() == SMB_SIGNING_REQUIRED
)
755 && (get_Protocol() < PROTOCOL_NT1
)) {
756 exit_server_cleanly("SMB signing is required and "
757 "client negotiated a downlevel protocol");
760 TALLOC_FREE(cliprotos
);
762 if (lp_async_smb_echo_handler() && (get_Protocol() < PROTOCOL_SMB2_02
) &&
763 !fork_echo_handler(sconn
)) {
764 exit_server("Failed to fork echo handler");
767 END_PROFILE(SMBnegprot
);