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