brintos

brintos / linux-shallow public Read only

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