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_generic_prepare(talloc_tos(),
208 sconn->remote_address,
209 &auth_ntlmssp_state);
210 if (NT_STATUS_IS_OK(status)) {
211 status = auth_generic_start(auth_ntlmssp_state, GENSEC_OID_SPNEGO);
212 if (NT_STATUS_IS_OK(status)) {
213 status = gensec_update(auth_ntlmssp_state->gensec_security, ctx,
214 NULL, data_blob_null, &blob);
215 /* If we get the list of OIDs, the 'OK' answer
216 * is NT_STATUS_MORE_PROCESSING_REQUIRED */
217 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
218 sconn->use_gensec_hook = true;
221 TALLOC_FREE(auth_ntlmssp_state);
224 sconn->smb1.negprot.spnego = true;
226 /* strangely enough, NT does not sent the single OID NTLMSSP when
227 not a ADS member, it sends no OIDs at all
229 OLD COMMENT : "we can't do this until we teach our sesssion setup parser to know
230 about raw NTLMSSP (clients send no ASN.1 wrapping if we do this)"
232 Our sessionsetup code now handles raw NTLMSSP connects, so we can go
233 back to doing what W2K3 does here. This is needed to make PocketPC 2003
234 CIFS connections work with SPNEGO. See bugzilla bugs #1828 and #3133
239 if (sconn->use_gensec_hook) {
240 /* blob initialised above */
241 } else if (lp_security() != SEC_ADS && !USE_KERBEROS_KEYTAB) {
243 /* Code for PocketPC client */
244 blob = data_blob(guid, 16);
246 /* Code for standalone WXP client */
247 blob = spnego_gen_negTokenInit(ctx, OIDs_ntlm, NULL, "NONE");
249 } else if (!lp_send_spnego_principal()) {
250 /* By default, Windows 2008 and later sends not_defined_in_RFC4178@please_ignore */
251 blob = spnego_gen_negTokenInit(ctx, OIDs_krb5, NULL, ADS_IGNORE_PRINCIPAL);
254 char *host_princ_s = NULL;
255 name_to_fqdn(myname, lp_netbios_name());
257 if (asprintf(&host_princ_s, "cifs/%s@%s", myname, lp_realm())
259 return data_blob_null;
261 blob = spnego_gen_negTokenInit(ctx, OIDs_krb5, NULL, host_princ_s);
262 SAFE_FREE(host_princ_s);
265 if (blob.length == 0 || blob.data == NULL) {
266 return data_blob_null;
269 blob_out = data_blob_talloc(ctx, NULL, 16 + blob.length);
270 if (blob_out.data == NULL) {
271 data_blob_free(&blob);
272 return data_blob_null;
275 memset(blob_out.data, '\0', 16);
277 checked_strlcpy(unix_name, lp_netbios_name(), sizeof(unix_name));
278 strlower_m(unix_name);
279 push_ascii_nstring(dos_name, unix_name);
280 strlcpy((char *)blob_out.data, dos_name, 17);
283 /* Fix valgrind 'uninitialized bytes' issue. */
284 slen = strlen(dos_name);
286 memset(blob_out.data+slen, '\0', 16 - slen);
290 memcpy(&blob_out.data[16], blob.data, blob.length);
292 data_blob_free(&blob);
297 /****************************************************************************
298 Reply for the nt protocol.
299 ****************************************************************************/
301 static void reply_nt1(struct smb_request *req, uint16 choice)
303 /* dual names + lock_and_read + nt SMBs + remote API calls */
304 int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ|
305 CAP_LEVEL_II_OPLOCKS;
308 bool negotiate_spnego = False;
311 struct smbd_server_connection *sconn = req->sconn;
312 bool signing_enabled = false;
313 bool signing_required = false;
315 sconn->smb1.negprot.encrypted_passwords = lp_encrypted_passwords();
317 /* Check the flags field to see if this is Vista.
318 WinXP sets it and Vista does not. But we have to
319 distinguish from NT which doesn't set it either. */
321 if ( (req->flags2 & FLAGS2_EXTENDED_SECURITY) &&
322 ((req->flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED) == 0) )
324 if (get_remote_arch() != RA_SAMBA) {
325 set_remote_arch( RA_VISTA );
329 reply_outbuf(req,17,0);
331 /* do spnego in user level security if the client
332 supports it and we can do encrypted passwords */
334 if (sconn->smb1.negprot.encrypted_passwords &&
335 (lp_security() != SEC_SHARE) &&
337 (req->flags2 & FLAGS2_EXTENDED_SECURITY)) {
338 negotiate_spnego = True;
339 capabilities |= CAP_EXTENDED_SECURITY;
340 add_to_common_flags2(FLAGS2_EXTENDED_SECURITY);
341 /* Ensure FLAGS2_EXTENDED_SECURITY gets set in this reply
342 (already partially constructed. */
343 SSVAL(req->outbuf, smb_flg2,
344 req->flags2 | FLAGS2_EXTENDED_SECURITY);
347 capabilities |= CAP_NT_SMBS|CAP_RPC_REMOTE_APIS|CAP_UNICODE;
349 if (lp_unix_extensions()) {
350 capabilities |= CAP_UNIX;
353 if (lp_large_readwrite() && (SMB_OFF_T_BITS == 64))
354 capabilities |= CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_W2K_SMBS;
356 if (SMB_OFF_T_BITS == 64)
357 capabilities |= CAP_LARGE_FILES;
359 if (lp_readraw() && lp_writeraw())
360 capabilities |= CAP_RAW_MODE;
362 if (lp_nt_status_support())
363 capabilities |= CAP_STATUS32;
366 capabilities |= CAP_DFS;
368 if (lp_security() >= SEC_USER) {
369 secword |= NEGOTIATE_SECURITY_USER_LEVEL;
371 if (sconn->smb1.negprot.encrypted_passwords) {
372 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
375 signing_enabled = smb_signing_is_allowed(req->sconn->smb1.signing_state);
376 signing_required = smb_signing_is_mandatory(req->sconn->smb1.signing_state);
378 if (signing_enabled) {
379 if (lp_security() >= SEC_USER) {
380 secword |= NEGOTIATE_SECURITY_SIGNATURES_ENABLED;
381 /* No raw mode with smb signing. */
382 capabilities &= ~CAP_RAW_MODE;
383 if (signing_required) {
384 secword |=NEGOTIATE_SECURITY_SIGNATURES_REQUIRED;
387 DEBUG(0,("reply_nt1: smb signing is incompatible with share level security !\n"));
388 if (signing_required) {
389 exit_server_cleanly("reply_nt1: smb signing required and share level security selected.");
394 SSVAL(req->outbuf,smb_vwv0,choice);
395 SCVAL(req->outbuf,smb_vwv1,secword);
397 set_Protocol(PROTOCOL_NT1);
399 SSVAL(req->outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
400 SSVAL(req->outbuf,smb_vwv2+1,1); /* num vcs */
401 SIVAL(req->outbuf,smb_vwv3+1,
402 sconn->smb1.negprot.max_recv); /* max buffer. LOTS! */
403 SIVAL(req->outbuf,smb_vwv5+1,0x10000); /* raw size. full 64k */
404 SIVAL(req->outbuf,smb_vwv7+1,sys_getpid()); /* session key */
405 SIVAL(req->outbuf,smb_vwv9+1,capabilities); /* capabilities */
406 clock_gettime(CLOCK_REALTIME,&ts);
407 put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER,(char *)req->outbuf+smb_vwv11+1,ts);
408 SSVALS(req->outbuf,smb_vwv15+1,set_server_zone_offset(ts.tv_sec)/60);
410 if (!negotiate_spnego) {
411 /* Create a token value and add it to the outgoing packet. */
412 if (sconn->smb1.negprot.encrypted_passwords) {
414 /* note that we do not send a challenge at all if
415 we are using plaintext */
416 get_challenge(sconn, chal);
417 ret = message_push_blob(
418 &req->outbuf, data_blob_const(chal, sizeof(chal)));
420 DEBUG(0, ("Could not push challenge\n"));
421 reply_nterror(req, NT_STATUS_NO_MEMORY);
424 SCVAL(req->outbuf, smb_vwv16+1, ret);
426 ret = message_push_string(&req->outbuf, lp_workgroup(),
427 STR_UNICODE|STR_TERMINATE
430 DEBUG(0, ("Could not push workgroup string\n"));
431 reply_nterror(req, NT_STATUS_NO_MEMORY);
434 ret = message_push_string(&req->outbuf, lp_netbios_name(),
435 STR_UNICODE|STR_TERMINATE
438 DEBUG(0, ("Could not push netbios name string\n"));
439 reply_nterror(req, NT_STATUS_NO_MEMORY);
442 DEBUG(3,("not using SPNEGO\n"));
444 DATA_BLOB spnego_blob = negprot_spnego(req, req->sconn);
446 if (spnego_blob.data == NULL) {
447 reply_nterror(req, NT_STATUS_NO_MEMORY);
451 ret = message_push_blob(&req->outbuf, spnego_blob);
453 DEBUG(0, ("Could not push spnego blob\n"));
454 reply_nterror(req, NT_STATUS_NO_MEMORY);
457 data_blob_free(&spnego_blob);
459 SCVAL(req->outbuf,smb_vwv16+1, 0);
460 DEBUG(3,("using SPNEGO\n"));
466 /* these are the protocol lists used for auto architecture detection:
469 protocol [PC NETWORK PROGRAM 1.0]
470 protocol [XENIX CORE]
471 protocol [MICROSOFT NETWORKS 1.03]
473 protocol [Windows for Workgroups 3.1a]
476 protocol [NT LM 0.12]
479 protocol [PC NETWORK PROGRAM 1.0]
480 protocol [XENIX CORE]
481 protocol [MICROSOFT NETWORKS 1.03]
483 protocol [Windows for Workgroups 3.1a]
486 protocol [NT LM 0.12]
489 protocol [PC NETWORK PROGRAM 1.0]
491 protocol [Windows for Workgroups 3.1a]
494 protocol [NT LM 0.12]
497 protocol [PC NETWORK PROGRAM 1.0]
499 protocol [Windows for Workgroups 3.1a]
502 protocol [NT LM 0.12]
506 protocol [PC NETWORK PROGRAM 1.0]
507 protocol [XENIX CORE]
514 * Modified to recognize the architecture of the remote machine better.
516 * This appears to be the matrix of which protocol is used by which
518 Protocol WfWg Win95 WinNT Win2K OS/2 Vista
519 PC NETWORK PROGRAM 1.0 1 1 1 1 1 1
521 MICROSOFT NETWORKS 3.0 2 2
523 MICROSOFT NETWORKS 1.03 3
526 Windows for Workgroups 3.1a 5 5 5 3 3
532 * tim@fsg.com 09/29/95
533 * Win2K added by matty 17/7/99
536 #define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
537 #define ARCH_WIN95 0x2
538 #define ARCH_WINNT 0x4
539 #define ARCH_WIN2K 0xC /* Win2K is like NT */
540 #define ARCH_OS2 0x14 /* Again OS/2 is like NT */
541 #define ARCH_SAMBA 0x20
542 #define ARCH_CIFSFS 0x40
543 #define ARCH_VISTA 0x8C /* Vista is like XP/2K */
545 #define ARCH_ALL 0x7F
547 /* List of supported protocols, most desired first */
548 static const struct {
549 const char *proto_name;
550 const char *short_name;
551 void (*proto_reply_fn)(struct smb_request *req, uint16 choice);
553 } supported_protocols[] = {
554 {"SMB 2.???", "SMB2_FF", reply_smb20ff, PROTOCOL_SMB2_10},
555 {"SMB 2.002", "SMB2_02", reply_smb2002, PROTOCOL_SMB2_02},
556 {"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1},
557 {"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1},
558 {"POSIX 2", "NT1", reply_nt1, PROTOCOL_NT1},
559 {"LANMAN2.1", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
560 {"LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
561 {"Samba", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
562 {"DOS LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
563 {"LANMAN1.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
564 {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
565 {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
566 {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep, PROTOCOL_CORE},
570 /****************************************************************************
572 conn POINTER CAN BE NULL HERE !
573 ****************************************************************************/
575 void reply_negprot(struct smb_request *req)
584 size_t converted_size;
585 struct smbd_server_connection *sconn = req->sconn;
587 START_PROFILE(SMBnegprot);
589 if (sconn->smb1.negprot.done) {
590 END_PROFILE(SMBnegprot);
591 exit_server_cleanly("multiple negprot's are not permitted");
593 sconn->smb1.negprot.done = true;
595 if (req->buflen == 0) {
596 DEBUG(0, ("negprot got no protocols\n"));
597 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
598 END_PROFILE(SMBnegprot);
602 if (req->buf[req->buflen-1] != '\0') {
603 DEBUG(0, ("negprot protocols not 0-terminated\n"));
604 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
605 END_PROFILE(SMBnegprot);
609 p = (const char *)req->buf + 1;
614 while (smbreq_bufrem(req, p) > 0) {
618 tmp = talloc_realloc(talloc_tos(), cliprotos, char *,
621 DEBUG(0, ("talloc failed\n"));
622 TALLOC_FREE(cliprotos);
623 reply_nterror(req, NT_STATUS_NO_MEMORY);
624 END_PROFILE(SMBnegprot);
630 if (!pull_ascii_talloc(cliprotos, &cliprotos[num_cliprotos], p,
632 DEBUG(0, ("pull_ascii_talloc failed\n"));
633 TALLOC_FREE(cliprotos);
634 reply_nterror(req, NT_STATUS_NO_MEMORY);
635 END_PROFILE(SMBnegprot);
639 DEBUG(3, ("Requested protocol [%s]\n",
640 cliprotos[num_cliprotos]));
646 for (i=0; i<num_cliprotos; i++) {
647 if (strcsequal(cliprotos[i], "Windows for Workgroups 3.1a"))
648 arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT
650 else if (strcsequal(cliprotos[i], "DOS LM1.2X002"))
651 arch &= ( ARCH_WFWG | ARCH_WIN95 );
652 else if (strcsequal(cliprotos[i], "DOS LANMAN2.1"))
653 arch &= ( ARCH_WFWG | ARCH_WIN95 );
654 else if (strcsequal(cliprotos[i], "NT LM 0.12"))
655 arch &= ( ARCH_WIN95 | ARCH_WINNT | ARCH_WIN2K
657 else if (strcsequal(cliprotos[i], "SMB 2.001"))
659 else if (strcsequal(cliprotos[i], "LANMAN2.1"))
660 arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 );
661 else if (strcsequal(cliprotos[i], "LM1.2X002"))
662 arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 );
663 else if (strcsequal(cliprotos[i], "MICROSOFT NETWORKS 1.03"))
665 else if (strcsequal(cliprotos[i], "XENIX CORE"))
666 arch &= ( ARCH_WINNT | ARCH_OS2 );
667 else if (strcsequal(cliprotos[i], "Samba")) {
670 } else if (strcsequal(cliprotos[i], "POSIX 2")) {
676 /* CIFSFS can send one arch only, NT LM 0.12. */
677 if (i == 1 && (arch & ARCH_CIFSFS)) {
683 set_remote_arch(RA_CIFSFS);
686 set_remote_arch(RA_SAMBA);
689 set_remote_arch(RA_WFWG);
692 set_remote_arch(RA_WIN95);
695 if(req->flags2 == FLAGS2_WIN2K_SIGNATURE)
696 set_remote_arch(RA_WIN2K);
698 set_remote_arch(RA_WINNT);
701 /* Vista may have been set in the negprot so don't
703 if ( get_remote_arch() != RA_VISTA )
704 set_remote_arch(RA_WIN2K);
707 set_remote_arch(RA_VISTA);
710 set_remote_arch(RA_OS2);
713 set_remote_arch(RA_UNKNOWN);
717 /* possibly reload - change of architecture */
718 reload_services(sconn, conn_snum_used, true);
720 /* moved from the netbios session setup code since we don't have that
721 when the client connects to port 445. Of course there is a small
722 window where we are listening to messages -- jerry */
724 serverid_register(messaging_server_id(sconn->msg_ctx),
725 FLAG_MSG_GENERAL|FLAG_MSG_SMBD
726 |FLAG_MSG_PRINT_GENERAL);
728 /* Check for protocols, most desirable first */
729 for (protocol = 0; supported_protocols[protocol].proto_name; protocol++) {
731 if ((supported_protocols[protocol].protocol_level <= lp_maxprotocol()) &&
732 (supported_protocols[protocol].protocol_level >= lp_minprotocol()))
733 while (i < num_cliprotos) {
734 if (strequal(cliprotos[i],supported_protocols[protocol].proto_name))
743 fstrcpy(remote_proto,supported_protocols[protocol].short_name);
744 reload_services(sconn, conn_snum_used, true);
745 supported_protocols[protocol].proto_reply_fn(req, choice);
746 DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
748 DEBUG(0,("No protocol supported !\n"));
749 reply_outbuf(req, 1, 0);
750 SSVAL(req->outbuf, smb_vwv0, choice);
753 DEBUG( 5, ( "negprot index=%d\n", choice ) );
755 if ((lp_server_signing() == SMB_SIGNING_REQUIRED)
756 && (get_Protocol() < PROTOCOL_NT1)) {
757 exit_server_cleanly("SMB signing is required and "
758 "client negotiated a downlevel protocol");
761 TALLOC_FREE(cliprotos);
763 if (lp_async_smb_echo_handler() && (get_Protocol() < PROTOCOL_SMB2_02) &&
764 !fork_echo_handler(sconn)) {
765 exit_server("Failed to fork echo handler");
768 END_PROFILE(SMBnegprot);