connect.c 115.3 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3
/*
 *   fs/cifs/connect.c
 *
4
 *   Copyright (C) International Business Machines  Corp., 2002,2011
L
Linus Torvalds 已提交
5 6 7 8 9 10 11 12 13 14 15 16 17 18
 *   Author(s): Steve French (sfrench@us.ibm.com)
 *
 *   This library is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU Lesser General Public License as published
 *   by the Free Software Foundation; either version 2.1 of the License, or
 *   (at your option) any later version.
 *
 *   This library is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
 *   the GNU Lesser General Public License for more details.
 *
 *   You should have received a copy of the GNU Lesser General Public License
 *   along with this library; if not, write to the Free Software
S
Steve French 已提交
19
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
L
Linus Torvalds 已提交
20 21 22 23
 */
#include <linux/fs.h>
#include <linux/net.h>
#include <linux/string.h>
24
#include <linux/sched/signal.h>
L
Linus Torvalds 已提交
25 26
#include <linux/list.h>
#include <linux/wait.h>
27
#include <linux/slab.h>
L
Linus Torvalds 已提交
28 29 30 31
#include <linux/pagemap.h>
#include <linux/ctype.h>
#include <linux/utsname.h>
#include <linux/mempool.h>
32
#include <linux/delay.h>
33
#include <linux/completion.h>
34
#include <linux/kthread.h>
35
#include <linux/pagevec.h>
36
#include <linux/freezer.h>
37
#include <linux/namei.h>
38
#include <linux/uuid.h>
39
#include <linux/uaccess.h>
L
Linus Torvalds 已提交
40
#include <asm/processor.h>
41
#include <linux/inet.h>
42
#include <linux/module.h>
43
#include <keys/user-type.h>
44
#include <net/ipv6.h>
45
#include <linux/parser.h>
46
#include <linux/bvec.h>
L
Linus Torvalds 已提交
47 48 49 50 51 52 53 54 55
#include "cifspdu.h"
#include "cifsglob.h"
#include "cifsproto.h"
#include "cifs_unicode.h"
#include "cifs_debug.h"
#include "cifs_fs_sb.h"
#include "ntlmssp.h"
#include "nterr.h"
#include "rfc1002pdu.h"
56
#include "fscache.h"
57
#include "smb2proto.h"
58
#include "smbdirect.h"
L
Linus Torvalds 已提交
59 60 61 62 63 64

#define CIFS_PORT 445
#define RFC1001_PORT 139

extern mempool_t *cifs_req_poolp;

65
/* FIXME: should these be tunable? */
66
#define TLINK_ERROR_EXPIRE	(1 * HZ)
67
#define TLINK_IDLE_EXPIRE	(600 * HZ)
68

69 70 71 72
enum {
	/* Mount options that take no arguments */
	Opt_user_xattr, Opt_nouser_xattr,
	Opt_forceuid, Opt_noforceuid,
J
Jeff Layton 已提交
73
	Opt_forcegid, Opt_noforcegid,
74 75
	Opt_noblocksend, Opt_noautotune,
	Opt_hard, Opt_soft, Opt_perm, Opt_noperm,
76
	Opt_mapposix, Opt_nomapposix,
77 78 79 80 81
	Opt_mapchars, Opt_nomapchars, Opt_sfu,
	Opt_nosfu, Opt_nodfs, Opt_posixpaths,
	Opt_noposixpaths, Opt_nounix,
	Opt_nocase,
	Opt_brl, Opt_nobrl,
82
	Opt_forcemandatorylock, Opt_setuidfromacl, Opt_setuids,
83 84 85 86 87 88 89
	Opt_nosetuids, Opt_dynperm, Opt_nodynperm,
	Opt_nohard, Opt_nosoft,
	Opt_nointr, Opt_intr,
	Opt_nostrictsync, Opt_strictsync,
	Opt_serverino, Opt_noserverino,
	Opt_rwpidforward, Opt_cifsacl, Opt_nocifsacl,
	Opt_acl, Opt_noacl, Opt_locallease,
90
	Opt_sign, Opt_seal, Opt_noac,
91
	Opt_fsc, Opt_mfsymlinks,
92
	Opt_multiuser, Opt_sloppy, Opt_nosharesock,
93
	Opt_persistent, Opt_nopersistent,
S
Steve French 已提交
94
	Opt_resilient, Opt_noresilient,
L
Long Li 已提交
95
	Opt_domainauto, Opt_rdma,
96 97 98 99 100 101

	/* Mount options which take numeric value */
	Opt_backupuid, Opt_backupgid, Opt_uid,
	Opt_cruid, Opt_gid, Opt_file_mode,
	Opt_dirmode, Opt_port,
	Opt_rsize, Opt_wsize, Opt_actimeo,
102
	Opt_echo_interval, Opt_max_credits,
103
	Opt_snapshot,
104 105 106

	/* Mount options which take string value */
	Opt_user, Opt_pass, Opt_ip,
107
	Opt_domain, Opt_srcaddr, Opt_iocharset,
108
	Opt_netbiosname, Opt_servern,
109
	Opt_ver, Opt_vers, Opt_sec, Opt_cache,
110 111 112 113 114 115

	/* Mount options to be ignored */
	Opt_ignore,

	/* Options which could be blank */
	Opt_blank_pass,
116 117
	Opt_blank_user,
	Opt_blank_ip,
118 119 120 121 122 123 124 125 126 127

	Opt_err
};

static const match_table_t cifs_mount_option_tokens = {

	{ Opt_user_xattr, "user_xattr" },
	{ Opt_nouser_xattr, "nouser_xattr" },
	{ Opt_forceuid, "forceuid" },
	{ Opt_noforceuid, "noforceuid" },
J
Jeff Layton 已提交
128 129
	{ Opt_forcegid, "forcegid" },
	{ Opt_noforcegid, "noforcegid" },
130 131 132 133 134 135
	{ Opt_noblocksend, "noblocksend" },
	{ Opt_noautotune, "noautotune" },
	{ Opt_hard, "hard" },
	{ Opt_soft, "soft" },
	{ Opt_perm, "perm" },
	{ Opt_noperm, "noperm" },
136
	{ Opt_mapchars, "mapchars" }, /* SFU style */
137
	{ Opt_nomapchars, "nomapchars" },
138 139
	{ Opt_mapposix, "mapposix" }, /* SFM style */
	{ Opt_nomapposix, "nomapposix" },
140 141 142 143 144 145 146 147 148 149 150 151 152
	{ Opt_sfu, "sfu" },
	{ Opt_nosfu, "nosfu" },
	{ Opt_nodfs, "nodfs" },
	{ Opt_posixpaths, "posixpaths" },
	{ Opt_noposixpaths, "noposixpaths" },
	{ Opt_nounix, "nounix" },
	{ Opt_nounix, "nolinux" },
	{ Opt_nocase, "nocase" },
	{ Opt_nocase, "ignorecase" },
	{ Opt_brl, "brl" },
	{ Opt_nobrl, "nobrl" },
	{ Opt_nobrl, "nolock" },
	{ Opt_forcemandatorylock, "forcemandatorylock" },
153
	{ Opt_forcemandatorylock, "forcemand" },
154 155
	{ Opt_setuids, "setuids" },
	{ Opt_nosetuids, "nosetuids" },
156
	{ Opt_setuidfromacl, "idsfromsid" },
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
	{ Opt_dynperm, "dynperm" },
	{ Opt_nodynperm, "nodynperm" },
	{ Opt_nohard, "nohard" },
	{ Opt_nosoft, "nosoft" },
	{ Opt_nointr, "nointr" },
	{ Opt_intr, "intr" },
	{ Opt_nostrictsync, "nostrictsync" },
	{ Opt_strictsync, "strictsync" },
	{ Opt_serverino, "serverino" },
	{ Opt_noserverino, "noserverino" },
	{ Opt_rwpidforward, "rwpidforward" },
	{ Opt_cifsacl, "cifsacl" },
	{ Opt_nocifsacl, "nocifsacl" },
	{ Opt_acl, "acl" },
	{ Opt_noacl, "noacl" },
	{ Opt_locallease, "locallease" },
	{ Opt_sign, "sign" },
	{ Opt_seal, "seal" },
	{ Opt_noac, "noac" },
	{ Opt_fsc, "fsc" },
	{ Opt_mfsymlinks, "mfsymlinks" },
	{ Opt_multiuser, "multiuser" },
179
	{ Opt_sloppy, "sloppy" },
180
	{ Opt_nosharesock, "nosharesock" },
181 182
	{ Opt_persistent, "persistenthandles"},
	{ Opt_nopersistent, "nopersistenthandles"},
S
Steve French 已提交
183 184
	{ Opt_resilient, "resilienthandles"},
	{ Opt_noresilient, "noresilienthandles"},
185
	{ Opt_domainauto, "domainauto"},
L
Long Li 已提交
186
	{ Opt_rdma, "rdma"},
187 188 189 190 191 192 193 194 195 196 197 198 199

	{ Opt_backupuid, "backupuid=%s" },
	{ Opt_backupgid, "backupgid=%s" },
	{ Opt_uid, "uid=%s" },
	{ Opt_cruid, "cruid=%s" },
	{ Opt_gid, "gid=%s" },
	{ Opt_file_mode, "file_mode=%s" },
	{ Opt_dirmode, "dirmode=%s" },
	{ Opt_dirmode, "dir_mode=%s" },
	{ Opt_port, "port=%s" },
	{ Opt_rsize, "rsize=%s" },
	{ Opt_wsize, "wsize=%s" },
	{ Opt_actimeo, "actimeo=%s" },
S
Steve French 已提交
200
	{ Opt_echo_interval, "echo_interval=%s" },
201
	{ Opt_max_credits, "max_credits=%s" },
202
	{ Opt_snapshot, "snapshot=%s" },
203

204 205
	{ Opt_blank_user, "user=" },
	{ Opt_blank_user, "username=" },
206 207 208
	{ Opt_user, "user=%s" },
	{ Opt_user, "username=%s" },
	{ Opt_blank_pass, "pass=" },
209
	{ Opt_blank_pass, "password=" },
210 211
	{ Opt_pass, "pass=%s" },
	{ Opt_pass, "password=%s" },
212 213
	{ Opt_blank_ip, "ip=" },
	{ Opt_blank_ip, "addr=" },
214 215
	{ Opt_ip, "ip=%s" },
	{ Opt_ip, "addr=%s" },
216 217 218
	{ Opt_ignore, "unc=%s" },
	{ Opt_ignore, "target=%s" },
	{ Opt_ignore, "path=%s" },
219 220 221 222
	{ Opt_domain, "dom=%s" },
	{ Opt_domain, "domain=%s" },
	{ Opt_domain, "workgroup=%s" },
	{ Opt_srcaddr, "srcaddr=%s" },
223
	{ Opt_ignore, "prefixpath=%s" },
224 225 226 227
	{ Opt_iocharset, "iocharset=%s" },
	{ Opt_netbiosname, "netbiosname=%s" },
	{ Opt_servern, "servern=%s" },
	{ Opt_ver, "ver=%s" },
228
	{ Opt_vers, "vers=%s" },
229
	{ Opt_sec, "sec=%s" },
230
	{ Opt_cache, "cache=%s" },
231 232 233

	{ Opt_ignore, "cred" },
	{ Opt_ignore, "credentials" },
234 235
	{ Opt_ignore, "cred=%s" },
	{ Opt_ignore, "credentials=%s" },
236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
	{ Opt_ignore, "guest" },
	{ Opt_ignore, "rw" },
	{ Opt_ignore, "ro" },
	{ Opt_ignore, "suid" },
	{ Opt_ignore, "nosuid" },
	{ Opt_ignore, "exec" },
	{ Opt_ignore, "noexec" },
	{ Opt_ignore, "nodev" },
	{ Opt_ignore, "noauto" },
	{ Opt_ignore, "dev" },
	{ Opt_ignore, "mand" },
	{ Opt_ignore, "nomand" },
	{ Opt_ignore, "_netdev" },

	{ Opt_err, NULL }
};

enum {
	Opt_sec_krb5, Opt_sec_krb5i, Opt_sec_krb5p,
	Opt_sec_ntlmsspi, Opt_sec_ntlmssp,
256 257
	Opt_ntlm, Opt_sec_ntlmi, Opt_sec_ntlmv2,
	Opt_sec_ntlmv2i, Opt_sec_lanman,
258 259 260 261 262 263 264 265 266 267 268 269 270
	Opt_sec_none,

	Opt_sec_err
};

static const match_table_t cifs_secflavor_tokens = {
	{ Opt_sec_krb5, "krb5" },
	{ Opt_sec_krb5i, "krb5i" },
	{ Opt_sec_krb5p, "krb5p" },
	{ Opt_sec_ntlmsspi, "ntlmsspi" },
	{ Opt_sec_ntlmssp, "ntlmssp" },
	{ Opt_ntlm, "ntlm" },
	{ Opt_sec_ntlmi, "ntlmi" },
271 272
	{ Opt_sec_ntlmv2, "nontlm" },
	{ Opt_sec_ntlmv2, "ntlmv2" },
273 274 275 276 277 278 279
	{ Opt_sec_ntlmv2i, "ntlmv2i" },
	{ Opt_sec_lanman, "lanman" },
	{ Opt_sec_none, "none" },

	{ Opt_sec_err, NULL }
};

280 281 282 283 284 285 286 287 288 289 290 291 292 293 294
/* cache flavors */
enum {
	Opt_cache_loose,
	Opt_cache_strict,
	Opt_cache_none,
	Opt_cache_err
};

static const match_table_t cifs_cacheflavor_tokens = {
	{ Opt_cache_loose, "loose" },
	{ Opt_cache_strict, "strict" },
	{ Opt_cache_none, "none" },
	{ Opt_cache_err, NULL }
};

295 296
static const match_table_t cifs_smb_version_tokens = {
	{ Smb_1, SMB1_VERSION_STRING },
S
Steve French 已提交
297
	{ Smb_20, SMB20_VERSION_STRING},
298
	{ Smb_21, SMB21_VERSION_STRING },
299
	{ Smb_30, SMB30_VERSION_STRING },
S
Steve French 已提交
300
	{ Smb_302, SMB302_VERSION_STRING },
301 302
#ifdef CONFIG_CIFS_SMB311
	{ Smb_311, SMB311_VERSION_STRING },
303
	{ Smb_311, ALT_SMB311_VERSION_STRING },
304
#endif /* SMB311 */
305 306
	{ Smb_3any, SMB3ANY_VERSION_STRING },
	{ Smb_default, SMBDEFAULT_VERSION_STRING },
307
	{ Smb_version_err, NULL }
308 309
};

310 311
static int ip_connect(struct TCP_Server_Info *server);
static int generic_ip_connect(struct TCP_Server_Info *server);
J
Jeff Layton 已提交
312
static void tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink);
313
static void cifs_prune_tlinks(struct work_struct *work);
J
Jeff Layton 已提交
314 315
static int cifs_setup_volume_info(struct smb_vol *volume_info, char *mount_data,
					const char *devname);
L
Linus Torvalds 已提交
316

317 318 319 320 321 322 323 324
/*
 * cifs tcp session reconnection
 *
 * mark tcp session as reconnecting so temporarily locked
 * mark all smb sessions as reconnecting for tcp session
 * reconnect tcp session
 * wake up waiters on reconnection? - (not needed currently)
 */
P
Pavel Shilovsky 已提交
325
int
L
Linus Torvalds 已提交
326 327 328
cifs_reconnect(struct TCP_Server_Info *server)
{
	int rc = 0;
329
	struct list_head *tmp, *tmp2;
330 331
	struct cifs_ses *ses;
	struct cifs_tcon *tcon;
S
Steve French 已提交
332
	struct mid_q_entry *mid_entry;
333
	struct list_head retry_list;
334

L
Linus Torvalds 已提交
335
	spin_lock(&GlobalMid_Lock);
336
	if (server->tcpStatus == CifsExiting) {
S
Steve French 已提交
337
		/* the demux thread will exit normally
L
Linus Torvalds 已提交
338 339 340 341 342 343 344
		next time through the loop */
		spin_unlock(&GlobalMid_Lock);
		return rc;
	} else
		server->tcpStatus = CifsNeedReconnect;
	spin_unlock(&GlobalMid_Lock);
	server->maxBuf = 0;
345
	server->max_read = 0;
L
Linus Torvalds 已提交
346

347
	cifs_dbg(FYI, "Reconnecting tcp session\n");
L
Linus Torvalds 已提交
348 349 350

	/* before reconnecting the tcp session, mark the smb session (uid)
		and the tid bad so they are not used until reconnected */
351 352
	cifs_dbg(FYI, "%s: marking sessions and tcons for reconnect\n",
		 __func__);
353
	spin_lock(&cifs_tcp_ses_lock);
354
	list_for_each(tmp, &server->smb_ses_list) {
355
		ses = list_entry(tmp, struct cifs_ses, smb_ses_list);
356 357
		ses->need_reconnect = true;
		ses->ipc_tid = 0;
358
		list_for_each(tmp2, &ses->tcon_list) {
359
			tcon = list_entry(tmp2, struct cifs_tcon, tcon_list);
S
Steve French 已提交
360
			tcon->need_reconnect = true;
L
Linus Torvalds 已提交
361 362
		}
	}
363
	spin_unlock(&cifs_tcp_ses_lock);
364

L
Linus Torvalds 已提交
365
	/* do not want to be sending data on a socket we are freeing */
366
	cifs_dbg(FYI, "%s: tearing down socket\n", __func__);
J
Jeff Layton 已提交
367
	mutex_lock(&server->srv_mutex);
S
Steve French 已提交
368
	if (server->ssocket) {
369 370
		cifs_dbg(FYI, "State: 0x%x Flags: 0x%lx\n",
			 server->ssocket->state, server->ssocket->flags);
371
		kernel_sock_shutdown(server->ssocket, SHUT_WR);
372 373
		cifs_dbg(FYI, "Post shutdown state: 0x%x Flags: 0x%lx\n",
			 server->ssocket->state, server->ssocket->flags);
L
Linus Torvalds 已提交
374 375 376
		sock_release(server->ssocket);
		server->ssocket = NULL;
	}
377 378
	server->sequence_number = 0;
	server->session_estab = false;
379 380 381
	kfree(server->session_key.response);
	server->session_key.response = NULL;
	server->session_key.len = 0;
382
	server->lstrp = jiffies;
L
Linus Torvalds 已提交
383

384
	/* mark submitted MIDs for retry and issue callback */
385
	INIT_LIST_HEAD(&retry_list);
386
	cifs_dbg(FYI, "%s: moving mids to private list\n", __func__);
L
Linus Torvalds 已提交
387
	spin_lock(&GlobalMid_Lock);
388 389
	list_for_each_safe(tmp, tmp2, &server->pending_mid_q) {
		mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
390 391
		if (mid_entry->mid_state == MID_REQUEST_SUBMITTED)
			mid_entry->mid_state = MID_RETRY_NEEDED;
392 393 394
		list_move(&mid_entry->qhead, &retry_list);
	}
	spin_unlock(&GlobalMid_Lock);
395
	mutex_unlock(&server->srv_mutex);
396

397
	cifs_dbg(FYI, "%s: issuing mid callbacks\n", __func__);
398 399
	list_for_each_safe(tmp, tmp2, &retry_list) {
		mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
400 401
		list_del_init(&mid_entry->qhead);
		mid_entry->callback(mid_entry);
L
Linus Torvalds 已提交
402 403
	}

404
	do {
405
		try_to_freeze();
406 407

		/* we should try only the port we connected to before */
408
		mutex_lock(&server->srv_mutex);
409 410 411 412
		if (cifs_rdma_enabled(server))
			rc = smbd_reconnect(server);
		else
			rc = generic_ip_connect(server);
S
Steve French 已提交
413
		if (rc) {
414
			cifs_dbg(FYI, "reconnect error %d\n", rc);
415
			mutex_unlock(&server->srv_mutex);
416
			msleep(3000);
L
Linus Torvalds 已提交
417 418 419
		} else {
			atomic_inc(&tcpSesReconnectCount);
			spin_lock(&GlobalMid_Lock);
420
			if (server->tcpStatus != CifsExiting)
421
				server->tcpStatus = CifsNeedNegotiate;
S
Steve French 已提交
422
			spin_unlock(&GlobalMid_Lock);
423
			mutex_unlock(&server->srv_mutex);
L
Linus Torvalds 已提交
424
		}
425
	} while (server->tcpStatus == CifsNeedReconnect);
426

427 428 429
	if (server->tcpStatus == CifsNeedNegotiate)
		mod_delayed_work(cifsiod_wq, &server->echo, 0);

L
Linus Torvalds 已提交
430 431 432
	return rc;
}

433 434 435 436 437 438
static void
cifs_echo_request(struct work_struct *work)
{
	int rc;
	struct TCP_Server_Info *server = container_of(work,
					struct TCP_Server_Info, echo.work);
439 440 441 442 443 444 445 446 447 448
	unsigned long echo_interval;

	/*
	 * If we need to renegotiate, set echo interval to zero to
	 * immediately call echo service where we can renegotiate.
	 */
	if (server->tcpStatus == CifsNeedNegotiate)
		echo_interval = 0;
	else
		echo_interval = server->echo_interval;
449

450
	/*
451 452
	 * We cannot send an echo if it is disabled.
	 * Also, no need to ping if we got a response recently.
453
	 */
454 455

	if (server->tcpStatus == CifsNeedReconnect ||
456 457
	    server->tcpStatus == CifsExiting ||
	    server->tcpStatus == CifsNew ||
458
	    (server->ops->can_echo && !server->ops->can_echo(server)) ||
S
Steve French 已提交
459
	    time_before(jiffies, server->lstrp + echo_interval - HZ))
460 461
		goto requeue_echo;

462
	rc = server->ops->echo ? server->ops->echo(server) : -ENOSYS;
463
	if (rc)
464 465
		cifs_dbg(FYI, "Unable to send echo request to server: %s\n",
			 server->hostname);
466 467

requeue_echo:
468
	queue_delayed_work(cifsiod_wq, &server->echo, server->echo_interval);
469 470
}

