Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.13.7.
   1// SPDX-License-Identifier: LGPL-2.1
   2/*
   3 *
   4 *   SMB/CIFS session setup handling routines
   5 *
   6 *   Copyright (c) International Business Machines  Corp., 2006, 2009
   7 *   Author(s): Steve French (sfrench@us.ibm.com)
   8 *
   9 */
  10
  11#include "cifspdu.h"
  12#include "cifsglob.h"
  13#include "cifsproto.h"
  14#include "cifs_unicode.h"
  15#include "cifs_debug.h"
  16#include "ntlmssp.h"
  17#include "nterr.h"
  18#include <linux/utsname.h>
  19#include <linux/slab.h>
  20#include <linux/version.h>
  21#include "cifsfs.h"
  22#include "cifs_spnego.h"
  23#include "smb2proto.h"
  24#include "fs_context.h"
  25
  26static int
  27cifs_ses_add_channel(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses,
  28		     struct cifs_server_iface *iface);
  29
  30bool
  31is_server_using_iface(struct TCP_Server_Info *server,
  32		      struct cifs_server_iface *iface)
  33{
  34	struct sockaddr_in *i4 = (struct sockaddr_in *)&iface->sockaddr;
  35	struct sockaddr_in6 *i6 = (struct sockaddr_in6 *)&iface->sockaddr;
  36	struct sockaddr_in *s4 = (struct sockaddr_in *)&server->dstaddr;
  37	struct sockaddr_in6 *s6 = (struct sockaddr_in6 *)&server->dstaddr;
  38
  39	if (server->dstaddr.ss_family != iface->sockaddr.ss_family)
  40		return false;
  41	if (server->dstaddr.ss_family == AF_INET) {
  42		if (s4->sin_addr.s_addr != i4->sin_addr.s_addr)
  43			return false;
  44	} else if (server->dstaddr.ss_family == AF_INET6) {
  45		if (memcmp(&s6->sin6_addr, &i6->sin6_addr,
  46			   sizeof(i6->sin6_addr)) != 0)
  47			return false;
  48	} else {
  49		/* unknown family.. */
  50		return false;
  51	}
  52	return true;
  53}
  54
  55bool is_ses_using_iface(struct cifs_ses *ses, struct cifs_server_iface *iface)
  56{
  57	int i;
  58
  59	spin_lock(&ses->chan_lock);
  60	for (i = 0; i < ses->chan_count; i++) {
  61		if (ses->chans[i].iface == iface) {
  62			spin_unlock(&ses->chan_lock);
  63			return true;
  64		}
  65	}
  66	spin_unlock(&ses->chan_lock);
  67	return false;
  68}
  69
  70/* channel helper functions. assumed that chan_lock is held by caller. */
  71
  72unsigned int
  73cifs_ses_get_chan_index(struct cifs_ses *ses,
  74			struct TCP_Server_Info *server)
  75{
  76	unsigned int i;
  77
  78	for (i = 0; i < ses->chan_count; i++) {
  79		if (ses->chans[i].server == server)
  80			return i;
  81	}
  82
  83	/* If we didn't find the channel, it is likely a bug */
  84	if (server)
  85		cifs_dbg(VFS, "unable to get chan index for server: 0x%llx",
  86			 server->conn_id);
  87	WARN_ON(1);
  88	return 0;
  89}
  90
  91void
  92cifs_chan_set_in_reconnect(struct cifs_ses *ses,
  93			     struct TCP_Server_Info *server)
  94{
  95	unsigned int chan_index = cifs_ses_get_chan_index(ses, server);
  96
  97	ses->chans[chan_index].in_reconnect = true;
  98}
  99
 100void
 101cifs_chan_clear_in_reconnect(struct cifs_ses *ses,
 102			     struct TCP_Server_Info *server)
 103{
 104	unsigned int chan_index = cifs_ses_get_chan_index(ses, server);
 105
 106	ses->chans[chan_index].in_reconnect = false;
 107}
 108
 109bool
 110cifs_chan_in_reconnect(struct cifs_ses *ses,
 111			  struct TCP_Server_Info *server)
 112{
 113	unsigned int chan_index = cifs_ses_get_chan_index(ses, server);
 114
 115	return CIFS_CHAN_IN_RECONNECT(ses, chan_index);
 116}
 117
 118void
 119cifs_chan_set_need_reconnect(struct cifs_ses *ses,
 120			     struct TCP_Server_Info *server)
 121{
 122	unsigned int chan_index = cifs_ses_get_chan_index(ses, server);
 123
 124	set_bit(chan_index, &ses->chans_need_reconnect);
 125	cifs_dbg(FYI, "Set reconnect bitmask for chan %u; now 0x%lx\n",
 126		 chan_index, ses->chans_need_reconnect);
 127}
 128
 129void
 130cifs_chan_clear_need_reconnect(struct cifs_ses *ses,
 131			       struct TCP_Server_Info *server)
 132{
 133	unsigned int chan_index = cifs_ses_get_chan_index(ses, server);
 134
 135	clear_bit(chan_index, &ses->chans_need_reconnect);
 136	cifs_dbg(FYI, "Cleared reconnect bitmask for chan %u; now 0x%lx\n",
 137		 chan_index, ses->chans_need_reconnect);
 138}
 139
 140bool
 141cifs_chan_needs_reconnect(struct cifs_ses *ses,
 142			  struct TCP_Server_Info *server)
 143{
 144	unsigned int chan_index = cifs_ses_get_chan_index(ses, server);
 145
 146	return CIFS_CHAN_NEEDS_RECONNECT(ses, chan_index);
 147}
 148
 149bool
 150cifs_chan_is_iface_active(struct cifs_ses *ses,
 151			  struct TCP_Server_Info *server)
 152{
 153	unsigned int chan_index = cifs_ses_get_chan_index(ses, server);
 154
 155	return ses->chans[chan_index].iface &&
 156		ses->chans[chan_index].iface->is_active;
 157}
 158
 159/* returns number of channels added */
 160int cifs_try_adding_channels(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses)
 161{
 162	int old_chan_count, new_chan_count;
 163	int left;
 164	int rc = 0;
 165	int tries = 0;
 166	struct cifs_server_iface *iface = NULL, *niface = NULL;
 167
 168	spin_lock(&ses->chan_lock);
 169
 170	new_chan_count = old_chan_count = ses->chan_count;
 171	left = ses->chan_max - ses->chan_count;
 172
 173	if (left <= 0) {
 174		spin_unlock(&ses->chan_lock);
 175		cifs_dbg(FYI,
 176			 "ses already at max_channels (%zu), nothing to open\n",
 177			 ses->chan_max);
 178		return 0;
 179	}
 180
 181	if (ses->server->dialect < SMB30_PROT_ID) {
 182		spin_unlock(&ses->chan_lock);
 183		cifs_dbg(VFS, "multichannel is not supported on this protocol version, use 3.0 or above\n");
 184		return 0;
 185	}
 186
 187	if (!(ses->server->capabilities & SMB2_GLOBAL_CAP_MULTI_CHANNEL)) {
 188		ses->chan_max = 1;
 189		spin_unlock(&ses->chan_lock);
 190		cifs_dbg(VFS, "server %s does not support multichannel\n", ses->server->hostname);
 191		return 0;
 192	}
 193	spin_unlock(&ses->chan_lock);
 194
 195	/*
 196	 * Keep connecting to same, fastest, iface for all channels as
 197	 * long as its RSS. Try next fastest one if not RSS or channel
 198	 * creation fails.
 199	 */
 200	spin_lock(&ses->iface_lock);
 201	iface = list_first_entry(&ses->iface_list, struct cifs_server_iface,
 202				 iface_head);
 203	spin_unlock(&ses->iface_lock);
 204
 205	while (left > 0) {
 206
 207		tries++;
 208		if (tries > 3*ses->chan_max) {
 209			cifs_dbg(FYI, "too many channel open attempts (%d channels left to open)\n",
 210				 left);
 211			break;
 212		}
 213
 214		spin_lock(&ses->iface_lock);
 215		if (!ses->iface_count) {
 216			spin_unlock(&ses->iface_lock);
 217			break;
 218		}
 219
 220		list_for_each_entry_safe_from(iface, niface, &ses->iface_list,
 221				    iface_head) {
 222			/* skip ifaces that are unusable */
 223			if (!iface->is_active ||
 224			    (is_ses_using_iface(ses, iface) &&
 225			     !iface->rss_capable)) {
 226				continue;
 227			}
 228
 229			/* take ref before unlock */
 230			kref_get(&iface->refcount);
 231
 232			spin_unlock(&ses->iface_lock);
 233			rc = cifs_ses_add_channel(cifs_sb, ses, iface);
 234			spin_lock(&ses->iface_lock);
 235
 236			if (rc) {
 237				cifs_dbg(VFS, "failed to open extra channel on iface:%pIS rc=%d\n",
 238					 &iface->sockaddr,
 239					 rc);
 240				kref_put(&iface->refcount, release_iface);
 241				continue;
 242			}
 243
 244			cifs_dbg(FYI, "successfully opened new channel on iface:%pIS\n",
 245				 &iface->sockaddr);
 246			break;
 247		}
 248		spin_unlock(&ses->iface_lock);
 249
 250		left--;
 251		new_chan_count++;
 252	}
 253
 254	return new_chan_count - old_chan_count;
 255}
 256
 257/*
 258 * update the iface for the channel if necessary.
 259 * will return 0 when iface is updated, 1 if removed, 2 otherwise
 260 * Must be called with chan_lock held.
 261 */
 262int
 263cifs_chan_update_iface(struct cifs_ses *ses, struct TCP_Server_Info *server)
 264{
 265	unsigned int chan_index;
 266	struct cifs_server_iface *iface = NULL;
 267	struct cifs_server_iface *old_iface = NULL;
 268	int rc = 0;
 269
 270	spin_lock(&ses->chan_lock);
 271	chan_index = cifs_ses_get_chan_index(ses, server);
 272	if (!chan_index) {
 273		spin_unlock(&ses->chan_lock);
 274		return 0;
 275	}
 276
 277	if (ses->chans[chan_index].iface) {
 278		old_iface = ses->chans[chan_index].iface;
 279		if (old_iface->is_active) {
 280			spin_unlock(&ses->chan_lock);
 281			return 1;
 282		}
 283	}
 284	spin_unlock(&ses->chan_lock);
 285
 286	spin_lock(&ses->iface_lock);
 287	/* then look for a new one */
 288	list_for_each_entry(iface, &ses->iface_list, iface_head) {
 289		if (!iface->is_active ||
 290		    (is_ses_using_iface(ses, iface) &&
 291		     !iface->rss_capable)) {
 292			continue;
 293		}
 294		kref_get(&iface->refcount);
 295		break;
 296	}
 297
 298	if (list_entry_is_head(iface, &ses->iface_list, iface_head)) {
 299		rc = 1;
 300		iface = NULL;
 301		cifs_dbg(FYI, "unable to find a suitable iface\n");
 302	}
 303
 304	/* now drop the ref to the current iface */
 305	if (old_iface && iface) {
 306		cifs_dbg(FYI, "replacing iface: %pIS with %pIS\n",
 307			 &old_iface->sockaddr,
 308			 &iface->sockaddr);
 309		kref_put(&old_iface->refcount, release_iface);
 310	} else if (old_iface) {
 311		cifs_dbg(FYI, "releasing ref to iface: %pIS\n",
 312			 &old_iface->sockaddr);
 313		kref_put(&old_iface->refcount, release_iface);
 314	} else {
 315		WARN_ON(!iface);
 316		cifs_dbg(FYI, "adding new iface: %pIS\n", &iface->sockaddr);
 317	}
 318	spin_unlock(&ses->iface_lock);
 319
 320	spin_lock(&ses->chan_lock);
 321	chan_index = cifs_ses_get_chan_index(ses, server);
 322	ses->chans[chan_index].iface = iface;
 323
 324	/* No iface is found. if secondary chan, drop connection */
 325	if (!iface && CIFS_SERVER_IS_CHAN(server))
 326		ses->chans[chan_index].server = NULL;
 327
 328	spin_unlock(&ses->chan_lock);
 329
 330	if (!iface && CIFS_SERVER_IS_CHAN(server))
 331		cifs_put_tcp_session(server, false);
 332
 333	return rc;
 334}
 335
 336/*
 337 * If server is a channel of ses, return the corresponding enclosing
 338 * cifs_chan otherwise return NULL.
 339 */
 340struct cifs_chan *
 341cifs_ses_find_chan(struct cifs_ses *ses, struct TCP_Server_Info *server)
 342{
 343	int i;
 344
 345	spin_lock(&ses->chan_lock);
 346	for (i = 0; i < ses->chan_count; i++) {
 347		if (ses->chans[i].server == server) {
 348			spin_unlock(&ses->chan_lock);
 349			return &ses->chans[i];
 350		}
 351	}
 352	spin_unlock(&ses->chan_lock);
 353	return NULL;
 354}
 355
 356static int
 357cifs_ses_add_channel(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses,
 358		     struct cifs_server_iface *iface)
 359{
 360	struct TCP_Server_Info *chan_server;
 361	struct cifs_chan *chan;
 362	struct smb3_fs_context ctx = {NULL};
 363	static const char unc_fmt[] = "\\%s\\foo";
 364	char unc[sizeof(unc_fmt)+SERVER_NAME_LEN_WITH_NULL] = {0};
 365	struct sockaddr_in *ipv4 = (struct sockaddr_in *)&iface->sockaddr;
 366	struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)&iface->sockaddr;
 367	int rc;
 368	unsigned int xid = get_xid();
 369
 370	if (iface->sockaddr.ss_family == AF_INET)
 371		cifs_dbg(FYI, "adding channel to ses %p (speed:%zu bps rdma:%s ip:%pI4)\n",
 372			 ses, iface->speed, iface->rdma_capable ? "yes" : "no",
 373			 &ipv4->sin_addr);
 374	else
 375		cifs_dbg(FYI, "adding channel to ses %p (speed:%zu bps rdma:%s ip:%pI6)\n",
 376			 ses, iface->speed, iface->rdma_capable ? "yes" : "no",
 377			 &ipv6->sin6_addr);
 378
 379	/*
 380	 * Setup a ctx with mostly the same info as the existing
 381	 * session and overwrite it with the requested iface data.
 382	 *
 383	 * We need to setup at least the fields used for negprot and
 384	 * sesssetup.
 385	 *
 386	 * We only need the ctx here, so we can reuse memory from
 387	 * the session and server without caring about memory
 388	 * management.
 389	 */
 390
 391	/* Always make new connection for now (TODO?) */
 392	ctx.nosharesock = true;
 393
 394	/* Auth */
 395	ctx.domainauto = ses->domainAuto;
 396	ctx.domainname = ses->domainName;
 397
 398	/* no hostname for extra channels */
 399	ctx.server_hostname = "";
 400
 401	ctx.username = ses->user_name;
 402	ctx.password = ses->password;
 403	ctx.sectype = ses->sectype;
 404	ctx.sign = ses->sign;
 405
 406	/* UNC and paths */
 407	/* XXX: Use ses->server->hostname? */
 408	sprintf(unc, unc_fmt, ses->ip_addr);
 409	ctx.UNC = unc;
 410	ctx.prepath = "";
 411
 412	/* Reuse same version as master connection */
 413	ctx.vals = ses->server->vals;
 414	ctx.ops = ses->server->ops;
 415
 416	ctx.noblocksnd = ses->server->noblocksnd;
 417	ctx.noautotune = ses->server->noautotune;
 418	ctx.sockopt_tcp_nodelay = ses->server->tcp_nodelay;
 419	ctx.echo_interval = ses->server->echo_interval / HZ;
 420	ctx.max_credits = ses->server->max_credits;
 421
 422	/*
 423	 * This will be used for encoding/decoding user/domain/pw
 424	 * during sess setup auth.
 425	 */
 426	ctx.local_nls = cifs_sb->local_nls;
 427
 428	/* Use RDMA if possible */
 429	ctx.rdma = iface->rdma_capable;
 430	memcpy(&ctx.dstaddr, &iface->sockaddr, sizeof(struct sockaddr_storage));
 431
 432	/* reuse master con client guid */
 433	memcpy(&ctx.client_guid, ses->server->client_guid,
 434	       SMB2_CLIENT_GUID_SIZE);
 435	ctx.use_client_guid = true;
 436
 437	chan_server = cifs_get_tcp_session(&ctx, ses->server);
 438
 439	spin_lock(&ses->chan_lock);
 440	chan = &ses->chans[ses->chan_count];
 441	chan->server = chan_server;
 442	if (IS_ERR(chan->server)) {
 443		rc = PTR_ERR(chan->server);
 444		chan->server = NULL;
 445		spin_unlock(&ses->chan_lock);
 446		goto out;
 447	}
 448	chan->iface = iface;
 449	ses->chan_count++;
 450	atomic_set(&ses->chan_seq, 0);
 451
 452	/* Mark this channel as needing connect/setup */
 453	cifs_chan_set_need_reconnect(ses, chan->server);
 454
 455	spin_unlock(&ses->chan_lock);
 456
 457	mutex_lock(&ses->session_mutex);
 458	/*
 459	 * We need to allocate the server crypto now as we will need
 460	 * to sign packets before we generate the channel signing key
 461	 * (we sign with the session key)
 462	 */
 463	rc = smb311_crypto_shash_allocate(chan->server);
 464	if (rc) {
 465		cifs_dbg(VFS, "%s: crypto alloc failed\n", __func__);
 466		mutex_unlock(&ses->session_mutex);
 467		goto out;
 468	}
 469
 470	rc = cifs_negotiate_protocol(xid, ses, chan->server);
 471	if (!rc)
 472		rc = cifs_setup_session(xid, ses, chan->server, cifs_sb->local_nls);
 473
 474	mutex_unlock(&ses->session_mutex);
 475
 476out:
 477	if (rc && chan->server) {
 478		/*
 479		 * we should avoid race with these delayed works before we
 480		 * remove this channel
 481		 */
 482		cancel_delayed_work_sync(&chan->server->echo);
 483		cancel_delayed_work_sync(&chan->server->resolve);
 484		cancel_delayed_work_sync(&chan->server->reconnect);
 485
 486		spin_lock(&ses->chan_lock);
 487		/* we rely on all bits beyond chan_count to be clear */
 488		cifs_chan_clear_need_reconnect(ses, chan->server);
 489		ses->chan_count--;
 490		/*
 491		 * chan_count should never reach 0 as at least the primary
 492		 * channel is always allocated
 493		 */
 494		WARN_ON(ses->chan_count < 1);
 495		spin_unlock(&ses->chan_lock);
 496
 497		cifs_put_tcp_session(chan->server, 0);
 498	}
 499
 500	free_xid(xid);
 501	return rc;
 502}
 503
 504#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
 505static __u32 cifs_ssetup_hdr(struct cifs_ses *ses,
 506			     struct TCP_Server_Info *server,
 507			     SESSION_SETUP_ANDX *pSMB)
 508{
 509	__u32 capabilities = 0;
 510
 511	/* init fields common to all four types of SessSetup */
 512	/* Note that offsets for first seven fields in req struct are same  */
 513	/*	in CIFS Specs so does not matter which of 3 forms of struct */
 514	/*	that we use in next few lines                               */
 515	/* Note that header is initialized to zero in header_assemble */
 516	pSMB->req.AndXCommand = 0xFF;
 517	pSMB->req.MaxBufferSize = cpu_to_le16(min_t(u32,
 518					CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4,
 519					USHRT_MAX));
 520	pSMB->req.MaxMpxCount = cpu_to_le16(server->maxReq);
 521	pSMB->req.VcNumber = cpu_to_le16(1);
 522
 523	/* Now no need to set SMBFLG_CASELESS or obsolete CANONICAL PATH */
 524
 525	/* BB verify whether signing required on neg or just on auth frame
 526	   (and NTLM case) */
 527
 528	capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
 529			CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;
 530
 531	if (server->sign)
 532		pSMB->req.hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
 533
 534	if (ses->capabilities & CAP_UNICODE) {
 535		pSMB->req.hdr.Flags2 |= SMBFLG2_UNICODE;
 536		capabilities |= CAP_UNICODE;
 537	}
 538	if (ses->capabilities & CAP_STATUS32) {
 539		pSMB->req.hdr.Flags2 |= SMBFLG2_ERR_STATUS;
 540		capabilities |= CAP_STATUS32;
 541	}
 542	if (ses->capabilities & CAP_DFS) {
 543		pSMB->req.hdr.Flags2 |= SMBFLG2_DFS;
 544		capabilities |= CAP_DFS;
 545	}
 546	if (ses->capabilities & CAP_UNIX)
 547		capabilities |= CAP_UNIX;
 548
 549	return capabilities;
 550}
 551
 552static void
 553unicode_oslm_strings(char **pbcc_area, const struct nls_table *nls_cp)
 554{
 555	char *bcc_ptr = *pbcc_area;
 556	int bytes_ret = 0;
 557
 558	/* Copy OS version */
 559	bytes_ret = cifs_strtoUTF16((__le16 *)bcc_ptr, "Linux version ", 32,
 560				    nls_cp);
 561	bcc_ptr += 2 * bytes_ret;
 562	bytes_ret = cifs_strtoUTF16((__le16 *) bcc_ptr, init_utsname()->release,
 563				    32, nls_cp);
 564	bcc_ptr += 2 * bytes_ret;
 565	bcc_ptr += 2; /* trailing null */
 566
 567	bytes_ret = cifs_strtoUTF16((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
 568				    32, nls_cp);
 569	bcc_ptr += 2 * bytes_ret;
 570	bcc_ptr += 2; /* trailing null */
 571
 572	*pbcc_area = bcc_ptr;
 573}
 574
 575static void unicode_domain_string(char **pbcc_area, struct cifs_ses *ses,
 576				   const struct nls_table *nls_cp)
 577{
 578	char *bcc_ptr = *pbcc_area;
 579	int bytes_ret = 0;
 580
 581	/* copy domain */
 582	if (ses->domainName == NULL) {
 583		/* Sending null domain better than using a bogus domain name (as
 584		we did briefly in 2.6.18) since server will use its default */
 585		*bcc_ptr = 0;
 586		*(bcc_ptr+1) = 0;
 587		bytes_ret = 0;
 588	} else
 589		bytes_ret = cifs_strtoUTF16((__le16 *) bcc_ptr, ses->domainName,
 590					    CIFS_MAX_DOMAINNAME_LEN, nls_cp);
 591	bcc_ptr += 2 * bytes_ret;
 592	bcc_ptr += 2;  /* account for null terminator */
 593
 594	*pbcc_area = bcc_ptr;
 595}
 596
 597static void unicode_ssetup_strings(char **pbcc_area, struct cifs_ses *ses,
 598				   const struct nls_table *nls_cp)
 599{
 600	char *bcc_ptr = *pbcc_area;
 601	int bytes_ret = 0;
 602
 603	/* BB FIXME add check that strings total less
 604	than 335 or will need to send them as arrays */
 605
 606	/* copy user */
 607	if (ses->user_name == NULL) {
 608		/* null user mount */
 609		*bcc_ptr = 0;
 610		*(bcc_ptr+1) = 0;
 611	} else {
 612		bytes_ret = cifs_strtoUTF16((__le16 *) bcc_ptr, ses->user_name,
 613					    CIFS_MAX_USERNAME_LEN, nls_cp);
 614	}
 615	bcc_ptr += 2 * bytes_ret;
 616	bcc_ptr += 2; /* account for null termination */
 617
 618	unicode_domain_string(&bcc_ptr, ses, nls_cp);
 619	unicode_oslm_strings(&bcc_ptr, nls_cp);
 620
 621	*pbcc_area = bcc_ptr;
 622}
 623
 624static void ascii_ssetup_strings(char **pbcc_area, struct cifs_ses *ses,
 625				 const struct nls_table *nls_cp)
 626{
 627	char *bcc_ptr = *pbcc_area;
 628	int len;
 629
 630	/* copy user */
 631	/* BB what about null user mounts - check that we do this BB */
 632	/* copy user */
 633	if (ses->user_name != NULL) {
 634		len = strscpy(bcc_ptr, ses->user_name, CIFS_MAX_USERNAME_LEN);
 635		if (WARN_ON_ONCE(len < 0))
 636			len = CIFS_MAX_USERNAME_LEN - 1;
 637		bcc_ptr += len;
 638	}
 639	/* else null user mount */
 640	*bcc_ptr = 0;
 641	bcc_ptr++; /* account for null termination */
 642
 643	/* copy domain */
 644	if (ses->domainName != NULL) {
 645		len = strscpy(bcc_ptr, ses->domainName, CIFS_MAX_DOMAINNAME_LEN);
 646		if (WARN_ON_ONCE(len < 0))
 647			len = CIFS_MAX_DOMAINNAME_LEN - 1;
 648		bcc_ptr += len;
 649	} /* else we will send a null domain name
 650	     so the server will default to its own domain */
 651	*bcc_ptr = 0;
 652	bcc_ptr++;
 653
 654	/* BB check for overflow here */
 655
 656	strcpy(bcc_ptr, "Linux version ");
 657	bcc_ptr += strlen("Linux version ");
 658	strcpy(bcc_ptr, init_utsname()->release);
 659	bcc_ptr += strlen(init_utsname()->release) + 1;
 660
 661	strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
 662	bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
 663
 664	*pbcc_area = bcc_ptr;
 665}
 666
 667static void
 668decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifs_ses *ses,
 669		      const struct nls_table *nls_cp)
 670{
 671	int len;
 672	char *data = *pbcc_area;
 673
 674	cifs_dbg(FYI, "bleft %d\n", bleft);
 675
 676	kfree(ses->serverOS);
 677	ses->serverOS = cifs_strndup_from_utf16(data, bleft, true, nls_cp);
 678	cifs_dbg(FYI, "serverOS=%s\n", ses->serverOS);
 679	len = (UniStrnlen((wchar_t *) data, bleft / 2) * 2) + 2;
 680	data += len;
 681	bleft -= len;
 682	if (bleft <= 0)
 683		return;
 684
 685	kfree(ses->serverNOS);
 686	ses->serverNOS = cifs_strndup_from_utf16(data, bleft, true, nls_cp);
 687	cifs_dbg(FYI, "serverNOS=%s\n", ses->serverNOS);
 688	len = (UniStrnlen((wchar_t *) data, bleft / 2) * 2) + 2;
 689	data += len;
 690	bleft -= len;
 691	if (bleft <= 0)
 692		return;
 693
 694	kfree(ses->serverDomain);
 695	ses->serverDomain = cifs_strndup_from_utf16(data, bleft, true, nls_cp);
 696	cifs_dbg(FYI, "serverDomain=%s\n", ses->serverDomain);
 697
 698	return;
 699}
 700
 701static void decode_ascii_ssetup(char **pbcc_area, __u16 bleft,
 702				struct cifs_ses *ses,
 703				const struct nls_table *nls_cp)
 704{
 705	int len;
 706	char *bcc_ptr = *pbcc_area;
 707
 708	cifs_dbg(FYI, "decode sessetup ascii. bleft %d\n", bleft);
 709
 710	len = strnlen(bcc_ptr, bleft);
 711	if (len >= bleft)
 712		return;
 713
 714	kfree(ses->serverOS);
 715
 716	ses->serverOS = kmalloc(len + 1, GFP_KERNEL);
 717	if (ses->serverOS) {
 718		memcpy(ses->serverOS, bcc_ptr, len);
 719		ses->serverOS[len] = 0;
 720		if (strncmp(ses->serverOS, "OS/2", 4) == 0)
 721			cifs_dbg(FYI, "OS/2 server\n");
 722	}
 723
 724	bcc_ptr += len + 1;
 725	bleft -= len + 1;
 726
 727	len = strnlen(bcc_ptr, bleft);
 728	if (len >= bleft)
 729		return;
 730
 731	kfree(ses->serverNOS);
 732
 733	ses->serverNOS = kmalloc(len + 1, GFP_KERNEL);
 734	if (ses->serverNOS) {
 735		memcpy(ses->serverNOS, bcc_ptr, len);
 736		ses->serverNOS[len] = 0;
 737	}
 738
 739	bcc_ptr += len + 1;
 740	bleft -= len + 1;
 741
 742	len = strnlen(bcc_ptr, bleft);
 743	if (len > bleft)
 744		return;
 745
 746	/* No domain field in LANMAN case. Domain is
 747	   returned by old servers in the SMB negprot response */
 748	/* BB For newer servers which do not support Unicode,
 749	   but thus do return domain here we could add parsing
 750	   for it later, but it is not very important */
 751	cifs_dbg(FYI, "ascii: bytes left %d\n", bleft);
 752}
 753#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
 754
 755int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
 756				    struct cifs_ses *ses)
 757{
 758	unsigned int tioffset; /* challenge message target info area */
 759	unsigned int tilen; /* challenge message target info area length  */
 760	CHALLENGE_MESSAGE *pblob = (CHALLENGE_MESSAGE *)bcc_ptr;
 761	__u32 server_flags;
 762
 763	if (blob_len < sizeof(CHALLENGE_MESSAGE)) {
 764		cifs_dbg(VFS, "challenge blob len %d too small\n", blob_len);
 765		return -EINVAL;
 766	}
 767
 768	if (memcmp(pblob->Signature, "NTLMSSP", 8)) {
 769		cifs_dbg(VFS, "blob signature incorrect %s\n",
 770			 pblob->Signature);
 771		return -EINVAL;
 772	}
 773	if (pblob->MessageType != NtLmChallenge) {
 774		cifs_dbg(VFS, "Incorrect message type %d\n",
 775			 pblob->MessageType);
 776		return -EINVAL;
 777	}
 778
 779	server_flags = le32_to_cpu(pblob->NegotiateFlags);
 780	cifs_dbg(FYI, "%s: negotiate=0x%08x challenge=0x%08x\n", __func__,
 781		 ses->ntlmssp->client_flags, server_flags);
 782
 783	if ((ses->ntlmssp->client_flags & (NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN)) &&
 784	    (!(server_flags & NTLMSSP_NEGOTIATE_56) && !(server_flags & NTLMSSP_NEGOTIATE_128))) {
 785		cifs_dbg(VFS, "%s: requested signing/encryption but server did not return either 56-bit or 128-bit session key size\n",
 786			 __func__);
 787		return -EINVAL;
 788	}
 789	if (!(server_flags & NTLMSSP_NEGOTIATE_NTLM) && !(server_flags & NTLMSSP_NEGOTIATE_EXTENDED_SEC)) {
 790		cifs_dbg(VFS, "%s: server does not seem to support either NTLMv1 or NTLMv2\n", __func__);
 791		return -EINVAL;
 792	}
 793	if (ses->server->sign && !(server_flags & NTLMSSP_NEGOTIATE_SIGN)) {
 794		cifs_dbg(VFS, "%s: forced packet signing but server does not seem to support it\n",
 795			 __func__);
 796		return -EOPNOTSUPP;
 797	}
 798	if ((ses->ntlmssp->client_flags & NTLMSSP_NEGOTIATE_KEY_XCH) &&
 799	    !(server_flags & NTLMSSP_NEGOTIATE_KEY_XCH))
 800		pr_warn_once("%s: authentication has been weakened as server does not support key exchange\n",
 801			     __func__);
 802
 803	ses->ntlmssp->server_flags = server_flags;
 804
 805	memcpy(ses->ntlmssp->cryptkey, pblob->Challenge, CIFS_CRYPTO_KEY_SIZE);
 806	/* In particular we can examine sign flags */
 807	/* BB spec says that if AvId field of MsvAvTimestamp is populated then
 808		we must set the MIC field of the AUTHENTICATE_MESSAGE */
 809
 810	tioffset = le32_to_cpu(pblob->TargetInfoArray.BufferOffset);
 811	tilen = le16_to_cpu(pblob->TargetInfoArray.Length);
 812	if (tioffset > blob_len || tioffset + tilen > blob_len) {
 813		cifs_dbg(VFS, "tioffset + tilen too high %u + %u\n",
 814			 tioffset, tilen);
 815		return -EINVAL;
 816	}
 817	if (tilen) {
 818		kfree_sensitive(ses->auth_key.response);
 819		ses->auth_key.response = kmemdup(bcc_ptr + tioffset, tilen,
 820						 GFP_KERNEL);
 821		if (!ses->auth_key.response) {
 822			cifs_dbg(VFS, "Challenge target info alloc failure\n");
 823			return -ENOMEM;
 824		}
 825		ses->auth_key.len = tilen;
 826	}
 827
 828	return 0;
 829}
 830
 831static int size_of_ntlmssp_blob(struct cifs_ses *ses, int base_size)
 832{
 833	int sz = base_size + ses->auth_key.len
 834		- CIFS_SESS_KEY_SIZE + CIFS_CPHTXT_SIZE + 2;
 835
 836	if (ses->domainName)
 837		sz += sizeof(__le16) * strnlen(ses->domainName, CIFS_MAX_DOMAINNAME_LEN);
 838	else
 839		sz += sizeof(__le16);
 840
 841	if (ses->user_name)
 842		sz += sizeof(__le16) * strnlen(ses->user_name, CIFS_MAX_USERNAME_LEN);
 843	else
 844		sz += sizeof(__le16);
 845
 846	if (ses->workstation_name[0])
 847		sz += sizeof(__le16) * strnlen(ses->workstation_name,
 848					       ntlmssp_workstation_name_size(ses));
 849	else
 850		sz += sizeof(__le16);
 851
 852	return sz;
 853}
 854
 855static inline void cifs_security_buffer_from_str(SECURITY_BUFFER *pbuf,
 856						 char *str_value,
 857						 int str_length,
 858						 unsigned char *pstart,
 859						 unsigned char **pcur,
 860						 const struct nls_table *nls_cp)
 861{
 862	unsigned char *tmp = pstart;
 863	int len;
 864
 865	if (!pbuf)
 866		return;
 867
 868	if (!pcur)
 869		pcur = &tmp;
 870
 871	if (!str_value) {
 872		pbuf->BufferOffset = cpu_to_le32(*pcur - pstart);
 873		pbuf->Length = 0;
 874		pbuf->MaximumLength = 0;
 875		*pcur += sizeof(__le16);
 876	} else {
 877		len = cifs_strtoUTF16((__le16 *)*pcur,
 878				      str_value,
 879				      str_length,
 880				      nls_cp);
 881		len *= sizeof(__le16);
 882		pbuf->BufferOffset = cpu_to_le32(*pcur - pstart);
 883		pbuf->Length = cpu_to_le16(len);
 884		pbuf->MaximumLength = cpu_to_le16(len);
 885		*pcur += len;
 886	}
 887}
 888
 889/* BB Move to ntlmssp.c eventually */
 890
 891int build_ntlmssp_negotiate_blob(unsigned char **pbuffer,
 892				 u16 *buflen,
 893				 struct cifs_ses *ses,
 894				 struct TCP_Server_Info *server,
 895				 const struct nls_table *nls_cp)
 896{
 897	int rc = 0;
 898	NEGOTIATE_MESSAGE *sec_blob;
 899	__u32 flags;
 900	unsigned char *tmp;
 901	int len;
 902
 903	len = size_of_ntlmssp_blob(ses, sizeof(NEGOTIATE_MESSAGE));
 904	*pbuffer = kmalloc(len, GFP_KERNEL);
 905	if (!*pbuffer) {
 906		rc = -ENOMEM;
 907		cifs_dbg(VFS, "Error %d during NTLMSSP allocation\n", rc);
 908		*buflen = 0;
 909		goto setup_ntlm_neg_ret;
 910	}
 911	sec_blob = (NEGOTIATE_MESSAGE *)*pbuffer;
 912
 913	memset(*pbuffer, 0, sizeof(NEGOTIATE_MESSAGE));
 914	memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
 915	sec_blob->MessageType = NtLmNegotiate;
 916
 917	/* BB is NTLMV2 session security format easier to use here? */
 918	flags = NTLMSSP_NEGOTIATE_56 |	NTLMSSP_REQUEST_TARGET |
 919		NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
 920		NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC |
 921		NTLMSSP_NEGOTIATE_ALWAYS_SIGN | NTLMSSP_NEGOTIATE_SEAL |
 922		NTLMSSP_NEGOTIATE_SIGN;
 923	if (!server->session_estab || ses->ntlmssp->sesskey_per_smbsess)
 924		flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
 925
 926	tmp = *pbuffer + sizeof(NEGOTIATE_MESSAGE);
 927	ses->ntlmssp->client_flags = flags;
 928	sec_blob->NegotiateFlags = cpu_to_le32(flags);
 929
 930	/* these fields should be null in negotiate phase MS-NLMP 3.1.5.1.1 */
 931	cifs_security_buffer_from_str(&sec_blob->DomainName,
 932				      NULL,
 933				      CIFS_MAX_DOMAINNAME_LEN,
 934				      *pbuffer, &tmp,
 935				      nls_cp);
 936
 937	cifs_security_buffer_from_str(&sec_blob->WorkstationName,
 938				      NULL,
 939				      CIFS_MAX_WORKSTATION_LEN,
 940				      *pbuffer, &tmp,
 941				      nls_cp);
 942
 943	*buflen = tmp - *pbuffer;
 944setup_ntlm_neg_ret:
 945	return rc;
 946}
 947
 948/*
 949 * Build ntlmssp blob with additional fields, such as version,
 950 * supported by modern servers. For safety limit to SMB3 or later
 951 * See notes in MS-NLMP Section 2.2.2.1 e.g.
 952 */
 953int build_ntlmssp_smb3_negotiate_blob(unsigned char **pbuffer,
 954				 u16 *buflen,
 955				 struct cifs_ses *ses,
 956				 struct TCP_Server_Info *server,
 957				 const struct nls_table *nls_cp)
 958{
 959	int rc = 0;
 960	struct negotiate_message *sec_blob;
 961	__u32 flags;
 962	unsigned char *tmp;
 963	int len;
 964
 965	len = size_of_ntlmssp_blob(ses, sizeof(struct negotiate_message));
 966	*pbuffer = kmalloc(len, GFP_KERNEL);
 967	if (!*pbuffer) {
 968		rc = -ENOMEM;
 969		cifs_dbg(VFS, "Error %d during NTLMSSP allocation\n", rc);
 970		*buflen = 0;
 971		goto setup_ntlm_smb3_neg_ret;
 972	}
 973	sec_blob = (struct negotiate_message *)*pbuffer;
 974
 975	memset(*pbuffer, 0, sizeof(struct negotiate_message));
 976	memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
 977	sec_blob->MessageType = NtLmNegotiate;
 978
 979	/* BB is NTLMV2 session security format easier to use here? */
 980	flags = NTLMSSP_NEGOTIATE_56 |	NTLMSSP_REQUEST_TARGET |
 981		NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
 982		NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC |
 983		NTLMSSP_NEGOTIATE_ALWAYS_SIGN | NTLMSSP_NEGOTIATE_SEAL |
 984		NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_VERSION;
 985	if (!server->session_estab || ses->ntlmssp->sesskey_per_smbsess)
 986		flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
 987
 988	sec_blob->Version.ProductMajorVersion = LINUX_VERSION_MAJOR;
 989	sec_blob->Version.ProductMinorVersion = LINUX_VERSION_PATCHLEVEL;
 990	sec_blob->Version.ProductBuild = cpu_to_le16(SMB3_PRODUCT_BUILD);
 991	sec_blob->Version.NTLMRevisionCurrent = NTLMSSP_REVISION_W2K3;
 992
 993	tmp = *pbuffer + sizeof(struct negotiate_message);
 994	ses->ntlmssp->client_flags = flags;
 995	sec_blob->NegotiateFlags = cpu_to_le32(flags);
 996
 997	/* these fields should be null in negotiate phase MS-NLMP 3.1.5.1.1 */
 998	cifs_security_buffer_from_str(&sec_blob->DomainName,
 999				      NULL,
1000				      CIFS_MAX_DOMAINNAME_LEN,
1001				      *pbuffer, &tmp,
1002				      nls_cp);
1003
1004	cifs_security_buffer_from_str(&sec_blob->WorkstationName,
1005				      NULL,
1006				      CIFS_MAX_WORKSTATION_LEN,
1007				      *pbuffer, &tmp,
1008				      nls_cp);
1009
1010	*buflen = tmp - *pbuffer;
1011setup_ntlm_smb3_neg_ret:
1012	return rc;
1013}
1014
1015
1016int build_ntlmssp_auth_blob(unsigned char **pbuffer,
1017					u16 *buflen,
1018				   struct cifs_ses *ses,
1019				   struct TCP_Server_Info *server,
1020				   const struct nls_table *nls_cp)
1021{
1022	int rc;
1023	AUTHENTICATE_MESSAGE *sec_blob;
1024	__u32 flags;
1025	unsigned char *tmp;
1026	int len;
1027
1028	rc = setup_ntlmv2_rsp(ses, nls_cp);
1029	if (rc) {
1030		cifs_dbg(VFS, "Error %d during NTLMSSP authentication\n", rc);
1031		*buflen = 0;
1032		goto setup_ntlmv2_ret;
1033	}
1034
1035	len = size_of_ntlmssp_blob(ses, sizeof(AUTHENTICATE_MESSAGE));
1036	*pbuffer = kmalloc(len, GFP_KERNEL);
1037	if (!*pbuffer) {
1038		rc = -ENOMEM;
1039		cifs_dbg(VFS, "Error %d during NTLMSSP allocation\n", rc);
1040		*buflen = 0;
1041		goto setup_ntlmv2_ret;
1042	}
1043	sec_blob = (AUTHENTICATE_MESSAGE *)*pbuffer;
1044
1045	memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
1046	sec_blob->MessageType = NtLmAuthenticate;
1047
1048	flags = ses->ntlmssp->server_flags | NTLMSSP_REQUEST_TARGET |
1049		NTLMSSP_NEGOTIATE_TARGET_INFO | NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED;
1050
1051	tmp = *pbuffer + sizeof(AUTHENTICATE_MESSAGE);
1052	sec_blob->NegotiateFlags = cpu_to_le32(flags);
1053
1054	sec_blob->LmChallengeResponse.BufferOffset =
1055				cpu_to_le32(sizeof(AUTHENTICATE_MESSAGE));
1056	sec_blob->LmChallengeResponse.Length = 0;
1057	sec_blob->LmChallengeResponse.MaximumLength = 0;
1058
1059	sec_blob->NtChallengeResponse.BufferOffset =
1060				cpu_to_le32(tmp - *pbuffer);
1061	if (ses->user_name != NULL) {
1062		memcpy(tmp, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
1063				ses->auth_key.len - CIFS_SESS_KEY_SIZE);
1064		tmp += ses->auth_key.len - CIFS_SESS_KEY_SIZE;
1065
1066		sec_blob->NtChallengeResponse.Length =
1067				cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
1068		sec_blob->NtChallengeResponse.MaximumLength =
1069				cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
1070	} else {
1071		/*
1072		 * don't send an NT Response for anonymous access
1073		 */
1074		sec_blob->NtChallengeResponse.Length = 0;
1075		sec_blob->NtChallengeResponse.MaximumLength = 0;
1076	}
1077
1078	cifs_security_buffer_from_str(&sec_blob->DomainName,
1079				      ses->domainName,
1080				      CIFS_MAX_DOMAINNAME_LEN,
1081				      *pbuffer, &tmp,
1082				      nls_cp);
1083
1084	cifs_security_buffer_from_str(&sec_blob->UserName,
1085				      ses->user_name,
1086				      CIFS_MAX_USERNAME_LEN,
1087				      *pbuffer, &tmp,
1088				      nls_cp);
1089
1090	cifs_security_buffer_from_str(&sec_blob->WorkstationName,
1091				      ses->workstation_name,
1092				      ntlmssp_workstation_name_size(ses),
1093				      *pbuffer, &tmp,
1094				      nls_cp);
1095
1096	if ((ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_KEY_XCH) &&
1097	    (!ses->server->session_estab || ses->ntlmssp->sesskey_per_smbsess) &&
1098	    !calc_seckey(ses)) {
1099		memcpy(tmp, ses->ntlmssp->ciphertext, CIFS_CPHTXT_SIZE);
1100		sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - *pbuffer);
1101		sec_blob->SessionKey.Length = cpu_to_le16(CIFS_CPHTXT_SIZE);
1102		sec_blob->SessionKey.MaximumLength =
1103				cpu_to_le16(CIFS_CPHTXT_SIZE);
1104		tmp += CIFS_CPHTXT_SIZE;
1105	} else {
1106		sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - *pbuffer);
1107		sec_blob->SessionKey.Length = 0;
1108		sec_blob->SessionKey.MaximumLength = 0;
1109	}
1110
1111	*buflen = tmp - *pbuffer;
1112setup_ntlmv2_ret:
1113	return rc;
1114}
1115
1116enum securityEnum
1117cifs_select_sectype(struct TCP_Server_Info *server, enum securityEnum requested)
1118{
1119	switch (server->negflavor) {
1120	case CIFS_NEGFLAVOR_EXTENDED:
1121		switch (requested) {
1122		case Kerberos:
1123		case RawNTLMSSP:
1124			return requested;
1125		case Unspecified:
1126			if (server->sec_ntlmssp &&
1127			    (global_secflags & CIFSSEC_MAY_NTLMSSP))
1128				return RawNTLMSSP;
1129			if ((server->sec_kerberos || server->sec_mskerberos) &&
1130			    (global_secflags & CIFSSEC_MAY_KRB5))
1131				return Kerberos;
1132			fallthrough;
1133		default:
1134			return Unspecified;
1135		}
1136	case CIFS_NEGFLAVOR_UNENCAP:
1137		switch (requested) {
1138		case NTLMv2:
1139			return requested;
1140		case Unspecified:
1141			if (global_secflags & CIFSSEC_MAY_NTLMV2)
1142				return NTLMv2;
1143			break;
1144		default:
1145			break;
1146		}
1147		fallthrough;
1148	default:
1149		return Unspecified;
1150	}
1151}
1152
1153struct sess_data {
1154	unsigned int xid;
1155	struct cifs_ses *ses;
1156	struct TCP_Server_Info *server;
1157	struct nls_table *nls_cp;
1158	void (*func)(struct sess_data *);
1159	int result;
1160
1161	/* we will send the SMB in three pieces:
1162	 * a fixed length beginning part, an optional
1163	 * SPNEGO blob (which can be zero length), and a
1164	 * last part which will include the strings
1165	 * and rest of bcc area. This allows us to avoid
1166	 * a large buffer 17K allocation
1167	 */
1168	int buf0_type;
1169	struct kvec iov[3];
1170};
1171
1172#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
1173static int
1174sess_alloc_buffer(struct sess_data *sess_data, int wct)
1175{
1176	int rc;
1177	struct cifs_ses *ses = sess_data->ses;
1178	struct smb_hdr *smb_buf;
1179
1180	rc = small_smb_init_no_tc(SMB_COM_SESSION_SETUP_ANDX, wct, ses,
1181				  (void **)&smb_buf);
1182
1183	if (rc)
1184		return rc;
1185
1186	sess_data->iov[0].iov_base = (char *)smb_buf;
1187	sess_data->iov[0].iov_len = be32_to_cpu(smb_buf->smb_buf_length) + 4;
1188	/*
1189	 * This variable will be used to clear the buffer
1190	 * allocated above in case of any error in the calling function.
1191	 */
1192	sess_data->buf0_type = CIFS_SMALL_BUFFER;
1193
1194	/* 2000 big enough to fit max user, domain, NOS name etc. */
1195	sess_data->iov[2].iov_base = kmalloc(2000, GFP_KERNEL);
1196	if (!sess_data->iov[2].iov_base) {
1197		rc = -ENOMEM;
1198		goto out_free_smb_buf;
1199	}
1200
1201	return 0;
1202
1203out_free_smb_buf:
1204	cifs_small_buf_release(smb_buf);
1205	sess_data->iov[0].iov_base = NULL;
1206	sess_data->iov[0].iov_len = 0;
1207	sess_data->buf0_type = CIFS_NO_BUFFER;
1208	return rc;
1209}
1210
1211static void
1212sess_free_buffer(struct sess_data *sess_data)
1213{
1214	struct kvec *iov = sess_data->iov;
1215
1216	/*
1217	 * Zero the session data before freeing, as it might contain sensitive info (keys, etc).
1218	 * Note that iov[1] is already freed by caller.
1219	 */
1220	if (sess_data->buf0_type != CIFS_NO_BUFFER && iov[0].iov_base)
1221		memzero_explicit(iov[0].iov_base, iov[0].iov_len);
1222
1223	free_rsp_buf(sess_data->buf0_type, iov[0].iov_base);
1224	sess_data->buf0_type = CIFS_NO_BUFFER;
1225	kfree_sensitive(iov[2].iov_base);
1226}
1227
1228static int
1229sess_establish_session(struct sess_data *sess_data)
1230{
1231	struct cifs_ses *ses = sess_data->ses;
1232	struct TCP_Server_Info *server = sess_data->server;
1233
1234	cifs_server_lock(server);
1235	if (!server->session_estab) {
1236		if (server->sign) {
1237			server->session_key.response =
1238				kmemdup(ses->auth_key.response,
1239				ses->auth_key.len, GFP_KERNEL);
1240			if (!server->session_key.response) {
1241				cifs_server_unlock(server);
1242				return -ENOMEM;
1243			}
1244			server->session_key.len =
1245						ses->auth_key.len;
1246		}
1247		server->sequence_number = 0x2;
1248		server->session_estab = true;
1249	}
1250	cifs_server_unlock(server);
1251
1252	cifs_dbg(FYI, "CIFS session established successfully\n");
1253	return 0;
1254}
1255
1256static int
1257sess_sendreceive(struct sess_data *sess_data)
1258{
1259	int rc;
1260	struct smb_hdr *smb_buf = (struct smb_hdr *) sess_data->iov[0].iov_base;
1261	__u16 count;
1262	struct kvec rsp_iov = { NULL, 0 };
1263
1264	count = sess_data->iov[1].iov_len + sess_data->iov[2].iov_len;
1265	be32_add_cpu(&smb_buf->smb_buf_length, count);
1266	put_bcc(count, smb_buf);
1267
1268	rc = SendReceive2(sess_data->xid, sess_data->ses,
1269			  sess_data->iov, 3 /* num_iovecs */,
1270			  &sess_data->buf0_type,
1271			  CIFS_LOG_ERROR, &rsp_iov);
1272	cifs_small_buf_release(sess_data->iov[0].iov_base);
1273	memcpy(&sess_data->iov[0], &rsp_iov, sizeof(struct kvec));
1274
1275	return rc;
1276}
1277
1278static void
1279sess_auth_ntlmv2(struct sess_data *sess_data)
1280{
1281	int rc = 0;
1282	struct smb_hdr *smb_buf;
1283	SESSION_SETUP_ANDX *pSMB;
1284	char *bcc_ptr;
1285	struct cifs_ses *ses = sess_data->ses;
1286	struct TCP_Server_Info *server = sess_data->server;
1287	__u32 capabilities;
1288	__u16 bytes_remaining;
1289
1290	/* old style NTLM sessionsetup */
1291	/* wct = 13 */
1292	rc = sess_alloc_buffer(sess_data, 13);
1293	if (rc)
1294		goto out;
1295
1296	pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
1297	bcc_ptr = sess_data->iov[2].iov_base;
1298	capabilities = cifs_ssetup_hdr(ses, server, pSMB);
1299
1300	pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
1301
1302	/* LM2 password would be here if we supported it */
1303	pSMB->req_no_secext.CaseInsensitivePasswordLength = 0;
1304
1305	if (ses->user_name != NULL) {
1306		/* calculate nlmv2 response and session key */
1307		rc = setup_ntlmv2_rsp(ses, sess_data->nls_cp);
1308		if (rc) {
1309			cifs_dbg(VFS, "Error %d during NTLMv2 authentication\n", rc);
1310			goto out;
1311		}
1312
1313		memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
1314				ses->auth_key.len - CIFS_SESS_KEY_SIZE);
1315		bcc_ptr += ses->auth_key.len - CIFS_SESS_KEY_SIZE;
1316
1317		/* set case sensitive password length after tilen may get
1318		 * assigned, tilen is 0 otherwise.
1319		 */
1320		pSMB->req_no_secext.CaseSensitivePasswordLength =
1321			cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
1322	} else {
1323		pSMB->req_no_secext.CaseSensitivePasswordLength = 0;
1324	}
1325
1326	if (ses->capabilities & CAP_UNICODE) {
1327		if (!IS_ALIGNED(sess_data->iov[0].iov_len, 2)) {
1328			*bcc_ptr = 0;
1329			bcc_ptr++;
1330		}
1331		unicode_ssetup_strings(&bcc_ptr, ses, sess_data->nls_cp);
1332	} else {
1333		ascii_ssetup_strings(&bcc_ptr, ses, sess_data->nls_cp);
1334	}
1335
1336
1337	sess_data->iov[2].iov_len = (long) bcc_ptr -
1338			(long) sess_data->iov[2].iov_base;
1339
1340	rc = sess_sendreceive(sess_data);
1341	if (rc)
1342		goto out;
1343
1344	pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
1345	smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
1346
1347	if (smb_buf->WordCount != 3) {
1348		rc = -EIO;
1349		cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
1350		goto out;
1351	}
1352
1353	if (le16_to_cpu(pSMB->resp.Action) & GUEST_LOGIN)
1354		cifs_dbg(FYI, "Guest login\n"); /* BB mark SesInfo struct? */
1355
1356	ses->Suid = smb_buf->Uid;   /* UID left in wire format (le) */
1357	cifs_dbg(FYI, "UID = %llu\n", ses->Suid);
1358
1359	bytes_remaining = get_bcc(smb_buf);
1360	bcc_ptr = pByteArea(smb_buf);
1361
1362	/* BB check if Unicode and decode strings */
1363	if (bytes_remaining == 0) {
1364		/* no string area to decode, do nothing */
1365	} else if (smb_buf->Flags2 & SMBFLG2_UNICODE) {
1366		/* unicode string area must be word-aligned */
1367		if (!IS_ALIGNED((unsigned long)bcc_ptr - (unsigned long)smb_buf, 2)) {
1368			++bcc_ptr;
1369			--bytes_remaining;
1370		}
1371		decode_unicode_ssetup(&bcc_ptr, bytes_remaining, ses,
1372				      sess_data->nls_cp);
1373	} else {
1374		decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses,
1375				    sess_data->nls_cp);
1376	}
1377
1378	rc = sess_establish_session(sess_data);
1379out:
1380	sess_data->result = rc;
1381	sess_data->func = NULL;
1382	sess_free_buffer(sess_data);
1383	kfree_sensitive(ses->auth_key.response);
1384	ses->auth_key.response = NULL;
1385}
1386
1387#ifdef CONFIG_CIFS_UPCALL
1388static void
1389sess_auth_kerberos(struct sess_data *sess_data)
1390{
1391	int rc = 0;
1392	struct smb_hdr *smb_buf;
1393	SESSION_SETUP_ANDX *pSMB;
1394	char *bcc_ptr;
1395	struct cifs_ses *ses = sess_data->ses;
1396	struct TCP_Server_Info *server = sess_data->server;
1397	__u32 capabilities;
1398	__u16 bytes_remaining;
1399	struct key *spnego_key = NULL;
1400	struct cifs_spnego_msg *msg;
1401	u16 blob_len;
1402
1403	/* extended security */
1404	/* wct = 12 */
1405	rc = sess_alloc_buffer(sess_data, 12);
1406	if (rc)
1407		goto out;
1408
1409	pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
1410	bcc_ptr = sess_data->iov[2].iov_base;
1411	capabilities = cifs_ssetup_hdr(ses, server, pSMB);
1412
1413	spnego_key = cifs_get_spnego_key(ses, server);
1414	if (IS_ERR(spnego_key)) {
1415		rc = PTR_ERR(spnego_key);
1416		spnego_key = NULL;
1417		goto out;
1418	}
1419
1420	msg = spnego_key->payload.data[0];
1421	/*
1422	 * check version field to make sure that cifs.upcall is
1423	 * sending us a response in an expected form
1424	 */
1425	if (msg->version != CIFS_SPNEGO_UPCALL_VERSION) {
1426		cifs_dbg(VFS, "incorrect version of cifs.upcall (expected %d but got %d)\n",
1427			 CIFS_SPNEGO_UPCALL_VERSION, msg->version);
1428		rc = -EKEYREJECTED;
1429		goto out_put_spnego_key;
1430	}
1431
1432	kfree_sensitive(ses->auth_key.response);
1433	ses->auth_key.response = kmemdup(msg->data, msg->sesskey_len,
1434					 GFP_KERNEL);
1435	if (!ses->auth_key.response) {
1436		cifs_dbg(VFS, "Kerberos can't allocate (%u bytes) memory\n",
1437			 msg->sesskey_len);
1438		rc = -ENOMEM;
1439		goto out_put_spnego_key;
1440	}
1441	ses->auth_key.len = msg->sesskey_len;
1442
1443	pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
1444	capabilities |= CAP_EXTENDED_SECURITY;
1445	pSMB->req.Capabilities = cpu_to_le32(capabilities);
1446	sess_data->iov[1].iov_base = msg->data + msg->sesskey_len;
1447	sess_data->iov[1].iov_len = msg->secblob_len;
1448	pSMB->req.SecurityBlobLength = cpu_to_le16(sess_data->iov[1].iov_len);
1449
1450	if (ses->capabilities & CAP_UNICODE) {
1451		/* unicode strings must be word aligned */
1452		if (!IS_ALIGNED(sess_data->iov[0].iov_len + sess_data->iov[1].iov_len, 2)) {
1453			*bcc_ptr = 0;
1454			bcc_ptr++;
1455		}
1456		unicode_oslm_strings(&bcc_ptr, sess_data->nls_cp);
1457		unicode_domain_string(&bcc_ptr, ses, sess_data->nls_cp);
1458	} else {
1459		/* BB: is this right? */
1460		ascii_ssetup_strings(&bcc_ptr, ses, sess_data->nls_cp);
1461	}
1462
1463	sess_data->iov[2].iov_len = (long) bcc_ptr -
1464			(long) sess_data->iov[2].iov_base;
1465
1466	rc = sess_sendreceive(sess_data);
1467	if (rc)
1468		goto out_put_spnego_key;
1469
1470	pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
1471	smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
1472
1473	if (smb_buf->WordCount != 4) {
1474		rc = -EIO;
1475		cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
1476		goto out_put_spnego_key;
1477	}
1478
1479	if (le16_to_cpu(pSMB->resp.Action) & GUEST_LOGIN)
1480		cifs_dbg(FYI, "Guest login\n"); /* BB mark SesInfo struct? */
1481
1482	ses->Suid = smb_buf->Uid;   /* UID left in wire format (le) */
1483	cifs_dbg(FYI, "UID = %llu\n", ses->Suid);
1484
1485	bytes_remaining = get_bcc(smb_buf);
1486	bcc_ptr = pByteArea(smb_buf);
1487
1488	blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
1489	if (blob_len > bytes_remaining) {
1490		cifs_dbg(VFS, "bad security blob length %d\n",
1491				blob_len);
1492		rc = -EINVAL;
1493		goto out_put_spnego_key;
1494	}
1495	bcc_ptr += blob_len;
1496	bytes_remaining -= blob_len;
1497
1498	/* BB check if Unicode and decode strings */
1499	if (bytes_remaining == 0) {
1500		/* no string area to decode, do nothing */
1501	} else if (smb_buf->Flags2 & SMBFLG2_UNICODE) {
1502		/* unicode string area must be word-aligned */
1503		if (!IS_ALIGNED((unsigned long)bcc_ptr - (unsigned long)smb_buf, 2)) {
1504			++bcc_ptr;
1505			--bytes_remaining;
1506		}
1507		decode_unicode_ssetup(&bcc_ptr, bytes_remaining, ses,
1508				      sess_data->nls_cp);
1509	} else {
1510		decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses,
1511				    sess_data->nls_cp);
1512	}
1513
1514	rc = sess_establish_session(sess_data);
1515out_put_spnego_key:
1516	key_invalidate(spnego_key);
1517	key_put(spnego_key);
1518out:
1519	sess_data->result = rc;
1520	sess_data->func = NULL;
1521	sess_free_buffer(sess_data);
1522	kfree_sensitive(ses->auth_key.response);
1523	ses->auth_key.response = NULL;
1524}
1525
1526#endif /* ! CONFIG_CIFS_UPCALL */
1527
1528/*
1529 * The required kvec buffers have to be allocated before calling this
1530 * function.
1531 */
1532static int
1533_sess_auth_rawntlmssp_assemble_req(struct sess_data *sess_data)
1534{
1535	SESSION_SETUP_ANDX *pSMB;
1536	struct cifs_ses *ses = sess_data->ses;
1537	struct TCP_Server_Info *server = sess_data->server;
1538	__u32 capabilities;
1539	char *bcc_ptr;
1540
1541	pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
1542
1543	capabilities = cifs_ssetup_hdr(ses, server, pSMB);
1544	if ((pSMB->req.hdr.Flags2 & SMBFLG2_UNICODE) == 0) {
1545		cifs_dbg(VFS, "NTLMSSP requires Unicode support\n");
1546		return -ENOSYS;
1547	}
1548
1549	pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
1550	capabilities |= CAP_EXTENDED_SECURITY;
1551	pSMB->req.Capabilities |= cpu_to_le32(capabilities);
1552
1553	bcc_ptr = sess_data->iov[2].iov_base;
1554	/* unicode strings must be word aligned */
1555	if (!IS_ALIGNED(sess_data->iov[0].iov_len + sess_data->iov[1].iov_len, 2)) {
1556		*bcc_ptr = 0;
1557		bcc_ptr++;
1558	}
1559	unicode_oslm_strings(&bcc_ptr, sess_data->nls_cp);
1560
1561	sess_data->iov[2].iov_len = (long) bcc_ptr -
1562					(long) sess_data->iov[2].iov_base;
1563
1564	return 0;
1565}
1566
1567static void
1568sess_auth_rawntlmssp_authenticate(struct sess_data *sess_data);
1569
1570static void
1571sess_auth_rawntlmssp_negotiate(struct sess_data *sess_data)
1572{
1573	int rc;
1574	struct smb_hdr *smb_buf;
1575	SESSION_SETUP_ANDX *pSMB;
1576	struct cifs_ses *ses = sess_data->ses;
1577	struct TCP_Server_Info *server = sess_data->server;
1578	__u16 bytes_remaining;
1579	char *bcc_ptr;
1580	unsigned char *ntlmsspblob = NULL;
1581	u16 blob_len;
1582
1583	cifs_dbg(FYI, "rawntlmssp session setup negotiate phase\n");
1584
1585	/*
1586	 * if memory allocation is successful, caller of this function
1587	 * frees it.
1588	 */
1589	ses->ntlmssp = kmalloc(sizeof(struct ntlmssp_auth), GFP_KERNEL);
1590	if (!ses->ntlmssp) {
1591		rc = -ENOMEM;
1592		goto out;
1593	}
1594	ses->ntlmssp->sesskey_per_smbsess = false;
1595
1596	/* wct = 12 */
1597	rc = sess_alloc_buffer(sess_data, 12);
1598	if (rc)
1599		goto out;
1600
1601	pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
1602
1603	/* Build security blob before we assemble the request */
1604	rc = build_ntlmssp_negotiate_blob(&ntlmsspblob,
1605				     &blob_len, ses, server,
1606				     sess_data->nls_cp);
1607	if (rc)
1608		goto out_free_ntlmsspblob;
1609
1610	sess_data->iov[1].iov_len = blob_len;
1611	sess_data->iov[1].iov_base = ntlmsspblob;
1612	pSMB->req.SecurityBlobLength = cpu_to_le16(blob_len);
1613
1614	rc = _sess_auth_rawntlmssp_assemble_req(sess_data);
1615	if (rc)
1616		goto out_free_ntlmsspblob;
1617
1618	rc = sess_sendreceive(sess_data);
1619
1620	pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
1621	smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
1622
1623	/* If true, rc here is expected and not an error */
1624	if (sess_data->buf0_type != CIFS_NO_BUFFER &&
1625	    smb_buf->Status.CifsError ==
1626			cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))
1627		rc = 0;
1628
1629	if (rc)
1630		goto out_free_ntlmsspblob;
1631
1632	cifs_dbg(FYI, "rawntlmssp session setup challenge phase\n");
1633
1634	if (smb_buf->WordCount != 4) {
1635		rc = -EIO;
1636		cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
1637		goto out_free_ntlmsspblob;
1638	}
1639
1640	ses->Suid = smb_buf->Uid;   /* UID left in wire format (le) */
1641	cifs_dbg(FYI, "UID = %llu\n", ses->Suid);
1642
1643	bytes_remaining = get_bcc(smb_buf);
1644	bcc_ptr = pByteArea(smb_buf);
1645
1646	blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
1647	if (blob_len > bytes_remaining) {
1648		cifs_dbg(VFS, "bad security blob length %d\n",
1649				blob_len);
1650		rc = -EINVAL;
1651		goto out_free_ntlmsspblob;
1652	}
1653
1654	rc = decode_ntlmssp_challenge(bcc_ptr, blob_len, ses);
1655
1656out_free_ntlmsspblob:
1657	kfree_sensitive(ntlmsspblob);
1658out:
1659	sess_free_buffer(sess_data);
1660
1661	if (!rc) {
1662		sess_data->func = sess_auth_rawntlmssp_authenticate;
1663		return;
1664	}
1665
1666	/* Else error. Cleanup */
1667	kfree_sensitive(ses->auth_key.response);
1668	ses->auth_key.response = NULL;
1669	kfree_sensitive(ses->ntlmssp);
1670	ses->ntlmssp = NULL;
1671
1672	sess_data->func = NULL;
1673	sess_data->result = rc;
1674}
1675
1676static void
1677sess_auth_rawntlmssp_authenticate(struct sess_data *sess_data)
1678{
1679	int rc;
1680	struct smb_hdr *smb_buf;
1681	SESSION_SETUP_ANDX *pSMB;
1682	struct cifs_ses *ses = sess_data->ses;
1683	struct TCP_Server_Info *server = sess_data->server;
1684	__u16 bytes_remaining;
1685	char *bcc_ptr;
1686	unsigned char *ntlmsspblob = NULL;
1687	u16 blob_len;
1688
1689	cifs_dbg(FYI, "rawntlmssp session setup authenticate phase\n");
1690
1691	/* wct = 12 */
1692	rc = sess_alloc_buffer(sess_data, 12);
1693	if (rc)
1694		goto out;
1695
1696	/* Build security blob before we assemble the request */
1697	pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
1698	smb_buf = (struct smb_hdr *)pSMB;
1699	rc = build_ntlmssp_auth_blob(&ntlmsspblob,
1700					&blob_len, ses, server,
1701					sess_data->nls_cp);
1702	if (rc)
1703		goto out_free_ntlmsspblob;
1704	sess_data->iov[1].iov_len = blob_len;
1705	sess_data->iov[1].iov_base = ntlmsspblob;
1706	pSMB->req.SecurityBlobLength = cpu_to_le16(blob_len);
1707	/*
1708	 * Make sure that we tell the server that we are using
1709	 * the uid that it just gave us back on the response
1710	 * (challenge)
1711	 */
1712	smb_buf->Uid = ses->Suid;
1713
1714	rc = _sess_auth_rawntlmssp_assemble_req(sess_data);
1715	if (rc)
1716		goto out_free_ntlmsspblob;
1717
1718	rc = sess_sendreceive(sess_data);
1719	if (rc)
1720		goto out_free_ntlmsspblob;
1721
1722	pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
1723	smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
1724	if (smb_buf->WordCount != 4) {
1725		rc = -EIO;
1726		cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
1727		goto out_free_ntlmsspblob;
1728	}
1729
1730	if (le16_to_cpu(pSMB->resp.Action) & GUEST_LOGIN)
1731		cifs_dbg(FYI, "Guest login\n"); /* BB mark SesInfo struct? */
1732
1733	if (ses->Suid != smb_buf->Uid) {
1734		ses->Suid = smb_buf->Uid;
1735		cifs_dbg(FYI, "UID changed! new UID = %llu\n", ses->Suid);
1736	}
1737
1738	bytes_remaining = get_bcc(smb_buf);
1739	bcc_ptr = pByteArea(smb_buf);
1740	blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
1741	if (blob_len > bytes_remaining) {
1742		cifs_dbg(VFS, "bad security blob length %d\n",
1743				blob_len);
1744		rc = -EINVAL;
1745		goto out_free_ntlmsspblob;
1746	}
1747	bcc_ptr += blob_len;
1748	bytes_remaining -= blob_len;
1749
1750
1751	/* BB check if Unicode and decode strings */
1752	if (bytes_remaining == 0) {
1753		/* no string area to decode, do nothing */
1754	} else if (smb_buf->Flags2 & SMBFLG2_UNICODE) {
1755		/* unicode string area must be word-aligned */
1756		if (!IS_ALIGNED((unsigned long)bcc_ptr - (unsigned long)smb_buf, 2)) {
1757			++bcc_ptr;
1758			--bytes_remaining;
1759		}
1760		decode_unicode_ssetup(&bcc_ptr, bytes_remaining, ses,
1761				      sess_data->nls_cp);
1762	} else {
1763		decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses,
1764				    sess_data->nls_cp);
1765	}
1766
1767out_free_ntlmsspblob:
1768	kfree_sensitive(ntlmsspblob);
1769out:
1770	sess_free_buffer(sess_data);
1771
1772	if (!rc)
1773		rc = sess_establish_session(sess_data);
1774
1775	/* Cleanup */
1776	kfree_sensitive(ses->auth_key.response);
1777	ses->auth_key.response = NULL;
1778	kfree_sensitive(ses->ntlmssp);
1779	ses->ntlmssp = NULL;
1780
1781	sess_data->func = NULL;
1782	sess_data->result = rc;
1783}
1784
1785static int select_sec(struct sess_data *sess_data)
1786{
1787	int type;
1788	struct cifs_ses *ses = sess_data->ses;
1789	struct TCP_Server_Info *server = sess_data->server;
1790
1791	type = cifs_select_sectype(server, ses->sectype);
1792	cifs_dbg(FYI, "sess setup type %d\n", type);
1793	if (type == Unspecified) {
1794		cifs_dbg(VFS, "Unable to select appropriate authentication method!\n");
1795		return -EINVAL;
1796	}
1797
1798	switch (type) {
1799	case NTLMv2:
1800		sess_data->func = sess_auth_ntlmv2;
1801		break;
1802	case Kerberos:
1803#ifdef CONFIG_CIFS_UPCALL
1804		sess_data->func = sess_auth_kerberos;
1805		break;
1806#else
1807		cifs_dbg(VFS, "Kerberos negotiated but upcall support disabled!\n");
1808		return -ENOSYS;
1809#endif /* CONFIG_CIFS_UPCALL */
1810	case RawNTLMSSP:
1811		sess_data->func = sess_auth_rawntlmssp_negotiate;
1812		break;
1813	default:
1814		cifs_dbg(VFS, "secType %d not supported!\n", type);
1815		return -ENOSYS;
1816	}
1817
1818	return 0;
1819}
1820
1821int CIFS_SessSetup(const unsigned int xid, struct cifs_ses *ses,
1822		   struct TCP_Server_Info *server,
1823		   const struct nls_table *nls_cp)
1824{
1825	int rc = 0;
1826	struct sess_data *sess_data;
1827
1828	if (ses == NULL) {
1829		WARN(1, "%s: ses == NULL!", __func__);
1830		return -EINVAL;
1831	}
1832
1833	sess_data = kzalloc(sizeof(struct sess_data), GFP_KERNEL);
1834	if (!sess_data)
1835		return -ENOMEM;
1836
1837	sess_data->xid = xid;
1838	sess_data->ses = ses;
1839	sess_data->server = server;
1840	sess_data->buf0_type = CIFS_NO_BUFFER;
1841	sess_data->nls_cp = (struct nls_table *) nls_cp;
1842
1843	rc = select_sec(sess_data);
1844	if (rc)
1845		goto out;
1846
1847	while (sess_data->func)
1848		sess_data->func(sess_data);
1849
1850	/* Store result before we free sess_data */
1851	rc = sess_data->result;
1852
1853out:
1854	kfree_sensitive(sess_data);
1855	return rc;
1856}
1857#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */