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