471
static bool
472
allocate_buffers(struct TCP_Server_Info *server)
473
{
474 475 476
	if (!server->bigbuf) {
		server->bigbuf = (char *)cifs_buf_get();
		if (!server->bigbuf) {
477
			cifs_dbg(VFS, "No memory for large SMB response\n");
478 479 480 481
			msleep(3000);
			/* retry will check if exiting */
			return false;
		}
482
	} else if (server->large_buf) {
483
		/* we are reusing a dirty large buf, clear its start */
484
		memset(server->bigbuf, 0, HEADER_SIZE(server));
485 486
	}

487 488 489
	if (!server->smallbuf) {
		server->smallbuf = (char *)cifs_small_buf_get();
		if (!server->smallbuf) {
490
			cifs_dbg(VFS, "No memory for SMB response\n");
491 492 493 494 495 496 497
			msleep(1000);
			/* retry will check if exiting */
			return false;
		}
		/* beginning of smb buffer is cleared in our buf_get */
	} else {
		/* if existing small buf clear beginning */
498
		memset(server->smallbuf, 0, HEADER_SIZE(server));
499 500 501 502 503
	}

	return true;
}

504 505 506
static bool
server_unresponsive(struct TCP_Server_Info *server)
{
507 508 509 510 511 512 513 514 515 516 517
	/*
	 * We need to wait 2 echo intervals to make sure we handle such
	 * situations right:
	 * 1s  client sends a normal SMB request
	 * 2s  client gets a response
	 * 30s echo workqueue job pops, and decides we got a response recently
	 *     and don't need to send another
	 * ...
	 * 65s kernel_recvmsg times out, and we see that we haven't gotten
	 *     a response in >60s.
	 */
518 519
	if ((server->tcpStatus == CifsGood ||
	    server->tcpStatus == CifsNeedNegotiate) &&
S
Steve French 已提交
520 521 522
	    time_after(jiffies, server->lstrp + 2 * server->echo_interval)) {
		cifs_dbg(VFS, "Server %s has not responded in %lu seconds. Reconnecting...\n",
			 server->hostname, (2 * server->echo_interval) / HZ);
523 524 525 526 527 528 529 530
		cifs_reconnect(server);
		wake_up(&server->response_q);
		return true;
	}

	return false;
}

531 532
static int
cifs_readv_from_socket(struct TCP_Server_Info *server, struct msghdr *smb_msg)
533
{
J
Jeff Layton 已提交
534 535
	int length = 0;
	int total_read;
536

537 538
	smb_msg->msg_control = NULL;
	smb_msg->msg_controllen = 0;
539

540
	for (total_read = 0; msg_data_left(smb_msg); total_read += length) {
541 542
		try_to_freeze();

543 544
		if (server_unresponsive(server))
			return -ECONNABORTED;
545

546
		length = sock_recvmsg(server->ssocket, smb_msg, 0);
547

548 549
		if (server->tcpStatus == CifsExiting)
			return -ESHUTDOWN;
550

551
		if (server->tcpStatus == CifsNeedReconnect) {
552
			cifs_reconnect(server);
553 554 555 556 557 558
			return -ECONNABORTED;
		}

		if (length == -ERESTARTSYS ||
		    length == -EAGAIN ||
		    length == -EINTR) {
559 560 561 562 563 564 565
			/*
			 * Minimum sleep to prevent looping, allowing socket
			 * to clear and app threads to set tcpStatus
			 * CifsNeedReconnect if server hung.
			 */
			usleep_range(1000, 2000);
			length = 0;
J
Jeff Layton 已提交
566
			continue;
567 568 569
		}

		if (length <= 0) {
570
			cifs_dbg(FYI, "Received no data or error: %d\n", length);
571
			cifs_reconnect(server);
572
			return -ECONNABORTED;
573 574
		}
	}
J
Jeff Layton 已提交
575
	return total_read;
576 577
}

J
Jeff Layton 已提交
578 579 580
int
cifs_read_from_socket(struct TCP_Server_Info *server, char *buf,
		      unsigned int to_read)
581
{
582 583 584
	struct msghdr smb_msg;
	struct kvec iov = {.iov_base = buf, .iov_len = to_read};
	iov_iter_kvec(&smb_msg.msg_iter, READ | ITER_KVEC, &iov, 1, to_read);
585

586 587
	return cifs_readv_from_socket(server, &smb_msg);
}
588

589 590 591 592 593 594 595 596
int
cifs_read_page_from_socket(struct TCP_Server_Info *server, struct page *page,
		      unsigned int to_read)
{
	struct msghdr smb_msg;
	struct bio_vec bv = {.bv_page = page, .bv_len = to_read};
	iov_iter_bvec(&smb_msg.msg_iter, READ | ITER_BVEC, &bv, 1, to_read);
	return cifs_readv_from_socket(server, &smb_msg);
597 598
}

599
static bool
J
Jeff Layton 已提交
600
is_smb_response(struct TCP_Server_Info *server, unsigned char type)
601 602 603 604 605 606
{
	/*
	 * The first byte big endian of the length field,
	 * is actually not part of the length but the type
	 * with the most common, zero, as regular data.
	 */
J
Jeff Layton 已提交
607 608 609 610 611
	switch (type) {
	case RFC1002_SESSION_MESSAGE:
		/* Regular SMB response */
		return true;
	case RFC1002_SESSION_KEEP_ALIVE:
612
		cifs_dbg(FYI, "RFC 1002 session keep alive\n");
J
Jeff Layton 已提交
613 614
		break;
	case RFC1002_POSITIVE_SESSION_RESPONSE:
615
		cifs_dbg(FYI, "RFC 1002 positive session response\n");
J
Jeff Layton 已提交
616 617
		break;
	case RFC1002_NEGATIVE_SESSION_RESPONSE:
618 619 620 621
		/*
		 * We get this from Windows 98 instead of an error on
		 * SMB negprot response.
		 */
622
		cifs_dbg(FYI, "RFC 1002 negative session response\n");
623 624 625 626 627 628 629 630
		/* give server a second to clean up */
		msleep(1000);
		/*
		 * Always try 445 first on reconnect since we get NACK
		 * on some if we ever connected to port 139 (the NACK
		 * is since we do not begin with RFC1001 session
		 * initialize frame).
		 */
J
Jeff Layton 已提交
631
		cifs_set_port((struct sockaddr *)&server->dstaddr, CIFS_PORT);
632 633
		cifs_reconnect(server);
		wake_up(&server->response_q);
J
Jeff Layton 已提交
634 635
		break;
	default:
636
		cifs_dbg(VFS, "RFC 1002 unknown response type 0x%x\n", type);
637 638 639
		cifs_reconnect(server);
	}

J
Jeff Layton 已提交
640
	return false;
641 642
}

J
Jeff Layton 已提交
643 644
void
dequeue_mid(struct mid_q_entry *mid, bool malformed)
645
{
646
#ifdef CONFIG_CIFS_STATS2
647
	mid->when_received = jiffies;
648
#endif
649 650
	spin_lock(&GlobalMid_Lock);
	if (!malformed)
651
		mid->mid_state = MID_RESPONSE_RECEIVED;
652
	else
653
		mid->mid_state = MID_RESPONSE_MALFORMED;
654
	list_del_init(&mid->qhead);
655
	spin_unlock(&GlobalMid_Lock);
656
}
657

658 659
static void
handle_mid(struct mid_q_entry *mid, struct TCP_Server_Info *server,
660
	   char *buf, int malformed)
661
{
662 663
	if (server->ops->check_trans2 &&
	    server->ops->check_trans2(mid, server, buf, malformed))
664
		return;
665
	mid->resp_buf = buf;
666
	mid->large_buf = server->large_buf;
667 668 669 670 671 672 673 674
	/* Was previous buf put in mpx struct for multi-rsp? */
	if (!mid->multiRsp) {
		/* smb buffer will be freed by user thread */
		if (server->large_buf)
			server->bigbuf = NULL;
		else
			server->smallbuf = NULL;
	}
675
	dequeue_mid(mid, malformed);
676 677
}

678 679 680 681 682 683 684 685 686 687 688 689 690 691
static void clean_demultiplex_info(struct TCP_Server_Info *server)
{
	int length;

	/* take it off the list, if it's not already */
	spin_lock(&cifs_tcp_ses_lock);
	list_del_init(&server->tcp_ses_list);
	spin_unlock(&cifs_tcp_ses_lock);

	spin_lock(&GlobalMid_Lock);
	server->tcpStatus = CifsExiting;
	spin_unlock(&GlobalMid_Lock);
	wake_up_all(&server->response_q);

692
	/* check if we have blocked requests that need to free */
P
Pavel Shilovsky 已提交
693
	spin_lock(&server->req_lock);
694 695
	if (server->credits <= 0)
		server->credits = 1;
P
Pavel Shilovsky 已提交
696
	spin_unlock(&server->req_lock);
697 698 699 700 701 702 703 704 705 706
	/*
	 * Although there should not be any requests blocked on this queue it
	 * can not hurt to be paranoid and try to wake up requests that may
	 * haven been blocked when more than 50 at time were on the wire to the
	 * same server - they now will see the session is in exit state and get
	 * out of SendReceive.
	 */
	wake_up_all(&server->request_q);
	/* give those requests time to exit */
	msleep(125);
707 708 709 710
	if (cifs_rdma_enabled(server) && server->smbd_conn) {
		smbd_destroy(server->smbd_conn);
		server->smbd_conn = NULL;
	}
711 712 713 714 715 716 717 718 719 720 721 722 723 724
	if (server->ssocket) {
		sock_release(server->ssocket);
		server->ssocket = NULL;
	}

	if (!list_empty(&server->pending_mid_q)) {
		struct list_head dispose_list;
		struct mid_q_entry *mid_entry;
		struct list_head *tmp, *tmp2;

		INIT_LIST_HEAD(&dispose_list);
		spin_lock(&GlobalMid_Lock);
		list_for_each_safe(tmp, tmp2, &server->pending_mid_q) {
			mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
725
			cifs_dbg(FYI, "Clearing mid 0x%llx\n", mid_entry->mid);
726
			mid_entry->mid_state = MID_SHUTDOWN;
727 728 729 730 731 732 733
			list_move(&mid_entry->qhead, &dispose_list);
		}
		spin_unlock(&GlobalMid_Lock);

		/* now walk dispose list and issue callbacks */
		list_for_each_safe(tmp, tmp2, &dispose_list) {
			mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
734
			cifs_dbg(FYI, "Callback mid 0x%llx\n", mid_entry->mid);
735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750
			list_del_init(&mid_entry->qhead);
			mid_entry->callback(mid_entry);
		}
		/* 1/8th of sec is more than enough time for them to exit */
		msleep(125);
	}

	if (!list_empty(&server->pending_mid_q)) {
		/*
		 * mpx threads have not exited yet give them at least the smb
		 * send timeout time for long ops.
		 *
		 * Due to delays on oplock break requests, we need to wait at
		 * least 45 seconds before giving up on a request getting a
		 * response and going ahead and killing cifsd.
		 */
751
		cifs_dbg(FYI, "Wait for exit from demultiplex thread\n");
752 753 754 755 756 757 758 759 760 761 762 763
		msleep(46000);
		/*
		 * If threads still have not exited they are probably never
		 * coming home not much else we can do but free the memory.
		 */
	}

	kfree(server->hostname);
	kfree(server);

	length = atomic_dec_return(&tcpSesAllocCount);
	if (length > 0)
764
		mempool_resize(cifs_req_poolp, length + cifs_min_rcv);
765 766
}

767 768 769 770 771
static int
standard_receive3(struct TCP_Server_Info *server, struct mid_q_entry *mid)
{
	int length;
	char *buf = server->smallbuf;
772
	unsigned int pdu_length = get_rfc1002_length(buf);
773 774

	/* make sure this will fit in a large buffer */
775
	if (pdu_length > CIFSMaxBufSize + MAX_HEADER_SIZE(server) - 4) {
776
		cifs_dbg(VFS, "SMB response too long (%u bytes)\n", pdu_length);
777 778
		cifs_reconnect(server);
		wake_up(&server->response_q);
779
		return -ECONNABORTED;
780 781 782 783 784
	}

	/* switch to large buffer if too big for a small one */
	if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) {
		server->large_buf = true;
785
		memcpy(server->bigbuf, buf, server->total_read);
786 787 788 789
		buf = server->bigbuf;
	}

	/* now read the rest */
790 791
	length = cifs_read_from_socket(server, buf + HEADER_SIZE(server) - 1,
				pdu_length - HEADER_SIZE(server) + 1 + 4);
792 793 794 795
	if (length < 0)
		return length;
	server->total_read += length;

796
	dump_smb(buf, server->total_read);
797

798 799 800 801 802 803 804 805 806
	return cifs_handle_standard(server, mid);
}

int
cifs_handle_standard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
{
	char *buf = server->large_buf ? server->bigbuf : server->smallbuf;
	int length;

807 808 809 810 811 812 813 814 815
	/*
	 * We know that we received enough to get to the MID as we
	 * checked the pdu_length earlier. Now check to see
	 * if the rest of the header is OK. We borrow the length
	 * var for the rest of the loop to avoid a new stack var.
	 *
	 * 48 bytes is enough to display the header and a little bit
	 * into the payload for debugging purposes.
	 */
816
	length = server->ops->check_message(buf, server->total_read, server);
817 818 819 820
	if (length != 0)
		cifs_dump_mem("Bad SMB: ", buf,
			min_t(unsigned int, server->total_read, 48));

821 822 823 824 825 826 827
	if (server->ops->is_session_expired &&
	    server->ops->is_session_expired(buf)) {
		cifs_reconnect(server);
		wake_up(&server->response_q);
		return -1;
	}

P
Pavel Shilovsky 已提交
828 829 830 831
	if (server->ops->is_status_pending &&
	    server->ops->is_status_pending(buf, server, length))
		return -1;

832 833
	if (!mid)
		return length;
834

835
	handle_mid(mid, server, buf, length);
836
	return 0;
837 838
}

L
Linus Torvalds 已提交
839
static int
840
cifs_demultiplex_thread(void *p)
L
Linus Torvalds 已提交
841 842
{
	int length;
843
	struct TCP_Server_Info *server = p;
844 845
	unsigned int pdu_length;
	char *buf = NULL;
846
	struct task_struct *task_to_wake = NULL;
L
Linus Torvalds 已提交
847 848 849
	struct mid_q_entry *mid_entry;

	current->flags |= PF_MEMALLOC;
850
	cifs_dbg(FYI, "Demultiplex PID: %d\n", task_pid_nr(current));
851 852 853

	length = atomic_inc_return(&tcpSesAllocCount);
	if (length > 1)
854
		mempool_resize(cifs_req_poolp, length + cifs_min_rcv);
L
Linus Torvalds 已提交
855

856
	set_freezable();
857
	while (server->tcpStatus != CifsExiting) {
858 859
		if (try_to_freeze())
			continue;
860

861
		if (!allocate_buffers(server))
862
			continue;
863

864 865
		server->large_buf = false;
		buf = server->smallbuf;
866
		pdu_length = 4; /* enough to get RFC1001 header */
867

J
Jeff Layton 已提交
868
		length = cifs_read_from_socket(server, buf, pdu_length);
J
Jeff Layton 已提交
869
		if (length < 0)
L
Linus Torvalds 已提交
870
			continue;
871
		server->total_read = length;
L
Linus Torvalds 已提交
872

873 874 875 876
		/*
		 * The right amount was read from socket - 4 bytes,
		 * so we can now interpret the length field.
		 */
877
		pdu_length = get_rfc1002_length(buf);
878

879
		cifs_dbg(FYI, "RFC1002 header 0x%x\n", pdu_length);
J
Jeff Layton 已提交
880
		if (!is_smb_response(server, buf[0]))
S
Steve French 已提交
881
			continue;
882

883
		/* make sure we have enough to get to the MID */
884
		if (pdu_length < HEADER_SIZE(server) - 1 - 4) {
885 886
			cifs_dbg(VFS, "SMB response too short (%u bytes)\n",
				 pdu_length);
887 888 889
			cifs_reconnect(server);
			wake_up(&server->response_q);
			continue;
890
		}
891

892
		/* read down to the MID */
J
Jeff Layton 已提交
893
		length = cifs_read_from_socket(server, buf + 4,
894
					       HEADER_SIZE(server) - 1 - 4);
895
		if (length < 0)
896
			continue;
897
		server->total_read += length;
L
Linus Torvalds 已提交
898

899 900 901 902 903 904 905
		if (server->ops->is_transform_hdr &&
		    server->ops->receive_transform &&
		    server->ops->is_transform_hdr(buf)) {
			length = server->ops->receive_transform(server,
								&mid_entry);
		} else {
			mid_entry = server->ops->find_mid(server, buf);
906

907 908 909 910 911
			if (!mid_entry || !mid_entry->receive)
				length = standard_receive3(server, mid_entry);
			else
				length = mid_entry->receive(server, mid_entry);
		}
912

913
		if (length < 0)
J
Jeff Layton 已提交
914
			continue;
L
Linus Torvalds 已提交
915

916
		if (server->large_buf)
917
			buf = server->bigbuf;
918 919

		server->lstrp = jiffies;
920
		if (mid_entry != NULL) {
S
Sachin Prabhu 已提交
921 922 923 924 925 926 927
			if ((mid_entry->mid_flags & MID_WAIT_CANCELLED) &&
			     mid_entry->mid_state == MID_RESPONSE_RECEIVED &&
					server->ops->handle_cancelled_mid)
				server->ops->handle_cancelled_mid(
							mid_entry->resp_buf,
							server);

928 929
			if (!mid_entry->multiRsp || mid_entry->multiEnd)
				mid_entry->callback(mid_entry);
S
Sachin Prabhu 已提交
930 931 932 933
		} else if (server->ops->is_oplock_break &&
			   server->ops->is_oplock_break(buf, server)) {
			cifs_dbg(FYI, "Received oplock break\n");
		} else {
934 935
			cifs_dbg(VFS, "No task to wake, unknown frame received! NumMids %d\n",
				 atomic_read(&midCount));
936 937
			cifs_dump_mem("Received Data is: ", buf,
				      HEADER_SIZE(server));
938
#ifdef CONFIG_CIFS_DEBUG2
939 940
			if (server->ops->dump_detail)
				server->ops->dump_detail(buf);
941 942
			cifs_dump_mids(server);
#endif /* CIFS_DEBUG2 */
943

944 945 946
		}
	} /* end while !EXITING */

947
	/* buffer usually freed in free_mid - need to free it here on exit */
948 949 950
	cifs_buf_release(server->bigbuf);
	if (server->smallbuf) /* no sense logging a debug message if NULL */
		cifs_small_buf_release(server->smallbuf);
L
Linus Torvalds 已提交
951

952
	task_to_wake = xchg(&server->tsk, NULL);
953
	clean_demultiplex_info(server);
954 955 956 957 958 959 960 961 962 963 964

	/* if server->tsk was NULL then wait for a signal before exiting */
	if (!task_to_wake) {
		set_current_state(TASK_INTERRUPTIBLE);
		while (!signal_pending(current)) {
			schedule();
			set_current_state(TASK_INTERRUPTIBLE);
		}
		set_current_state(TASK_RUNNING);
	}

965
	module_put_and_exit(0);
L
Linus Torvalds 已提交
966 967
}

968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995
/* extract the host portion of the UNC string */
static char *
extract_hostname(const char *unc)
{
	const char *src;
	char *dst, *delim;
	unsigned int len;

	/* skip double chars at beginning of string */
	/* BB: check validity of these bytes? */
	src = unc + 2;

	/* delimiter between hostname and sharename is always '\\' now */
	delim = strchr(src, '\\');
	if (!delim)
		return ERR_PTR(-EINVAL);

	len = delim - src;
	dst = kmalloc((len + 1), GFP_KERNEL);
	if (dst == NULL)
		return ERR_PTR(-ENOMEM);

	memcpy(dst, src, len);
	dst[len] = '\0';

	return dst;
}

996 997 998 999 1000 1001 1002 1003
static int get_option_ul(substring_t args[], unsigned long *option)
{
	int rc;
	char *string;

	string = match_strdup(args);
	if (string == NULL)
		return -ENOMEM;
1004
	rc = kstrtoul(string, 0, option);
1005 1006 1007 1008 1009
	kfree(string);

	return rc;
}

1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044
static int get_option_uid(substring_t args[], kuid_t *result)
{
	unsigned long value;
	kuid_t uid;
	int rc;

	rc = get_option_ul(args, &value);
	if (rc)
		return rc;

	uid = make_kuid(current_user_ns(), value);
	if (!uid_valid(uid))
		return -EINVAL;

	*result = uid;
	return 0;
}

static int get_option_gid(substring_t args[], kgid_t *result)
{
	unsigned long value;
	kgid_t gid;
	int rc;

	rc = get_option_ul(args, &value);
	if (rc)
		return rc;

	gid = make_kgid(current_user_ns(), value);
	if (!gid_valid(gid))
		return -EINVAL;

	*result = gid;
	return 0;
}
1045 1046 1047 1048 1049 1050 1051

static int cifs_parse_security_flavors(char *value,
				       struct smb_vol *vol)
{

	substring_t args[MAX_OPT_ARGS];

1052 1053 1054 1055 1056 1057 1058
	/*
	 * With mount options, the last one should win. Reset any existing
	 * settings back to default.
	 */
	vol->sectype = Unspecified;
	vol->sign = false;

1059
	switch (match_token(value, cifs_secflavor_tokens, args)) {
1060 1061 1062 1063 1064 1065
	case Opt_sec_krb5p:
		cifs_dbg(VFS, "sec=krb5p is not supported!\n");
		return 1;
	case Opt_sec_krb5i:
		vol->sign = true;
		/* Fallthrough */
1066
	case Opt_sec_krb5:
1067
		vol->sectype = Kerberos;
1068
		break;
1069
	case Opt_sec_ntlmsspi:
1070
		vol->sign = true;
1071
		/* Fallthrough */
1072
	case Opt_sec_ntlmssp:
1073
		vol->sectype = RawNTLMSSP;
1074
		break;
1075
	case Opt_sec_ntlmi:
1076
		vol->sign = true;
1077
		/* Fallthrough */
1078
	case Opt_ntlm:
1079
		vol->sectype = NTLM;
1080
		break;
1081
	case Opt_sec_ntlmv2i:
1082
		vol->sign = true;
1083
		/* Fallthrough */
1084
	case Opt_sec_ntlmv2:
1085
		vol->sectype = NTLMv2;
1086 1087 1088
		break;
#ifdef CONFIG_CIFS_WEAK_PW_HASH
	case Opt_sec_lanman:
1089
		vol->sectype = LANMAN;
1090 1091 1092 1093 1094 1095
		break;
#endif
	case Opt_sec_none:
		vol->nullauth = 1;
		break;
	default:
1096
		cifs_dbg(VFS, "bad security option: %s\n", value);
1097 1098 1099 1100 1101 1102
		return 1;
	}

	return 0;
}

