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