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