1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121
static int
cifs_parse_cache_flavor(char *value, struct smb_vol *vol)
{
	substring_t args[MAX_OPT_ARGS];

	switch (match_token(value, cifs_cacheflavor_tokens, args)) {
	case Opt_cache_loose:
		vol->direct_io = false;
		vol->strict_io = false;
		break;
	case Opt_cache_strict:
		vol->direct_io = false;
		vol->strict_io = true;
		break;
	case Opt_cache_none:
		vol->direct_io = true;
		vol->strict_io = false;
		break;
	default:
1122
		cifs_dbg(VFS, "bad cache= option: %s\n", value);
1123 1124 1125 1126 1127
		return 1;
	}
	return 0;
}

1128 1129 1130 1131 1132 1133 1134 1135 1136 1137
static int
cifs_parse_smb_version(char *value, struct smb_vol *vol)
{
	substring_t args[MAX_OPT_ARGS];

	switch (match_token(value, cifs_smb_version_tokens, args)) {
	case Smb_1:
		vol->ops = &smb1_operations;
		vol->vals = &smb1_values;
		break;
S
Steve French 已提交
1138
	case Smb_20:
1139
		vol->ops = &smb20_operations;
S
Steve French 已提交
1140 1141
		vol->vals = &smb20_values;
		break;
1142 1143 1144 1145
	case Smb_21:
		vol->ops = &smb21_operations;
		vol->vals = &smb21_values;
		break;
1146
	case Smb_30:
1147
		vol->ops = &smb30_operations;
1148 1149
		vol->vals = &smb30_values;
		break;
S
Steve French 已提交
1150 1151 1152 1153
	case Smb_302:
		vol->ops = &smb30_operations; /* currently identical with 3.0 */
		vol->vals = &smb302_values;
		break;
1154 1155
#ifdef CONFIG_CIFS_SMB311
	case Smb_311:
1156
		vol->ops = &smb311_operations;
1157 1158 1159
		vol->vals = &smb311_values;
		break;
#endif /* SMB311 */
1160 1161 1162 1163 1164 1165 1166 1167
	case Smb_3any:
		vol->ops = &smb30_operations; /* currently identical with 3.0 */
		vol->vals = &smb3any_values;
		break;
	case Smb_default:
		vol->ops = &smb30_operations; /* currently identical with 3.0 */
		vol->vals = &smbdefault_values;
		break;
1168
	default:
1169
		cifs_dbg(VFS, "Unknown vers= option specified: %s\n", value);
1170 1171 1172 1173 1174
		return 1;
	}
	return 0;
}

1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209
/*
 * Parse a devname into substrings and populate the vol->UNC and vol->prepath
 * fields with the result. Returns 0 on success and an error otherwise.
 */
static int
cifs_parse_devname(const char *devname, struct smb_vol *vol)
{
	char *pos;
	const char *delims = "/\\";
	size_t len;

	/* make sure we have a valid UNC double delimiter prefix */
	len = strspn(devname, delims);
	if (len != 2)
		return -EINVAL;

	/* find delimiter between host and sharename */
	pos = strpbrk(devname + 2, delims);
	if (!pos)
		return -EINVAL;

	/* skip past delimiter */
	++pos;

	/* now go until next delimiter or end of string */
	len = strcspn(pos, delims);

	/* move "pos" up to delimiter or NULL */
	pos += len;
	vol->UNC = kstrndup(devname, pos - devname, GFP_KERNEL);
	if (!vol->UNC)
		return -ENOMEM;

	convert_delimiter(vol->UNC, '\\');

1210 1211 1212 1213 1214 1215
	/* skip any delimiter */
	if (*pos == '/' || *pos == '\\')
		pos++;

	/* If pos is NULL then no prepath */
	if (!*pos)
1216 1217 1218 1219 1220 1221 1222 1223 1224
		return 0;

	vol->prepath = kstrdup(pos, GFP_KERNEL);
	if (!vol->prepath)
		return -ENOMEM;

	return 0;
}

L
Linus Torvalds 已提交
1225
static int
1226
cifs_parse_mount_options(const char *mountdata, const char *devname,
1227
			 struct smb_vol *vol)
L
Linus Torvalds 已提交
1228
{
1229
	char *data, *end;
1230
	char *mountdata_copy = NULL, *options;
L
Linus Torvalds 已提交
1231 1232
	unsigned int  temp_len, i, j;
	char separator[2];
1233 1234 1235 1236
	short int override_uid = -1;
	short int override_gid = -1;
	bool uid_specified = false;
	bool gid_specified = false;
1237 1238
	bool sloppy = false;
	char *invalid = NULL;
J
Jeff Layton 已提交
1239
	char *nodename = utsname()->nodename;
1240 1241 1242
	char *string = NULL;
	char *tmp_end, *value;
	char delim;
1243
	bool got_ip = false;
1244
	bool got_version = false;
1245 1246
	unsigned short port = 0;
	struct sockaddr *dstaddr = (struct sockaddr *)&vol->dstaddr;
L
Linus Torvalds 已提交
1247 1248

	separator[0] = ',';
1249
	separator[1] = 0;
1250
	delim = separator[0];
L
Linus Torvalds 已提交
1251

1252 1253 1254
	/* ensure we always start with zeroed-out smb_vol */
	memset(vol, 0, sizeof(*vol));

J
Jeff Layton 已提交
1255 1256 1257 1258 1259
	/*
	 * does not have to be perfect mapping since field is
	 * informational, only used for servers that do not support
	 * port 445 and it can be overridden at mount time
	 */
1260 1261
	memset(vol->source_rfc1001_name, 0x20, RFC1001_NAME_LEN);
	for (i = 0; i < strnlen(nodename, RFC1001_NAME_LEN); i++)
J
Jeff Layton 已提交
1262 1263
		vol->source_rfc1001_name[i] = toupper(nodename[i]);

1264
	vol->source_rfc1001_name[RFC1001_NAME_LEN] = 0;
1265 1266 1267
	/* null target name indicates to use *SMBSERVR default called name
	   if we end up sending RFC1001 session initialize */
	vol->target_rfc1001_name[0] = 0;
1268 1269
	vol->cred_uid = current_uid();
	vol->linux_uid = current_uid();
1270
	vol->linux_gid = current_gid();
1271

1272 1273 1274 1275 1276 1277 1278 1279
	/*
	 * default to SFM style remapping of seven reserved characters
	 * unless user overrides it or we negotiate CIFS POSIX where
	 * it is unnecessary.  Can not simultaneously use more than one mapping
	 * since then readdir could list files that open could not open
	 */
	vol->remap = true;

1280 1281
	/* default to only allowing write access to owner of the mount */
	vol->dir_mode = vol->file_mode = S_IRUGO | S_IXUGO | S_IWUSR;
L
Linus Torvalds 已提交
1282 1283

	/* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */
1284 1285
	/* default is always to request posix paths. */
	vol->posix_paths = 1;
1286 1287
	/* default to using server inode numbers where available */
	vol->server_ino = 1;
1288

1289 1290 1291
	/* default is to use strict cifs caching semantics */
	vol->strict_io = true;

1292 1293
	vol->actimeo = CIFS_DEF_ACTIMEO;

1294 1295 1296
	/* offer SMB2.1 and later (SMB3 etc). Secure and widely accepted */
	vol->ops = &smb30_operations;
	vol->vals = &smbdefault_values;
1297

R
Rabin Vincent 已提交
1298 1299
	vol->echo_interval = SMB_ECHO_INTERVAL_DEFAULT;

1300 1301 1302 1303 1304 1305
	if (!mountdata)
		goto cifs_parse_mount_err;

	mountdata_copy = kstrndup(mountdata, PAGE_SIZE, GFP_KERNEL);
	if (!mountdata_copy)
		goto cifs_parse_mount_err;
L
Linus Torvalds 已提交
1306

1307
	options = mountdata_copy;
1308
	end = options + strlen(options);
1309

1310
	if (strncmp(options, "sep=", 4) == 0) {
S
Steve French 已提交
1311
		if (options[4] != 0) {
L
Linus Torvalds 已提交
1312 1313 1314
			separator[0] = options[4];
			options += 5;
		} else {
1315
			cifs_dbg(FYI, "Null separator not allowed\n");
L
Linus Torvalds 已提交
1316 1317
		}
	}
1318 1319
	vol->backupuid_specified = false; /* no backup intent for a user */
	vol->backupgid_specified = false; /* no backup intent for a group */
1320

1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332
	switch (cifs_parse_devname(devname, vol)) {
	case 0:
		break;
	case -ENOMEM:
		cifs_dbg(VFS, "Unable to allocate memory for devname.\n");
		goto cifs_parse_mount_err;
	case -EINVAL:
		cifs_dbg(VFS, "Malformed UNC in devname.\n");
		goto cifs_parse_mount_err;
	default:
		cifs_dbg(VFS, "Unknown error parsing devname.\n");
		goto cifs_parse_mount_err;
1333 1334
	}

L
Linus Torvalds 已提交
1335
	while ((data = strsep(&options, separator)) != NULL) {
1336 1337 1338 1339
		substring_t args[MAX_OPT_ARGS];
		unsigned long option;
		int token;

L
Linus Torvalds 已提交
1340 1341 1342
		if (!*data)
			continue;

1343 1344 1345 1346 1347 1348 1349 1350 1351 1352
		token = match_token(data, cifs_mount_option_tokens, args);

		switch (token) {

		/* Ingnore the following */
		case Opt_ignore:
			break;

		/* Boolean values */
		case Opt_user_xattr:
L
Linus Torvalds 已提交
1353
			vol->no_xattr = 0;
1354 1355
			break;
		case Opt_nouser_xattr:
L
Linus Torvalds 已提交
1356
			vol->no_xattr = 1;
1357 1358
			break;
		case Opt_forceuid:
1359
			override_uid = 1;
1360 1361
			break;
		case Opt_noforceuid:
1362
			override_uid = 0;
1363
			break;
J
Jeff Layton 已提交
1364 1365 1366 1367 1368 1369
		case Opt_forcegid:
			override_gid = 1;
			break;
		case Opt_noforcegid:
			override_gid = 0;
			break;
1370
		case Opt_noblocksend:
1371
			vol->noblocksnd = 1;
1372 1373
			break;
		case Opt_noautotune:
1374
			vol->noautotune = 1;
1375 1376
			break;
		case Opt_hard:
L
Linus Torvalds 已提交
1377
			vol->retry = 1;
1378 1379
			break;
		case Opt_soft:
L
Linus Torvalds 已提交
1380
			vol->retry = 0;
1381 1382
			break;
		case Opt_perm:
L
Linus Torvalds 已提交
1383
			vol->noperm = 0;
1384 1385
			break;
		case Opt_noperm:
L
Linus Torvalds 已提交
1386
			vol->noperm = 1;
1387 1388
			break;
		case Opt_mapchars:
1389 1390
			vol->sfu_remap = true;
			vol->remap = false; /* disable SFM mapping */
1391 1392
			break;
		case Opt_nomapchars:
1393 1394 1395 1396 1397 1398 1399 1400
			vol->sfu_remap = false;
			break;
		case Opt_mapposix:
			vol->remap = true;
			vol->sfu_remap = false; /* disable SFU mapping */
			break;
		case Opt_nomapposix:
			vol->remap = false;
1401 1402
			break;
		case Opt_sfu:
1403
			vol->sfu_emul = 1;
1404 1405
			break;
		case Opt_nosfu:
1406
			vol->sfu_emul = 0;
1407 1408
			break;
		case Opt_nodfs:
S
Steve French 已提交
1409
			vol->nodfs = 1;
1410 1411
			break;
		case Opt_posixpaths:
1412
			vol->posix_paths = 1;
1413 1414
			break;
		case Opt_noposixpaths:
1415
			vol->posix_paths = 0;
1416 1417
			break;
		case Opt_nounix:
1418
			vol->no_linux_ext = 1;
1419 1420
			break;
		case Opt_nocase:
1421
			vol->nocase = 1;
1422 1423
			break;
		case Opt_brl:
1424
			vol->nobrl =  0;
1425 1426
			break;
		case Opt_nobrl:
1427
			vol->nobrl =  1;
1428 1429
			/*
			 * turn off mandatory locking in mode
1430
			 * if remote locking is turned off since the
1431 1432
			 * local vfs will do advisory
			 */
1433 1434
			if (vol->file_mode ==
				(S_IALLUGO & ~(S_ISUID | S_IXGRP)))
1435
				vol->file_mode = S_IALLUGO;
1436 1437
			break;
		case Opt_forcemandatorylock:
1438
			vol->mand_lock = 1;
1439 1440
			break;
		case Opt_setuids:
L
Linus Torvalds 已提交
1441
			vol->setuids = 1;
1442 1443
			break;
		case Opt_nosetuids:
L
Linus Torvalds 已提交
1444
			vol->setuids = 0;
1445
			break;
1446 1447 1448
		case Opt_setuidfromacl:
			vol->setuidfromacl = 1;
			break;
1449
		case Opt_dynperm:
1450
			vol->dynperm = true;
1451 1452
			break;
		case Opt_nodynperm:
1453
			vol->dynperm = false;
1454 1455
			break;
		case Opt_nohard:
L
Linus Torvalds 已提交
1456
			vol->retry = 0;
1457 1458
			break;
		case Opt_nosoft:
L
Linus Torvalds 已提交
1459
			vol->retry = 1;
1460 1461
			break;
		case Opt_nointr:
L
Linus Torvalds 已提交
1462
			vol->intr = 0;
1463 1464
			break;
		case Opt_intr:
L
Linus Torvalds 已提交
1465
			vol->intr = 1;
1466 1467
			break;
		case Opt_nostrictsync:
1468
			vol->nostrictsync = 1;
1469 1470
			break;
		case Opt_strictsync:
1471
			vol->nostrictsync = 0;
1472 1473
			break;
		case Opt_serverino:
L
Linus Torvalds 已提交
1474
			vol->server_ino = 1;
1475 1476
			break;
		case Opt_noserverino:
L
Linus Torvalds 已提交
1477
			vol->server_ino = 0;
1478 1479
			break;
		case Opt_rwpidforward:
1480
			vol->rwpidforward = 1;
1481 1482
			break;
		case Opt_cifsacl:
1483
			vol->cifs_acl = 1;
1484 1485
			break;
		case Opt_nocifsacl:
1486
			vol->cifs_acl = 0;
1487 1488
			break;
		case Opt_acl:
L
Linus Torvalds 已提交
1489
			vol->no_psx_acl = 0;
1490 1491
			break;
		case Opt_noacl:
L
Linus Torvalds 已提交
1492
			vol->no_psx_acl = 1;
1493 1494
			break;
		case Opt_locallease:
S
Steve French 已提交
1495
			vol->local_lease = 1;
1496 1497
			break;
		case Opt_sign:
1498
			vol->sign = true;
1499 1500
			break;
		case Opt_seal:
1501
			/* we do not do the following in secFlags because seal
1502 1503 1504 1505
			 * is a per tree connection (mount) not a per socket
			 * or per-smb connection option in the protocol
			 * vol->secFlg |= CIFSSEC_MUST_SEAL;
			 */
1506
			vol->seal = 1;
1507 1508
			break;
		case Opt_noac:
1509
			pr_warn("CIFS: Mount option noac not supported. Instead set /proc/fs/cifs/LookupCacheEnabled to 0\n");
1510 1511
			break;
		case Opt_fsc:
1512
#ifndef CONFIG_CIFS_FSCACHE
1513
			cifs_dbg(VFS, "FS-Cache support needs CONFIG_CIFS_FSCACHE kernel config option set\n");
1514
			goto cifs_parse_mount_err;
1515
#endif
1516
			vol->fsc = true;
1517 1518
			break;
		case Opt_mfsymlinks:
1519
			vol->mfsymlinks = true;
1520 1521
			break;
		case Opt_multiuser:
J
Jeff Layton 已提交
1522
			vol->multiuser = true;
1523
			break;
1524 1525 1526
		case Opt_sloppy:
			sloppy = true;
			break;
1527 1528 1529
		case Opt_nosharesock:
			vol->nosharesock = true;
			break;
1530 1531 1532 1533 1534 1535 1536 1537 1538 1539
		case Opt_nopersistent:
			vol->nopersistent = true;
			if (vol->persistent) {
				cifs_dbg(VFS,
				  "persistenthandles mount options conflict\n");
				goto cifs_parse_mount_err;
			}
			break;
		case Opt_persistent:
			vol->persistent = true;
S
Steve French 已提交
1540
			if ((vol->nopersistent) || (vol->resilient)) {
1541 1542 1543 1544 1545
				cifs_dbg(VFS,
				  "persistenthandles mount options conflict\n");
				goto cifs_parse_mount_err;
			}
			break;
S
Steve French 已提交
1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556
		case Opt_resilient:
			vol->resilient = true;
			if (vol->persistent) {
				cifs_dbg(VFS,
				  "persistenthandles mount options conflict\n");
				goto cifs_parse_mount_err;
			}
			break;
		case Opt_noresilient:
			vol->resilient = false; /* already the default */
			break;
1557 1558 1559
		case Opt_domainauto:
			vol->domainauto = true;
			break;
L
Long Li 已提交
1560 1561 1562
		case Opt_rdma:
			vol->rdma = true;
			break;
1563 1564 1565

		/* Numeric Values */
		case Opt_backupuid:
1566
			if (get_option_uid(args, &vol->backupuid)) {
1567 1568
				cifs_dbg(VFS, "%s: Invalid backupuid value\n",
					 __func__);
1569 1570 1571
				goto cifs_parse_mount_err;
			}
			vol->backupuid_specified = true;
1572 1573
			break;
		case Opt_backupgid:
1574
			if (get_option_gid(args, &vol->backupgid)) {
1575 1576
				cifs_dbg(VFS, "%s: Invalid backupgid value\n",
					 __func__);
1577 1578 1579
				goto cifs_parse_mount_err;
			}
			vol->backupgid_specified = true;
1580 1581
			break;
		case Opt_uid:
1582
			if (get_option_uid(args, &vol->linux_uid)) {
1583 1584
				cifs_dbg(VFS, "%s: Invalid uid value\n",
					 __func__);
1585 1586 1587 1588 1589
				goto cifs_parse_mount_err;
			}
			uid_specified = true;
			break;
		case Opt_cruid:
1590
			if (get_option_uid(args, &vol->cred_uid)) {
1591 1592
				cifs_dbg(VFS, "%s: Invalid cruid value\n",
					 __func__);
1593 1594 1595 1596
				goto cifs_parse_mount_err;
			}
			break;
		case Opt_gid:
1597
			if (get_option_gid(args, &vol->linux_gid)) {
1598 1599
				cifs_dbg(VFS, "%s: Invalid gid value\n",
					 __func__);
1600 1601 1602 1603 1604 1605
				goto cifs_parse_mount_err;
			}
			gid_specified = true;
			break;
		case Opt_file_mode:
			if (get_option_ul(args, &option)) {
1606 1607
				cifs_dbg(VFS, "%s: Invalid file_mode value\n",
					 __func__);
1608 1609 1610 1611 1612 1613
				goto cifs_parse_mount_err;
			}
			vol->file_mode = option;
			break;
		case Opt_dirmode:
			if (get_option_ul(args, &option)) {
1614 1615
				cifs_dbg(VFS, "%s: Invalid dir_mode value\n",
					 __func__);
1616 1617 1618 1619 1620
				goto cifs_parse_mount_err;
			}
			vol->dir_mode = option;
			break;
		case Opt_port:
1621 1622
			if (get_option_ul(args, &option) ||
			    option > USHRT_MAX) {
1623 1624
				cifs_dbg(VFS, "%s: Invalid port value\n",
					 __func__);
1625 1626
				goto cifs_parse_mount_err;
			}
1627
			port = (unsigned short)option;
1628 1629 1630
			break;
		case Opt_rsize:
			if (get_option_ul(args, &option)) {
1631 1632
				cifs_dbg(VFS, "%s: Invalid rsize value\n",
					 __func__);
1633
				goto cifs_parse_mount_err;
1634 1635 1636 1637 1638
			}
			vol->rsize = option;
			break;
		case Opt_wsize:
			if (get_option_ul(args, &option)) {
1639 1640
				cifs_dbg(VFS, "%s: Invalid wsize value\n",
					 __func__);
1641 1642 1643 1644 1645 1646
				goto cifs_parse_mount_err;
			}
			vol->wsize = option;
			break;
		case Opt_actimeo:
			if (get_option_ul(args, &option)) {
1647 1648
				cifs_dbg(VFS, "%s: Invalid actimeo value\n",
					 __func__);
1649 1650 1651 1652
				goto cifs_parse_mount_err;
			}
			vol->actimeo = HZ * option;
			if (vol->actimeo > CIFS_MAX_ACTIMEO) {
1653
				cifs_dbg(VFS, "attribute cache timeout too large\n");
1654 1655 1656
				goto cifs_parse_mount_err;
			}
			break;
S
Steve French 已提交
1657 1658 1659 1660 1661 1662 1663 1664
		case Opt_echo_interval:
			if (get_option_ul(args, &option)) {
				cifs_dbg(VFS, "%s: Invalid echo interval value\n",
					 __func__);
				goto cifs_parse_mount_err;
			}
			vol->echo_interval = option;
			break;
1665 1666 1667 1668 1669 1670 1671 1672
		case Opt_snapshot:
			if (get_option_ul(args, &option)) {
				cifs_dbg(VFS, "%s: Invalid snapshot time\n",
					 __func__);
				goto cifs_parse_mount_err;
			}
			vol->snapshot_time = option;
			break;
1673 1674 1675 1676 1677 1678 1679 1680 1681
		case Opt_max_credits:
			if (get_option_ul(args, &option) || (option < 20) ||
			    (option > 60000)) {
				cifs_dbg(VFS, "%s: Invalid max_credits value\n",
					 __func__);
				goto cifs_parse_mount_err;
			}
			vol->max_credits = option;
			break;
1682 1683 1684

		/* String Arguments */

1685 1686 1687 1688 1689
		case Opt_blank_user:
			/* null user, ie. anonymous authentication */
			vol->nullauth = 1;
			vol->username = NULL;
			break;
1690 1691 1692 1693 1694
		case Opt_user:
			string = match_strdup(args);
			if (string == NULL)
				goto out_nomem;

1695 1696
			if (strnlen(string, CIFS_MAX_USERNAME_LEN) >
							CIFS_MAX_USERNAME_LEN) {
1697
				pr_warn("CIFS: username too long\n");
1698 1699
				goto cifs_parse_mount_err;
			}
1700 1701

			kfree(vol->username);
1702
			vol->username = kstrdup(string, GFP_KERNEL);
1703
			if (!vol->username)
1704 1705 1706 1707 1708 1709 1710 1711
				goto cifs_parse_mount_err;
			break;
		case Opt_blank_pass:
			/* passwords have to be handled differently
			 * to allow the character used for deliminator
			 * to be passed within them
			 */

1712 1713 1714 1715 1716 1717 1718 1719
			/*
			 * Check if this is a case where the  password
			 * starts with a delimiter
			 */
			tmp_end = strchr(data, '=');
			tmp_end++;
			if (!(tmp_end < end && tmp_end[1] == delim)) {
				/* No it is not. Set the password to NULL */
1720
				kfree(vol->password);
1721 1722 1723 1724 1725
				vol->password = NULL;
				break;
			}
			/* Yes it is. Drop down to Opt_pass below.*/
		case Opt_pass:
1726 1727
			/* Obtain the value string */
			value = strchr(data, '=');
1728
			value++;
1729 1730 1731 1732 1733 1734 1735 1736

			/* Set tmp_end to end of the string */
			tmp_end = (char *) value + strlen(value);

			/* Check if following character is the deliminator
			 * If yes, we have encountered a double deliminator
			 * reset the NULL character to the deliminator
			 */
1737
			if (tmp_end < end && tmp_end[1] == delim) {
1738 1739
				tmp_end[0] = delim;

1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755
				/* Keep iterating until we get to a single
				 * deliminator OR the end
				 */
				while ((tmp_end = strchr(tmp_end, delim))
					!= NULL && (tmp_end[1] == delim)) {
						tmp_end = (char *) &tmp_end[2];
				}

				/* Reset var options to point to next element */
				if (tmp_end) {
					tmp_end[0] = '\0';
					options = (char *) &tmp_end[1];
				} else
					/* Reached the end of the mount option
					 * string */
					options = end;
1756 1757
			}

1758
			kfree(vol->password);
1759 1760 1761 1762
			/* Now build new password string */
			temp_len = strlen(value);
			vol->password = kzalloc(temp_len+1, GFP_KERNEL);
			if (vol->password == NULL) {
1763
				pr_warn("CIFS: no memory for password\n");
1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775
				goto cifs_parse_mount_err;
			}

			for (i = 0, j = 0; i < temp_len; i++, j++) {
				vol->password[j] = value[i];
				if ((value[i] == delim) &&
				     value[i+1] == delim)
					/* skip the second deliminator */
					i++;
			}
			vol->password[j] = '\0';
			break;
1776
		case Opt_blank_ip:
1777 1778
			/* FIXME: should this be an error instead? */
			got_ip = false;
1779
			break;
1780 1781 1782 1783 1784
		case Opt_ip:
			string = match_strdup(args);
			if (string == NULL)
				goto out_nomem;

1785 1786
			if (!cifs_convert_address(dstaddr, string,
					strlen(string))) {
1787
				pr_err("CIFS: bad ip= option (%s).\n", string);
1788 1789
				goto cifs_parse_mount_err;
			}
1790
			got_ip = true;
1791 1792 1793 1794 1795 1796
			break;
		case Opt_domain:
			string = match_strdup(args);
			if (string == NULL)
				goto out_nomem;

1797 1798
			if (strnlen(string, CIFS_MAX_DOMAINNAME_LEN)
					== CIFS_MAX_DOMAINNAME_LEN) {
1799
				pr_warn("CIFS: domain name too long\n");
1800 1801 1802
				goto cifs_parse_mount_err;
			}

1803
			kfree(vol->domainname);
1804 1805
			vol->domainname = kstrdup(string, GFP_KERNEL);
			if (!vol->domainname) {
1806
				pr_warn("CIFS: no memory for domainname\n");
1807 1808
				goto cifs_parse_mount_err;
			}
1809
			cifs_dbg(FYI, "Domain name set\n");
1810 1811 1812 1813 1814 1815
			break;
		case Opt_srcaddr:
			string = match_strdup(args);
			if (string == NULL)
				goto out_nomem;

1816
			if (!cifs_convert_address(
1817 1818
					(struct sockaddr *)&vol->srcaddr,
					string, strlen(string))) {
1819 1820
				pr_warn("CIFS: Could not parse srcaddr: %s\n",
					string);
1821 1822 1823 1824 1825 1826 1827 1828
				goto cifs_parse_mount_err;
			}
			break;
		case Opt_iocharset:
			string = match_strdup(args);
			if (string == NULL)
				goto out_nomem;

1829
			if (strnlen(string, 1024) >= 65) {
1830
				pr_warn("CIFS: iocharset name too long.\n");
1831 1832 1833
				goto cifs_parse_mount_err;
			}

1834
			 if (strncasecmp(string, "default", 7) != 0) {
1835
				kfree(vol->iocharset);
1836 1837 1838
				vol->iocharset = kstrdup(string,
							 GFP_KERNEL);
				if (!vol->iocharset) {
1839
					pr_warn("CIFS: no memory for charset\n");
1840 1841 1842 1843 1844 1845
					goto cifs_parse_mount_err;
				}
			}
			/* if iocharset not set then load_nls_default
			 * is used by caller
			 */
1846
			 cifs_dbg(FYI, "iocharset set to %s\n", string);
1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869
			break;
		case Opt_netbiosname:
			string = match_strdup(args);
			if (string == NULL)
				goto out_nomem;

			memset(vol->source_rfc1001_name, 0x20,
				RFC1001_NAME_LEN);
			/*
			 * FIXME: are there cases in which a comma can
			 * be valid in workstation netbios name (and
			 * need special handling)?
			 */
			for (i = 0; i < RFC1001_NAME_LEN; i++) {
				/* don't ucase netbiosname for user */
				if (string[i] == 0)
					break;
				vol->source_rfc1001_name[i] = string[i];
			}
			/* The string has 16th byte zero still from
			 * set at top of the function
			 */
			if (i == RFC1001_NAME_LEN && string[i] != 0)
1870
				pr_warn("CIFS: netbiosname longer than 15 truncated.\n");
1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895
			break;
		case Opt_servern:
			/* servernetbiosname specified override *SMBSERVER */
			string = match_strdup(args);
			if (string == NULL)
				goto out_nomem;

			/* last byte, type, is 0x20 for servr type */
			memset(vol->target_rfc1001_name, 0x20,
				RFC1001_NAME_LEN_WITH_NULL);

			/* BB are there cases in which a comma can be
			   valid in this workstation netbios name
			   (and need special handling)? */

			/* user or mount helper must uppercase the
			   netbios name */
			for (i = 0; i < 15; i++) {
				if (string[i] == 0)
					break;
				vol->target_rfc1001_name[i] = string[i];
			}
			/* The string has 16th byte zero still from
			   set at top of the function  */
			if (i == RFC1001_NAME_LEN && string[i] != 0)
1896
				pr_warn("CIFS: server netbiosname longer than 15 truncated.\n");
1897 1898
			break;
		case Opt_ver:
1899
			/* version of mount userspace tools, not dialect */
1900 1901 1902 1903
			string = match_strdup(args);
			if (string == NULL)
				goto out_nomem;

1904
			/* If interface changes in mount.cifs bump to new ver */
1905
			if (strncasecmp(string, "1", 1) == 0) {
1906 1907 1908 1909 1910 1911 1912
				if (strlen(string) > 1) {
					pr_warn("Bad mount helper ver=%s. Did "
						"you want SMB1 (CIFS) dialect "
						"and mean to type vers=1.0 "
						"instead?\n", string);
					goto cifs_parse_mount_err;
				}
1913 1914 1915 1916
				/* This is the default */
				break;
			}
			/* For all other value, error */
1917
			pr_warn("CIFS: Invalid mount helper version specified\n");
1918
			goto cifs_parse_mount_err;
1919
		case Opt_vers:
1920
			/* protocol version (dialect) */
1921 1922 1923 1924 1925 1926
			string = match_strdup(args);
			if (string == NULL)
				goto out_nomem;

			if (cifs_parse_smb_version(string, vol) != 0)
				goto cifs_parse_mount_err;
1927
			got_version = true;
1928
			break;
1929 1930 1931 1932 1933 1934 1935 1936
		case Opt_sec:
			string = match_strdup(args);
			if (string == NULL)
				goto out_nomem;

			if (cifs_parse_security_flavors(string, vol) != 0)
				goto cifs_parse_mount_err;
			break;
1937 1938 1939 1940 1941 1942 1943 1944
		case Opt_cache:
			string = match_strdup(args);
			if (string == NULL)
				goto out_nomem;

			if (cifs_parse_cache_flavor(string, vol) != 0)
				goto cifs_parse_mount_err;
			break;
1945
		default:
1946 1947 1948 1949 1950 1951
			/*
			 * An option we don't recognize. Save it off for later
			 * if we haven't already found one
			 */
			if (!invalid)
				invalid = data;
1952
			break;
L
Linus Torvalds 已提交
1953
		}
1954 1955 1956
		/* Free up any allocated string */
		kfree(string);
		string = NULL;
L
Linus Torvalds 已提交
1957
	}
J
Jeff Layton 已提交
1958

1959
	if (!sloppy && invalid) {
1960
		pr_err("CIFS: Unknown mount option \"%s\"\n", invalid);
1961 1962 1963
		goto cifs_parse_mount_err;
	}

L
Long Li 已提交
1964 1965 1966 1967 1968
	if (vol->rdma && vol->vals->protocol_id < SMB30_PROT_ID) {
		cifs_dbg(VFS, "SMB Direct requires Version >=3.0\n");
		goto cifs_parse_mount_err;
	}

1969 1970 1971
#ifndef CONFIG_KEYS
	/* Muliuser mounts require CONFIG_KEYS support */
	if (vol->multiuser) {
1972
		cifs_dbg(VFS, "Multiuser mounts require kernels with CONFIG_KEYS enabled\n");
1973
		goto cifs_parse_mount_err;
J
Jeff Layton 已提交
1974
	}
1975
#endif
1976
	if (!vol->UNC) {
1977
		cifs_dbg(VFS, "CIFS mount error: No usable UNC path provided in device string!\n");
1978 1979
		goto cifs_parse_mount_err;
	}
J
Jeff Layton 已提交
1980

1981 1982
	/* make sure UNC has a share name */
	if (!strchr(vol->UNC + 3, '\\')) {
1983
		cifs_dbg(VFS, "Malformed UNC. Unable to find share name.\n");
1984 1985 1986
		goto cifs_parse_mount_err;
	}

1987
	if (!got_ip) {
1988 1989 1990
		int len;
		const char *slash;

1991
		/* No ip= option specified? Try to get it from UNC */
1992 1993 1994 1995
		/* Use the address part of the UNC. */
		slash = strchr(&vol->UNC[2], '\\');
		len = slash - &vol->UNC[2];
		if (!cifs_convert_address(dstaddr, &vol->UNC[2], len)) {
1996
			pr_err("Unable to determine destination address.\n");
1997 1998 1999 2000 2001 2002
			goto cifs_parse_mount_err;
		}
	}

	/* set the port that we got earlier */
	cifs_set_port(dstaddr, port);
L
Linus Torvalds 已提交
2003

2004 2005 2006
	if (uid_specified)
		vol->override_uid = override_uid;
	else if (override_uid == 1)
2007
		pr_notice("CIFS: ignoring forceuid mount option specified with no uid= option.\n");
2008 2009 2010 2011

	if (gid_specified)
		vol->override_gid = override_gid;
	else if (override_gid == 1)
2012
		pr_notice("CIFS: ignoring forcegid mount option specified with no gid= option.\n");
2013

2014 2015
	if (got_version == false)
		pr_warn("No dialect specified on mount. Default has changed to "
2016
			"a more secure dialect, SMB2.1 or later (e.g. SMB3), from CIFS "
2017
			"(SMB1). To use the less secure SMB1 dialect to access "
2018 2019
			"old servers which do not support SMB3 (or SMB2.1) specify vers=1.0"
			" on mount.\n");
2020

2021
	kfree(mountdata_copy);
L
Linus Torvalds 已提交
2022
	return 0;
2023

2024
out_nomem:
2025
	pr_warn("Could not allocate temporary buffer\n");
2026
cifs_parse_mount_err:
2027
	kfree(string);
2028 2029
	kfree(mountdata_copy);
	return 1;
L
Linus Torvalds 已提交
2030 2031
}

