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