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