2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048
/** Returns true if srcaddr isn't specified and rhs isn't
 * specified, or if srcaddr is specified and
 * matches the IP address of the rhs argument.
 */
static bool
srcip_matches(struct sockaddr *srcaddr, struct sockaddr *rhs)
{
	switch (srcaddr->sa_family) {
	case AF_UNSPEC:
		return (rhs->sa_family == AF_UNSPEC);
	case AF_INET: {
		struct sockaddr_in *saddr4 = (struct sockaddr_in *)srcaddr;
		struct sockaddr_in *vaddr4 = (struct sockaddr_in *)rhs;
		return (saddr4->sin_addr.s_addr == vaddr4->sin_addr.s_addr);
	}
	case AF_INET6: {
		struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *)srcaddr;
2049
		struct sockaddr_in6 *vaddr6 = (struct sockaddr_in6 *)rhs;
2050 2051 2052 2053 2054 2055 2056 2057
		return ipv6_addr_equal(&saddr6->sin6_addr, &vaddr6->sin6_addr);
	}
	default:
		WARN_ON(1);
		return false; /* don't expect to be here */
	}
}

2058 2059 2060 2061 2062 2063 2064 2065
/*
 * If no port is specified in addr structure, we try to match with 445 port
 * and if it fails - with 139 ports. It should be called only if address
 * families of server and addr are equal.
 */
static bool
match_port(struct TCP_Server_Info *server, struct sockaddr *addr)
{
2066
	__be16 port, *sport;
2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091

	switch (addr->sa_family) {
	case AF_INET:
		sport = &((struct sockaddr_in *) &server->dstaddr)->sin_port;
		port = ((struct sockaddr_in *) addr)->sin_port;
		break;
	case AF_INET6:
		sport = &((struct sockaddr_in6 *) &server->dstaddr)->sin6_port;
		port = ((struct sockaddr_in6 *) addr)->sin6_port;
		break;
	default:
		WARN_ON(1);
		return false;
	}

	if (!port) {
		port = htons(CIFS_PORT);
		if (port == *sport)
			return true;

		port = htons(RFC1001_PORT);
	}

	return port == *sport;
}
2092

2093
static bool
2094 2095
match_address(struct TCP_Server_Info *server, struct sockaddr *addr,
	      struct sockaddr *srcaddr)
2096 2097
{
	switch (addr->sa_family) {
2098 2099 2100 2101 2102 2103
	case AF_INET: {
		struct sockaddr_in *addr4 = (struct sockaddr_in *)addr;
		struct sockaddr_in *srv_addr4 =
					(struct sockaddr_in *)&server->dstaddr;

		if (addr4->sin_addr.s_addr != srv_addr4->sin_addr.s_addr)
2104 2105
			return false;
		break;
2106 2107 2108 2109 2110 2111
	}
	case AF_INET6: {
		struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr;
		struct sockaddr_in6 *srv_addr6 =
					(struct sockaddr_in6 *)&server->dstaddr;

2112
		if (!ipv6_addr_equal(&addr6->sin6_addr,
2113
				     &srv_addr6->sin6_addr))
2114
			return false;
2115
		if (addr6->sin6_scope_id != srv_addr6->sin6_scope_id)
2116 2117 2118
			return false;
		break;
	}
2119 2120 2121 2122
	default:
		WARN_ON(1);
		return false; /* don't expect to be here */
	}
2123

2124 2125 2126
	if (!srcip_matches(srcaddr, (struct sockaddr *)&server->srcaddr))
		return false;

2127 2128 2129
	return true;
}

2130 2131 2132
static bool
match_security(struct TCP_Server_Info *server, struct smb_vol *vol)
{
2133 2134 2135 2136 2137
	/*
	 * The select_sectype function should either return the vol->sectype
	 * that was specified, or "Unspecified" if that sectype was not
	 * compatible with the given NEGOTIATE request.
	 */
S
Sachin Prabhu 已提交
2138 2139
	if (server->ops->select_sectype(server, vol->sectype)
	     == Unspecified)
2140 2141
		return false;

2142 2143 2144 2145 2146
	/*
	 * Now check if signing mode is acceptable. No need to check
	 * global_secflags at this point since if MUST_SIGN is set then
	 * the server->sign had better be too.
	 */
2147 2148
	if (vol->sign && !server->sign)
		return false;
2149 2150 2151 2152

	return true;
}

2153
static int match_server(struct TCP_Server_Info *server, struct smb_vol *vol)
2154
{
2155 2156
	struct sockaddr *addr = (struct sockaddr *)&vol->dstaddr;

2157 2158 2159
	if (vol->nosharesock)
		return 0;

2160
	/* BB update this for smb3any and default case */
2161 2162 2163
	if ((server->vals != vol->vals) || (server->ops != vol->ops))
		return 0;

2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176
	if (!net_eq(cifs_net_ns(server), current->nsproxy->net_ns))
		return 0;

	if (!match_address(server, addr,
			   (struct sockaddr *)&vol->srcaddr))
		return 0;

	if (!match_port(server, addr))
		return 0;

	if (!match_security(server, vol))
		return 0;

R
Rabin Vincent 已提交
2177
	if (server->echo_interval != vol->echo_interval * HZ)
S
Steve French 已提交
2178 2179
		return 0;

L
Long Li 已提交
2180 2181 2182
	if (server->rdma != vol->rdma)
		return 0;

2183 2184 2185
	return 1;
}

2186
static struct TCP_Server_Info *
2187
cifs_find_tcp_session(struct smb_vol *vol)
L
Linus Torvalds 已提交
2188
{
2189 2190
	struct TCP_Server_Info *server;

2191
	spin_lock(&cifs_tcp_ses_lock);
2192
	list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
2193
		if (!match_server(server, vol))
2194 2195
			continue;

2196
		++server->srv_count;
2197
		spin_unlock(&cifs_tcp_ses_lock);
2198
		cifs_dbg(FYI, "Existing tcp session with server found\n");
2199
		return server;
L
Linus Torvalds 已提交
2200
	}
2201
	spin_unlock(&cifs_tcp_ses_lock);
L
Linus Torvalds 已提交
2202 2203
	return NULL;
}
2204

2205 2206
void
cifs_put_tcp_session(struct TCP_Server_Info *server, int from_reconnect)
L
Linus Torvalds 已提交
2207
{
2208 2209
	struct task_struct *task;

2210
	spin_lock(&cifs_tcp_ses_lock);
2211
	if (--server->srv_count > 0) {
2212
		spin_unlock(&cifs_tcp_ses_lock);
2213
		return;
L
Linus Torvalds 已提交
2214
	}
2215

2216 2217
	put_net(cifs_net_ns(server));

2218
	list_del_init(&server->tcp_ses_list);
2219
	spin_unlock(&cifs_tcp_ses_lock);
2220

2221 2222
	cancel_delayed_work_sync(&server->echo);

2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233
	if (from_reconnect)
		/*
		 * Avoid deadlock here: reconnect work calls
		 * cifs_put_tcp_session() at its end. Need to be sure
		 * that reconnect work does nothing with server pointer after
		 * that step.
		 */
		cancel_delayed_work(&server->reconnect);
	else
		cancel_delayed_work_sync(&server->reconnect);

2234 2235 2236
	spin_lock(&GlobalMid_Lock);
	server->tcpStatus = CifsExiting;
	spin_unlock(&GlobalMid_Lock);
2237

2238
	cifs_crypto_secmech_release(server);
2239 2240
	cifs_fscache_release_client_cookie(server);

2241 2242 2243
	kfree(server->session_key.response);
	server->session_key.response = NULL;
	server->session_key.len = 0;
2244 2245 2246 2247

	task = xchg(&server->tsk, NULL);
	if (task)
		force_sig(SIGKILL, task);
L
Linus Torvalds 已提交
2248 2249
}

