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