s3:libsmb: move cli_session_setup_get_account into cli_session_creds_init()
[Samba.git] / source3 / smbd / negprot.c
blobbd09b1df1b1d582db8374545e151e238fa0fae06
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"
31 extern fstring remote_proto;
33 static void get_challenge(struct smbXsrv_connection *xconn, uint8_t buff[8])
35 NTSTATUS nt_status;
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);
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!");
53 DEBUG(10, ("get challenge: getting challenge\n"));
54 xconn->smb1.negprot.auth_context->get_ntlm_challenge(
55 xconn->smb1.negprot.auth_context, buff);
58 /****************************************************************************
59 Reply for the lanman 1.0 protocol.
60 ****************************************************************************/
62 static void reply_lanman1(struct smb_request *req, uint16_t choice)
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);
74 xconn->smb1.negprot.encrypted_passwords = lp_encrypt_passwords();
76 secword |= NEGOTIATE_SECURITY_USER_LEVEL;
77 if (xconn->smb1.negprot.encrypted_passwords) {
78 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
81 reply_outbuf(req, 13, xconn->smb1.negprot.encrypted_passwords?8:0);
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);
91 smbXsrv_connection_init_tables(xconn, PROTOCOL_LANMAN1);
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);
103 srv_put_dos_date((char *)req->outbuf,smb_vwv8,t);
105 return;
108 /****************************************************************************
109 Reply for the lanman 2.0 protocol.
110 ****************************************************************************/
112 static void reply_lanman2(struct smb_request *req, uint16_t choice)
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);
124 xconn->smb1.negprot.encrypted_passwords = lp_encrypt_passwords();
126 secword |= NEGOTIATE_SECURITY_USER_LEVEL;
127 if (xconn->smb1.negprot.encrypted_passwords) {
128 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
131 reply_outbuf(req, 13, xconn->smb1.negprot.encrypted_passwords?8:0);
133 SSVAL(req->outbuf,smb_vwv0, choice);
134 SSVAL(req->outbuf,smb_vwv1, secword);
135 SIVAL(req->outbuf,smb_vwv6, getpid());
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);
143 smbXsrv_connection_init_tables(xconn, PROTOCOL_LANMAN2);
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);
155 /****************************************************************************
156 Generate the spnego negprot reply blob. Return the number of bytes used.
157 ****************************************************************************/
159 DATA_BLOB negprot_spnego(TALLOC_CTX *ctx, struct smbXsrv_connection *xconn)
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;
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;
187 TALLOC_FREE(gensec_security);
190 xconn->smb1.negprot.spnego = true;
192 /* strangely enough, NT does not sent the single OID NTLMSSP when
193 not a ADS member, it sends no OIDs at all
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)"
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.
205 if (blob.length == 0 || blob.data == NULL) {
206 return data_blob_null;
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;
215 memset(blob_out.data, '\0', 16);
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);
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);
228 #endif
230 memcpy(&blob_out.data[16], blob.data, blob.length);
232 data_blob_free(&blob);
234 return blob_out;
237 /****************************************************************************
238 Reply for the nt protocol.
239 ****************************************************************************/
241 static void reply_nt1(struct smb_request *req, uint16_t choice)
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;
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;
255 xconn->smb1.negprot.encrypted_passwords = lp_encrypt_passwords();
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. */
261 if ( (req->flags2 & FLAGS2_EXTENDED_SECURITY) &&
262 ((req->flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED) == 0) )
264 if ((get_remote_arch() != RA_SAMBA) &&
265 (get_remote_arch() != RA_CIFSFS)) {
266 set_remote_arch( RA_VISTA );
270 reply_outbuf(req,17,0);
272 /* do spnego in user level security if the client
273 supports it and we can do encrypted passwords */
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);
287 capabilities |= CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
289 if (lp_unicode()) {
290 capabilities |= CAP_UNICODE;
293 if (lp_unix_extensions()) {
294 capabilities |= CAP_UNIX;
297 if (lp_large_readwrite())
298 capabilities |= CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_W2K_SMBS;
300 capabilities |= CAP_LARGE_FILES;
302 if (!lp_async_smb_echo_handler() && lp_read_raw() && lp_write_raw())
303 capabilities |= CAP_RAW_MODE;
305 if (lp_nt_status_support())
306 capabilities |= CAP_STATUS32;
308 if (lp_host_msdfs())
309 capabilities |= CAP_DFS;
311 secword |= NEGOTIATE_SECURITY_USER_LEVEL;
312 if (xconn->smb1.negprot.encrypted_passwords) {
313 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
316 signing_desired = smb_signing_is_desired(xconn->smb1.signing_state);
317 signing_required = smb_signing_is_mandatory(xconn->smb1.signing_state);
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;
328 SSVAL(req->outbuf,smb_vwv0,choice);
329 SCVAL(req->outbuf,smb_vwv1,secword);
331 smbXsrv_connection_init_tables(xconn, PROTOCOL_NT1);
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);
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;
358 SCVAL(req->outbuf, smb_vwv16+1, ret);
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;
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;
376 DEBUG(3,("not using SPNEGO\n"));
377 } else {
378 DATA_BLOB spnego_blob = negprot_spnego(req, xconn);
380 if (spnego_blob.data == NULL) {
381 reply_nterror(req, NT_STATUS_NO_MEMORY);
382 return;
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;
391 data_blob_free(&spnego_blob);
393 SCVAL(req->outbuf,smb_vwv16+1, 0);
394 DEBUG(3,("using SPNEGO\n"));
397 return;
400 /* these are the protocol lists used for auto architecture detection:
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]
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]
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]
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]
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]
446 OSX:
447 protocol [NT LM 0.12]
448 protocol [SMB 2.002]
449 protocol [SMB 2.???]
453 * Modified to recognize the architecture of the remote machine better.
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
473 * tim@fsg.com 09/29/95
474 * Win2K added by matty 17/7/99
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
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 )
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},
528 /****************************************************************************
529 Reply to a negprot.
530 conn POINTER CAN BE NULL HERE !
531 ****************************************************************************/
533 void reply_negprot(struct smb_request *req)
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;
548 START_PROFILE(SMBnegprot);
550 if (xconn->smb1.negprot.done) {
551 END_PROFILE(SMBnegprot);
552 exit_server_cleanly("multiple negprot's are not permitted");
554 xconn->smb1.negprot.done = true;
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;
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;
570 p = (const char *)req->buf + 1;
572 num_cliprotos = 0;
573 cliprotos = NULL;
575 while (smbreq_bufrem(req, p) > 0) {
577 char **tmp;
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;
589 cliprotos = tmp;
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;
600 DEBUG(3, ("Requested protocol [%s]\n",
601 cliprotos[num_cliprotos]));
603 num_cliprotos += 1;
604 p += strlen(p) + 2;
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;
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;
680 /* possibly reload - change of architecture */
681 reload_services(sconn, conn_snum_used, true);
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 */
687 serverid_register(messaging_server_id(sconn->msg_ctx),
688 FLAG_MSG_GENERAL|FLAG_MSG_SMBD
689 |FLAG_MSG_PRINT_GENERAL);
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;
701 i++;
703 if(choice != -1)
704 break;
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 DBG_NOTICE("No protocol supported !\n");
714 reply_outbuf(req, 1, 0);
715 SSVAL(req->outbuf, smb_vwv0, choice);
718 DEBUG( 5, ( "negprot index=%d\n", choice ) );
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");
727 TALLOC_FREE(cliprotos);
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");
734 END_PROFILE(SMBnegprot);
735 return;