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