s3: Remove the smbd_messaging_context from spoolss_init_cb
[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
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->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         time_t t = time(NULL);
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         put_long_date((char *)req->outbuf+smb_vwv11+1,t);
363         SSVALS(req->outbuf,smb_vwv15+1,set_server_zone_offset(t)/60);
364         
365         p = q = smb_buf(req->outbuf);
366         if (!negotiate_spnego) {
367                 /* Create a token value and add it to the outgoing packet. */
368                 if (sconn->smb1.negprot.encrypted_passwords) {
369                         uint8 chal[8];
370                         /* note that we do not send a challenge at all if
371                            we are using plaintext */
372                         get_challenge(sconn, chal);
373                         ret = message_push_blob(
374                                 &req->outbuf, data_blob_const(chal, sizeof(chal)));
375                         if (ret == -1) {
376                                 DEBUG(0, ("Could not push challenge\n"));
377                                 reply_nterror(req, NT_STATUS_NO_MEMORY);
378                                 return;
379                         }
380                         SCVAL(req->outbuf, smb_vwv16+1, ret);
381                         p += ret;
382                 }
383                 ret = message_push_string(&req->outbuf, lp_workgroup(),
384                                           STR_UNICODE|STR_TERMINATE
385                                           |STR_NOALIGN);
386                 if (ret == -1) {
387                         DEBUG(0, ("Could not push challenge\n"));
388                         reply_nterror(req, NT_STATUS_NO_MEMORY);
389                         return;
390                 }
391                 DEBUG(3,("not using SPNEGO\n"));
392         } else {
393                 DATA_BLOB spnego_blob = negprot_spnego(req, req->sconn);
394
395                 if (spnego_blob.data == NULL) {
396                         reply_nterror(req, NT_STATUS_NO_MEMORY);
397                         return;
398                 }
399
400                 ret = message_push_blob(&req->outbuf, spnego_blob);
401                 if (ret == -1) {
402                         DEBUG(0, ("Could not push spnego blob\n"));
403                         reply_nterror(req, NT_STATUS_NO_MEMORY);
404                         return;
405                 }
406                 p += ret;
407                 data_blob_free(&spnego_blob);
408
409                 SCVAL(req->outbuf,smb_vwv16+1, 0);
410                 DEBUG(3,("using SPNEGO\n"));
411         }
412         
413         SSVAL(req->outbuf,smb_vwv17, p - q); /* length of challenge+domain
414                                               * strings */
415
416         return;
417 }
418
419 /* these are the protocol lists used for auto architecture detection:
420
421 WinNT 3.51:
422 protocol [PC NETWORK PROGRAM 1.0]
423 protocol [XENIX CORE]
424 protocol [MICROSOFT NETWORKS 1.03]
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 Win95:
432 protocol [PC NETWORK PROGRAM 1.0]
433 protocol [XENIX CORE]
434 protocol [MICROSOFT NETWORKS 1.03]
435 protocol [LANMAN1.0]
436 protocol [Windows for Workgroups 3.1a]
437 protocol [LM1.2X002]
438 protocol [LANMAN2.1]
439 protocol [NT LM 0.12]
440
441 Win2K:
442 protocol [PC NETWORK PROGRAM 1.0]
443 protocol [LANMAN1.0]
444 protocol [Windows for Workgroups 3.1a]
445 protocol [LM1.2X002]
446 protocol [LANMAN2.1]
447 protocol [NT LM 0.12]
448
449 Vista:
450 protocol [PC NETWORK PROGRAM 1.0]
451 protocol [LANMAN1.0]
452 protocol [Windows for Workgroups 3.1a]
453 protocol [LM1.2X002]
454 protocol [LANMAN2.1]
455 protocol [NT LM 0.12]
456 protocol [SMB 2.001]
457
458 OS/2:
459 protocol [PC NETWORK PROGRAM 1.0]
460 protocol [XENIX CORE]
461 protocol [LANMAN1.0]
462 protocol [LM1.2X002]
463 protocol [LANMAN2.1]
464 */
465
466 /*
467   * Modified to recognize the architecture of the remote machine better.
468   *
469   * This appears to be the matrix of which protocol is used by which
470   * MS product.
471        Protocol                       WfWg    Win95   WinNT  Win2K  OS/2 Vista
472        PC NETWORK PROGRAM 1.0          1       1       1      1      1     1
473        XENIX CORE                                      2             2
474        MICROSOFT NETWORKS 3.0          2       2       
475        DOS LM1.2X002                   3       3       
476        MICROSOFT NETWORKS 1.03                         3
477        DOS LANMAN2.1                   4       4       
478        LANMAN1.0                                       4      2      3     2
479        Windows for Workgroups 3.1a     5       5       5      3            3
480        LM1.2X002                                       6      4      4     4
481        LANMAN2.1                                       7      5      5     5
482        NT LM 0.12                              6       8      6            6
483        SMB 2.001                                                           7
484   *
485   *  tim@fsg.com 09/29/95
486   *  Win2K added by matty 17/7/99
487   */
488   
489 #define ARCH_WFWG     0x3      /* This is a fudge because WfWg is like Win95 */
490 #define ARCH_WIN95    0x2
491 #define ARCH_WINNT    0x4
492 #define ARCH_WIN2K    0xC      /* Win2K is like NT */
493 #define ARCH_OS2      0x14     /* Again OS/2 is like NT */
494 #define ARCH_SAMBA    0x20
495 #define ARCH_CIFSFS   0x40
496 #define ARCH_VISTA    0x8C     /* Vista is like XP/2K */
497  
498 #define ARCH_ALL      0x7F
499  
500 /* List of supported protocols, most desired first */
501 static const struct {
502         const char *proto_name;
503         const char *short_name;
504         void (*proto_reply_fn)(struct smb_request *req, uint16 choice);
505         int protocol_level;
506 } supported_protocols[] = {
507         {"SMB 2.002",               "SMB2",     reply_smb2002,  PROTOCOL_SMB2},
508         {"NT LANMAN 1.0",           "NT1",      reply_nt1,      PROTOCOL_NT1},
509         {"NT LM 0.12",              "NT1",      reply_nt1,      PROTOCOL_NT1},
510         {"POSIX 2",                 "NT1",      reply_nt1,      PROTOCOL_NT1},
511         {"LANMAN2.1",               "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
512         {"LM1.2X002",               "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
513         {"Samba",                   "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
514         {"DOS LM1.2X002",           "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
515         {"LANMAN1.0",               "LANMAN1",  reply_lanman1,  PROTOCOL_LANMAN1},
516         {"MICROSOFT NETWORKS 3.0",  "LANMAN1",  reply_lanman1,  PROTOCOL_LANMAN1},
517         {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
518         {"PC NETWORK PROGRAM 1.0",  "CORE",     reply_corep,    PROTOCOL_CORE}, 
519         {NULL,NULL,NULL,0},
520 };
521
522 /****************************************************************************
523  Reply to a negprot.
524  conn POINTER CAN BE NULL HERE !
525 ****************************************************************************/
526
527 void reply_negprot(struct smb_request *req)
528 {
529         int choice= -1;
530         int protocol;
531         const char *p;
532         int arch = ARCH_ALL;
533         int num_cliprotos;
534         char **cliprotos;
535         int i;
536         size_t converted_size;
537         struct smbd_server_connection *sconn = req->sconn;
538
539         START_PROFILE(SMBnegprot);
540
541         if (sconn->smb1.negprot.done) {
542                 END_PROFILE(SMBnegprot);
543                 exit_server_cleanly("multiple negprot's are not permitted");
544         }
545         sconn->smb1.negprot.done = true;
546
547         if (req->buflen == 0) {
548                 DEBUG(0, ("negprot got no protocols\n"));
549                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
550                 END_PROFILE(SMBnegprot);
551                 return;
552         }
553
554         if (req->buf[req->buflen-1] != '\0') {
555                 DEBUG(0, ("negprot protocols not 0-terminated\n"));
556                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
557                 END_PROFILE(SMBnegprot);
558                 return;
559         }
560
561         p = (const char *)req->buf + 1;
562
563         num_cliprotos = 0;
564         cliprotos = NULL;
565
566         while (smbreq_bufrem(req, p) > 0) {
567
568                 char **tmp;
569
570                 tmp = TALLOC_REALLOC_ARRAY(talloc_tos(), cliprotos, char *,
571                                            num_cliprotos+1);
572                 if (tmp == NULL) {
573                         DEBUG(0, ("talloc failed\n"));
574                         TALLOC_FREE(cliprotos);
575                         reply_nterror(req, NT_STATUS_NO_MEMORY);
576                         END_PROFILE(SMBnegprot);
577                         return;
578                 }
579
580                 cliprotos = tmp;
581
582                 if (!pull_ascii_talloc(cliprotos, &cliprotos[num_cliprotos], p,
583                                        &converted_size)) {
584                         DEBUG(0, ("pull_ascii_talloc failed\n"));
585                         TALLOC_FREE(cliprotos);
586                         reply_nterror(req, NT_STATUS_NO_MEMORY);
587                         END_PROFILE(SMBnegprot);
588                         return;
589                 }
590
591                 DEBUG(3, ("Requested protocol [%s]\n",
592                           cliprotos[num_cliprotos]));
593
594                 num_cliprotos += 1;
595                 p += strlen(p) + 2;
596         }
597
598         for (i=0; i<num_cliprotos; i++) {
599                 if (strcsequal(cliprotos[i], "Windows for Workgroups 3.1a"))
600                         arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT
601                                   | ARCH_WIN2K );
602                 else if (strcsequal(cliprotos[i], "DOS LM1.2X002"))
603                         arch &= ( ARCH_WFWG | ARCH_WIN95 );
604                 else if (strcsequal(cliprotos[i], "DOS LANMAN2.1"))
605                         arch &= ( ARCH_WFWG | ARCH_WIN95 );
606                 else if (strcsequal(cliprotos[i], "NT LM 0.12"))
607                         arch &= ( ARCH_WIN95 | ARCH_WINNT | ARCH_WIN2K
608                                   | ARCH_CIFSFS);
609                 else if (strcsequal(cliprotos[i], "SMB 2.001"))
610                         arch = ARCH_VISTA;              
611                 else if (strcsequal(cliprotos[i], "LANMAN2.1"))
612                         arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 );
613                 else if (strcsequal(cliprotos[i], "LM1.2X002"))
614                         arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 );
615                 else if (strcsequal(cliprotos[i], "MICROSOFT NETWORKS 1.03"))
616                         arch &= ARCH_WINNT;
617                 else if (strcsequal(cliprotos[i], "XENIX CORE"))
618                         arch &= ( ARCH_WINNT | ARCH_OS2 );
619                 else if (strcsequal(cliprotos[i], "Samba")) {
620                         arch = ARCH_SAMBA;
621                         break;
622                 } else if (strcsequal(cliprotos[i], "POSIX 2")) {
623                         arch = ARCH_CIFSFS;
624                         break;
625                 }
626         }
627
628         /* CIFSFS can send one arch only, NT LM 0.12. */
629         if (i == 1 && (arch & ARCH_CIFSFS)) {
630                 arch = ARCH_CIFSFS;
631         }
632
633         switch ( arch ) {
634                 case ARCH_CIFSFS:
635                         set_remote_arch(RA_CIFSFS);
636                         break;
637                 case ARCH_SAMBA:
638                         set_remote_arch(RA_SAMBA);
639                         break;
640                 case ARCH_WFWG:
641                         set_remote_arch(RA_WFWG);
642                         break;
643                 case ARCH_WIN95:
644                         set_remote_arch(RA_WIN95);
645                         break;
646                 case ARCH_WINNT:
647                         if(req->flags2 == FLAGS2_WIN2K_SIGNATURE)
648                                 set_remote_arch(RA_WIN2K);
649                         else
650                                 set_remote_arch(RA_WINNT);
651                         break;
652                 case ARCH_WIN2K:
653                         /* Vista may have been set in the negprot so don't 
654                            override it here */
655                         if ( get_remote_arch() != RA_VISTA )
656                                 set_remote_arch(RA_WIN2K);
657                         break;
658                 case ARCH_VISTA:
659                         set_remote_arch(RA_VISTA);
660                         break;
661                 case ARCH_OS2:
662                         set_remote_arch(RA_OS2);
663                         break;
664                 default:
665                         set_remote_arch(RA_UNKNOWN);
666                 break;
667         }
668  
669         /* possibly reload - change of architecture */
670         reload_services(sconn->msg_ctx, True);
671         
672         /* moved from the netbios session setup code since we don't have that 
673            when the client connects to port 445.  Of course there is a small
674            window where we are listening to messages   -- jerry */
675
676         serverid_register(sconn_server_id(sconn),
677                           FLAG_MSG_GENERAL|FLAG_MSG_SMBD
678                           |FLAG_MSG_PRINT_GENERAL);
679     
680         /* Check for protocols, most desirable first */
681         for (protocol = 0; supported_protocols[protocol].proto_name; protocol++) {
682                 i = 0;
683                 if ((supported_protocols[protocol].protocol_level <= lp_maxprotocol()) &&
684                                 (supported_protocols[protocol].protocol_level >= lp_minprotocol()))
685                         while (i < num_cliprotos) {
686                                 if (strequal(cliprotos[i],supported_protocols[protocol].proto_name))
687                                         choice = i;
688                                 i++;
689                         }
690                 if(choice != -1)
691                         break;
692         }
693   
694         if(choice != -1) {
695                 fstrcpy(remote_proto,supported_protocols[protocol].short_name);
696                 reload_services(sconn->msg_ctx, True);
697                 supported_protocols[protocol].proto_reply_fn(req, choice);
698                 DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
699         } else {
700                 DEBUG(0,("No protocol supported !\n"));
701                 reply_outbuf(req, 1, 0);
702                 SSVAL(req->outbuf, smb_vwv0, choice);
703         }
704   
705         DEBUG( 5, ( "negprot index=%d\n", choice ) );
706
707         if ((lp_server_signing() == Required) && (get_Protocol() < PROTOCOL_NT1)) {
708                 exit_server_cleanly("SMB signing is required and "
709                         "client negotiated a downlevel protocol");
710         }
711
712         TALLOC_FREE(cliprotos);
713         END_PROFILE(SMBnegprot);
714         return;
715 }