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"
32 extern fstring remote_proto
;
34 static void get_challenge(struct smbd_server_connection
*sconn
, uint8 buff
[8])
38 /* We might be called more than once, multiple negprots are
40 if (sconn
->smb1
.negprot
.auth_context
) {
41 DEBUG(3, ("get challenge: is this a secondary negprot? "
42 "sconn->negprot.auth_context is non-NULL!\n"));
43 TALLOC_FREE(sconn
->smb1
.negprot
.auth_context
);
46 DEBUG(10, ("get challenge: creating negprot_global_auth_context\n"));
47 nt_status
= make_auth_context_subsystem(
48 sconn
, &sconn
->smb1
.negprot
.auth_context
);
49 if (!NT_STATUS_IS_OK(nt_status
)) {
50 DEBUG(0, ("make_auth_context_subsystem returned %s",
51 nt_errstr(nt_status
)));
52 smb_panic("cannot make_negprot_global_auth_context!");
54 DEBUG(10, ("get challenge: getting challenge\n"));
55 sconn
->smb1
.negprot
.auth_context
->get_ntlm_challenge(
56 sconn
->smb1
.negprot
.auth_context
, buff
);
59 /****************************************************************************
60 Reply for the core protocol.
61 ****************************************************************************/
63 static void reply_corep(struct smb_request
*req
, uint16 choice
)
65 reply_outbuf(req
, 1, 0);
66 SSVAL(req
->outbuf
, smb_vwv0
, choice
);
68 set_Protocol(PROTOCOL_CORE
);
71 /****************************************************************************
72 Reply for the coreplus protocol.
73 ****************************************************************************/
75 static void reply_coreplus(struct smb_request
*req
, uint16 choice
)
77 int raw
= (lp_readraw()?1:0) | (lp_writeraw()?2:0);
79 reply_outbuf(req
, 13, 0);
81 SSVAL(req
->outbuf
,smb_vwv0
,choice
);
82 SSVAL(req
->outbuf
,smb_vwv5
,raw
); /* tell redirector we support
83 readbraw and writebraw (possibly) */
84 /* Reply, SMBlockread, SMBwritelock supported. */
85 SCVAL(req
->outbuf
,smb_flg
,FLAG_REPLY
|FLAG_SUPPORT_LOCKREAD
);
86 SSVAL(req
->outbuf
,smb_vwv1
,0x1); /* user level security, don't
88 set_Protocol(PROTOCOL_COREPLUS
);
91 /****************************************************************************
92 Reply for the lanman 1.0 protocol.
93 ****************************************************************************/
95 static void reply_lanman1(struct smb_request
*req
, uint16 choice
)
97 int raw
= (lp_readraw()?1:0) | (lp_writeraw()?2:0);
99 time_t t
= time(NULL
);
100 struct smbd_server_connection
*sconn
= req
->sconn
;
102 sconn
->smb1
.negprot
.encrypted_passwords
= lp_encrypted_passwords();
104 if (lp_security()>=SEC_USER
) {
105 secword
|= NEGOTIATE_SECURITY_USER_LEVEL
;
107 if (sconn
->smb1
.negprot
.encrypted_passwords
) {
108 secword
|= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
;
111 reply_outbuf(req
, 13, sconn
->smb1
.negprot
.encrypted_passwords
?8:0);
113 SSVAL(req
->outbuf
,smb_vwv0
,choice
);
114 SSVAL(req
->outbuf
,smb_vwv1
,secword
);
115 /* Create a token value and add it to the outgoing packet. */
116 if (sconn
->smb1
.negprot
.encrypted_passwords
) {
117 get_challenge(sconn
, (uint8
*)smb_buf(req
->outbuf
));
118 SSVAL(req
->outbuf
,smb_vwv11
, 8);
121 set_Protocol(PROTOCOL_LANMAN1
);
123 /* Reply, SMBlockread, SMBwritelock supported. */
124 SCVAL(req
->outbuf
,smb_flg
,FLAG_REPLY
|FLAG_SUPPORT_LOCKREAD
);
125 SSVAL(req
->outbuf
,smb_vwv2
,sconn
->smb1
.negprot
.max_recv
);
126 SSVAL(req
->outbuf
,smb_vwv3
,lp_maxmux()); /* maxmux */
127 SSVAL(req
->outbuf
,smb_vwv4
,1);
128 SSVAL(req
->outbuf
,smb_vwv5
,raw
); /* tell redirector we support
129 readbraw writebraw (possibly) */
130 SIVAL(req
->outbuf
,smb_vwv6
,sys_getpid());
131 SSVAL(req
->outbuf
,smb_vwv10
, set_server_zone_offset(t
)/60);
133 srv_put_dos_date((char *)req
->outbuf
,smb_vwv8
,t
);
138 /****************************************************************************
139 Reply for the lanman 2.0 protocol.
140 ****************************************************************************/
142 static void reply_lanman2(struct smb_request
*req
, uint16 choice
)
144 int raw
= (lp_readraw()?1:0) | (lp_writeraw()?2:0);
146 time_t t
= time(NULL
);
147 struct smbd_server_connection
*sconn
= req
->sconn
;
149 sconn
->smb1
.negprot
.encrypted_passwords
= lp_encrypted_passwords();
151 if (lp_security()>=SEC_USER
) {
152 secword
|= NEGOTIATE_SECURITY_USER_LEVEL
;
154 if (sconn
->smb1
.negprot
.encrypted_passwords
) {
155 secword
|= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
;
158 reply_outbuf(req
, 13, sconn
->smb1
.negprot
.encrypted_passwords
?8:0);
160 SSVAL(req
->outbuf
,smb_vwv0
,choice
);
161 SSVAL(req
->outbuf
,smb_vwv1
,secword
);
162 SIVAL(req
->outbuf
,smb_vwv6
,sys_getpid());
164 /* Create a token value and add it to the outgoing packet. */
165 if (sconn
->smb1
.negprot
.encrypted_passwords
) {
166 get_challenge(sconn
, (uint8
*)smb_buf(req
->outbuf
));
167 SSVAL(req
->outbuf
,smb_vwv11
, 8);
170 set_Protocol(PROTOCOL_LANMAN2
);
172 /* Reply, SMBlockread, SMBwritelock supported. */
173 SCVAL(req
->outbuf
,smb_flg
,FLAG_REPLY
|FLAG_SUPPORT_LOCKREAD
);
174 SSVAL(req
->outbuf
,smb_vwv2
,sconn
->smb1
.negprot
.max_recv
);
175 SSVAL(req
->outbuf
,smb_vwv3
,lp_maxmux());
176 SSVAL(req
->outbuf
,smb_vwv4
,1);
177 SSVAL(req
->outbuf
,smb_vwv5
,raw
); /* readbraw and/or writebraw */
178 SSVAL(req
->outbuf
,smb_vwv10
, set_server_zone_offset(t
)/60);
179 srv_put_dos_date((char *)req
->outbuf
,smb_vwv8
,t
);
182 /****************************************************************************
183 Generate the spnego negprot reply blob. Return the number of bytes used.
184 ****************************************************************************/
186 DATA_BLOB
negprot_spnego(TALLOC_CTX
*ctx
, struct smbd_server_connection
*sconn
)
188 DATA_BLOB blob
= data_blob_null
;
189 DATA_BLOB blob_out
= data_blob_null
;
196 const char *OIDs_krb5
[] = {OID_KERBEROS5
,
200 const char *OIDs_ntlm
[] = {OID_NTLMSSP
, NULL
};
201 struct auth_ntlmssp_state
*auth_ntlmssp_state
;
203 sconn
->use_gensec_hook
= false;
205 /* See if we can get an SPNEGO blob out of the gensec hook (if auth_samba4 is loaded) */
206 status
= auth_ntlmssp_prepare(sconn
->remote_address
,
207 &auth_ntlmssp_state
);
208 if (NT_STATUS_IS_OK(status
)) {
209 status
= auth_generic_start(auth_ntlmssp_state
, GENSEC_OID_SPNEGO
);
210 if (NT_STATUS_IS_OK(status
)) {
211 status
= auth_ntlmssp_update(auth_ntlmssp_state
, ctx
,
212 data_blob_null
, &blob
);
213 /* If we get the list of OIDs, the 'OK' answer
214 * is NT_STATUS_MORE_PROCESSING_REQUIRED */
215 if (NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
216 sconn
->use_gensec_hook
= true;
219 TALLOC_FREE(auth_ntlmssp_state
);
222 sconn
->smb1
.negprot
.spnego
= true;
224 /* strangely enough, NT does not sent the single OID NTLMSSP when
225 not a ADS member, it sends no OIDs at all
227 OLD COMMENT : "we can't do this until we teach our sesssion setup parser to know
228 about raw NTLMSSP (clients send no ASN.1 wrapping if we do this)"
230 Our sessionsetup code now handles raw NTLMSSP connects, so we can go
231 back to doing what W2K3 does here. This is needed to make PocketPC 2003
232 CIFS connections work with SPNEGO. See bugzilla bugs #1828 and #3133
237 if (sconn
->use_gensec_hook
) {
238 /* blob initialised above */
239 } else if (lp_security() != SEC_ADS
&& !USE_KERBEROS_KEYTAB
) {
241 /* Code for PocketPC client */
242 blob
= data_blob(guid
, 16);
244 /* Code for standalone WXP client */
245 blob
= spnego_gen_negTokenInit(ctx
, OIDs_ntlm
, NULL
, "NONE");
247 } else if (!lp_send_spnego_principal()) {
248 /* By default, Windows 2008 and later sends not_defined_in_RFC4178@please_ignore */
249 blob
= spnego_gen_negTokenInit(ctx
, OIDs_krb5
, NULL
, ADS_IGNORE_PRINCIPAL
);
252 char *host_princ_s
= NULL
;
253 name_to_fqdn(myname
, lp_netbios_name());
255 if (asprintf(&host_princ_s
, "cifs/%s@%s", myname
, lp_realm())
257 return data_blob_null
;
259 blob
= spnego_gen_negTokenInit(ctx
, OIDs_krb5
, NULL
, host_princ_s
);
260 SAFE_FREE(host_princ_s
);
263 if (blob
.length
== 0 || blob
.data
== NULL
) {
264 return data_blob_null
;
267 blob_out
= data_blob_talloc(ctx
, NULL
, 16 + blob
.length
);
268 if (blob_out
.data
== NULL
) {
269 data_blob_free(&blob
);
270 return data_blob_null
;
273 memset(blob_out
.data
, '\0', 16);
275 checked_strlcpy(unix_name
, lp_netbios_name(), sizeof(unix_name
));
276 strlower_m(unix_name
);
277 push_ascii_nstring(dos_name
, unix_name
);
278 strlcpy((char *)blob_out
.data
, dos_name
, 17);
281 /* Fix valgrind 'uninitialized bytes' issue. */
282 slen
= strlen(dos_name
);
284 memset(blob_out
.data
+slen
, '\0', 16 - slen
);
288 memcpy(&blob_out
.data
[16], blob
.data
, blob
.length
);
290 data_blob_free(&blob
);
295 /****************************************************************************
296 Reply for the nt protocol.
297 ****************************************************************************/
299 static void reply_nt1(struct smb_request
*req
, uint16 choice
)
301 /* dual names + lock_and_read + nt SMBs + remote API calls */
302 int capabilities
= CAP_NT_FIND
|CAP_LOCK_AND_READ
|
303 CAP_LEVEL_II_OPLOCKS
;
306 bool negotiate_spnego
= False
;
309 struct smbd_server_connection
*sconn
= req
->sconn
;
311 sconn
->smb1
.negprot
.encrypted_passwords
= lp_encrypted_passwords();
313 /* Check the flags field to see if this is Vista.
314 WinXP sets it and Vista does not. But we have to
315 distinguish from NT which doesn't set it either. */
317 if ( (req
->flags2
& FLAGS2_EXTENDED_SECURITY
) &&
318 ((req
->flags2
& FLAGS2_UNKNOWN_BIT4
) == 0) )
320 if (get_remote_arch() != RA_SAMBA
) {
321 set_remote_arch( RA_VISTA
);
325 reply_outbuf(req
,17,0);
327 /* do spnego in user level security if the client
328 supports it and we can do encrypted passwords */
330 if (sconn
->smb1
.negprot
.encrypted_passwords
&&
331 (lp_security() != SEC_SHARE
) &&
333 (req
->flags2
& FLAGS2_EXTENDED_SECURITY
)) {
334 negotiate_spnego
= True
;
335 capabilities
|= CAP_EXTENDED_SECURITY
;
336 add_to_common_flags2(FLAGS2_EXTENDED_SECURITY
);
337 /* Ensure FLAGS2_EXTENDED_SECURITY gets set in this reply
338 (already partially constructed. */
339 SSVAL(req
->outbuf
, smb_flg2
,
340 req
->flags2
| FLAGS2_EXTENDED_SECURITY
);
343 capabilities
|= CAP_NT_SMBS
|CAP_RPC_REMOTE_APIS
|CAP_UNICODE
;
345 if (lp_unix_extensions()) {
346 capabilities
|= CAP_UNIX
;
349 if (lp_large_readwrite() && (SMB_OFF_T_BITS
== 64))
350 capabilities
|= CAP_LARGE_READX
|CAP_LARGE_WRITEX
|CAP_W2K_SMBS
;
352 if (SMB_OFF_T_BITS
== 64)
353 capabilities
|= CAP_LARGE_FILES
;
355 if (lp_readraw() && lp_writeraw())
356 capabilities
|= CAP_RAW_MODE
;
358 if (lp_nt_status_support())
359 capabilities
|= CAP_STATUS32
;
362 capabilities
|= CAP_DFS
;
364 if (lp_security() >= SEC_USER
) {
365 secword
|= NEGOTIATE_SECURITY_USER_LEVEL
;
367 if (sconn
->smb1
.negprot
.encrypted_passwords
) {
368 secword
|= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
;
371 if (lp_server_signing()) {
372 if (lp_security() >= SEC_USER
) {
373 secword
|= NEGOTIATE_SECURITY_SIGNATURES_ENABLED
;
374 /* No raw mode with smb signing. */
375 capabilities
&= ~CAP_RAW_MODE
;
376 if (lp_server_signing() == Required
)
377 secword
|=NEGOTIATE_SECURITY_SIGNATURES_REQUIRED
;
378 srv_set_signing_negotiated(sconn
);
380 DEBUG(0,("reply_nt1: smb signing is incompatible with share level security !\n"));
381 if (lp_server_signing() == Required
) {
382 exit_server_cleanly("reply_nt1: smb signing required and share level security selected.");
387 SSVAL(req
->outbuf
,smb_vwv0
,choice
);
388 SCVAL(req
->outbuf
,smb_vwv1
,secword
);
390 set_Protocol(PROTOCOL_NT1
);
392 SSVAL(req
->outbuf
,smb_vwv1
+1,lp_maxmux()); /* maxmpx */
393 SSVAL(req
->outbuf
,smb_vwv2
+1,1); /* num vcs */
394 SIVAL(req
->outbuf
,smb_vwv3
+1,
395 sconn
->smb1
.negprot
.max_recv
); /* max buffer. LOTS! */
396 SIVAL(req
->outbuf
,smb_vwv5
+1,0x10000); /* raw size. full 64k */
397 SIVAL(req
->outbuf
,smb_vwv7
+1,sys_getpid()); /* session key */
398 SIVAL(req
->outbuf
,smb_vwv9
+1,capabilities
); /* capabilities */
399 clock_gettime(CLOCK_REALTIME
,&ts
);
400 put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER
,(char *)req
->outbuf
+smb_vwv11
+1,ts
);
401 SSVALS(req
->outbuf
,smb_vwv15
+1,set_server_zone_offset(ts
.tv_sec
)/60);
403 if (!negotiate_spnego
) {
404 /* Create a token value and add it to the outgoing packet. */
405 if (sconn
->smb1
.negprot
.encrypted_passwords
) {
407 /* note that we do not send a challenge at all if
408 we are using plaintext */
409 get_challenge(sconn
, chal
);
410 ret
= message_push_blob(
411 &req
->outbuf
, data_blob_const(chal
, sizeof(chal
)));
413 DEBUG(0, ("Could not push challenge\n"));
414 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
417 SCVAL(req
->outbuf
, smb_vwv16
+1, ret
);
419 ret
= message_push_string(&req
->outbuf
, lp_workgroup(),
420 STR_UNICODE
|STR_TERMINATE
423 DEBUG(0, ("Could not push workgroup string\n"));
424 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
427 DEBUG(3,("not using SPNEGO\n"));
429 DATA_BLOB spnego_blob
= negprot_spnego(req
, req
->sconn
);
431 if (spnego_blob
.data
== NULL
) {
432 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
436 ret
= message_push_blob(&req
->outbuf
, spnego_blob
);
438 DEBUG(0, ("Could not push spnego blob\n"));
439 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
442 data_blob_free(&spnego_blob
);
444 SCVAL(req
->outbuf
,smb_vwv16
+1, 0);
445 DEBUG(3,("using SPNEGO\n"));
451 /* these are the protocol lists used for auto architecture detection:
454 protocol [PC NETWORK PROGRAM 1.0]
455 protocol [XENIX CORE]
456 protocol [MICROSOFT NETWORKS 1.03]
458 protocol [Windows for Workgroups 3.1a]
461 protocol [NT LM 0.12]
464 protocol [PC NETWORK PROGRAM 1.0]
465 protocol [XENIX CORE]
466 protocol [MICROSOFT NETWORKS 1.03]
468 protocol [Windows for Workgroups 3.1a]
471 protocol [NT LM 0.12]
474 protocol [PC NETWORK PROGRAM 1.0]
476 protocol [Windows for Workgroups 3.1a]
479 protocol [NT LM 0.12]
482 protocol [PC NETWORK PROGRAM 1.0]
484 protocol [Windows for Workgroups 3.1a]
487 protocol [NT LM 0.12]
491 protocol [PC NETWORK PROGRAM 1.0]
492 protocol [XENIX CORE]
499 * Modified to recognize the architecture of the remote machine better.
501 * This appears to be the matrix of which protocol is used by which
503 Protocol WfWg Win95 WinNT Win2K OS/2 Vista
504 PC NETWORK PROGRAM 1.0 1 1 1 1 1 1
506 MICROSOFT NETWORKS 3.0 2 2
508 MICROSOFT NETWORKS 1.03 3
511 Windows for Workgroups 3.1a 5 5 5 3 3
517 * tim@fsg.com 09/29/95
518 * Win2K added by matty 17/7/99
521 #define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
522 #define ARCH_WIN95 0x2
523 #define ARCH_WINNT 0x4
524 #define ARCH_WIN2K 0xC /* Win2K is like NT */
525 #define ARCH_OS2 0x14 /* Again OS/2 is like NT */
526 #define ARCH_SAMBA 0x20
527 #define ARCH_CIFSFS 0x40
528 #define ARCH_VISTA 0x8C /* Vista is like XP/2K */
530 #define ARCH_ALL 0x7F
532 /* List of supported protocols, most desired first */
533 static const struct {
534 const char *proto_name
;
535 const char *short_name
;
536 void (*proto_reply_fn
)(struct smb_request
*req
, uint16 choice
);
538 } supported_protocols
[] = {
539 {"SMB 2.002", "SMB2_02", reply_smb2002
, PROTOCOL_SMB2_02
},
540 {"NT LANMAN 1.0", "NT1", reply_nt1
, PROTOCOL_NT1
},
541 {"NT LM 0.12", "NT1", reply_nt1
, PROTOCOL_NT1
},
542 {"POSIX 2", "NT1", reply_nt1
, PROTOCOL_NT1
},
543 {"LANMAN2.1", "LANMAN2", reply_lanman2
, PROTOCOL_LANMAN2
},
544 {"LM1.2X002", "LANMAN2", reply_lanman2
, PROTOCOL_LANMAN2
},
545 {"Samba", "LANMAN2", reply_lanman2
, PROTOCOL_LANMAN2
},
546 {"DOS LM1.2X002", "LANMAN2", reply_lanman2
, PROTOCOL_LANMAN2
},
547 {"LANMAN1.0", "LANMAN1", reply_lanman1
, PROTOCOL_LANMAN1
},
548 {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1
, PROTOCOL_LANMAN1
},
549 {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus
, PROTOCOL_COREPLUS
},
550 {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep
, PROTOCOL_CORE
},
554 /****************************************************************************
556 conn POINTER CAN BE NULL HERE !
557 ****************************************************************************/
559 void reply_negprot(struct smb_request
*req
)
568 size_t converted_size
;
569 struct smbd_server_connection
*sconn
= req
->sconn
;
571 START_PROFILE(SMBnegprot
);
573 if (sconn
->smb1
.negprot
.done
) {
574 END_PROFILE(SMBnegprot
);
575 exit_server_cleanly("multiple negprot's are not permitted");
577 sconn
->smb1
.negprot
.done
= true;
579 if (req
->buflen
== 0) {
580 DEBUG(0, ("negprot got no protocols\n"));
581 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
582 END_PROFILE(SMBnegprot
);
586 if (req
->buf
[req
->buflen
-1] != '\0') {
587 DEBUG(0, ("negprot protocols not 0-terminated\n"));
588 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
589 END_PROFILE(SMBnegprot
);
593 p
= (const char *)req
->buf
+ 1;
598 while (smbreq_bufrem(req
, p
) > 0) {
602 tmp
= talloc_realloc(talloc_tos(), cliprotos
, char *,
605 DEBUG(0, ("talloc failed\n"));
606 TALLOC_FREE(cliprotos
);
607 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
608 END_PROFILE(SMBnegprot
);
614 if (!pull_ascii_talloc(cliprotos
, &cliprotos
[num_cliprotos
], p
,
616 DEBUG(0, ("pull_ascii_talloc failed\n"));
617 TALLOC_FREE(cliprotos
);
618 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
619 END_PROFILE(SMBnegprot
);
623 DEBUG(3, ("Requested protocol [%s]\n",
624 cliprotos
[num_cliprotos
]));
630 for (i
=0; i
<num_cliprotos
; i
++) {
631 if (strcsequal(cliprotos
[i
], "Windows for Workgroups 3.1a"))
632 arch
&= ( ARCH_WFWG
| ARCH_WIN95
| ARCH_WINNT
634 else if (strcsequal(cliprotos
[i
], "DOS LM1.2X002"))
635 arch
&= ( ARCH_WFWG
| ARCH_WIN95
);
636 else if (strcsequal(cliprotos
[i
], "DOS LANMAN2.1"))
637 arch
&= ( ARCH_WFWG
| ARCH_WIN95
);
638 else if (strcsequal(cliprotos
[i
], "NT LM 0.12"))
639 arch
&= ( ARCH_WIN95
| ARCH_WINNT
| ARCH_WIN2K
641 else if (strcsequal(cliprotos
[i
], "SMB 2.001"))
643 else if (strcsequal(cliprotos
[i
], "LANMAN2.1"))
644 arch
&= ( ARCH_WINNT
| ARCH_WIN2K
| ARCH_OS2
);
645 else if (strcsequal(cliprotos
[i
], "LM1.2X002"))
646 arch
&= ( ARCH_WINNT
| ARCH_WIN2K
| ARCH_OS2
);
647 else if (strcsequal(cliprotos
[i
], "MICROSOFT NETWORKS 1.03"))
649 else if (strcsequal(cliprotos
[i
], "XENIX CORE"))
650 arch
&= ( ARCH_WINNT
| ARCH_OS2
);
651 else if (strcsequal(cliprotos
[i
], "Samba")) {
654 } else if (strcsequal(cliprotos
[i
], "POSIX 2")) {
660 /* CIFSFS can send one arch only, NT LM 0.12. */
661 if (i
== 1 && (arch
& ARCH_CIFSFS
)) {
667 set_remote_arch(RA_CIFSFS
);
670 set_remote_arch(RA_SAMBA
);
673 set_remote_arch(RA_WFWG
);
676 set_remote_arch(RA_WIN95
);
679 if(req
->flags2
== FLAGS2_WIN2K_SIGNATURE
)
680 set_remote_arch(RA_WIN2K
);
682 set_remote_arch(RA_WINNT
);
685 /* Vista may have been set in the negprot so don't
687 if ( get_remote_arch() != RA_VISTA
)
688 set_remote_arch(RA_WIN2K
);
691 set_remote_arch(RA_VISTA
);
694 set_remote_arch(RA_OS2
);
697 set_remote_arch(RA_UNKNOWN
);
701 /* possibly reload - change of architecture */
702 reload_services(sconn
->msg_ctx
, sconn
->sock
, True
);
704 /* moved from the netbios session setup code since we don't have that
705 when the client connects to port 445. Of course there is a small
706 window where we are listening to messages -- jerry */
708 serverid_register(sconn_server_id(sconn
),
709 FLAG_MSG_GENERAL
|FLAG_MSG_SMBD
710 |FLAG_MSG_PRINT_GENERAL
);
712 /* Check for protocols, most desirable first */
713 for (protocol
= 0; supported_protocols
[protocol
].proto_name
; protocol
++) {
715 if ((supported_protocols
[protocol
].protocol_level
<= lp_maxprotocol()) &&
716 (supported_protocols
[protocol
].protocol_level
>= lp_minprotocol()))
717 while (i
< num_cliprotos
) {
718 if (strequal(cliprotos
[i
],supported_protocols
[protocol
].proto_name
))
727 fstrcpy(remote_proto
,supported_protocols
[protocol
].short_name
);
728 reload_services(sconn
->msg_ctx
, sconn
->sock
, True
);
729 supported_protocols
[protocol
].proto_reply_fn(req
, choice
);
730 DEBUG(3,("Selected protocol %s\n",supported_protocols
[protocol
].proto_name
));
732 DEBUG(0,("No protocol supported !\n"));
733 reply_outbuf(req
, 1, 0);
734 SSVAL(req
->outbuf
, smb_vwv0
, choice
);
737 DEBUG( 5, ( "negprot index=%d\n", choice
) );
739 if ((lp_server_signing() == Required
) && (get_Protocol() < PROTOCOL_NT1
)) {
740 exit_server_cleanly("SMB signing is required and "
741 "client negotiated a downlevel protocol");
744 TALLOC_FREE(cliprotos
);
746 if (lp_async_smb_echo_handler() && !fork_echo_handler(sconn
)) {
747 exit_server("Failed to fork echo handler");
750 END_PROFILE(SMBnegprot
);