2250 2251 2252 2253 2254 2255
static struct TCP_Server_Info *
cifs_get_tcp_session(struct smb_vol *volume_info)
{
	struct TCP_Server_Info *tcp_ses = NULL;
	int rc;

2256
	cifs_dbg(FYI, "UNC: %s\n", volume_info->UNC);
2257 2258

	/* see if we already have a matching tcp_ses */
2259
	tcp_ses = cifs_find_tcp_session(volume_info);
2260 2261 2262 2263 2264 2265 2266 2267 2268
	if (tcp_ses)
		return tcp_ses;

	tcp_ses = kzalloc(sizeof(struct TCP_Server_Info), GFP_KERNEL);
	if (!tcp_ses) {
		rc = -ENOMEM;
		goto out_err;
	}

2269 2270
	tcp_ses->ops = volume_info->ops;
	tcp_ses->vals = volume_info->vals;
2271
	cifs_set_net_ns(tcp_ses, get_net(current->nsproxy->net_ns));
2272 2273 2274
	tcp_ses->hostname = extract_hostname(volume_info->UNC);
	if (IS_ERR(tcp_ses->hostname)) {
		rc = PTR_ERR(tcp_ses->hostname);
2275
		goto out_err_crypto_release;
2276 2277 2278 2279
	}

	tcp_ses->noblocksnd = volume_info->noblocksnd;
	tcp_ses->noautotune = volume_info->noautotune;
2280
	tcp_ses->tcp_nodelay = volume_info->sockopt_tcp_nodelay;
L
Long Li 已提交
2281
	tcp_ses->rdma = volume_info->rdma;
P
Pavel Shilovsky 已提交
2282
	tcp_ses->in_flight = 0;
2283
	tcp_ses->credits = 1;
2284 2285 2286 2287 2288 2289 2290 2291
	init_waitqueue_head(&tcp_ses->response_q);
	init_waitqueue_head(&tcp_ses->request_q);
	INIT_LIST_HEAD(&tcp_ses->pending_mid_q);
	mutex_init(&tcp_ses->srv_mutex);
	memcpy(tcp_ses->workstation_RFC1001_name,
		volume_info->source_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL);
	memcpy(tcp_ses->server_RFC1001_name,
		volume_info->target_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL);
2292
	tcp_ses->session_estab = false;
2293
	tcp_ses->sequence_number = 0;
2294
	tcp_ses->lstrp = jiffies;
2295
	spin_lock_init(&tcp_ses->req_lock);
2296 2297
	INIT_LIST_HEAD(&tcp_ses->tcp_ses_list);
	INIT_LIST_HEAD(&tcp_ses->smb_ses_list);
2298
	INIT_DELAYED_WORK(&tcp_ses->echo, cifs_echo_request);
2299 2300
	INIT_DELAYED_WORK(&tcp_ses->reconnect, smb2_reconnect_server);
	mutex_init(&tcp_ses->reconnect_mutex);
2301 2302 2303 2304
	memcpy(&tcp_ses->srcaddr, &volume_info->srcaddr,
	       sizeof(tcp_ses->srcaddr));
	memcpy(&tcp_ses->dstaddr, &volume_info->dstaddr,
		sizeof(tcp_ses->dstaddr));
2305
	generate_random_uuid(tcp_ses->client_guid);
2306 2307 2308 2309 2310 2311 2312 2313
	/*
	 * at this point we are the only ones with the pointer
	 * to the struct since the kernel thread not created yet
	 * no need to spinlock this init of tcpStatus or srv_count
	 */
	tcp_ses->tcpStatus = CifsNew;
	++tcp_ses->srv_count;

S
Steve French 已提交
2314 2315 2316 2317 2318
	if (volume_info->echo_interval >= SMB_ECHO_INTERVAL_MIN &&
		volume_info->echo_interval <= SMB_ECHO_INTERVAL_MAX)
		tcp_ses->echo_interval = volume_info->echo_interval * HZ;
	else
		tcp_ses->echo_interval = SMB_ECHO_INTERVAL_DEFAULT * HZ;
2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335
	if (tcp_ses->rdma) {
#ifndef CONFIG_CIFS_SMB_DIRECT
		cifs_dbg(VFS, "CONFIG_CIFS_SMB_DIRECT is not enabled\n");
		rc = -ENOENT;
		goto out_err_crypto_release;
#endif
		tcp_ses->smbd_conn = smbd_get_connection(
			tcp_ses, (struct sockaddr *)&volume_info->dstaddr);
		if (tcp_ses->smbd_conn) {
			cifs_dbg(VFS, "RDMA transport established\n");
			rc = 0;
			goto smbd_connected;
		} else {
			rc = -ENOENT;
			goto out_err_crypto_release;
		}
	}
2336
	rc = ip_connect(tcp_ses);
2337
	if (rc < 0) {
2338
		cifs_dbg(VFS, "Error connecting to socket. Aborting operation.\n");
2339
		goto out_err_crypto_release;
2340
	}
2341
smbd_connected:
2342 2343 2344 2345 2346
	/*
	 * since we're in a cifs function already, we know that
	 * this will succeed. No need for try_module_get().
	 */
	__module_get(THIS_MODULE);
2347
	tcp_ses->tsk = kthread_run(cifs_demultiplex_thread,
2348 2349 2350
				  tcp_ses, "cifsd");
	if (IS_ERR(tcp_ses->tsk)) {
		rc = PTR_ERR(tcp_ses->tsk);
2351
		cifs_dbg(VFS, "error %d create cifsd thread\n", rc);
2352
		module_put(THIS_MODULE);
2353
		goto out_err_crypto_release;
2354
	}
2355
	tcp_ses->tcpStatus = CifsNeedNegotiate;
2356 2357

	/* thread spawned, put it on the list */
2358
	spin_lock(&cifs_tcp_ses_lock);
2359
	list_add(&tcp_ses->tcp_ses_list, &cifs_tcp_ses_list);
2360
	spin_unlock(&cifs_tcp_ses_lock);
2361

2362 2363
	cifs_fscache_get_client_cookie(tcp_ses);

2364
	/* queue echo request delayed work */
S
Steve French 已提交
2365
	queue_delayed_work(cifsiod_wq, &tcp_ses->echo, tcp_ses->echo_interval);
2366

2367 2368
	return tcp_ses;

2369
out_err_crypto_release:
2370
	cifs_crypto_secmech_release(tcp_ses);
2371

2372 2373
	put_net(cifs_net_ns(tcp_ses));

2374 2375
out_err:
	if (tcp_ses) {
2376 2377
		if (!IS_ERR(tcp_ses->hostname))
			kfree(tcp_ses->hostname);
2378 2379 2380 2381 2382 2383 2384
		if (tcp_ses->ssocket)
			sock_release(tcp_ses->ssocket);
		kfree(tcp_ses);
	}
	return ERR_PTR(rc);
}

2385
static int match_session(struct cifs_ses *ses, struct smb_vol *vol)
2386
{
2387 2388 2389 2390 2391
	if (vol->sectype != Unspecified &&
	    vol->sectype != ses->sectype)
		return 0;

	switch (ses->sectype) {
2392
	case Kerberos:
2393
		if (!uid_eq(vol->cred_uid, ses->cred_uid))
2394 2395 2396
			return 0;
		break;
	default:
J
Jeff Layton 已提交
2397 2398 2399 2400 2401 2402 2403
		/* NULL username means anonymous session */
		if (ses->user_name == NULL) {
			if (!vol->nullauth)
				return 0;
			break;
		}

2404
		/* anything else takes username/password */
J
Jeff Layton 已提交
2405 2406
		if (strncmp(ses->user_name,
			    vol->username ? vol->username : "",
2407
			    CIFS_MAX_USERNAME_LEN))
2408
			return 0;
2409
		if ((vol->username && strlen(vol->username) != 0) &&
2410 2411 2412
		    ses->password != NULL &&
		    strncmp(ses->password,
			    vol->password ? vol->password : "",
2413
			    CIFS_MAX_PASSWORD_LEN))
2414 2415 2416 2417 2418
			return 0;
	}
	return 1;
}

2419
static struct cifs_ses *
2420
cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb_vol *vol)
L
Linus Torvalds 已提交
2421
{
2422
	struct cifs_ses *ses;
2423

2424
	spin_lock(&cifs_tcp_ses_lock);
2425
	list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
2426 2427
		if (ses->status == CifsExiting)
			continue;
2428 2429
		if (!match_session(ses, vol))
			continue;
2430
		++ses->ses_count;
2431
		spin_unlock(&cifs_tcp_ses_lock);
2432 2433
		return ses;
	}
2434
	spin_unlock(&cifs_tcp_ses_lock);
2435 2436
	return NULL;
}
2437

2438
static void
2439
cifs_put_smb_ses(struct cifs_ses *ses)
2440
{
2441
	unsigned int rc, xid;
2442
	struct TCP_Server_Info *server = ses->server;
2443

2444
	cifs_dbg(FYI, "%s: ses_count=%d\n", __func__, ses->ses_count);
2445

2446
	spin_lock(&cifs_tcp_ses_lock);
2447 2448 2449 2450
	if (ses->status == CifsExiting) {
		spin_unlock(&cifs_tcp_ses_lock);
		return;
	}
2451
	if (--ses->ses_count > 0) {
2452
		spin_unlock(&cifs_tcp_ses_lock);
2453 2454
		return;
	}
2455 2456
	if (ses->status == CifsGood)
		ses->status = CifsExiting;
2457
	spin_unlock(&cifs_tcp_ses_lock);
2458

2459
	if (ses->status == CifsExiting && server->ops->logoff) {
2460
		xid = get_xid();
2461 2462 2463 2464
		rc = server->ops->logoff(xid, ses);
		if (rc)
			cifs_dbg(VFS, "%s: Session Logoff failure rc=%d\n",
				__func__, rc);
2465
		_free_xid(xid);
2466
	}
2467 2468 2469 2470 2471

	spin_lock(&cifs_tcp_ses_lock);
	list_del_init(&ses->smb_ses_list);
	spin_unlock(&cifs_tcp_ses_lock);

2472
	sesInfoFree(ses);
2473
	cifs_put_tcp_session(server, 0);
2474
}
2475

2476 2477
#ifdef CONFIG_KEYS

2478 2479
/* strlen("cifs:a:") + CIFS_MAX_DOMAINNAME_LEN + 1 */
#define CIFSCREDS_DESC_SIZE (7 + CIFS_MAX_DOMAINNAME_LEN + 1)
2480 2481 2482 2483 2484 2485

/* Populate username and pw fields from keyring if possible */
static int
cifs_set_cifscreds(struct smb_vol *vol, struct cifs_ses *ses)
{
	int rc = 0;
2486 2487
	const char *delim, *payload;
	char *desc;
2488 2489 2490 2491 2492
	ssize_t len;
	struct key *key;
	struct TCP_Server_Info *server = ses->server;
	struct sockaddr_in *sa;
	struct sockaddr_in6 *sa6;
2493
	const struct user_key_payload *upayload;
2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509

	desc = kmalloc(CIFSCREDS_DESC_SIZE, GFP_KERNEL);
	if (!desc)
		return -ENOMEM;

	/* try to find an address key first */
	switch (server->dstaddr.ss_family) {
	case AF_INET:
		sa = (struct sockaddr_in *)&server->dstaddr;
		sprintf(desc, "cifs:a:%pI4", &sa->sin_addr.s_addr);
		break;
	case AF_INET6:
		sa6 = (struct sockaddr_in6 *)&server->dstaddr;
		sprintf(desc, "cifs:a:%pI6c", &sa6->sin6_addr.s6_addr);
		break;
	default:
2510 2511
		cifs_dbg(FYI, "Bad ss_family (%hu)\n",
			 server->dstaddr.ss_family);
2512 2513 2514 2515
		rc = -EINVAL;
		goto out_err;
	}

2516
	cifs_dbg(FYI, "%s: desc=%s\n", __func__, desc);
2517 2518 2519
	key = request_key(&key_type_logon, desc, "");
	if (IS_ERR(key)) {
		if (!ses->domainName) {
2520
			cifs_dbg(FYI, "domainName is NULL\n");
2521 2522 2523 2524 2525 2526
			rc = PTR_ERR(key);
			goto out_err;
		}

		/* didn't work, try to find a domain key */
		sprintf(desc, "cifs:d:%s", ses->domainName);
2527
		cifs_dbg(FYI, "%s: desc=%s\n", __func__, desc);
2528 2529 2530 2531 2532 2533 2534 2535
		key = request_key(&key_type_logon, desc, "");
		if (IS_ERR(key)) {
			rc = PTR_ERR(key);
			goto out_err;
		}
	}

	down_read(&key->sem);
2536
	upayload = user_key_payload_locked(key);
2537
	if (IS_ERR_OR_NULL(upayload)) {
2538
		rc = upayload ? PTR_ERR(upayload) : -EINVAL;
2539 2540 2541 2542
		goto out_key_put;
	}

	/* find first : in payload */
2543
	payload = upayload->data;
2544
	delim = strnchr(payload, upayload->datalen, ':');
2545
	cifs_dbg(FYI, "payload=%s\n", payload);
2546
	if (!delim) {
2547 2548
		cifs_dbg(FYI, "Unable to find ':' in payload (datalen=%d)\n",
			 upayload->datalen);
2549 2550 2551 2552 2553
		rc = -EINVAL;
		goto out_key_put;
	}

	len = delim - payload;
2554
	if (len > CIFS_MAX_USERNAME_LEN || len <= 0) {
2555 2556
		cifs_dbg(FYI, "Bad value from username search (len=%zd)\n",
			 len);
2557 2558 2559 2560 2561 2562
		rc = -EINVAL;
		goto out_key_put;
	}

	vol->username = kstrndup(payload, len, GFP_KERNEL);
	if (!vol->username) {
2563 2564
		cifs_dbg(FYI, "Unable to allocate %zd bytes for username\n",
			 len);
2565 2566 2567
		rc = -ENOMEM;
		goto out_key_put;
	}
2568
	cifs_dbg(FYI, "%s: username=%s\n", __func__, vol->username);
2569 2570

	len = key->datalen - (len + 1);
2571
	if (len > CIFS_MAX_PASSWORD_LEN || len <= 0) {
2572
		cifs_dbg(FYI, "Bad len for password search (len=%zd)\n", len);
2573 2574 2575 2576 2577 2578 2579 2580 2581
		rc = -EINVAL;
		kfree(vol->username);
		vol->username = NULL;
		goto out_key_put;
	}

	++delim;
	vol->password = kstrndup(delim, len, GFP_KERNEL);
	if (!vol->password) {
2582 2583
		cifs_dbg(FYI, "Unable to allocate %zd bytes for password\n",
			 len);
2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594
		rc = -ENOMEM;
		kfree(vol->username);
		vol->username = NULL;
		goto out_key_put;
	}

out_key_put:
	up_read(&key->sem);
	key_put(key);
out_err:
	kfree(desc);
2595
	cifs_dbg(FYI, "%s: returning %d\n", __func__, rc);
2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606
	return rc;
}
#else /* ! CONFIG_KEYS */
static inline int
cifs_set_cifscreds(struct smb_vol *vol __attribute__((unused)),
		   struct cifs_ses *ses __attribute__((unused)))
{
	return -ENOSYS;
}
#endif /* CONFIG_KEYS */

2607
static struct cifs_ses *
2608 2609
cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
{
2610 2611
	int rc = -ENOMEM;
	unsigned int xid;
2612
	struct cifs_ses *ses;
2613 2614
	struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr;
	struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&server->dstaddr;
2615

2616
	xid = get_xid();
2617

2618
	ses = cifs_find_smb_ses(server, volume_info);
2619
	if (ses) {
2620 2621
		cifs_dbg(FYI, "Existing smb sess found (status=%d)\n",
			 ses->status);
2622 2623

		mutex_lock(&ses->session_mutex);
2624 2625 2626 2627 2628
		rc = cifs_negotiate_protocol(xid, ses);
		if (rc) {
			mutex_unlock(&ses->session_mutex);
			/* problem -- put our ses reference */
			cifs_put_smb_ses(ses);
2629
			free_xid(xid);
2630 2631
			return ERR_PTR(rc);
		}
2632
		if (ses->need_reconnect) {
2633
			cifs_dbg(FYI, "Session needs reconnect\n");
2634 2635 2636 2637 2638 2639
			rc = cifs_setup_session(xid, ses,
						volume_info->local_nls);
			if (rc) {
				mutex_unlock(&ses->session_mutex);
				/* problem -- put our reference */
				cifs_put_smb_ses(ses);
2640
				free_xid(xid);
2641 2642 2643 2644
				return ERR_PTR(rc);
			}
		}
		mutex_unlock(&ses->session_mutex);
2645 2646

		/* existing SMB ses has a server reference already */
2647
		cifs_put_tcp_session(server, 0);
2648
		free_xid(xid);
2649 2650 2651
		return ses;
	}

2652
	cifs_dbg(FYI, "Existing smb sess not found\n");
2653 2654 2655 2656 2657 2658
	ses = sesInfoAlloc();
	if (ses == NULL)
		goto get_ses_fail;

	/* new SMB session uses our server ref */
	ses->server = server;
2659 2660
	if (server->dstaddr.ss_family == AF_INET6)
		sprintf(ses->serverName, "%pI6", &addr6->sin6_addr);
2661
	else
2662
		sprintf(ses->serverName, "%pI4", &addr->sin_addr);
2663

2664 2665 2666 2667 2668
	if (volume_info->username) {
		ses->user_name = kstrdup(volume_info->username, GFP_KERNEL);
		if (!ses->user_name)
			goto get_ses_fail;
	}
2669 2670 2671 2672 2673 2674 2675 2676

	/* volume_info->password freed at unmount */
	if (volume_info->password) {
		ses->password = kstrdup(volume_info->password, GFP_KERNEL);
		if (!ses->password)
			goto get_ses_fail;
	}
	if (volume_info->domainname) {
2677 2678 2679
		ses->domainName = kstrdup(volume_info->domainname, GFP_KERNEL);
		if (!ses->domainName)
			goto get_ses_fail;
2680
	}
2681 2682
	if (volume_info->domainauto)
		ses->domainAuto = volume_info->domainauto;
2683
	ses->cred_uid = volume_info->cred_uid;
2684
	ses->linux_uid = volume_info->linux_uid;
2685

2686 2687
	ses->sectype = volume_info->sectype;
	ses->sign = volume_info->sign;
2688 2689

	mutex_lock(&ses->session_mutex);
2690 2691 2692
	rc = cifs_negotiate_protocol(xid, ses);
	if (!rc)
		rc = cifs_setup_session(xid, ses, volume_info->local_nls);
2693
	mutex_unlock(&ses->session_mutex);
2694
	if (rc)
2695 2696 2697
		goto get_ses_fail;

	/* success, put it on the list */
2698
	spin_lock(&cifs_tcp_ses_lock);
2699
	list_add(&ses->smb_ses_list, &server->smb_ses_list);
2700
	spin_unlock(&cifs_tcp_ses_lock);
2701

2702
	free_xid(xid);
2703 2704 2705 2706
	return ses;

get_ses_fail:
	sesInfoFree(ses);
2707
	free_xid(xid);
2708 2709 2710
	return ERR_PTR(rc);
}

2711
static int match_tcon(struct cifs_tcon *tcon, struct smb_vol *volume_info)
2712 2713 2714
{
	if (tcon->tidStatus == CifsExiting)
		return 0;
2715
	if (strncmp(tcon->treeName, volume_info->UNC, MAX_TREE_SIZE))
2716
		return 0;
2717 2718 2719 2720
	if (tcon->seal != volume_info->seal)
		return 0;
	if (tcon->snapshot_time != volume_info->snapshot_time)
		return 0;
2721 2722 2723
	return 1;
}

2724
static struct cifs_tcon *
2725
cifs_find_tcon(struct cifs_ses *ses, struct smb_vol *volume_info)
2726 2727
{
	struct list_head *tmp;
2728
	struct cifs_tcon *tcon;
2729

2730
	spin_lock(&cifs_tcp_ses_lock);
2731
	list_for_each(tmp, &ses->tcon_list) {
2732
		tcon = list_entry(tmp, struct cifs_tcon, tcon_list);
2733
		if (!match_tcon(tcon, volume_info))
2734 2735
			continue;
		++tcon->tc_count;
2736
		spin_unlock(&cifs_tcp_ses_lock);
2737
		return tcon;
L
Linus Torvalds 已提交
2738
	}
2739
	spin_unlock(&cifs_tcp_ses_lock);
L
Linus Torvalds 已提交
2740 2741 2742
	return NULL;
}

2743
void
2744
cifs_put_tcon(struct cifs_tcon *tcon)
2745
{
2746
	unsigned int xid;
2747
	struct cifs_ses *ses = tcon->ses;
2748

2749
	cifs_dbg(FYI, "%s: tc_count=%d\n", __func__, tcon->tc_count);
2750
	spin_lock(&cifs_tcp_ses_lock);
2751
	if (--tcon->tc_count > 0) {
2752
		spin_unlock(&cifs_tcp_ses_lock);
2753 2754 2755 2756
		return;
	}

	list_del_init(&tcon->tcon_list);
2757
	spin_unlock(&cifs_tcp_ses_lock);
2758

2759
	xid = get_xid();
2760 2761
	if (ses->server->ops->tree_disconnect)
		ses->server->ops->tree_disconnect(xid, tcon);
2762
	_free_xid(xid);
2763

2764
	cifs_fscache_release_super_cookie(tcon);
2765
	tconInfoFree(tcon);
2766 2767 2768
	cifs_put_smb_ses(ses);
}

2769 2770
static struct cifs_tcon *
cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info)
2771 2772
{
	int rc, xid;
2773
	struct cifs_tcon *tcon;
2774

2775
	tcon = cifs_find_tcon(ses, volume_info);
2776
	if (tcon) {
2777
		cifs_dbg(FYI, "Found match on UNC path\n");
2778 2779 2780 2781 2782
		/* existing tcon already has a reference */
		cifs_put_smb_ses(ses);
		return tcon;
	}

2783 2784 2785 2786 2787
	if (!ses->server->ops->tree_connect) {
		rc = -ENOSYS;
		goto out_fail;
	}

2788 2789 2790 2791 2792 2793
	tcon = tconInfoAlloc();
	if (tcon == NULL) {
		rc = -ENOMEM;
		goto out_fail;
	}

2794 2795 2796 2797 2798 2799 2800 2801 2802 2803
	if (volume_info->snapshot_time) {
		if (ses->server->vals->protocol_id == 0) {
			cifs_dbg(VFS,
			     "Use SMB2 or later for snapshot mount option\n");
			rc = -EOPNOTSUPP;
			goto out_fail;
		} else
			tcon->snapshot_time = volume_info->snapshot_time;
	}

2804 2805 2806 2807 2808 2809 2810 2811 2812
	tcon->ses = ses;
	if (volume_info->password) {
		tcon->password = kstrdup(volume_info->password, GFP_KERNEL);
		if (!tcon->password) {
			rc = -ENOMEM;
			goto out_fail;
		}
	}

2813 2814 2815 2816
	/*
	 * BB Do we need to wrap session_mutex around this TCon call and Unix
	 * SetFS as we do on SessSetup and reconnect?
	 */
2817
	xid = get_xid();
2818 2819
	rc = ses->server->ops->tree_connect(xid, ses, volume_info->UNC, tcon,
					    volume_info->local_nls);
2820
	free_xid(xid);
2821
	cifs_dbg(FYI, "Tcon rc = %d\n", rc);
2822 2823 2824 2825 2826
	if (rc)
		goto out_fail;

	if (volume_info->nodfs) {
		tcon->Flags &= ~SMB_SHARE_IS_IN_DFS;
2827
		cifs_dbg(FYI, "DFS disabled (%d)\n", tcon->Flags);
2828
	}
2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850
	tcon->use_persistent = false;
	/* check if SMB2 or later, CIFS does not support persistent handles */
	if (volume_info->persistent) {
		if (ses->server->vals->protocol_id == 0) {
			cifs_dbg(VFS,
			     "SMB3 or later required for persistent handles\n");
			rc = -EOPNOTSUPP;
			goto out_fail;
		} else if (ses->server->capabilities &
			   SMB2_GLOBAL_CAP_PERSISTENT_HANDLES)
			tcon->use_persistent = true;
		else /* persistent handles requested but not supported */ {
			cifs_dbg(VFS,
				"Persistent handles not supported on share\n");
			rc = -EOPNOTSUPP;
			goto out_fail;
		}
	} else if ((tcon->capabilities & SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY)
	     && (ses->server->capabilities & SMB2_GLOBAL_CAP_PERSISTENT_HANDLES)
	     && (volume_info->nopersistent == false)) {
		cifs_dbg(FYI, "enabling persistent handles\n");
		tcon->use_persistent = true;
S
Steve French 已提交
2851 2852 2853 2854 2855 2856 2857 2858
	} else if (volume_info->resilient) {
		if (ses->server->vals->protocol_id == 0) {
			cifs_dbg(VFS,
			     "SMB2.1 or later required for resilient handles\n");
			rc = -EOPNOTSUPP;
			goto out_fail;
		}
		tcon->use_resilient = true;
2859 2860
	}

2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876
	if (volume_info->seal) {
		if (ses->server->vals->protocol_id == 0) {
			cifs_dbg(VFS,
				 "SMB3 or later required for encryption\n");
			rc = -EOPNOTSUPP;
			goto out_fail;
		} else if (tcon->ses->server->capabilities &
					SMB2_GLOBAL_CAP_ENCRYPTION)
			tcon->seal = true;
		else {
			cifs_dbg(VFS, "Encryption is not supported on share\n");
			rc = -EOPNOTSUPP;
			goto out_fail;
		}
	}

2877 2878 2879 2880 2881
	/*
	 * We can have only one retry value for a connection to a share so for
	 * resources mounted more than once to the same server share the last
	 * value passed in for the retry flag is used.
	 */
2882 2883 2884
	tcon->retry = volume_info->retry;
	tcon->nocase = volume_info->nocase;
	tcon->local_lease = volume_info->local_lease;
2885
	INIT_LIST_HEAD(&tcon->pending_opens);
2886

2887
	spin_lock(&cifs_tcp_ses_lock);
2888
	list_add(&tcon->tcon_list, &ses->tcon_list);
2889
	spin_unlock(&cifs_tcp_ses_lock);
2890

2891 2892
	cifs_fscache_get_super_cookie(tcon);

2893 2894 2895 2896 2897 2898 2899
	return tcon;

out_fail:
	tconInfoFree(tcon);
	return ERR_PTR(rc);
}

