librpc: rerun make idl
[Samba/gbeck.git] / source3 / smbd / negprot.c
blob57608a9b406785b507a29af8fe74b7b4ecebac02
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;
30 const uint8 *cryptkey;
32 /* We might be called more than once, multiple negprots are
33 * permitted */
34 if (negprot_global_auth_context) {
35 DEBUG(3, ("get challenge: is this a secondary negprot? negprot_global_auth_context is non-NULL!\n"));
36 (negprot_global_auth_context->free)(&negprot_global_auth_context);
39 DEBUG(10, ("get challenge: creating negprot_global_auth_context\n"));
40 if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&negprot_global_auth_context))) {
41 DEBUG(0, ("make_auth_context_subsystem returned %s", nt_errstr(nt_status)));
42 smb_panic("cannot make_negprot_global_auth_context!");
44 DEBUG(10, ("get challenge: getting challenge\n"));
45 cryptkey = negprot_global_auth_context->get_ntlm_challenge(negprot_global_auth_context);
46 memcpy(buff, cryptkey, 8);
49 /****************************************************************************
50 Reply for the core protocol.
51 ****************************************************************************/
53 static void reply_corep(struct smb_request *req, uint16 choice)
55 reply_outbuf(req, 1, 0);
56 SSVAL(req->outbuf, smb_vwv0, choice);
58 Protocol = PROTOCOL_CORE;
61 /****************************************************************************
62 Reply for the coreplus protocol.
63 ****************************************************************************/
65 static void reply_coreplus(struct smb_request *req, uint16 choice)
67 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
69 reply_outbuf(req, 13, 0);
71 SSVAL(req->outbuf,smb_vwv0,choice);
72 SSVAL(req->outbuf,smb_vwv5,raw); /* tell redirector we support
73 readbraw and writebraw (possibly) */
74 /* Reply, SMBlockread, SMBwritelock supported. */
75 SCVAL(req->outbuf,smb_flg,FLAG_REPLY|FLAG_SUPPORT_LOCKREAD);
76 SSVAL(req->outbuf,smb_vwv1,0x1); /* user level security, don't
77 * encrypt */
78 Protocol = PROTOCOL_COREPLUS;
81 /****************************************************************************
82 Reply for the lanman 1.0 protocol.
83 ****************************************************************************/
85 static void reply_lanman1(struct smb_request *req, uint16 choice)
87 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
88 int secword=0;
89 time_t t = time(NULL);
91 global_encrypted_passwords_negotiated = lp_encrypted_passwords();
93 if (lp_security()>=SEC_USER)
94 secword |= NEGOTIATE_SECURITY_USER_LEVEL;
95 if (global_encrypted_passwords_negotiated)
96 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
98 reply_outbuf(req, 13, global_encrypted_passwords_negotiated?8:0);
100 SSVAL(req->outbuf,smb_vwv0,choice);
101 SSVAL(req->outbuf,smb_vwv1,secword);
102 /* Create a token value and add it to the outgoing packet. */
103 if (global_encrypted_passwords_negotiated) {
104 get_challenge((uint8 *)smb_buf(req->outbuf));
105 SSVAL(req->outbuf,smb_vwv11, 8);
108 Protocol = PROTOCOL_LANMAN1;
110 /* Reply, SMBlockread, SMBwritelock supported. */
111 SCVAL(req->outbuf,smb_flg,FLAG_REPLY|FLAG_SUPPORT_LOCKREAD);
112 SSVAL(req->outbuf,smb_vwv2,max_recv);
113 SSVAL(req->outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
114 SSVAL(req->outbuf,smb_vwv4,1);
115 SSVAL(req->outbuf,smb_vwv5,raw); /* tell redirector we support
116 readbraw writebraw (possibly) */
117 SIVAL(req->outbuf,smb_vwv6,sys_getpid());
118 SSVAL(req->outbuf,smb_vwv10, set_server_zone_offset(t)/60);
120 srv_put_dos_date((char *)req->outbuf,smb_vwv8,t);
122 return;
125 /****************************************************************************
126 Reply for the lanman 2.0 protocol.
127 ****************************************************************************/
129 static void reply_lanman2(struct smb_request *req, uint16 choice)
131 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
132 int secword=0;
133 time_t t = time(NULL);
135 global_encrypted_passwords_negotiated = lp_encrypted_passwords();
137 if (lp_security()>=SEC_USER)
138 secword |= NEGOTIATE_SECURITY_USER_LEVEL;
139 if (global_encrypted_passwords_negotiated)
140 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
142 reply_outbuf(req, 13, global_encrypted_passwords_negotiated?8:0);
144 SSVAL(req->outbuf,smb_vwv0,choice);
145 SSVAL(req->outbuf,smb_vwv1,secword);
146 SIVAL(req->outbuf,smb_vwv6,sys_getpid());
148 /* Create a token value and add it to the outgoing packet. */
149 if (global_encrypted_passwords_negotiated) {
150 get_challenge((uint8 *)smb_buf(req->outbuf));
151 SSVAL(req->outbuf,smb_vwv11, 8);
154 Protocol = PROTOCOL_LANMAN2;
156 /* Reply, SMBlockread, SMBwritelock supported. */
157 SCVAL(req->outbuf,smb_flg,FLAG_REPLY|FLAG_SUPPORT_LOCKREAD);
158 SSVAL(req->outbuf,smb_vwv2,max_recv);
159 SSVAL(req->outbuf,smb_vwv3,lp_maxmux());
160 SSVAL(req->outbuf,smb_vwv4,1);
161 SSVAL(req->outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
162 SSVAL(req->outbuf,smb_vwv10, set_server_zone_offset(t)/60);
163 srv_put_dos_date((char *)req->outbuf,smb_vwv8,t);
166 /****************************************************************************
167 Generate the spnego negprot reply blob. Return the number of bytes used.
168 ****************************************************************************/
170 static DATA_BLOB negprot_spnego(void)
172 DATA_BLOB blob;
173 nstring dos_name;
174 fstring unix_name;
175 #ifdef DEVELOPER
176 size_t slen;
177 #endif
178 char guid[17];
179 const char *OIDs_krb5[] = {OID_KERBEROS5,
180 OID_KERBEROS5_OLD,
181 OID_NTLMSSP,
182 NULL};
183 const char *OIDs_plain[] = {OID_NTLMSSP, NULL};
185 global_spnego_negotiated = True;
187 memset(guid, '\0', sizeof(guid));
189 safe_strcpy(unix_name, global_myname(), sizeof(unix_name)-1);
190 strlower_m(unix_name);
191 push_ascii_nstring(dos_name, unix_name);
192 safe_strcpy(guid, dos_name, sizeof(guid)-1);
194 #ifdef DEVELOPER
195 /* Fix valgrind 'uninitialized bytes' issue. */
196 slen = strlen(dos_name);
197 if (slen < sizeof(guid)) {
198 memset(guid+slen, '\0', sizeof(guid) - slen);
200 #endif
202 /* strangely enough, NT does not sent the single OID NTLMSSP when
203 not a ADS member, it sends no OIDs at all
205 OLD COMMENT : "we can't do this until we teach our sesssion setup parser to know
206 about raw NTLMSSP (clients send no ASN.1 wrapping if we do this)"
208 Our sessionsetup code now handles raw NTLMSSP connects, so we can go
209 back to doing what W2K3 does here. This is needed to make PocketPC 2003
210 CIFS connections work with SPNEGO. See bugzilla bugs #1828 and #3133
211 for details. JRA.
215 if (lp_security() != SEC_ADS && !USE_KERBEROS_KEYTAB) {
216 #if 0
217 /* Code for PocketPC client */
218 blob = data_blob(guid, 16);
219 #else
220 /* Code for standalone WXP client */
221 blob = spnego_gen_negTokenInit(guid, OIDs_plain, "NONE");
222 #endif
223 } else {
224 fstring myname;
225 char *host_princ_s = NULL;
226 name_to_fqdn(myname, global_myname());
227 strlower_m(myname);
228 if (asprintf(&host_princ_s, "cifs/%s@%s", myname, lp_realm())
229 == -1) {
230 return data_blob_null;
232 blob = spnego_gen_negTokenInit(guid, OIDs_krb5, host_princ_s);
233 SAFE_FREE(host_princ_s);
236 return blob;
239 /****************************************************************************
240 Reply for the nt protocol.
241 ****************************************************************************/
243 static void reply_nt1(struct smb_request *req, uint16 choice)
245 /* dual names + lock_and_read + nt SMBs + remote API calls */
246 int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ|
247 CAP_LEVEL_II_OPLOCKS;
249 int secword=0;
250 char *p, *q;
251 bool negotiate_spnego = False;
252 time_t t = time(NULL);
253 ssize_t ret;
255 global_encrypted_passwords_negotiated = lp_encrypted_passwords();
257 /* Check the flags field to see if this is Vista.
258 WinXP sets it and Vista does not. But we have to
259 distinguish from NT which doesn't set it either. */
261 if ( (req->flags2 & FLAGS2_EXTENDED_SECURITY) &&
262 ((req->flags2 & FLAGS2_UNKNOWN_BIT4) == 0) )
264 if (get_remote_arch() != RA_SAMBA) {
265 set_remote_arch( RA_VISTA );
269 reply_outbuf(req,17,0);
271 /* do spnego in user level security if the client
272 supports it and we can do encrypted passwords */
274 if (global_encrypted_passwords_negotiated &&
275 (lp_security() != SEC_SHARE) &&
276 lp_use_spnego() &&
277 (req->flags2 & FLAGS2_EXTENDED_SECURITY)) {
278 negotiate_spnego = True;
279 capabilities |= CAP_EXTENDED_SECURITY;
280 add_to_common_flags2(FLAGS2_EXTENDED_SECURITY);
281 /* Ensure FLAGS2_EXTENDED_SECURITY gets set in this reply
282 (already partially constructed. */
283 SSVAL(req->outbuf, smb_flg2,
284 req->flags2 | FLAGS2_EXTENDED_SECURITY);
287 capabilities |= CAP_NT_SMBS|CAP_RPC_REMOTE_APIS|CAP_UNICODE;
289 if (lp_unix_extensions()) {
290 capabilities |= CAP_UNIX;
293 if (lp_large_readwrite() && (SMB_OFF_T_BITS == 64))
294 capabilities |= CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_W2K_SMBS;
296 if (SMB_OFF_T_BITS == 64)
297 capabilities |= CAP_LARGE_FILES;
299 if (lp_readraw() && lp_writeraw())
300 capabilities |= CAP_RAW_MODE;
302 if (lp_nt_status_support())
303 capabilities |= CAP_STATUS32;
305 if (lp_host_msdfs())
306 capabilities |= CAP_DFS;
308 if (lp_security() >= SEC_USER)
309 secword |= NEGOTIATE_SECURITY_USER_LEVEL;
310 if (global_encrypted_passwords_negotiated)
311 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
313 if (lp_server_signing()) {
314 if (lp_security() >= SEC_USER) {
315 secword |= NEGOTIATE_SECURITY_SIGNATURES_ENABLED;
316 /* No raw mode with smb signing. */
317 capabilities &= ~CAP_RAW_MODE;
318 if (lp_server_signing() == Required)
319 secword |=NEGOTIATE_SECURITY_SIGNATURES_REQUIRED;
320 srv_set_signing_negotiated();
321 } else {
322 DEBUG(0,("reply_nt1: smb signing is incompatible with share level security !\n"));
323 if (lp_server_signing() == Required) {
324 exit_server_cleanly("reply_nt1: smb signing required and share level security selected.");
329 SSVAL(req->outbuf,smb_vwv0,choice);
330 SCVAL(req->outbuf,smb_vwv1,secword);
332 Protocol = PROTOCOL_NT1;
334 SSVAL(req->outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
335 SSVAL(req->outbuf,smb_vwv2+1,1); /* num vcs */
336 SIVAL(req->outbuf,smb_vwv3+1,max_recv); /* max buffer. LOTS! */
337 SIVAL(req->outbuf,smb_vwv5+1,0x10000); /* raw size. full 64k */
338 SIVAL(req->outbuf,smb_vwv7+1,sys_getpid()); /* session key */
339 SIVAL(req->outbuf,smb_vwv9+1,capabilities); /* capabilities */
340 put_long_date((char *)req->outbuf+smb_vwv11+1,t);
341 SSVALS(req->outbuf,smb_vwv15+1,set_server_zone_offset(t)/60);
343 p = q = smb_buf(req->outbuf);
344 if (!negotiate_spnego) {
345 /* Create a token value and add it to the outgoing packet. */
346 if (global_encrypted_passwords_negotiated) {
347 uint8 chal[8];
348 /* note that we do not send a challenge at all if
349 we are using plaintext */
350 get_challenge(chal);
351 ret = message_push_blob(
352 &req->outbuf, data_blob_const(chal, sizeof(chal)));
353 if (ret == -1) {
354 DEBUG(0, ("Could not push challenge\n"));
355 reply_nterror(req, NT_STATUS_NO_MEMORY);
356 return;
358 SCVAL(req->outbuf, smb_vwv16+1, ret);
359 p += ret;
361 ret = message_push_string(&req->outbuf, lp_workgroup(),
362 STR_UNICODE|STR_TERMINATE
363 |STR_NOALIGN);
364 if (ret == -1) {
365 DEBUG(0, ("Could not push challenge\n"));
366 reply_nterror(req, NT_STATUS_NO_MEMORY);
367 return;
369 DEBUG(3,("not using SPNEGO\n"));
370 } else {
371 DATA_BLOB spnego_blob = negprot_spnego();
373 if (spnego_blob.data == NULL) {
374 reply_nterror(req, NT_STATUS_NO_MEMORY);
375 return;
378 ret = message_push_blob(&req->outbuf, spnego_blob);
379 if (ret == -1) {
380 DEBUG(0, ("Could not push spnego blob\n"));
381 reply_nterror(req, NT_STATUS_NO_MEMORY);
382 return;
384 p += ret;
385 data_blob_free(&spnego_blob);
387 SCVAL(req->outbuf,smb_vwv16+1, 0);
388 DEBUG(3,("using SPNEGO\n"));
391 SSVAL(req->outbuf,smb_vwv17, p - q); /* length of challenge+domain
392 * strings */
394 return;
397 /* these are the protocol lists used for auto architecture detection:
399 WinNT 3.51:
400 protocol [PC NETWORK PROGRAM 1.0]
401 protocol [XENIX CORE]
402 protocol [MICROSOFT NETWORKS 1.03]
403 protocol [LANMAN1.0]
404 protocol [Windows for Workgroups 3.1a]
405 protocol [LM1.2X002]
406 protocol [LANMAN2.1]
407 protocol [NT LM 0.12]
409 Win95:
410 protocol [PC NETWORK PROGRAM 1.0]
411 protocol [XENIX CORE]
412 protocol [MICROSOFT NETWORKS 1.03]
413 protocol [LANMAN1.0]
414 protocol [Windows for Workgroups 3.1a]
415 protocol [LM1.2X002]
416 protocol [LANMAN2.1]
417 protocol [NT LM 0.12]
419 Win2K:
420 protocol [PC NETWORK PROGRAM 1.0]
421 protocol [LANMAN1.0]
422 protocol [Windows for Workgroups 3.1a]
423 protocol [LM1.2X002]
424 protocol [LANMAN2.1]
425 protocol [NT LM 0.12]
427 Vista:
428 protocol [PC NETWORK PROGRAM 1.0]
429 protocol [LANMAN1.0]
430 protocol [Windows for Workgroups 3.1a]
431 protocol [LM1.2X002]
432 protocol [LANMAN2.1]
433 protocol [NT LM 0.12]
434 protocol [SMB 2.001]
436 OS/2:
437 protocol [PC NETWORK PROGRAM 1.0]
438 protocol [XENIX CORE]
439 protocol [LANMAN1.0]
440 protocol [LM1.2X002]
441 protocol [LANMAN2.1]
445 * Modified to recognize the architecture of the remote machine better.
447 * This appears to be the matrix of which protocol is used by which
448 * MS product.
449 Protocol WfWg Win95 WinNT Win2K OS/2 Vista
450 PC NETWORK PROGRAM 1.0 1 1 1 1 1 1
451 XENIX CORE 2 2
452 MICROSOFT NETWORKS 3.0 2 2
453 DOS LM1.2X002 3 3
454 MICROSOFT NETWORKS 1.03 3
455 DOS LANMAN2.1 4 4
456 LANMAN1.0 4 2 3 2
457 Windows for Workgroups 3.1a 5 5 5 3 3
458 LM1.2X002 6 4 4 4
459 LANMAN2.1 7 5 5 5
460 NT LM 0.12 6 8 6 6
461 SMB 2.001 7
463 * tim@fsg.com 09/29/95
464 * Win2K added by matty 17/7/99
467 #define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
468 #define ARCH_WIN95 0x2
469 #define ARCH_WINNT 0x4
470 #define ARCH_WIN2K 0xC /* Win2K is like NT */
471 #define ARCH_OS2 0x14 /* Again OS/2 is like NT */
472 #define ARCH_SAMBA 0x20
473 #define ARCH_CIFSFS 0x40
474 #define ARCH_VISTA 0x8C /* Vista is like XP/2K */
476 #define ARCH_ALL 0x7F
478 /* List of supported protocols, most desired first */
479 static const struct {
480 const char *proto_name;
481 const char *short_name;
482 void (*proto_reply_fn)(struct smb_request *req, uint16 choice);
483 int protocol_level;
484 } supported_protocols[] = {
485 {"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1},
486 {"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1},
487 {"POSIX 2", "NT1", reply_nt1, PROTOCOL_NT1},
488 {"LANMAN2.1", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
489 {"LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
490 {"Samba", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
491 {"DOS LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
492 {"LANMAN1.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
493 {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
494 {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
495 {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep, PROTOCOL_CORE},
496 {NULL,NULL,NULL,0},
499 /****************************************************************************
500 Reply to a negprot.
501 conn POINTER CAN BE NULL HERE !
502 ****************************************************************************/
504 void reply_negprot(struct smb_request *req)
506 int choice= -1;
507 int protocol;
508 const char *p;
509 int arch = ARCH_ALL;
510 int num_cliprotos;
511 char **cliprotos;
512 int i;
513 size_t converted_size;
515 START_PROFILE(SMBnegprot);
517 if (done_negprot) {
518 END_PROFILE(SMBnegprot);
519 exit_server_cleanly("multiple negprot's are not permitted");
521 done_negprot = True;
523 if (req->buflen == 0) {
524 DEBUG(0, ("negprot got no protocols\n"));
525 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
526 END_PROFILE(SMBnegprot);
527 return;
530 if (req->buf[req->buflen-1] != '\0') {
531 DEBUG(0, ("negprot protocols not 0-terminated\n"));
532 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
533 END_PROFILE(SMBnegprot);
534 return;
537 p = (const char *)req->buf + 1;
539 num_cliprotos = 0;
540 cliprotos = NULL;
542 while (smbreq_bufrem(req, p) > 0) {
544 char **tmp;
546 tmp = TALLOC_REALLOC_ARRAY(talloc_tos(), cliprotos, char *,
547 num_cliprotos+1);
548 if (tmp == NULL) {
549 DEBUG(0, ("talloc failed\n"));
550 TALLOC_FREE(cliprotos);
551 reply_nterror(req, NT_STATUS_NO_MEMORY);
552 END_PROFILE(SMBnegprot);
553 return;
556 cliprotos = tmp;
558 if (!pull_ascii_talloc(cliprotos, &cliprotos[num_cliprotos], p,
559 &converted_size)) {
560 DEBUG(0, ("pull_ascii_talloc failed\n"));
561 TALLOC_FREE(cliprotos);
562 reply_nterror(req, NT_STATUS_NO_MEMORY);
563 END_PROFILE(SMBnegprot);
564 return;
567 DEBUG(3, ("Requested protocol [%s]\n",
568 cliprotos[num_cliprotos]));
570 num_cliprotos += 1;
571 p += strlen(p) + 2;
574 for (i=0; i<num_cliprotos; i++) {
575 if (strcsequal(cliprotos[i], "Windows for Workgroups 3.1a"))
576 arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT
577 | ARCH_WIN2K );
578 else if (strcsequal(cliprotos[i], "DOS LM1.2X002"))
579 arch &= ( ARCH_WFWG | ARCH_WIN95 );
580 else if (strcsequal(cliprotos[i], "DOS LANMAN2.1"))
581 arch &= ( ARCH_WFWG | ARCH_WIN95 );
582 else if (strcsequal(cliprotos[i], "NT LM 0.12"))
583 arch &= ( ARCH_WIN95 | ARCH_WINNT | ARCH_WIN2K
584 | ARCH_CIFSFS);
585 else if (strcsequal(cliprotos[i], "SMB 2.001"))
586 arch = ARCH_VISTA;
587 else if (strcsequal(cliprotos[i], "LANMAN2.1"))
588 arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 );
589 else if (strcsequal(cliprotos[i], "LM1.2X002"))
590 arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 );
591 else if (strcsequal(cliprotos[i], "MICROSOFT NETWORKS 1.03"))
592 arch &= ARCH_WINNT;
593 else if (strcsequal(cliprotos[i], "XENIX CORE"))
594 arch &= ( ARCH_WINNT | ARCH_OS2 );
595 else if (strcsequal(cliprotos[i], "Samba")) {
596 arch = ARCH_SAMBA;
597 break;
598 } else if (strcsequal(cliprotos[i], "POSIX 2")) {
599 arch = ARCH_CIFSFS;
600 break;
604 /* CIFSFS can send one arch only, NT LM 0.12. */
605 if (i == 1 && (arch & ARCH_CIFSFS)) {
606 arch = ARCH_CIFSFS;
609 switch ( arch ) {
610 case ARCH_CIFSFS:
611 set_remote_arch(RA_CIFSFS);
612 break;
613 case ARCH_SAMBA:
614 set_remote_arch(RA_SAMBA);
615 break;
616 case ARCH_WFWG:
617 set_remote_arch(RA_WFWG);
618 break;
619 case ARCH_WIN95:
620 set_remote_arch(RA_WIN95);
621 break;
622 case ARCH_WINNT:
623 if(req->flags2 == FLAGS2_WIN2K_SIGNATURE)
624 set_remote_arch(RA_WIN2K);
625 else
626 set_remote_arch(RA_WINNT);
627 break;
628 case ARCH_WIN2K:
629 /* Vista may have been set in the negprot so don't
630 override it here */
631 if ( get_remote_arch() != RA_VISTA )
632 set_remote_arch(RA_WIN2K);
633 break;
634 case ARCH_VISTA:
635 set_remote_arch(RA_VISTA);
636 break;
637 case ARCH_OS2:
638 set_remote_arch(RA_OS2);
639 break;
640 default:
641 set_remote_arch(RA_UNKNOWN);
642 break;
645 /* possibly reload - change of architecture */
646 reload_services(True);
648 /* moved from the netbios session setup code since we don't have that
649 when the client connects to port 445. Of course there is a small
650 window where we are listening to messages -- jerry */
652 claim_connection(
653 NULL,"",FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL);
655 /* Check for protocols, most desirable first */
656 for (protocol = 0; supported_protocols[protocol].proto_name; protocol++) {
657 i = 0;
658 if ((supported_protocols[protocol].protocol_level <= lp_maxprotocol()) &&
659 (supported_protocols[protocol].protocol_level >= lp_minprotocol()))
660 while (i < num_cliprotos) {
661 if (strequal(cliprotos[i],supported_protocols[protocol].proto_name))
662 choice = i;
663 i++;
665 if(choice != -1)
666 break;
669 if(choice != -1) {
670 fstrcpy(remote_proto,supported_protocols[protocol].short_name);
671 reload_services(True);
672 supported_protocols[protocol].proto_reply_fn(req, choice);
673 DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
674 } else {
675 DEBUG(0,("No protocol supported !\n"));
676 reply_outbuf(req, 1, 0);
677 SSVAL(req->outbuf, smb_vwv0, choice);
680 DEBUG( 5, ( "negprot index=%d\n", choice ) );
682 if ((lp_server_signing() == Required) && (Protocol < PROTOCOL_NT1)) {
683 exit_server_cleanly("SMB signing is required and "
684 "client negotiated a downlevel protocol");
687 TALLOC_FREE(cliprotos);
688 END_PROFILE(SMBnegprot);
689 return;