1
0
Fork 0

Convert default dialect to smb2.1 or later to allow connecting to Windows 7 for example, also includes some fixes for stable

-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQGcBAABAgAGBQJZwBUiAAoJEIosvXAHck9RbygL/0jG69MaHf1HSZdZQDmHQZFk
 9U3M8vhufxWx4bkM574Hm3TJJMZ4X5GNLB9oqOKdHa6Ciz2XRqwsGkIuqWuGCFmo
 vwBtHGwz3iGVaOb1LMzqxRKG/W1LJgGFZe57ZwGhwglDa6rMn46ygT11e8fH0+g1
 OI1OhUxDqLE8EDLHcfAaTlrRze8tNnYiEsRYU7qx6k4yeh5r3o9UMU3dqdMyEaw2
 pM2xLyBp8pZDcfCMrZwSoSFS4zt8eD5C9l7TDsoixxhChf2cVGA1nfbQUPYHfVd4
 tV4MmpHZtD9Uay4+L+tUAv1lAmuM93AMoltLXk34RojiPLjWzr5MSqdo2L0bEjYe
 SaItonZhOA/Y+A6VpvRKQBxOmSdgNhcyenUsQE8ybifPAksqIGlzc3Ba9iGLcVrp
 Izz4WARBrDAXC+FTt9N6kfVSN3QGIrYeZ2uwYmZCadK7GHu6O2s3wtYXa/0mewXG
 9s7s26kQwvJUAIcK3xu61HiJBx0jCW5DjKeejoaXxw==
 =sn5Y
 -----END PGP SIGNATURE-----

Merge tag '4.14-smb3-multidialect-support-and-fixes-for-stable' of git://git.samba.org/sfrench/cifs-2.6

Pull cifs fixes from Steve French:
 "Convert default dialect to smb2.1 or later to allow connecting to
  Windows 7 for example, also includes some fixes for stable"

* tag '4.14-smb3-multidialect-support-and-fixes-for-stable' of git://git.samba.org/sfrench/cifs-2.6:
  Update version of cifs module
  cifs: hide unused functions
  SMB3: Add support for multidialect negotiate (SMB2.1 and later)
  CIFS/SMB3: Update documentation to reflect SMB3 and various changes
  cifs: check rsp for NULL before dereferencing in SMB2_open
zero-colors
Linus Torvalds 2017-09-19 08:35:42 -07:00
commit 24420862bf
10 changed files with 235 additions and 112 deletions

View File

@ -41,6 +41,11 @@ Igor Mammedov (DFS support)
Jeff Layton (many, many fixes, as well as great work on the cifs Kerberos code)
Scott Lovenberg
Pavel Shilovsky (for great work adding SMB2 support, and various SMB3 features)
Aurelien Aptel (for DFS SMB3 work and some key bug fixes)
Ronnie Sahlberg (for SMB3 xattr work and bug fixes)
Shirish Pargaonkar (for many ACL patches over the years)
Sachin Prabhu (many bug fixes, including for reconnect, copy offload and security)
Test case and Bug Report contributors
-------------------------------------

View File