2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916
void
cifs_put_tlink(struct tcon_link *tlink)
{
	if (!tlink || IS_ERR(tlink))
		return;

	if (!atomic_dec_and_test(&tlink->tl_count) ||
	    test_bit(TCON_LINK_IN_TREE, &tlink->tl_flags)) {
		tlink->tl_time = jiffies;
		return;
	}

	if (!IS_ERR(tlink_tcon(tlink)))
		cifs_put_tcon(tlink_tcon(tlink));
	kfree(tlink);
	return;
}
2917

2918
static inline struct tcon_link *
P
Pavel Shilovsky 已提交
2919 2920 2921 2922
cifs_sb_master_tlink(struct cifs_sb_info *cifs_sb)
{
	return cifs_sb->master_tlink;
}
2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937

static int
compare_mount_options(struct super_block *sb, struct cifs_mnt_data *mnt_data)
{
	struct cifs_sb_info *old = CIFS_SB(sb);
	struct cifs_sb_info *new = mnt_data->cifs_sb;

	if ((sb->s_flags & CIFS_MS_MASK) != (mnt_data->flags & CIFS_MS_MASK))
		return 0;

	if ((old->mnt_cifs_flags & CIFS_MOUNT_MASK) !=
	    (new->mnt_cifs_flags & CIFS_MOUNT_MASK))
		return 0;

	/*
2938 2939
	 * We want to share sb only if we don't specify an r/wsize or
	 * specified r/wsize is greater than or equal to existing one.
2940 2941 2942 2943
	 */
	if (new->wsize && new->wsize < old->wsize)
		return 0;

2944 2945 2946
	if (new->rsize && new->rsize < old->rsize)
		return 0;

2947
	if (!uid_eq(old->mnt_uid, new->mnt_uid) || !gid_eq(old->mnt_gid, new->mnt_gid))
2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962
		return 0;

	if (old->mnt_file_mode != new->mnt_file_mode ||
	    old->mnt_dir_mode != new->mnt_dir_mode)
		return 0;

	if (strcmp(old->local_nls->charset, new->local_nls->charset))
		return 0;

	if (old->actimeo != new->actimeo)
		return 0;

	return 1;
}

2963 2964 2965 2966 2967
static int
match_prepath(struct super_block *sb, struct cifs_mnt_data *mnt_data)
{
	struct cifs_sb_info *old = CIFS_SB(sb);
	struct cifs_sb_info *new = mnt_data->cifs_sb;
S
Sachin Prabhu 已提交
2968 2969
	bool old_set = old->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH;
	bool new_set = new->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH;
2970

S
Sachin Prabhu 已提交
2971
	if (old_set && new_set && !strcmp(new->prepath, old->prepath))
2972
		return 1;
S
Sachin Prabhu 已提交
2973 2974 2975
	else if (!old_set && !new_set)
		return 1;

2976 2977 2978
	return 0;
}

2979 2980 2981 2982 2983 2984 2985
int
cifs_match_super(struct super_block *sb, void *data)
{
	struct cifs_mnt_data *mnt_data = (struct cifs_mnt_data *)data;
	struct smb_vol *volume_info;
	struct cifs_sb_info *cifs_sb;
	struct TCP_Server_Info *tcp_srv;
2986 2987
	struct cifs_ses *ses;
	struct cifs_tcon *tcon;
2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003
	struct tcon_link *tlink;
	int rc = 0;

	spin_lock(&cifs_tcp_ses_lock);
	cifs_sb = CIFS_SB(sb);
	tlink = cifs_get_tlink(cifs_sb_master_tlink(cifs_sb));
	if (IS_ERR(tlink)) {
		spin_unlock(&cifs_tcp_ses_lock);
		return rc;
	}
	tcon = tlink_tcon(tlink);
	ses = tcon->ses;
	tcp_srv = ses->server;

	volume_info = mnt_data->vol;

3004
	if (!match_server(tcp_srv, volume_info) ||
3005
	    !match_session(ses, volume_info) ||
3006
	    !match_tcon(tcon, volume_info) ||
3007
	    !match_prepath(sb, mnt_data)) {
3008 3009 3010 3011 3012 3013 3014
		rc = 0;
		goto out;
	}

	rc = compare_mount_options(sb, mnt_data);
out:
	spin_unlock(&cifs_tcp_ses_lock);
3015
	cifs_put_tlink(tlink);
3016 3017 3018
	return rc;
}

L
Linus Torvalds 已提交
3019
int
3020
get_dfs_path(const unsigned int xid, struct cifs_ses *ses, const char *old_path,
3021 3022
	     const struct nls_table *nls_codepage, unsigned int *num_referrals,
	     struct dfs_info3_param **referrals, int remap)
L
Linus Torvalds 已提交
3023 3024 3025 3026
{
	char *temp_unc;
	int rc = 0;

3027
	if (!ses->server->ops->tree_connect || !ses->server->ops->get_dfs_refer)
3028 3029 3030 3031
		return -ENOSYS;

	*num_referrals = 0;
	*referrals = NULL;
L
Linus Torvalds 已提交
3032

3033
	if (ses->ipc_tid == 0) {
L
Linus Torvalds 已提交
3034
		temp_unc = kmalloc(2 /* for slashes */ +
3035 3036
			strnlen(ses->serverName, SERVER_NAME_LEN_WITH_NULL * 2)
				+ 1 + 4 /* slash IPC$ */ + 2, GFP_KERNEL);
L
Linus Torvalds 已提交
3037 3038 3039 3040
		if (temp_unc == NULL)
			return -ENOMEM;
		temp_unc[0] = '\\';
		temp_unc[1] = '\\';
3041 3042 3043 3044
		strcpy(temp_unc + 2, ses->serverName);
		strcpy(temp_unc + 2 + strlen(ses->serverName), "\\IPC$");
		rc = ses->server->ops->tree_connect(xid, ses, temp_unc, NULL,
						    nls_codepage);
3045
		cifs_dbg(FYI, "Tcon rc = %d ipc_tid = %d\n", rc, ses->ipc_tid);
L
Linus Torvalds 已提交
3046 3047 3048
		kfree(temp_unc);
	}
	if (rc == 0)
3049 3050 3051
		rc = ses->server->ops->get_dfs_refer(xid, ses, old_path,
						     referrals, num_referrals,
						     nls_codepage, remap);
3052 3053
	/*
	 * BB - map targetUNCs to dfs_info3 structures, here or in
3054
	 * ses->server->ops->get_dfs_refer.
3055
	 */
L
Linus Torvalds 已提交
3056 3057 3058 3059

	return rc;
}

3060 3061 3062 3063 3064 3065 3066 3067
#ifdef CONFIG_DEBUG_LOCK_ALLOC
static struct lock_class_key cifs_key[2];
static struct lock_class_key cifs_slock_key[2];

static inline void
cifs_reclassify_socket4(struct socket *sock)
{
	struct sock *sk = sock->sk;
3068
	BUG_ON(!sock_allow_reclassification(sk));
3069 3070 3071 3072 3073 3074 3075 3076
	sock_lock_init_class_and_name(sk, "slock-AF_INET-CIFS",
		&cifs_slock_key[0], "sk_lock-AF_INET-CIFS", &cifs_key[0]);
}

static inline void
cifs_reclassify_socket6(struct socket *sock)
{
	struct sock *sk = sock->sk;
3077
	BUG_ON(!sock_allow_reclassification(sk));
3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092
	sock_lock_init_class_and_name(sk, "slock-AF_INET6-CIFS",
		&cifs_slock_key[1], "sk_lock-AF_INET6-CIFS", &cifs_key[1]);
}
#else
static inline void
cifs_reclassify_socket4(struct socket *sock)
{
}

static inline void
cifs_reclassify_socket6(struct socket *sock)
{
}
#endif

L
Linus Torvalds 已提交
3093
/* See RFC1001 section 14 on representation of Netbios names */
3094
static void rfc1002mangle(char *target, char *source, unsigned int length)
L
Linus Torvalds 已提交
3095
{
3096
	unsigned int i, j;
L
Linus Torvalds 已提交
3097

3098
	for (i = 0, j = 0; i < (length); i++) {
L
Linus Torvalds 已提交
3099 3100 3101
		/* mask a nibble at a time and encode */
		target[j] = 'A' + (0x0F & (source[i] >> 4));
		target[j+1] = 'A' + (0x0F & source[i]);
3102
		j += 2;
L
Linus Torvalds 已提交
3103 3104 3105 3106
	}

}

3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122
static int
bind_socket(struct TCP_Server_Info *server)
{
	int rc = 0;
	if (server->srcaddr.ss_family != AF_UNSPEC) {
		/* Bind to the specified local IP address */
		struct socket *socket = server->ssocket;
		rc = socket->ops->bind(socket,
				       (struct sockaddr *) &server->srcaddr,
				       sizeof(server->srcaddr));
		if (rc < 0) {
			struct sockaddr_in *saddr4;
			struct sockaddr_in6 *saddr6;
			saddr4 = (struct sockaddr_in *)&server->srcaddr;
			saddr6 = (struct sockaddr_in6 *)&server->srcaddr;
			if (saddr6->sin6_family == AF_INET6)
3123 3124
				cifs_dbg(VFS, "Failed to bind to: %pI6c, error: %d\n",
					 &saddr6->sin6_addr, rc);
3125
			else
3126 3127
				cifs_dbg(VFS, "Failed to bind to: %pI4, error: %d\n",
					 &saddr4->sin_addr.s_addr, rc);
3128 3129 3130 3131
		}
	}
	return rc;
}
L
Linus Torvalds 已提交
3132 3133

static int
3134
ip_rfc1001_connect(struct TCP_Server_Info *server)
L
Linus Torvalds 已提交
3135 3136
{
	int rc = 0;
3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148
	/*
	 * some servers require RFC1001 sessinit before sending
	 * negprot - BB check reconnection in case where second
	 * sessinit is sent but no second negprot
	 */
	struct rfc1002_session_packet *ses_init_buf;
	struct smb_hdr *smb_buf;
	ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet),
			       GFP_KERNEL);
	if (ses_init_buf) {
		ses_init_buf->trailer.session_req.called_len = 32;

3149
		if (server->server_RFC1001_name[0] != 0)
3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165
			rfc1002mangle(ses_init_buf->trailer.
				      session_req.called_name,
				      server->server_RFC1001_name,
				      RFC1001_NAME_LEN_WITH_NULL);
		else
			rfc1002mangle(ses_init_buf->trailer.
				      session_req.called_name,
				      DEFAULT_CIFS_CALLED_NAME,
				      RFC1001_NAME_LEN_WITH_NULL);

		ses_init_buf->trailer.session_req.calling_len = 32;

		/*
		 * calling name ends in null (byte 16) from old smb
		 * convention.
		 */
3166
		if (server->workstation_RFC1001_name[0] != 0)
3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181
			rfc1002mangle(ses_init_buf->trailer.
				      session_req.calling_name,
				      server->workstation_RFC1001_name,
				      RFC1001_NAME_LEN_WITH_NULL);
		else
			rfc1002mangle(ses_init_buf->trailer.
				      session_req.calling_name,
				      "LINUX_CIFS_CLNT",
				      RFC1001_NAME_LEN_WITH_NULL);

		ses_init_buf->trailer.session_req.scope1 = 0;
		ses_init_buf->trailer.session_req.scope2 = 0;
		smb_buf = (struct smb_hdr *)ses_init_buf;

		/* sizeof RFC1002_SESSION_REQUEST with no scope */
3182
		smb_buf->smb_buf_length = cpu_to_be32(0x81000044);
3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208
		rc = smb_send(server, smb_buf, 0x44);
		kfree(ses_init_buf);
		/*
		 * RFC1001 layer in at least one server
		 * requires very short break before negprot
		 * presumably because not expecting negprot
		 * to follow so fast.  This is a simple
		 * solution that works without
		 * complicating the code and causes no
		 * significant slowing down on mount
		 * for everyone else
		 */
		usleep_range(1000, 2000);
	}
	/*
	 * else the negprot may still work without this
	 * even though malloc failed
	 */

	return rc;
}

static int
generic_ip_connect(struct TCP_Server_Info *server)
{
	int rc = 0;
3209
	__be16 sport;
3210
	int slen, sfamily;
3211
	struct socket *socket = server->ssocket;
3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224
	struct sockaddr *saddr;

	saddr = (struct sockaddr *) &server->dstaddr;

	if (server->dstaddr.ss_family == AF_INET6) {
		sport = ((struct sockaddr_in6 *) saddr)->sin6_port;
		slen = sizeof(struct sockaddr_in6);
		sfamily = AF_INET6;
	} else {
		sport = ((struct sockaddr_in *) saddr)->sin_port;
		slen = sizeof(struct sockaddr_in);
		sfamily = AF_INET;
	}
L
Linus Torvalds 已提交
3225

3226
	if (socket == NULL) {
3227 3228
		rc = __sock_create(cifs_net_ns(server), sfamily, SOCK_STREAM,
				   IPPROTO_TCP, &socket, 1);
L
Linus Torvalds 已提交
3229
		if (rc < 0) {
3230
			cifs_dbg(VFS, "Error %d creating socket\n", rc);
3231
			server->ssocket = NULL;
L
Linus Torvalds 已提交
3232 3233
			return rc;
		}
3234 3235

		/* BB other socket options to set KEEPALIVE, NODELAY? */
3236
		cifs_dbg(FYI, "Socket created\n");
3237 3238
		server->ssocket = socket;
		socket->sk->sk_allocation = GFP_NOFS;
3239 3240 3241 3242
		if (sfamily == AF_INET6)
			cifs_reclassify_socket6(socket);
		else
			cifs_reclassify_socket4(socket);
L
Linus Torvalds 已提交
3243 3244
	}

3245 3246 3247 3248
	rc = bind_socket(server);
	if (rc < 0)
		return rc;

3249 3250
	/*
	 * Eventually check for other socket options to change from
3251 3252
	 * the default. sock_setsockopt not used because it expects
	 * user space buffer
3253 3254
	 */
	socket->sk->sk_rcvtimeo = 7 * HZ;
3255
	socket->sk->sk_sndtimeo = 5 * HZ;
3256

3257
	/* make the bufsizes depend on wsize/rsize and max requests */
3258 3259 3260 3261 3262
	if (server->noautotune) {
		if (socket->sk->sk_sndbuf < (200 * 1024))
			socket->sk->sk_sndbuf = 200 * 1024;
		if (socket->sk->sk_rcvbuf < (140 * 1024))
			socket->sk->sk_rcvbuf = 140 * 1024;
3263
	}
L
Linus Torvalds 已提交
3264

3265
	if (server->tcp_nodelay) {
3266
		int val = 1;
3267 3268 3269
		rc = kernel_setsockopt(socket, SOL_TCP, TCP_NODELAY,
				(char *)&val, sizeof(val));
		if (rc)
3270 3271
			cifs_dbg(FYI, "set TCP_NODELAY socket option error %d\n",
				 rc);
3272 3273
	}

3274
	cifs_dbg(FYI, "sndbuf %d rcvbuf %d rcvtimeo 0x%lx\n",
3275
		 socket->sk->sk_sndbuf,
3276
		 socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo);
3277

3278 3279
	rc = socket->ops->connect(socket, saddr, slen, 0);
	if (rc < 0) {
3280
		cifs_dbg(FYI, "Error %d connecting to server\n", rc);
3281 3282 3283 3284 3285
		sock_release(socket);
		server->ssocket = NULL;
		return rc;
	}

3286 3287
	if (sport == htons(RFC1001_PORT))
		rc = ip_rfc1001_connect(server);
3288

L
Linus Torvalds 已提交
3289 3290 3291 3292
	return rc;
}

static int
3293
ip_connect(struct TCP_Server_Info *server)
L
Linus Torvalds 已提交
3294
{
3295
	__be16 *sport;
3296 3297
	struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&server->dstaddr;
	struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr;
L
Linus Torvalds 已提交
3298

3299 3300 3301 3302
	if (server->dstaddr.ss_family == AF_INET6)
		sport = &addr6->sin6_port;
	else
		sport = &addr->sin_port;
L
Linus Torvalds 已提交
3303

3304 3305
	if (*sport == 0) {
		int rc;
L
Linus Torvalds 已提交
3306

3307 3308
		/* try with 445 port at first */
		*sport = htons(CIFS_PORT);
3309

3310
		rc = generic_ip_connect(server);
L
Linus Torvalds 已提交
3311
		if (rc >= 0)
3312
			return rc;
3313

3314 3315
		/* if it failed, try with 139 port */
		*sport = htons(RFC1001_PORT);
3316 3317
	}

3318
	return generic_ip_connect(server);
L
Linus Torvalds 已提交
3319 3320
}

3321
void reset_cifs_unix_caps(unsigned int xid, struct cifs_tcon *tcon,
3322
			  struct cifs_sb_info *cifs_sb, struct smb_vol *vol_info)
3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333
{
	/* if we are reconnecting then should we check to see if
	 * any requested capabilities changed locally e.g. via
	 * remount but we can not do much about it here
	 * if they have (even if we could detect it by the following)
	 * Perhaps we could add a backpointer to array of sb from tcon
	 * or if we change to make all sb to same share the same
	 * sb as NFS - then we only have one backpointer to sb.
	 * What if we wanted to mount the server share twice once with
	 * and once without posixacls or posix paths? */
	__u64 saved_cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
3334

3335 3336 3337
	if (vol_info && vol_info->no_linux_ext) {
		tcon->fsUnixInfo.Capability = 0;
		tcon->unix_ext = 0; /* Unix Extensions disabled */
3338
		cifs_dbg(FYI, "Linux protocol extensions disabled\n");
3339 3340 3341 3342 3343
		return;
	} else if (vol_info)
		tcon->unix_ext = 1; /* Unix Extensions supported */

	if (tcon->unix_ext == 0) {
3344
		cifs_dbg(FYI, "Unix extensions disabled so not set on reconnect\n");
3345 3346
		return;
	}
3347

S
Steve French 已提交
3348
	if (!CIFSSMBQFSUnixInfo(xid, tcon)) {
3349
		__u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
3350
		cifs_dbg(FYI, "unix caps which server supports %lld\n", cap);
3351 3352
		/* check for reconnect case in which we do not
		   want to change the mount behavior if we can avoid it */
S
Steve French 已提交
3353
		if (vol_info == NULL) {
3354
			/* turn off POSIX ACL and PATHNAMES if not set
3355 3356 3357
			   originally at mount time */
			if ((saved_cap & CIFS_UNIX_POSIX_ACL_CAP) == 0)
				cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
3358 3359
			if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
				if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
3360
					cifs_dbg(VFS, "POSIXPATH support change\n");
3361
				cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
3362
			} else if ((cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
3363 3364
				cifs_dbg(VFS, "possible reconnect error\n");
				cifs_dbg(VFS, "server disabled POSIX path support\n");
3365
			}
3366
		}
3367

3368
		if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)
3369
			cifs_dbg(VFS, "per-share encryption not supported yet\n");
3370

3371
		cap &= CIFS_UNIX_CAP_MASK;
3372
		if (vol_info && vol_info->no_psx_acl)
3373
			cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
3374
		else if (CIFS_UNIX_POSIX_ACL_CAP & cap) {
3375
			cifs_dbg(FYI, "negotiated posix acl support\n");
3376 3377 3378
			if (cifs_sb)
				cifs_sb->mnt_cifs_flags |=
					CIFS_MOUNT_POSIXACL;
3379 3380
		}

3381
		if (vol_info && vol_info->posix_paths == 0)
3382
			cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
3383
		else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
3384
			cifs_dbg(FYI, "negotiate posix pathnames\n");
3385 3386
			if (cifs_sb)
				cifs_sb->mnt_cifs_flags |=
3387 3388
					CIFS_MOUNT_POSIX_PATHS;
		}
3389

3390
		cifs_dbg(FYI, "Negotiate caps 0x%x\n", (int)cap);
3391
#ifdef CONFIG_CIFS_DEBUG2
3392
		if (cap & CIFS_UNIX_FCNTL_CAP)
3393
			cifs_dbg(FYI, "FCNTL cap\n");
3394
		if (cap & CIFS_UNIX_EXTATTR_CAP)
3395
			cifs_dbg(FYI, "EXTATTR cap\n");
3396
		if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
3397
			cifs_dbg(FYI, "POSIX path cap\n");
3398
		if (cap & CIFS_UNIX_XATTR_CAP)
3399
			cifs_dbg(FYI, "XATTR cap\n");
3400
		if (cap & CIFS_UNIX_POSIX_ACL_CAP)
3401
			cifs_dbg(FYI, "POSIX ACL cap\n");
3402
		if (cap & CIFS_UNIX_LARGE_READ_CAP)
3403
			cifs_dbg(FYI, "very large read cap\n");
3404
		if (cap & CIFS_UNIX_LARGE_WRITE_CAP)
3405
			cifs_dbg(FYI, "very large write cap\n");
3406
		if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)
3407
			cifs_dbg(FYI, "transport encryption cap\n");
3408
		if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)
3409
			cifs_dbg(FYI, "mandatory transport encryption cap\n");
3410 3411
#endif /* CIFS_DEBUG2 */
		if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
3412
			if (vol_info == NULL) {
3413
				cifs_dbg(FYI, "resetting capabilities failed\n");
3414
			} else
