s3: Add an async smbsock_connect
[Samba.git] / source3 / smbd / negprot.c
bloba921954c49c4f162645b79991d6845a844bbb007
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/globals.h"
24 extern fstring remote_proto;
25 extern enum protocol_types Protocol;
27 static void get_challenge(uint8 buff[8])
29 NTSTATUS nt_status;
31 /* We might be called more than once, multiple negprots are
32 * permitted */
33 if (negprot_global_auth_context) {
34 DEBUG(3, ("get challenge: is this a secondary negprot? negprot_global_auth_context is non-NULL!\n"));
35 (negprot_global_auth_context->free)(&negprot_global_auth_context);
38 DEBUG(10, ("get challenge: creating negprot_global_auth_context\n"));
39 if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&negprot_global_auth_context))) {
40 DEBUG(0, ("make_auth_context_subsystem returned %s", nt_errstr(nt_status)));
41 smb_panic("cannot make_negprot_global_auth_context!");
43 DEBUG(10, ("get challenge: getting challenge\n"));
44 negprot_global_auth_context->get_ntlm_challenge(
45 negprot_global_auth_context, buff);
48 /****************************************************************************
49 Reply for the core protocol.
50 ****************************************************************************/
52 static void reply_corep(struct smb_request *req, uint16 choice)
54 reply_outbuf(req, 1, 0);
55 SSVAL(req->outbuf, smb_vwv0, choice);
57 Protocol = PROTOCOL_CORE;
60 /****************************************************************************
61 Reply for the coreplus protocol.
62 ****************************************************************************/
64 static void reply_coreplus(struct smb_request *req, uint16 choice)
66 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
68 reply_outbuf(req, 13, 0);
70 SSVAL(req->outbuf,smb_vwv0,choice);
71 SSVAL(req->outbuf,smb_vwv5,raw); /* tell redirector we support
72 readbraw and writebraw (possibly) */
73 /* Reply, SMBlockread, SMBwritelock supported. */
74 SCVAL(req->outbuf,smb_flg,FLAG_REPLY|FLAG_SUPPORT_LOCKREAD);
75 SSVAL(req->outbuf,smb_vwv1,0x1); /* user level security, don't
76 * encrypt */
77 Protocol = PROTOCOL_COREPLUS;
80 /****************************************************************************
81 Reply for the lanman 1.0 protocol.
82 ****************************************************************************/
84 static void reply_lanman1(struct smb_request *req, uint16 choice)
86 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
87 int secword=0;
88 time_t t = time(NULL);
90 global_encrypted_passwords_negotiated = lp_encrypted_passwords();
92 if (lp_security()>=SEC_USER)
93 secword |= NEGOTIATE_SECURITY_USER_LEVEL;
94 if (global_encrypted_passwords_negotiated)
95 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
97 reply_outbuf(req, 13, global_encrypted_passwords_negotiated?8:0);
99 SSVAL(req->outbuf,smb_vwv0,choice);
100 SSVAL(req->outbuf,smb_vwv1,secword);
101 /* Create a token value and add it to the outgoing packet. */
102 if (global_encrypted_passwords_negotiated) {
103 get_challenge((uint8 *)smb_buf(req->outbuf));
104 SSVAL(req->outbuf,smb_vwv11, 8);
107 Protocol = PROTOCOL_LANMAN1;
109 /* Reply, SMBlockread, SMBwritelock supported. */
110 SCVAL(req->outbuf,smb_flg,FLAG_REPLY|FLAG_SUPPORT_LOCKREAD);
111 SSVAL(req->outbuf,smb_vwv2,max_recv);
112 SSVAL(req->outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
113 SSVAL(req->outbuf,smb_vwv4,1);
114 SSVAL(req->outbuf,smb_vwv5,raw); /* tell redirector we support
115 readbraw writebraw (possibly) */
116 SIVAL(req->outbuf,smb_vwv6,sys_getpid());
117 SSVAL(req->outbuf,smb_vwv10, set_server_zone_offset(t)/60);
119 srv_put_dos_date((char *)req->outbuf,smb_vwv8,t);
121 return;
124 /****************************************************************************
125 Reply for the lanman 2.0 protocol.
126 ****************************************************************************/
128 static void reply_lanman2(struct smb_request *req, uint16 choice)
130 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
131 int secword=0;
132 time_t t = time(NULL);
134 global_encrypted_passwords_negotiated = lp_encrypted_passwords();
136 if (lp_security()>=SEC_USER)
137 secword |= NEGOTIATE_SECURITY_USER_LEVEL;
138 if (global_encrypted_passwords_negotiated)
139 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
141 reply_outbuf(req, 13, global_encrypted_passwords_negotiated?8:0);
143 SSVAL(req->outbuf,smb_vwv0,choice);
144 SSVAL(req->outbuf,smb_vwv1,secword);
145 SIVAL(req->outbuf,smb_vwv6,sys_getpid());
147 /* Create a token value and add it to the outgoing packet. */
148 if (global_encrypted_passwords_negotiated) {
149 get_challenge((uint8 *)smb_buf(req->outbuf));
150 SSVAL(req->outbuf,smb_vwv11, 8);
153 Protocol = PROTOCOL_LANMAN2;
155 /* Reply, SMBlockread, SMBwritelock supported. */
156 SCVAL(req->outbuf,smb_flg,FLAG_REPLY|FLAG_SUPPORT_LOCKREAD);
157 SSVAL(req->outbuf,smb_vwv2,max_recv);
158 SSVAL(req->outbuf,smb_vwv3,lp_maxmux());
159 SSVAL(req->outbuf,smb_vwv4,1);
160 SSVAL(req->outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
161 SSVAL(req->outbuf,smb_vwv10, set_server_zone_offset(t)/60);
162 srv_put_dos_date((char *)req->outbuf,smb_vwv8,t);
165 /****************************************************************************
166 Generate the spnego negprot reply blob. Return the number of bytes used.
167 ****************************************************************************/
169 static DATA_BLOB negprot_spnego(void)
171 DATA_BLOB blob;
172 nstring dos_name;
173 fstring unix_name;
174 #ifdef DEVELOPER
175 size_t slen;
176 #endif
177 char guid[17];
178 const char *OIDs_krb5[] = {OID_KERBEROS5,
179 OID_KERBEROS5_OLD,
180 OID_NTLMSSP,
181 NULL};
182 const char *OIDs_plain[] = {OID_NTLMSSP, NULL};
184 global_spnego_negotiated = True;
186 memset(guid, '\0', sizeof(guid));
188 safe_strcpy(unix_name, global_myname(), sizeof(unix_name)-1);
189 strlower_m(unix_name);
190 push_ascii_nstring(dos_name, unix_name);
191 safe_strcpy(guid, dos_name, sizeof(guid)-1);
193 #ifdef DEVELOPER
194 /* Fix valgrind 'uninitialized bytes' issue. */
195 slen = strlen(dos_name);
196 if (slen < sizeof(guid)) {
197 memset(guid+slen, '\0', sizeof(guid) - slen);
199 #endif
201 /* strangely enough, NT does not sent the single OID NTLMSSP when
202 not a ADS member, it sends no OIDs at all
204 OLD COMMENT : "we can't do this until we teach our sesssion setup parser to know
205 about raw NTLMSSP (clients send no ASN.1 wrapping if we do this)"
207 Our sessionsetup code now handles raw NTLMSSP connects, so we can go
208 back to doing what W2K3 does here. This is needed to make PocketPC 2003
209 CIFS connections work with SPNEGO. See bugzilla bugs #1828 and #3133
210 for details. JRA.
214 if (lp_security() != SEC_ADS && !USE_KERBEROS_KEYTAB) {
215 #if 0
216 /* Code for PocketPC client */
217 blob = data_blob(guid, 16);
218 #else
219 /* Code for standalone WXP client */
220 blob = spnego_gen_negTokenInit(guid, OIDs_plain, "NONE");
221 #endif
222 } else {
223 fstring myname;
224 char *host_princ_s = NULL;
225 name_to_fqdn(myname, global_myname());
226 strlower_m(myname);
227 if (asprintf(&host_princ_s, "cifs/%s@%s", myname, lp_realm())
228 == -1) {
229 return data_blob_null;
231 blob = spnego_gen_negTokenInit(guid, OIDs_krb5, host_princ_s);
232 SAFE_FREE(host_princ_s);
235 return blob;
238 /****************************************************************************
239 Reply for the nt protocol.
240 ****************************************************************************/
242 static void reply_nt1(struct smb_request *req, uint16 choice)
244 /* dual names + lock_and_read + nt SMBs + remote API calls */
245 int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ|
246 CAP_LEVEL_II_OPLOCKS;
248 int secword=0;
249 char *p, *q;
250 bool negotiate_spnego = False;
251 time_t t = time(NULL);
252 ssize_t ret;
254 global_encrypted_passwords_negotiated = lp_encrypted_passwords();
256 /* Check the flags field to see if this is Vista.
257 WinXP sets it and Vista does not. But we have to
258 distinguish from NT which doesn't set it either. */
260 if ( (req->flags2 & FLAGS2_EXTENDED_SECURITY) &&
261 ((req->flags2 & FLAGS2_UNKNOWN_BIT4) == 0) )
263 if (get_remote_arch() != RA_SAMBA) {
264 set_remote_arch( RA_VISTA );
268 reply_outbuf(req,17,0);
270 /* do spnego in user level security if the client
271 supports it and we can do encrypted passwords */
273 if (global_encrypted_passwords_negotiated &&
274 (lp_security() != SEC_SHARE) &&
275 lp_use_spnego() &&
276 (req->flags2 & FLAGS2_EXTENDED_SECURITY)) {
277 negotiate_spnego = True;
278 capabilities |= CAP_EXTENDED_SECURITY;
279 add_to_common_flags2(FLAGS2_EXTENDED_SECURITY);
280 /* Ensure FLAGS2_EXTENDED_SECURITY gets set in this reply
281 (already partially constructed. */
282 SSVAL(req->outbuf, smb_flg2,
283 req->flags2 | FLAGS2_EXTENDED_SECURITY);
286 capabilities |= CAP_NT_SMBS|CAP_RPC_REMOTE_APIS|CAP_UNICODE;
288 if (lp_unix_extensions()) {
289 capabilities |= CAP_UNIX;
292 if (lp_large_readwrite() && (SMB_OFF_T_BITS == 64))
293 capabilities |= CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_W2K_SMBS;
295 if (SMB_OFF_T_BITS == 64)
296 capabilities |= CAP_LARGE_FILES;
298 if (lp_readraw() && lp_writeraw())
299 capabilities |= CAP_RAW_MODE;
301 if (lp_nt_status_support())
302 capabilities |= CAP_STATUS32;
304 if (lp_host_msdfs())
305 capabilities |= CAP_DFS;
307 if (lp_security() >= SEC_USER)
308 secword |= NEGOTIATE_SECURITY_USER_LEVEL;
309 if (global_encrypted_passwords_negotiated)
310 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
312 if (lp_server_signing()) {
313 if (lp_security() >= SEC_USER) {
314 secword |= NEGOTIATE_SECURITY_SIGNATURES_ENABLED;
315 /* No raw mode with smb signing. */
316 capabilities &= ~CAP_RAW_MODE;
317 if (lp_server_signing() == Required)
318 secword |=NEGOTIATE_SECURITY_SIGNATURES_REQUIRED;
319 srv_set_signing_negotiated();
320 } else {
321 DEBUG(0,("reply_nt1: smb signing is incompatible with share level security !\n"));
322 if (lp_server_signing() == Required) {
323 exit_server_cleanly("reply_nt1: smb signing required and share level security selected.");
328 SSVAL(req->outbuf,smb_vwv0,choice);
329 SCVAL(req->outbuf,smb_vwv1,secword);
331 Protocol = PROTOCOL_NT1;
333 SSVAL(req->outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
334 SSVAL(req->outbuf,smb_vwv2+1,1); /* num vcs */
335 SIVAL(req->outbuf,smb_vwv3+1,max_recv); /* max buffer. LOTS! */
336 SIVAL(req->outbuf,smb_vwv5+1,0x10000); /* raw size. full 64k */
337 SIVAL(req->outbuf,smb_vwv7+1,sys_getpid()); /* session key */
338 SIVAL(req->outbuf,smb_vwv9+1,capabilities); /* capabilities */
339 put_long_date((char *)req->outbuf+smb_vwv11+1,t);
340 SSVALS(req->outbuf,smb_vwv15+1,set_server_zone_offset(t)/60);
342 p = q = smb_buf(req->outbuf);
343 if (!negotiate_spnego) {
344 /* Create a token value and add it to the outgoing packet. */
345 if (global_encrypted_passwords_negotiated) {
346 uint8 chal[8];
347 /* note that we do not send a challenge at all if
348 we are using plaintext */
349 get_challenge(chal);
350 ret = message_push_blob(
351 &req->outbuf, data_blob_const(chal, sizeof(chal)));
352 if (ret == -1) {
353 DEBUG(0, ("Could not push challenge\n"));
354 reply_nterror(req, NT_STATUS_NO_MEMORY);
355 return;
357 SCVAL(req->outbuf, smb_vwv16+1, ret);
358 p += ret;
360 ret = message_push_string(&req->outbuf, lp_workgroup(),
361 STR_UNICODE|STR_TERMINATE
362 |STR_NOALIGN);
363 if (ret == -1) {
364 DEBUG(0, ("Could not push challenge\n"));
365 reply_nterror(req, NT_STATUS_NO_MEMORY);
366 return;
368 DEBUG(3,("not using SPNEGO\n"));
369 } else {
370 DATA_BLOB spnego_blob = negprot_spnego();
372 if (spnego_blob.data == NULL) {
373 reply_nterror(req, NT_STATUS_NO_MEMORY);
374 return;
377 ret = message_push_blob(&req->outbuf, spnego_blob);
378 if (ret == -1) {
379 DEBUG(0, ("Could not push spnego blob\n"));
380 reply_nterror(req, NT_STATUS_NO_MEMORY);
381 return;
383 p += ret;
384 data_blob_free(&spnego_blob);
386 SCVAL(req->outbuf,smb_vwv16+1, 0);
387 DEBUG(3,("using SPNEGO\n"));
390 SSVAL(req->outbuf,smb_vwv17, p - q); /* length of challenge+domain
391 * strings */
393 return;
396 /* these are the protocol lists used for auto architecture detection:
398 WinNT 3.51:
399 protocol [PC NETWORK PROGRAM 1.0]
400 protocol [XENIX CORE]
401 protocol [MICROSOFT NETWORKS 1.03]
402 protocol [LANMAN1.0]
403 protocol [Windows for Workgroups 3.1a]
404 protocol [LM1.2X002]
405 protocol [LANMAN2.1]
406 protocol [NT LM 0.12]
408 Win95:
409 protocol [PC NETWORK PROGRAM 1.0]
410 protocol [XENIX CORE]
411 protocol [MICROSOFT NETWORKS 1.03]
412 protocol [LANMAN1.0]
413 protocol [Windows for Workgroups 3.1a]
414 protocol [LM1.2X002]
415 protocol [LANMAN2.1]
416 protocol [NT LM 0.12]
418 Win2K:
419 protocol [PC NETWORK PROGRAM 1.0]
420 protocol [LANMAN1.0]
421 protocol [Windows for Workgroups 3.1a]
422 protocol [LM1.2X002]
423 protocol [LANMAN2.1]
424 protocol [NT LM 0.12]
426 Vista:
427 protocol [PC NETWORK PROGRAM 1.0]
428 protocol [LANMAN1.0]
429 protocol [Windows for Workgroups 3.1a]
430 protocol [LM1.2X002]
431 protocol [LANMAN2.1]
432 protocol [NT LM 0.12]
433 protocol [SMB 2.001]
435 OS/2:
436 protocol [PC NETWORK PROGRAM 1.0]
437 protocol [XENIX CORE]
438 protocol [LANMAN1.0]
439 protocol [LM1.2X002]
440 protocol [LANMAN2.1]
444 * Modified to recognize the architecture of the remote machine better.
446 * This appears to be the matrix of which protocol is used by which
447 * MS product.
448 Protocol WfWg Win95 WinNT Win2K OS/2 Vista
449 PC NETWORK PROGRAM 1.0 1 1 1 1 1 1
450 XENIX CORE 2 2
451 MICROSOFT NETWORKS 3.0 2 2
452 DOS LM1.2X002 3 3
453 MICROSOFT NETWORKS 1.03 3
454 DOS LANMAN2.1 4 4
455 LANMAN1.0 4 2 3 2
456 Windows for Workgroups 3.1a 5 5 5 3 3
457 LM1.2X002 6 4 4 4
458 LANMAN2.1 7 5 5 5
459 NT LM 0.12 6 8 6 6
460 SMB 2.001 7
462 * tim@fsg.com 09/29/95
463 * Win2K added by matty 17/7/99
466 #define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
467 #define ARCH_WIN95 0x2
468 #define ARCH_WINNT 0x4
469 #define ARCH_WIN2K 0xC /* Win2K is like NT */
470 #define ARCH_OS2 0x14 /* Again OS/2 is like NT */
471 #define ARCH_SAMBA 0x20
472 #define ARCH_CIFSFS 0x40
473 #define ARCH_VISTA 0x8C /* Vista is like XP/2K */
475 #define ARCH_ALL 0x7F
477 /* List of supported protocols, most desired first */
478 static const struct {
479 const char *proto_name;
480 const char *short_name;
481 void (*proto_reply_fn)(struct smb_request *req, uint16 choice);
482 int protocol_level;
483 } supported_protocols[] = {
484 {"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1},
485 {"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1},
486 {"POSIX 2", "NT1", reply_nt1, PROTOCOL_NT1},
487 {"LANMAN2.1", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
488 {"LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
489 {"Samba", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
490 {"DOS LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
491 {"LANMAN1.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
492 {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
493 {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
494 {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep, PROTOCOL_CORE},
495 {NULL,NULL,NULL,0},
498 /****************************************************************************
499 Reply to a negprot.
500 conn POINTER CAN BE NULL HERE !
501 ****************************************************************************/
503 void reply_negprot(struct smb_request *req)
505 int choice= -1;
506 int protocol;
507 const char *p;
508 int arch = ARCH_ALL;
509 int num_cliprotos;
510 char **cliprotos;
511 int i;
512 size_t converted_size;
514 START_PROFILE(SMBnegprot);
516 if (done_negprot) {
517 END_PROFILE(SMBnegprot);
518 exit_server_cleanly("multiple negprot's are not permitted");
520 done_negprot = True;
522 if (req->buflen == 0) {
523 DEBUG(0, ("negprot got no protocols\n"));
524 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
525 END_PROFILE(SMBnegprot);
526 return;
529 if (req->buf[req->buflen-1] != '\0') {
530 DEBUG(0, ("negprot protocols not 0-terminated\n"));
531 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
532 END_PROFILE(SMBnegprot);
533 return;
536 p = (const char *)req->buf + 1;
538 num_cliprotos = 0;
539 cliprotos = NULL;
541 while (smbreq_bufrem(req, p) > 0) {
543 char **tmp;
545 tmp = TALLOC_REALLOC_ARRAY(talloc_tos(), cliprotos, char *,
546 num_cliprotos+1);
547 if (tmp == NULL) {
548 DEBUG(0, ("talloc failed\n"));
549 TALLOC_FREE(cliprotos);
550 reply_nterror(req, NT_STATUS_NO_MEMORY);
551 END_PROFILE(SMBnegprot);
552 return;
555 cliprotos = tmp;
557 if (!pull_ascii_talloc(cliprotos, &cliprotos[num_cliprotos], p,
558 &converted_size)) {
559 DEBUG(0, ("pull_ascii_talloc failed\n"));
560 TALLOC_FREE(cliprotos);
561 reply_nterror(req, NT_STATUS_NO_MEMORY);
562 END_PROFILE(SMBnegprot);
563 return;
566 DEBUG(3, ("Requested protocol [%s]\n",
567 cliprotos[num_cliprotos]));
569 num_cliprotos += 1;
570 p += strlen(p) + 2;
573 for (i=0; i<num_cliprotos; i++) {
574 if (strcsequal(cliprotos[i], "Windows for Workgroups 3.1a"))
575 arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT
576 | ARCH_WIN2K );
577 else if (strcsequal(cliprotos[i], "DOS LM1.2X002"))
578 arch &= ( ARCH_WFWG | ARCH_WIN95 );
579 else if (strcsequal(cliprotos[i], "DOS LANMAN2.1"))
580 arch &= ( ARCH_WFWG | ARCH_WIN95 );
581 else if (strcsequal(cliprotos[i], "NT LM 0.12"))
582 arch &= ( ARCH_WIN95 | ARCH_WINNT | ARCH_WIN2K
583 | ARCH_CIFSFS);
584 else if (strcsequal(cliprotos[i], "SMB 2.001"))
585 arch = ARCH_VISTA;
586 else if (strcsequal(cliprotos[i], "LANMAN2.1"))
587 arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 );
588 else if (strcsequal(cliprotos[i], "LM1.2X002"))
589 arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 );
590 else if (strcsequal(cliprotos[i], "MICROSOFT NETWORKS 1.03"))
591 arch &= ARCH_WINNT;
592 else if (strcsequal(cliprotos[i], "XENIX CORE"))
593 arch &= ( ARCH_WINNT | ARCH_OS2 );
594 else if (strcsequal(cliprotos[i], "Samba")) {
595 arch = ARCH_SAMBA;
596 break;
597 } else if (strcsequal(cliprotos[i], "POSIX 2")) {
598 arch = ARCH_CIFSFS;
599 break;
603 /* CIFSFS can send one arch only, NT LM 0.12. */
604 if (i == 1 && (arch & ARCH_CIFSFS)) {
605 arch = ARCH_CIFSFS;
608 switch ( arch ) {
609 case ARCH_CIFSFS:
610 set_remote_arch(RA_CIFSFS);
611 break;
612 case ARCH_SAMBA:
613 set_remote_arch(RA_SAMBA);
614 break;
615 case ARCH_WFWG:
616 set_remote_arch(RA_WFWG);
617 break;
618 case ARCH_WIN95:
619 set_remote_arch(RA_WIN95);
620 break;
621 case ARCH_WINNT:
622 if(req->flags2 == FLAGS2_WIN2K_SIGNATURE)
623 set_remote_arch(RA_WIN2K);
624 else
625 set_remote_arch(RA_WINNT);
626 break;
627 case ARCH_WIN2K:
628 /* Vista may have been set in the negprot so don't
629 override it here */
630 if ( get_remote_arch() != RA_VISTA )
631 set_remote_arch(RA_WIN2K);
632 break;
633 case ARCH_VISTA:
634 set_remote_arch(RA_VISTA);
635 break;
636 case ARCH_OS2:
637 set_remote_arch(RA_OS2);
638 break;
639 default:
640 set_remote_arch(RA_UNKNOWN);
641 break;
644 /* possibly reload - change of architecture */
645 reload_services(True);
647 /* moved from the netbios session setup code since we don't have that
648 when the client connects to port 445. Of course there is a small
649 window where we are listening to messages -- jerry */
651 claim_connection(
652 NULL,"",FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL);
654 /* Check for protocols, most desirable first */
655 for (protocol = 0; supported_protocols[protocol].proto_name; protocol++) {
656 i = 0;
657 if ((supported_protocols[protocol].protocol_level <= lp_maxprotocol()) &&
658 (supported_protocols[protocol].protocol_level >= lp_minprotocol()))
659 while (i < num_cliprotos) {
660 if (strequal(cliprotos[i],supported_protocols[protocol].proto_name))
661 choice = i;
662 i++;
664 if(choice != -1)
665 break;
668 if(choice != -1) {
669 fstrcpy(remote_proto,supported_protocols[protocol].short_name);
670 reload_services(True);
671 supported_protocols[protocol].proto_reply_fn(req, choice);
672 DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
673 } else {
674 DEBUG(0,("No protocol supported !\n"));
675 reply_outbuf(req, 1, 0);
676 SSVAL(req->outbuf, smb_vwv0, choice);
679 DEBUG( 5, ( "negprot index=%d\n", choice ) );
681 if ((lp_server_signing() == Required) && (Protocol < PROTOCOL_NT1)) {
682 exit_server_cleanly("SMB signing is required and "
683 "client negotiated a downlevel protocol");
686 TALLOC_FREE(cliprotos);
687 END_PROFILE(SMBnegprot);
688 return;