d2e5e2ee27e3b86c07069d9e583fcedda5a457ca
[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                                       &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
548         START_PROFILE(SMBnegprot);
549
550         if (xconn->smb1.negprot.done) {
551                 END_PROFILE(SMBnegprot);
552                 exit_server_cleanly("multiple negprot's are not permitted");
553         }
554         xconn->smb1.negprot.done = true;
555
556         if (req->buflen == 0) {
557                 DEBUG(0, ("negprot got no protocols\n"));
558                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
559                 END_PROFILE(SMBnegprot);
560                 return;
561         }
562
563         if (req->buf[req->buflen-1] != '\0') {
564                 DEBUG(0, ("negprot protocols not 0-terminated\n"));
565                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
566                 END_PROFILE(SMBnegprot);
567                 return;
568         }
569
570         p = (const char *)req->buf + 1;
571
572         num_cliprotos = 0;
573         cliprotos = NULL;
574
575         while (smbreq_bufrem(req, p) > 0) {
576
577                 char **tmp;
578
579                 tmp = talloc_realloc(talloc_tos(), cliprotos, char *,
580                                            num_cliprotos+1);
581                 if (tmp == NULL) {
582                         DEBUG(0, ("talloc failed\n"));
583                         TALLOC_FREE(cliprotos);
584                         reply_nterror(req, NT_STATUS_NO_MEMORY);
585                         END_PROFILE(SMBnegprot);
586                         return;
587                 }
588
589                 cliprotos = tmp;
590
591                 if (!pull_ascii_talloc(cliprotos, &cliprotos[num_cliprotos], p,
592                                        &converted_size)) {
593                         DEBUG(0, ("pull_ascii_talloc failed\n"));
594                         TALLOC_FREE(cliprotos);
595                         reply_nterror(req, NT_STATUS_NO_MEMORY);
596                         END_PROFILE(SMBnegprot);
597                         return;
598                 }
599
600                 DEBUG(3, ("Requested protocol [%s]\n",
601                           cliprotos[num_cliprotos]));
602
603                 num_cliprotos += 1;
604                 p += strlen(p) + 2;
605         }
606
607         for (i=0; i<num_cliprotos; i++) {
608                 if (strcsequal(cliprotos[i], "Windows for Workgroups 3.1a")) {
609                         protocols |= PROT_WFWG;
610                 } else if (strcsequal(cliprotos[i], "DOS LM1.2X002")) {
611                         protocols |= PROT_DOS_LM1_2X002;
612                 } else if (strcsequal(cliprotos[i], "DOS LANMAN2.1")) {
613                         protocols |= PROT_DOS_LANMAN2_1;
614                 } else if (strcsequal(cliprotos[i], "LANMAN1.0")) {
615                         protocols |= PROT_LANMAN1_0;
616                 } else if (strcsequal(cliprotos[i], "NT LM 0.12")) {
617                         protocols |= PROT_NT_LM_0_12;
618                 } else if (strcsequal(cliprotos[i], "SMB 2.001")) {
619                         protocols |= PROT_SMB_2_001;
620                 } else if (strcsequal(cliprotos[i], "SMB 2.002")) {
621                         protocols |= PROT_SMB_2_002;
622                 } else if (strcsequal(cliprotos[i], "SMB 2.???")) {
623                         protocols |= PROT_SMB_2_FF;
624                 } else if (strcsequal(cliprotos[i], "LANMAN2.1")) {
625                         protocols |= PROT_LANMAN2_1;
626                 } else if (strcsequal(cliprotos[i], "LM1.2X002")) {
627                         protocols |= PROT_LM1_2X002;
628                 } else if (strcsequal(cliprotos[i], "MICROSOFT NETWORKS 1.03")) {
629                         protocols |= PROT_MICROSOFT_NETWORKS_1_03;
630                 } else if (strcsequal(cliprotos[i], "MICROSOFT NETWORKS 3.0")) {
631                         protocols |= PROT_MICROSOFT_NETWORKS_3_0;
632                 } else if (strcsequal(cliprotos[i], "PC NETWORK PROGRAM 1.0")) {
633                         protocols |= PROT_PC_NETWORK_PROGRAM_1_0;
634                 } else if (strcsequal(cliprotos[i], "XENIX CORE")) {
635                         protocols |= PROT_XENIX_CORE;
636                 } else if (strcsequal(cliprotos[i], "Samba")) {
637                         protocols = PROT_SAMBA;
638                         break;
639                 } else if (strcsequal(cliprotos[i], "POSIX 2")) {
640                         protocols = PROT_POSIX_2;
641                         break;
642                 }
643         }
644
645         switch ( protocols ) {
646                 /* Old CIFSFS can send one arch only, NT LM 0.12. */
647                 case PROT_NT_LM_0_12:
648                 case ARCH_CIFSFS:
649                         set_remote_arch(RA_CIFSFS);
650                         break;
651                 case ARCH_SAMBA:
652                         set_remote_arch(RA_SAMBA);
653                         break;
654                 case ARCH_WFWG:
655                         set_remote_arch(RA_WFWG);
656                         break;
657                 case ARCH_WIN95:
658                         set_remote_arch(RA_WIN95);
659                         break;
660                 case ARCH_WINNT:
661                         set_remote_arch(RA_WINNT);
662                         break;
663                 case ARCH_WIN2K:
664                         set_remote_arch(RA_WIN2K);
665                         break;
666                 case ARCH_VISTA:
667                         set_remote_arch(RA_VISTA);
668                         break;
669                 case ARCH_OS2:
670                         set_remote_arch(RA_OS2);
671                         break;
672                 case ARCH_OSX:
673                         set_remote_arch(RA_OSX);
674                         break;
675                 default:
676                         set_remote_arch(RA_UNKNOWN);
677                 break;
678         }
679
680         /* possibly reload - change of architecture */
681         reload_services(sconn, conn_snum_used, true);
682
683         /* moved from the netbios session setup code since we don't have that 
684            when the client connects to port 445.  Of course there is a small
685            window where we are listening to messages   -- jerry */
686
687         serverid_register(messaging_server_id(sconn->msg_ctx),
688                           FLAG_MSG_GENERAL|FLAG_MSG_SMBD
689                           |FLAG_MSG_PRINT_GENERAL);
690
691         /* Check for protocols, most desirable first */
692         for (protocol = 0; supported_protocols[protocol].proto_name; protocol++) {
693                 i = 0;
694                 if ((supported_protocols[protocol].protocol_level <= lp_server_max_protocol()) &&
695                                 (supported_protocols[protocol].protocol_level >= lp_server_min_protocol()))
696                         while (i < num_cliprotos) {
697                                 if (strequal(cliprotos[i],supported_protocols[protocol].proto_name)) {
698                                         choice = i;
699                                         chosen_level = supported_protocols[protocol].protocol_level;
700                                 }
701                                 i++;
702                         }
703                 if(choice != -1)
704                         break;
705         }
706
707         if(choice != -1) {
708                 fstrcpy(remote_proto,supported_protocols[protocol].short_name);
709                 reload_services(sconn, conn_snum_used, true);
710                 supported_protocols[protocol].proto_reply_fn(req, choice);
711                 DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
712         } else {
713                 DEBUG(0,("No protocol supported !\n"));
714                 reply_outbuf(req, 1, 0);
715                 SSVAL(req->outbuf, smb_vwv0, choice);
716         }
717
718         DEBUG( 5, ( "negprot index=%d\n", choice ) );
719
720         /* We always have xconn->smb1.signing_state also for >= SMB2_02 */
721         signing_required = smb_signing_is_mandatory(xconn->smb1.signing_state);
722         if (signing_required && (chosen_level < PROTOCOL_NT1)) {
723                 exit_server_cleanly("SMB signing is required and "
724                         "client negotiated a downlevel protocol");
725         }
726
727         TALLOC_FREE(cliprotos);
728
729         if (lp_async_smb_echo_handler() && (chosen_level < PROTOCOL_SMB2_02) &&
730             !fork_echo_handler(xconn)) {
731                 exit_server("Failed to fork echo handler");
732         }
733
734         END_PROFILE(SMBnegprot);
735         return;
736 }