@ -1,10 +1,14 @@
The CIFS VFS support for Linux supports many advanced network filesystem
features such as hierarchical dfs like namespace, hardlinks, locking and more.
This module supports the SMB3 family of advanced network protocols (as well
as older dialects, originally called "CIFS" or SMB1).
The CIFS VFS module for Linux supports many advanced network filesystem
features such as hierarchical DFS like namespace, hardlinks, locking and more.
It was designed to comply with the SNIA CIFS Technical Reference (which
supersedes the 1992 X/Open SMB Standard) as well as to perform best practice
practical interoperability with Windows 2000, Windows XP, Samba and equivalent
servers. This code was developed in participation with the Protocol Freedom
Information Foundation.
Information Foundation. CIFS and now SMB3 has now become a defacto
standard for interoperating between Macs and Windows and major NAS appliances.
Please see
http://protocolfreedom.org/ and
@ -15,30 +19,11 @@ for more details.
For questions or bug reports please contact:
sfrench@samba.org (sfrench@us.ibm.com)
See the project page at: https://wiki.samba.org/index.php/LinuxCIFS_utils
Build instructions:
==================
For Linux 2.4:
1) Get the kernel source (e.g.from http://www.kernel.org)
and download the cifs vfs source (see the project page
at http://us1.samba.org/samba/Linux_CIFS_client.html)
and change directory into the top of the kernel directory
then patch the kernel (e.g. "patch -p1 < cifs_24.patch")
to add the cifs vfs to your kernel configure options if
it has not already been added (e.g. current SuSE and UL
users do not need to apply the cifs_24.patch since the cifs vfs is
already in the kernel configure menu) and then
mkdir linux/fs/cifs and then copy the current cifs vfs files from
the cifs download to your kernel build directory e.g.
cp <cifs_download_dir>/fs/cifs/* to <kernel_download_dir>/fs/cifs
2) make menuconfig (or make xconfig)
3) select cifs from within the network filesystem choices
4) save and exit
5) make dep
6) make modules (or "make" if CIFS VFS not to be built as a module)
For Linux 2.6:
For Linux:
1) Download the kernel (e.g. from http://www.kernel.org)
and change directory into the top of the kernel directory tree
(e.g. /usr/src/linux-2.5.73)
@ -61,16 +46,13 @@ would simply type "make install").
If you do not have the utility mount.cifs (in the Samba 3.0 source tree and on
the CIFS VFS web site) copy it to the same directory in which mount.smbfs and
similar files reside (usually /sbin). Although the helper software is not
required, mount.cifs is recommended. Eventually the Samba 3.0 utility program
"net" may also be helpful since it may someday provide easier mount syntax for
users who are used to Windows e.g.
net use <mount point> <UNC name or cifs URL>
required, mount.cifs is recommended. Most distros include a "cifs-utils"
package that includes this utility so it is recommended to install this.
Note that running the Winbind pam/nss module (logon service) on all of your
Linux clients is useful in mapping Uids and Gids consistently across the
domain to the proper network user. The mount.cifs mount helper can be
trivially built from Samba 3.0 or later source e.g. by executing:
gcc samba/source/client/mount.cifs.c -o mount.cifs
found at cifs-utils.git on git.samba.org
If cifs is built as a module, then the size and number of network buffers
and maximum number of simultaneous requests to one server can be configured.
@ -79,6 +61,18 @@ Changing these from their defaults is not recommended. By executing modinfo
on kernel/fs/cifs/cifs.ko the list of configuration changes that can be made
at module initialization time (by running insmod cifs.ko) can be seen.
Recommendations
===============
To improve security the SMB2.1 dialect or later (usually will get SMB3) is now
the new default. To use old dialects (e.g. to mount Windows XP) use "vers=1.0"
on mount (or vers=2.0 for Windows Vista). Note that the CIFS (vers=1.0) is
much older and less secure than the default dialect SMB3 which includes
many advanced security features such as downgrade attack detection
and encrypted shares and stronger signing and authentication algorithms.
There are additional mount options that may be helpful for SMB3 to get
improved POSIX behavior (NB: can use vers=3.0 to force only SMB3, never 2.1):
"mfsymlinks" and "cifsacl" and "idsfromsid"
Allowing User Mounts
====================
To permit users to mount and unmount over directories they own is possible
@ -98,9 +92,7 @@ and execution of suid programs on the remote target would be enabled
by default. This can be changed, as with nfs and other filesystems,
by simply specifying "nosuid" among the mount options. For user mounts
though to be able to pass the suid flag to mount requires rebuilding
mount.cifs with the following flag:
gcc samba/source/client/mount.cifs.c -DCIFS_ALLOW_USR_SUID -o mount.cifs
mount.cifs with the following flag: CIFS_ALLOW_USR_SUID
There is a corresponding manual page for cifs mounting in the Samba 3.0 and
later source tree in docs/manpages/mount.cifs.8
@ -189,18 +181,18 @@ applications running on the same server as Samba.
Use instructions:
================
Once the CIFS VFS support is built into the kernel or installed as a module
(cifs.o), you can use mount syntax like the following to access Samba or Windows
servers:
(cifs.ko), you can use mount syntax like the following to access Samba or
Mac or Windows servers:
mount -t cifs //9.53.216.11/e$ /mnt -o user=myname,pass=mypassword
mount -t cifs //9.53.216.11/e$ /mnt -o username=myname,password=mypassword
Before -o the option -v may be specified to make the mount.cifs
mount helper display the mount steps more verbosely.
After -o the following commonly used cifs vfs specific options
are supported:
user=<username>
pass=<password>
username=<username>
password=<password>
domain=<domain name>
Other cifs mount options are described below. Use of TCP names (in addition to
@ -246,13 +238,16 @@ the Server's registry. Samba starting with version 3.10 will allow such
filenames (ie those which contain valid Linux characters, which normally
would be forbidden for Windows/CIFS semantics) as long as the server is
configured for Unix Extensions (and the client has not disabled
/proc/fs/cifs/LinuxExtensionsEnabled).
/proc/fs/cifs/LinuxExtensionsEnabled). In addition the mount option
"mapposix" can be used on CIFS (vers=1.0) to force the mapping of
illegal Windows/NTFS/SMB characters to a remap range (this mount parm
is the default for SMB3). This remap ("mapposix") range is also
compatible with Mac (and "Services for Mac" on some older Windows).
CIFS VFS Mount Options
======================
A partial list of the supported mount options follows:
user The user name to use when trying to establish
username The user name to use when trying to establish
the CIFS session.
password The user password. If the mount helper is
installed, the user will be prompted for password

View File

@ -1,4 +1,4 @@
Version 2.03 August 1, 2014
Version 2.04 September 13, 2017
A Partial List of Missing Features
==================================
@ -8,73 +8,69 @@ for visible, important contributions to this module. Here
is a partial list of the known problems and missing features:
a) SMB3 (and SMB3.02) missing optional features:
- RDMA
- RDMA (started)
- multichannel (started)
- directory leases (improved metadata caching)
- T10 copy offload (copy chunk is only mechanism supported)
- encrypted shares
b) improved sparse file support
c) Directory entry caching relies on a 1 second timer, rather than
using FindNotify or equivalent. - (started)
using Directory Leases
d) quota support (needs minor kernel change since quota calls
to make it to network filesystems or deviceless filesystems)
e) improve support for very old servers (OS/2 and Win9x for example)
Including support for changing the time remotely (utimes command).
e) Better optimize open to reduce redundant opens (using reference
counts more) and to improve use of compounding in SMB3 to reduce
number of roundtrips.
f) hook lower into the sockets api (as NFS/SunRPC does) to avoid the
extra copy in/out of the socket buffers in some cases.
g) Better optimize open (and pathbased setfilesize) to reduce the
oplock breaks coming from windows srv. Piggyback identical file
opens on top of each other by incrementing reference count rather
than resending (helps reduce server resource utilization and avoid
spurious oplock breaks).
h) Add support for storing symlink info to Windows servers
in the Extended Attribute format their SFU clients would recognize.
i) Finish inotify support so kde and gnome file list windows
f) Finish inotify support so kde and gnome file list windows
will autorefresh (partially complete by Asser). Needs minor kernel
vfs change to support removing D_NOTIFY on a file.
j) Add GUI tool to configure /proc/fs/cifs settings and for display of
g) Add GUI tool to configure /proc/fs/cifs settings and for display of
the CIFS statistics (started)
k) implement support for security and trusted categories of xattrs
h) implement support for security and trusted categories of xattrs
(requires minor protocol extension) to enable better support for SELINUX
l) Implement O_DIRECT flag on open (already supported on mount)
i) Implement O_DIRECT flag on open (already supported on mount)
m) Create UID mapping facility so server UIDs can be mapped on a per
j) Create UID mapping facility so server UIDs can be mapped on a per
mount or a per server basis to client UIDs or nobody if no mapping
exists. This is helpful when Unix extensions are negotiated to
allow better permission checking when UIDs differ on the server
and client. Add new protocol request to the CIFS protocol
standard for asking the server for the corresponding name of a
particular uid.
exists. Also better integration with winbind for resolving SID owners
n) DOS attrs - returned as pseudo-xattr in Samba format (check VFAT and NTFS for this too)
k) Add tools to take advantage of more smb3 specific ioctls and features
o) mount check for unmatched uids
l) encrypted file support
p) Add support for new vfs entry point for fallocate
m) improved stats gathering, tools (perhaps integration with nfsometer?)
q) Add tools to take advantage of cifs/smb3 specific ioctls and features
such as "CopyChunk" (fast server side file copy)
n) allow setting more NTFS/SMB3 file attributes remotely (currently limited to compressed
file attribute via chflags) and improve user space tools for managing and
viewing them.
r) encrypted file support
o) mount helper GUI (to simplify the various configuration options on mount)
s) improved stats gathering, tools (perhaps integration with nfsometer?)
p) autonegotiation of dialects (offering more than one dialect ie SMB3.02,
SMB3, SMB2.1 not just SMB3).
t) allow setting more NTFS/SMB3 file attributes remotely (currently limited to compressed
file attribute via chflags)
q) Allow mount.cifs to be more verbose in reporting errors with dialect
or unsupported feature errors.
u) mount helper GUI (to simplify the various configuration options on mount)
r) updating cifs documentation, and user guid.
s) Addressing bugs found by running a broader set of xfstests in standard
file system xfstest suite.
t) split cifs and smb3 support into separate modules so legacy (and less
secure) CIFS dialect can be disabled in environments that don't need it
and simplify the code.
u) Finish up SMB3.1.1 dialect support
v) POSIX Extensions for SMB3.1.1
KNOWN BUGS
====================================

View File

@ -1,24 +1,28 @@
This is the client VFS module for the Common Internet File System
(CIFS) protocol which is the successor to the Server Message Block
This is the client VFS module for the SMB3 NAS protocol as well
older dialects such as the Common Internet File System (CIFS)
protocol which was the successor to the Server Message Block
(SMB) protocol, the native file sharing mechanism for most early
PC operating systems. New and improved versions of CIFS are now
called SMB2 and SMB3. These dialects are also supported by the
CIFS VFS module. CIFS is fully supported by network
file servers such as Windows 2000, 2003, 2008 and 2012
file servers such as Windows 2000, 2003, 2008, 2012 and 2016
as well by Samba (which provides excellent CIFS
server support for Linux and many other operating systems), so
server support for Linux and many other operating systems), Apple
systems, as well as most Network Attached Storage vendors, so
this network filesystem client can mount to a wide variety of
servers.
The intent of this module is to provide the most advanced network
file system function for CIFS compliant servers, including better
POSIX compliance, secure per-user session establishment, high
performance safe distributed caching (oplock), optional packet
file system function for SMB3 compliant servers, including advanced
security features, excellent parallelized high performance i/o, better
POSIX compliance, secure per-user session establishment, encryption,
high performance safe distributed caching (leases/oplocks), optional packet
signing, large files, Unicode support and other internationalization
improvements. Since both Samba server and this filesystem client support
the CIFS Unix extensions, the combination can provide a reasonable
alternative to NFSv4 for fileserving in some Linux to Linux environments,
not just in Linux to Windows environments.
the CIFS Unix extensions (and in the future SMB3 POSIX extensions),
the combination can provide a reasonable alternative to other network and
cluster file systems for fileserving in some Linux to Linux environments,
not just in Linux to Windows (or Linux to Mac) environments.
This filesystem has an mount utility (mount.cifs) that can be obtained from

View File

@ -149,5 +149,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg);
extern const struct export_operations cifs_export_ops;
#endif /* CONFIG_CIFS_NFSD_EXPORT */
#define CIFS_VERSION "2.09"
#define CIFS_VERSION "2.10"
#endif /* _CIFSFS_H */

View File

@ -188,6 +188,8 @@ enum smb_version {
#ifdef CONFIG_CIFS_SMB311
Smb_311,
#endif /* SMB311 */
Smb_3any,
Smb_default,
Smb_version_err
};
@ -1701,6 +1703,10 @@ extern struct smb_version_values smb20_values;
#define SMB21_VERSION_STRING "2.1"
extern struct smb_version_operations smb21_operations;
extern struct smb_version_values smb21_values;
#define SMBDEFAULT_VERSION_STRING "default"
extern struct smb_version_values smbdefault_values;
#define SMB3ANY_VERSION_STRING "3"
extern struct smb_version_values smb3any_values;
#define SMB30_VERSION_STRING "3.0"
extern struct smb_version_operations smb30_operations;
extern struct smb_version_values smb30_values;

View File

@ -301,6 +301,8 @@ static const match_table_t cifs_smb_version_tokens = {
{ Smb_311, SMB311_VERSION_STRING },
{ Smb_311, ALT_SMB311_VERSION_STRING },
#endif /* SMB311 */
{ Smb_3any, SMB3ANY_VERSION_STRING },
{ Smb_default, SMBDEFAULT_VERSION_STRING },
{ Smb_version_err, NULL }
};
@ -1148,6 +1150,14 @@ cifs_parse_smb_version(char *value, struct smb_vol *vol)
vol->vals = &smb311_values;
break;
#endif /* SMB311 */
case Smb_3any:
vol->ops = &smb30_operations; /* currently identical with 3.0 */
vol->vals = &smb3any_values;
break;
case Smb_default:
vol->ops = &smb30_operations; /* currently identical with 3.0 */
vol->vals = &smbdefault_values;
break;
default:
cifs_dbg(VFS, "Unknown vers= option specified: %s\n", value);
return 1;
@ -1274,9 +1284,9 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
vol->actimeo = CIFS_DEF_ACTIMEO;
/* FIXME: add autonegotiation for SMB3 or later rather than just SMB3 */
vol->ops = &smb30_operations; /* both secure and accepted widely */
vol->vals = &smb30_values;
/* offer SMB2.1 and later (SMB3 etc). Secure and widely accepted */
vol->ops = &smb30_operations;
vol->vals = &smbdefault_values;
vol->echo_interval = SMB_ECHO_INTERVAL_DEFAULT;
@ -1988,11 +1998,10 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
if (got_version == false)
pr_warn("No dialect specified on mount. Default has changed to "
"a more secure dialect, SMB3 (vers=3.0), from CIFS "
"a more secure dialect, SMB2.1 or later (e.g. SMB3), from CIFS "
"(SMB1). To use the less secure SMB1 dialect to access "
"old servers which do not support SMB3 specify vers=1.0"
" on mount. For somewhat newer servers such as Windows "
"7 try vers=2.1.\n");
"old servers which do not support SMB3 (or SMB2.1) specify vers=1.0"
" on mount.\n");
kfree(mountdata_copy);
return 0;
@ -2133,6 +2142,7 @@ static int match_server(struct TCP_Server_Info *server, struct smb_vol *vol)
if (vol->nosharesock)
return 0;
/* BB update this for smb3any and default case */
if ((server->vals != vol->vals) || (server->ops != vol->ops))
return 0;

View File

@ -426,6 +426,7 @@ smb2_query_file_info(const unsigned int xid, struct cifs_tcon *tcon,
return rc;
}
#ifdef CONFIG_CIFS_XATTR
static ssize_t
move_smb2_ea_to_cifs(char *dst, size_t dst_size,
struct smb2_file_full_ea_info *src, size_t src_size,
@ -613,6 +614,7 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
return rc;
}
#endif
static bool
smb2_can_echo(struct TCP_Server_Info *server)
@ -3110,6 +3112,46 @@ struct smb_version_values smb21_values = {
.create_lease_size = sizeof(struct create_lease),
};
struct smb_version_values smb3any_values = {
.version_string = SMB3ANY_VERSION_STRING,
.protocol_id = SMB302_PROT_ID, /* doesn't matter, send protocol array */
.req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION,
.large_lock_type = 0,
.exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
.shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
.unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
.header_size = sizeof(struct smb2_hdr),
.max_header_size = MAX_SMB2_HDR_SIZE,
.read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
.lock_cmd = SMB2_LOCK,
.cap_unix = 0,
.cap_nt_find = SMB2_NT_FIND,
.cap_large_files = SMB2_LARGE_FILES,
.signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED,
.signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED,
.create_lease_size = sizeof(struct create_lease_v2),
};
struct smb_version_values smbdefault_values = {
.version_string = SMBDEFAULT_VERSION_STRING,
.protocol_id = SMB302_PROT_ID, /* doesn't matter, send protocol array */
.req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION,
.large_lock_type = 0,
.exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
.shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
.unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
.header_size = sizeof(struct smb2_hdr),
.max_header_size = MAX_SMB2_HDR_SIZE,
.read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
.lock_cmd = SMB2_LOCK,
.cap_unix = 0,
.cap_nt_find = SMB2_NT_FIND,
.cap_large_files = SMB2_LARGE_FILES,
.signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED,
.signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED,
.create_lease_size = sizeof(struct create_lease_v2),
};
struct smb_version_values smb30_values = {
.version_string = SMB30_VERSION_STRING,
.protocol_id = SMB30_PROT_ID,

View File

@ -491,10 +491,25 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses)
req->hdr.sync_hdr.SessionId = 0;
req->Dialects[0] = cpu_to_le16(ses->server->vals->protocol_id);
req->DialectCount = cpu_to_le16(1); /* One vers= at a time for now */
inc_rfc1001_len(req, 2);
if (strcmp(ses->server->vals->version_string,
SMB3ANY_VERSION_STRING) == 0) {
req->Dialects[0] = cpu_to_le16(SMB30_PROT_ID);
req->Dialects[1] = cpu_to_le16(SMB302_PROT_ID);
req->DialectCount = cpu_to_le16(2);
inc_rfc1001_len(req, 4);
} else if (strcmp(ses->server->vals->version_string,
SMBDEFAULT_VERSION_STRING) == 0) {
req->Dialects[0] = cpu_to_le16(SMB21_PROT_ID);
req->Dialects[1] = cpu_to_le16(SMB30_PROT_ID);
req->Dialects[2] = cpu_to_le16(SMB302_PROT_ID);
req->DialectCount = cpu_to_le16(3);
inc_rfc1001_len(req, 6);
} else {
/* otherwise send specific dialect */
req->Dialects[0] = cpu_to_le16(ses->server->vals->protocol_id);
req->DialectCount = cpu_to_le16(1);
inc_rfc1001_len(req, 2);
}
/* only one of SMB2 signing flags may be set in SMB2 request */
if (ses->sign)
@ -528,16 +543,42 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses)
*/
if (rc == -EOPNOTSUPP) {
cifs_dbg(VFS, "Dialect not supported by server. Consider "
"specifying vers=1.0 or vers=2.1 on mount for accessing"
"specifying vers=1.0 or vers=2.0 on mount for accessing"
" older servers\n");
goto neg_exit;
} else if (rc != 0)
goto neg_exit;
if (strcmp(ses->server->vals->version_string,
SMB3ANY_VERSION_STRING) == 0) {
if (rsp->DialectRevision == cpu_to_le16(SMB20_PROT_ID)) {
cifs_dbg(VFS,
"SMB2 dialect returned but not requested\n");
return -EIO;
} else if (rsp->DialectRevision == cpu_to_le16(SMB21_PROT_ID)) {
cifs_dbg(VFS,
"SMB2.1 dialect returned but not requested\n");
return -EIO;
}
} else if (strcmp(ses->server->vals->version_string,
SMBDEFAULT_VERSION_STRING) == 0) {
if (rsp->DialectRevision == cpu_to_le16(SMB20_PROT_ID)) {
cifs_dbg(VFS,
"SMB2 dialect returned but not requested\n");
return -EIO;
} else if (rsp->DialectRevision == cpu_to_le16(SMB21_PROT_ID)) {
/* ops set to 3.0 by default for default so update */
ses->server->ops = &smb21_operations;
}
} else if (rsp->DialectRevision != ses->server->vals->protocol_id) {
/* if requested single dialect ensure returned dialect matched */
cifs_dbg(VFS, "Illegal 0x%x dialect returned: not requested\n",
cpu_to_le16(rsp->DialectRevision));
return -EIO;
}
cifs_dbg(FYI, "mode 0x%x\n", rsp->SecurityMode);
/* BB we may eventually want to match the negotiated vs. requested
dialect, even though we are only requesting one at a time */
if (rsp->DialectRevision == cpu_to_le16(SMB20_PROT_ID))
cifs_dbg(FYI, "negotiated smb2.0 dialect\n");
else if (rsp->DialectRevision == cpu_to_le16(SMB21_PROT_ID))
@ -558,6 +599,8 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses)
}
server->dialect = le16_to_cpu(rsp->DialectRevision);
/* BB: add check that dialect was valid given dialect(s) we asked for */
/* SMB2 only has an extended negflavor */
server->negflavor = CIFS_NEGFLAVOR_EXTENDED;
/* set it to the maximum buffer size value we can send with 1 credit */
@ -606,6 +649,7 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon)
struct validate_negotiate_info_req vneg_inbuf;
struct validate_negotiate_info_rsp *pneg_rsp;
u32 rsplen;
u32 inbuflen; /* max of 4 dialects */
cifs_dbg(FYI, "validate negotiate\n");
@ -634,9 +678,30 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon)
else
vneg_inbuf.SecurityMode = 0;
vneg_inbuf.DialectCount = cpu_to_le16(1);
vneg_inbuf.Dialects[0] =
cpu_to_le16(tcon->ses->server->vals->protocol_id);
if (strcmp(tcon->ses->server->vals->version_string,
SMB3ANY_VERSION_STRING) == 0) {
vneg_inbuf.Dialects[0] = cpu_to_le16(SMB30_PROT_ID);
vneg_inbuf.Dialects[1] = cpu_to_le16(SMB302_PROT_ID);
vneg_inbuf.DialectCount = cpu_to_le16(2);
/* structure is big enough for 3 dialects, sending only 2 */
inbuflen = sizeof(struct validate_negotiate_info_req) - 2;
} else if (strcmp(tcon->ses->server->vals->version_string,
SMBDEFAULT_VERSION_STRING) == 0) {
vneg_inbuf.Dialects[0] = cpu_to_le16(SMB21_PROT_ID);
vneg_inbuf.Dialects[1] = cpu_to_le16(SMB30_PROT_ID);
vneg_inbuf.Dialects[2] = cpu_to_le16(SMB302_PROT_ID);
vneg_inbuf.DialectCount = cpu_to_le16(3);
/* structure is big enough for 3 dialects */
inbuflen = sizeof(struct validate_negotiate_info_req);
} else {
/* otherwise specific dialect was requested */
vneg_inbuf.Dialects[0] =
cpu_to_le16(tcon->ses->server->vals->protocol_id);
vneg_inbuf.DialectCount = cpu_to_le16(1);
/* structure is big enough for 3 dialects, sending only 1 */
inbuflen = sizeof(struct validate_negotiate_info_req) - 4;
}
rc = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID,
FSCTL_VALIDATE_NEGOTIATE_INFO, true /* is_fsctl */,
@ -1634,7 +1699,7 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
struct cifs_tcon *tcon = oparms->tcon;
struct cifs_ses *ses = tcon->ses;
struct kvec iov[4];
struct kvec rsp_iov;
struct kvec rsp_iov = {NULL, 0};
int resp_buftype;
int uni_path_len;
__le16 *copy_path = NULL;
@ -1763,7 +1828,7 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
if (rc != 0) {
cifs_stats_fail_inc(tcon, SMB2_CREATE_HE);
if (err_buf)
if (err_buf && rsp)
*err_buf = kmemdup(rsp, get_rfc1002_length(rsp) + 4,
GFP_KERNEL);
goto creat_exit;

View File

@ -716,7 +716,7 @@ struct validate_negotiate_info_req {
__u8 Guid[SMB2_CLIENT_GUID_SIZE];
__le16 SecurityMode;
__le16 DialectCount;
__le16 Dialects[1]; /* dialect (someday maybe list) client asked for */
__le16 Dialects[3]; /* BB expand this if autonegotiate > 3 dialects */
} __packed;
struct validate_negotiate_info_rsp {