s4 dns: Support DNS_QTYPE_ALL queries
[Samba/bb.git] / source3 / smbd / negprot.c
blob9b58a79795e9332001f35ddd88754648bfd1883e
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 "../libcli/auth/spnego.h"
25 #include "serverid.h"
26 #include "auth.h"
27 #include "ntlmssp_wrap.h"
28 #include "messages.h"
29 #include "smbprofile.h"
30 #include "auth/gensec/gensec.h"
32 extern fstring remote_proto;
34 static void get_challenge(struct smbd_server_connection *sconn, uint8 buff[8])
36 NTSTATUS nt_status;
38 /* We might be called more than once, multiple negprots are
39 * permitted */
40 if (sconn->smb1.negprot.auth_context) {
41 DEBUG(3, ("get challenge: is this a secondary negprot? "
42 "sconn->negprot.auth_context is non-NULL!\n"));
43 TALLOC_FREE(sconn->smb1.negprot.auth_context);
46 DEBUG(10, ("get challenge: creating negprot_global_auth_context\n"));
47 nt_status = make_auth_context_subsystem(
48 sconn, &sconn->smb1.negprot.auth_context);
49 if (!NT_STATUS_IS_OK(nt_status)) {
50 DEBUG(0, ("make_auth_context_subsystem returned %s",
51 nt_errstr(nt_status)));
52 smb_panic("cannot make_negprot_global_auth_context!");
54 DEBUG(10, ("get challenge: getting challenge\n"));
55 sconn->smb1.negprot.auth_context->get_ntlm_challenge(
56 sconn->smb1.negprot.auth_context, buff);
59 /****************************************************************************
60 Reply for the core protocol.
61 ****************************************************************************/
63 static void reply_corep(struct smb_request *req, uint16 choice)
65 reply_outbuf(req, 1, 0);
66 SSVAL(req->outbuf, smb_vwv0, choice);
68 set_Protocol(PROTOCOL_CORE);
71 /****************************************************************************
72 Reply for the coreplus protocol.
73 ****************************************************************************/
75 static void reply_coreplus(struct smb_request *req, uint16 choice)
77 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
79 reply_outbuf(req, 13, 0);
81 SSVAL(req->outbuf,smb_vwv0,choice);
82 SSVAL(req->outbuf,smb_vwv5,raw); /* tell redirector we support
83 readbraw and writebraw (possibly) */
84 /* Reply, SMBlockread, SMBwritelock supported. */
85 SCVAL(req->outbuf,smb_flg,FLAG_REPLY|FLAG_SUPPORT_LOCKREAD);
86 SSVAL(req->outbuf,smb_vwv1,0x1); /* user level security, don't
87 * encrypt */
88 set_Protocol(PROTOCOL_COREPLUS);
91 /****************************************************************************
92 Reply for the lanman 1.0 protocol.
93 ****************************************************************************/
95 static void reply_lanman1(struct smb_request *req, uint16 choice)
97 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
98 int secword=0;
99 time_t t = time(NULL);
100 struct smbd_server_connection *sconn = req->sconn;
102 sconn->smb1.negprot.encrypted_passwords = lp_encrypted_passwords();
104 if (lp_security()>=SEC_USER) {
105 secword |= NEGOTIATE_SECURITY_USER_LEVEL;
107 if (sconn->smb1.negprot.encrypted_passwords) {
108 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
111 reply_outbuf(req, 13, sconn->smb1.negprot.encrypted_passwords?8:0);
113 SSVAL(req->outbuf,smb_vwv0,choice);
114 SSVAL(req->outbuf,smb_vwv1,secword);
115 /* Create a token value and add it to the outgoing packet. */
116 if (sconn->smb1.negprot.encrypted_passwords) {
117 get_challenge(sconn, (uint8 *)smb_buf(req->outbuf));
118 SSVAL(req->outbuf,smb_vwv11, 8);
121 set_Protocol(PROTOCOL_LANMAN1);
123 /* Reply, SMBlockread, SMBwritelock supported. */
124 SCVAL(req->outbuf,smb_flg,FLAG_REPLY|FLAG_SUPPORT_LOCKREAD);
125 SSVAL(req->outbuf,smb_vwv2,sconn->smb1.negprot.max_recv);
126 SSVAL(req->outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
127 SSVAL(req->outbuf,smb_vwv4,1);
128 SSVAL(req->outbuf,smb_vwv5,raw); /* tell redirector we support
129 readbraw writebraw (possibly) */
130 SIVAL(req->outbuf,smb_vwv6,sys_getpid());
131 SSVAL(req->outbuf,smb_vwv10, set_server_zone_offset(t)/60);
133 srv_put_dos_date((char *)req->outbuf,smb_vwv8,t);
135 return;
138 /****************************************************************************
139 Reply for the lanman 2.0 protocol.
140 ****************************************************************************/
142 static void reply_lanman2(struct smb_request *req, uint16 choice)
144 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
145 int secword=0;
146 time_t t = time(NULL);
147 struct smbd_server_connection *sconn = req->sconn;
149 sconn->smb1.negprot.encrypted_passwords = lp_encrypted_passwords();
151 if (lp_security()>=SEC_USER) {
152 secword |= NEGOTIATE_SECURITY_USER_LEVEL;
154 if (sconn->smb1.negprot.encrypted_passwords) {
155 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
158 reply_outbuf(req, 13, sconn->smb1.negprot.encrypted_passwords?8:0);
160 SSVAL(req->outbuf,smb_vwv0,choice);
161 SSVAL(req->outbuf,smb_vwv1,secword);
162 SIVAL(req->outbuf,smb_vwv6,sys_getpid());
164 /* Create a token value and add it to the outgoing packet. */
165 if (sconn->smb1.negprot.encrypted_passwords) {
166 get_challenge(sconn, (uint8 *)smb_buf(req->outbuf));
167 SSVAL(req->outbuf,smb_vwv11, 8);
170 set_Protocol(PROTOCOL_LANMAN2);
172 /* Reply, SMBlockread, SMBwritelock supported. */
173 SCVAL(req->outbuf,smb_flg,FLAG_REPLY|FLAG_SUPPORT_LOCKREAD);
174 SSVAL(req->outbuf,smb_vwv2,sconn->smb1.negprot.max_recv);
175 SSVAL(req->outbuf,smb_vwv3,lp_maxmux());
176 SSVAL(req->outbuf,smb_vwv4,1);
177 SSVAL(req->outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
178 SSVAL(req->outbuf,smb_vwv10, set_server_zone_offset(t)/60);
179 srv_put_dos_date((char *)req->outbuf,smb_vwv8,t);
182 /****************************************************************************
183 Generate the spnego negprot reply blob. Return the number of bytes used.
184 ****************************************************************************/
186 DATA_BLOB negprot_spnego(TALLOC_CTX *ctx, struct smbd_server_connection *sconn)
188 DATA_BLOB blob = data_blob_null;
189 DATA_BLOB blob_out = data_blob_null;
190 nstring dos_name;
191 fstring unix_name;
192 NTSTATUS status;
193 #ifdef DEVELOPER
194 size_t slen;
195 #endif
196 const char *OIDs_krb5[] = {OID_KERBEROS5,
197 OID_KERBEROS5_OLD,
198 OID_NTLMSSP,
199 NULL};
200 const char *OIDs_ntlm[] = {OID_NTLMSSP, NULL};
201 struct auth_ntlmssp_state *auth_ntlmssp_state;
203 sconn->use_gensec_hook = false;
205 /* See if we can get an SPNEGO blob out of the gensec hook (if auth_samba4 is loaded) */
206 status = auth_ntlmssp_prepare(sconn->remote_address,
207 &auth_ntlmssp_state);
208 if (NT_STATUS_IS_OK(status)) {
209 status = auth_generic_start(auth_ntlmssp_state, GENSEC_OID_SPNEGO);
210 if (NT_STATUS_IS_OK(status)) {
211 status = gensec_update(auth_ntlmssp_state->gensec_security, ctx,
212 NULL, data_blob_null, &blob);
213 /* If we get the list of OIDs, the 'OK' answer
214 * is NT_STATUS_MORE_PROCESSING_REQUIRED */
215 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
216 sconn->use_gensec_hook = true;
219 TALLOC_FREE(auth_ntlmssp_state);
222 sconn->smb1.negprot.spnego = true;
224 /* strangely enough, NT does not sent the single OID NTLMSSP when
225 not a ADS member, it sends no OIDs at all
227 OLD COMMENT : "we can't do this until we teach our sesssion setup parser to know
228 about raw NTLMSSP (clients send no ASN.1 wrapping if we do this)"
230 Our sessionsetup code now handles raw NTLMSSP connects, so we can go
231 back to doing what W2K3 does here. This is needed to make PocketPC 2003
232 CIFS connections work with SPNEGO. See bugzilla bugs #1828 and #3133
233 for details. JRA.
237 if (sconn->use_gensec_hook) {
238 /* blob initialised above */
239 } else if (lp_security() != SEC_ADS && !USE_KERBEROS_KEYTAB) {
240 #if 0
241 /* Code for PocketPC client */
242 blob = data_blob(guid, 16);
243 #else
244 /* Code for standalone WXP client */
245 blob = spnego_gen_negTokenInit(ctx, OIDs_ntlm, NULL, "NONE");
246 #endif
247 } else if (!lp_send_spnego_principal()) {
248 /* By default, Windows 2008 and later sends not_defined_in_RFC4178@please_ignore */
249 blob = spnego_gen_negTokenInit(ctx, OIDs_krb5, NULL, ADS_IGNORE_PRINCIPAL);
250 } else {
251 fstring myname;
252 char *host_princ_s = NULL;
253 name_to_fqdn(myname, lp_netbios_name());
254 strlower_m(myname);
255 if (asprintf(&host_princ_s, "cifs/%s@%s", myname, lp_realm())
256 == -1) {
257 return data_blob_null;
259 blob = spnego_gen_negTokenInit(ctx, OIDs_krb5, NULL, host_princ_s);
260 SAFE_FREE(host_princ_s);
263 if (blob.length == 0 || blob.data == NULL) {
264 return data_blob_null;
267 blob_out = data_blob_talloc(ctx, NULL, 16 + blob.length);
268 if (blob_out.data == NULL) {
269 data_blob_free(&blob);
270 return data_blob_null;
273 memset(blob_out.data, '\0', 16);
275 checked_strlcpy(unix_name, lp_netbios_name(), sizeof(unix_name));
276 strlower_m(unix_name);
277 push_ascii_nstring(dos_name, unix_name);
278 strlcpy((char *)blob_out.data, dos_name, 17);
280 #ifdef DEVELOPER
281 /* Fix valgrind 'uninitialized bytes' issue. */
282 slen = strlen(dos_name);
283 if (slen < 16) {
284 memset(blob_out.data+slen, '\0', 16 - slen);
286 #endif
288 memcpy(&blob_out.data[16], blob.data, blob.length);
290 data_blob_free(&blob);
292 return blob_out;
295 /****************************************************************************
296 Reply for the nt protocol.
297 ****************************************************************************/
299 static void reply_nt1(struct smb_request *req, uint16 choice)
301 /* dual names + lock_and_read + nt SMBs + remote API calls */
302 int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ|
303 CAP_LEVEL_II_OPLOCKS;
305 int secword=0;
306 bool negotiate_spnego = False;
307 struct timespec ts;
308 ssize_t ret;
309 struct smbd_server_connection *sconn = req->sconn;
311 sconn->smb1.negprot.encrypted_passwords = lp_encrypted_passwords();
313 /* Check the flags field to see if this is Vista.
314 WinXP sets it and Vista does not. But we have to
315 distinguish from NT which doesn't set it either. */
317 if ( (req->flags2 & FLAGS2_EXTENDED_SECURITY) &&
318 ((req->flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED) == 0) )
320 if (get_remote_arch() != RA_SAMBA) {
321 set_remote_arch( RA_VISTA );
325 reply_outbuf(req,17,0);
327 /* do spnego in user level security if the client
328 supports it and we can do encrypted passwords */
330 if (sconn->smb1.negprot.encrypted_passwords &&
331 (lp_security() != SEC_SHARE) &&
332 lp_use_spnego() &&
333 (req->flags2 & FLAGS2_EXTENDED_SECURITY)) {
334 negotiate_spnego = True;
335 capabilities |= CAP_EXTENDED_SECURITY;
336 add_to_common_flags2(FLAGS2_EXTENDED_SECURITY);
337 /* Ensure FLAGS2_EXTENDED_SECURITY gets set in this reply
338 (already partially constructed. */
339 SSVAL(req->outbuf, smb_flg2,
340 req->flags2 | FLAGS2_EXTENDED_SECURITY);
343 capabilities |= CAP_NT_SMBS|CAP_RPC_REMOTE_APIS|CAP_UNICODE;
345 if (lp_unix_extensions()) {
346 capabilities |= CAP_UNIX;
349 if (lp_large_readwrite() && (SMB_OFF_T_BITS == 64))
350 capabilities |= CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_W2K_SMBS;
352 if (SMB_OFF_T_BITS == 64)
353 capabilities |= CAP_LARGE_FILES;
355 if (lp_readraw() && lp_writeraw())
356 capabilities |= CAP_RAW_MODE;
358 if (lp_nt_status_support())
359 capabilities |= CAP_STATUS32;
361 if (lp_host_msdfs())
362 capabilities |= CAP_DFS;
364 if (lp_security() >= SEC_USER) {
365 secword |= NEGOTIATE_SECURITY_USER_LEVEL;
367 if (sconn->smb1.negprot.encrypted_passwords) {
368 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
371 if (lp_server_signing() != SMB_SIGNING_OFF) {
372 if (lp_security() >= SEC_USER) {
373 secword |= NEGOTIATE_SECURITY_SIGNATURES_ENABLED;
374 /* No raw mode with smb signing. */
375 capabilities &= ~CAP_RAW_MODE;
376 if (lp_server_signing() == SMB_SIGNING_REQUIRED)
377 secword |=NEGOTIATE_SECURITY_SIGNATURES_REQUIRED;
378 } else {
379 DEBUG(0,("reply_nt1: smb signing is incompatible with share level security !\n"));
380 if (lp_server_signing() == SMB_SIGNING_REQUIRED) {
381 exit_server_cleanly("reply_nt1: smb signing required and share level security selected.");
386 SSVAL(req->outbuf,smb_vwv0,choice);
387 SCVAL(req->outbuf,smb_vwv1,secword);
389 set_Protocol(PROTOCOL_NT1);
391 SSVAL(req->outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
392 SSVAL(req->outbuf,smb_vwv2+1,1); /* num vcs */
393 SIVAL(req->outbuf,smb_vwv3+1,
394 sconn->smb1.negprot.max_recv); /* max buffer. LOTS! */
395 SIVAL(req->outbuf,smb_vwv5+1,0x10000); /* raw size. full 64k */
396 SIVAL(req->outbuf,smb_vwv7+1,sys_getpid()); /* session key */
397 SIVAL(req->outbuf,smb_vwv9+1,capabilities); /* capabilities */
398 clock_gettime(CLOCK_REALTIME,&ts);
399 put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER,(char *)req->outbuf+smb_vwv11+1,ts);
400 SSVALS(req->outbuf,smb_vwv15+1,set_server_zone_offset(ts.tv_sec)/60);
402 if (!negotiate_spnego) {
403 /* Create a token value and add it to the outgoing packet. */
404 if (sconn->smb1.negprot.encrypted_passwords) {
405 uint8 chal[8];
406 /* note that we do not send a challenge at all if
407 we are using plaintext */
408 get_challenge(sconn, chal);
409 ret = message_push_blob(
410 &req->outbuf, data_blob_const(chal, sizeof(chal)));
411 if (ret == -1) {
412 DEBUG(0, ("Could not push challenge\n"));
413 reply_nterror(req, NT_STATUS_NO_MEMORY);
414 return;
416 SCVAL(req->outbuf, smb_vwv16+1, ret);
418 ret = message_push_string(&req->outbuf, lp_workgroup(),
419 STR_UNICODE|STR_TERMINATE
420 |STR_NOALIGN);
421 if (ret == -1) {
422 DEBUG(0, ("Could not push workgroup string\n"));
423 reply_nterror(req, NT_STATUS_NO_MEMORY);
424 return;
426 ret = message_push_string(&req->outbuf, lp_netbios_name(),
427 STR_UNICODE|STR_TERMINATE
428 |STR_NOALIGN);
429 if (ret == -1) {
430 DEBUG(0, ("Could not push netbios name string\n"));
431 reply_nterror(req, NT_STATUS_NO_MEMORY);
432 return;
434 DEBUG(3,("not using SPNEGO\n"));
435 } else {
436 DATA_BLOB spnego_blob = negprot_spnego(req, req->sconn);
438 if (spnego_blob.data == NULL) {
439 reply_nterror(req, NT_STATUS_NO_MEMORY);
440 return;
443 ret = message_push_blob(&req->outbuf, spnego_blob);
444 if (ret == -1) {
445 DEBUG(0, ("Could not push spnego blob\n"));
446 reply_nterror(req, NT_STATUS_NO_MEMORY);
447 return;
449 data_blob_free(&spnego_blob);
451 SCVAL(req->outbuf,smb_vwv16+1, 0);
452 DEBUG(3,("using SPNEGO\n"));
455 return;
458 /* these are the protocol lists used for auto architecture detection:
460 WinNT 3.51:
461 protocol [PC NETWORK PROGRAM 1.0]
462 protocol [XENIX CORE]
463 protocol [MICROSOFT NETWORKS 1.03]
464 protocol [LANMAN1.0]
465 protocol [Windows for Workgroups 3.1a]
466 protocol [LM1.2X002]
467 protocol [LANMAN2.1]
468 protocol [NT LM 0.12]
470 Win95:
471 protocol [PC NETWORK PROGRAM 1.0]
472 protocol [XENIX CORE]
473 protocol [MICROSOFT NETWORKS 1.03]
474 protocol [LANMAN1.0]
475 protocol [Windows for Workgroups 3.1a]
476 protocol [LM1.2X002]
477 protocol [LANMAN2.1]
478 protocol [NT LM 0.12]
480 Win2K:
481 protocol [PC NETWORK PROGRAM 1.0]
482 protocol [LANMAN1.0]
483 protocol [Windows for Workgroups 3.1a]
484 protocol [LM1.2X002]
485 protocol [LANMAN2.1]
486 protocol [NT LM 0.12]
488 Vista:
489 protocol [PC NETWORK PROGRAM 1.0]
490 protocol [LANMAN1.0]
491 protocol [Windows for Workgroups 3.1a]
492 protocol [LM1.2X002]
493 protocol [LANMAN2.1]
494 protocol [NT LM 0.12]
495 protocol [SMB 2.001]
497 OS/2:
498 protocol [PC NETWORK PROGRAM 1.0]
499 protocol [XENIX CORE]
500 protocol [LANMAN1.0]
501 protocol [LM1.2X002]
502 protocol [LANMAN2.1]
506 * Modified to recognize the architecture of the remote machine better.
508 * This appears to be the matrix of which protocol is used by which
509 * MS product.
510 Protocol WfWg Win95 WinNT Win2K OS/2 Vista
511 PC NETWORK PROGRAM 1.0 1 1 1 1 1 1
512 XENIX CORE 2 2
513 MICROSOFT NETWORKS 3.0 2 2
514 DOS LM1.2X002 3 3
515 MICROSOFT NETWORKS 1.03 3
516 DOS LANMAN2.1 4 4
517 LANMAN1.0 4 2 3 2
518 Windows for Workgroups 3.1a 5 5 5 3 3
519 LM1.2X002 6 4 4 4
520 LANMAN2.1 7 5 5 5
521 NT LM 0.12 6 8 6 6
522 SMB 2.001 7
524 * tim@fsg.com 09/29/95
525 * Win2K added by matty 17/7/99
528 #define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
529 #define ARCH_WIN95 0x2
530 #define ARCH_WINNT 0x4
531 #define ARCH_WIN2K 0xC /* Win2K is like NT */
532 #define ARCH_OS2 0x14 /* Again OS/2 is like NT */
533 #define ARCH_SAMBA 0x20
534 #define ARCH_CIFSFS 0x40
535 #define ARCH_VISTA 0x8C /* Vista is like XP/2K */
537 #define ARCH_ALL 0x7F
539 /* List of supported protocols, most desired first */
540 static const struct {
541 const char *proto_name;
542 const char *short_name;
543 void (*proto_reply_fn)(struct smb_request *req, uint16 choice);
544 int protocol_level;
545 } supported_protocols[] = {
546 {"SMB 2.???", "SMB2_FF", reply_smb20ff, PROTOCOL_SMB2_10},
547 {"SMB 2.002", "SMB2_02", reply_smb2002, PROTOCOL_SMB2_02},
548 {"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1},
549 {"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1},
550 {"POSIX 2", "NT1", reply_nt1, PROTOCOL_NT1},
551 {"LANMAN2.1", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
552 {"LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
553 {"Samba", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
554 {"DOS LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
555 {"LANMAN1.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
556 {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
557 {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
558 {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep, PROTOCOL_CORE},
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 int choice= -1;
570 int protocol;
571 const char *p;
572 int arch = ARCH_ALL;
573 int num_cliprotos;
574 char **cliprotos;
575 int i;
576 size_t converted_size;
577 struct smbd_server_connection *sconn = req->sconn;
579 START_PROFILE(SMBnegprot);
581 if (sconn->smb1.negprot.done) {
582 END_PROFILE(SMBnegprot);
583 exit_server_cleanly("multiple negprot's are not permitted");
585 sconn->smb1.negprot.done = true;
587 if (req->buflen == 0) {
588 DEBUG(0, ("negprot got no protocols\n"));
589 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
590 END_PROFILE(SMBnegprot);
591 return;
594 if (req->buf[req->buflen-1] != '\0') {
595 DEBUG(0, ("negprot protocols not 0-terminated\n"));
596 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
597 END_PROFILE(SMBnegprot);
598 return;
601 p = (const char *)req->buf + 1;
603 num_cliprotos = 0;
604 cliprotos = NULL;
606 while (smbreq_bufrem(req, p) > 0) {
608 char **tmp;
610 tmp = talloc_realloc(talloc_tos(), cliprotos, char *,
611 num_cliprotos+1);
612 if (tmp == NULL) {
613 DEBUG(0, ("talloc failed\n"));
614 TALLOC_FREE(cliprotos);
615 reply_nterror(req, NT_STATUS_NO_MEMORY);
616 END_PROFILE(SMBnegprot);
617 return;
620 cliprotos = tmp;
622 if (!pull_ascii_talloc(cliprotos, &cliprotos[num_cliprotos], p,
623 &converted_size)) {
624 DEBUG(0, ("pull_ascii_talloc failed\n"));
625 TALLOC_FREE(cliprotos);
626 reply_nterror(req, NT_STATUS_NO_MEMORY);
627 END_PROFILE(SMBnegprot);
628 return;
631 DEBUG(3, ("Requested protocol [%s]\n",
632 cliprotos[num_cliprotos]));
634 num_cliprotos += 1;
635 p += strlen(p) + 2;
638 for (i=0; i<num_cliprotos; i++) {
639 if (strcsequal(cliprotos[i], "Windows for Workgroups 3.1a"))
640 arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT
641 | ARCH_WIN2K );
642 else if (strcsequal(cliprotos[i], "DOS LM1.2X002"))
643 arch &= ( ARCH_WFWG | ARCH_WIN95 );
644 else if (strcsequal(cliprotos[i], "DOS LANMAN2.1"))
645 arch &= ( ARCH_WFWG | ARCH_WIN95 );
646 else if (strcsequal(cliprotos[i], "NT LM 0.12"))
647 arch &= ( ARCH_WIN95 | ARCH_WINNT | ARCH_WIN2K
648 | ARCH_CIFSFS);
649 else if (strcsequal(cliprotos[i], "SMB 2.001"))
650 arch = ARCH_VISTA;
651 else if (strcsequal(cliprotos[i], "LANMAN2.1"))
652 arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 );
653 else if (strcsequal(cliprotos[i], "LM1.2X002"))
654 arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 );
655 else if (strcsequal(cliprotos[i], "MICROSOFT NETWORKS 1.03"))
656 arch &= ARCH_WINNT;
657 else if (strcsequal(cliprotos[i], "XENIX CORE"))
658 arch &= ( ARCH_WINNT | ARCH_OS2 );
659 else if (strcsequal(cliprotos[i], "Samba")) {
660 arch = ARCH_SAMBA;
661 break;
662 } else if (strcsequal(cliprotos[i], "POSIX 2")) {
663 arch = ARCH_CIFSFS;
664 break;
668 /* CIFSFS can send one arch only, NT LM 0.12. */
669 if (i == 1 && (arch & ARCH_CIFSFS)) {
670 arch = ARCH_CIFSFS;
673 switch ( arch ) {
674 case ARCH_CIFSFS:
675 set_remote_arch(RA_CIFSFS);
676 break;
677 case ARCH_SAMBA:
678 set_remote_arch(RA_SAMBA);
679 break;
680 case ARCH_WFWG:
681 set_remote_arch(RA_WFWG);
682 break;
683 case ARCH_WIN95:
684 set_remote_arch(RA_WIN95);
685 break;
686 case ARCH_WINNT:
687 if(req->flags2 == FLAGS2_WIN2K_SIGNATURE)
688 set_remote_arch(RA_WIN2K);
689 else
690 set_remote_arch(RA_WINNT);
691 break;
692 case ARCH_WIN2K:
693 /* Vista may have been set in the negprot so don't
694 override it here */
695 if ( get_remote_arch() != RA_VISTA )
696 set_remote_arch(RA_WIN2K);
697 break;
698 case ARCH_VISTA:
699 set_remote_arch(RA_VISTA);
700 break;
701 case ARCH_OS2:
702 set_remote_arch(RA_OS2);
703 break;
704 default:
705 set_remote_arch(RA_UNKNOWN);
706 break;
709 /* possibly reload - change of architecture */
710 reload_services(sconn->msg_ctx, sconn->sock, True);
712 /* moved from the netbios session setup code since we don't have that
713 when the client connects to port 445. Of course there is a small
714 window where we are listening to messages -- jerry */
716 serverid_register(sconn_server_id(sconn),
717 FLAG_MSG_GENERAL|FLAG_MSG_SMBD
718 |FLAG_MSG_PRINT_GENERAL);
720 /* Check for protocols, most desirable first */
721 for (protocol = 0; supported_protocols[protocol].proto_name; protocol++) {
722 i = 0;
723 if ((supported_protocols[protocol].protocol_level <= lp_maxprotocol()) &&
724 (supported_protocols[protocol].protocol_level >= lp_minprotocol()))
725 while (i < num_cliprotos) {
726 if (strequal(cliprotos[i],supported_protocols[protocol].proto_name))
727 choice = i;
728 i++;
730 if(choice != -1)
731 break;
734 if(choice != -1) {
735 fstrcpy(remote_proto,supported_protocols[protocol].short_name);
736 reload_services(sconn->msg_ctx, sconn->sock, True);
737 supported_protocols[protocol].proto_reply_fn(req, choice);
738 DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
739 } else {
740 DEBUG(0,("No protocol supported !\n"));
741 reply_outbuf(req, 1, 0);
742 SSVAL(req->outbuf, smb_vwv0, choice);
745 DEBUG( 5, ( "negprot index=%d\n", choice ) );
747 if ((lp_server_signing() == SMB_SIGNING_REQUIRED)
748 && (get_Protocol() < PROTOCOL_NT1)) {
749 exit_server_cleanly("SMB signing is required and "
750 "client negotiated a downlevel protocol");
753 TALLOC_FREE(cliprotos);
755 if (lp_async_smb_echo_handler() && (get_Protocol() < PROTOCOL_SMB2_02) &&
756 !fork_echo_handler(sconn)) {
757 exit_server("Failed to fork echo handler");
760 END_PROFILE(SMBnegprot);
761 return;