blob: ecb0803bdb0e50479f50b0e874a4e87cb064e2d0 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * fs/cifs/connect.c
3 *
Steve French1080ef72011-02-24 18:07:19 +00004 * Copyright (C) International Business Machines Corp., 2002,2011
Linus Torvalds1da177e2005-04-16 15:20:36 -07005 * Author(s): Steve French (sfrench@us.ibm.com)
6 *
7 * This library is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published
9 * by the Free Software Foundation; either version 2.1 of the License, or
10 * (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
15 * the GNU Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this library; if not, write to the Free Software
Steve Frenchfb8c4b12007-07-10 01:16:18 +000019 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Linus Torvalds1da177e2005-04-16 15:20:36 -070020 */
21#include <linux/fs.h>
22#include <linux/net.h>
23#include <linux/string.h>
24#include <linux/list.h>
25#include <linux/wait.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090026#include <linux/slab.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#include <linux/pagemap.h>
28#include <linux/ctype.h>
29#include <linux/utsname.h>
30#include <linux/mempool.h>
Steve Frenchb8643e12005-04-28 22:41:07 -070031#include <linux/delay.h>
Steve Frenchf1914012005-08-18 09:37:34 -070032#include <linux/completion.h>
Igor Mammedovaaf737a2007-04-03 19:16:43 +000033#include <linux/kthread.h>
Steve French0ae0efa2005-10-10 10:57:19 -070034#include <linux/pagevec.h>
Nigel Cunningham7dfb7102006-12-06 20:34:23 -080035#include <linux/freezer.h>
Igor Mammedov5c2503a2009-04-21 19:31:05 +040036#include <linux/namei.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070037#include <asm/uaccess.h>
38#include <asm/processor.h>
Jeff Layton50b64e32009-06-02 06:55:20 -040039#include <linux/inet.h>
Paul Gortmaker143cb492011-07-01 14:23:34 -040040#include <linux/module.h>
Jeff Layton8a8798a2012-01-17 16:09:15 -050041#include <keys/user-type.h>
Steve French0e2beda2009-01-30 21:24:41 +000042#include <net/ipv6.h>
Sachin Prabhu8830d7e2012-03-23 14:40:56 -040043#include <linux/parser.h>
44
Linus Torvalds1da177e2005-04-16 15:20:36 -070045#include "cifspdu.h"
46#include "cifsglob.h"
47#include "cifsproto.h"
48#include "cifs_unicode.h"
49#include "cifs_debug.h"
50#include "cifs_fs_sb.h"
51#include "ntlmssp.h"
52#include "nterr.h"
53#include "rfc1002pdu.h"
Suresh Jayaraman488f1d2d2010-07-05 18:12:15 +053054#include "fscache.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070055
56#define CIFS_PORT 445
57#define RFC1001_PORT 139
58
Linus Torvalds1da177e2005-04-16 15:20:36 -070059extern mempool_t *cifs_req_poolp;
60
Jeff Layton2de970f2010-10-06 19:51:12 -040061/* FIXME: should these be tunable? */
Jeff Layton9d002df2010-10-06 19:51:11 -040062#define TLINK_ERROR_EXPIRE (1 * HZ)
Jeff Layton2de970f2010-10-06 19:51:12 -040063#define TLINK_IDLE_EXPIRE (600 * HZ)
Jeff Layton9d002df2010-10-06 19:51:11 -040064
Sachin Prabhu8830d7e2012-03-23 14:40:56 -040065enum {
66
67 /* Mount options that take no arguments */
68 Opt_user_xattr, Opt_nouser_xattr,
69 Opt_forceuid, Opt_noforceuid,
Jeff Layton72bd4812012-10-03 16:02:36 -040070 Opt_forcegid, Opt_noforcegid,
Sachin Prabhu8830d7e2012-03-23 14:40:56 -040071 Opt_noblocksend, Opt_noautotune,
72 Opt_hard, Opt_soft, Opt_perm, Opt_noperm,
Steve French2baa2682014-09-27 02:19:01 -050073 Opt_mapposix, Opt_nomapposix,
Sachin Prabhu8830d7e2012-03-23 14:40:56 -040074 Opt_mapchars, Opt_nomapchars, Opt_sfu,
75 Opt_nosfu, Opt_nodfs, Opt_posixpaths,
76 Opt_noposixpaths, Opt_nounix,
77 Opt_nocase,
78 Opt_brl, Opt_nobrl,
79 Opt_forcemandatorylock, Opt_setuids,
80 Opt_nosetuids, Opt_dynperm, Opt_nodynperm,
81 Opt_nohard, Opt_nosoft,
82 Opt_nointr, Opt_intr,
83 Opt_nostrictsync, Opt_strictsync,
84 Opt_serverino, Opt_noserverino,
85 Opt_rwpidforward, Opt_cifsacl, Opt_nocifsacl,
86 Opt_acl, Opt_noacl, Opt_locallease,
Jeff Layton1b359202012-09-19 15:20:27 -070087 Opt_sign, Opt_seal, Opt_noac,
Sachin Prabhu8830d7e2012-03-23 14:40:56 -040088 Opt_fsc, Opt_mfsymlinks,
Jeff Laytona0b3df52013-05-24 07:40:59 -040089 Opt_multiuser, Opt_sloppy, Opt_nosharesock,
Steve Frenchb2a30772015-09-29 21:49:28 -050090 Opt_persistent, Opt_nopersistent,
Steve French592fafe2015-11-03 10:08:53 -060091 Opt_resilient, Opt_noresilient,
Sachin Prabhu8830d7e2012-03-23 14:40:56 -040092
93 /* Mount options which take numeric value */
94 Opt_backupuid, Opt_backupgid, Opt_uid,
95 Opt_cruid, Opt_gid, Opt_file_mode,
96 Opt_dirmode, Opt_port,
97 Opt_rsize, Opt_wsize, Opt_actimeo,
98
99 /* Mount options which take string value */
100 Opt_user, Opt_pass, Opt_ip,
Jeff Layton73a999f2013-03-22 08:42:57 -0400101 Opt_domain, Opt_srcaddr, Opt_iocharset,
Sachin Prabhu8830d7e2012-03-23 14:40:56 -0400102 Opt_netbiosname, Opt_servern,
Jeff Layton23db65f2012-05-15 12:20:51 -0400103 Opt_ver, Opt_vers, Opt_sec, Opt_cache,
Sachin Prabhu8830d7e2012-03-23 14:40:56 -0400104
105 /* Mount options to be ignored */
106 Opt_ignore,
107
108 /* Options which could be blank */
109 Opt_blank_pass,
Sachin Prabhu4fe9e962012-04-10 18:12:27 +0100110 Opt_blank_user,
111 Opt_blank_ip,
Sachin Prabhu8830d7e2012-03-23 14:40:56 -0400112
113 Opt_err
114};
115
116static const match_table_t cifs_mount_option_tokens = {
117
118 { Opt_user_xattr, "user_xattr" },
119 { Opt_nouser_xattr, "nouser_xattr" },
120 { Opt_forceuid, "forceuid" },
121 { Opt_noforceuid, "noforceuid" },
Jeff Layton72bd4812012-10-03 16:02:36 -0400122 { Opt_forcegid, "forcegid" },
123 { Opt_noforcegid, "noforcegid" },
Sachin Prabhu8830d7e2012-03-23 14:40:56 -0400124 { Opt_noblocksend, "noblocksend" },
125 { Opt_noautotune, "noautotune" },
126 { Opt_hard, "hard" },
127 { Opt_soft, "soft" },
128 { Opt_perm, "perm" },
129 { Opt_noperm, "noperm" },
Steve French2baa2682014-09-27 02:19:01 -0500130 { Opt_mapchars, "mapchars" }, /* SFU style */
Sachin Prabhu8830d7e2012-03-23 14:40:56 -0400131 { Opt_nomapchars, "nomapchars" },
Steve French2baa2682014-09-27 02:19:01 -0500132 { Opt_mapposix, "mapposix" }, /* SFM style */
133 { Opt_nomapposix, "nomapposix" },
Sachin Prabhu8830d7e2012-03-23 14:40:56 -0400134 { Opt_sfu, "sfu" },
135 { Opt_nosfu, "nosfu" },
136 { Opt_nodfs, "nodfs" },
137 { Opt_posixpaths, "posixpaths" },
138 { Opt_noposixpaths, "noposixpaths" },
139 { Opt_nounix, "nounix" },
140 { Opt_nounix, "nolinux" },
141 { Opt_nocase, "nocase" },
142 { Opt_nocase, "ignorecase" },
143 { Opt_brl, "brl" },
144 { Opt_nobrl, "nobrl" },
145 { Opt_nobrl, "nolock" },
146 { Opt_forcemandatorylock, "forcemandatorylock" },
Pavel Shilovsky5cfdddc2012-03-27 20:51:15 +0400147 { Opt_forcemandatorylock, "forcemand" },
Sachin Prabhu8830d7e2012-03-23 14:40:56 -0400148 { Opt_setuids, "setuids" },
149 { Opt_nosetuids, "nosetuids" },
150 { Opt_dynperm, "dynperm" },
151 { Opt_nodynperm, "nodynperm" },
152 { Opt_nohard, "nohard" },
153 { Opt_nosoft, "nosoft" },
154 { Opt_nointr, "nointr" },
155 { Opt_intr, "intr" },
156 { Opt_nostrictsync, "nostrictsync" },
157 { Opt_strictsync, "strictsync" },
158 { Opt_serverino, "serverino" },
159 { Opt_noserverino, "noserverino" },
160 { Opt_rwpidforward, "rwpidforward" },
161 { Opt_cifsacl, "cifsacl" },
162 { Opt_nocifsacl, "nocifsacl" },
163 { Opt_acl, "acl" },
164 { Opt_noacl, "noacl" },
165 { Opt_locallease, "locallease" },
166 { Opt_sign, "sign" },
167 { Opt_seal, "seal" },
Sachin Prabhu8830d7e2012-03-23 14:40:56 -0400168 { Opt_noac, "noac" },
169 { Opt_fsc, "fsc" },
170 { Opt_mfsymlinks, "mfsymlinks" },
171 { Opt_multiuser, "multiuser" },
Jeff Laytond8162552012-03-23 14:40:56 -0400172 { Opt_sloppy, "sloppy" },
Jeff Laytona0b3df52013-05-24 07:40:59 -0400173 { Opt_nosharesock, "nosharesock" },
Steve Frenchb2a30772015-09-29 21:49:28 -0500174 { Opt_persistent, "persistenthandles"},
175 { Opt_nopersistent, "nopersistenthandles"},
Steve French592fafe2015-11-03 10:08:53 -0600176 { Opt_resilient, "resilienthandles"},
177 { Opt_noresilient, "noresilienthandles"},
Sachin Prabhu8830d7e2012-03-23 14:40:56 -0400178
179 { Opt_backupuid, "backupuid=%s" },
180 { Opt_backupgid, "backupgid=%s" },
181 { Opt_uid, "uid=%s" },
182 { Opt_cruid, "cruid=%s" },
183 { Opt_gid, "gid=%s" },
184 { Opt_file_mode, "file_mode=%s" },
185 { Opt_dirmode, "dirmode=%s" },
186 { Opt_dirmode, "dir_mode=%s" },
187 { Opt_port, "port=%s" },
188 { Opt_rsize, "rsize=%s" },
189 { Opt_wsize, "wsize=%s" },
190 { Opt_actimeo, "actimeo=%s" },
191
Sachin Prabhu4fe9e962012-04-10 18:12:27 +0100192 { Opt_blank_user, "user=" },
193 { Opt_blank_user, "username=" },
Sachin Prabhu8830d7e2012-03-23 14:40:56 -0400194 { Opt_user, "user=%s" },
195 { Opt_user, "username=%s" },
196 { Opt_blank_pass, "pass=" },
Jesper Nilsson3c15b4c2012-11-29 17:31:16 +0100197 { Opt_blank_pass, "password=" },
Sachin Prabhu8830d7e2012-03-23 14:40:56 -0400198 { Opt_pass, "pass=%s" },
199 { Opt_pass, "password=%s" },
Sachin Prabhu4fe9e962012-04-10 18:12:27 +0100200 { Opt_blank_ip, "ip=" },
201 { Opt_blank_ip, "addr=" },
Sachin Prabhu8830d7e2012-03-23 14:40:56 -0400202 { Opt_ip, "ip=%s" },
203 { Opt_ip, "addr=%s" },
Jeff Layton73a999f2013-03-22 08:42:57 -0400204 { Opt_ignore, "unc=%s" },
205 { Opt_ignore, "target=%s" },
206 { Opt_ignore, "path=%s" },
Sachin Prabhu8830d7e2012-03-23 14:40:56 -0400207 { Opt_domain, "dom=%s" },
208 { Opt_domain, "domain=%s" },
209 { Opt_domain, "workgroup=%s" },
210 { Opt_srcaddr, "srcaddr=%s" },
Jeff Layton73a999f2013-03-22 08:42:57 -0400211 { Opt_ignore, "prefixpath=%s" },
Sachin Prabhu8830d7e2012-03-23 14:40:56 -0400212 { Opt_iocharset, "iocharset=%s" },
Sachin Prabhu8830d7e2012-03-23 14:40:56 -0400213 { Opt_netbiosname, "netbiosname=%s" },
214 { Opt_servern, "servern=%s" },
215 { Opt_ver, "ver=%s" },
Jeff Layton23db65f2012-05-15 12:20:51 -0400216 { Opt_vers, "vers=%s" },
Sachin Prabhu8830d7e2012-03-23 14:40:56 -0400217 { Opt_sec, "sec=%s" },
Jeff Layton15b6a472012-05-16 07:50:15 -0400218 { Opt_cache, "cache=%s" },
Sachin Prabhu8830d7e2012-03-23 14:40:56 -0400219
220 { Opt_ignore, "cred" },
221 { Opt_ignore, "credentials" },
Jeff Laytona557b972012-05-02 14:02:40 -0400222 { Opt_ignore, "cred=%s" },
223 { Opt_ignore, "credentials=%s" },
Sachin Prabhu8830d7e2012-03-23 14:40:56 -0400224 { Opt_ignore, "guest" },
225 { Opt_ignore, "rw" },
226 { Opt_ignore, "ro" },
227 { Opt_ignore, "suid" },
228 { Opt_ignore, "nosuid" },
229 { Opt_ignore, "exec" },
230 { Opt_ignore, "noexec" },
231 { Opt_ignore, "nodev" },
232 { Opt_ignore, "noauto" },
233 { Opt_ignore, "dev" },
234 { Opt_ignore, "mand" },
235 { Opt_ignore, "nomand" },
236 { Opt_ignore, "_netdev" },
237
238 { Opt_err, NULL }
239};
240
241enum {
242 Opt_sec_krb5, Opt_sec_krb5i, Opt_sec_krb5p,
243 Opt_sec_ntlmsspi, Opt_sec_ntlmssp,
Jeff Layton76596242012-07-23 20:34:17 -0400244 Opt_ntlm, Opt_sec_ntlmi, Opt_sec_ntlmv2,
245 Opt_sec_ntlmv2i, Opt_sec_lanman,
Sachin Prabhu8830d7e2012-03-23 14:40:56 -0400246 Opt_sec_none,
247
248 Opt_sec_err
249};
250
251static const match_table_t cifs_secflavor_tokens = {
252 { Opt_sec_krb5, "krb5" },
253 { Opt_sec_krb5i, "krb5i" },
254 { Opt_sec_krb5p, "krb5p" },
255 { Opt_sec_ntlmsspi, "ntlmsspi" },
256 { Opt_sec_ntlmssp, "ntlmssp" },
257 { Opt_ntlm, "ntlm" },
258 { Opt_sec_ntlmi, "ntlmi" },
Jeff Layton76596242012-07-23 20:34:17 -0400259 { Opt_sec_ntlmv2, "nontlm" },
260 { Opt_sec_ntlmv2, "ntlmv2" },
Sachin Prabhu8830d7e2012-03-23 14:40:56 -0400261 { Opt_sec_ntlmv2i, "ntlmv2i" },
Sachin Prabhu8830d7e2012-03-23 14:40:56 -0400262 { Opt_sec_lanman, "lanman" },
263 { Opt_sec_none, "none" },
264
265 { Opt_sec_err, NULL }
266};
267
Jeff Layton15b6a472012-05-16 07:50:15 -0400268/* cache flavors */
269enum {
270 Opt_cache_loose,
271 Opt_cache_strict,
272 Opt_cache_none,
273 Opt_cache_err
274};
275
276static const match_table_t cifs_cacheflavor_tokens = {
277 { Opt_cache_loose, "loose" },
278 { Opt_cache_strict, "strict" },
279 { Opt_cache_none, "none" },
280 { Opt_cache_err, NULL }
281};
282
Jeff Layton23db65f2012-05-15 12:20:51 -0400283static const match_table_t cifs_smb_version_tokens = {
284 { Smb_1, SMB1_VERSION_STRING },
Steve Frenchdd446b12012-11-28 23:21:06 -0600285 { Smb_20, SMB20_VERSION_STRING},
Steve French1080ef72011-02-24 18:07:19 +0000286 { Smb_21, SMB21_VERSION_STRING },
Steve Frenche4aa25e2012-10-01 12:26:22 -0500287 { Smb_30, SMB30_VERSION_STRING },
Steve French20b6d8b2013-06-12 22:48:41 -0500288 { Smb_302, SMB302_VERSION_STRING },
Steve French5f7fbf72014-12-17 22:52:58 -0600289#ifdef CONFIG_CIFS_SMB311
290 { Smb_311, SMB311_VERSION_STRING },
Steve Frenchaab18932015-06-23 23:37:11 -0500291 { Smb_311, ALT_SMB311_VERSION_STRING },
Steve French5f7fbf72014-12-17 22:52:58 -0600292#endif /* SMB311 */
293 { Smb_version_err, NULL }
Jeff Layton23db65f2012-05-15 12:20:51 -0400294};
295
Pavel Shilovskya9f1b852010-12-13 19:08:35 +0300296static int ip_connect(struct TCP_Server_Info *server);
297static int generic_ip_connect(struct TCP_Server_Info *server);
Jeff Laytonb647c352010-10-28 11:16:44 -0400298static void tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink);
Jeff Layton2de970f2010-10-06 19:51:12 -0400299static void cifs_prune_tlinks(struct work_struct *work);
Jeff Laytonb9bce2e2011-07-06 08:10:39 -0400300static int cifs_setup_volume_info(struct smb_vol *volume_info, char *mount_data,
301 const char *devname);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700302
Jeff Laytond5c56052008-12-01 18:42:33 -0500303/*
304 * cifs tcp session reconnection
305 *
306 * mark tcp session as reconnecting so temporarily locked
307 * mark all smb sessions as reconnecting for tcp session
308 * reconnect tcp session
309 * wake up waiters on reconnection? - (not needed currently)
310 */
Pavel Shilovsky28ea5292012-05-23 16:18:00 +0400311int
Linus Torvalds1da177e2005-04-16 15:20:36 -0700312cifs_reconnect(struct TCP_Server_Info *server)
313{
314 int rc = 0;
Jeff Laytonf1987b42008-11-15 11:12:47 -0500315 struct list_head *tmp, *tmp2;
Steve French96daf2b2011-05-27 04:34:02 +0000316 struct cifs_ses *ses;
317 struct cifs_tcon *tcon;
Steve Frenchfb8c4b12007-07-10 01:16:18 +0000318 struct mid_q_entry *mid_entry;
Jeff Layton3c1105d2011-05-22 07:09:13 -0400319 struct list_head retry_list;
Steve French50c2f752007-07-13 00:33:32 +0000320
Linus Torvalds1da177e2005-04-16 15:20:36 -0700321 spin_lock(&GlobalMid_Lock);
Jeff Layton469ee612008-10-16 18:46:39 +0000322 if (server->tcpStatus == CifsExiting) {
Steve Frenchfb8c4b12007-07-10 01:16:18 +0000323 /* the demux thread will exit normally
Linus Torvalds1da177e2005-04-16 15:20:36 -0700324 next time through the loop */
325 spin_unlock(&GlobalMid_Lock);
326 return rc;
327 } else
328 server->tcpStatus = CifsNeedReconnect;
329 spin_unlock(&GlobalMid_Lock);
330 server->maxBuf = 0;
Pavel Shilovskyaa24d1e2011-12-27 16:23:34 +0400331#ifdef CONFIG_CIFS_SMB2
332 server->max_read = 0;
333#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700334
Joe Perchesf96637b2013-05-04 22:12:25 -0500335 cifs_dbg(FYI, "Reconnecting tcp session\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700336
337 /* before reconnecting the tcp session, mark the smb session (uid)
338 and the tid bad so they are not used until reconnected */
Joe Perchesf96637b2013-05-04 22:12:25 -0500339 cifs_dbg(FYI, "%s: marking sessions and tcons for reconnect\n",
340 __func__);
Suresh Jayaraman3f9bcca2010-10-18 23:29:37 +0530341 spin_lock(&cifs_tcp_ses_lock);
Jeff Layton14fbf502008-11-14 13:53:46 -0500342 list_for_each(tmp, &server->smb_ses_list) {
Steve French96daf2b2011-05-27 04:34:02 +0000343 ses = list_entry(tmp, struct cifs_ses, smb_ses_list);
Jeff Layton14fbf502008-11-14 13:53:46 -0500344 ses->need_reconnect = true;
345 ses->ipc_tid = 0;
Jeff Laytonf1987b42008-11-15 11:12:47 -0500346 list_for_each(tmp2, &ses->tcon_list) {
Steve French96daf2b2011-05-27 04:34:02 +0000347 tcon = list_entry(tmp2, struct cifs_tcon, tcon_list);
Jeff Laytonf1987b42008-11-15 11:12:47 -0500348 tcon->need_reconnect = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700349 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700350 }
Suresh Jayaraman3f9bcca2010-10-18 23:29:37 +0530351 spin_unlock(&cifs_tcp_ses_lock);
Jeff Layton2b84a36c2011-01-11 07:24:21 -0500352
Linus Torvalds1da177e2005-04-16 15:20:36 -0700353 /* do not want to be sending data on a socket we are freeing */
Joe Perchesf96637b2013-05-04 22:12:25 -0500354 cifs_dbg(FYI, "%s: tearing down socket\n", __func__);
Jeff Layton72ca5452008-12-01 07:09:36 -0500355 mutex_lock(&server->srv_mutex);
Steve Frenchfb8c4b12007-07-10 01:16:18 +0000356 if (server->ssocket) {
Joe Perchesf96637b2013-05-04 22:12:25 -0500357 cifs_dbg(FYI, "State: 0x%x Flags: 0x%lx\n",
358 server->ssocket->state, server->ssocket->flags);
Trond Myklebust91cf45f2007-11-12 18:10:39 -0800359 kernel_sock_shutdown(server->ssocket, SHUT_WR);
Joe Perchesf96637b2013-05-04 22:12:25 -0500360 cifs_dbg(FYI, "Post shutdown state: 0x%x Flags: 0x%lx\n",
361 server->ssocket->state, server->ssocket->flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700362 sock_release(server->ssocket);
363 server->ssocket = NULL;
364 }
Shirish Pargaonkar5d0d2882010-10-13 18:15:00 -0500365 server->sequence_number = 0;
366 server->session_estab = false;
Shirish Pargaonkar21e73392010-10-21 06:42:55 -0500367 kfree(server->session_key.response);
368 server->session_key.response = NULL;
369 server->session_key.len = 0;
Steve Frenchfda35942011-01-20 18:06:34 +0000370 server->lstrp = jiffies;
Jeff Layton2b84a36c2011-01-11 07:24:21 -0500371 mutex_unlock(&server->srv_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700372
Jeff Layton2b84a36c2011-01-11 07:24:21 -0500373 /* mark submitted MIDs for retry and issue callback */
Jeff Layton3c1105d2011-05-22 07:09:13 -0400374 INIT_LIST_HEAD(&retry_list);
Joe Perchesf96637b2013-05-04 22:12:25 -0500375 cifs_dbg(FYI, "%s: moving mids to private list\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700376 spin_lock(&GlobalMid_Lock);
Jeff Layton2b84a36c2011-01-11 07:24:21 -0500377 list_for_each_safe(tmp, tmp2, &server->pending_mid_q) {
378 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
Pavel Shilovsky7c9421e2012-03-23 14:28:03 -0400379 if (mid_entry->mid_state == MID_REQUEST_SUBMITTED)
380 mid_entry->mid_state = MID_RETRY_NEEDED;
Jeff Layton3c1105d2011-05-22 07:09:13 -0400381 list_move(&mid_entry->qhead, &retry_list);
382 }
383 spin_unlock(&GlobalMid_Lock);
384
Joe Perchesf96637b2013-05-04 22:12:25 -0500385 cifs_dbg(FYI, "%s: issuing mid callbacks\n", __func__);
Jeff Layton3c1105d2011-05-22 07:09:13 -0400386 list_for_each_safe(tmp, tmp2, &retry_list) {
387 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
Jeff Layton2b84a36c2011-01-11 07:24:21 -0500388 list_del_init(&mid_entry->qhead);
389 mid_entry->callback(mid_entry);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700390 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700391
Jeff Layton7fdbaa12011-06-10 16:14:57 -0400392 do {
Steve French6c3d8902006-07-31 22:46:20 +0000393 try_to_freeze();
Pavel Shilovskya9f1b852010-12-13 19:08:35 +0300394
395 /* we should try only the port we connected to before */
Jeff Layton73e216a2013-09-05 08:38:10 -0400396 mutex_lock(&server->srv_mutex);
Pavel Shilovskya9f1b852010-12-13 19:08:35 +0300397 rc = generic_ip_connect(server);
Steve Frenchfb8c4b12007-07-10 01:16:18 +0000398 if (rc) {
Joe Perchesf96637b2013-05-04 22:12:25 -0500399 cifs_dbg(FYI, "reconnect error %d\n", rc);
Federico Sauter4afe2602015-03-17 17:45:28 +0100400 mutex_unlock(&server->srv_mutex);
Steve French0cb766a2005-04-28 22:41:11 -0700401 msleep(3000);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402 } else {
403 atomic_inc(&tcpSesReconnectCount);
404 spin_lock(&GlobalMid_Lock);
Jeff Layton469ee612008-10-16 18:46:39 +0000405 if (server->tcpStatus != CifsExiting)
Steve Frenchfd88ce92011-04-12 01:01:14 +0000406 server->tcpStatus = CifsNeedNegotiate;
Steve Frenchfb8c4b12007-07-10 01:16:18 +0000407 spin_unlock(&GlobalMid_Lock);
Federico Sauter4afe2602015-03-17 17:45:28 +0100408 mutex_unlock(&server->srv_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409 }
Jeff Layton7fdbaa12011-06-10 16:14:57 -0400410 } while (server->tcpStatus == CifsNeedReconnect);
Jeff Layton2b84a36c2011-01-11 07:24:21 -0500411
Linus Torvalds1da177e2005-04-16 15:20:36 -0700412 return rc;
413}
414
Jeff Laytonc74093b2011-01-11 07:24:23 -0500415static void
416cifs_echo_request(struct work_struct *work)
417{
418 int rc;
419 struct TCP_Server_Info *server = container_of(work,
420 struct TCP_Server_Info, echo.work);
421
Jeff Layton247ec9b2011-02-04 17:09:50 -0500422 /*
Pavel Shilovskyf6d76172012-05-25 14:47:16 +0400423 * We cannot send an echo if it is disabled or until the
424 * NEGOTIATE_PROTOCOL request is done, which is indicated by
425 * server->ops->need_neg() == true. Also, no need to ping if
426 * we got a response recently.
Jeff Layton247ec9b2011-02-04 17:09:50 -0500427 */
Pavel Shilovsky286170a2012-05-25 10:43:58 +0400428 if (!server->ops->need_neg || server->ops->need_neg(server) ||
Pavel Shilovskyf6d76172012-05-25 14:47:16 +0400429 (server->ops->can_echo && !server->ops->can_echo(server)) ||
Jeff Layton247ec9b2011-02-04 17:09:50 -0500430 time_before(jiffies, server->lstrp + SMB_ECHO_INTERVAL - HZ))
Jeff Laytonc74093b2011-01-11 07:24:23 -0500431 goto requeue_echo;
432
Pavel Shilovskyf6d76172012-05-25 14:47:16 +0400433 rc = server->ops->echo ? server->ops->echo(server) : -ENOSYS;
Jeff Laytonc74093b2011-01-11 07:24:23 -0500434 if (rc)
Joe Perchesf96637b2013-05-04 22:12:25 -0500435 cifs_dbg(FYI, "Unable to send echo request to server: %s\n",
436 server->hostname);
Jeff Laytonc74093b2011-01-11 07:24:23 -0500437
438requeue_echo:
Jeff Laytonda472fc2012-03-23 14:40:53 -0400439 queue_delayed_work(cifsiod_wq, &server->echo, SMB_ECHO_INTERVAL);
Jeff Laytonc74093b2011-01-11 07:24:23 -0500440}
441
Pavel Shilovsky3d9c2472011-08-01 13:19:40 +0400442static bool
Jeff Layton2a37ef92011-10-19 15:29:23 -0400443allocate_buffers(struct TCP_Server_Info *server)
Pavel Shilovsky3d9c2472011-08-01 13:19:40 +0400444{
Jeff Layton2a37ef92011-10-19 15:29:23 -0400445 if (!server->bigbuf) {
446 server->bigbuf = (char *)cifs_buf_get();
447 if (!server->bigbuf) {
Joe Perchesf96637b2013-05-04 22:12:25 -0500448 cifs_dbg(VFS, "No memory for large SMB response\n");
Pavel Shilovsky3d9c2472011-08-01 13:19:40 +0400449 msleep(3000);
450 /* retry will check if exiting */
451 return false;
452 }
Jeff Layton2a37ef92011-10-19 15:29:23 -0400453 } else if (server->large_buf) {
Pavel Shilovsky3d9c2472011-08-01 13:19:40 +0400454 /* we are reusing a dirty large buf, clear its start */
Pavel Shilovsky1887f602012-05-17 12:45:31 +0400455 memset(server->bigbuf, 0, HEADER_SIZE(server));
Pavel Shilovsky3d9c2472011-08-01 13:19:40 +0400456 }
457
Jeff Layton2a37ef92011-10-19 15:29:23 -0400458 if (!server->smallbuf) {
459 server->smallbuf = (char *)cifs_small_buf_get();
460 if (!server->smallbuf) {
Joe Perchesf96637b2013-05-04 22:12:25 -0500461 cifs_dbg(VFS, "No memory for SMB response\n");
Pavel Shilovsky3d9c2472011-08-01 13:19:40 +0400462 msleep(1000);
463 /* retry will check if exiting */
464 return false;
465 }
466 /* beginning of smb buffer is cleared in our buf_get */
467 } else {
468 /* if existing small buf clear beginning */
Pavel Shilovsky1887f602012-05-17 12:45:31 +0400469 memset(server->smallbuf, 0, HEADER_SIZE(server));
Pavel Shilovsky3d9c2472011-08-01 13:19:40 +0400470 }
471
Pavel Shilovsky3d9c2472011-08-01 13:19:40 +0400472 return true;
473}
474
Jeff Laytonba749e62011-10-11 06:41:32 -0400475static bool
476server_unresponsive(struct TCP_Server_Info *server)
Pavel Shilovskye7015fb2011-08-01 13:19:41 +0400477{
Pavel Shilovsky6dae51a2012-02-21 16:50:23 +0300478 /*
479 * We need to wait 2 echo intervals to make sure we handle such
480 * situations right:
481 * 1s client sends a normal SMB request
482 * 2s client gets a response
483 * 30s echo workqueue job pops, and decides we got a response recently
484 * and don't need to send another
485 * ...
486 * 65s kernel_recvmsg times out, and we see that we haven't gotten
487 * a response in >60s.
488 */
489 if (server->tcpStatus == CifsGood &&
490 time_after(jiffies, server->lstrp + 2 * SMB_ECHO_INTERVAL)) {
Joe Perchesf96637b2013-05-04 22:12:25 -0500491 cifs_dbg(VFS, "Server %s has not responded in %d seconds. Reconnecting...\n",
492 server->hostname, (2 * SMB_ECHO_INTERVAL) / HZ);
Jeff Laytonba749e62011-10-11 06:41:32 -0400493 cifs_reconnect(server);
494 wake_up(&server->response_q);
495 return true;
496 }
Pavel Shilovskye7015fb2011-08-01 13:19:41 +0400497
Jeff Laytonba749e62011-10-11 06:41:32 -0400498 return false;
499}
500
Jeff Layton42c4dfc2011-10-19 15:28:17 -0400501/*
502 * kvec_array_init - clone a kvec array, and advance into it
503 * @new: pointer to memory for cloned array
504 * @iov: pointer to original array
505 * @nr_segs: number of members in original array
506 * @bytes: number of bytes to advance into the cloned array
507 *
508 * This function will copy the array provided in iov to a section of memory
509 * and advance the specified number of bytes into the new array. It returns
510 * the number of segments in the new array. "new" must be at least as big as
511 * the original iov array.
512 */
513static unsigned int
514kvec_array_init(struct kvec *new, struct kvec *iov, unsigned int nr_segs,
515 size_t bytes)
516{
517 size_t base = 0;
518
519 while (bytes || !iov->iov_len) {
520 int copy = min(bytes, iov->iov_len);
521
522 bytes -= copy;
523 base += copy;
524 if (iov->iov_len == base) {
525 iov++;
526 nr_segs--;
527 base = 0;
528 }
529 }
530 memcpy(new, iov, sizeof(*iov) * nr_segs);
531 new->iov_base += base;
532 new->iov_len -= base;
533 return nr_segs;
534}
535
Jeff Layton1041e3f2011-10-19 15:28:27 -0400536static struct kvec *
537get_server_iovec(struct TCP_Server_Info *server, unsigned int nr_segs)
538{
539 struct kvec *new_iov;
540
541 if (server->iov && nr_segs <= server->nr_iov)
542 return server->iov;
543
544 /* not big enough -- allocate a new one and release the old */
545 new_iov = kmalloc(sizeof(*new_iov) * nr_segs, GFP_NOFS);
546 if (new_iov) {
547 kfree(server->iov);
548 server->iov = new_iov;
549 server->nr_iov = nr_segs;
550 }
551 return new_iov;
552}
553
Jeff Laytone28bc5b2011-10-19 15:30:07 -0400554int
555cifs_readv_from_socket(struct TCP_Server_Info *server, struct kvec *iov_orig,
556 unsigned int nr_segs, unsigned int to_read)
Pavel Shilovskye7015fb2011-08-01 13:19:41 +0400557{
Jeff Laytona52c1eb2011-10-11 06:41:32 -0400558 int length = 0;
559 int total_read;
Jeff Layton42c4dfc2011-10-19 15:28:17 -0400560 unsigned int segs;
Jeff Laytone831e6c2011-10-11 06:41:32 -0400561 struct msghdr smb_msg;
Jeff Layton42c4dfc2011-10-19 15:28:17 -0400562 struct kvec *iov;
563
Jeff Layton1041e3f2011-10-19 15:28:27 -0400564 iov = get_server_iovec(server, nr_segs);
Jeff Layton42c4dfc2011-10-19 15:28:17 -0400565 if (!iov)
566 return -ENOMEM;
Pavel Shilovskye7015fb2011-08-01 13:19:41 +0400567
Jeff Laytone831e6c2011-10-11 06:41:32 -0400568 smb_msg.msg_control = NULL;
569 smb_msg.msg_controllen = 0;
570
Jeff Laytona52c1eb2011-10-11 06:41:32 -0400571 for (total_read = 0; to_read; total_read += length, to_read -= length) {
Jeff Layton95edcff2011-12-01 20:22:41 -0500572 try_to_freeze();
573
Jeff Laytonba749e62011-10-11 06:41:32 -0400574 if (server_unresponsive(server)) {
Pavel Shilovsky3fabaa22014-07-10 09:55:52 +0400575 total_read = -ECONNABORTED;
Jeff Laytonba749e62011-10-11 06:41:32 -0400576 break;
577 }
578
Jeff Layton42c4dfc2011-10-19 15:28:17 -0400579 segs = kvec_array_init(iov, iov_orig, nr_segs, total_read);
580
581 length = kernel_recvmsg(server->ssocket, &smb_msg,
582 iov, segs, to_read, 0);
583
Pavel Shilovskye7015fb2011-08-01 13:19:41 +0400584 if (server->tcpStatus == CifsExiting) {
Jeff Laytona52c1eb2011-10-11 06:41:32 -0400585 total_read = -ESHUTDOWN;
Pavel Shilovskye7015fb2011-08-01 13:19:41 +0400586 break;
587 } else if (server->tcpStatus == CifsNeedReconnect) {
588 cifs_reconnect(server);
Pavel Shilovsky3fabaa22014-07-10 09:55:52 +0400589 total_read = -ECONNABORTED;
Pavel Shilovskye7015fb2011-08-01 13:19:41 +0400590 break;
591 } else if (length == -ERESTARTSYS ||
592 length == -EAGAIN ||
593 length == -EINTR) {
594 /*
595 * Minimum sleep to prevent looping, allowing socket
596 * to clear and app threads to set tcpStatus
597 * CifsNeedReconnect if server hung.
598 */
599 usleep_range(1000, 2000);
600 length = 0;
Jeff Laytona52c1eb2011-10-11 06:41:32 -0400601 continue;
Pavel Shilovskye7015fb2011-08-01 13:19:41 +0400602 } else if (length <= 0) {
Joe Perchesf96637b2013-05-04 22:12:25 -0500603 cifs_dbg(FYI, "Received no data or error: expecting %d\n"
604 "got %d", to_read, length);
Pavel Shilovskye7015fb2011-08-01 13:19:41 +0400605 cifs_reconnect(server);
Pavel Shilovsky3fabaa22014-07-10 09:55:52 +0400606 total_read = -ECONNABORTED;
Pavel Shilovskye7015fb2011-08-01 13:19:41 +0400607 break;
608 }
609 }
Jeff Laytona52c1eb2011-10-11 06:41:32 -0400610 return total_read;
Pavel Shilovskye7015fb2011-08-01 13:19:41 +0400611}
Pavel Shilovskye7015fb2011-08-01 13:19:41 +0400612
Jeff Laytone28bc5b2011-10-19 15:30:07 -0400613int
614cifs_read_from_socket(struct TCP_Server_Info *server, char *buf,
615 unsigned int to_read)
Jeff Layton42c4dfc2011-10-19 15:28:17 -0400616{
617 struct kvec iov;
618
619 iov.iov_base = buf;
620 iov.iov_len = to_read;
621
Jeff Laytone28bc5b2011-10-19 15:30:07 -0400622 return cifs_readv_from_socket(server, &iov, 1, to_read);
Pavel Shilovskye7015fb2011-08-01 13:19:41 +0400623}
624
Pavel Shilovsky98bac622011-08-01 13:19:42 +0400625static bool
Jeff Laytonfe11e4c2011-10-11 06:41:32 -0400626is_smb_response(struct TCP_Server_Info *server, unsigned char type)
Pavel Shilovsky98bac622011-08-01 13:19:42 +0400627{
Pavel Shilovsky98bac622011-08-01 13:19:42 +0400628 /*
629 * The first byte big endian of the length field,
630 * is actually not part of the length but the type
631 * with the most common, zero, as regular data.
632 */
Jeff Laytonfe11e4c2011-10-11 06:41:32 -0400633 switch (type) {
634 case RFC1002_SESSION_MESSAGE:
635 /* Regular SMB response */
636 return true;
637 case RFC1002_SESSION_KEEP_ALIVE:
Joe Perchesf96637b2013-05-04 22:12:25 -0500638 cifs_dbg(FYI, "RFC 1002 session keep alive\n");
Jeff Laytonfe11e4c2011-10-11 06:41:32 -0400639 break;
640 case RFC1002_POSITIVE_SESSION_RESPONSE:
Joe Perchesf96637b2013-05-04 22:12:25 -0500641 cifs_dbg(FYI, "RFC 1002 positive session response\n");
Jeff Laytonfe11e4c2011-10-11 06:41:32 -0400642 break;
643 case RFC1002_NEGATIVE_SESSION_RESPONSE:
Pavel Shilovsky98bac622011-08-01 13:19:42 +0400644 /*
645 * We get this from Windows 98 instead of an error on
646 * SMB negprot response.
647 */
Joe Perchesf96637b2013-05-04 22:12:25 -0500648 cifs_dbg(FYI, "RFC 1002 negative session response\n");
Pavel Shilovsky98bac622011-08-01 13:19:42 +0400649 /* give server a second to clean up */
650 msleep(1000);
651 /*
652 * Always try 445 first on reconnect since we get NACK
653 * on some if we ever connected to port 139 (the NACK
654 * is since we do not begin with RFC1001 session
655 * initialize frame).
656 */
Jeff Laytonfe11e4c2011-10-11 06:41:32 -0400657 cifs_set_port((struct sockaddr *)&server->dstaddr, CIFS_PORT);
Pavel Shilovsky98bac622011-08-01 13:19:42 +0400658 cifs_reconnect(server);
659 wake_up(&server->response_q);
Jeff Laytonfe11e4c2011-10-11 06:41:32 -0400660 break;
661 default:
Joe Perchesf96637b2013-05-04 22:12:25 -0500662 cifs_dbg(VFS, "RFC 1002 unknown response type 0x%x\n", type);
Pavel Shilovsky98bac622011-08-01 13:19:42 +0400663 cifs_reconnect(server);
Pavel Shilovsky98bac622011-08-01 13:19:42 +0400664 }
665
Jeff Laytonfe11e4c2011-10-11 06:41:32 -0400666 return false;
Pavel Shilovsky98bac622011-08-01 13:19:42 +0400667}
668
Jeff Laytone28bc5b2011-10-19 15:30:07 -0400669void
670dequeue_mid(struct mid_q_entry *mid, bool malformed)
Jeff Laytonea1f4502011-10-19 15:29:05 -0400671{
672#ifdef CONFIG_CIFS_STATS2
673 mid->when_received = jiffies;
674#endif
675 spin_lock(&GlobalMid_Lock);
676 if (!malformed)
Pavel Shilovsky7c9421e2012-03-23 14:28:03 -0400677 mid->mid_state = MID_RESPONSE_RECEIVED;
Jeff Laytonea1f4502011-10-19 15:29:05 -0400678 else
Pavel Shilovsky7c9421e2012-03-23 14:28:03 -0400679 mid->mid_state = MID_RESPONSE_MALFORMED;
Jeff Laytonea1f4502011-10-19 15:29:05 -0400680 list_del_init(&mid->qhead);
681 spin_unlock(&GlobalMid_Lock);
682}
683
Jeff Laytonc8054eb2011-10-19 15:29:31 -0400684static void
685handle_mid(struct mid_q_entry *mid, struct TCP_Server_Info *server,
Pavel Shilovskyd4e48542012-03-23 14:28:02 -0400686 char *buf, int malformed)
Jeff Laytonea1f4502011-10-19 15:29:05 -0400687{
Pavel Shilovsky316cf942012-05-23 14:31:03 +0400688 if (server->ops->check_trans2 &&
689 server->ops->check_trans2(mid, server, buf, malformed))
Jeff Laytonc8054eb2011-10-19 15:29:31 -0400690 return;
Jeff Laytonea1f4502011-10-19 15:29:05 -0400691 mid->resp_buf = buf;
Pavel Shilovsky7c9421e2012-03-23 14:28:03 -0400692 mid->large_buf = server->large_buf;
Jeff Layton2a37ef92011-10-19 15:29:23 -0400693 /* Was previous buf put in mpx struct for multi-rsp? */
694 if (!mid->multiRsp) {
695 /* smb buffer will be freed by user thread */
696 if (server->large_buf)
697 server->bigbuf = NULL;
698 else
699 server->smallbuf = NULL;
700 }
Jeff Laytonffc00e22011-10-19 15:29:13 -0400701 dequeue_mid(mid, malformed);
Pavel Shilovskyad69bae2011-08-01 13:19:43 +0400702}
703
Pavel Shilovsky762dfd12011-08-01 13:19:44 +0400704static void clean_demultiplex_info(struct TCP_Server_Info *server)
705{
706 int length;
707
708 /* take it off the list, if it's not already */
709 spin_lock(&cifs_tcp_ses_lock);
710 list_del_init(&server->tcp_ses_list);
711 spin_unlock(&cifs_tcp_ses_lock);
712
713 spin_lock(&GlobalMid_Lock);
714 server->tcpStatus = CifsExiting;
715 spin_unlock(&GlobalMid_Lock);
716 wake_up_all(&server->response_q);
717
Pavel Shilovsky2d86dbc2012-02-06 15:59:18 +0400718 /* check if we have blocked requests that need to free */
Pavel Shilovskyfc40f9c2012-02-17 17:09:12 +0300719 spin_lock(&server->req_lock);
Pavel Shilovsky2d86dbc2012-02-06 15:59:18 +0400720 if (server->credits <= 0)
721 server->credits = 1;
Pavel Shilovskyfc40f9c2012-02-17 17:09:12 +0300722 spin_unlock(&server->req_lock);
Pavel Shilovsky762dfd12011-08-01 13:19:44 +0400723 /*
724 * Although there should not be any requests blocked on this queue it
725 * can not hurt to be paranoid and try to wake up requests that may
726 * haven been blocked when more than 50 at time were on the wire to the
727 * same server - they now will see the session is in exit state and get
728 * out of SendReceive.
729 */
730 wake_up_all(&server->request_q);
731 /* give those requests time to exit */
732 msleep(125);
733
734 if (server->ssocket) {
735 sock_release(server->ssocket);
736 server->ssocket = NULL;
737 }
738
739 if (!list_empty(&server->pending_mid_q)) {
740 struct list_head dispose_list;
741 struct mid_q_entry *mid_entry;
742 struct list_head *tmp, *tmp2;
743
744 INIT_LIST_HEAD(&dispose_list);
745 spin_lock(&GlobalMid_Lock);
746 list_for_each_safe(tmp, tmp2, &server->pending_mid_q) {
747 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
Joe Perchesf96637b2013-05-04 22:12:25 -0500748 cifs_dbg(FYI, "Clearing mid 0x%llx\n", mid_entry->mid);
Pavel Shilovsky7c9421e2012-03-23 14:28:03 -0400749 mid_entry->mid_state = MID_SHUTDOWN;
Pavel Shilovsky762dfd12011-08-01 13:19:44 +0400750 list_move(&mid_entry->qhead, &dispose_list);
751 }
752 spin_unlock(&GlobalMid_Lock);
753
754 /* now walk dispose list and issue callbacks */
755 list_for_each_safe(tmp, tmp2, &dispose_list) {
756 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
Joe Perchesf96637b2013-05-04 22:12:25 -0500757 cifs_dbg(FYI, "Callback mid 0x%llx\n", mid_entry->mid);
Pavel Shilovsky762dfd12011-08-01 13:19:44 +0400758 list_del_init(&mid_entry->qhead);
759 mid_entry->callback(mid_entry);
760 }
761 /* 1/8th of sec is more than enough time for them to exit */
762 msleep(125);
763 }
764
765 if (!list_empty(&server->pending_mid_q)) {
766 /*
767 * mpx threads have not exited yet give them at least the smb
768 * send timeout time for long ops.
769 *
770 * Due to delays on oplock break requests, we need to wait at
771 * least 45 seconds before giving up on a request getting a
772 * response and going ahead and killing cifsd.
773 */
Joe Perchesf96637b2013-05-04 22:12:25 -0500774 cifs_dbg(FYI, "Wait for exit from demultiplex thread\n");
Pavel Shilovsky762dfd12011-08-01 13:19:44 +0400775 msleep(46000);
776 /*
777 * If threads still have not exited they are probably never
778 * coming home not much else we can do but free the memory.
779 */
780 }
781
782 kfree(server->hostname);
Jeff Layton1041e3f2011-10-19 15:28:27 -0400783 kfree(server->iov);
Pavel Shilovsky762dfd12011-08-01 13:19:44 +0400784 kfree(server);
785
786 length = atomic_dec_return(&tcpSesAllocCount);
787 if (length > 0)
David Rientjes11d83362015-04-14 15:48:21 -0700788 mempool_resize(cifs_req_poolp, length + cifs_min_rcv);
Pavel Shilovsky762dfd12011-08-01 13:19:44 +0400789}
790
Pavel Shilovskye7015fb2011-08-01 13:19:41 +0400791static int
Jeff Laytone9097ab2011-10-19 15:29:40 -0400792standard_receive3(struct TCP_Server_Info *server, struct mid_q_entry *mid)
793{
794 int length;
795 char *buf = server->smallbuf;
Pavel Shilovskyd4e48542012-03-23 14:28:02 -0400796 unsigned int pdu_length = get_rfc1002_length(buf);
Jeff Laytone9097ab2011-10-19 15:29:40 -0400797
798 /* make sure this will fit in a large buffer */
Pavel Shilovsky1887f602012-05-17 12:45:31 +0400799 if (pdu_length > CIFSMaxBufSize + MAX_HEADER_SIZE(server) - 4) {
Joe Perchesf96637b2013-05-04 22:12:25 -0500800 cifs_dbg(VFS, "SMB response too long (%u bytes)\n", pdu_length);
Jeff Laytone9097ab2011-10-19 15:29:40 -0400801 cifs_reconnect(server);
802 wake_up(&server->response_q);
Pavel Shilovsky3fabaa22014-07-10 09:55:52 +0400803 return -ECONNABORTED;
Jeff Laytone9097ab2011-10-19 15:29:40 -0400804 }
805
806 /* switch to large buffer if too big for a small one */
807 if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) {
808 server->large_buf = true;
Pavel Shilovskyd4e48542012-03-23 14:28:02 -0400809 memcpy(server->bigbuf, buf, server->total_read);
Jeff Laytone9097ab2011-10-19 15:29:40 -0400810 buf = server->bigbuf;
Jeff Laytone9097ab2011-10-19 15:29:40 -0400811 }
812
813 /* now read the rest */
Pavel Shilovsky1887f602012-05-17 12:45:31 +0400814 length = cifs_read_from_socket(server, buf + HEADER_SIZE(server) - 1,
815 pdu_length - HEADER_SIZE(server) + 1 + 4);
Jeff Laytone9097ab2011-10-19 15:29:40 -0400816 if (length < 0)
817 return length;
818 server->total_read += length;
819
Pavel Shilovskyd4e48542012-03-23 14:28:02 -0400820 dump_smb(buf, server->total_read);
Jeff Laytone9097ab2011-10-19 15:29:40 -0400821
822 /*
823 * We know that we received enough to get to the MID as we
824 * checked the pdu_length earlier. Now check to see
825 * if the rest of the header is OK. We borrow the length
826 * var for the rest of the loop to avoid a new stack var.
827 *
828 * 48 bytes is enough to display the header and a little bit
829 * into the payload for debugging purposes.
830 */
Pavel Shilovsky8aa26f32012-05-17 13:25:35 +0400831 length = server->ops->check_message(buf, server->total_read);
Jeff Laytone9097ab2011-10-19 15:29:40 -0400832 if (length != 0)
833 cifs_dump_mem("Bad SMB: ", buf,
834 min_t(unsigned int, server->total_read, 48));
835
Pavel Shilovsky2e44b282012-09-18 16:20:33 -0700836 if (server->ops->is_status_pending &&
837 server->ops->is_status_pending(buf, server, length))
838 return -1;
839
Jeff Laytonff4fa4a2012-02-07 06:31:05 -0500840 if (!mid)
841 return length;
Jeff Laytone9097ab2011-10-19 15:29:40 -0400842
Pavel Shilovskyd4e48542012-03-23 14:28:02 -0400843 handle_mid(mid, server, buf, length);
Jeff Laytonff4fa4a2012-02-07 06:31:05 -0500844 return 0;
Jeff Laytone9097ab2011-10-19 15:29:40 -0400845}
846
847static int
Al Viro7c97c202011-06-21 08:51:28 -0400848cifs_demultiplex_thread(void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700849{
850 int length;
Al Viro7c97c202011-06-21 08:51:28 -0400851 struct TCP_Server_Info *server = p;
Jeff Layton2a37ef92011-10-19 15:29:23 -0400852 unsigned int pdu_length;
853 char *buf = NULL;
Steve Frencha5c3e1c2014-09-16 04:16:19 -0500854 struct task_struct *task_to_wake = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700855 struct mid_q_entry *mid_entry;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700856
Linus Torvalds1da177e2005-04-16 15:20:36 -0700857 current->flags |= PF_MEMALLOC;
Joe Perchesf96637b2013-05-04 22:12:25 -0500858 cifs_dbg(FYI, "Demultiplex PID: %d\n", task_pid_nr(current));
Jeff Layton93d0ec82008-08-02 08:00:48 -0400859
860 length = atomic_inc_return(&tcpSesAllocCount);
861 if (length > 1)
David Rientjes11d83362015-04-14 15:48:21 -0700862 mempool_resize(cifs_req_poolp, length + cifs_min_rcv);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700863
Rafael J. Wysocki83144182007-07-17 04:03:35 -0700864 set_freezable();
Jeff Layton469ee612008-10-16 18:46:39 +0000865 while (server->tcpStatus != CifsExiting) {
Steve Frenchede13272005-08-30 20:10:14 -0700866 if (try_to_freeze())
867 continue;
Steve Frenchb8643e12005-04-28 22:41:07 -0700868
Jeff Layton2a37ef92011-10-19 15:29:23 -0400869 if (!allocate_buffers(server))
Pavel Shilovsky3d9c2472011-08-01 13:19:40 +0400870 continue;
Steve Frenchb8643e12005-04-28 22:41:07 -0700871
Jeff Layton2a37ef92011-10-19 15:29:23 -0400872 server->large_buf = false;
Jeff Layton2a37ef92011-10-19 15:29:23 -0400873 buf = server->smallbuf;
Steve Frenchf01d5e12007-08-30 21:13:31 +0000874 pdu_length = 4; /* enough to get RFC1001 header */
Steve Frenchfda35942011-01-20 18:06:34 +0000875
Jeff Laytone28bc5b2011-10-19 15:30:07 -0400876 length = cifs_read_from_socket(server, buf, pdu_length);
Jeff Laytona52c1eb2011-10-11 06:41:32 -0400877 if (length < 0)
Steve Frenchfda35942011-01-20 18:06:34 +0000878 continue;
Jeff Layton2a37ef92011-10-19 15:29:23 -0400879 server->total_read = length;
Steve French67010fb2005-04-28 22:41:09 -0700880
Pavel Shilovsky98bac622011-08-01 13:19:42 +0400881 /*
882 * The right amount was read from socket - 4 bytes,
883 * so we can now interpret the length field.
884 */
Pavel Shilovskyd4e48542012-03-23 14:28:02 -0400885 pdu_length = get_rfc1002_length(buf);
Steve French46810cb2005-04-28 22:41:09 -0700886
Joe Perchesf96637b2013-05-04 22:12:25 -0500887 cifs_dbg(FYI, "RFC1002 header 0x%x\n", pdu_length);
Jeff Laytonfe11e4c2011-10-11 06:41:32 -0400888 if (!is_smb_response(server, buf[0]))
Steve Frenchfb8c4b12007-07-10 01:16:18 +0000889 continue;
Steve Frenche4eb2952005-04-28 22:41:09 -0700890
Jeff Layton89482a52011-10-19 15:28:57 -0400891 /* make sure we have enough to get to the MID */
Pavel Shilovsky1887f602012-05-17 12:45:31 +0400892 if (pdu_length < HEADER_SIZE(server) - 1 - 4) {
Joe Perchesf96637b2013-05-04 22:12:25 -0500893 cifs_dbg(VFS, "SMB response too short (%u bytes)\n",
894 pdu_length);
Jeff Layton89482a52011-10-19 15:28:57 -0400895 cifs_reconnect(server);
896 wake_up(&server->response_q);
897 continue;
Steve Frenche4eb2952005-04-28 22:41:09 -0700898 }
Pavel Shilovskye7015fb2011-08-01 13:19:41 +0400899
Jeff Layton89482a52011-10-19 15:28:57 -0400900 /* read down to the MID */
Jeff Laytone28bc5b2011-10-19 15:30:07 -0400901 length = cifs_read_from_socket(server, buf + 4,
Pavel Shilovsky1887f602012-05-17 12:45:31 +0400902 HEADER_SIZE(server) - 1 - 4);
Jeff Layton89482a52011-10-19 15:28:57 -0400903 if (length < 0)
904 continue;
Jeff Layton2a37ef92011-10-19 15:29:23 -0400905 server->total_read += length;
Jeff Layton89482a52011-10-19 15:28:57 -0400906
Pavel Shilovsky8aa26f32012-05-17 13:25:35 +0400907 mid_entry = server->ops->find_mid(server, buf);
Jeff Laytonc8054eb2011-10-19 15:29:31 -0400908
Jeff Layton44d22d82011-10-19 15:29:49 -0400909 if (!mid_entry || !mid_entry->receive)
910 length = standard_receive3(server, mid_entry);
911 else
912 length = mid_entry->receive(server, mid_entry);
913
Jeff Laytona52c1eb2011-10-11 06:41:32 -0400914 if (length < 0)
Steve Frenche4eb2952005-04-28 22:41:09 -0700915 continue;
916
Pavel Shilovskyd4e48542012-03-23 14:28:02 -0400917 if (server->large_buf)
Jeff Laytone9097ab2011-10-19 15:29:40 -0400918 buf = server->bigbuf;
Steve Frenche4eb2952005-04-28 22:41:09 -0700919
Steve Frenchfda35942011-01-20 18:06:34 +0000920 server->lstrp = jiffies;
Jeff Layton2b84a36c2011-01-11 07:24:21 -0500921 if (mid_entry != NULL) {
Jeff Layton2a37ef92011-10-19 15:29:23 -0400922 if (!mid_entry->multiRsp || mid_entry->multiEnd)
923 mid_entry->callback(mid_entry);
Pavel Shilovsky7f0adb52012-05-28 15:50:10 +0400924 } else if (!server->ops->is_oplock_break ||
925 !server->ops->is_oplock_break(buf, server)) {
Joe Perchesf96637b2013-05-04 22:12:25 -0500926 cifs_dbg(VFS, "No task to wake, unknown frame received! NumMids %d\n",
927 atomic_read(&midCount));
Pavel Shilovsky1887f602012-05-17 12:45:31 +0400928 cifs_dump_mem("Received Data is: ", buf,
929 HEADER_SIZE(server));
Steve French39798772006-05-31 22:40:51 +0000930#ifdef CONFIG_CIFS_DEBUG2
Pavel Shilovsky7f0adb52012-05-28 15:50:10 +0400931 if (server->ops->dump_detail)
932 server->ops->dump_detail(buf);
Steve French39798772006-05-31 22:40:51 +0000933 cifs_dump_mids(server);
934#endif /* CIFS_DEBUG2 */
Steve French50c2f752007-07-13 00:33:32 +0000935
Steve Frenche4eb2952005-04-28 22:41:09 -0700936 }
937 } /* end while !EXITING */
938
Justin P. Mattockfd62cb72011-02-24 22:15:02 -0800939 /* buffer usually freed in free_mid - need to free it here on exit */
Jeff Layton2a37ef92011-10-19 15:29:23 -0400940 cifs_buf_release(server->bigbuf);
941 if (server->smallbuf) /* no sense logging a debug message if NULL */
942 cifs_small_buf_release(server->smallbuf);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700943
Steve Frencha5c3e1c2014-09-16 04:16:19 -0500944 task_to_wake = xchg(&server->tsk, NULL);
Pavel Shilovsky762dfd12011-08-01 13:19:44 +0400945 clean_demultiplex_info(server);
Steve Frencha5c3e1c2014-09-16 04:16:19 -0500946
947 /* if server->tsk was NULL then wait for a signal before exiting */
948 if (!task_to_wake) {
949 set_current_state(TASK_INTERRUPTIBLE);
950 while (!signal_pending(current)) {
951 schedule();
952 set_current_state(TASK_INTERRUPTIBLE);
953 }
954 set_current_state(TASK_RUNNING);
955 }
956
Jeff Layton0468a2c2008-12-01 07:09:35 -0500957 module_put_and_exit(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700958}
959
Jeff Laytonc359cf32007-11-16 22:22:06 +0000960/* extract the host portion of the UNC string */
961static char *
962extract_hostname(const char *unc)
963{
964 const char *src;
965 char *dst, *delim;
966 unsigned int len;
967
968 /* skip double chars at beginning of string */
969 /* BB: check validity of these bytes? */
970 src = unc + 2;
971
972 /* delimiter between hostname and sharename is always '\\' now */
973 delim = strchr(src, '\\');
974 if (!delim)
975 return ERR_PTR(-EINVAL);
976
977 len = delim - src;
978 dst = kmalloc((len + 1), GFP_KERNEL);
979 if (dst == NULL)
980 return ERR_PTR(-ENOMEM);
981
982 memcpy(dst, src, len);
983 dst[len] = '\0';
984
985 return dst;
986}
987
Sachin Prabhu8830d7e2012-03-23 14:40:56 -0400988static int get_option_ul(substring_t args[], unsigned long *option)
989{
990 int rc;
991 char *string;
992
993 string = match_strdup(args);
994 if (string == NULL)
995 return -ENOMEM;
Sachin Prabhubfa890a2012-04-13 14:04:32 +0100996 rc = kstrtoul(string, 0, option);
Sachin Prabhu8830d7e2012-03-23 14:40:56 -0400997 kfree(string);
998
999 return rc;
1000}
1001
Eric W. Biederman3da46562013-02-06 01:37:39 -08001002static int get_option_uid(substring_t args[], kuid_t *result)
1003{
1004 unsigned long value;
1005 kuid_t uid;
1006 int rc;
1007
1008 rc = get_option_ul(args, &value);
1009 if (rc)
1010 return rc;
1011
1012 uid = make_kuid(current_user_ns(), value);
1013 if (!uid_valid(uid))
1014 return -EINVAL;
1015
1016 *result = uid;
1017 return 0;
1018}
1019
1020static int get_option_gid(substring_t args[], kgid_t *result)
1021{
1022 unsigned long value;
1023 kgid_t gid;
1024 int rc;
1025
1026 rc = get_option_ul(args, &value);
1027 if (rc)
1028 return rc;
1029
1030 gid = make_kgid(current_user_ns(), value);
1031 if (!gid_valid(gid))
1032 return -EINVAL;
1033
1034 *result = gid;
1035 return 0;
1036}
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001037
1038static int cifs_parse_security_flavors(char *value,
1039 struct smb_vol *vol)
1040{
1041
1042 substring_t args[MAX_OPT_ARGS];
1043
Jeff Layton1e3cc572013-06-10 17:12:23 -05001044 /*
1045 * With mount options, the last one should win. Reset any existing
1046 * settings back to default.
1047 */
1048 vol->sectype = Unspecified;
1049 vol->sign = false;
1050
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001051 switch (match_token(value, cifs_secflavor_tokens, args)) {
Jeff Layton3f618222013-06-12 19:52:14 -05001052 case Opt_sec_krb5p:
1053 cifs_dbg(VFS, "sec=krb5p is not supported!\n");
1054 return 1;
1055 case Opt_sec_krb5i:
1056 vol->sign = true;
1057 /* Fallthrough */
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001058 case Opt_sec_krb5:
Jeff Layton1e3cc572013-06-10 17:12:23 -05001059 vol->sectype = Kerberos;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001060 break;
1061 case Opt_sec_ntlmsspi:
Jeff Layton1e3cc572013-06-10 17:12:23 -05001062 vol->sign = true;
Jeff Layton3f618222013-06-12 19:52:14 -05001063 /* Fallthrough */
1064 case Opt_sec_ntlmssp:
1065 vol->sectype = RawNTLMSSP;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001066 break;
1067 case Opt_sec_ntlmi:
Jeff Layton1e3cc572013-06-10 17:12:23 -05001068 vol->sign = true;
Jeff Layton3f618222013-06-12 19:52:14 -05001069 /* Fallthrough */
1070 case Opt_ntlm:
1071 vol->sectype = NTLM;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001072 break;
1073 case Opt_sec_ntlmv2i:
Jeff Layton1e3cc572013-06-10 17:12:23 -05001074 vol->sign = true;
Jeff Layton3f618222013-06-12 19:52:14 -05001075 /* Fallthrough */
1076 case Opt_sec_ntlmv2:
1077 vol->sectype = NTLMv2;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001078 break;
1079#ifdef CONFIG_CIFS_WEAK_PW_HASH
1080 case Opt_sec_lanman:
Jeff Layton1e3cc572013-06-10 17:12:23 -05001081 vol->sectype = LANMAN;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001082 break;
1083#endif
1084 case Opt_sec_none:
1085 vol->nullauth = 1;
1086 break;
1087 default:
Joe Perchesf96637b2013-05-04 22:12:25 -05001088 cifs_dbg(VFS, "bad security option: %s\n", value);
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001089 return 1;
1090 }
1091
1092 return 0;
1093}
1094
Linus Torvalds1da177e2005-04-16 15:20:36 -07001095static int
Jeff Layton15b6a472012-05-16 07:50:15 -04001096cifs_parse_cache_flavor(char *value, struct smb_vol *vol)
1097{
1098 substring_t args[MAX_OPT_ARGS];
1099
1100 switch (match_token(value, cifs_cacheflavor_tokens, args)) {
1101 case Opt_cache_loose:
1102 vol->direct_io = false;
1103 vol->strict_io = false;
1104 break;
1105 case Opt_cache_strict:
1106 vol->direct_io = false;
1107 vol->strict_io = true;
1108 break;
1109 case Opt_cache_none:
1110 vol->direct_io = true;
1111 vol->strict_io = false;
1112 break;
1113 default:
Joe Perchesf96637b2013-05-04 22:12:25 -05001114 cifs_dbg(VFS, "bad cache= option: %s\n", value);
Jeff Layton15b6a472012-05-16 07:50:15 -04001115 return 1;
1116 }
1117 return 0;
1118}
1119
1120static int
Jeff Layton23db65f2012-05-15 12:20:51 -04001121cifs_parse_smb_version(char *value, struct smb_vol *vol)
1122{
1123 substring_t args[MAX_OPT_ARGS];
1124
1125 switch (match_token(value, cifs_smb_version_tokens, args)) {
1126 case Smb_1:
1127 vol->ops = &smb1_operations;
1128 vol->vals = &smb1_values;
1129 break;
Steve French1080ef72011-02-24 18:07:19 +00001130#ifdef CONFIG_CIFS_SMB2
Steve Frenchdd446b12012-11-28 23:21:06 -06001131 case Smb_20:
Pavel Shilovsky53ef1012013-09-05 16:11:28 +04001132 vol->ops = &smb20_operations;
Steve Frenchdd446b12012-11-28 23:21:06 -06001133 vol->vals = &smb20_values;
1134 break;
Steve French1080ef72011-02-24 18:07:19 +00001135 case Smb_21:
1136 vol->ops = &smb21_operations;
1137 vol->vals = &smb21_values;
1138 break;
Steve Frenche4aa25e2012-10-01 12:26:22 -05001139 case Smb_30:
Steve French38107d42012-12-08 22:08:06 -06001140 vol->ops = &smb30_operations;
Steve Frenche4aa25e2012-10-01 12:26:22 -05001141 vol->vals = &smb30_values;
1142 break;
Steve French20b6d8b2013-06-12 22:48:41 -05001143 case Smb_302:
1144 vol->ops = &smb30_operations; /* currently identical with 3.0 */
1145 vol->vals = &smb302_values;
1146 break;
Steve French5f7fbf72014-12-17 22:52:58 -06001147#ifdef CONFIG_CIFS_SMB311
1148 case Smb_311:
Steve Frenchaab18932015-06-23 23:37:11 -05001149 vol->ops = &smb311_operations;
Steve French5f7fbf72014-12-17 22:52:58 -06001150 vol->vals = &smb311_values;
1151 break;
1152#endif /* SMB311 */
Steve French1080ef72011-02-24 18:07:19 +00001153#endif
Jeff Layton23db65f2012-05-15 12:20:51 -04001154 default:
Joe Perchesf96637b2013-05-04 22:12:25 -05001155 cifs_dbg(VFS, "Unknown vers= option specified: %s\n", value);
Jeff Layton23db65f2012-05-15 12:20:51 -04001156 return 1;
1157 }
1158 return 0;
1159}
1160
Jeff Laytond387a5c2012-12-10 06:10:46 -05001161/*
1162 * Parse a devname into substrings and populate the vol->UNC and vol->prepath
1163 * fields with the result. Returns 0 on success and an error otherwise.
1164 */
1165static int
1166cifs_parse_devname(const char *devname, struct smb_vol *vol)
1167{
1168 char *pos;
1169 const char *delims = "/\\";
1170 size_t len;
1171
1172 /* make sure we have a valid UNC double delimiter prefix */
1173 len = strspn(devname, delims);
1174 if (len != 2)
1175 return -EINVAL;
1176
1177 /* find delimiter between host and sharename */
1178 pos = strpbrk(devname + 2, delims);
1179 if (!pos)
1180 return -EINVAL;
1181
1182 /* skip past delimiter */
1183 ++pos;
1184
1185 /* now go until next delimiter or end of string */
1186 len = strcspn(pos, delims);
1187
1188 /* move "pos" up to delimiter or NULL */
1189 pos += len;
1190 vol->UNC = kstrndup(devname, pos - devname, GFP_KERNEL);
1191 if (!vol->UNC)
1192 return -ENOMEM;
1193
1194 convert_delimiter(vol->UNC, '\\');
1195
1196 /* If pos is NULL, or is a bogus trailing delimiter then no prepath */
1197 if (!*pos++ || !*pos)
1198 return 0;
1199
1200 vol->prepath = kstrdup(pos, GFP_KERNEL);
1201 if (!vol->prepath)
1202 return -ENOMEM;
1203
1204 return 0;
1205}
1206
Jeff Layton23db65f2012-05-15 12:20:51 -04001207static int
Sean Finneyb9468452011-04-11 13:19:32 +00001208cifs_parse_mount_options(const char *mountdata, const char *devname,
Steve French50c2f752007-07-13 00:33:32 +00001209 struct smb_vol *vol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001210{
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001211 char *data, *end;
Vasily Averin957df452011-06-06 11:33:12 +04001212 char *mountdata_copy = NULL, *options;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001213 unsigned int temp_len, i, j;
1214 char separator[2];
Jeff Layton9b9d6b242009-07-31 06:56:09 -04001215 short int override_uid = -1;
1216 short int override_gid = -1;
1217 bool uid_specified = false;
1218 bool gid_specified = false;
Jeff Laytond8162552012-03-23 14:40:56 -04001219 bool sloppy = false;
1220 char *invalid = NULL;
Jeff Layton88463992010-11-22 15:31:03 -05001221 char *nodename = utsname()->nodename;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001222 char *string = NULL;
1223 char *tmp_end, *value;
1224 char delim;
Jeff Laytonb979aaa2012-11-26 11:09:55 -05001225 bool got_ip = false;
1226 unsigned short port = 0;
1227 struct sockaddr *dstaddr = (struct sockaddr *)&vol->dstaddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001228
1229 separator[0] = ',';
Steve French50c2f752007-07-13 00:33:32 +00001230 separator[1] = 0;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001231 delim = separator[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001232
Jeff Layton6ee95422012-11-26 11:09:57 -05001233 /* ensure we always start with zeroed-out smb_vol */
1234 memset(vol, 0, sizeof(*vol));
1235
Jeff Layton88463992010-11-22 15:31:03 -05001236 /*
1237 * does not have to be perfect mapping since field is
1238 * informational, only used for servers that do not support
1239 * port 445 and it can be overridden at mount time
1240 */
Jeff Layton1397f2e2011-01-07 11:30:28 -05001241 memset(vol->source_rfc1001_name, 0x20, RFC1001_NAME_LEN);
1242 for (i = 0; i < strnlen(nodename, RFC1001_NAME_LEN); i++)
Jeff Layton88463992010-11-22 15:31:03 -05001243 vol->source_rfc1001_name[i] = toupper(nodename[i]);
1244
Jeff Layton1397f2e2011-01-07 11:30:28 -05001245 vol->source_rfc1001_name[RFC1001_NAME_LEN] = 0;
Steve Frencha10faeb22005-08-22 21:38:31 -07001246 /* null target name indicates to use *SMBSERVR default called name
1247 if we end up sending RFC1001 session initialize */
1248 vol->target_rfc1001_name[0] = 0;
Jeff Layton3e4b3e12010-07-19 18:00:17 -04001249 vol->cred_uid = current_uid();
1250 vol->linux_uid = current_uid();
David Howellsa001e5b2008-11-14 10:38:47 +11001251 vol->linux_gid = current_gid();
Jeff Laytonf55ed1a2009-05-26 16:28:11 -04001252
Steve French2baa2682014-09-27 02:19:01 -05001253 /*
1254 * default to SFM style remapping of seven reserved characters
1255 * unless user overrides it or we negotiate CIFS POSIX where
1256 * it is unnecessary. Can not simultaneously use more than one mapping
1257 * since then readdir could list files that open could not open
1258 */
1259 vol->remap = true;
1260
Jeff Laytonf55ed1a2009-05-26 16:28:11 -04001261 /* default to only allowing write access to owner of the mount */
1262 vol->dir_mode = vol->file_mode = S_IRUGO | S_IXUGO | S_IWUSR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001263
1264 /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */
Jeremy Allisonac670552005-06-22 17:26:35 -07001265 /* default is always to request posix paths. */
1266 vol->posix_paths = 1;
Jeff Laytona0c92172009-05-27 15:40:47 -04001267 /* default to using server inode numbers where available */
1268 vol->server_ino = 1;
Jeremy Allisonac670552005-06-22 17:26:35 -07001269
Jeff Layton1b359202012-09-19 15:20:27 -07001270 /* default is to use strict cifs caching semantics */
1271 vol->strict_io = true;
1272
Suresh Jayaraman6d20e842010-12-01 14:42:28 +05301273 vol->actimeo = CIFS_DEF_ACTIMEO;
1274
Jeff Layton23db65f2012-05-15 12:20:51 -04001275 /* FIXME: add autonegotiation -- for now, SMB1 is default */
1276 vol->ops = &smb1_operations;
1277 vol->vals = &smb1_values;
1278
Sean Finneyb9468452011-04-11 13:19:32 +00001279 if (!mountdata)
1280 goto cifs_parse_mount_err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001281
Sean Finneyb9468452011-04-11 13:19:32 +00001282 mountdata_copy = kstrndup(mountdata, PAGE_SIZE, GFP_KERNEL);
1283 if (!mountdata_copy)
1284 goto cifs_parse_mount_err;
1285
1286 options = mountdata_copy;
Pavel Shilovsky4906e502011-04-14 22:00:56 +04001287 end = options + strlen(options);
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001288
Steve French50c2f752007-07-13 00:33:32 +00001289 if (strncmp(options, "sep=", 4) == 0) {
Steve Frenchfb8c4b12007-07-10 01:16:18 +00001290 if (options[4] != 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001291 separator[0] = options[4];
1292 options += 5;
1293 } else {
Joe Perchesf96637b2013-05-04 22:12:25 -05001294 cifs_dbg(FYI, "Null separator not allowed\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001295 }
1296 }
Shirish Pargaonkar3d3ea8e2011-09-26 09:56:44 -05001297 vol->backupuid_specified = false; /* no backup intent for a user */
1298 vol->backupgid_specified = false; /* no backup intent for a group */
Steve French50c2f752007-07-13 00:33:32 +00001299
Jeff Layton37d4f992013-05-24 07:40:05 -04001300 switch (cifs_parse_devname(devname, vol)) {
1301 case 0:
1302 break;
1303 case -ENOMEM:
1304 cifs_dbg(VFS, "Unable to allocate memory for devname.\n");
1305 goto cifs_parse_mount_err;
1306 case -EINVAL:
1307 cifs_dbg(VFS, "Malformed UNC in devname.\n");
1308 goto cifs_parse_mount_err;
1309 default:
1310 cifs_dbg(VFS, "Unknown error parsing devname.\n");
1311 goto cifs_parse_mount_err;
Jeff Laytond387a5c2012-12-10 06:10:46 -05001312 }
1313
Linus Torvalds1da177e2005-04-16 15:20:36 -07001314 while ((data = strsep(&options, separator)) != NULL) {
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001315 substring_t args[MAX_OPT_ARGS];
1316 unsigned long option;
1317 int token;
1318
Linus Torvalds1da177e2005-04-16 15:20:36 -07001319 if (!*data)
1320 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001321
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001322 token = match_token(data, cifs_mount_option_tokens, args);
1323
1324 switch (token) {
1325
1326 /* Ingnore the following */
1327 case Opt_ignore:
1328 break;
1329
1330 /* Boolean values */
1331 case Opt_user_xattr:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001332 vol->no_xattr = 0;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001333 break;
1334 case Opt_nouser_xattr:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001335 vol->no_xattr = 1;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001336 break;
1337 case Opt_forceuid:
Jeff Layton9b9d6b242009-07-31 06:56:09 -04001338 override_uid = 1;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001339 break;
1340 case Opt_noforceuid:
Jeff Layton9b9d6b242009-07-31 06:56:09 -04001341 override_uid = 0;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001342 break;
Jeff Layton72bd4812012-10-03 16:02:36 -04001343 case Opt_forcegid:
1344 override_gid = 1;
1345 break;
1346 case Opt_noforcegid:
1347 override_gid = 0;
1348 break;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001349 case Opt_noblocksend:
Steve Frenchedf1ae42008-10-29 00:47:57 +00001350 vol->noblocksnd = 1;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001351 break;
1352 case Opt_noautotune:
Steve Frenchedf1ae42008-10-29 00:47:57 +00001353 vol->noautotune = 1;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001354 break;
1355 case Opt_hard:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001356 vol->retry = 1;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001357 break;
1358 case Opt_soft:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001359 vol->retry = 0;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001360 break;
1361 case Opt_perm:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001362 vol->noperm = 0;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001363 break;
1364 case Opt_noperm:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001365 vol->noperm = 1;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001366 break;
1367 case Opt_mapchars:
Steve French2baa2682014-09-27 02:19:01 -05001368 vol->sfu_remap = true;
1369 vol->remap = false; /* disable SFM mapping */
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001370 break;
1371 case Opt_nomapchars:
Steve French2baa2682014-09-27 02:19:01 -05001372 vol->sfu_remap = false;
1373 break;
1374 case Opt_mapposix:
1375 vol->remap = true;
1376 vol->sfu_remap = false; /* disable SFU mapping */
1377 break;
1378 case Opt_nomapposix:
1379 vol->remap = false;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001380 break;
1381 case Opt_sfu:
Steve French50c2f752007-07-13 00:33:32 +00001382 vol->sfu_emul = 1;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001383 break;
1384 case Opt_nosfu:
Steve French50c2f752007-07-13 00:33:32 +00001385 vol->sfu_emul = 0;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001386 break;
1387 case Opt_nodfs:
Steve French2c1b8612008-10-16 18:35:21 +00001388 vol->nodfs = 1;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001389 break;
1390 case Opt_posixpaths:
Jeremy Allisonac670552005-06-22 17:26:35 -07001391 vol->posix_paths = 1;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001392 break;
1393 case Opt_noposixpaths:
Jeremy Allisonac670552005-06-22 17:26:35 -07001394 vol->posix_paths = 0;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001395 break;
1396 case Opt_nounix:
Steve Frenchc18c8422007-07-18 23:21:09 +00001397 vol->no_linux_ext = 1;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001398 break;
1399 case Opt_nocase:
Steve French50c2f752007-07-13 00:33:32 +00001400 vol->nocase = 1;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001401 break;
1402 case Opt_brl:
Steve Frenchc46fa8a2005-08-18 20:49:57 -07001403 vol->nobrl = 0;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001404 break;
1405 case Opt_nobrl:
Steve Frenchc46fa8a2005-08-18 20:49:57 -07001406 vol->nobrl = 1;
Pavel Shilovsky5cfdddc2012-03-27 20:51:15 +04001407 /*
1408 * turn off mandatory locking in mode
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001409 * if remote locking is turned off since the
Pavel Shilovsky5cfdddc2012-03-27 20:51:15 +04001410 * local vfs will do advisory
1411 */
Steve French50c2f752007-07-13 00:33:32 +00001412 if (vol->file_mode ==
1413 (S_IALLUGO & ~(S_ISUID | S_IXGRP)))
Steve Frenchd3485d32005-08-19 11:04:29 -07001414 vol->file_mode = S_IALLUGO;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001415 break;
1416 case Opt_forcemandatorylock:
Steve French13a6e422008-12-02 17:24:33 +00001417 vol->mand_lock = 1;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001418 break;
1419 case Opt_setuids:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001420 vol->setuids = 1;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001421 break;
1422 case Opt_nosetuids:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001423 vol->setuids = 0;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001424 break;
1425 case Opt_dynperm:
Jeff Laytond0a9c072008-05-12 22:23:49 +00001426 vol->dynperm = true;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001427 break;
1428 case Opt_nodynperm:
Jeff Laytond0a9c072008-05-12 22:23:49 +00001429 vol->dynperm = false;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001430 break;
1431 case Opt_nohard:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001432 vol->retry = 0;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001433 break;
1434 case Opt_nosoft:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001435 vol->retry = 1;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001436 break;
1437 case Opt_nointr:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001438 vol->intr = 0;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001439 break;
1440 case Opt_intr:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001441 vol->intr = 1;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001442 break;
1443 case Opt_nostrictsync:
Steve Frenchbe652442009-02-23 15:21:59 +00001444 vol->nostrictsync = 1;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001445 break;
1446 case Opt_strictsync:
Steve Frenchbe652442009-02-23 15:21:59 +00001447 vol->nostrictsync = 0;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001448 break;
1449 case Opt_serverino:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001450 vol->server_ino = 1;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001451 break;
1452 case Opt_noserverino:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001453 vol->server_ino = 0;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001454 break;
1455 case Opt_rwpidforward:
Pavel Shilovskyd4ffff12011-05-26 06:02:00 +00001456 vol->rwpidforward = 1;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001457 break;
1458 case Opt_cifsacl:
Steve French0a4b92c2006-01-12 15:44:21 -08001459 vol->cifs_acl = 1;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001460 break;
1461 case Opt_nocifsacl:
Steve French0a4b92c2006-01-12 15:44:21 -08001462 vol->cifs_acl = 0;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001463 break;
1464 case Opt_acl:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001465 vol->no_psx_acl = 0;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001466 break;
1467 case Opt_noacl:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001468 vol->no_psx_acl = 1;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001469 break;
1470 case Opt_locallease:
Steve French84210e92008-10-23 04:42:37 +00001471 vol->local_lease = 1;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001472 break;
1473 case Opt_sign:
Jeff Layton1e3cc572013-06-10 17:12:23 -05001474 vol->sign = true;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001475 break;
1476 case Opt_seal:
Steve French95b1cb92008-05-15 16:44:38 +00001477 /* we do not do the following in secFlags because seal
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001478 * is a per tree connection (mount) not a per socket
1479 * or per-smb connection option in the protocol
1480 * vol->secFlg |= CIFSSEC_MUST_SEAL;
1481 */
Steve French95b1cb92008-05-15 16:44:38 +00001482 vol->seal = 1;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001483 break;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001484 case Opt_noac:
Andy Shevchenko0b456f02014-08-27 16:49:44 +03001485 pr_warn("CIFS: Mount option noac not supported. Instead set /proc/fs/cifs/LookupCacheEnabled to 0\n");
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001486 break;
1487 case Opt_fsc:
Suresh Jayaraman607a5692010-11-24 17:49:05 +05301488#ifndef CONFIG_CIFS_FSCACHE
Joe Perchesf96637b2013-05-04 22:12:25 -05001489 cifs_dbg(VFS, "FS-Cache support needs CONFIG_CIFS_FSCACHE kernel config option set\n");
Sean Finneyb9468452011-04-11 13:19:32 +00001490 goto cifs_parse_mount_err;
Suresh Jayaraman607a5692010-11-24 17:49:05 +05301491#endif
Suresh Jayaramanfa1df752010-07-05 18:13:36 +05301492 vol->fsc = true;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001493 break;
1494 case Opt_mfsymlinks:
Stefan Metzmacher736a3322010-07-30 14:56:00 +02001495 vol->mfsymlinks = true;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001496 break;
1497 case Opt_multiuser:
Jeff Layton0eb8a132010-10-06 19:51:12 -04001498 vol->multiuser = true;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001499 break;
Jeff Laytond8162552012-03-23 14:40:56 -04001500 case Opt_sloppy:
1501 sloppy = true;
1502 break;
Jeff Laytona0b3df52013-05-24 07:40:59 -04001503 case Opt_nosharesock:
1504 vol->nosharesock = true;
1505 break;
Steve Frenchb2a30772015-09-29 21:49:28 -05001506 case Opt_nopersistent:
1507 vol->nopersistent = true;
1508 if (vol->persistent) {
1509 cifs_dbg(VFS,
1510 "persistenthandles mount options conflict\n");
1511 goto cifs_parse_mount_err;
1512 }
1513 break;
1514 case Opt_persistent:
1515 vol->persistent = true;
Steve French592fafe2015-11-03 10:08:53 -06001516 if ((vol->nopersistent) || (vol->resilient)) {
Steve Frenchb2a30772015-09-29 21:49:28 -05001517 cifs_dbg(VFS,
1518 "persistenthandles mount options conflict\n");
1519 goto cifs_parse_mount_err;
1520 }
1521 break;
Steve French592fafe2015-11-03 10:08:53 -06001522 case Opt_resilient:
1523 vol->resilient = true;
1524 if (vol->persistent) {
1525 cifs_dbg(VFS,
1526 "persistenthandles mount options conflict\n");
1527 goto cifs_parse_mount_err;
1528 }
1529 break;
1530 case Opt_noresilient:
1531 vol->resilient = false; /* already the default */
1532 break;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001533
1534 /* Numeric Values */
1535 case Opt_backupuid:
Eric W. Biederman3da46562013-02-06 01:37:39 -08001536 if (get_option_uid(args, &vol->backupuid)) {
Joe Perchesf96637b2013-05-04 22:12:25 -05001537 cifs_dbg(VFS, "%s: Invalid backupuid value\n",
1538 __func__);
Shirish Pargaonkar3d3ea8e2011-09-26 09:56:44 -05001539 goto cifs_parse_mount_err;
1540 }
1541 vol->backupuid_specified = true;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001542 break;
1543 case Opt_backupgid:
Eric W. Biederman3da46562013-02-06 01:37:39 -08001544 if (get_option_gid(args, &vol->backupgid)) {
Joe Perchesf96637b2013-05-04 22:12:25 -05001545 cifs_dbg(VFS, "%s: Invalid backupgid value\n",
1546 __func__);
Shirish Pargaonkar3d3ea8e2011-09-26 09:56:44 -05001547 goto cifs_parse_mount_err;
1548 }
1549 vol->backupgid_specified = true;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001550 break;
1551 case Opt_uid:
Eric W. Biederman3da46562013-02-06 01:37:39 -08001552 if (get_option_uid(args, &vol->linux_uid)) {
Joe Perchesf96637b2013-05-04 22:12:25 -05001553 cifs_dbg(VFS, "%s: Invalid uid value\n",
1554 __func__);
Sean Finneyb9468452011-04-11 13:19:32 +00001555 goto cifs_parse_mount_err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001556 }
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001557 uid_specified = true;
1558 break;
1559 case Opt_cruid:
Eric W. Biederman3da46562013-02-06 01:37:39 -08001560 if (get_option_uid(args, &vol->cred_uid)) {
Joe Perchesf96637b2013-05-04 22:12:25 -05001561 cifs_dbg(VFS, "%s: Invalid cruid value\n",
1562 __func__);
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001563 goto cifs_parse_mount_err;
1564 }
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001565 break;
1566 case Opt_gid:
Eric W. Biederman3da46562013-02-06 01:37:39 -08001567 if (get_option_gid(args, &vol->linux_gid)) {
Joe Perchesf96637b2013-05-04 22:12:25 -05001568 cifs_dbg(VFS, "%s: Invalid gid value\n",
1569 __func__);
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001570 goto cifs_parse_mount_err;
1571 }
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001572 gid_specified = true;
1573 break;
1574 case Opt_file_mode:
1575 if (get_option_ul(args, &option)) {
Joe Perchesf96637b2013-05-04 22:12:25 -05001576 cifs_dbg(VFS, "%s: Invalid file_mode value\n",
1577 __func__);
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001578 goto cifs_parse_mount_err;
1579 }
1580 vol->file_mode = option;
1581 break;
1582 case Opt_dirmode:
1583 if (get_option_ul(args, &option)) {
Joe Perchesf96637b2013-05-04 22:12:25 -05001584 cifs_dbg(VFS, "%s: Invalid dir_mode value\n",
1585 __func__);
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001586 goto cifs_parse_mount_err;
1587 }
1588 vol->dir_mode = option;
1589 break;
1590 case Opt_port:
Jeff Laytonb979aaa2012-11-26 11:09:55 -05001591 if (get_option_ul(args, &option) ||
1592 option > USHRT_MAX) {
Joe Perchesf96637b2013-05-04 22:12:25 -05001593 cifs_dbg(VFS, "%s: Invalid port value\n",
1594 __func__);
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001595 goto cifs_parse_mount_err;
1596 }
Jeff Laytonb979aaa2012-11-26 11:09:55 -05001597 port = (unsigned short)option;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001598 break;
1599 case Opt_rsize:
1600 if (get_option_ul(args, &option)) {
Joe Perchesf96637b2013-05-04 22:12:25 -05001601 cifs_dbg(VFS, "%s: Invalid rsize value\n",
1602 __func__);
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001603 goto cifs_parse_mount_err;
1604 }
1605 vol->rsize = option;
1606 break;
1607 case Opt_wsize:
1608 if (get_option_ul(args, &option)) {
Joe Perchesf96637b2013-05-04 22:12:25 -05001609 cifs_dbg(VFS, "%s: Invalid wsize value\n",
1610 __func__);
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001611 goto cifs_parse_mount_err;
1612 }
1613 vol->wsize = option;
1614 break;
1615 case Opt_actimeo:
1616 if (get_option_ul(args, &option)) {
Joe Perchesf96637b2013-05-04 22:12:25 -05001617 cifs_dbg(VFS, "%s: Invalid actimeo value\n",
1618 __func__);
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001619 goto cifs_parse_mount_err;
1620 }
1621 vol->actimeo = HZ * option;
1622 if (vol->actimeo > CIFS_MAX_ACTIMEO) {
Joe Perchesf96637b2013-05-04 22:12:25 -05001623 cifs_dbg(VFS, "attribute cache timeout too large\n");
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001624 goto cifs_parse_mount_err;
1625 }
1626 break;
1627
1628 /* String Arguments */
1629
Sachin Prabhu4fe9e962012-04-10 18:12:27 +01001630 case Opt_blank_user:
1631 /* null user, ie. anonymous authentication */
1632 vol->nullauth = 1;
1633 vol->username = NULL;
1634 break;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001635 case Opt_user:
1636 string = match_strdup(args);
1637 if (string == NULL)
1638 goto out_nomem;
1639
Scott Lovenberg8c3a2b42013-08-09 08:47:17 -04001640 if (strnlen(string, CIFS_MAX_USERNAME_LEN) >
1641 CIFS_MAX_USERNAME_LEN) {
Andy Shevchenko0b456f02014-08-27 16:49:44 +03001642 pr_warn("CIFS: username too long\n");
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001643 goto cifs_parse_mount_err;
1644 }
Taesoo Kim2bd50fb2015-03-21 19:08:30 -04001645
1646 kfree(vol->username);
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001647 vol->username = kstrdup(string, GFP_KERNEL);
Joe Perchesf96637b2013-05-04 22:12:25 -05001648 if (!vol->username)
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001649 goto cifs_parse_mount_err;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001650 break;
1651 case Opt_blank_pass:
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001652 /* passwords have to be handled differently
1653 * to allow the character used for deliminator
1654 * to be passed within them
1655 */
1656
Sachin Prabhuc369c9a2013-04-09 18:17:41 +01001657 /*
1658 * Check if this is a case where the password
1659 * starts with a delimiter
1660 */
1661 tmp_end = strchr(data, '=');
1662 tmp_end++;
1663 if (!(tmp_end < end && tmp_end[1] == delim)) {
1664 /* No it is not. Set the password to NULL */
Namjae Jeond6ccf492014-08-21 19:11:20 +09001665 kfree(vol->password);
Sachin Prabhuc369c9a2013-04-09 18:17:41 +01001666 vol->password = NULL;
1667 break;
1668 }
1669 /* Yes it is. Drop down to Opt_pass below.*/
1670 case Opt_pass:
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001671 /* Obtain the value string */
1672 value = strchr(data, '=');
Sachin Prabhu10238072012-03-28 18:07:08 +01001673 value++;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001674
1675 /* Set tmp_end to end of the string */
1676 tmp_end = (char *) value + strlen(value);
1677
1678 /* Check if following character is the deliminator
1679 * If yes, we have encountered a double deliminator
1680 * reset the NULL character to the deliminator
1681 */
Suresh Jayaramane73f8432012-06-12 07:15:50 +05301682 if (tmp_end < end && tmp_end[1] == delim) {
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001683 tmp_end[0] = delim;
1684
Suresh Jayaramane73f8432012-06-12 07:15:50 +05301685 /* Keep iterating until we get to a single
1686 * deliminator OR the end
1687 */
1688 while ((tmp_end = strchr(tmp_end, delim))
1689 != NULL && (tmp_end[1] == delim)) {
1690 tmp_end = (char *) &tmp_end[2];
1691 }
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001692
Suresh Jayaramane73f8432012-06-12 07:15:50 +05301693 /* Reset var options to point to next element */
1694 if (tmp_end) {
1695 tmp_end[0] = '\0';
1696 options = (char *) &tmp_end[1];
1697 } else
1698 /* Reached the end of the mount option
1699 * string */
1700 options = end;
1701 }
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001702
Namjae Jeond6ccf492014-08-21 19:11:20 +09001703 kfree(vol->password);
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001704 /* Now build new password string */
1705 temp_len = strlen(value);
1706 vol->password = kzalloc(temp_len+1, GFP_KERNEL);
1707 if (vol->password == NULL) {
Andy Shevchenko0b456f02014-08-27 16:49:44 +03001708 pr_warn("CIFS: no memory for password\n");
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001709 goto cifs_parse_mount_err;
1710 }
1711
1712 for (i = 0, j = 0; i < temp_len; i++, j++) {
1713 vol->password[j] = value[i];
1714 if ((value[i] == delim) &&
1715 value[i+1] == delim)
1716 /* skip the second deliminator */
1717 i++;
1718 }
1719 vol->password[j] = '\0';
1720 break;
Sachin Prabhu4fe9e962012-04-10 18:12:27 +01001721 case Opt_blank_ip:
Jeff Laytonb979aaa2012-11-26 11:09:55 -05001722 /* FIXME: should this be an error instead? */
1723 got_ip = false;
Sachin Prabhu4fe9e962012-04-10 18:12:27 +01001724 break;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001725 case Opt_ip:
1726 string = match_strdup(args);
1727 if (string == NULL)
1728 goto out_nomem;
1729
Jeff Laytonb979aaa2012-11-26 11:09:55 -05001730 if (!cifs_convert_address(dstaddr, string,
1731 strlen(string))) {
Andy Shevchenko0b456f02014-08-27 16:49:44 +03001732 pr_err("CIFS: bad ip= option (%s).\n", string);
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001733 goto cifs_parse_mount_err;
1734 }
Jeff Laytonb979aaa2012-11-26 11:09:55 -05001735 got_ip = true;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001736 break;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001737 case Opt_domain:
1738 string = match_strdup(args);
1739 if (string == NULL)
1740 goto out_nomem;
1741
Chen Gang057d6332013-07-19 09:01:36 +08001742 if (strnlen(string, CIFS_MAX_DOMAINNAME_LEN)
1743 == CIFS_MAX_DOMAINNAME_LEN) {
Andy Shevchenko0b456f02014-08-27 16:49:44 +03001744 pr_warn("CIFS: domain name too long\n");
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001745 goto cifs_parse_mount_err;
1746 }
1747
Taesoo Kim2bd50fb2015-03-21 19:08:30 -04001748 kfree(vol->domainname);
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001749 vol->domainname = kstrdup(string, GFP_KERNEL);
1750 if (!vol->domainname) {
Andy Shevchenko0b456f02014-08-27 16:49:44 +03001751 pr_warn("CIFS: no memory for domainname\n");
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001752 goto cifs_parse_mount_err;
1753 }
Joe Perchesf96637b2013-05-04 22:12:25 -05001754 cifs_dbg(FYI, "Domain name set\n");
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001755 break;
1756 case Opt_srcaddr:
1757 string = match_strdup(args);
1758 if (string == NULL)
1759 goto out_nomem;
1760
Sachin Prabhu4fe9e962012-04-10 18:12:27 +01001761 if (!cifs_convert_address(
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001762 (struct sockaddr *)&vol->srcaddr,
1763 string, strlen(string))) {
Andy Shevchenko0b456f02014-08-27 16:49:44 +03001764 pr_warn("CIFS: Could not parse srcaddr: %s\n",
1765 string);
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001766 goto cifs_parse_mount_err;
1767 }
1768 break;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001769 case Opt_iocharset:
1770 string = match_strdup(args);
1771 if (string == NULL)
1772 goto out_nomem;
1773
Sachin Prabhu4fe9e962012-04-10 18:12:27 +01001774 if (strnlen(string, 1024) >= 65) {
Andy Shevchenko0b456f02014-08-27 16:49:44 +03001775 pr_warn("CIFS: iocharset name too long.\n");
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001776 goto cifs_parse_mount_err;
1777 }
1778
Rasmus Villemoes87e747c2014-10-13 15:54:35 -07001779 if (strncasecmp(string, "default", 7) != 0) {
Taesoo Kim2bd50fb2015-03-21 19:08:30 -04001780 kfree(vol->iocharset);
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001781 vol->iocharset = kstrdup(string,
1782 GFP_KERNEL);
1783 if (!vol->iocharset) {
Andy Shevchenko0b456f02014-08-27 16:49:44 +03001784 pr_warn("CIFS: no memory for charset\n");
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001785 goto cifs_parse_mount_err;
1786 }
1787 }
1788 /* if iocharset not set then load_nls_default
1789 * is used by caller
1790 */
Joe Perchesf96637b2013-05-04 22:12:25 -05001791 cifs_dbg(FYI, "iocharset set to %s\n", string);
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001792 break;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001793 case Opt_netbiosname:
1794 string = match_strdup(args);
1795 if (string == NULL)
1796 goto out_nomem;
1797
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001798 memset(vol->source_rfc1001_name, 0x20,
1799 RFC1001_NAME_LEN);
1800 /*
1801 * FIXME: are there cases in which a comma can
1802 * be valid in workstation netbios name (and
1803 * need special handling)?
1804 */
1805 for (i = 0; i < RFC1001_NAME_LEN; i++) {
1806 /* don't ucase netbiosname for user */
1807 if (string[i] == 0)
1808 break;
1809 vol->source_rfc1001_name[i] = string[i];
1810 }
1811 /* The string has 16th byte zero still from
1812 * set at top of the function
1813 */
1814 if (i == RFC1001_NAME_LEN && string[i] != 0)
Andy Shevchenko0b456f02014-08-27 16:49:44 +03001815 pr_warn("CIFS: netbiosname longer than 15 truncated.\n");
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001816 break;
1817 case Opt_servern:
1818 /* servernetbiosname specified override *SMBSERVER */
1819 string = match_strdup(args);
1820 if (string == NULL)
1821 goto out_nomem;
1822
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001823 /* last byte, type, is 0x20 for servr type */
1824 memset(vol->target_rfc1001_name, 0x20,
1825 RFC1001_NAME_LEN_WITH_NULL);
1826
1827 /* BB are there cases in which a comma can be
1828 valid in this workstation netbios name
1829 (and need special handling)? */
1830
1831 /* user or mount helper must uppercase the
1832 netbios name */
1833 for (i = 0; i < 15; i++) {
1834 if (string[i] == 0)
1835 break;
1836 vol->target_rfc1001_name[i] = string[i];
1837 }
1838 /* The string has 16th byte zero still from
1839 set at top of the function */
1840 if (i == RFC1001_NAME_LEN && string[i] != 0)
Andy Shevchenko0b456f02014-08-27 16:49:44 +03001841 pr_warn("CIFS: server netbiosname longer than 15 truncated.\n");
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001842 break;
1843 case Opt_ver:
1844 string = match_strdup(args);
1845 if (string == NULL)
1846 goto out_nomem;
1847
Rasmus Villemoes87e747c2014-10-13 15:54:35 -07001848 if (strncasecmp(string, "1", 1) == 0) {
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001849 /* This is the default */
1850 break;
1851 }
1852 /* For all other value, error */
Andy Shevchenko0b456f02014-08-27 16:49:44 +03001853 pr_warn("CIFS: Invalid version specified\n");
Sean Finneyb9468452011-04-11 13:19:32 +00001854 goto cifs_parse_mount_err;
Jeff Layton23db65f2012-05-15 12:20:51 -04001855 case Opt_vers:
1856 string = match_strdup(args);
1857 if (string == NULL)
1858 goto out_nomem;
1859
1860 if (cifs_parse_smb_version(string, vol) != 0)
1861 goto cifs_parse_mount_err;
1862 break;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001863 case Opt_sec:
1864 string = match_strdup(args);
1865 if (string == NULL)
1866 goto out_nomem;
1867
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001868 if (cifs_parse_security_flavors(string, vol) != 0)
1869 goto cifs_parse_mount_err;
1870 break;
Jeff Layton15b6a472012-05-16 07:50:15 -04001871 case Opt_cache:
1872 string = match_strdup(args);
1873 if (string == NULL)
1874 goto out_nomem;
1875
1876 if (cifs_parse_cache_flavor(string, vol) != 0)
1877 goto cifs_parse_mount_err;
1878 break;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001879 default:
Jeff Laytond8162552012-03-23 14:40:56 -04001880 /*
1881 * An option we don't recognize. Save it off for later
1882 * if we haven't already found one
1883 */
1884 if (!invalid)
1885 invalid = data;
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001886 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001887 }
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001888 /* Free up any allocated string */
1889 kfree(string);
1890 string = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001891 }
Jeff Layton0eb8a132010-10-06 19:51:12 -04001892
Jeff Laytond8162552012-03-23 14:40:56 -04001893 if (!sloppy && invalid) {
Andy Shevchenko0b456f02014-08-27 16:49:44 +03001894 pr_err("CIFS: Unknown mount option \"%s\"\n", invalid);
Jeff Laytond8162552012-03-23 14:40:56 -04001895 goto cifs_parse_mount_err;
1896 }
1897
Jeff Layton8a8798a2012-01-17 16:09:15 -05001898#ifndef CONFIG_KEYS
1899 /* Muliuser mounts require CONFIG_KEYS support */
1900 if (vol->multiuser) {
Joe Perchesf96637b2013-05-04 22:12:25 -05001901 cifs_dbg(VFS, "Multiuser mounts require kernels with CONFIG_KEYS enabled\n");
Sean Finneyb9468452011-04-11 13:19:32 +00001902 goto cifs_parse_mount_err;
Jeff Layton0eb8a132010-10-06 19:51:12 -04001903 }
Jeff Layton8a8798a2012-01-17 16:09:15 -05001904#endif
Jeff Laytone5e69ab2012-11-25 08:00:42 -05001905 if (!vol->UNC) {
Jeff Layton37d4f992013-05-24 07:40:05 -04001906 cifs_dbg(VFS, "CIFS mount error: No usable UNC path provided in device string!\n");
Jeff Laytone5e69ab2012-11-25 08:00:42 -05001907 goto cifs_parse_mount_err;
1908 }
Jeff Layton0eb8a132010-10-06 19:51:12 -04001909
Jeff Layton62a1a432012-12-10 06:10:45 -05001910 /* make sure UNC has a share name */
1911 if (!strchr(vol->UNC + 3, '\\')) {
Joe Perchesf96637b2013-05-04 22:12:25 -05001912 cifs_dbg(VFS, "Malformed UNC. Unable to find share name.\n");
Jeff Layton62a1a432012-12-10 06:10:45 -05001913 goto cifs_parse_mount_err;
1914 }
1915
Jeff Laytonb979aaa2012-11-26 11:09:55 -05001916 if (!got_ip) {
1917 /* No ip= option specified? Try to get it from UNC */
1918 if (!cifs_convert_address(dstaddr, &vol->UNC[2],
1919 strlen(&vol->UNC[2]))) {
Andy Shevchenko0b456f02014-08-27 16:49:44 +03001920 pr_err("Unable to determine destination address.\n");
Jeff Laytonb979aaa2012-11-26 11:09:55 -05001921 goto cifs_parse_mount_err;
1922 }
1923 }
1924
1925 /* set the port that we got earlier */
1926 cifs_set_port(dstaddr, port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001927
Jeff Layton9b9d6b242009-07-31 06:56:09 -04001928 if (uid_specified)
1929 vol->override_uid = override_uid;
1930 else if (override_uid == 1)
Andy Shevchenko0b456f02014-08-27 16:49:44 +03001931 pr_notice("CIFS: ignoring forceuid mount option specified with no uid= option.\n");
Jeff Layton9b9d6b242009-07-31 06:56:09 -04001932
1933 if (gid_specified)
1934 vol->override_gid = override_gid;
1935 else if (override_gid == 1)
Andy Shevchenko0b456f02014-08-27 16:49:44 +03001936 pr_notice("CIFS: ignoring forcegid mount option specified with no gid= option.\n");
Jeff Layton9b9d6b242009-07-31 06:56:09 -04001937
Sean Finneyb9468452011-04-11 13:19:32 +00001938 kfree(mountdata_copy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001939 return 0;
Sean Finneyb9468452011-04-11 13:19:32 +00001940
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001941out_nomem:
Andy Shevchenko0b456f02014-08-27 16:49:44 +03001942 pr_warn("Could not allocate temporary buffer\n");
Sean Finneyb9468452011-04-11 13:19:32 +00001943cifs_parse_mount_err:
Sachin Prabhu8830d7e2012-03-23 14:40:56 -04001944 kfree(string);
Sean Finneyb9468452011-04-11 13:19:32 +00001945 kfree(mountdata_copy);
1946 return 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001947}
1948
Ben Greear3eb9a882010-09-01 17:06:02 -07001949/** Returns true if srcaddr isn't specified and rhs isn't
1950 * specified, or if srcaddr is specified and
1951 * matches the IP address of the rhs argument.
1952 */
Jeff Layton45151482010-07-06 20:43:02 -04001953static bool
Ben Greear3eb9a882010-09-01 17:06:02 -07001954srcip_matches(struct sockaddr *srcaddr, struct sockaddr *rhs)
1955{
1956 switch (srcaddr->sa_family) {
1957 case AF_UNSPEC:
1958 return (rhs->sa_family == AF_UNSPEC);
1959 case AF_INET: {
1960 struct sockaddr_in *saddr4 = (struct sockaddr_in *)srcaddr;
1961 struct sockaddr_in *vaddr4 = (struct sockaddr_in *)rhs;
1962 return (saddr4->sin_addr.s_addr == vaddr4->sin_addr.s_addr);
1963 }
1964 case AF_INET6: {
1965 struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *)srcaddr;
Nickolai Zeldoviche3e27752013-01-16 21:36:17 -05001966 struct sockaddr_in6 *vaddr6 = (struct sockaddr_in6 *)rhs;
Ben Greear3eb9a882010-09-01 17:06:02 -07001967 return ipv6_addr_equal(&saddr6->sin6_addr, &vaddr6->sin6_addr);
1968 }
1969 default:
1970 WARN_ON(1);
1971 return false; /* don't expect to be here */
1972 }
1973}
1974
Pavel Shilovsky4b886132010-12-13 22:18:07 +03001975/*
1976 * If no port is specified in addr structure, we try to match with 445 port
1977 * and if it fails - with 139 ports. It should be called only if address
1978 * families of server and addr are equal.
1979 */
1980static bool
1981match_port(struct TCP_Server_Info *server, struct sockaddr *addr)
1982{
Steve French6da97912011-03-13 18:55:55 +00001983 __be16 port, *sport;
Pavel Shilovsky4b886132010-12-13 22:18:07 +03001984
1985 switch (addr->sa_family) {
1986 case AF_INET:
1987 sport = &((struct sockaddr_in *) &server->dstaddr)->sin_port;
1988 port = ((struct sockaddr_in *) addr)->sin_port;
1989 break;
1990 case AF_INET6:
1991 sport = &((struct sockaddr_in6 *) &server->dstaddr)->sin6_port;
1992 port = ((struct sockaddr_in6 *) addr)->sin6_port;
1993 break;
1994 default:
1995 WARN_ON(1);
1996 return false;
1997 }
1998
1999 if (!port) {
2000 port = htons(CIFS_PORT);
2001 if (port == *sport)
2002 return true;
2003
2004 port = htons(RFC1001_PORT);
2005 }
2006
2007 return port == *sport;
2008}
Ben Greear3eb9a882010-09-01 17:06:02 -07002009
2010static bool
2011match_address(struct TCP_Server_Info *server, struct sockaddr *addr,
2012 struct sockaddr *srcaddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002013{
Jeff Layton45151482010-07-06 20:43:02 -04002014 switch (addr->sa_family) {
Pavel Shilovskya9f1b852010-12-13 19:08:35 +03002015 case AF_INET: {
2016 struct sockaddr_in *addr4 = (struct sockaddr_in *)addr;
2017 struct sockaddr_in *srv_addr4 =
2018 (struct sockaddr_in *)&server->dstaddr;
2019
2020 if (addr4->sin_addr.s_addr != srv_addr4->sin_addr.s_addr)
Jeff Layton45151482010-07-06 20:43:02 -04002021 return false;
Jeff Layton45151482010-07-06 20:43:02 -04002022 break;
Pavel Shilovskya9f1b852010-12-13 19:08:35 +03002023 }
2024 case AF_INET6: {
2025 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr;
2026 struct sockaddr_in6 *srv_addr6 =
2027 (struct sockaddr_in6 *)&server->dstaddr;
2028
Jeff Layton45151482010-07-06 20:43:02 -04002029 if (!ipv6_addr_equal(&addr6->sin6_addr,
Pavel Shilovskya9f1b852010-12-13 19:08:35 +03002030 &srv_addr6->sin6_addr))
Jeff Layton45151482010-07-06 20:43:02 -04002031 return false;
Pavel Shilovskya9f1b852010-12-13 19:08:35 +03002032 if (addr6->sin6_scope_id != srv_addr6->sin6_scope_id)
Jeff Layton45151482010-07-06 20:43:02 -04002033 return false;
Jeff Layton45151482010-07-06 20:43:02 -04002034 break;
2035 }
Pavel Shilovskya9f1b852010-12-13 19:08:35 +03002036 default:
2037 WARN_ON(1);
2038 return false; /* don't expect to be here */
2039 }
Jeff Layton45151482010-07-06 20:43:02 -04002040
Ben Greear3eb9a882010-09-01 17:06:02 -07002041 if (!srcip_matches(srcaddr, (struct sockaddr *)&server->srcaddr))
2042 return false;
2043
Jeff Layton45151482010-07-06 20:43:02 -04002044 return true;
2045}
2046
Jeff Laytondaf5b0b2010-07-06 20:43:02 -04002047static bool
2048match_security(struct TCP_Server_Info *server, struct smb_vol *vol)
2049{
Jeff Layton3f618222013-06-12 19:52:14 -05002050 /*
2051 * The select_sectype function should either return the vol->sectype
2052 * that was specified, or "Unspecified" if that sectype was not
2053 * compatible with the given NEGOTIATE request.
2054 */
2055 if (select_sectype(server, vol->sectype) == Unspecified)
Jeff Laytondaf5b0b2010-07-06 20:43:02 -04002056 return false;
Jeff Laytondaf5b0b2010-07-06 20:43:02 -04002057
Jeff Layton3f618222013-06-12 19:52:14 -05002058 /*
2059 * Now check if signing mode is acceptable. No need to check
2060 * global_secflags at this point since if MUST_SIGN is set then
2061 * the server->sign had better be too.
2062 */
Jeff Layton38d77c52013-05-26 07:01:00 -04002063 if (vol->sign && !server->sign)
2064 return false;
Jeff Laytondaf5b0b2010-07-06 20:43:02 -04002065
2066 return true;
2067}
2068
Jeff Layton9fa114f2012-11-26 11:09:57 -05002069static int match_server(struct TCP_Server_Info *server, struct smb_vol *vol)
Pavel Shilovsky37bb04e2011-05-05 09:55:11 +00002070{
Jeff Layton9fa114f2012-11-26 11:09:57 -05002071 struct sockaddr *addr = (struct sockaddr *)&vol->dstaddr;
2072
Jeff Laytona0b3df52013-05-24 07:40:59 -04002073 if (vol->nosharesock)
2074 return 0;
2075
Jeff Layton23db65f2012-05-15 12:20:51 -04002076 if ((server->vals != vol->vals) || (server->ops != vol->ops))
2077 return 0;
2078
Pavel Shilovsky37bb04e2011-05-05 09:55:11 +00002079 if (!net_eq(cifs_net_ns(server), current->nsproxy->net_ns))
2080 return 0;
2081
2082 if (!match_address(server, addr,
2083 (struct sockaddr *)&vol->srcaddr))
2084 return 0;
2085
2086 if (!match_port(server, addr))
2087 return 0;
2088
2089 if (!match_security(server, vol))
2090 return 0;
2091
2092 return 1;
2093}
2094
Jeff Layton45151482010-07-06 20:43:02 -04002095static struct TCP_Server_Info *
Jeff Layton9fa114f2012-11-26 11:09:57 -05002096cifs_find_tcp_session(struct smb_vol *vol)
Jeff Layton45151482010-07-06 20:43:02 -04002097{
Jeff Laytone7ddee92008-11-14 13:44:38 -05002098 struct TCP_Server_Info *server;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002099
Suresh Jayaraman3f9bcca2010-10-18 23:29:37 +05302100 spin_lock(&cifs_tcp_ses_lock);
Jeff Layton45151482010-07-06 20:43:02 -04002101 list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
Jeff Layton9fa114f2012-11-26 11:09:57 -05002102 if (!match_server(server, vol))
Jeff Laytondaf5b0b2010-07-06 20:43:02 -04002103 continue;
2104
Jeff Laytone7ddee92008-11-14 13:44:38 -05002105 ++server->srv_count;
Suresh Jayaraman3f9bcca2010-10-18 23:29:37 +05302106 spin_unlock(&cifs_tcp_ses_lock);
Joe Perchesf96637b2013-05-04 22:12:25 -05002107 cifs_dbg(FYI, "Existing tcp session with server found\n");
Jeff Laytone7ddee92008-11-14 13:44:38 -05002108 return server;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002109 }
Suresh Jayaraman3f9bcca2010-10-18 23:29:37 +05302110 spin_unlock(&cifs_tcp_ses_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002111 return NULL;
2112}
2113
Jeff Layton14fbf502008-11-14 13:53:46 -05002114static void
Jeff Laytone7ddee92008-11-14 13:44:38 -05002115cifs_put_tcp_session(struct TCP_Server_Info *server)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002116{
Steve Frencha5c3e1c2014-09-16 04:16:19 -05002117 struct task_struct *task;
2118
Suresh Jayaraman3f9bcca2010-10-18 23:29:37 +05302119 spin_lock(&cifs_tcp_ses_lock);
Jeff Laytone7ddee92008-11-14 13:44:38 -05002120 if (--server->srv_count > 0) {
Suresh Jayaraman3f9bcca2010-10-18 23:29:37 +05302121 spin_unlock(&cifs_tcp_ses_lock);
Jeff Laytone7ddee92008-11-14 13:44:38 -05002122 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002123 }
Steve Frenchdea570e02008-05-06 22:05:51 +00002124
Rob Landleyf1d0c992011-01-22 15:44:05 -06002125 put_net(cifs_net_ns(server));
2126
Jeff Laytone7ddee92008-11-14 13:44:38 -05002127 list_del_init(&server->tcp_ses_list);
Suresh Jayaraman3f9bcca2010-10-18 23:29:37 +05302128 spin_unlock(&cifs_tcp_ses_lock);
Jeff Laytone7ddee92008-11-14 13:44:38 -05002129
Jeff Laytonc74093b2011-01-11 07:24:23 -05002130 cancel_delayed_work_sync(&server->echo);
2131
Jeff Laytone7ddee92008-11-14 13:44:38 -05002132 spin_lock(&GlobalMid_Lock);
2133 server->tcpStatus = CifsExiting;
2134 spin_unlock(&GlobalMid_Lock);
2135
Shirish Pargaonkard2b91522010-10-21 14:25:08 -05002136 cifs_crypto_shash_release(server);
Suresh Jayaraman488f1d2d2010-07-05 18:12:15 +05302137 cifs_fscache_release_client_cookie(server);
2138
Shirish Pargaonkar21e73392010-10-21 06:42:55 -05002139 kfree(server->session_key.response);
2140 server->session_key.response = NULL;
2141 server->session_key.len = 0;
Steve Frencha5c3e1c2014-09-16 04:16:19 -05002142
2143 task = xchg(&server->tsk, NULL);
2144 if (task)
2145 force_sig(SIGKILL, task);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002146}
2147
Jeff Layton63c038c2008-12-01 18:41:46 -05002148static struct TCP_Server_Info *
2149cifs_get_tcp_session(struct smb_vol *volume_info)
2150{
2151 struct TCP_Server_Info *tcp_ses = NULL;
Jeff Layton63c038c2008-12-01 18:41:46 -05002152 int rc;
2153
Joe Perchesf96637b2013-05-04 22:12:25 -05002154 cifs_dbg(FYI, "UNC: %s\n", volume_info->UNC);
Jeff Layton63c038c2008-12-01 18:41:46 -05002155
2156 /* see if we already have a matching tcp_ses */
Jeff Layton9fa114f2012-11-26 11:09:57 -05002157 tcp_ses = cifs_find_tcp_session(volume_info);
Jeff Layton63c038c2008-12-01 18:41:46 -05002158 if (tcp_ses)
2159 return tcp_ses;
2160
2161 tcp_ses = kzalloc(sizeof(struct TCP_Server_Info), GFP_KERNEL);
2162 if (!tcp_ses) {
2163 rc = -ENOMEM;
2164 goto out_err;
2165 }
2166
Jeff Layton23db65f2012-05-15 12:20:51 -04002167 tcp_ses->ops = volume_info->ops;
2168 tcp_ses->vals = volume_info->vals;
Rob Landleyf1d0c992011-01-22 15:44:05 -06002169 cifs_set_net_ns(tcp_ses, get_net(current->nsproxy->net_ns));
Jeff Layton63c038c2008-12-01 18:41:46 -05002170 tcp_ses->hostname = extract_hostname(volume_info->UNC);
2171 if (IS_ERR(tcp_ses->hostname)) {
2172 rc = PTR_ERR(tcp_ses->hostname);
Shirish Pargaonkarf7c54452010-10-26 18:10:24 -05002173 goto out_err_crypto_release;
Jeff Layton63c038c2008-12-01 18:41:46 -05002174 }
2175
2176 tcp_ses->noblocksnd = volume_info->noblocksnd;
2177 tcp_ses->noautotune = volume_info->noautotune;
Steve French6a5fa2362010-01-01 01:28:43 +00002178 tcp_ses->tcp_nodelay = volume_info->sockopt_tcp_nodelay;
Pavel Shilovskyfc40f9c2012-02-17 17:09:12 +03002179 tcp_ses->in_flight = 0;
Pavel Shilovsky2d86dbc2012-02-06 15:59:18 +04002180 tcp_ses->credits = 1;
Jeff Layton63c038c2008-12-01 18:41:46 -05002181 init_waitqueue_head(&tcp_ses->response_q);
2182 init_waitqueue_head(&tcp_ses->request_q);
2183 INIT_LIST_HEAD(&tcp_ses->pending_mid_q);
2184 mutex_init(&tcp_ses->srv_mutex);
2185 memcpy(tcp_ses->workstation_RFC1001_name,
2186 volume_info->source_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL);
2187 memcpy(tcp_ses->server_RFC1001_name,
2188 volume_info->target_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL);
Shirish Pargaonkar5d0d2882010-10-13 18:15:00 -05002189 tcp_ses->session_estab = false;
Jeff Layton63c038c2008-12-01 18:41:46 -05002190 tcp_ses->sequence_number = 0;
Steve Frenchfda35942011-01-20 18:06:34 +00002191 tcp_ses->lstrp = jiffies;
Jeff Layton58fa0152012-05-01 17:41:16 -04002192 spin_lock_init(&tcp_ses->req_lock);
Jeff Layton63c038c2008-12-01 18:41:46 -05002193 INIT_LIST_HEAD(&tcp_ses->tcp_ses_list);
2194 INIT_LIST_HEAD(&tcp_ses->smb_ses_list);
Jeff Laytonc74093b2011-01-11 07:24:23 -05002195 INIT_DELAYED_WORK(&tcp_ses->echo, cifs_echo_request);
Jeff Layton9fa114f2012-11-26 11:09:57 -05002196 memcpy(&tcp_ses->srcaddr, &volume_info->srcaddr,
2197 sizeof(tcp_ses->srcaddr));
2198 memcpy(&tcp_ses->dstaddr, &volume_info->dstaddr,
2199 sizeof(tcp_ses->dstaddr));
Sachin Prabhu39552ea2014-05-13 00:48:12 +01002200#ifdef CONFIG_CIFS_SMB2
2201 get_random_bytes(tcp_ses->client_guid, SMB2_CLIENT_GUID_SIZE);
2202#endif
Jeff Layton63c038c2008-12-01 18:41:46 -05002203 /*
2204 * at this point we are the only ones with the pointer
2205 * to the struct since the kernel thread not created yet
2206 * no need to spinlock this init of tcpStatus or srv_count
2207 */
2208 tcp_ses->tcpStatus = CifsNew;
2209 ++tcp_ses->srv_count;
2210
Pavel Shilovskya9f1b852010-12-13 19:08:35 +03002211 rc = ip_connect(tcp_ses);
Jeff Layton63c038c2008-12-01 18:41:46 -05002212 if (rc < 0) {
Joe Perchesf96637b2013-05-04 22:12:25 -05002213 cifs_dbg(VFS, "Error connecting to socket. Aborting operation.\n");
Shirish Pargaonkarf7c54452010-10-26 18:10:24 -05002214 goto out_err_crypto_release;
Jeff Layton63c038c2008-12-01 18:41:46 -05002215 }
2216
2217 /*
2218 * since we're in a cifs function already, we know that
2219 * this will succeed. No need for try_module_get().
2220 */
2221 __module_get(THIS_MODULE);
Al Viro7c97c202011-06-21 08:51:28 -04002222 tcp_ses->tsk = kthread_run(cifs_demultiplex_thread,
Jeff Layton63c038c2008-12-01 18:41:46 -05002223 tcp_ses, "cifsd");
2224 if (IS_ERR(tcp_ses->tsk)) {
2225 rc = PTR_ERR(tcp_ses->tsk);
Joe Perchesf96637b2013-05-04 22:12:25 -05002226 cifs_dbg(VFS, "error %d create cifsd thread\n", rc);
Jeff Layton63c038c2008-12-01 18:41:46 -05002227 module_put(THIS_MODULE);
Shirish Pargaonkarf7c54452010-10-26 18:10:24 -05002228 goto out_err_crypto_release;
Jeff Layton63c038c2008-12-01 18:41:46 -05002229 }
Steve Frenchfd88ce92011-04-12 01:01:14 +00002230 tcp_ses->tcpStatus = CifsNeedNegotiate;
Jeff Layton63c038c2008-12-01 18:41:46 -05002231
2232 /* thread spawned, put it on the list */
Suresh Jayaraman3f9bcca2010-10-18 23:29:37 +05302233 spin_lock(&cifs_tcp_ses_lock);
Jeff Layton63c038c2008-12-01 18:41:46 -05002234 list_add(&tcp_ses->tcp_ses_list, &cifs_tcp_ses_list);
Suresh Jayaraman3f9bcca2010-10-18 23:29:37 +05302235 spin_unlock(&cifs_tcp_ses_lock);
Jeff Layton63c038c2008-12-01 18:41:46 -05002236
Suresh Jayaraman488f1d2d2010-07-05 18:12:15 +05302237 cifs_fscache_get_client_cookie(tcp_ses);
2238
Jeff Laytonc74093b2011-01-11 07:24:23 -05002239 /* queue echo request delayed work */
Jeff Laytonda472fc2012-03-23 14:40:53 -04002240 queue_delayed_work(cifsiod_wq, &tcp_ses->echo, SMB_ECHO_INTERVAL);
Jeff Laytonc74093b2011-01-11 07:24:23 -05002241
Jeff Layton63c038c2008-12-01 18:41:46 -05002242 return tcp_ses;
2243
Shirish Pargaonkarf7c54452010-10-26 18:10:24 -05002244out_err_crypto_release:
Shirish Pargaonkard2b91522010-10-21 14:25:08 -05002245 cifs_crypto_shash_release(tcp_ses);
2246
Rob Landleyf1d0c992011-01-22 15:44:05 -06002247 put_net(cifs_net_ns(tcp_ses));
2248
Jeff Layton63c038c2008-12-01 18:41:46 -05002249out_err:
2250 if (tcp_ses) {
Steve French8347a5c2009-10-06 18:31:29 +00002251 if (!IS_ERR(tcp_ses->hostname))
2252 kfree(tcp_ses->hostname);
Jeff Layton63c038c2008-12-01 18:41:46 -05002253 if (tcp_ses->ssocket)
2254 sock_release(tcp_ses->ssocket);
2255 kfree(tcp_ses);
2256 }
2257 return ERR_PTR(rc);
2258}
2259
Steve French96daf2b2011-05-27 04:34:02 +00002260static int match_session(struct cifs_ses *ses, struct smb_vol *vol)
Pavel Shilovsky37bb04e2011-05-05 09:55:11 +00002261{
Jeff Layton3f618222013-06-12 19:52:14 -05002262 if (vol->sectype != Unspecified &&
2263 vol->sectype != ses->sectype)
2264 return 0;
2265
2266 switch (ses->sectype) {
Pavel Shilovsky37bb04e2011-05-05 09:55:11 +00002267 case Kerberos:
Eric W. Biederman64ed39d2013-02-06 02:30:39 -08002268 if (!uid_eq(vol->cred_uid, ses->cred_uid))
Pavel Shilovsky37bb04e2011-05-05 09:55:11 +00002269 return 0;
2270 break;
2271 default:
Jeff Layton04febab2012-01-17 16:09:15 -05002272 /* NULL username means anonymous session */
2273 if (ses->user_name == NULL) {
2274 if (!vol->nullauth)
2275 return 0;
2276 break;
2277 }
2278
Pavel Shilovsky37bb04e2011-05-05 09:55:11 +00002279 /* anything else takes username/password */
Jeff Layton04febab2012-01-17 16:09:15 -05002280 if (strncmp(ses->user_name,
2281 vol->username ? vol->username : "",
Scott Lovenberg8c3a2b42013-08-09 08:47:17 -04002282 CIFS_MAX_USERNAME_LEN))
Pavel Shilovsky37bb04e2011-05-05 09:55:11 +00002283 return 0;
Jeff Layton08b37d52014-05-23 06:53:10 -04002284 if ((vol->username && strlen(vol->username) != 0) &&
Pavel Shilovsky37bb04e2011-05-05 09:55:11 +00002285 ses->password != NULL &&
2286 strncmp(ses->password,
2287 vol->password ? vol->password : "",
Scott Lovenberg8c3a2b42013-08-09 08:47:17 -04002288 CIFS_MAX_PASSWORD_LEN))
Pavel Shilovsky37bb04e2011-05-05 09:55:11 +00002289 return 0;
2290 }
2291 return 1;
2292}
2293
Steve French96daf2b2011-05-27 04:34:02 +00002294static struct cifs_ses *
Jeff Layton4ff67b72010-07-06 20:43:02 -04002295cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb_vol *vol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002296{
Steve French96daf2b2011-05-27 04:34:02 +00002297 struct cifs_ses *ses;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002298
Suresh Jayaraman3f9bcca2010-10-18 23:29:37 +05302299 spin_lock(&cifs_tcp_ses_lock);
Jeff Layton4ff67b72010-07-06 20:43:02 -04002300 list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
Shirish Pargaonkar7f485582013-10-12 10:06:03 -05002301 if (ses->status == CifsExiting)
2302 continue;
Pavel Shilovsky37bb04e2011-05-05 09:55:11 +00002303 if (!match_session(ses, vol))
2304 continue;
Jeff Layton14fbf502008-11-14 13:53:46 -05002305 ++ses->ses_count;
Suresh Jayaraman3f9bcca2010-10-18 23:29:37 +05302306 spin_unlock(&cifs_tcp_ses_lock);
Jeff Layton14fbf502008-11-14 13:53:46 -05002307 return ses;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002308 }
Suresh Jayaraman3f9bcca2010-10-18 23:29:37 +05302309 spin_unlock(&cifs_tcp_ses_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002310 return NULL;
2311}
2312
Jeff Layton14fbf502008-11-14 13:53:46 -05002313static void
Steve French96daf2b2011-05-27 04:34:02 +00002314cifs_put_smb_ses(struct cifs_ses *ses)
Jeff Layton14fbf502008-11-14 13:53:46 -05002315{
Shirish Pargaonkar7f485582013-10-12 10:06:03 -05002316 unsigned int rc, xid;
Jeff Layton14fbf502008-11-14 13:53:46 -05002317 struct TCP_Server_Info *server = ses->server;
2318
Joe Perchesf96637b2013-05-04 22:12:25 -05002319 cifs_dbg(FYI, "%s: ses_count=%d\n", __func__, ses->ses_count);
Shirish Pargaonkar7f485582013-10-12 10:06:03 -05002320
Suresh Jayaraman3f9bcca2010-10-18 23:29:37 +05302321 spin_lock(&cifs_tcp_ses_lock);
Shirish Pargaonkar7f485582013-10-12 10:06:03 -05002322 if (ses->status == CifsExiting) {
2323 spin_unlock(&cifs_tcp_ses_lock);
2324 return;
2325 }
Jeff Layton14fbf502008-11-14 13:53:46 -05002326 if (--ses->ses_count > 0) {
Suresh Jayaraman3f9bcca2010-10-18 23:29:37 +05302327 spin_unlock(&cifs_tcp_ses_lock);
Jeff Layton14fbf502008-11-14 13:53:46 -05002328 return;
2329 }
Shirish Pargaonkar7f485582013-10-12 10:06:03 -05002330 if (ses->status == CifsGood)
2331 ses->status = CifsExiting;
2332 spin_unlock(&cifs_tcp_ses_lock);
Jeff Layton14fbf502008-11-14 13:53:46 -05002333
Shirish Pargaonkar7f485582013-10-12 10:06:03 -05002334 if (ses->status == CifsExiting && server->ops->logoff) {
2335 xid = get_xid();
2336 rc = server->ops->logoff(xid, ses);
2337 if (rc)
2338 cifs_dbg(VFS, "%s: Session Logoff failure rc=%d\n",
2339 __func__, rc);
2340 _free_xid(xid);
2341 }
2342
2343 spin_lock(&cifs_tcp_ses_lock);
Jeff Layton14fbf502008-11-14 13:53:46 -05002344 list_del_init(&ses->smb_ses_list);
Suresh Jayaraman3f9bcca2010-10-18 23:29:37 +05302345 spin_unlock(&cifs_tcp_ses_lock);
Jeff Layton14fbf502008-11-14 13:53:46 -05002346
Jeff Layton14fbf502008-11-14 13:53:46 -05002347 sesInfoFree(ses);
2348 cifs_put_tcp_session(server);
2349}
2350
Jeff Layton8a8798a2012-01-17 16:09:15 -05002351#ifdef CONFIG_KEYS
2352
Chen Gang057d6332013-07-19 09:01:36 +08002353/* strlen("cifs:a:") + CIFS_MAX_DOMAINNAME_LEN + 1 */
2354#define CIFSCREDS_DESC_SIZE (7 + CIFS_MAX_DOMAINNAME_LEN + 1)
Jeff Layton8a8798a2012-01-17 16:09:15 -05002355
2356/* Populate username and pw fields from keyring if possible */
2357static int
2358cifs_set_cifscreds(struct smb_vol *vol, struct cifs_ses *ses)
2359{
2360 int rc = 0;
David Howells146aa8b2015-10-21 14:04:48 +01002361 const char *delim, *payload;
2362 char *desc;
Jeff Layton8a8798a2012-01-17 16:09:15 -05002363 ssize_t len;
2364 struct key *key;
2365 struct TCP_Server_Info *server = ses->server;
2366 struct sockaddr_in *sa;
2367 struct sockaddr_in6 *sa6;
David Howells146aa8b2015-10-21 14:04:48 +01002368 const struct user_key_payload *upayload;
Jeff Layton8a8798a2012-01-17 16:09:15 -05002369
2370 desc = kmalloc(CIFSCREDS_DESC_SIZE, GFP_KERNEL);
2371 if (!desc)
2372 return -ENOMEM;
2373
2374 /* try to find an address key first */
2375 switch (server->dstaddr.ss_family) {
2376 case AF_INET:
2377 sa = (struct sockaddr_in *)&server->dstaddr;
2378 sprintf(desc, "cifs:a:%pI4", &sa->sin_addr.s_addr);
2379 break;
2380 case AF_INET6:
2381 sa6 = (struct sockaddr_in6 *)&server->dstaddr;
2382 sprintf(desc, "cifs:a:%pI6c", &sa6->sin6_addr.s6_addr);
2383 break;
2384 default:
Joe Perchesf96637b2013-05-04 22:12:25 -05002385 cifs_dbg(FYI, "Bad ss_family (%hu)\n",
2386 server->dstaddr.ss_family);
Jeff Layton8a8798a2012-01-17 16:09:15 -05002387 rc = -EINVAL;
2388 goto out_err;
2389 }
2390
Joe Perchesf96637b2013-05-04 22:12:25 -05002391 cifs_dbg(FYI, "%s: desc=%s\n", __func__, desc);
Jeff Layton8a8798a2012-01-17 16:09:15 -05002392 key = request_key(&key_type_logon, desc, "");
2393 if (IS_ERR(key)) {
2394 if (!ses->domainName) {
Joe Perchesf96637b2013-05-04 22:12:25 -05002395 cifs_dbg(FYI, "domainName is NULL\n");
Jeff Layton8a8798a2012-01-17 16:09:15 -05002396 rc = PTR_ERR(key);
2397 goto out_err;
2398 }
2399
2400 /* didn't work, try to find a domain key */
2401 sprintf(desc, "cifs:d:%s", ses->domainName);
Joe Perchesf96637b2013-05-04 22:12:25 -05002402 cifs_dbg(FYI, "%s: desc=%s\n", __func__, desc);
Jeff Layton8a8798a2012-01-17 16:09:15 -05002403 key = request_key(&key_type_logon, desc, "");
2404 if (IS_ERR(key)) {
2405 rc = PTR_ERR(key);
2406 goto out_err;
2407 }
2408 }
2409
2410 down_read(&key->sem);
David Howells146aa8b2015-10-21 14:04:48 +01002411 upayload = user_key_payload(key);
Jeff Layton8a8798a2012-01-17 16:09:15 -05002412 if (IS_ERR_OR_NULL(upayload)) {
Jeff Layton4edc53c2012-02-07 06:30:51 -05002413 rc = upayload ? PTR_ERR(upayload) : -EINVAL;
Jeff Layton8a8798a2012-01-17 16:09:15 -05002414 goto out_key_put;
2415 }
2416
2417 /* find first : in payload */
David Howells146aa8b2015-10-21 14:04:48 +01002418 payload = upayload->data;
Jeff Layton8a8798a2012-01-17 16:09:15 -05002419 delim = strnchr(payload, upayload->datalen, ':');
Joe Perchesf96637b2013-05-04 22:12:25 -05002420 cifs_dbg(FYI, "payload=%s\n", payload);
Jeff Layton8a8798a2012-01-17 16:09:15 -05002421 if (!delim) {
Joe Perchesf96637b2013-05-04 22:12:25 -05002422 cifs_dbg(FYI, "Unable to find ':' in payload (datalen=%d)\n",
2423 upayload->datalen);
Jeff Layton8a8798a2012-01-17 16:09:15 -05002424 rc = -EINVAL;
2425 goto out_key_put;
2426 }
2427
2428 len = delim - payload;
Scott Lovenberg8c3a2b42013-08-09 08:47:17 -04002429 if (len > CIFS_MAX_USERNAME_LEN || len <= 0) {
Joe Perchesf96637b2013-05-04 22:12:25 -05002430 cifs_dbg(FYI, "Bad value from username search (len=%zd)\n",
2431 len);
Jeff Layton8a8798a2012-01-17 16:09:15 -05002432 rc = -EINVAL;
2433 goto out_key_put;
2434 }
2435
2436 vol->username = kstrndup(payload, len, GFP_KERNEL);
2437 if (!vol->username) {
Joe Perchesf96637b2013-05-04 22:12:25 -05002438 cifs_dbg(FYI, "Unable to allocate %zd bytes for username\n",
2439 len);
Jeff Layton8a8798a2012-01-17 16:09:15 -05002440 rc = -ENOMEM;
2441 goto out_key_put;
2442 }
Joe Perchesf96637b2013-05-04 22:12:25 -05002443 cifs_dbg(FYI, "%s: username=%s\n", __func__, vol->username);
Jeff Layton8a8798a2012-01-17 16:09:15 -05002444
2445 len = key->datalen - (len + 1);
Scott Lovenberg8c3a2b42013-08-09 08:47:17 -04002446 if (len > CIFS_MAX_PASSWORD_LEN || len <= 0) {
Joe Perchesf96637b2013-05-04 22:12:25 -05002447 cifs_dbg(FYI, "Bad len for password search (len=%zd)\n", len);
Jeff Layton8a8798a2012-01-17 16:09:15 -05002448 rc = -EINVAL;
2449 kfree(vol->username);
2450 vol->username = NULL;
2451 goto out_key_put;
2452 }
2453
2454 ++delim;
2455 vol->password = kstrndup(delim, len, GFP_KERNEL);
2456 if (!vol->password) {
Joe Perchesf96637b2013-05-04 22:12:25 -05002457 cifs_dbg(FYI, "Unable to allocate %zd bytes for password\n",
2458 len);
Jeff Layton8a8798a2012-01-17 16:09:15 -05002459 rc = -ENOMEM;
2460 kfree(vol->username);
2461 vol->username = NULL;
2462 goto out_key_put;
2463 }
2464
2465out_key_put:
2466 up_read(&key->sem);
2467 key_put(key);
2468out_err:
2469 kfree(desc);
Joe Perchesf96637b2013-05-04 22:12:25 -05002470 cifs_dbg(FYI, "%s: returning %d\n", __func__, rc);
Jeff Layton8a8798a2012-01-17 16:09:15 -05002471 return rc;
2472}
2473#else /* ! CONFIG_KEYS */
2474static inline int
2475cifs_set_cifscreds(struct smb_vol *vol __attribute__((unused)),
2476 struct cifs_ses *ses __attribute__((unused)))
2477{
2478 return -ENOSYS;
2479}
2480#endif /* CONFIG_KEYS */
2481
Steve French96daf2b2011-05-27 04:34:02 +00002482static struct cifs_ses *
Jeff Layton36988c72010-04-24 07:57:43 -04002483cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
2484{
Pavel Shilovsky286170a2012-05-25 10:43:58 +04002485 int rc = -ENOMEM;
2486 unsigned int xid;
Steve French96daf2b2011-05-27 04:34:02 +00002487 struct cifs_ses *ses;
Pavel Shilovskya9f1b852010-12-13 19:08:35 +03002488 struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr;
2489 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&server->dstaddr;
Jeff Layton36988c72010-04-24 07:57:43 -04002490
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +04002491 xid = get_xid();
Jeff Layton36988c72010-04-24 07:57:43 -04002492
Jeff Layton4ff67b72010-07-06 20:43:02 -04002493 ses = cifs_find_smb_ses(server, volume_info);
Jeff Layton36988c72010-04-24 07:57:43 -04002494 if (ses) {
Joe Perchesf96637b2013-05-04 22:12:25 -05002495 cifs_dbg(FYI, "Existing smb sess found (status=%d)\n",
2496 ses->status);
Jeff Layton36988c72010-04-24 07:57:43 -04002497
Jeff Layton36988c72010-04-24 07:57:43 -04002498 mutex_lock(&ses->session_mutex);
Jeff Layton198b5682010-04-24 07:57:48 -04002499 rc = cifs_negotiate_protocol(xid, ses);
2500 if (rc) {
2501 mutex_unlock(&ses->session_mutex);
2502 /* problem -- put our ses reference */
2503 cifs_put_smb_ses(ses);
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +04002504 free_xid(xid);
Jeff Layton198b5682010-04-24 07:57:48 -04002505 return ERR_PTR(rc);
2506 }
Jeff Layton36988c72010-04-24 07:57:43 -04002507 if (ses->need_reconnect) {
Joe Perchesf96637b2013-05-04 22:12:25 -05002508 cifs_dbg(FYI, "Session needs reconnect\n");
Jeff Layton36988c72010-04-24 07:57:43 -04002509 rc = cifs_setup_session(xid, ses,
2510 volume_info->local_nls);
2511 if (rc) {
2512 mutex_unlock(&ses->session_mutex);
2513 /* problem -- put our reference */
2514 cifs_put_smb_ses(ses);
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +04002515 free_xid(xid);
Jeff Layton36988c72010-04-24 07:57:43 -04002516 return ERR_PTR(rc);
2517 }
2518 }
2519 mutex_unlock(&ses->session_mutex);
Jeff Layton460cf342010-09-14 11:38:24 -04002520
2521 /* existing SMB ses has a server reference already */
2522 cifs_put_tcp_session(server);
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +04002523 free_xid(xid);
Jeff Layton36988c72010-04-24 07:57:43 -04002524 return ses;
2525 }
2526
Joe Perchesf96637b2013-05-04 22:12:25 -05002527 cifs_dbg(FYI, "Existing smb sess not found\n");
Jeff Layton36988c72010-04-24 07:57:43 -04002528 ses = sesInfoAlloc();
2529 if (ses == NULL)
2530 goto get_ses_fail;
2531
2532 /* new SMB session uses our server ref */
2533 ses->server = server;
Pavel Shilovskya9f1b852010-12-13 19:08:35 +03002534 if (server->dstaddr.ss_family == AF_INET6)
2535 sprintf(ses->serverName, "%pI6", &addr6->sin6_addr);
Jeff Layton36988c72010-04-24 07:57:43 -04002536 else
Pavel Shilovskya9f1b852010-12-13 19:08:35 +03002537 sprintf(ses->serverName, "%pI4", &addr->sin_addr);
Jeff Layton36988c72010-04-24 07:57:43 -04002538
Steve French8727c8a2011-02-25 01:11:56 -06002539 if (volume_info->username) {
2540 ses->user_name = kstrdup(volume_info->username, GFP_KERNEL);
2541 if (!ses->user_name)
2542 goto get_ses_fail;
2543 }
Jeff Layton36988c72010-04-24 07:57:43 -04002544
2545 /* volume_info->password freed at unmount */
2546 if (volume_info->password) {
2547 ses->password = kstrdup(volume_info->password, GFP_KERNEL);
2548 if (!ses->password)
2549 goto get_ses_fail;
2550 }
2551 if (volume_info->domainname) {
Shirish Pargaonkard3686d52010-10-28 09:53:07 -05002552 ses->domainName = kstrdup(volume_info->domainname, GFP_KERNEL);
2553 if (!ses->domainName)
2554 goto get_ses_fail;
Jeff Layton36988c72010-04-24 07:57:43 -04002555 }
Jeff Layton3e4b3e12010-07-19 18:00:17 -04002556 ses->cred_uid = volume_info->cred_uid;
Jeff Layton36988c72010-04-24 07:57:43 -04002557 ses->linux_uid = volume_info->linux_uid;
Steve Frenchd9b94202011-04-12 01:24:57 +00002558
Jeff Layton28e11bd2013-05-26 07:01:00 -04002559 ses->sectype = volume_info->sectype;
2560 ses->sign = volume_info->sign;
Jeff Layton36988c72010-04-24 07:57:43 -04002561
2562 mutex_lock(&ses->session_mutex);
Jeff Layton198b5682010-04-24 07:57:48 -04002563 rc = cifs_negotiate_protocol(xid, ses);
2564 if (!rc)
2565 rc = cifs_setup_session(xid, ses, volume_info->local_nls);
Jeff Layton36988c72010-04-24 07:57:43 -04002566 mutex_unlock(&ses->session_mutex);
Steve Frenchc8e56f12010-09-08 21:10:58 +00002567 if (rc)
Jeff Layton36988c72010-04-24 07:57:43 -04002568 goto get_ses_fail;
2569
2570 /* success, put it on the list */
Suresh Jayaraman3f9bcca2010-10-18 23:29:37 +05302571 spin_lock(&cifs_tcp_ses_lock);
Jeff Layton36988c72010-04-24 07:57:43 -04002572 list_add(&ses->smb_ses_list, &server->smb_ses_list);
Suresh Jayaraman3f9bcca2010-10-18 23:29:37 +05302573 spin_unlock(&cifs_tcp_ses_lock);
Jeff Layton36988c72010-04-24 07:57:43 -04002574
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +04002575 free_xid(xid);
Jeff Layton36988c72010-04-24 07:57:43 -04002576 return ses;
2577
2578get_ses_fail:
2579 sesInfoFree(ses);
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +04002580 free_xid(xid);
Jeff Layton36988c72010-04-24 07:57:43 -04002581 return ERR_PTR(rc);
2582}
2583
Steve French96daf2b2011-05-27 04:34:02 +00002584static int match_tcon(struct cifs_tcon *tcon, const char *unc)
Pavel Shilovsky37bb04e2011-05-05 09:55:11 +00002585{
2586 if (tcon->tidStatus == CifsExiting)
2587 return 0;
2588 if (strncmp(tcon->treeName, unc, MAX_TREE_SIZE))
2589 return 0;
2590 return 1;
2591}
2592
Steve French96daf2b2011-05-27 04:34:02 +00002593static struct cifs_tcon *
2594cifs_find_tcon(struct cifs_ses *ses, const char *unc)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002595{
2596 struct list_head *tmp;
Steve French96daf2b2011-05-27 04:34:02 +00002597 struct cifs_tcon *tcon;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002598
Suresh Jayaraman3f9bcca2010-10-18 23:29:37 +05302599 spin_lock(&cifs_tcp_ses_lock);
Jeff Laytonf1987b42008-11-15 11:12:47 -05002600 list_for_each(tmp, &ses->tcon_list) {
Steve French96daf2b2011-05-27 04:34:02 +00002601 tcon = list_entry(tmp, struct cifs_tcon, tcon_list);
Pavel Shilovsky37bb04e2011-05-05 09:55:11 +00002602 if (!match_tcon(tcon, unc))
Jeff Laytonf1987b42008-11-15 11:12:47 -05002603 continue;
Jeff Laytonf1987b42008-11-15 11:12:47 -05002604 ++tcon->tc_count;
Suresh Jayaraman3f9bcca2010-10-18 23:29:37 +05302605 spin_unlock(&cifs_tcp_ses_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002606 return tcon;
2607 }
Suresh Jayaraman3f9bcca2010-10-18 23:29:37 +05302608 spin_unlock(&cifs_tcp_ses_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002609 return NULL;
2610}
2611
Jeff Laytonf1987b42008-11-15 11:12:47 -05002612static void
Steve French96daf2b2011-05-27 04:34:02 +00002613cifs_put_tcon(struct cifs_tcon *tcon)
Jeff Laytonf1987b42008-11-15 11:12:47 -05002614{
Pavel Shilovsky2e6e02a2012-05-25 11:11:39 +04002615 unsigned int xid;
Steve French96daf2b2011-05-27 04:34:02 +00002616 struct cifs_ses *ses = tcon->ses;
Jeff Laytonf1987b42008-11-15 11:12:47 -05002617
Joe Perchesf96637b2013-05-04 22:12:25 -05002618 cifs_dbg(FYI, "%s: tc_count=%d\n", __func__, tcon->tc_count);
Suresh Jayaraman3f9bcca2010-10-18 23:29:37 +05302619 spin_lock(&cifs_tcp_ses_lock);
Jeff Laytonf1987b42008-11-15 11:12:47 -05002620 if (--tcon->tc_count > 0) {
Suresh Jayaraman3f9bcca2010-10-18 23:29:37 +05302621 spin_unlock(&cifs_tcp_ses_lock);
Jeff Laytonf1987b42008-11-15 11:12:47 -05002622 return;
2623 }
2624
2625 list_del_init(&tcon->tcon_list);
Suresh Jayaraman3f9bcca2010-10-18 23:29:37 +05302626 spin_unlock(&cifs_tcp_ses_lock);
Jeff Laytonf1987b42008-11-15 11:12:47 -05002627
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +04002628 xid = get_xid();
Pavel Shilovsky2e6e02a2012-05-25 11:11:39 +04002629 if (ses->server->ops->tree_disconnect)
2630 ses->server->ops->tree_disconnect(xid, tcon);
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +04002631 _free_xid(xid);
Jeff Laytonf1987b42008-11-15 11:12:47 -05002632
Suresh Jayaramand03382c2010-07-05 18:12:27 +05302633 cifs_fscache_release_super_cookie(tcon);
Steve French9f841592010-07-23 20:37:53 +00002634 tconInfoFree(tcon);
Jeff Laytonf1987b42008-11-15 11:12:47 -05002635 cifs_put_smb_ses(ses);
2636}
2637
Steve French96daf2b2011-05-27 04:34:02 +00002638static struct cifs_tcon *
2639cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info)
Jeff Laytond00c28d2010-04-24 07:57:44 -04002640{
2641 int rc, xid;
Steve French96daf2b2011-05-27 04:34:02 +00002642 struct cifs_tcon *tcon;
Jeff Laytond00c28d2010-04-24 07:57:44 -04002643
2644 tcon = cifs_find_tcon(ses, volume_info->UNC);
2645 if (tcon) {
Joe Perchesf96637b2013-05-04 22:12:25 -05002646 cifs_dbg(FYI, "Found match on UNC path\n");
Jeff Laytond00c28d2010-04-24 07:57:44 -04002647 /* existing tcon already has a reference */
2648 cifs_put_smb_ses(ses);
2649 if (tcon->seal != volume_info->seal)
Joe Perchesf96637b2013-05-04 22:12:25 -05002650 cifs_dbg(VFS, "transport encryption setting conflicts with existing tid\n");
Jeff Laytond00c28d2010-04-24 07:57:44 -04002651 return tcon;
2652 }
2653
Pavel Shilovsky2e6e02a2012-05-25 11:11:39 +04002654 if (!ses->server->ops->tree_connect) {
2655 rc = -ENOSYS;
2656 goto out_fail;
2657 }
2658
Jeff Laytond00c28d2010-04-24 07:57:44 -04002659 tcon = tconInfoAlloc();
2660 if (tcon == NULL) {
2661 rc = -ENOMEM;
2662 goto out_fail;
2663 }
2664
2665 tcon->ses = ses;
2666 if (volume_info->password) {
2667 tcon->password = kstrdup(volume_info->password, GFP_KERNEL);
2668 if (!tcon->password) {
2669 rc = -ENOMEM;
2670 goto out_fail;
2671 }
2672 }
2673
Pavel Shilovsky2e6e02a2012-05-25 11:11:39 +04002674 /*
2675 * BB Do we need to wrap session_mutex around this TCon call and Unix
2676 * SetFS as we do on SessSetup and reconnect?
2677 */
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +04002678 xid = get_xid();
Pavel Shilovsky2e6e02a2012-05-25 11:11:39 +04002679 rc = ses->server->ops->tree_connect(xid, ses, volume_info->UNC, tcon,
2680 volume_info->local_nls);
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +04002681 free_xid(xid);
Joe Perchesf96637b2013-05-04 22:12:25 -05002682 cifs_dbg(FYI, "Tcon rc = %d\n", rc);
Jeff Laytond00c28d2010-04-24 07:57:44 -04002683 if (rc)
2684 goto out_fail;
2685
2686 if (volume_info->nodfs) {
2687 tcon->Flags &= ~SMB_SHARE_IS_IN_DFS;
Joe Perchesf96637b2013-05-04 22:12:25 -05002688 cifs_dbg(FYI, "DFS disabled (%d)\n", tcon->Flags);
Jeff Laytond00c28d2010-04-24 07:57:44 -04002689 }
2690 tcon->seal = volume_info->seal;
Steve Frenchb618f002015-11-03 09:15:03 -06002691 tcon->use_persistent = false;
2692 /* check if SMB2 or later, CIFS does not support persistent handles */
2693 if (volume_info->persistent) {
2694 if (ses->server->vals->protocol_id == 0) {
2695 cifs_dbg(VFS,
2696 "SMB3 or later required for persistent handles\n");
2697 rc = -EOPNOTSUPP;
2698 goto out_fail;
Steve French592fafe2015-11-03 10:08:53 -06002699#ifdef CONFIG_CIFS_SMB2
Steve Frenchb618f002015-11-03 09:15:03 -06002700 } else if (ses->server->capabilities &
2701 SMB2_GLOBAL_CAP_PERSISTENT_HANDLES)
2702 tcon->use_persistent = true;
2703 else /* persistent handles requested but not supported */ {
2704 cifs_dbg(VFS,
2705 "Persistent handles not supported on share\n");
2706 rc = -EOPNOTSUPP;
2707 goto out_fail;
Steve French592fafe2015-11-03 10:08:53 -06002708#endif /* CONFIG_CIFS_SMB2 */
Steve Frenchb618f002015-11-03 09:15:03 -06002709 }
Steve French592fafe2015-11-03 10:08:53 -06002710#ifdef CONFIG_CIFS_SMB2
Steve Frenchb618f002015-11-03 09:15:03 -06002711 } else if ((tcon->capabilities & SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY)
2712 && (ses->server->capabilities & SMB2_GLOBAL_CAP_PERSISTENT_HANDLES)
2713 && (volume_info->nopersistent == false)) {
2714 cifs_dbg(FYI, "enabling persistent handles\n");
2715 tcon->use_persistent = true;
Steve French592fafe2015-11-03 10:08:53 -06002716#endif /* CONFIG_CIFS_SMB2 */
2717 } else if (volume_info->resilient) {
2718 if (ses->server->vals->protocol_id == 0) {
2719 cifs_dbg(VFS,
2720 "SMB2.1 or later required for resilient handles\n");
2721 rc = -EOPNOTSUPP;
2722 goto out_fail;
2723 }
2724 tcon->use_resilient = true;
Steve Frenchb618f002015-11-03 09:15:03 -06002725 }
2726
Pavel Shilovsky2e6e02a2012-05-25 11:11:39 +04002727 /*
2728 * We can have only one retry value for a connection to a share so for
2729 * resources mounted more than once to the same server share the last
2730 * value passed in for the retry flag is used.
2731 */
Jeff Laytond00c28d2010-04-24 07:57:44 -04002732 tcon->retry = volume_info->retry;
2733 tcon->nocase = volume_info->nocase;
2734 tcon->local_lease = volume_info->local_lease;
Pavel Shilovsky233839b2012-09-19 06:22:45 -07002735 INIT_LIST_HEAD(&tcon->pending_opens);
Jeff Laytond00c28d2010-04-24 07:57:44 -04002736
Suresh Jayaraman3f9bcca2010-10-18 23:29:37 +05302737 spin_lock(&cifs_tcp_ses_lock);
Jeff Laytond00c28d2010-04-24 07:57:44 -04002738 list_add(&tcon->tcon_list, &ses->tcon_list);
Suresh Jayaraman3f9bcca2010-10-18 23:29:37 +05302739 spin_unlock(&cifs_tcp_ses_lock);
Jeff Laytond00c28d2010-04-24 07:57:44 -04002740
Suresh Jayaramand03382c2010-07-05 18:12:27 +05302741 cifs_fscache_get_super_cookie(tcon);
2742
Jeff Laytond00c28d2010-04-24 07:57:44 -04002743 return tcon;
2744
2745out_fail:
2746 tconInfoFree(tcon);
2747 return ERR_PTR(rc);
2748}
2749
Jeff Layton9d002df2010-10-06 19:51:11 -04002750void
2751cifs_put_tlink(struct tcon_link *tlink)
2752{
2753 if (!tlink || IS_ERR(tlink))
2754 return;
2755
2756 if (!atomic_dec_and_test(&tlink->tl_count) ||
2757 test_bit(TCON_LINK_IN_TREE, &tlink->tl_flags)) {
2758 tlink->tl_time = jiffies;
2759 return;
2760 }
2761
2762 if (!IS_ERR(tlink_tcon(tlink)))
2763 cifs_put_tcon(tlink_tcon(tlink));
2764 kfree(tlink);
2765 return;
2766}
Jeff Laytond00c28d2010-04-24 07:57:44 -04002767
Pavel Shilovsky25c7f412011-05-26 23:35:47 +04002768static inline struct tcon_link *
Pavel Shilovskycd518752011-06-09 12:58:53 +04002769cifs_sb_master_tlink(struct cifs_sb_info *cifs_sb)
2770{
2771 return cifs_sb->master_tlink;
2772}
Pavel Shilovsky25c7f412011-05-26 23:35:47 +04002773
2774static int
2775compare_mount_options(struct super_block *sb, struct cifs_mnt_data *mnt_data)
2776{
2777 struct cifs_sb_info *old = CIFS_SB(sb);
2778 struct cifs_sb_info *new = mnt_data->cifs_sb;
2779
2780 if ((sb->s_flags & CIFS_MS_MASK) != (mnt_data->flags & CIFS_MS_MASK))
2781 return 0;
2782
2783 if ((old->mnt_cifs_flags & CIFS_MOUNT_MASK) !=
2784 (new->mnt_cifs_flags & CIFS_MOUNT_MASK))
2785 return 0;
2786
Pavel Shilovsky25c7f412011-05-26 23:35:47 +04002787 /*
Jeff Layton5eba8ab2011-10-19 15:30:26 -04002788 * We want to share sb only if we don't specify an r/wsize or
2789 * specified r/wsize is greater than or equal to existing one.
Pavel Shilovsky25c7f412011-05-26 23:35:47 +04002790 */
2791 if (new->wsize && new->wsize < old->wsize)
2792 return 0;
2793
Jeff Layton5eba8ab2011-10-19 15:30:26 -04002794 if (new->rsize && new->rsize < old->rsize)
2795 return 0;
2796
Eric W. Biederman1f682332013-02-06 01:20:20 -08002797 if (!uid_eq(old->mnt_uid, new->mnt_uid) || !gid_eq(old->mnt_gid, new->mnt_gid))
Pavel Shilovsky25c7f412011-05-26 23:35:47 +04002798 return 0;
2799
2800 if (old->mnt_file_mode != new->mnt_file_mode ||
2801 old->mnt_dir_mode != new->mnt_dir_mode)
2802 return 0;
2803
2804 if (strcmp(old->local_nls->charset, new->local_nls->charset))
2805 return 0;
2806
2807 if (old->actimeo != new->actimeo)
2808 return 0;
2809
2810 return 1;
2811}
2812
2813int
2814cifs_match_super(struct super_block *sb, void *data)
2815{
2816 struct cifs_mnt_data *mnt_data = (struct cifs_mnt_data *)data;
2817 struct smb_vol *volume_info;
2818 struct cifs_sb_info *cifs_sb;
2819 struct TCP_Server_Info *tcp_srv;
Steve French96daf2b2011-05-27 04:34:02 +00002820 struct cifs_ses *ses;
2821 struct cifs_tcon *tcon;
Pavel Shilovsky25c7f412011-05-26 23:35:47 +04002822 struct tcon_link *tlink;
Pavel Shilovsky25c7f412011-05-26 23:35:47 +04002823 int rc = 0;
2824
Pavel Shilovsky25c7f412011-05-26 23:35:47 +04002825 spin_lock(&cifs_tcp_ses_lock);
2826 cifs_sb = CIFS_SB(sb);
2827 tlink = cifs_get_tlink(cifs_sb_master_tlink(cifs_sb));
2828 if (IS_ERR(tlink)) {
2829 spin_unlock(&cifs_tcp_ses_lock);
2830 return rc;
2831 }
2832 tcon = tlink_tcon(tlink);
2833 ses = tcon->ses;
2834 tcp_srv = ses->server;
2835
2836 volume_info = mnt_data->vol;
2837
Jeff Layton9fa114f2012-11-26 11:09:57 -05002838 if (!match_server(tcp_srv, volume_info) ||
Pavel Shilovsky25c7f412011-05-26 23:35:47 +04002839 !match_session(ses, volume_info) ||
2840 !match_tcon(tcon, volume_info->UNC)) {
2841 rc = 0;
2842 goto out;
2843 }
2844
2845 rc = compare_mount_options(sb, mnt_data);
2846out:
Pavel Shilovsky25c7f412011-05-26 23:35:47 +04002847 spin_unlock(&cifs_tcp_ses_lock);
Jeff Laytonf484b5d02011-07-11 10:16:34 -04002848 cifs_put_tlink(tlink);
Pavel Shilovsky25c7f412011-05-26 23:35:47 +04002849 return rc;
2850}
2851
Linus Torvalds1da177e2005-04-16 15:20:36 -07002852int
Pavel Shilovskyb669f332012-05-27 20:21:53 +04002853get_dfs_path(const unsigned int xid, struct cifs_ses *ses, const char *old_path,
Pavel Shilovsky2e6e02a2012-05-25 11:11:39 +04002854 const struct nls_table *nls_codepage, unsigned int *num_referrals,
2855 struct dfs_info3_param **referrals, int remap)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002856{
2857 char *temp_unc;
2858 int rc = 0;
2859
Pavel Shilovskyb669f332012-05-27 20:21:53 +04002860 if (!ses->server->ops->tree_connect || !ses->server->ops->get_dfs_refer)
Pavel Shilovsky2e6e02a2012-05-25 11:11:39 +04002861 return -ENOSYS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002862
Pavel Shilovsky2e6e02a2012-05-25 11:11:39 +04002863 *num_referrals = 0;
2864 *referrals = NULL;
2865
2866 if (ses->ipc_tid == 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002867 temp_unc = kmalloc(2 /* for slashes */ +
Pavel Shilovsky2e6e02a2012-05-25 11:11:39 +04002868 strnlen(ses->serverName, SERVER_NAME_LEN_WITH_NULL * 2)
2869 + 1 + 4 /* slash IPC$ */ + 2, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002870 if (temp_unc == NULL)
2871 return -ENOMEM;
2872 temp_unc[0] = '\\';
2873 temp_unc[1] = '\\';
Pavel Shilovsky2e6e02a2012-05-25 11:11:39 +04002874 strcpy(temp_unc + 2, ses->serverName);
2875 strcpy(temp_unc + 2 + strlen(ses->serverName), "\\IPC$");
2876 rc = ses->server->ops->tree_connect(xid, ses, temp_unc, NULL,
2877 nls_codepage);
Joe Perchesf96637b2013-05-04 22:12:25 -05002878 cifs_dbg(FYI, "Tcon rc = %d ipc_tid = %d\n", rc, ses->ipc_tid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002879 kfree(temp_unc);
2880 }
2881 if (rc == 0)
Pavel Shilovskyb669f332012-05-27 20:21:53 +04002882 rc = ses->server->ops->get_dfs_refer(xid, ses, old_path,
2883 referrals, num_referrals,
2884 nls_codepage, remap);
Pavel Shilovsky2e6e02a2012-05-25 11:11:39 +04002885 /*
2886 * BB - map targetUNCs to dfs_info3 structures, here or in
Pavel Shilovskyb669f332012-05-27 20:21:53 +04002887 * ses->server->ops->get_dfs_refer.
Pavel Shilovsky2e6e02a2012-05-25 11:11:39 +04002888 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002889
2890 return rc;
2891}
2892
Jeff Layton09e50d52008-07-23 10:11:19 -04002893#ifdef CONFIG_DEBUG_LOCK_ALLOC
2894static struct lock_class_key cifs_key[2];
2895static struct lock_class_key cifs_slock_key[2];
2896
2897static inline void
2898cifs_reclassify_socket4(struct socket *sock)
2899{
2900 struct sock *sk = sock->sk;
2901 BUG_ON(sock_owned_by_user(sk));
2902 sock_lock_init_class_and_name(sk, "slock-AF_INET-CIFS",
2903 &cifs_slock_key[0], "sk_lock-AF_INET-CIFS", &cifs_key[0]);
2904}
2905
2906static inline void
2907cifs_reclassify_socket6(struct socket *sock)
2908{
2909 struct sock *sk = sock->sk;
2910 BUG_ON(sock_owned_by_user(sk));
2911 sock_lock_init_class_and_name(sk, "slock-AF_INET6-CIFS",
2912 &cifs_slock_key[1], "sk_lock-AF_INET6-CIFS", &cifs_key[1]);
2913}
2914#else
2915static inline void
2916cifs_reclassify_socket4(struct socket *sock)
2917{
2918}
2919
2920static inline void
2921cifs_reclassify_socket6(struct socket *sock)
2922{
2923}
2924#endif
2925
Linus Torvalds1da177e2005-04-16 15:20:36 -07002926/* See RFC1001 section 14 on representation of Netbios names */
Steve French50c2f752007-07-13 00:33:32 +00002927static void rfc1002mangle(char *target, char *source, unsigned int length)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002928{
Steve French50c2f752007-07-13 00:33:32 +00002929 unsigned int i, j;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002930
Steve French50c2f752007-07-13 00:33:32 +00002931 for (i = 0, j = 0; i < (length); i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002932 /* mask a nibble at a time and encode */
2933 target[j] = 'A' + (0x0F & (source[i] >> 4));
2934 target[j+1] = 'A' + (0x0F & source[i]);
Steve French50c2f752007-07-13 00:33:32 +00002935 j += 2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002936 }
2937
2938}
2939
Ben Greear3eb9a882010-09-01 17:06:02 -07002940static int
2941bind_socket(struct TCP_Server_Info *server)
2942{
2943 int rc = 0;
2944 if (server->srcaddr.ss_family != AF_UNSPEC) {
2945 /* Bind to the specified local IP address */
2946 struct socket *socket = server->ssocket;
2947 rc = socket->ops->bind(socket,
2948 (struct sockaddr *) &server->srcaddr,
2949 sizeof(server->srcaddr));
2950 if (rc < 0) {
2951 struct sockaddr_in *saddr4;
2952 struct sockaddr_in6 *saddr6;
2953 saddr4 = (struct sockaddr_in *)&server->srcaddr;
2954 saddr6 = (struct sockaddr_in6 *)&server->srcaddr;
2955 if (saddr6->sin6_family == AF_INET6)
Joe Perchesf96637b2013-05-04 22:12:25 -05002956 cifs_dbg(VFS, "Failed to bind to: %pI6c, error: %d\n",
2957 &saddr6->sin6_addr, rc);
Ben Greear3eb9a882010-09-01 17:06:02 -07002958 else
Joe Perchesf96637b2013-05-04 22:12:25 -05002959 cifs_dbg(VFS, "Failed to bind to: %pI4, error: %d\n",
2960 &saddr4->sin_addr.s_addr, rc);
Ben Greear3eb9a882010-09-01 17:06:02 -07002961 }
2962 }
2963 return rc;
2964}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002965
2966static int
Pavel Shilovskya9f1b852010-12-13 19:08:35 +03002967ip_rfc1001_connect(struct TCP_Server_Info *server)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002968{
2969 int rc = 0;
Pavel Shilovskya9f1b852010-12-13 19:08:35 +03002970 /*
2971 * some servers require RFC1001 sessinit before sending
2972 * negprot - BB check reconnection in case where second
2973 * sessinit is sent but no second negprot
2974 */
2975 struct rfc1002_session_packet *ses_init_buf;
2976 struct smb_hdr *smb_buf;
2977 ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet),
2978 GFP_KERNEL);
2979 if (ses_init_buf) {
2980 ses_init_buf->trailer.session_req.called_len = 32;
2981
2982 if (server->server_RFC1001_name &&
2983 server->server_RFC1001_name[0] != 0)
2984 rfc1002mangle(ses_init_buf->trailer.
2985 session_req.called_name,
2986 server->server_RFC1001_name,
2987 RFC1001_NAME_LEN_WITH_NULL);
2988 else
2989 rfc1002mangle(ses_init_buf->trailer.
2990 session_req.called_name,
2991 DEFAULT_CIFS_CALLED_NAME,
2992 RFC1001_NAME_LEN_WITH_NULL);
2993
2994 ses_init_buf->trailer.session_req.calling_len = 32;
2995
2996 /*
2997 * calling name ends in null (byte 16) from old smb
2998 * convention.
2999 */
Steve Frenchc85c35f2015-03-27 01:15:02 -05003000 if (server->workstation_RFC1001_name[0] != 0)
Pavel Shilovskya9f1b852010-12-13 19:08:35 +03003001 rfc1002mangle(ses_init_buf->trailer.
3002 session_req.calling_name,
3003 server->workstation_RFC1001_name,
3004 RFC1001_NAME_LEN_WITH_NULL);
3005 else
3006 rfc1002mangle(ses_init_buf->trailer.
3007 session_req.calling_name,
3008 "LINUX_CIFS_CLNT",
3009 RFC1001_NAME_LEN_WITH_NULL);
3010
3011 ses_init_buf->trailer.session_req.scope1 = 0;
3012 ses_init_buf->trailer.session_req.scope2 = 0;
3013 smb_buf = (struct smb_hdr *)ses_init_buf;
3014
3015 /* sizeof RFC1002_SESSION_REQUEST with no scope */
Steve Frenchbe8e3b02011-04-29 05:40:20 +00003016 smb_buf->smb_buf_length = cpu_to_be32(0x81000044);
Pavel Shilovskya9f1b852010-12-13 19:08:35 +03003017 rc = smb_send(server, smb_buf, 0x44);
3018 kfree(ses_init_buf);
3019 /*
3020 * RFC1001 layer in at least one server
3021 * requires very short break before negprot
3022 * presumably because not expecting negprot
3023 * to follow so fast. This is a simple
3024 * solution that works without
3025 * complicating the code and causes no
3026 * significant slowing down on mount
3027 * for everyone else
3028 */
3029 usleep_range(1000, 2000);
3030 }
3031 /*
3032 * else the negprot may still work without this
3033 * even though malloc failed
3034 */
3035
3036 return rc;
3037}
3038
3039static int
3040generic_ip_connect(struct TCP_Server_Info *server)
3041{
3042 int rc = 0;
Steve French6da97912011-03-13 18:55:55 +00003043 __be16 sport;
Pavel Shilovskya9f1b852010-12-13 19:08:35 +03003044 int slen, sfamily;
Jeff Laytonbcf4b102008-12-01 18:42:15 -05003045 struct socket *socket = server->ssocket;
Pavel Shilovskya9f1b852010-12-13 19:08:35 +03003046 struct sockaddr *saddr;
3047
3048 saddr = (struct sockaddr *) &server->dstaddr;
3049
3050 if (server->dstaddr.ss_family == AF_INET6) {
3051 sport = ((struct sockaddr_in6 *) saddr)->sin6_port;
3052 slen = sizeof(struct sockaddr_in6);
3053 sfamily = AF_INET6;
3054 } else {
3055 sport = ((struct sockaddr_in *) saddr)->sin_port;
3056 slen = sizeof(struct sockaddr_in);
3057 sfamily = AF_INET;
3058 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003059
Jeff Laytonbcf4b102008-12-01 18:42:15 -05003060 if (socket == NULL) {
Rob Landleyf1d0c992011-01-22 15:44:05 -06003061 rc = __sock_create(cifs_net_ns(server), sfamily, SOCK_STREAM,
3062 IPPROTO_TCP, &socket, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003063 if (rc < 0) {
Joe Perchesf96637b2013-05-04 22:12:25 -05003064 cifs_dbg(VFS, "Error %d creating socket\n", rc);
Pavel Shilovskya9f1b852010-12-13 19:08:35 +03003065 server->ssocket = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003066 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003067 }
Jeff Laytonbcf4b102008-12-01 18:42:15 -05003068
3069 /* BB other socket options to set KEEPALIVE, NODELAY? */
Joe Perchesf96637b2013-05-04 22:12:25 -05003070 cifs_dbg(FYI, "Socket created\n");
Jeff Laytonbcf4b102008-12-01 18:42:15 -05003071 server->ssocket = socket;
3072 socket->sk->sk_allocation = GFP_NOFS;
Pavel Shilovskya9f1b852010-12-13 19:08:35 +03003073 if (sfamily == AF_INET6)
3074 cifs_reclassify_socket6(socket);
3075 else
3076 cifs_reclassify_socket4(socket);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003077 }
3078
Ben Greear3eb9a882010-09-01 17:06:02 -07003079 rc = bind_socket(server);
3080 if (rc < 0)
3081 return rc;
3082
Jeff Laytond5c56052008-12-01 18:42:33 -05003083 /*
3084 * Eventually check for other socket options to change from
3085 * the default. sock_setsockopt not used because it expects
3086 * user space buffer
3087 */
3088 socket->sk->sk_rcvtimeo = 7 * HZ;
Steve Frenchda505c32009-01-19 03:49:35 +00003089 socket->sk->sk_sndtimeo = 5 * HZ;
Steve French6a5fa2362010-01-01 01:28:43 +00003090
Pavel Shilovskya9f1b852010-12-13 19:08:35 +03003091 /* make the bufsizes depend on wsize/rsize and max requests */
3092 if (server->noautotune) {
3093 if (socket->sk->sk_sndbuf < (200 * 1024))
3094 socket->sk->sk_sndbuf = 200 * 1024;
3095 if (socket->sk->sk_rcvbuf < (140 * 1024))
3096 socket->sk->sk_rcvbuf = 140 * 1024;
3097 }
3098
Steve French6a5fa2362010-01-01 01:28:43 +00003099 if (server->tcp_nodelay) {
Pavel Shilovskya9f1b852010-12-13 19:08:35 +03003100 int val = 1;
Steve French6a5fa2362010-01-01 01:28:43 +00003101 rc = kernel_setsockopt(socket, SOL_TCP, TCP_NODELAY,
3102 (char *)&val, sizeof(val));
3103 if (rc)
Joe Perchesf96637b2013-05-04 22:12:25 -05003104 cifs_dbg(FYI, "set TCP_NODELAY socket option error %d\n",
3105 rc);
Steve French6a5fa2362010-01-01 01:28:43 +00003106 }
3107
Joe Perchesf96637b2013-05-04 22:12:25 -05003108 cifs_dbg(FYI, "sndbuf %d rcvbuf %d rcvtimeo 0x%lx\n",
Pavel Shilovskya9f1b852010-12-13 19:08:35 +03003109 socket->sk->sk_sndbuf,
3110 socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo);
3111
Jeff Laytonee1b3ea2011-06-21 07:18:26 -04003112 rc = socket->ops->connect(socket, saddr, slen, 0);
3113 if (rc < 0) {
Joe Perchesf96637b2013-05-04 22:12:25 -05003114 cifs_dbg(FYI, "Error %d connecting to server\n", rc);
Jeff Laytonee1b3ea2011-06-21 07:18:26 -04003115 sock_release(socket);
3116 server->ssocket = NULL;
3117 return rc;
3118 }
3119
Pavel Shilovskya9f1b852010-12-13 19:08:35 +03003120 if (sport == htons(RFC1001_PORT))
3121 rc = ip_rfc1001_connect(server);
Steve French50c2f752007-07-13 00:33:32 +00003122
Linus Torvalds1da177e2005-04-16 15:20:36 -07003123 return rc;
3124}
3125
Pavel Shilovskya9f1b852010-12-13 19:08:35 +03003126static int
3127ip_connect(struct TCP_Server_Info *server)
3128{
Steve French6da97912011-03-13 18:55:55 +00003129 __be16 *sport;
Pavel Shilovskya9f1b852010-12-13 19:08:35 +03003130 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&server->dstaddr;
3131 struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr;
3132
3133 if (server->dstaddr.ss_family == AF_INET6)
3134 sport = &addr6->sin6_port;
3135 else
3136 sport = &addr->sin_port;
3137
3138 if (*sport == 0) {
3139 int rc;
3140
3141 /* try with 445 port at first */
3142 *sport = htons(CIFS_PORT);
3143
3144 rc = generic_ip_connect(server);
3145 if (rc >= 0)
3146 return rc;
3147
3148 /* if it failed, try with 139 port */
3149 *sport = htons(RFC1001_PORT);
3150 }
3151
3152 return generic_ip_connect(server);
3153}
3154
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +04003155void reset_cifs_unix_caps(unsigned int xid, struct cifs_tcon *tcon,
Al Viro2c6292a2011-06-17 09:05:48 -04003156 struct cifs_sb_info *cifs_sb, struct smb_vol *vol_info)
Steve French8af18972007-02-14 04:42:51 +00003157{
3158 /* if we are reconnecting then should we check to see if
3159 * any requested capabilities changed locally e.g. via
3160 * remount but we can not do much about it here
3161 * if they have (even if we could detect it by the following)
3162 * Perhaps we could add a backpointer to array of sb from tcon
3163 * or if we change to make all sb to same share the same
3164 * sb as NFS - then we only have one backpointer to sb.
3165 * What if we wanted to mount the server share twice once with
3166 * and once without posixacls or posix paths? */
3167 __u64 saved_cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
Steve French50c2f752007-07-13 00:33:32 +00003168
Steve Frenchc18c8422007-07-18 23:21:09 +00003169 if (vol_info && vol_info->no_linux_ext) {
3170 tcon->fsUnixInfo.Capability = 0;
3171 tcon->unix_ext = 0; /* Unix Extensions disabled */
Joe Perchesf96637b2013-05-04 22:12:25 -05003172 cifs_dbg(FYI, "Linux protocol extensions disabled\n");
Steve Frenchc18c8422007-07-18 23:21:09 +00003173 return;
3174 } else if (vol_info)
3175 tcon->unix_ext = 1; /* Unix Extensions supported */
3176
3177 if (tcon->unix_ext == 0) {
Joe Perchesf96637b2013-05-04 22:12:25 -05003178 cifs_dbg(FYI, "Unix extensions disabled so not set on reconnect\n");
Steve Frenchc18c8422007-07-18 23:21:09 +00003179 return;
3180 }
Steve French50c2f752007-07-13 00:33:32 +00003181
Steve Frenchfb8c4b12007-07-10 01:16:18 +00003182 if (!CIFSSMBQFSUnixInfo(xid, tcon)) {
Steve French8af18972007-02-14 04:42:51 +00003183 __u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
Joe Perchesf96637b2013-05-04 22:12:25 -05003184 cifs_dbg(FYI, "unix caps which server supports %lld\n", cap);
Steve French8af18972007-02-14 04:42:51 +00003185 /* check for reconnect case in which we do not
3186 want to change the mount behavior if we can avoid it */
Steve Frenchfb8c4b12007-07-10 01:16:18 +00003187 if (vol_info == NULL) {
Steve French50c2f752007-07-13 00:33:32 +00003188 /* turn off POSIX ACL and PATHNAMES if not set
Steve French8af18972007-02-14 04:42:51 +00003189 originally at mount time */
3190 if ((saved_cap & CIFS_UNIX_POSIX_ACL_CAP) == 0)
3191 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
Igor Mammedov11b6d642008-02-15 19:06:04 +00003192 if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
3193 if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
Joe Perchesf96637b2013-05-04 22:12:25 -05003194 cifs_dbg(VFS, "POSIXPATH support change\n");
Steve French8af18972007-02-14 04:42:51 +00003195 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
Igor Mammedov11b6d642008-02-15 19:06:04 +00003196 } else if ((cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
Joe Perchesf96637b2013-05-04 22:12:25 -05003197 cifs_dbg(VFS, "possible reconnect error\n");
3198 cifs_dbg(VFS, "server disabled POSIX path support\n");
Igor Mammedov11b6d642008-02-15 19:06:04 +00003199 }
Steve French8af18972007-02-14 04:42:51 +00003200 }
Steve French50c2f752007-07-13 00:33:32 +00003201
Steve French6848b732011-05-26 18:38:54 +00003202 if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)
Joe Perchesf96637b2013-05-04 22:12:25 -05003203 cifs_dbg(VFS, "per-share encryption not supported yet\n");
Steve French6848b732011-05-26 18:38:54 +00003204
Steve French8af18972007-02-14 04:42:51 +00003205 cap &= CIFS_UNIX_CAP_MASK;
Steve French75865f8c2007-06-24 18:30:48 +00003206 if (vol_info && vol_info->no_psx_acl)
Steve French8af18972007-02-14 04:42:51 +00003207 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
Steve French75865f8c2007-06-24 18:30:48 +00003208 else if (CIFS_UNIX_POSIX_ACL_CAP & cap) {
Joe Perchesf96637b2013-05-04 22:12:25 -05003209 cifs_dbg(FYI, "negotiated posix acl support\n");
Al Viro2c6292a2011-06-17 09:05:48 -04003210 if (cifs_sb)
3211 cifs_sb->mnt_cifs_flags |=
3212 CIFS_MOUNT_POSIXACL;
Steve French8af18972007-02-14 04:42:51 +00003213 }
3214
Steve French75865f8c2007-06-24 18:30:48 +00003215 if (vol_info && vol_info->posix_paths == 0)
Steve French8af18972007-02-14 04:42:51 +00003216 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
Steve French75865f8c2007-06-24 18:30:48 +00003217 else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
Joe Perchesf96637b2013-05-04 22:12:25 -05003218 cifs_dbg(FYI, "negotiate posix pathnames\n");
Al Viro2c6292a2011-06-17 09:05:48 -04003219 if (cifs_sb)
3220 cifs_sb->mnt_cifs_flags |=
Steve French8af18972007-02-14 04:42:51 +00003221 CIFS_MOUNT_POSIX_PATHS;
3222 }
Steve French50c2f752007-07-13 00:33:32 +00003223
Joe Perchesf96637b2013-05-04 22:12:25 -05003224 cifs_dbg(FYI, "Negotiate caps 0x%x\n", (int)cap);
Steve French8af18972007-02-14 04:42:51 +00003225#ifdef CONFIG_CIFS_DEBUG2
Steve French75865f8c2007-06-24 18:30:48 +00003226 if (cap & CIFS_UNIX_FCNTL_CAP)
Joe Perchesf96637b2013-05-04 22:12:25 -05003227 cifs_dbg(FYI, "FCNTL cap\n");
Steve French75865f8c2007-06-24 18:30:48 +00003228 if (cap & CIFS_UNIX_EXTATTR_CAP)
Joe Perchesf96637b2013-05-04 22:12:25 -05003229 cifs_dbg(FYI, "EXTATTR cap\n");
Steve French75865f8c2007-06-24 18:30:48 +00003230 if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
Joe Perchesf96637b2013-05-04 22:12:25 -05003231 cifs_dbg(FYI, "POSIX path cap\n");
Steve French75865f8c2007-06-24 18:30:48 +00003232 if (cap & CIFS_UNIX_XATTR_CAP)
Joe Perchesf96637b2013-05-04 22:12:25 -05003233 cifs_dbg(FYI, "XATTR cap\n");
Steve French75865f8c2007-06-24 18:30:48 +00003234 if (cap & CIFS_UNIX_POSIX_ACL_CAP)
Joe Perchesf96637b2013-05-04 22:12:25 -05003235 cifs_dbg(FYI, "POSIX ACL cap\n");
Steve French75865f8c2007-06-24 18:30:48 +00003236 if (cap & CIFS_UNIX_LARGE_READ_CAP)
Joe Perchesf96637b2013-05-04 22:12:25 -05003237 cifs_dbg(FYI, "very large read cap\n");
Steve French75865f8c2007-06-24 18:30:48 +00003238 if (cap & CIFS_UNIX_LARGE_WRITE_CAP)
Joe Perchesf96637b2013-05-04 22:12:25 -05003239 cifs_dbg(FYI, "very large write cap\n");
Steve French6848b732011-05-26 18:38:54 +00003240 if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)
Joe Perchesf96637b2013-05-04 22:12:25 -05003241 cifs_dbg(FYI, "transport encryption cap\n");
Steve French6848b732011-05-26 18:38:54 +00003242 if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)
Joe Perchesf96637b2013-05-04 22:12:25 -05003243 cifs_dbg(FYI, "mandatory transport encryption cap\n");
Steve French8af18972007-02-14 04:42:51 +00003244#endif /* CIFS_DEBUG2 */
3245 if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
Steve French442aa312007-09-24 20:25:46 +00003246 if (vol_info == NULL) {
Joe Perchesf96637b2013-05-04 22:12:25 -05003247 cifs_dbg(FYI, "resetting capabilities failed\n");
Steve French442aa312007-09-24 20:25:46 +00003248 } else
Joe Perchesf96637b2013-05-04 22:12:25 -05003249 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");
Steve French5a44b312007-09-20 15:16:24 +00003250
Steve French8af18972007-02-14 04:42:51 +00003251 }
3252 }
3253}
3254
Pavel Shilovsky724d9f12011-05-05 09:55:12 +00003255void cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
3256 struct cifs_sb_info *cifs_sb)
Jeff Laytonb1c8d2b2008-10-22 13:57:07 -04003257{
Jeff Layton2de970f2010-10-06 19:51:12 -04003258 INIT_DELAYED_WORK(&cifs_sb->prune_tlinks, cifs_prune_tlinks);
3259
Al Viro2ced6f62011-06-17 09:20:04 -04003260 spin_lock_init(&cifs_sb->tlink_tree_lock);
3261 cifs_sb->tlink_tree = RB_ROOT;
3262
Pavel Shilovsky25c7f412011-05-26 23:35:47 +04003263 /*
Jeff Layton5eba8ab2011-10-19 15:30:26 -04003264 * Temporarily set r/wsize for matching superblock. If we end up using
3265 * new sb then client will later negotiate it downward if needed.
Pavel Shilovsky25c7f412011-05-26 23:35:47 +04003266 */
Jeff Layton5eba8ab2011-10-19 15:30:26 -04003267 cifs_sb->rsize = pvolume_info->rsize;
Pavel Shilovsky25c7f412011-05-26 23:35:47 +04003268 cifs_sb->wsize = pvolume_info->wsize;
3269
Steve French3b795212008-11-13 19:45:32 +00003270 cifs_sb->mnt_uid = pvolume_info->linux_uid;
3271 cifs_sb->mnt_gid = pvolume_info->linux_gid;
3272 cifs_sb->mnt_file_mode = pvolume_info->file_mode;
3273 cifs_sb->mnt_dir_mode = pvolume_info->dir_mode;
Joe Perchesf96637b2013-05-04 22:12:25 -05003274 cifs_dbg(FYI, "file mode: 0x%hx dir mode: 0x%hx\n",
3275 cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode);
Steve French3b795212008-11-13 19:45:32 +00003276
Suresh Jayaraman6d20e842010-12-01 14:42:28 +05303277 cifs_sb->actimeo = pvolume_info->actimeo;
Pavel Shilovsky724d9f12011-05-05 09:55:12 +00003278 cifs_sb->local_nls = pvolume_info->local_nls;
Suresh Jayaraman6d20e842010-12-01 14:42:28 +05303279
Steve French3b795212008-11-13 19:45:32 +00003280 if (pvolume_info->noperm)
3281 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
3282 if (pvolume_info->setuids)
3283 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
3284 if (pvolume_info->server_ino)
3285 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM;
3286 if (pvolume_info->remap)
Steve French2baa2682014-09-27 02:19:01 -05003287 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SFM_CHR;
3288 if (pvolume_info->sfu_remap)
Steve French3b795212008-11-13 19:45:32 +00003289 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
3290 if (pvolume_info->no_xattr)
3291 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
3292 if (pvolume_info->sfu_emul)
3293 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL;
3294 if (pvolume_info->nobrl)
3295 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL;
Steve Frenchbe652442009-02-23 15:21:59 +00003296 if (pvolume_info->nostrictsync)
Steve French4717bed2009-02-24 14:44:19 +00003297 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOSSYNC;
Steve French13a6e422008-12-02 17:24:33 +00003298 if (pvolume_info->mand_lock)
3299 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOPOSIXBRL;
Pavel Shilovskyd4ffff12011-05-26 06:02:00 +00003300 if (pvolume_info->rwpidforward)
3301 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_RWPIDFORWARD;
Steve French3b795212008-11-13 19:45:32 +00003302 if (pvolume_info->cifs_acl)
3303 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
Sachin Prabhu3c7c87f2012-04-24 15:28:14 +01003304 if (pvolume_info->backupuid_specified) {
Shirish Pargaonkar3d3ea8e2011-09-26 09:56:44 -05003305 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_BACKUPUID;
Sachin Prabhu3c7c87f2012-04-24 15:28:14 +01003306 cifs_sb->mnt_backupuid = pvolume_info->backupuid;
3307 }
3308 if (pvolume_info->backupgid_specified) {
Shirish Pargaonkar3d3ea8e2011-09-26 09:56:44 -05003309 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_BACKUPGID;
Sachin Prabhu3c7c87f2012-04-24 15:28:14 +01003310 cifs_sb->mnt_backupgid = pvolume_info->backupgid;
3311 }
Steve French3b795212008-11-13 19:45:32 +00003312 if (pvolume_info->override_uid)
3313 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
3314 if (pvolume_info->override_gid)
3315 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID;
3316 if (pvolume_info->dynperm)
3317 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM;
Suresh Jayaramanfa1df752010-07-05 18:13:36 +05303318 if (pvolume_info->fsc)
3319 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_FSCACHE;
Jeff Layton0eb8a132010-10-06 19:51:12 -04003320 if (pvolume_info->multiuser)
3321 cifs_sb->mnt_cifs_flags |= (CIFS_MOUNT_MULTIUSER |
3322 CIFS_MOUNT_NO_PERM);
Pavel Shilovskyd39454f2011-01-24 14:16:35 -05003323 if (pvolume_info->strict_io)
3324 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_STRICT_IO;
Steve French3b795212008-11-13 19:45:32 +00003325 if (pvolume_info->direct_io) {
Joe Perchesf96637b2013-05-04 22:12:25 -05003326 cifs_dbg(FYI, "mounting share using direct i/o\n");
Steve French3b795212008-11-13 19:45:32 +00003327 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
3328 }
Stefan Metzmacher736a3322010-07-30 14:56:00 +02003329 if (pvolume_info->mfsymlinks) {
3330 if (pvolume_info->sfu_emul) {
Steve Frenchdb8b6312014-09-22 05:13:55 -05003331 /*
3332 * Our SFU ("Services for Unix" emulation does not allow
3333 * creating symlinks but does allow reading existing SFU
3334 * symlinks (it does allow both creating and reading SFU
3335 * style mknod and FIFOs though). When "mfsymlinks" and
3336 * "sfu" are both enabled at the same time, it allows
3337 * reading both types of symlinks, but will only create
3338 * them with mfsymlinks format. This allows better
3339 * Apple compatibility (probably better for Samba too)
3340 * while still recognizing old Windows style symlinks.
3341 */
3342 cifs_dbg(VFS, "mount options mfsymlinks and sfu both enabled\n");
Stefan Metzmacher736a3322010-07-30 14:56:00 +02003343 }
Steve Frenchdb8b6312014-09-22 05:13:55 -05003344 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MF_SYMLINKS;
Stefan Metzmacher736a3322010-07-30 14:56:00 +02003345 }
Steve French3b795212008-11-13 19:45:32 +00003346
3347 if ((pvolume_info->cifs_acl) && (pvolume_info->dynperm))
Joe Perchesf96637b2013-05-04 22:12:25 -05003348 cifs_dbg(VFS, "mount option dynperm ignored if cifsacl mount option supported\n");
Jeff Laytonb1c8d2b2008-10-22 13:57:07 -04003349}
3350
Jeff Laytonb9bce2e2011-07-06 08:10:39 -04003351static void
3352cleanup_volume_info_contents(struct smb_vol *volume_info)
Igor Mammedov1bfe73c2009-04-01 17:54:42 +04003353{
Sean Finneyb9468452011-04-11 13:19:32 +00003354 kfree(volume_info->username);
Igor Mammedov1bfe73c2009-04-01 17:54:42 +04003355 kzfree(volume_info->password);
Jesper Juhl95c75452011-08-27 18:58:34 +02003356 kfree(volume_info->UNC);
Sean Finneyb9468452011-04-11 13:19:32 +00003357 kfree(volume_info->domainname);
3358 kfree(volume_info->iocharset);
Igor Mammedov1bfe73c2009-04-01 17:54:42 +04003359 kfree(volume_info->prepath);
Igor Mammedov1bfe73c2009-04-01 17:54:42 +04003360}
3361
Jeff Laytonb9bce2e2011-07-06 08:10:39 -04003362void
3363cifs_cleanup_volume_info(struct smb_vol *volume_info)
3364{
3365 if (!volume_info)
3366 return;
3367 cleanup_volume_info_contents(volume_info);
3368 kfree(volume_info);
3369}
3370
3371
Steve French2d6d5892009-04-09 00:36:44 +00003372#ifdef CONFIG_CIFS_DFS_UPCALL
Steve French6d3ea7e2012-11-28 22:34:41 -06003373/*
3374 * cifs_build_path_to_root returns full path to root when we do not have an
3375 * exiting connection (tcon)
3376 */
Igor Mammedov1bfe73c2009-04-01 17:54:42 +04003377static char *
Jeff Laytonb2a0fa12011-07-06 08:10:36 -04003378build_unc_path_to_root(const struct smb_vol *vol,
Igor Mammedov1bfe73c2009-04-01 17:54:42 +04003379 const struct cifs_sb_info *cifs_sb)
3380{
Jeff Laytonb2a0fa12011-07-06 08:10:36 -04003381 char *full_path, *pos;
Jeff Layton839db3d2012-12-10 06:10:45 -05003382 unsigned int pplen = vol->prepath ? strlen(vol->prepath) + 1 : 0;
Jeff Laytonb2a0fa12011-07-06 08:10:36 -04003383 unsigned int unc_len = strnlen(vol->UNC, MAX_TREE_SIZE + 1);
Igor Mammedov1bfe73c2009-04-01 17:54:42 +04003384
Jeff Laytonb2a0fa12011-07-06 08:10:36 -04003385 full_path = kmalloc(unc_len + pplen + 1, GFP_KERNEL);
Igor Mammedov1bfe73c2009-04-01 17:54:42 +04003386 if (full_path == NULL)
3387 return ERR_PTR(-ENOMEM);
3388
Jeff Laytonb2a0fa12011-07-06 08:10:36 -04003389 strncpy(full_path, vol->UNC, unc_len);
3390 pos = full_path + unc_len;
3391
3392 if (pplen) {
Jeff Layton1fc29ba2013-05-31 10:00:18 -04003393 *pos = CIFS_DIR_SEP(cifs_sb);
3394 strncpy(pos + 1, vol->prepath, pplen);
Jeff Laytonb2a0fa12011-07-06 08:10:36 -04003395 pos += pplen;
3396 }
3397
3398 *pos = '\0'; /* add trailing null */
Steve Frenchf87d39d2011-05-27 03:50:55 +00003399 convert_delimiter(full_path, CIFS_DIR_SEP(cifs_sb));
Joe Perchesf96637b2013-05-04 22:12:25 -05003400 cifs_dbg(FYI, "%s: full_path=%s\n", __func__, full_path);
Igor Mammedov1bfe73c2009-04-01 17:54:42 +04003401 return full_path;
3402}
Sean Finneydd613942011-04-11 13:19:30 +00003403
3404/*
3405 * Perform a dfs referral query for a share and (optionally) prefix
3406 *
Sean Finney046462a2011-04-11 13:19:33 +00003407 * If a referral is found, cifs_sb->mountdata will be (re-)allocated
3408 * to a string containing updated options for the submount. Otherwise it
3409 * will be left untouched.
Sean Finneydd613942011-04-11 13:19:30 +00003410 *
3411 * Returns the rc from get_dfs_path to the caller, which can be used to
3412 * determine whether there were referrals.
3413 */
3414static int
Pavel Shilovskyb669f332012-05-27 20:21:53 +04003415expand_dfs_referral(const unsigned int xid, struct cifs_ses *ses,
Sean Finneydd613942011-04-11 13:19:30 +00003416 struct smb_vol *volume_info, struct cifs_sb_info *cifs_sb,
Sean Finney046462a2011-04-11 13:19:33 +00003417 int check_prefix)
Sean Finneydd613942011-04-11 13:19:30 +00003418{
3419 int rc;
3420 unsigned int num_referrals = 0;
3421 struct dfs_info3_param *referrals = NULL;
3422 char *full_path = NULL, *ref_path = NULL, *mdata = NULL;
3423
3424 full_path = build_unc_path_to_root(volume_info, cifs_sb);
3425 if (IS_ERR(full_path))
3426 return PTR_ERR(full_path);
3427
3428 /* For DFS paths, skip the first '\' of the UNC */
3429 ref_path = check_prefix ? full_path + 1 : volume_info->UNC + 1;
3430
Pavel Shilovskyb669f332012-05-27 20:21:53 +04003431 rc = get_dfs_path(xid, ses, ref_path, cifs_sb->local_nls,
Steve French2baa2682014-09-27 02:19:01 -05003432 &num_referrals, &referrals, cifs_remap(cifs_sb));
Sean Finneydd613942011-04-11 13:19:30 +00003433
3434 if (!rc && num_referrals > 0) {
3435 char *fake_devname = NULL;
3436
3437 mdata = cifs_compose_mount_options(cifs_sb->mountdata,
3438 full_path + 1, referrals,
3439 &fake_devname);
3440
3441 free_dfs_info_array(referrals, num_referrals);
Sean Finney046462a2011-04-11 13:19:33 +00003442
Sean Finneydd613942011-04-11 13:19:30 +00003443 if (IS_ERR(mdata)) {
3444 rc = PTR_ERR(mdata);
3445 mdata = NULL;
Jeff Laytonb9bce2e2011-07-06 08:10:39 -04003446 } else {
3447 cleanup_volume_info_contents(volume_info);
Jeff Laytonb9bce2e2011-07-06 08:10:39 -04003448 rc = cifs_setup_volume_info(volume_info, mdata,
3449 fake_devname);
Sean Finneydd613942011-04-11 13:19:30 +00003450 }
Jeff Laytonb9bce2e2011-07-06 08:10:39 -04003451 kfree(fake_devname);
3452 kfree(cifs_sb->mountdata);
Sean Finney046462a2011-04-11 13:19:33 +00003453 cifs_sb->mountdata = mdata;
Sean Finneydd613942011-04-11 13:19:30 +00003454 }
3455 kfree(full_path);
3456 return rc;
3457}
Steve French2d6d5892009-04-09 00:36:44 +00003458#endif
Igor Mammedov1bfe73c2009-04-01 17:54:42 +04003459
Jeff Layton04db79b2011-07-06 08:10:38 -04003460static int
3461cifs_setup_volume_info(struct smb_vol *volume_info, char *mount_data,
3462 const char *devname)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003463{
Pavel Shilovsky724d9f12011-05-05 09:55:12 +00003464 int rc = 0;
Sean Finneydd613942011-04-11 13:19:30 +00003465
Jeff Layton04db79b2011-07-06 08:10:38 -04003466 if (cifs_parse_mount_options(mount_data, devname, volume_info))
3467 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003468
Jeff Layton7586b762008-12-01 18:41:49 -05003469 if (volume_info->nullauth) {
Joe Perchesf96637b2013-05-04 22:12:25 -05003470 cifs_dbg(FYI, "Anonymous login\n");
Jeff Layton04febab2012-01-17 16:09:15 -05003471 kfree(volume_info->username);
3472 volume_info->username = NULL;
Jeff Layton7586b762008-12-01 18:41:49 -05003473 } else if (volume_info->username) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003474 /* BB fixme parse for domain name here */
Joe Perchesf96637b2013-05-04 22:12:25 -05003475 cifs_dbg(FYI, "Username: %s\n", volume_info->username);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003476 } else {
Joe Perchesf96637b2013-05-04 22:12:25 -05003477 cifs_dbg(VFS, "No username specified\n");
Steve French50c2f752007-07-13 00:33:32 +00003478 /* In userspace mount helper we can get user name from alternate
3479 locations such as env variables and files on disk */
Jeff Layton04db79b2011-07-06 08:10:38 -04003480 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003481 }
3482
Linus Torvalds1da177e2005-04-16 15:20:36 -07003483 /* this is needed for ASCII cp to Unicode converts */
Jeff Layton7586b762008-12-01 18:41:49 -05003484 if (volume_info->iocharset == NULL) {
Jeff Laytona5fc4ce2010-04-24 07:57:42 -04003485 /* load_nls_default cannot return null */
3486 volume_info->local_nls = load_nls_default();
Linus Torvalds1da177e2005-04-16 15:20:36 -07003487 } else {
Jeff Laytona5fc4ce2010-04-24 07:57:42 -04003488 volume_info->local_nls = load_nls(volume_info->iocharset);
3489 if (volume_info->local_nls == NULL) {
Joe Perchesf96637b2013-05-04 22:12:25 -05003490 cifs_dbg(VFS, "CIFS mount error: iocharset %s not found\n",
Joe Perchesb6b38f72010-04-21 03:50:45 +00003491 volume_info->iocharset);
Jeff Layton04db79b2011-07-06 08:10:38 -04003492 return -ELIBACC;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003493 }
3494 }
Pavel Shilovsky724d9f12011-05-05 09:55:12 +00003495
Pavel Shilovsky724d9f12011-05-05 09:55:12 +00003496 return rc;
Jeff Layton04db79b2011-07-06 08:10:38 -04003497}
3498
3499struct smb_vol *
3500cifs_get_volume_info(char *mount_data, const char *devname)
3501{
3502 int rc;
3503 struct smb_vol *volume_info;
3504
Jeff Layton6ee95422012-11-26 11:09:57 -05003505 volume_info = kmalloc(sizeof(struct smb_vol), GFP_KERNEL);
Jeff Layton04db79b2011-07-06 08:10:38 -04003506 if (!volume_info)
3507 return ERR_PTR(-ENOMEM);
3508
3509 rc = cifs_setup_volume_info(volume_info, mount_data, devname);
3510 if (rc) {
3511 cifs_cleanup_volume_info(volume_info);
3512 volume_info = ERR_PTR(rc);
3513 }
3514
3515 return volume_info;
Pavel Shilovsky724d9f12011-05-05 09:55:12 +00003516}
3517
3518int
Al Viro2c6292a2011-06-17 09:05:48 -04003519cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info)
Pavel Shilovsky724d9f12011-05-05 09:55:12 +00003520{
Jeff Layton1daaae82012-03-21 06:30:40 -04003521 int rc;
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +04003522 unsigned int xid;
Pavel Shilovskyaf4281d2012-05-27 20:48:35 +04003523 struct cifs_ses *ses;
Steve French96daf2b2011-05-27 04:34:02 +00003524 struct cifs_tcon *tcon;
Pavel Shilovskyaf4281d2012-05-27 20:48:35 +04003525 struct TCP_Server_Info *server;
Pavel Shilovsky724d9f12011-05-05 09:55:12 +00003526 char *full_path;
3527 struct tcon_link *tlink;
3528#ifdef CONFIG_CIFS_DFS_UPCALL
3529 int referral_walks_count = 0;
Jeff Layton20547492011-07-09 12:21:07 -04003530#endif
Al Virodd854462011-06-17 08:24:42 -04003531
Christoph Hellwigb4caecd2015-01-14 10:42:32 +01003532 rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs");
Al Virodd854462011-06-17 08:24:42 -04003533 if (rc)
3534 return rc;
3535
Jeff Layton20547492011-07-09 12:21:07 -04003536#ifdef CONFIG_CIFS_DFS_UPCALL
Pavel Shilovsky724d9f12011-05-05 09:55:12 +00003537try_mount_again:
3538 /* cleanup activities if we're chasing a referral */
3539 if (referral_walks_count) {
3540 if (tcon)
3541 cifs_put_tcon(tcon);
Pavel Shilovskyaf4281d2012-05-27 20:48:35 +04003542 else if (ses)
3543 cifs_put_smb_ses(ses);
Pavel Shilovsky724d9f12011-05-05 09:55:12 +00003544
Sachin Prabhu1dfd18d2015-06-16 16:36:17 +01003545 cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_POSIX_PATHS;
3546
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +04003547 free_xid(xid);
Pavel Shilovsky724d9f12011-05-05 09:55:12 +00003548 }
3549#endif
Jeff Layton1daaae82012-03-21 06:30:40 -04003550 rc = 0;
Pavel Shilovsky724d9f12011-05-05 09:55:12 +00003551 tcon = NULL;
Pavel Shilovskyaf4281d2012-05-27 20:48:35 +04003552 ses = NULL;
3553 server = NULL;
Pavel Shilovsky724d9f12011-05-05 09:55:12 +00003554 full_path = NULL;
3555 tlink = NULL;
3556
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +04003557 xid = get_xid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07003558
Jeff Layton63c038c2008-12-01 18:41:46 -05003559 /* get a reference to a tcp session */
Pavel Shilovskyaf4281d2012-05-27 20:48:35 +04003560 server = cifs_get_tcp_session(volume_info);
3561 if (IS_ERR(server)) {
3562 rc = PTR_ERR(server);
Al Virodd854462011-06-17 08:24:42 -04003563 bdi_destroy(&cifs_sb->bdi);
Jeff Layton63c038c2008-12-01 18:41:46 -05003564 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003565 }
3566
Jeff Layton36988c72010-04-24 07:57:43 -04003567 /* get a reference to a SMB session */
Pavel Shilovskyaf4281d2012-05-27 20:48:35 +04003568 ses = cifs_get_smb_ses(server, volume_info);
3569 if (IS_ERR(ses)) {
3570 rc = PTR_ERR(ses);
3571 ses = NULL;
Jeff Layton36988c72010-04-24 07:57:43 -04003572 goto mount_fail_check;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003573 }
Steve French50c2f752007-07-13 00:33:32 +00003574
Steve French592fafe2015-11-03 10:08:53 -06003575#ifdef CONFIG_CIFS_SMB2
Steve Frenchb618f002015-11-03 09:15:03 -06003576 if ((volume_info->persistent == true) && ((ses->server->capabilities &
3577 SMB2_GLOBAL_CAP_PERSISTENT_HANDLES) == 0)) {
3578 cifs_dbg(VFS, "persistent handles not supported by server\n");
3579 rc = -EOPNOTSUPP;
3580 goto mount_fail_check;
3581 }
Steve French592fafe2015-11-03 10:08:53 -06003582#endif /* CONFIG_CIFS_SMB2*/
3583
Jeff Laytond00c28d2010-04-24 07:57:44 -04003584 /* search for existing tcon to this server share */
Pavel Shilovskyaf4281d2012-05-27 20:48:35 +04003585 tcon = cifs_get_tcon(ses, volume_info);
Jeff Laytond00c28d2010-04-24 07:57:44 -04003586 if (IS_ERR(tcon)) {
3587 rc = PTR_ERR(tcon);
3588 tcon = NULL;
Igor Mammedov1bfe73c2009-04-01 17:54:42 +04003589 goto remote_path_check;
Jeff Laytond00c28d2010-04-24 07:57:44 -04003590 }
Igor Mammedov1bfe73c2009-04-01 17:54:42 +04003591
Steve French6848b732011-05-26 18:38:54 +00003592 /* tell server which Unix caps we support */
Pavel Shilovsky29e20f92012-07-13 13:58:14 +04003593 if (cap_unix(tcon->ses)) {
Steve French6848b732011-05-26 18:38:54 +00003594 /* reset of caps checks mount to see if unix extensions
3595 disabled for just this mount */
Al Viro2c6292a2011-06-17 09:05:48 -04003596 reset_cifs_unix_caps(xid, tcon, cifs_sb, volume_info);
Steve French6848b732011-05-26 18:38:54 +00003597 if ((tcon->ses->server->tcpStatus == CifsNeedReconnect) &&
3598 (le64_to_cpu(tcon->fsUnixInfo.Capability) &
3599 CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)) {
3600 rc = -EACCES;
3601 goto mount_fail_check;
3602 }
3603 } else
3604 tcon->unix_ext = 0; /* server does not support them */
3605
Pavel Shilovskyaf4281d2012-05-27 20:48:35 +04003606 /* do not care if a following call succeed - informational */
3607 if (!tcon->ipc && server->ops->qfs_tcon)
3608 server->ops->qfs_tcon(xid, tcon);
Steve Frenchd82c2df2008-11-15 00:07:26 +00003609
Pavel Shilovsky24985c52012-09-18 16:20:28 -07003610 cifs_sb->wsize = server->ops->negotiate_wsize(tcon, volume_info);
3611 cifs_sb->rsize = server->ops->negotiate_rsize(tcon, volume_info);
Jeff Laytonf7910cb2011-05-19 16:22:58 -04003612
Jeff Layton66bfaad2011-10-19 15:30:35 -04003613 /* tune readahead according to rsize */
Jeff Layton8f714652012-05-01 17:41:49 -04003614 cifs_sb->bdi.ra_pages = cifs_sb->rsize / PAGE_CACHE_SIZE;
Jeff Layton03ceace2010-12-06 21:07:33 -05003615
Igor Mammedove4cce942009-02-10 14:10:26 +03003616remote_path_check:
3617#ifdef CONFIG_CIFS_DFS_UPCALL
3618 /*
3619 * Perform an unconditional check for whether there are DFS
3620 * referrals for this path without prefix, to provide support
3621 * for DFS referrals from w2k8 servers which don't seem to respond
Igor Mammedov1bfe73c2009-04-01 17:54:42 +04003622 * with PATH_NOT_COVERED to requests that include the prefix.
3623 * Chase the referral if found, otherwise continue normally.
Steve Frenchd036f502009-04-03 03:12:08 +00003624 */
Igor Mammedov5c2503a2009-04-21 19:31:05 +04003625 if (referral_walks_count == 0) {
Pavel Shilovskyaf4281d2012-05-27 20:48:35 +04003626 int refrc = expand_dfs_referral(xid, ses, volume_info, cifs_sb,
3627 false);
Steve Frencheeac8042006-01-13 21:34:58 -08003628 if (!refrc) {
Steve French4523cc32007-04-30 20:13:06 +00003629 referral_walks_count++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003630 goto try_mount_again;
3631 }
3632 }
3633#endif
Igor Mammedov1bfe73c2009-04-01 17:54:42 +04003634
Steve Frenchf87d39d2011-05-27 03:50:55 +00003635 /* check if a whole path is not remote */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003636 if (!rc && tcon) {
Pavel Shilovsky68889f22012-05-25 14:40:22 +04003637 if (!server->ops->is_path_accessible) {
3638 rc = -ENOSYS;
3639 goto mount_fail_check;
3640 }
Steve French6d3ea7e2012-11-28 22:34:41 -06003641 /*
3642 * cifs_build_path_to_root works only when we have a valid tcon
3643 */
3644 full_path = cifs_build_path_to_root(volume_info, cifs_sb, tcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003645 if (full_path == NULL) {
3646 rc = -ENOMEM;
3647 goto mount_fail_check;
3648 }
Pavel Shilovsky68889f22012-05-25 14:40:22 +04003649 rc = server->ops->is_path_accessible(xid, tcon, cifs_sb,
3650 full_path);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003651 if (rc != 0 && rc != -EREMOTE) {
3652 kfree(full_path);
3653 goto mount_fail_check;
3654 }
3655 kfree(full_path);
3656 }
3657
3658 /* get referral if needed */
Igor Mammedov1bfe73c2009-04-01 17:54:42 +04003659 if (rc == -EREMOTE) {
3660#ifdef CONFIG_CIFS_DFS_UPCALL
Igor Mammedov5c2503a2009-04-21 19:31:05 +04003661 if (referral_walks_count > MAX_NESTED_LINKS) {
3662 /*
3663 * BB: when we implement proper loop detection,
3664 * we will remove this check. But now we need it
3665 * to prevent an indefinite loop if 'DFS tree' is
3666 * misconfigured (i.e. has loops).
3667 */
3668 rc = -ELOOP;
3669 goto mount_fail_check;
3670 }
Igor Mammedov1bfe73c2009-04-01 17:54:42 +04003671
Pavel Shilovskyaf4281d2012-05-27 20:48:35 +04003672 rc = expand_dfs_referral(xid, ses, volume_info, cifs_sb, true);
Jeff Layton7b91e262009-07-23 15:22:30 -04003673
Sean Finneydd613942011-04-11 13:19:30 +00003674 if (!rc) {
Igor Mammedov5c2503a2009-04-21 19:31:05 +04003675 referral_walks_count++;
Igor Mammedov1bfe73c2009-04-01 17:54:42 +04003676 goto try_mount_again;
3677 }
Sean Finneydd613942011-04-11 13:19:30 +00003678 goto mount_fail_check;
Steve Frenchd036f502009-04-03 03:12:08 +00003679#else /* No DFS support, return error on mount */
3680 rc = -EOPNOTSUPP;
3681#endif
Igor Mammedov1bfe73c2009-04-01 17:54:42 +04003682 }
3683
Jeff Layton9d002df2010-10-06 19:51:11 -04003684 if (rc)
3685 goto mount_fail_check;
3686
3687 /* now, hang the tcon off of the superblock */
3688 tlink = kzalloc(sizeof *tlink, GFP_KERNEL);
3689 if (tlink == NULL) {
3690 rc = -ENOMEM;
3691 goto mount_fail_check;
3692 }
3693
Pavel Shilovskyaf4281d2012-05-27 20:48:35 +04003694 tlink->tl_uid = ses->linux_uid;
Jeff Layton9d002df2010-10-06 19:51:11 -04003695 tlink->tl_tcon = tcon;
3696 tlink->tl_time = jiffies;
3697 set_bit(TCON_LINK_MASTER, &tlink->tl_flags);
3698 set_bit(TCON_LINK_IN_TREE, &tlink->tl_flags);
3699
Jeff Layton413e6612010-10-28 13:33:38 -04003700 cifs_sb->master_tlink = tlink;
Jeff Laytonb647c352010-10-28 11:16:44 -04003701 spin_lock(&cifs_sb->tlink_tree_lock);
3702 tlink_rb_insert(&cifs_sb->tlink_tree, tlink);
3703 spin_unlock(&cifs_sb->tlink_tree_lock);
Jeff Layton413e6612010-10-28 13:33:38 -04003704
Jeff Laytonda472fc2012-03-23 14:40:53 -04003705 queue_delayed_work(cifsiod_wq, &cifs_sb->prune_tlinks,
Jeff Layton2de970f2010-10-06 19:51:12 -04003706 TLINK_IDLE_EXPIRE);
3707
Igor Mammedov1bfe73c2009-04-01 17:54:42 +04003708mount_fail_check:
3709 /* on error free sesinfo and tcon struct if needed */
3710 if (rc) {
Igor Mammedov1bfe73c2009-04-01 17:54:42 +04003711 /* If find_unc succeeded then rc == 0 so we can not end */
Lucas De Marchi25985ed2011-03-30 22:57:33 -03003712 /* up accidentally freeing someone elses tcon struct */
Igor Mammedov1bfe73c2009-04-01 17:54:42 +04003713 if (tcon)
3714 cifs_put_tcon(tcon);
Pavel Shilovskyaf4281d2012-05-27 20:48:35 +04003715 else if (ses)
3716 cifs_put_smb_ses(ses);
Igor Mammedov1bfe73c2009-04-01 17:54:42 +04003717 else
Pavel Shilovskyaf4281d2012-05-27 20:48:35 +04003718 cifs_put_tcp_session(server);
Al Virodd854462011-06-17 08:24:42 -04003719 bdi_destroy(&cifs_sb->bdi);
Igor Mammedov1bfe73c2009-04-01 17:54:42 +04003720 }
3721
Linus Torvalds1da177e2005-04-16 15:20:36 -07003722out:
Pavel Shilovsky6d5786a2012-06-20 11:21:16 +04003723 free_xid(xid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003724 return rc;
3725}
3726
Jeff Layton8d1bca32011-06-11 21:17:10 -04003727/*
3728 * Issue a TREE_CONNECT request. Note that for IPC$ shares, that the tcon
3729 * pointer may be NULL.
3730 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003731int
Pavel Shilovsky2e6e02a2012-05-25 11:11:39 +04003732CIFSTCon(const unsigned int xid, struct cifs_ses *ses,
Steve French96daf2b2011-05-27 04:34:02 +00003733 const char *tree, struct cifs_tcon *tcon,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003734 const struct nls_table *nls_codepage)
3735{
3736 struct smb_hdr *smb_buffer;
3737 struct smb_hdr *smb_buffer_response;
3738 TCONX_REQ *pSMB;
3739 TCONX_RSP *pSMBr;
3740 unsigned char *bcc_ptr;
3741 int rc = 0;
Jeff Layton690c5222011-01-20 13:36:51 -05003742 int length;
3743 __u16 bytes_left, count;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003744
3745 if (ses == NULL)
3746 return -EIO;
3747
3748 smb_buffer = cifs_buf_get();
Steve Frenchca43e3b2009-09-01 17:20:50 +00003749 if (smb_buffer == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003750 return -ENOMEM;
Steve Frenchca43e3b2009-09-01 17:20:50 +00003751
Linus Torvalds1da177e2005-04-16 15:20:36 -07003752 smb_buffer_response = smb_buffer;
3753
3754 header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
3755 NULL /*no tid */ , 4 /*wct */ );
Steve French1982c342005-08-17 12:38:22 -07003756
Pavel Shilovsky88257362012-05-23 14:01:59 +04003757 smb_buffer->Mid = get_next_mid(ses->server);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003758 smb_buffer->Uid = ses->Suid;
3759 pSMB = (TCONX_REQ *) smb_buffer;
3760 pSMBr = (TCONX_RSP *) smb_buffer_response;
3761
3762 pSMB->AndXCommand = 0xFF;
3763 pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003764 bcc_ptr = &pSMB->Password[0];
Jeff Layton8d1bca32011-06-11 21:17:10 -04003765 if (!tcon || (ses->server->sec_mode & SECMODE_USER)) {
Steve Frencheeac8042006-01-13 21:34:58 -08003766 pSMB->PasswordLength = cpu_to_le16(1); /* minimum */
Steve French7c7b25b2006-06-01 19:20:10 +00003767 *bcc_ptr = 0; /* password is null byte */
Steve Frencheeac8042006-01-13 21:34:58 -08003768 bcc_ptr++; /* skip password */
Steve French7c7b25b2006-06-01 19:20:10 +00003769 /* already aligned so no need to do it below */
Steve Frencheeac8042006-01-13 21:34:58 -08003770 } else {
Shirish Pargaonkar540b2e32011-01-18 22:33:54 -06003771 pSMB->PasswordLength = cpu_to_le16(CIFS_AUTH_RESP_SIZE);
Steve Frencheeac8042006-01-13 21:34:58 -08003772 /* BB FIXME add code to fail this if NTLMv2 or Kerberos
3773 specified as required (when that support is added to
3774 the vfs in the future) as only NTLM or the much
Steve French7c7b25b2006-06-01 19:20:10 +00003775 weaker LANMAN (which we do not send by default) is accepted
Steve Frencheeac8042006-01-13 21:34:58 -08003776 by Samba (not sure whether other servers allow
3777 NTLMv2 password here) */
Steve French7c7b25b2006-06-01 19:20:10 +00003778#ifdef CONFIG_CIFS_WEAK_PW_HASH
Jeff Layton04912d62010-04-24 07:57:45 -04003779 if ((global_secflags & CIFSSEC_MAY_LANMAN) &&
Jeff Layton3f618222013-06-12 19:52:14 -05003780 (ses->sectype == LANMAN))
Shirish Pargaonkard3ba50b2010-10-27 15:20:36 -05003781 calc_lanman_hash(tcon->password, ses->server->cryptkey,
Steve French96daf2b2011-05-27 04:34:02 +00003782 ses->server->sec_mode &
Jeff Layton4e53a3f2008-12-05 20:41:21 -05003783 SECMODE_PW_ENCRYPT ? true : false,
3784 bcc_ptr);
Steve French7c7b25b2006-06-01 19:20:10 +00003785 else
3786#endif /* CIFS_WEAK_PW_HASH */
Shirish Pargaonkaree2c9252011-01-27 09:58:04 -06003787 rc = SMBNTencrypt(tcon->password, ses->server->cryptkey,
Shirish Pargaonkar9ef59922011-10-20 13:21:59 -05003788 bcc_ptr, nls_codepage);
Steve Frenchf3a31a22015-03-26 19:23:20 -05003789 if (rc) {
3790 cifs_dbg(FYI, "%s Can't generate NTLM rsp. Error: %d\n",
3791 __func__, rc);
3792 cifs_buf_release(smb_buffer);
3793 return rc;
3794 }
Steve Frencheeac8042006-01-13 21:34:58 -08003795
Shirish Pargaonkar540b2e32011-01-18 22:33:54 -06003796 bcc_ptr += CIFS_AUTH_RESP_SIZE;
Steve Frenchfb8c4b12007-07-10 01:16:18 +00003797 if (ses->capabilities & CAP_UNICODE) {
Steve French7c7b25b2006-06-01 19:20:10 +00003798 /* must align unicode strings */
3799 *bcc_ptr = 0; /* null byte password */
3800 bcc_ptr++;
3801 }
Steve Frencheeac8042006-01-13 21:34:58 -08003802 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003803
Jeff Layton38d77c52013-05-26 07:01:00 -04003804 if (ses->server->sign)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003805 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
3806
3807 if (ses->capabilities & CAP_STATUS32) {
3808 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
3809 }
3810 if (ses->capabilities & CAP_DFS) {
3811 smb_buffer->Flags2 |= SMBFLG2_DFS;
3812 }
3813 if (ses->capabilities & CAP_UNICODE) {
3814 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
3815 length =
Steve Frenchacbbb762012-01-18 22:32:33 -06003816 cifs_strtoUTF16((__le16 *) bcc_ptr, tree,
Steve French50c2f752007-07-13 00:33:32 +00003817 6 /* max utf8 char length in bytes */ *
Steve Frencha878fb22006-05-30 18:04:19 +00003818 (/* server len*/ + 256 /* share len */), nls_codepage);
3819 bcc_ptr += 2 * length; /* convert num 16 bit words to bytes */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003820 bcc_ptr += 2; /* skip trailing null */
3821 } else { /* ASCII */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003822 strcpy(bcc_ptr, tree);
3823 bcc_ptr += strlen(tree) + 1;
3824 }
3825 strcpy(bcc_ptr, "?????");
3826 bcc_ptr += strlen("?????");
3827 bcc_ptr += 1;
3828 count = bcc_ptr - &pSMB->Password[0];
Steve Frenchbe8e3b02011-04-29 05:40:20 +00003829 pSMB->hdr.smb_buf_length = cpu_to_be32(be32_to_cpu(
3830 pSMB->hdr.smb_buf_length) + count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003831 pSMB->ByteCount = cpu_to_le16(count);
3832
Steve French133672e2007-11-13 22:41:37 +00003833 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length,
Jeff Layton77499812011-01-11 07:24:23 -05003834 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003835
Linus Torvalds1da177e2005-04-16 15:20:36 -07003836 /* above now done in SendReceive */
3837 if ((rc == 0) && (tcon != NULL)) {
Steve French0e0d2cf2009-05-01 05:27:32 +00003838 bool is_unicode;
3839
Linus Torvalds1da177e2005-04-16 15:20:36 -07003840 tcon->tidStatus = CifsGood;
Steve French3b795212008-11-13 19:45:32 +00003841 tcon->need_reconnect = false;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003842 tcon->tid = smb_buffer_response->Tid;
3843 bcc_ptr = pByteArea(smb_buffer_response);
Jeff Layton690c5222011-01-20 13:36:51 -05003844 bytes_left = get_bcc(smb_buffer_response);
Jeff Laytoncc20c032009-04-30 07:16:21 -04003845 length = strnlen(bcc_ptr, bytes_left - 2);
Steve French0e0d2cf2009-05-01 05:27:32 +00003846 if (smb_buffer->Flags2 & SMBFLG2_UNICODE)
3847 is_unicode = true;
3848 else
3849 is_unicode = false;
3850
Jeff Laytoncc20c032009-04-30 07:16:21 -04003851
Steve French50c2f752007-07-13 00:33:32 +00003852 /* skip service field (NB: this field is always ASCII) */
Steve French7f8ed422007-09-28 22:28:55 +00003853 if (length == 3) {
3854 if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') &&
3855 (bcc_ptr[2] == 'C')) {
Joe Perchesf96637b2013-05-04 22:12:25 -05003856 cifs_dbg(FYI, "IPC connection\n");
Steve French7f8ed422007-09-28 22:28:55 +00003857 tcon->ipc = 1;
3858 }
3859 } else if (length == 2) {
3860 if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) {
3861 /* the most common case */
Joe Perchesf96637b2013-05-04 22:12:25 -05003862 cifs_dbg(FYI, "disk share connection\n");
Steve French7f8ed422007-09-28 22:28:55 +00003863 }
3864 }
Steve French50c2f752007-07-13 00:33:32 +00003865 bcc_ptr += length + 1;
Jeff Laytoncc20c032009-04-30 07:16:21 -04003866 bytes_left -= (length + 1);
Zhao Hongjiang46b51d02013-06-24 01:57:47 -05003867 strlcpy(tcon->treeName, tree, sizeof(tcon->treeName));
Jeff Laytoncc20c032009-04-30 07:16:21 -04003868
3869 /* mostly informational -- no need to fail on error here */
Jeff Layton90a98b22009-07-20 13:40:52 -04003870 kfree(tcon->nativeFileSystem);
Steve Frenchacbbb762012-01-18 22:32:33 -06003871 tcon->nativeFileSystem = cifs_strndup_from_utf16(bcc_ptr,
Steve French0e0d2cf2009-05-01 05:27:32 +00003872 bytes_left, is_unicode,
Jeff Laytoncc20c032009-04-30 07:16:21 -04003873 nls_codepage);
3874
Joe Perchesf96637b2013-05-04 22:12:25 -05003875 cifs_dbg(FYI, "nativeFileSystem=%s\n", tcon->nativeFileSystem);
Jeff Laytoncc20c032009-04-30 07:16:21 -04003876
Steve Frenchfb8c4b12007-07-10 01:16:18 +00003877 if ((smb_buffer_response->WordCount == 3) ||
Steve French1a4e15a2006-10-12 21:33:51 +00003878 (smb_buffer_response->WordCount == 7))
3879 /* field is in same location */
Steve French39798772006-05-31 22:40:51 +00003880 tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
3881 else
3882 tcon->Flags = 0;
Joe Perchesf96637b2013-05-04 22:12:25 -05003883 cifs_dbg(FYI, "Tcon flags: 0x%x\n", tcon->Flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003884 } else if ((rc == 0) && tcon == NULL) {
Steve French50c2f752007-07-13 00:33:32 +00003885 /* all we need to save for IPC$ connection */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003886 ses->ipc_tid = smb_buffer_response->Tid;
3887 }
3888
Mariusz Kozlowskia8a11d32007-10-03 16:41:24 +00003889 cifs_buf_release(smb_buffer);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003890 return rc;
3891}
3892
Al Viro2e32cf52013-10-03 12:53:37 -04003893static void delayed_free(struct rcu_head *p)
3894{
3895 struct cifs_sb_info *sbi = container_of(p, struct cifs_sb_info, rcu);
3896 unload_nls(sbi->local_nls);
3897 kfree(sbi);
3898}
3899
Al Viro2a9b9952011-06-17 09:27:16 -04003900void
3901cifs_umount(struct cifs_sb_info *cifs_sb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003902{
Jeff Laytonb647c352010-10-28 11:16:44 -04003903 struct rb_root *root = &cifs_sb->tlink_tree;
3904 struct rb_node *node;
3905 struct tcon_link *tlink;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003906
Jeff Layton2de970f2010-10-06 19:51:12 -04003907 cancel_delayed_work_sync(&cifs_sb->prune_tlinks);
3908
Jeff Laytonb647c352010-10-28 11:16:44 -04003909 spin_lock(&cifs_sb->tlink_tree_lock);
3910 while ((node = rb_first(root))) {
3911 tlink = rb_entry(node, struct tcon_link, tl_rbnode);
3912 cifs_get_tlink(tlink);
3913 clear_bit(TCON_LINK_IN_TREE, &tlink->tl_flags);
3914 rb_erase(node, root);
Steve French50c2f752007-07-13 00:33:32 +00003915
Jeff Laytonb647c352010-10-28 11:16:44 -04003916 spin_unlock(&cifs_sb->tlink_tree_lock);
3917 cifs_put_tlink(tlink);
3918 spin_lock(&cifs_sb->tlink_tree_lock);
3919 }
3920 spin_unlock(&cifs_sb->tlink_tree_lock);
Jeff Layton9d002df2010-10-06 19:51:11 -04003921
Al Virodd854462011-06-17 08:24:42 -04003922 bdi_destroy(&cifs_sb->bdi);
Al Virod757d712011-06-17 09:42:43 -04003923 kfree(cifs_sb->mountdata);
Al Viro2e32cf52013-10-03 12:53:37 -04003924 call_rcu(&cifs_sb->rcu, delayed_free);
Steve French50c2f752007-07-13 00:33:32 +00003925}
Linus Torvalds1da177e2005-04-16 15:20:36 -07003926
Pavel Shilovsky286170a2012-05-25 10:43:58 +04003927int
3928cifs_negotiate_protocol(const unsigned int xid, struct cifs_ses *ses)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003929{
3930 int rc = 0;
Jeff Layton198b5682010-04-24 07:57:48 -04003931 struct TCP_Server_Info *server = ses->server;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003932
Pavel Shilovsky286170a2012-05-25 10:43:58 +04003933 if (!server->ops->need_neg || !server->ops->negotiate)
3934 return -ENOSYS;
3935
Jeff Layton198b5682010-04-24 07:57:48 -04003936 /* only send once per connect */
Pavel Shilovsky286170a2012-05-25 10:43:58 +04003937 if (!server->ops->need_neg(server))
Jeff Layton198b5682010-04-24 07:57:48 -04003938 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003939
Pavel Shilovsky45275782012-05-17 17:53:29 +04003940 set_credits(server, 1);
Pavel Shilovsky286170a2012-05-25 10:43:58 +04003941
3942 rc = server->ops->negotiate(xid, ses);
Jeff Layton198b5682010-04-24 07:57:48 -04003943 if (rc == 0) {
3944 spin_lock(&GlobalMid_Lock);
Jeff Layton7fdbaa12011-06-10 16:14:57 -04003945 if (server->tcpStatus == CifsNeedNegotiate)
Jeff Layton198b5682010-04-24 07:57:48 -04003946 server->tcpStatus = CifsGood;
3947 else
3948 rc = -EHOSTDOWN;
3949 spin_unlock(&GlobalMid_Lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003950 }
Steve French26b994f2008-08-06 05:11:33 +00003951
Jeff Layton198b5682010-04-24 07:57:48 -04003952 return rc;
3953}
Steve French26b994f2008-08-06 05:11:33 +00003954
Pavel Shilovsky58c45c52012-05-25 10:54:49 +04003955int
3956cifs_setup_session(const unsigned int xid, struct cifs_ses *ses,
3957 struct nls_table *nls_info)
Jeff Layton198b5682010-04-24 07:57:48 -04003958{
Pavel Shilovsky58c45c52012-05-25 10:54:49 +04003959 int rc = -ENOSYS;
Jeff Layton198b5682010-04-24 07:57:48 -04003960 struct TCP_Server_Info *server = ses->server;
3961
Jeff Layton198b5682010-04-24 07:57:48 -04003962 ses->capabilities = server->capabilities;
Steve French26b994f2008-08-06 05:11:33 +00003963 if (linuxExtEnabled == 0)
Pavel Shilovsky29e20f92012-07-13 13:58:14 +04003964 ses->capabilities &= (~server->vals->cap_unix);
Steve French20418ac2009-04-30 16:13:32 +00003965
Joe Perchesf96637b2013-05-04 22:12:25 -05003966 cifs_dbg(FYI, "Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d\n",
Steve French96daf2b2011-05-27 04:34:02 +00003967 server->sec_mode, server->capabilities, server->timeAdj);
Jeff Laytoncb7691b2008-08-18 15:41:05 -04003968
Pavel Shilovsky58c45c52012-05-25 10:54:49 +04003969 if (server->ops->sess_setup)
3970 rc = server->ops->sess_setup(xid, ses, nls_info);
3971
Shirish Pargaonkard4e63bd2013-08-29 08:35:09 -05003972 if (rc)
Joe Perchesf96637b2013-05-04 22:12:25 -05003973 cifs_dbg(VFS, "Send error in SessSetup = %d\n", rc);
Shirish Pargaonkar21e73392010-10-21 06:42:55 -05003974
Linus Torvalds1da177e2005-04-16 15:20:36 -07003975 return rc;
3976}
3977
Jeff Layton8a8798a2012-01-17 16:09:15 -05003978static int
3979cifs_set_vol_auth(struct smb_vol *vol, struct cifs_ses *ses)
3980{
Jeff Layton3f618222013-06-12 19:52:14 -05003981 vol->sectype = ses->sectype;
3982
3983 /* krb5 is special, since we don't need username or pw */
3984 if (vol->sectype == Kerberos)
Jeff Layton8a8798a2012-01-17 16:09:15 -05003985 return 0;
Jeff Layton8a8798a2012-01-17 16:09:15 -05003986
3987 return cifs_set_cifscreds(vol, ses);
3988}
3989
Steve French96daf2b2011-05-27 04:34:02 +00003990static struct cifs_tcon *
Eric W. Biederman6d4a0832013-02-06 01:48:56 -08003991cifs_construct_tcon(struct cifs_sb_info *cifs_sb, kuid_t fsuid)
Jeff Layton9d002df2010-10-06 19:51:11 -04003992{
Jeff Layton8a8798a2012-01-17 16:09:15 -05003993 int rc;
Steve French96daf2b2011-05-27 04:34:02 +00003994 struct cifs_tcon *master_tcon = cifs_sb_master_tcon(cifs_sb);
3995 struct cifs_ses *ses;
3996 struct cifs_tcon *tcon = NULL;
Jeff Layton9d002df2010-10-06 19:51:11 -04003997 struct smb_vol *vol_info;
Jeff Layton9d002df2010-10-06 19:51:11 -04003998
3999 vol_info = kzalloc(sizeof(*vol_info), GFP_KERNEL);
Dan Carpenter803ab972012-01-24 11:39:22 +03004000 if (vol_info == NULL)
4001 return ERR_PTR(-ENOMEM);
Jeff Layton9d002df2010-10-06 19:51:11 -04004002
Jeff Layton9d002df2010-10-06 19:51:11 -04004003 vol_info->local_nls = cifs_sb->local_nls;
4004 vol_info->linux_uid = fsuid;
4005 vol_info->cred_uid = fsuid;
4006 vol_info->UNC = master_tcon->treeName;
4007 vol_info->retry = master_tcon->retry;
4008 vol_info->nocase = master_tcon->nocase;
4009 vol_info->local_lease = master_tcon->local_lease;
4010 vol_info->no_linux_ext = !master_tcon->unix_ext;
Jeff Layton28e11bd2013-05-26 07:01:00 -04004011 vol_info->sectype = master_tcon->ses->sectype;
4012 vol_info->sign = master_tcon->ses->sign;
Jeff Layton9d002df2010-10-06 19:51:11 -04004013
Jeff Layton8a8798a2012-01-17 16:09:15 -05004014 rc = cifs_set_vol_auth(vol_info, master_tcon->ses);
4015 if (rc) {
4016 tcon = ERR_PTR(rc);
4017 goto out;
4018 }
Jeff Layton9d002df2010-10-06 19:51:11 -04004019
4020 /* get a reference for the same TCP session */
Suresh Jayaraman3f9bcca2010-10-18 23:29:37 +05304021 spin_lock(&cifs_tcp_ses_lock);
Jeff Layton9d002df2010-10-06 19:51:11 -04004022 ++master_tcon->ses->server->srv_count;
Suresh Jayaraman3f9bcca2010-10-18 23:29:37 +05304023 spin_unlock(&cifs_tcp_ses_lock);
Jeff Layton9d002df2010-10-06 19:51:11 -04004024
4025 ses = cifs_get_smb_ses(master_tcon->ses->server, vol_info);
4026 if (IS_ERR(ses)) {
Steve French96daf2b2011-05-27 04:34:02 +00004027 tcon = (struct cifs_tcon *)ses;
Jeff Layton9d002df2010-10-06 19:51:11 -04004028 cifs_put_tcp_session(master_tcon->ses->server);
4029 goto out;
4030 }
4031
4032 tcon = cifs_get_tcon(ses, vol_info);
4033 if (IS_ERR(tcon)) {
4034 cifs_put_smb_ses(ses);
4035 goto out;
4036 }
4037
Pavel Shilovsky29e20f92012-07-13 13:58:14 +04004038 if (cap_unix(ses))
Jeff Layton9d002df2010-10-06 19:51:11 -04004039 reset_cifs_unix_caps(0, tcon, NULL, vol_info);
4040out:
Jeff Layton8a8798a2012-01-17 16:09:15 -05004041 kfree(vol_info->username);
4042 kfree(vol_info->password);
Jeff Layton9d002df2010-10-06 19:51:11 -04004043 kfree(vol_info);
4044
4045 return tcon;
4046}
4047
Steve French96daf2b2011-05-27 04:34:02 +00004048struct cifs_tcon *
Jeff Layton9d002df2010-10-06 19:51:11 -04004049cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb)
4050{
4051 return tlink_tcon(cifs_sb_master_tlink(cifs_sb));
4052}
4053
Jeff Laytonb647c352010-10-28 11:16:44 -04004054/* find and return a tlink with given uid */
4055static struct tcon_link *
Eric W. Biederman6d4a0832013-02-06 01:48:56 -08004056tlink_rb_search(struct rb_root *root, kuid_t uid)
Jeff Laytonb647c352010-10-28 11:16:44 -04004057{
4058 struct rb_node *node = root->rb_node;
4059 struct tcon_link *tlink;
4060
4061 while (node) {
4062 tlink = rb_entry(node, struct tcon_link, tl_rbnode);
4063
Eric W. Biederman6d4a0832013-02-06 01:48:56 -08004064 if (uid_gt(tlink->tl_uid, uid))
Jeff Laytonb647c352010-10-28 11:16:44 -04004065 node = node->rb_left;
Eric W. Biederman6d4a0832013-02-06 01:48:56 -08004066 else if (uid_lt(tlink->tl_uid, uid))
Jeff Laytonb647c352010-10-28 11:16:44 -04004067 node = node->rb_right;
4068 else
4069 return tlink;
4070 }
4071 return NULL;
4072}
4073
4074/* insert a tcon_link into the tree */
4075static void
4076tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink)
4077{
4078 struct rb_node **new = &(root->rb_node), *parent = NULL;
4079 struct tcon_link *tlink;
4080
4081 while (*new) {
4082 tlink = rb_entry(*new, struct tcon_link, tl_rbnode);
4083 parent = *new;
4084
Eric W. Biederman6d4a0832013-02-06 01:48:56 -08004085 if (uid_gt(tlink->tl_uid, new_tlink->tl_uid))
Jeff Laytonb647c352010-10-28 11:16:44 -04004086 new = &((*new)->rb_left);
4087 else
4088 new = &((*new)->rb_right);
4089 }
4090
4091 rb_link_node(&new_tlink->tl_rbnode, parent, new);
4092 rb_insert_color(&new_tlink->tl_rbnode, root);
4093}
4094
Jeff Layton9d002df2010-10-06 19:51:11 -04004095/*
4096 * Find or construct an appropriate tcon given a cifs_sb and the fsuid of the
4097 * current task.
4098 *
4099 * If the superblock doesn't refer to a multiuser mount, then just return
4100 * the master tcon for the mount.
4101 *
Suresh Jayaraman6ef933a2010-11-03 10:53:49 +05304102 * First, search the rbtree for an existing tcon for this fsuid. If one
Jeff Layton9d002df2010-10-06 19:51:11 -04004103 * exists, then check to see if it's pending construction. If it is then wait
4104 * for construction to complete. Once it's no longer pending, check to see if
4105 * it failed and either return an error or retry construction, depending on
4106 * the timeout.
4107 *
4108 * If one doesn't exist then insert a new tcon_link struct into the tree and
4109 * try to construct a new one.
4110 */
4111struct tcon_link *
4112cifs_sb_tlink(struct cifs_sb_info *cifs_sb)
4113{
4114 int ret;
Eric W. Biederman6d4a0832013-02-06 01:48:56 -08004115 kuid_t fsuid = current_fsuid();
Jeff Layton9d002df2010-10-06 19:51:11 -04004116 struct tcon_link *tlink, *newtlink;
4117
4118 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER))
4119 return cifs_get_tlink(cifs_sb_master_tlink(cifs_sb));
4120
4121 spin_lock(&cifs_sb->tlink_tree_lock);
Jeff Laytonb647c352010-10-28 11:16:44 -04004122 tlink = tlink_rb_search(&cifs_sb->tlink_tree, fsuid);
Jeff Layton9d002df2010-10-06 19:51:11 -04004123 if (tlink)
4124 cifs_get_tlink(tlink);
4125 spin_unlock(&cifs_sb->tlink_tree_lock);
4126
4127 if (tlink == NULL) {
4128 newtlink = kzalloc(sizeof(*tlink), GFP_KERNEL);
4129 if (newtlink == NULL)
4130 return ERR_PTR(-ENOMEM);
Jeff Laytonb647c352010-10-28 11:16:44 -04004131 newtlink->tl_uid = fsuid;
Jeff Layton9d002df2010-10-06 19:51:11 -04004132 newtlink->tl_tcon = ERR_PTR(-EACCES);
4133 set_bit(TCON_LINK_PENDING, &newtlink->tl_flags);
4134 set_bit(TCON_LINK_IN_TREE, &newtlink->tl_flags);
4135 cifs_get_tlink(newtlink);
4136
Jeff Layton9d002df2010-10-06 19:51:11 -04004137 spin_lock(&cifs_sb->tlink_tree_lock);
4138 /* was one inserted after previous search? */
Jeff Laytonb647c352010-10-28 11:16:44 -04004139 tlink = tlink_rb_search(&cifs_sb->tlink_tree, fsuid);
Jeff Layton9d002df2010-10-06 19:51:11 -04004140 if (tlink) {
4141 cifs_get_tlink(tlink);
4142 spin_unlock(&cifs_sb->tlink_tree_lock);
Jeff Layton9d002df2010-10-06 19:51:11 -04004143 kfree(newtlink);
4144 goto wait_for_construction;
4145 }
Jeff Layton9d002df2010-10-06 19:51:11 -04004146 tlink = newtlink;
Jeff Laytonb647c352010-10-28 11:16:44 -04004147 tlink_rb_insert(&cifs_sb->tlink_tree, tlink);
4148 spin_unlock(&cifs_sb->tlink_tree_lock);
Jeff Layton9d002df2010-10-06 19:51:11 -04004149 } else {
4150wait_for_construction:
4151 ret = wait_on_bit(&tlink->tl_flags, TCON_LINK_PENDING,
Jeff Layton9d002df2010-10-06 19:51:11 -04004152 TASK_INTERRUPTIBLE);
4153 if (ret) {
4154 cifs_put_tlink(tlink);
NeilBrown74316202014-07-07 15:16:04 +10004155 return ERR_PTR(-ERESTARTSYS);
Jeff Layton9d002df2010-10-06 19:51:11 -04004156 }
4157
4158 /* if it's good, return it */
4159 if (!IS_ERR(tlink->tl_tcon))
4160 return tlink;
4161
4162 /* return error if we tried this already recently */
4163 if (time_before(jiffies, tlink->tl_time + TLINK_ERROR_EXPIRE)) {
4164 cifs_put_tlink(tlink);
4165 return ERR_PTR(-EACCES);
4166 }
4167
4168 if (test_and_set_bit(TCON_LINK_PENDING, &tlink->tl_flags))
4169 goto wait_for_construction;
4170 }
4171
4172 tlink->tl_tcon = cifs_construct_tcon(cifs_sb, fsuid);
4173 clear_bit(TCON_LINK_PENDING, &tlink->tl_flags);
4174 wake_up_bit(&tlink->tl_flags, TCON_LINK_PENDING);
4175
4176 if (IS_ERR(tlink->tl_tcon)) {
4177 cifs_put_tlink(tlink);
4178 return ERR_PTR(-EACCES);
4179 }
4180
4181 return tlink;
4182}
Jeff Layton2de970f2010-10-06 19:51:12 -04004183
4184/*
4185 * periodic workqueue job that scans tcon_tree for a superblock and closes
4186 * out tcons.
4187 */
4188static void
4189cifs_prune_tlinks(struct work_struct *work)
4190{
4191 struct cifs_sb_info *cifs_sb = container_of(work, struct cifs_sb_info,
4192 prune_tlinks.work);
Jeff Laytonb647c352010-10-28 11:16:44 -04004193 struct rb_root *root = &cifs_sb->tlink_tree;
4194 struct rb_node *node = rb_first(root);
4195 struct rb_node *tmp;
4196 struct tcon_link *tlink;
Jeff Layton2de970f2010-10-06 19:51:12 -04004197
Jeff Laytonb647c352010-10-28 11:16:44 -04004198 /*
4199 * Because we drop the spinlock in the loop in order to put the tlink
4200 * it's not guarded against removal of links from the tree. The only
4201 * places that remove entries from the tree are this function and
4202 * umounts. Because this function is non-reentrant and is canceled
4203 * before umount can proceed, this is safe.
4204 */
4205 spin_lock(&cifs_sb->tlink_tree_lock);
4206 node = rb_first(root);
4207 while (node != NULL) {
4208 tmp = node;
4209 node = rb_next(tmp);
4210 tlink = rb_entry(tmp, struct tcon_link, tl_rbnode);
4211
4212 if (test_bit(TCON_LINK_MASTER, &tlink->tl_flags) ||
4213 atomic_read(&tlink->tl_count) != 0 ||
4214 time_after(tlink->tl_time + TLINK_IDLE_EXPIRE, jiffies))
4215 continue;
4216
4217 cifs_get_tlink(tlink);
4218 clear_bit(TCON_LINK_IN_TREE, &tlink->tl_flags);
4219 rb_erase(tmp, root);
4220
Jeff Layton2de970f2010-10-06 19:51:12 -04004221 spin_unlock(&cifs_sb->tlink_tree_lock);
Jeff Laytonb647c352010-10-28 11:16:44 -04004222 cifs_put_tlink(tlink);
4223 spin_lock(&cifs_sb->tlink_tree_lock);
4224 }
4225 spin_unlock(&cifs_sb->tlink_tree_lock);
Jeff Layton2de970f2010-10-06 19:51:12 -04004226
Jeff Laytonda472fc2012-03-23 14:40:53 -04004227 queue_delayed_work(cifsiod_wq, &cifs_sb->prune_tlinks,
Jeff Layton2de970f2010-10-06 19:51:12 -04004228 TLINK_IDLE_EXPIRE);
4229}