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