aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve French <stfrench@microsoft.com>2018-05-20 23:41:10 -0500
committerSteve French <stfrench@microsoft.com>2018-05-30 16:06:18 -0500
commitb326614ea2159ea5c835d320f261d05d080cd201 (patch)
tree8ae0dbfeee7e85b80d944e2149f4aa529e94015c
parentfcef0db6d630ccadaa65138b77eac5fce16a13c9 (diff)
downloadlinux-security-b326614ea2159ea5c835d320f261d05d080cd201.tar.gz
smb3: allow "posix" mount option to enable new SMB311 protocol extensions
If "posix" (or synonym "unix" for backward compatibility) specified on mount, and server advertises support for SMB3.11 POSIX negotiate context, then enable the new posix extensions on the tcon. This can be viewed by looking for "posix" in the mount options displayed by /proc/mounts for that mount (ie if posix extensions allowed by server and the experimental POSIX extensions also requested on the mount by specifying "posix" at mount time). Also add check to warn user if conflicting unix/nounix or posix/noposix specified on mount. Signed-off-by: Steve French <smfrench@gmail.com>
-rw-r--r--fs/cifs/cifsfs.c10
-rw-r--r--fs/cifs/cifsglob.h4
-rw-r--r--fs/cifs/connect.c23
3 files changed, 36 insertions, 1 deletions
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index c608ea62f53618..eb7b6573f322e4 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -481,10 +481,20 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
seq_puts(s, ",persistenthandles");
else if (tcon->use_resilient)
seq_puts(s, ",resilienthandles");
+
+#ifdef CONFIG_CIFS_SMB311
+ if (tcon->posix_extensions)
+ seq_puts(s, ",posix");
+ else if (tcon->unix_ext)
+ seq_puts(s, ",unix");
+ else
+ seq_puts(s, ",nounix");
+#else
if (tcon->unix_ext)
seq_puts(s, ",unix");
else
seq_puts(s, ",nounix");
+#endif /* SMB311 */
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
seq_puts(s, ",posixpaths");
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index b131a395b95c86..3e2ee7e1d85e2f 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -522,6 +522,7 @@ struct smb_vol {
bool sfu_remap:1; /* remap seven reserved chars ala SFU */
bool posix_paths:1; /* unset to not ask for posix pathnames. */
bool no_linux_ext:1;
+ bool linux_ext:1;
bool sfu_emul:1;
bool nullauth:1; /* attempt to authenticate with null user */
bool nocase:1; /* request case insensitive filenames */
@@ -960,6 +961,9 @@ struct cifs_tcon {
bool seal:1; /* transport encryption for this mounted share */
bool unix_ext:1; /* if false disable Linux extensions to CIFS protocol
for this mount even if server would support */
+#ifdef CONFIG_CIFS_SMB311
+ bool posix_extensions; /* if true SMB3.11 posix extensions enabled */
+#endif /* CIFS_311 */
bool local_lease:1; /* check leases (only) on local system not remote */
bool broken_posix_open; /* e.g. Samba server versions < 3.3.2, 3.2.9 */
bool broken_sparse_sup; /* if server or share does not support sparse */
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index ed3b6de88395dd..4c0e3f6ae356c8 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -77,7 +77,7 @@ enum {
Opt_mapposix, Opt_nomapposix,
Opt_mapchars, Opt_nomapchars, Opt_sfu,
Opt_nosfu, Opt_nodfs, Opt_posixpaths,
- Opt_noposixpaths, Opt_nounix,
+ Opt_noposixpaths, Opt_nounix, Opt_unix,
Opt_nocase,
Opt_brl, Opt_nobrl,
Opt_handlecache, Opt_nohandlecache,
@@ -146,6 +146,10 @@ static const match_table_t cifs_mount_option_tokens = {
{ Opt_noposixpaths, "noposixpaths" },
{ Opt_nounix, "nounix" },
{ Opt_nounix, "nolinux" },
+ { Opt_nounix, "noposix" },
+ { Opt_unix, "unix" },
+ { Opt_unix, "linux" },
+ { Opt_unix, "posix" },
{ Opt_nocase, "nocase" },
{ Opt_nocase, "ignorecase" },
{ Opt_brl, "brl" },
@@ -1438,8 +1442,17 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
vol->posix_paths = 0;
break;
case Opt_nounix:
+ if (vol->linux_ext)
+ cifs_dbg(VFS,
+ "conflicting unix mount options\n");
vol->no_linux_ext = 1;
break;
+ case Opt_unix:
+ if (vol->no_linux_ext)
+ cifs_dbg(VFS,
+ "conflicting unix mount options\n");
+ vol->linux_ext = 1;
+ break;
case Opt_nocase:
vol->nocase = 1;
break;
@@ -2985,6 +2998,13 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info)
}
}
+#ifdef CONFIG_CIFS_SMB311
+ if ((volume_info->linux_ext) && (ses->server->posix_ext_supported)) {
+ if (ses->server->vals->protocol_id == SMB311_PROT_ID)
+ tcon->posix_extensions = true;
+ }
+#endif /* 311 */
+
/*
* BB Do we need to wrap session_mutex around this TCon call and Unix
* SetFS as we do on SessSetup and reconnect?
@@ -4406,6 +4426,7 @@ cifs_construct_tcon(struct cifs_sb_info *cifs_sb, kuid_t fsuid)
if (cap_unix(ses))
reset_cifs_unix_caps(0, tcon, NULL, vol_info);
+
out:
kfree(vol_info->username);
kzfree(vol_info->password);