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