3415
				cifs_dbg(VFS, "Negotiating Unix capabilities with the server failed. Consider mounting with the Unix Extensions disabled if problems are found by specifying the nounix mount option.\n");
3416

3417 3418 3419 3420
		}
	}
}

3421
int cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
3422
			struct cifs_sb_info *cifs_sb)
3423
{
3424 3425
	INIT_DELAYED_WORK(&cifs_sb->prune_tlinks, cifs_prune_tlinks);

3426 3427 3428
	spin_lock_init(&cifs_sb->tlink_tree_lock);
	cifs_sb->tlink_tree = RB_ROOT;

3429
	/*
3430 3431
	 * Temporarily set r/wsize for matching superblock. If we end up using
	 * new sb then client will later negotiate it downward if needed.
3432
	 */
3433
	cifs_sb->rsize = pvolume_info->rsize;
3434 3435
	cifs_sb->wsize = pvolume_info->wsize;

S
Steve French 已提交
3436 3437 3438 3439
	cifs_sb->mnt_uid = pvolume_info->linux_uid;
	cifs_sb->mnt_gid = pvolume_info->linux_gid;
	cifs_sb->mnt_file_mode = pvolume_info->file_mode;
	cifs_sb->mnt_dir_mode = pvolume_info->dir_mode;
3440 3441
	cifs_dbg(FYI, "file mode: 0x%hx  dir mode: 0x%hx\n",
		 cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode);
S
Steve French 已提交
3442

3443
	cifs_sb->actimeo = pvolume_info->actimeo;
3444
	cifs_sb->local_nls = pvolume_info->local_nls;
3445

S
Steve French 已提交
3446 3447 3448 3449
	if (pvolume_info->noperm)
		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
	if (pvolume_info->setuids)
		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
3450 3451
	if (pvolume_info->setuidfromacl)
		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UID_FROM_ACL;
S
Steve French 已提交
3452 3453 3454
	if (pvolume_info->server_ino)
		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM;
	if (pvolume_info->remap)
3455 3456
		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SFM_CHR;
	if (pvolume_info->sfu_remap)
S
Steve French 已提交
3457 3458 3459 3460 3461 3462 3463
		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
	if (pvolume_info->no_xattr)
		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
	if (pvolume_info->sfu_emul)
		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL;
	if (pvolume_info->nobrl)
		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL;
3464
	if (pvolume_info->nostrictsync)
S
Steve French 已提交
3465
		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOSSYNC;
3466 3467
	if (pvolume_info->mand_lock)
		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOPOSIXBRL;
3468 3469
	if (pvolume_info->rwpidforward)
		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_RWPIDFORWARD;
S
Steve French 已提交
3470 3471
	if (pvolume_info->cifs_acl)
		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
3472
	if (pvolume_info->backupuid_specified) {
3473
		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_BACKUPUID;
3474 3475 3476
		cifs_sb->mnt_backupuid = pvolume_info->backupuid;
	}
	if (pvolume_info->backupgid_specified) {
3477
		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_BACKUPGID;
3478 3479
		cifs_sb->mnt_backupgid = pvolume_info->backupgid;
	}
S
Steve French 已提交
3480 3481 3482 3483 3484 3485
	if (pvolume_info->override_uid)
		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
	if (pvolume_info->override_gid)
		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID;
	if (pvolume_info->dynperm)
		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM;
3486 3487
	if (pvolume_info->fsc)
		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_FSCACHE;
J
Jeff Layton 已提交
3488 3489 3490
	if (pvolume_info->multiuser)
		cifs_sb->mnt_cifs_flags |= (CIFS_MOUNT_MULTIUSER |
					    CIFS_MOUNT_NO_PERM);
3491 3492
	if (pvolume_info->strict_io)
		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_STRICT_IO;
S
Steve French 已提交
3493
	if (pvolume_info->direct_io) {
3494
		cifs_dbg(FYI, "mounting share using direct i/o\n");
S
Steve French 已提交
3495 3496
		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
	}
3497 3498
	if (pvolume_info->mfsymlinks) {
		if (pvolume_info->sfu_emul) {
3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510
			/*
			 * Our SFU ("Services for Unix" emulation does not allow
			 * creating symlinks but does allow reading existing SFU
			 * symlinks (it does allow both creating and reading SFU
			 * style mknod and FIFOs though). When "mfsymlinks" and
			 * "sfu" are both enabled at the same time, it allows
			 * reading both types of symlinks, but will only create
			 * them with mfsymlinks format. This allows better
			 * Apple compatibility (probably better for Samba too)
			 * while still recognizing old Windows style symlinks.
			 */
			cifs_dbg(VFS, "mount options mfsymlinks and sfu both enabled\n");
3511
		}
3512
		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MF_SYMLINKS;
3513
	}
S
Steve French 已提交
3514 3515

	if ((pvolume_info->cifs_acl) && (pvolume_info->dynperm))
3516
		cifs_dbg(VFS, "mount option dynperm ignored if cifsacl mount option supported\n");
3517 3518 3519 3520 3521 3522 3523 3524

	if (pvolume_info->prepath) {
		cifs_sb->prepath = kstrdup(pvolume_info->prepath, GFP_KERNEL);
		if (cifs_sb->prepath == NULL)
			return -ENOMEM;
	}

	return 0;
3525 3526
}

J
Jeff Layton 已提交
3527 3528
static void
cleanup_volume_info_contents(struct smb_vol *volume_info)
I
Igor Mammedov 已提交
3529
{
3530
	kfree(volume_info->username);
I
Igor Mammedov 已提交
3531
	kzfree(volume_info->password);
3532
	kfree(volume_info->UNC);
3533 3534
	kfree(volume_info->domainname);
	kfree(volume_info->iocharset);
I
Igor Mammedov 已提交
3535
	kfree(volume_info->prepath);
J
Jeff Layton 已提交
3536 3537 3538 3539 3540 3541 3542 3543
}

void
cifs_cleanup_volume_info(struct smb_vol *volume_info)
{
	if (!volume_info)
		return;
	cleanup_volume_info_contents(volume_info);
I
Igor Mammedov 已提交
3544 3545 3546
	kfree(volume_info);
}

J
Jeff Layton 已提交
3547

S
Steve French 已提交
3548
#ifdef CONFIG_CIFS_DFS_UPCALL
3549 3550 3551 3552
/*
 * cifs_build_path_to_root returns full path to root when we do not have an
 * exiting connection (tcon)
 */
I
Igor Mammedov 已提交
3553
static char *
3554
build_unc_path_to_root(const struct smb_vol *vol,
I
Igor Mammedov 已提交
3555 3556
		const struct cifs_sb_info *cifs_sb)
{
3557
	char *full_path, *pos;
3558
	unsigned int pplen = vol->prepath ? strlen(vol->prepath) + 1 : 0;
3559
	unsigned int unc_len = strnlen(vol->UNC, MAX_TREE_SIZE + 1);
I
Igor Mammedov 已提交
3560

3561
	full_path = kmalloc(unc_len + pplen + 1, GFP_KERNEL);
I
Igor Mammedov 已提交
3562 3563 3564
	if (full_path == NULL)
		return ERR_PTR(-ENOMEM);

3565 3566 3567 3568
	strncpy(full_path, vol->UNC, unc_len);
	pos = full_path + unc_len;

	if (pplen) {
3569 3570
		*pos = CIFS_DIR_SEP(cifs_sb);
		strncpy(pos + 1, vol->prepath, pplen);
3571 3572 3573 3574
		pos += pplen;
	}

	*pos = '\0'; /* add trailing null */
3575
	convert_delimiter(full_path, CIFS_DIR_SEP(cifs_sb));
3576
	cifs_dbg(FYI, "%s: full_path=%s\n", __func__, full_path);
I
Igor Mammedov 已提交
3577 3578
	return full_path;
}
3579 3580 3581 3582

/*
 * Perform a dfs referral query for a share and (optionally) prefix
 *
3583 3584 3585
 * If a referral is found, cifs_sb->mountdata will be (re-)allocated
 * to a string containing updated options for the submount.  Otherwise it
 * will be left untouched.
3586 3587 3588 3589 3590
 *
 * Returns the rc from get_dfs_path to the caller, which can be used to
 * determine whether there were referrals.
 */
static int
3591
expand_dfs_referral(const unsigned int xid, struct cifs_ses *ses,
3592
		    struct smb_vol *volume_info, struct cifs_sb_info *cifs_sb,
3593
		    int check_prefix)
3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606
{
	int rc;
	unsigned int num_referrals = 0;
	struct dfs_info3_param *referrals = NULL;
	char *full_path = NULL, *ref_path = NULL, *mdata = NULL;

	full_path = build_unc_path_to_root(volume_info, cifs_sb);
	if (IS_ERR(full_path))
		return PTR_ERR(full_path);

	/* For DFS paths, skip the first '\' of the UNC */
	ref_path = check_prefix ? full_path + 1 : volume_info->UNC + 1;

3607
	rc = get_dfs_path(xid, ses, ref_path, cifs_sb->local_nls,
3608
			  &num_referrals, &referrals, cifs_remap(cifs_sb));
3609 3610 3611 3612 3613 3614 3615 3616 3617

	if (!rc && num_referrals > 0) {
		char *fake_devname = NULL;

		mdata = cifs_compose_mount_options(cifs_sb->mountdata,
						   full_path + 1, referrals,
						   &fake_devname);

		free_dfs_info_array(referrals, num_referrals);
3618

3619 3620 3621
		if (IS_ERR(mdata)) {
			rc = PTR_ERR(mdata);
			mdata = NULL;
J
Jeff Layton 已提交
3622 3623 3624 3625
		} else {
			cleanup_volume_info_contents(volume_info);
			rc = cifs_setup_volume_info(volume_info, mdata,
							fake_devname);
3626
		}
J
Jeff Layton 已提交
3627 3628
		kfree(fake_devname);
		kfree(cifs_sb->mountdata);
3629
		cifs_sb->mountdata = mdata;
3630 3631 3632 3633
	}
	kfree(full_path);
	return rc;
}
S
Steve French 已提交
3634
#endif
I
Igor Mammedov 已提交
3635

3636 3637 3638
static int
cifs_setup_volume_info(struct smb_vol *volume_info, char *mount_data,
			const char *devname)
L
Linus Torvalds 已提交
3639
{
3640
	int rc = 0;
L
Linus Torvalds 已提交
3641

3642 3643
	if (cifs_parse_mount_options(mount_data, devname, volume_info))
		return -EINVAL;
L
Linus Torvalds 已提交
3644

3645
	if (volume_info->nullauth) {
3646
		cifs_dbg(FYI, "Anonymous login\n");
J
Jeff Layton 已提交
3647 3648
		kfree(volume_info->username);
		volume_info->username = NULL;
3649
	} else if (volume_info->username) {
L
Linus Torvalds 已提交
3650
		/* BB fixme parse for domain name here */
3651
		cifs_dbg(FYI, "Username: %s\n", volume_info->username);
L
Linus Torvalds 已提交
3652
	} else {
3653
		cifs_dbg(VFS, "No username specified\n");
3654 3655
	/* In userspace mount helper we can get user name from alternate
	   locations such as env variables and files on disk */
3656
		return -EINVAL;
L
Linus Torvalds 已提交
3657 3658 3659
	}

	/* this is needed for ASCII cp to Unicode converts */
3660
	if (volume_info->iocharset == NULL) {
3661 3662
		/* load_nls_default cannot return null */
		volume_info->local_nls = load_nls_default();
L
Linus Torvalds 已提交
3663
	} else {
3664 3665
		volume_info->local_nls = load_nls(volume_info->iocharset);
		if (volume_info->local_nls == NULL) {
3666
			cifs_dbg(VFS, "CIFS mount error: iocharset %s not found\n",
3667
				 volume_info->iocharset);
3668
			return -ELIBACC;
L
Linus Torvalds 已提交
3669 3670
		}
	}
3671 3672 3673 3674

	return rc;
}

3675 3676 3677 3678 3679 3680
struct smb_vol *
cifs_get_volume_info(char *mount_data, const char *devname)
{
	int rc;
	struct smb_vol *volume_info;

3681
	volume_info = kmalloc(sizeof(struct smb_vol), GFP_KERNEL);
3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693
	if (!volume_info)
		return ERR_PTR(-ENOMEM);

	rc = cifs_setup_volume_info(volume_info, mount_data, devname);
	if (rc) {
		cifs_cleanup_volume_info(volume_info);
		volume_info = ERR_PTR(rc);
	}

	return volume_info;
}

3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731
static int
cifs_are_all_path_components_accessible(struct TCP_Server_Info *server,
					unsigned int xid,
					struct cifs_tcon *tcon,
					struct cifs_sb_info *cifs_sb,
					char *full_path)
{
	int rc;
	char *s;
	char sep, tmp;

	sep = CIFS_DIR_SEP(cifs_sb);
	s = full_path;

	rc = server->ops->is_path_accessible(xid, tcon, cifs_sb, "");
	while (rc == 0) {
		/* skip separators */
		while (*s == sep)
			s++;
		if (!*s)
			break;
		/* next separator */
		while (*s && *s != sep)
			s++;

		/*
		 * temporarily null-terminate the path at the end of
		 * the current component
		 */
		tmp = *s;
		*s = 0;
		rc = server->ops->is_path_accessible(xid, tcon, cifs_sb,
						     full_path);
		*s = tmp;
	}
	return rc;
}

3732
int
3733
cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info)
3734
{
3735
	int rc;
3736
	unsigned int xid;
3737
	struct cifs_ses *ses;
3738
	struct cifs_tcon *tcon;
3739
	struct TCP_Server_Info *server;
3740 3741 3742 3743
	char   *full_path;
	struct tcon_link *tlink;
#ifdef CONFIG_CIFS_DFS_UPCALL
	int referral_walks_count = 0;
3744
#endif
3745

3746
#ifdef CONFIG_CIFS_DFS_UPCALL
3747 3748 3749 3750 3751
try_mount_again:
	/* cleanup activities if we're chasing a referral */
	if (referral_walks_count) {
		if (tcon)
			cifs_put_tcon(tcon);
3752 3753
		else if (ses)
			cifs_put_smb_ses(ses);
3754

3755 3756
		cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_POSIX_PATHS;

3757
		free_xid(xid);
3758 3759
	}
#endif
3760
	rc = 0;
3761
	tcon = NULL;
3762 3763
	ses = NULL;
	server = NULL;
3764 3765 3766
	full_path = NULL;
	tlink = NULL;

3767
	xid = get_xid();
L
Linus Torvalds 已提交
3768

3769
	/* get a reference to a tcp session */
3770 3771 3772
	server = cifs_get_tcp_session(volume_info);
	if (IS_ERR(server)) {
		rc = PTR_ERR(server);
3773
		goto out;
L
Linus Torvalds 已提交
3774
	}
3775 3776 3777 3778 3779
	if ((volume_info->max_credits < 20) ||
	     (volume_info->max_credits > 60000))
		server->max_credits = SMB2_MAX_CREDITS_AVAILABLE;
	else
		server->max_credits = volume_info->max_credits;
3780
	/* get a reference to a SMB session */
3781 3782 3783 3784
	ses = cifs_get_smb_ses(server, volume_info);
	if (IS_ERR(ses)) {
		rc = PTR_ERR(ses);
		ses = NULL;
3785
		goto mount_fail_check;
L
Linus Torvalds 已提交
3786
	}
3787

3788 3789 3790 3791 3792 3793
	if ((volume_info->persistent == true) && ((ses->server->capabilities &
		SMB2_GLOBAL_CAP_PERSISTENT_HANDLES) == 0)) {
		cifs_dbg(VFS, "persistent handles not supported by server\n");
		rc = -EOPNOTSUPP;
		goto mount_fail_check;
	}
S
Steve French 已提交
3794

3795
	/* search for existing tcon to this server share */
3796
	tcon = cifs_get_tcon(ses, volume_info);
3797 3798 3799
	if (IS_ERR(tcon)) {
		rc = PTR_ERR(tcon);
		tcon = NULL;
3800 3801 3802
		if (rc == -EACCES)
			goto mount_fail_check;

I
Igor Mammedov 已提交
3803
		goto remote_path_check;
3804
	}
I
Igor Mammedov 已提交
3805

S
Steve French 已提交
3806
	/* tell server which Unix caps we support */
3807
	if (cap_unix(tcon->ses)) {
S
Steve French 已提交
3808 3809
		/* reset of caps checks mount to see if unix extensions
		   disabled for just this mount */
3810
		reset_cifs_unix_caps(xid, tcon, cifs_sb, volume_info);
3811 3812 3813 3814 3815 3816 3817
		if ((tcon->ses->server->tcpStatus == CifsNeedReconnect) &&
		    (le64_to_cpu(tcon->fsUnixInfo.Capability) &
		     CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)) {
			rc = -EACCES;
			goto mount_fail_check;
		}
	} else
S
Steve French 已提交
3818
		tcon->unix_ext = 0; /* server does not support them */
3819

3820 3821 3822
	/* do not care if a following call succeed - informational */
	if (!tcon->ipc && server->ops->qfs_tcon)
		server->ops->qfs_tcon(xid, tcon);
3823

3824 3825
	cifs_sb->wsize = server->ops->negotiate_wsize(tcon, volume_info);
	cifs_sb->rsize = server->ops->negotiate_rsize(tcon, volume_info);
3826

I
Igor Mammedov 已提交
3827
remote_path_check:
3828 3829 3830 3831 3832 3833 3834 3835 3836
#ifdef CONFIG_CIFS_DFS_UPCALL
	/*
	 * Perform an unconditional check for whether there are DFS
	 * referrals for this path without prefix, to provide support
	 * for DFS referrals from w2k8 servers which don't seem to respond
	 * with PATH_NOT_COVERED to requests that include the prefix.
	 * Chase the referral if found, otherwise continue normally.
	 */
	if (referral_walks_count == 0) {
3837 3838
		int refrc = expand_dfs_referral(xid, ses, volume_info, cifs_sb,
						false);
3839 3840 3841 3842 3843 3844 3845
		if (!refrc) {
			referral_walks_count++;
			goto try_mount_again;
		}
	}
#endif

3846
	/* check if a whole path is not remote */
3847
	if (!rc && tcon) {
3848 3849 3850 3851
		if (!server->ops->is_path_accessible) {
			rc = -ENOSYS;
			goto mount_fail_check;
		}
3852 3853 3854
		/*
		 * cifs_build_path_to_root works only when we have a valid tcon
		 */
3855 3856
		full_path = cifs_build_path_to_root(volume_info, cifs_sb, tcon,
					tcon->Flags & SMB_SHARE_IS_IN_DFS);
3857 3858 3859 3860
		if (full_path == NULL) {
			rc = -ENOMEM;
			goto mount_fail_check;
		}
3861 3862
		rc = server->ops->is_path_accessible(xid, tcon, cifs_sb,
						     full_path);
3863
		if (rc != 0 && rc != -EREMOTE) {
3864 3865 3866
			kfree(full_path);
			goto mount_fail_check;
		}
3867

3868 3869
		if (rc != -EREMOTE) {
			rc = cifs_are_all_path_components_accessible(server,
3870 3871
							     xid, tcon, cifs_sb,
							     full_path);
3872 3873 3874 3875 3876 3877
			if (rc != 0) {
				cifs_dbg(VFS, "cannot query dirs between root and final path, "
					 "enabling CIFS_MOUNT_USE_PREFIX_PATH\n");
				cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH;
				rc = 0;
			}
3878
		}
3879 3880 3881
		kfree(full_path);
	}

I
Igor Mammedov 已提交
3882 3883
	/* get referral if needed */
	if (rc == -EREMOTE) {
3884
#ifdef CONFIG_CIFS_DFS_UPCALL
3885 3886 3887 3888 3889 3890 3891 3892 3893 3894
		if (referral_walks_count > MAX_NESTED_LINKS) {
			/*
			 * BB: when we implement proper loop detection,
			 *     we will remove this check. But now we need it
			 *     to prevent an indefinite loop if 'DFS tree' is
			 *     misconfigured (i.e. has loops).
			 */
			rc = -ELOOP;
			goto mount_fail_check;
		}
I
Igor Mammedov 已提交
3895

3896
		rc = expand_dfs_referral(xid, ses, volume_info, cifs_sb, true);
3897

3898
		if (!rc) {
3899
			referral_walks_count++;
I
Igor Mammedov 已提交
3900 3901
			goto try_mount_again;
		}
3902
		goto mount_fail_check;
3903 3904 3905
#else /* No DFS support, return error on mount */
		rc = -EOPNOTSUPP;
#endif
I
Igor Mammedov 已提交
3906 3907
	}

3908 3909 3910 3911 3912 3913 3914 3915 3916 3917
	if (rc)
		goto mount_fail_check;

	/* now, hang the tcon off of the superblock */
	tlink = kzalloc(sizeof *tlink, GFP_KERNEL);
	if (tlink == NULL) {
		rc = -ENOMEM;
		goto mount_fail_check;
	}

3918
	tlink->tl_uid = ses->linux_uid;
3919 3920 3921 3922 3923
	tlink->tl_tcon = tcon;
	tlink->tl_time = jiffies;
	set_bit(TCON_LINK_MASTER, &tlink->tl_flags);
	set_bit(TCON_LINK_IN_TREE, &tlink->tl_flags);

J
Jeff Layton 已提交
3924
	cifs_sb->master_tlink = tlink;
3925
	spin_lock(&cifs_sb->tlink_tree_lock);
J
Jeff Layton 已提交
3926
	tlink_rb_insert(&cifs_sb->tlink_tree, tlink);
3927
	spin_unlock(&cifs_sb->tlink_tree_lock);
3928

J
Jeff Layton 已提交
3929
	queue_delayed_work(cifsiod_wq, &cifs_sb->prune_tlinks,
3930 3931
				TLINK_IDLE_EXPIRE);

I
Igor Mammedov 已提交
3932 3933 3934 3935
mount_fail_check:
	/* on error free sesinfo and tcon struct if needed */
	if (rc) {
		/* If find_unc succeeded then rc == 0 so we can not end */
L
Lucas De Marchi 已提交
3936
		/* up accidentally freeing someone elses tcon struct */
I
Igor Mammedov 已提交
3937 3938
		if (tcon)
			cifs_put_tcon(tcon);
3939 3940
		else if (ses)
			cifs_put_smb_ses(ses);
I
Igor Mammedov 已提交
3941
		else
3942
			cifs_put_tcp_session(server, 0);
I
Igor Mammedov 已提交
3943 3944
	}

3945
out:
3946
	free_xid(xid);
L
Linus Torvalds 已提交
3947 3948 3949
	return rc;
}

3950 3951 3952 3953
/*
 * Issue a TREE_CONNECT request. Note that for IPC$ shares, that the tcon
 * pointer may be NULL.
 */
L
Linus Torvalds 已提交
3954
int
3955
CIFSTCon(const unsigned int xid, struct cifs_ses *ses,
3956
	 const char *tree, struct cifs_tcon *tcon,
L
Linus Torvalds 已提交
3957 3958 3959 3960 3961 3962 3963 3964
	 const struct nls_table *nls_codepage)
{
	struct smb_hdr *smb_buffer;
	struct smb_hdr *smb_buffer_response;
	TCONX_REQ *pSMB;
	TCONX_RSP *pSMBr;
	unsigned char *bcc_ptr;
	int rc = 0;
3965 3966
	int length;
	__u16 bytes_left, count;
L
Linus Torvalds 已提交
3967 3968 3969 3970 3971

	if (ses == NULL)
		return -EIO;

	smb_buffer = cifs_buf_get();
S
Steve French 已提交
3972
	if (smb_buffer == NULL)
L
Linus Torvalds 已提交
3973
		return -ENOMEM;
S
Steve French 已提交
3974

L
Linus Torvalds 已提交
3975 3976 3977 3978
	smb_buffer_response = smb_buffer;

	header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
			NULL /*no tid */ , 4 /*wct */ );
3979

3980
	smb_buffer->Mid = get_next_mid(ses->server);
L
Linus Torvalds 已提交
3981 3982 3983 3984 3985 3986 3987
	smb_buffer->Uid = ses->Suid;
	pSMB = (TCONX_REQ *) smb_buffer;
	pSMBr = (TCONX_RSP *) smb_buffer_response;

	pSMB->AndXCommand = 0xFF;
	pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
	bcc_ptr = &pSMB->Password[0];
3988
	if (!tcon || (ses->server->sec_mode & SECMODE_USER)) {
3989
		pSMB->PasswordLength = cpu_to_le16(1);	/* minimum */
3990
		*bcc_ptr = 0; /* password is null byte */
3991
		bcc_ptr++;              /* skip password */
3992
		/* already aligned so no need to do it below */
3993
	} else {
3994
		pSMB->PasswordLength = cpu_to_le16(CIFS_AUTH_RESP_SIZE);
3995 3996 3997
		/* BB FIXME add code to fail this if NTLMv2 or Kerberos
		   specified as required (when that support is added to
		   the vfs in the future) as only NTLM or the much
3998
		   weaker LANMAN (which we do not send by default) is accepted
3999 4000
		   by Samba (not sure whether other servers allow
		   NTLMv2 password here) */
4001
#ifdef CONFIG_CIFS_WEAK_PW_HASH
4002
		if ((global_secflags & CIFSSEC_MAY_LANMAN) &&
4003
		    (ses->sectype == LANMAN))
4004
			calc_lanman_hash(tcon->password, ses->server->cryptkey,
4005
					 ses->server->sec_mode &
4006 4007
					    SECMODE_PW_ENCRYPT ? true : false,
					 bcc_ptr);
4008 4009
		else
#endif /* CIFS_WEAK_PW_HASH */
4010
		rc = SMBNTencrypt(tcon->password, ses->server->cryptkey,
4011
					bcc_ptr, nls_codepage);
4012 4013 4014 4015 4016 4017
		if (rc) {
			cifs_dbg(FYI, "%s Can't generate NTLM rsp. Error: %d\n",
				 __func__, rc);
			cifs_buf_release(smb_buffer);
			return rc;
		}
4018

4019
		bcc_ptr += CIFS_AUTH_RESP_SIZE;
S
Steve French 已提交
4020
		if (ses->capabilities & CAP_UNICODE) {
4021 4022 4023 4024
			/* must align unicode strings */
			*bcc_ptr = 0; /* null byte password */
			bcc_ptr++;
		}
4025
	}
L
Linus Torvalds 已提交
4026

4027
	if (ses->server->sign)
L
Linus Torvalds 已提交
4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038
		smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;

	if (ses->capabilities & CAP_STATUS32) {
		smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
	}
	if (ses->capabilities & CAP_DFS) {
		smb_buffer->Flags2 |= SMBFLG2_DFS;
	}
	if (ses->capabilities & CAP_UNICODE) {
		smb_buffer->Flags2 |= SMBFLG2_UNICODE;
		length =
4039
		    cifs_strtoUTF16((__le16 *) bcc_ptr, tree,
4040
			6 /* max utf8 char length in bytes */ *
4041 4042
			(/* server len*/ + 256 /* share len */), nls_codepage);
		bcc_ptr += 2 * length;	/* convert num 16 bit words to bytes */
L
Linus Torvalds 已提交
4043 4044 4045 4046 4047 4048 4049 4050 4051
		bcc_ptr += 2;	/* skip trailing null */
	} else {		/* ASCII */
		strcpy(bcc_ptr, tree);
		bcc_ptr += strlen(tree) + 1;
	}
	strcpy(bcc_ptr, "?????");
	bcc_ptr += strlen("?????");
	bcc_ptr += 1;
	count = bcc_ptr - &pSMB->Password[0];
4052 4053
	pSMB->hdr.smb_buf_length = cpu_to_be32(be32_to_cpu(
					pSMB->hdr.smb_buf_length) + count);
L
Linus Torvalds 已提交
4054 4055
	pSMB->ByteCount = cpu_to_le16(count);

4056
	rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length,
4057
			 0);
L
Linus Torvalds 已提交
4058 4059 4060

	/* above now done in SendReceive */
	if ((rc == 0) && (tcon != NULL)) {
4061 4062
		bool is_unicode;

L
Linus Torvalds 已提交
4063
		tcon->tidStatus = CifsGood;
S
Steve French 已提交
4064
		tcon->need_reconnect = false;
L
Linus Torvalds 已提交
4065 4066
		tcon->tid = smb_buffer_response->Tid;
		bcc_ptr = pByteArea(smb_buffer_response);
4067
		bytes_left = get_bcc(smb_buffer_response);
4068
		length = strnlen(bcc_ptr, bytes_left - 2);
4069 4070 4071 4072 4073
		if (smb_buffer->Flags2 & SMBFLG2_UNICODE)
			is_unicode = true;
		else
			is_unicode = false;

4074

4075
		/* skip service field (NB: this field is always ASCII) */
4076 4077 4078
		if (length == 3) {
			if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') &&
			    (bcc_ptr[2] == 'C')) {
4079
				cifs_dbg(FYI, "IPC connection\n");
4080 4081 4082 4083 4084
				tcon->ipc = 1;
			}
		} else if (length == 2) {
			if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) {
				/* the most common case */
4085
				cifs_dbg(FYI, "disk share connection\n");
4086 4087
			}
		}
4088
		bcc_ptr += length + 1;
4089
		bytes_left -= (length + 1);
4090
		strlcpy(tcon->treeName, tree, sizeof(tcon->treeName));
4091 4092

		/* mostly informational -- no need to fail on error here */
4093
		kfree(tcon->nativeFileSystem);
4094
		tcon->nativeFileSystem = cifs_strndup_from_utf16(bcc_ptr,
4095
						      bytes_left, is_unicode,
4096 4097
						      nls_codepage);

4098
		cifs_dbg(FYI, "nativeFileSystem=%s\n", tcon->nativeFileSystem);
4099

S
Steve French 已提交
4100
		if ((smb_buffer_response->WordCount == 3) ||
S
Steve French 已提交
4101 4102
			 (smb_buffer_response->WordCount == 7))
			/* field is in same location */
4103 4104 4105
			tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
		else
			tcon->Flags = 0;
4106
		cifs_dbg(FYI, "Tcon flags: 0x%x\n", tcon->Flags);
L
Linus Torvalds 已提交
4107
	} else if ((rc == 0) && tcon == NULL) {
4108
		/* all we need to save for IPC$ connection */
L
Linus Torvalds 已提交
4109 4110 4111
		ses->ipc_tid = smb_buffer_response->Tid;
	}

4112
	cifs_buf_release(smb_buffer);
L
Linus Torvalds 已提交
4113 4114 4115
	return rc;
}

4116 4117 4118 4119 4120 4121 4122
static void delayed_free(struct rcu_head *p)
{
	struct cifs_sb_info *sbi = container_of(p, struct cifs_sb_info, rcu);
	unload_nls(sbi->local_nls);
	kfree(sbi);
}

A
Al Viro 已提交
4123 4124
void
cifs_umount(struct cifs_sb_info *cifs_sb)
L
Linus Torvalds 已提交
4125
{
J
Jeff Layton 已提交
4126 4127 4128
	struct rb_root *root = &cifs_sb->tlink_tree;
	struct rb_node *node;
	struct tcon_link *tlink;
4129

4130 4131
	cancel_delayed_work_sync(&cifs_sb->prune_tlinks);

J
Jeff Layton 已提交
4132 4133 4134 4135 4136 4137
	spin_lock(&cifs_sb->tlink_tree_lock);
	while ((node = rb_first(root))) {
		tlink = rb_entry(node, struct tcon_link, tl_rbnode);
		cifs_get_tlink(tlink);
		clear_bit(TCON_LINK_IN_TREE, &tlink->tl_flags);
		rb_erase(node, root);
L
Linus Torvalds 已提交
4138

J
Jeff Layton 已提交
4139 4140 4141 4142 4143
		spin_unlock(&cifs_sb->tlink_tree_lock);
		cifs_put_tlink(tlink);
		spin_lock(&cifs_sb->tlink_tree_lock);
	}
	spin_unlock(&cifs_sb->tlink_tree_lock);
4144

4145
	kfree(cifs_sb->mountdata);
4146
	kfree(cifs_sb->prepath);
4147
	call_rcu(&cifs_sb->rcu, delayed_free);
4148
}
L
Linus Torvalds 已提交
4149

4150 4151
int
cifs_negotiate_protocol(const unsigned int xid, struct cifs_ses *ses)
L
Linus Torvalds 已提交
4152 4153
{
	int rc = 0;
4154
	struct TCP_Server_Info *server = ses->server;
L
Linus Torvalds 已提交
4155

4156 4157 4158
	if (!server->ops->need_neg || !server->ops->negotiate)
		return -ENOSYS;

4159
	/* only send once per connect */
4160
	if (!server->ops->need_neg(server))
4161 4162
		return 0;

4163
	set_credits(server, 1);
4164 4165

	rc = server->ops->negotiate(xid, ses);
4166 4167
	if (rc == 0) {
		spin_lock(&GlobalMid_Lock);
4168
		if (server->tcpStatus == CifsNeedNegotiate)
4169 4170 4171 4172 4173 4174 4175 4176 4177
			server->tcpStatus = CifsGood;
		else
			rc = -EHOSTDOWN;
		spin_unlock(&GlobalMid_Lock);
	}

	return rc;
}

4178 4179 4180
int
cifs_setup_session(const unsigned int xid, struct cifs_ses *ses,
		   struct nls_table *nls_info)
4181
{
4182
	int rc = -ENOSYS;
4183
	struct TCP_Server_Info *server = ses->server;
4184

4185
	ses->capabilities = server->capabilities;
4186
	if (linuxExtEnabled == 0)
4187
		ses->capabilities &= (~server->vals->cap_unix);
4188

4189
	cifs_dbg(FYI, "Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d\n",
4190
		 server->sec_mode, server->capabilities, server->timeAdj);
4191

4192 4193 4194 4195 4196 4197 4198 4199
	if (ses->auth_key.response) {
		cifs_dbg(VFS, "Free previous auth_key.response = %p\n",
			 ses->auth_key.response);
		kfree(ses->auth_key.response);
		ses->auth_key.response = NULL;
		ses->auth_key.len = 0;
	}

4200 4201 4202
	if (server->ops->sess_setup)
		rc = server->ops->sess_setup(xid, ses, nls_info);

4203
	if (rc)
4204
		cifs_dbg(VFS, "Send error in SessSetup = %d\n", rc);
4205

L
Linus Torvalds 已提交
4206 4207 4208
	return rc;
}

4209 4210 4211
static int
cifs_set_vol_auth(struct smb_vol *vol, struct cifs_ses *ses)
{
4212 4213 4214 4215
	vol->sectype = ses->sectype;

	/* krb5 is special, since we don't need username or pw */
	if (vol->sectype == Kerberos)
4216 4217 4218 4219 4220
		return 0;

	return cifs_set_cifscreds(vol, ses);
}

4221
static struct cifs_tcon *
4222
cifs_construct_tcon(struct cifs_sb_info *cifs_sb, kuid_t fsuid)
4223
{
4224
	int rc;
4225 4226 4227
	struct cifs_tcon *master_tcon = cifs_sb_master_tcon(cifs_sb);
	struct cifs_ses *ses;
	struct cifs_tcon *tcon = NULL;
4228 4229 4230
	struct smb_vol *vol_info;

	vol_info = kzalloc(sizeof(*vol_info), GFP_KERNEL);
4231 4232
	if (vol_info == NULL)
		return ERR_PTR(-ENOMEM);
4233 4234 4235 4236 4237 4238 4239 4240 4241

	vol_info->local_nls = cifs_sb->local_nls;
	vol_info->linux_uid = fsuid;
	vol_info->cred_uid = fsuid;
	vol_info->UNC = master_tcon->treeName;
	vol_info->retry = master_tcon->retry;
	vol_info->nocase = master_tcon->nocase;
	vol_info->local_lease = master_tcon->local_lease;
	vol_info->no_linux_ext = !master_tcon->unix_ext;
4242 4243
	vol_info->sectype = master_tcon->ses->sectype;
	vol_info->sign = master_tcon->ses->sign;
4244

4245 4246 4247 4248 4249
	rc = cifs_set_vol_auth(vol_info, master_tcon->ses);
	if (rc) {
		tcon = ERR_PTR(rc);
		goto out;
	}
4250 4251

	/* get a reference for the same TCP session */
4252
	spin_lock(&cifs_tcp_ses_lock);
4253
	++master_tcon->ses->server->srv_count;
4254
	spin_unlock(&cifs_tcp_ses_lock);
4255 4256 4257

	ses = cifs_get_smb_ses(master_tcon->ses->server, vol_info);
	if (IS_ERR(ses)) {
4258
		tcon = (struct cifs_tcon *)ses;
4259
		cifs_put_tcp_session(master_tcon->ses->server, 0);
4260 4261 4262 4263 4264 4265 4266 4267 4268
		goto out;
	}

	tcon = cifs_get_tcon(ses, vol_info);
	if (IS_ERR(tcon)) {
		cifs_put_smb_ses(ses);
		goto out;
	}

4269
	if (cap_unix(ses))
4270 4271
		reset_cifs_unix_caps(0, tcon, NULL, vol_info);
out:
4272 4273
	kfree(vol_info->username);
	kfree(vol_info->password);
4274 4275 4276 4277 4278
	kfree(vol_info);

	return tcon;
}

4279
struct cifs_tcon *
4280 4281 4282 4283 4284
cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb)
{
	return tlink_tcon(cifs_sb_master_tlink(cifs_sb));
}

J
Jeff Layton 已提交
4285 4286
/* find and return a tlink with given uid */
static struct tcon_link *
4287
tlink_rb_search(struct rb_root *root, kuid_t uid)
J
Jeff Layton 已提交
4288 4289 4290 4291 4292 4293 4294
{
	struct rb_node *node = root->rb_node;
	struct tcon_link *tlink;

	while (node) {
		tlink = rb_entry(node, struct tcon_link, tl_rbnode);

4295
		if (uid_gt(tlink->tl_uid, uid))
J
Jeff Layton 已提交
4296
			node = node->rb_left;
4297
		else if (uid_lt(tlink->tl_uid, uid))
J
Jeff Layton 已提交
4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315
			node = node->rb_right;
		else
			return tlink;
	}
	return NULL;
}

/* insert a tcon_link into the tree */
static void
tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink)
{
	struct rb_node **new = &(root->rb_node), *parent = NULL;
	struct tcon_link *tlink;

	while (*new) {
		tlink = rb_entry(*new, struct tcon_link, tl_rbnode);
		parent = *new;

4316
		if (uid_gt(tlink->tl_uid, new_tlink->tl_uid))
J
Jeff Layton 已提交
4317 4318 4319 4320 4321 4322 4323 4324 4325
			new = &((*new)->rb_left);
		else
			new = &((*new)->rb_right);
	}

	rb_link_node(&new_tlink->tl_rbnode, parent, new);
	rb_insert_color(&new_tlink->tl_rbnode, root);
}

4326 4327 4328 4329 4330 4331 4332
/*
 * Find or construct an appropriate tcon given a cifs_sb and the fsuid of the
 * current task.
 *
 * If the superblock doesn't refer to a multiuser mount, then just return
 * the master tcon for the mount.
 *
4333
 * First, search the rbtree for an existing tcon for this fsuid. If one
4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345
 * exists, then check to see if it's pending construction. If it is then wait
 * for construction to complete. Once it's no longer pending, check to see if
 * it failed and either return an error or retry construction, depending on
 * the timeout.
 *
 * If one doesn't exist then insert a new tcon_link struct into the tree and
 * try to construct a new one.
 */
struct tcon_link *
cifs_sb_tlink(struct cifs_sb_info *cifs_sb)
{
	int ret;
4346
	kuid_t fsuid = current_fsuid();
4347 4348 4349 4350 4351 4352
	struct tcon_link *tlink, *newtlink;

	if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER))
		return cifs_get_tlink(cifs_sb_master_tlink(cifs_sb));

	spin_lock(&cifs_sb->tlink_tree_lock);
J
Jeff Layton 已提交
4353
	tlink = tlink_rb_search(&cifs_sb->tlink_tree, fsuid);
4354 4355 4356 4357 4358 4359 4360 4361
	if (tlink)
		cifs_get_tlink(tlink);
	spin_unlock(&cifs_sb->tlink_tree_lock);

	if (tlink == NULL) {
		newtlink = kzalloc(sizeof(*tlink), GFP_KERNEL);
		if (newtlink == NULL)
			return ERR_PTR(-ENOMEM);
J
Jeff Layton 已提交
4362
		newtlink->tl_uid = fsuid;
4363 4364 4365 4366 4367 4368 4369
		newtlink->tl_tcon = ERR_PTR(-EACCES);
		set_bit(TCON_LINK_PENDING, &newtlink->tl_flags);
		set_bit(TCON_LINK_IN_TREE, &newtlink->tl_flags);
		cifs_get_tlink(newtlink);

		spin_lock(&cifs_sb->tlink_tree_lock);
		/* was one inserted after previous search? */
J
Jeff Layton 已提交
4370
		tlink = tlink_rb_search(&cifs_sb->tlink_tree, fsuid);
4371 4372 4373 4374 4375 4376 4377
		if (tlink) {
			cifs_get_tlink(tlink);
			spin_unlock(&cifs_sb->tlink_tree_lock);
			kfree(newtlink);
			goto wait_for_construction;
		}
		tlink = newtlink;
J
Jeff Layton 已提交
4378 4379
		tlink_rb_insert(&cifs_sb->tlink_tree, tlink);
		spin_unlock(&cifs_sb->tlink_tree_lock);
4380 4381 4382 4383 4384 4385
	} else {
wait_for_construction:
		ret = wait_on_bit(&tlink->tl_flags, TCON_LINK_PENDING,
				  TASK_INTERRUPTIBLE);
		if (ret) {
			cifs_put_tlink(tlink);
4386
			return ERR_PTR(-ERESTARTSYS);
4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413
		}

		/* if it's good, return it */
		if (!IS_ERR(tlink->tl_tcon))
			return tlink;

		/* return error if we tried this already recently */
		if (time_before(jiffies, tlink->tl_time + TLINK_ERROR_EXPIRE)) {
			cifs_put_tlink(tlink);
			return ERR_PTR(-EACCES);
		}

		if (test_and_set_bit(TCON_LINK_PENDING, &tlink->tl_flags))
			goto wait_for_construction;
	}

	tlink->tl_tcon = cifs_construct_tcon(cifs_sb, fsuid);
	clear_bit(TCON_LINK_PENDING, &tlink->tl_flags);
	wake_up_bit(&tlink->tl_flags, TCON_LINK_PENDING);

	if (IS_ERR(tlink->tl_tcon)) {
		cifs_put_tlink(tlink);
		return ERR_PTR(-EACCES);
	}

	return tlink;
}
4414 4415 4416 4417 4418 4419 4420 4421 4422 4423

/*
 * periodic workqueue job that scans tcon_tree for a superblock and closes
 * out tcons.
 */
static void
cifs_prune_tlinks(struct work_struct *work)
{
	struct cifs_sb_info *cifs_sb = container_of(work, struct cifs_sb_info,
						    prune_tlinks.work);
J
Jeff Layton 已提交
4424 4425 4426 4427
	struct rb_root *root = &cifs_sb->tlink_tree;
	struct rb_node *node = rb_first(root);
	struct rb_node *tmp;
	struct tcon_link *tlink;
4428

J
Jeff Layton 已提交
4429 4430 4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446
	/*
	 * Because we drop the spinlock in the loop in order to put the tlink
	 * it's not guarded against removal of links from the tree. The only
	 * places that remove entries from the tree are this function and
	 * umounts. Because this function is non-reentrant and is canceled
	 * before umount can proceed, this is safe.
	 */
	spin_lock(&cifs_sb->tlink_tree_lock);
	node = rb_first(root);
	while (node != NULL) {
		tmp = node;
		node = rb_next(tmp);
		tlink = rb_entry(tmp, struct tcon_link, tl_rbnode);

		if (test_bit(TCON_LINK_MASTER, &tlink->tl_flags) ||
		    atomic_read(&tlink->tl_count) != 0 ||
		    time_after(tlink->tl_time + TLINK_IDLE_EXPIRE, jiffies))
			continue;
4447

J
Jeff Layton 已提交
4448 4449 4450 4451 4452 4453 4454 4455 4456
		cifs_get_tlink(tlink);
		clear_bit(TCON_LINK_IN_TREE, &tlink->tl_flags);
		rb_erase(tmp, root);

		spin_unlock(&cifs_sb->tlink_tree_lock);
		cifs_put_tlink(tlink);
		spin_lock(&cifs_sb->tlink_tree_lock);
	}
	spin_unlock(&cifs_sb->tlink_tree_lock);
4457

J
Jeff Layton 已提交
4458
	queue_delayed_work(cifsiod_wq, &cifs_sb->prune_tlinks,
4459 4460
				TLINK_IDLE_EXPIRE);
}