Commit Graph

364 Commits

Author SHA1 Message Date
Linus Torvalds 7c9e41e0ef 10 CIFS/SMB3 changesets including some important multichannel fixes, as well as support for handle leases (deferred close) and shutdown support
-----BEGIN PGP SIGNATURE-----
 
 iQGzBAABCgAdFiEE6fsu8pdIjtWE/DpLiiy9cAdyT1EFAmCSKIIACgkQiiy9cAdy
 T1F+Hgv+L3NkOFwMvBgGjHP9b+Lkv/YWGKeJkLwQW1xqoHIUHn0/+C5+9ScJGBZc
 WVuzp4pqEIgv4my4UQiyqVwzcmz4BqY2KTDJzBYtqANt6pVp1w6YtC2GplgJE3J2
 qoQh1RwZaqSXfjcoPSRnv5EiSF6DbHlBUhPMd53qOE9pwaf/38i9/M3d9G7EIB8h
 rRNmpGtFuzBHdtGQ2b+4+8ftCIpEBDu/OXcA6QXMUMcvKGaruU39NOxBuW6a/VO5
 9P47Nsof3dlN758uesoQT2VMEc0pcpwAs9BwOkinfXWGUyNqJmbPNvddIOlaP/dv
 vG58n/+JqvWUKgEnrNk5h+wD7wmXpgxpQ523sD5k6bID1hc+vh4lXf+O+iltbYtc
 1ce9ITglSVxA7z4qwFWhtawBy1j1YyvltTAGvhnzdtKZLRk6e5AYIFOUn9O+AMJw
 Eofk4lD0kNTdXyMkveGluRMBXrOzKMdmfw5FW/9hObYgebEGpTQkGyIMpaStraZM
 8hDNAGTk
 =BFOj
 -----END PGP SIGNATURE-----

Merge tag '5.13-rc-smb3-part2' of git://git.samba.org/sfrench/cifs-2.6

Pull cifs updates from Steve French:
 "Ten CIFS/SMB3 changes - including two marked for stable - including
  some important multichannel fixes, as well as support for handle
  leases (deferred close) and shutdown support:

   - some important multichannel fixes

   - support for handle leases (deferred close)

   - shutdown support (which is also helpful since it enables multiple
     xfstests)

   - enable negotiating stronger encryption by default (GCM256)

   - improve wireshark debugging by allowing more options for root to
     dump decryption keys

  SambaXP and the SMB3 Plugfest test event are going on now so I am
  expecting more patches over the next few days due to extra testing
  (including more multichannel fixes)"

* tag '5.13-rc-smb3-part2' of git://git.samba.org/sfrench/cifs-2.6:
  fs/cifs: Fix resource leak
  Cifs: Fix kernel oops caused by deferred close for files.
  cifs: fix regression when mounting shares with prefix paths
  cifs: use echo_interval even when connection not ready.
  cifs: detect dead connections only when echoes are enabled.
  smb3.1.1: allow dumping keys for multiuser mounts
  smb3.1.1: allow dumping GCM256 keys to improve debugging of encrypted shares
  cifs: add shutdown support
  cifs: Deferred close for files
  smb3.1.1: enable negotiating stronger encryption by default
2021-05-05 13:37:07 -07:00
Rohith Surabattula 78c09634f7 Cifs: Fix kernel oops caused by deferred close for files.
Fix regression issue caused by deferred close for files.

Signed-off-by: Rohith Surabattula <rohiths@microsoft.com>
Reviewed-by: Shyam Prasad N <sprasad@microsoft.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
2021-05-04 11:53:15 -05:00
Rohith Surabattula c3f207ab29 cifs: Deferred close for files
When file is closed, SMB2 close request is not sent to server
immediately and is deferred for acregmax defined interval. When file is
reopened by same process for read or write, the file handle
is reused if an oplock is held.

When client receives a oplock/lease break, file is closed immediately
if reference count is zero, else oplock is downgraded.

Signed-off-by: Rohith Surabattula <rohiths@microsoft.com>
Reviewed-by: Shyam Prasad N <sprasad@microsoft.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
2021-05-03 11:20:35 -05:00
Linus Torvalds d1466bc583 Merge branch 'work.inode-type-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs inode type handling updates from Al Viro:
 "We should never change the type bits of ->i_mode or the method tables
  (->i_op and ->i_fop) of a live inode.

  Unfortunately, not all filesystems took care to prevent that"

* 'work.inode-type-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  spufs: fix bogosity in S_ISGID handling
  9p: missing chunk of "fs/9p: Don't update file type when updating file attributes"
  openpromfs: don't do unlock_new_inode() until the new inode is set up
  hostfs_mknod(): don't bother with init_special_inode()
  cifs: have cifs_fattr_to_inode() refuse to change type on live inode
  cifs: have ->mkdir() handle race with another client sanely
  do_cifs_create(): don't set ->i_mode of something we had not created
  gfs2: be careful with inode refresh
  ocfs2_inode_lock_update(): make sure we don't change the type bits of i_mode
  orangefs_inode_is_stale(): i_mode type bits do *not* form a bitmap...
  vboxsf: don't allow to change the inode type
  afs: Fix updating of i_mode due to 3rd party change
  ceph: don't allow type or device number to change on non-I_NEW inodes
  ceph: fix up error handling with snapdirs
  new helper: inode_wrong_type()
2021-04-27 10:57:42 -07:00
Al Viro f6a9bc336b cifs: allocate buffer in the caller of build_path_from_dentry()
build_path_from_dentry() open-codes dentry_path_raw().  The reason
we can't use dentry_path_raw() in there (and postprocess the
result as needed) is that the callers of build_path_from_dentry()
expect that the object to be freed on cleanup and the string to
be used are at the same address.  That's painful, since the path
is naturally built end-to-beginning - we start at the leaf and
go through the ancestors, accumulating the pathname.

Life would be easier if we left the buffer allocation to callers.
It wouldn't be exact-sized buffer, but none of the callers keep
the result for long - it's always freed before the caller returns.
So there's no need to do exact-sized allocation; better use
__getname()/__putname(), same as we do for pathname arguments
of syscalls.  What's more, there's no need to do allocation under
spinlocks, so GFP_ATOMIC is not needed.

Next patch will replace the open-coded dentry_path_raw() (in
build_path_from_dentry_optional_prefix()) with calling the real
thing.  This patch only introduces wrappers for allocating/freeing
the buffers and switches to new calling conventions:
	build_path_from_dentry(dentry, buf)
expects buf to be address of a page-sized object or NULL,
return value is a pathname built inside that buffer on success,
ERR_PTR(-ENOMEM) if buf is NULL and ERR_PTR(-ENAMETOOLONG) if
the pathname won't fit into page.  Note that we don't need to
check for failure when allocating the buffer in the caller -
build_path_from_dentry() will do the right thing.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Steve French <stfrench@microsoft.com>
2021-04-25 16:28:23 -05:00
Al Viro 8e33cf20ce cifs: make build_path_from_dentry() return const char *
... and adjust the callers.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Steve French <stfrench@microsoft.com>
2021-04-25 16:28:23 -05:00
Al Viro f6f1f17907 cifs: constify pathname arguments in a bunch of helpers
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Steve French <stfrench@microsoft.com>
2021-04-25 16:28:23 -05:00
Aurelien Aptel ec4e4862a9 cifs: remove old dead code
While reviewing a patch clarifying locks and locking hierarchy I
realized some locks were unused.

This commit removes old data and code that isn't actually used
anywhere, or hidden in ifdefs which cannot be enabled from the kernel
config.

* The uid/gid trees and associated locks are left-overs from when
  uid/sid mapping had an extra caching layer on top of the keyring and
  are now unused.
  See commit faa65f07d2 ("cifs: simplify id_to_sid and sid_to_id mapping code")
  from 2012.

* cifs_oplock_break_ops is a left-over from when slow_work was remplaced
  by regular workqueue and is now unused.
  See commit 9b64697246 ("cifs: use workqueue instead of slow-work")
  from 2010.

* CIFSSMBSetAttrLegacy is SMB1 cruft dealing with some legacy
  NT4/Win9x behaviour.

* Remove CONFIG_CIFS_DNOTIFY_EXPERIMENTAL left-overs. This was already
  partially removed in 392e1c5dc9 ("cifs: rename and clarify CIFS_ASYNC_OP and CIFS_NO_RESP")
  from 2019. Kill it completely.

* Another candidate that was considered but spared is
  CONFIG_CIFS_NFSD_EXPORT which has an empty implementation and cannot
  be enabled by a config option (although it is listed but disabled with
  "BROKEN" as a dep). It's unclear whether this could even function
  today in its current form but it has it's own .c file and Kconfig
  entry which is a bit more involved to remove and might make a come
  back?

Signed-off-by: Aurelien Aptel <aaptel@suse.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
2021-04-25 16:28:22 -05:00
Al Viro 4d66952a20 cifs: have cifs_fattr_to_inode() refuse to change type on live inode
... instead of trying to do that in the callers (and missing some,
at that)

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2021-03-12 22:15:20 -05:00
David Howells cf0604a686 cifs: use discard iterator to discard unneeded network data more efficiently
The iterator, ITER_DISCARD, that can only be used in READ mode and
just discards any data copied to it, was added to allow a network
filesystem to discard any unwanted data sent by a server.
Convert cifs_discard_from_socket() to use this.

Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
2021-02-25 19:08:06 -06:00
Ronnie Sahlberg 0d4873f9aa cifs: fix dfs domain referrals
The new mount API requires additional changes to how DFS
is handled. Additional testing of DFS uncovered problems
with domain based DFS referrals (a follow on patch addresses
DFS links) which this patch addresses.

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
Signed-off-by: Paulo Alcantara (SUSE) <pc@cjr.nz>
Signed-off-by: Steve French <stfrench@microsoft.com>
2021-01-28 21:40:43 -06:00
Boris Protopopov 3970acf7dd SMB3: Add support for getting and setting SACLs
Add SYSTEM_SECURITY access flag and use with smb2 when opening
files for getting/setting SACLs. Add "system.cifs_ntsd_full"
extended attribute to allow user-space access to the functionality.
Avoid multiple server calls when setting owner, DACL, and SACL.

Signed-off-by: Boris Protopopov <pboris@amazon.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
2020-12-18 13:25:57 -06:00
Ronnie Sahlberg 51acd208bd cifs: remove ctx argument from cifs_setup_cifs_sb
Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
2020-12-14 09:26:30 -06:00
Ronnie Sahlberg 387ec58f33 cifs: simplify handling of cifs_sb/ctx->local_nls
Only load/unload local_nls from cifs_sb and just make the ctx
contain a pointer to cifs_sb->ctx.

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
2020-12-14 09:26:30 -06:00
Ronnie Sahlberg c741cba2cd cifs: move cifs_cleanup_volume_info[_content] to fs_context.c
and rename it to smb3_cleanup_fs_context[_content]

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
2020-12-14 09:26:30 -06:00
Samuel Cabrero e73a42e07a cifs: Make extract_sharename function public
Move the function to misc.c

Signed-off-by: Samuel Cabrero <scabrero@suse.de>
Reviewed-by: Aurelien Aptel <aaptel@suse.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
2020-12-14 09:16:22 -06:00
Samuel Cabrero a87e67254b cifs: Make extract_hostname function public
Move the function to misc.c and give it a public header.

Signed-off-by: Samuel Cabrero <scabrero@suse.de>
Reviewed-by: Aurelien Aptel <aaptel@suse.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
2020-12-14 09:16:22 -06:00
Ronnie Sahlberg 4deb075985 cifs: remove the devname argument to cifs_compose_mount_options
none of the callers use this argument any more.

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
2020-12-13 19:12:07 -06:00
Ronnie Sahlberg 24e0a1eff9 cifs: switch to new mount api
See Documentation/filesystems/mount_api.rst for details on new mount API

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
2020-12-13 19:12:07 -06:00
Ronnie Sahlberg 66e7b09c73 cifs: move cifs_parse_devname to fs_context.c
Also rename the function from cifs_ to smb3_

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
2020-12-13 19:12:07 -06:00
Ronnie Sahlberg 3fa1c6d1b8 cifs: rename smb_vol as smb3_fs_context and move it to fs_context.h
Harmonize and change all such variables to 'ctx', where possible.
No changes to actual logic.

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
2020-12-13 19:12:07 -06:00
Shyam Prasad N 0f22053e81 cifs: Fix unix perm bits to cifsacl conversion for "other" bits.
With the "cifsacl" mount option, the mode bits set on the file/dir
is converted to corresponding ACEs in DACL. However, only the
ALLOWED ACEs were being set for "owner" and "group" SIDs. Since
owner is a subset of group, and group is a subset of
everyone/world SID, in order to properly emulate unix perm groups,
we need to add DENIED ACEs. If we don't do that, "owner" and "group"
SIDs could get more access rights than they should. Which is what
was happening. This fixes it.

We try to keep the "preferred" order of ACEs, i.e. DENYs followed
by ALLOWs. However, for a small subset of cases we cannot
maintain the preferred order. In that case, we'll end up with the
DENY ACE for group after the ALLOW for the owner.

If owner SID == group SID, use the more restrictive
among the two perm bits and convert them to ACEs.

Also, for reverse mapping, i.e. to convert ACL to unix perm bits,
for the "others" bits, we needed to add the masked bits of the
owner and group masks to others mask.

Updated version of patch fixes a problem noted by the kernel
test robot.

Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Shyam Prasad N <sprasad@microsoft.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
2020-12-13 19:12:07 -06:00
Steve French 9934430e21 SMB3.1.1: Fix ids returned in POSIX query dir
We were setting the uid/gid to the default in each dir entry
in the parsing of the POSIX query dir response, rather
than attempting to map the user and group SIDs returned by
the server to well known SIDs (or upcall if not found).

CC: Stable <stable@vger.kernel.org>
Reviewed-by: Aurelien Aptel <aaptel@suse.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
2020-10-20 11:51:24 -05:00
Paulo Alcantara 7548e1da8d cifs: handle RESP_GET_DFS_REFERRAL.PathConsumed in reconnect
Use PathConsumed field when parsing prefixes of referral paths that
either match a cache entry or are a complete prefix path of an
existing entry.

Signed-off-by: Paulo Alcantara (SUSE) <pc@cjr.nz>
Reviewed-by: Aurelien Aptel <aaptel@suse.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
2020-08-02 18:00:26 -05:00
Stefan Metzmacher 565674d613 cifs: merge __{cifs,smb2}_reconnect[_tcon]() into cifs_tree_connect()
They were identical execpt to CIFSTCon() vs. SMB2_tcon().
These are also available via ops->tree_connect().

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Signed-off-by: Paulo Alcantara (SUSE) <pc@cjr.nz>
Reviewed-by: Aurelien Aptel <aaptel@suse.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
2020-08-02 18:00:26 -05:00
Ronnie Sahlberg 8e408fc9fd cifs: smb1: Try failing back to SetFileInfo if SetPathInfo fails
RHBZ 1145308

Some very old server may not support SetPathInfo to adjust the timestamps
of directories. For these servers, try to open the directory and use SetFileInfo.

Minor correction to patch included that was
Reported-by: kernel test robot <lkp@intel.com>

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
Tested-by: Kenneth D'souza <kdsouza@redhat.com>
2020-08-02 18:00:25 -05:00
Roberto Bergantinos Corpas a3713ec3d7 cifs`: handle ERRBaduid for SMB1
If server returns ERRBaduid but does not reset transport connection,
we'll keep sending command with a non-valid UID for the server as long
as transport is healthy, without actually recovering. This have been
observed on the field.

This patch adds ERRBaduid handling so that we set CifsNeedReconnect.

map_and_check_smb_error() can be modified to extend use cases.

Signed-off-by: Roberto Bergantinos Corpas <rbergant@redhat.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
Reviewed-by: Ronnie Sahlberg <lsahlber@redhat.com>
2020-08-02 18:00:25 -05:00
Steve French 975221eca5 smb3: allow uid and gid owners to be set on create with idsfromsid mount option
Currently idsfromsid mount option allows querying owner information from the
special sids used to represent POSIX uids and gids but needed changes to
populate the security descriptor context with the owner information when
idsfromsid mount option was used.

Signed-off-by: Steve French <stfrench@microsoft.com>
Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
2020-06-12 13:21:15 -05:00
Steve French 6a5f6592a0 SMB311: Add support for query info using posix extensions (level 100)
Adds support for better query info on dentry revalidation (using
the SMB3.1.1 POSIX extensions level 100).  Followon patch will
add support for translating the UID/GID from the SID and also
will add support for using the posix query info on lookup.

Signed-off-by: Steve French <stfrench@microsoft.com>
Reviewed-by: Ronnie Sahlberg <lsahlber@redhat.com>
Reviewed-by: Aurelien Aptel <aaptel@suse.com>
2020-06-12 06:20:38 -05:00
Aurelien Aptel 2f58967979 cifs: multichannel: try to rebind when reconnecting a channel
first steps in trying to make channels properly reconnect.

* add cifs_ses_find_chan() function to find the enclosing cifs_chan
  struct it belongs to
* while we have the session lock and are redoing negprot and
  sess.setup in smb2_reconnect() redo the binding of channels.

Signed-off-by: Aurelien Aptel <aaptel@suse.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
2020-06-04 13:50:55 -05:00
Aurelien Aptel 352d96f3ac cifs: multichannel: move channel selection above transport layer
Move the channel (TCP_Server_Info*) selection from the tranport
layer to higher in the call stack so that:

- credit handling is done with the server that will actually be used
  to send.
  * ->wait_mtu_credit
  * ->set_credits / set_credits
  * ->add_credits / add_credits
  * add_credits_and_wake_if

- potential reconnection (smb2_reconnect) done when initializing a
  request is checked and done with the server that will actually be
  used to send.

To do this:

- remove the cifs_pick_channel() call out of compound_send_recv()

- select channel and pass it down by adding a cifs_pick_channel(ses)
  call in:
  - smb311_posix_mkdir
  - SMB2_open
  - SMB2_ioctl
  - __SMB2_close
  - query_info
  - SMB2_change_notify
  - SMB2_flush
  - smb2_async_readv  (if none provided in context param)
  - SMB2_read         (if none provided in context param)
  - smb2_async_writev (if none provided in context param)
  - SMB2_write        (if none provided in context param)
  - SMB2_query_directory
  - send_set_info
  - SMB2_oplock_break
  - SMB311_posix_qfs_info
  - SMB2_QFS_info
  - SMB2_QFS_attr
  - smb2_lockv
  - SMB2_lease_break
    - smb2_compound_op
  - smb2_set_ea
  - smb2_ioctl_query_info
  - smb2_query_dir_first
  - smb2_query_info_comound
  - smb2_query_symlink
  - cifs_writepages
  - cifs_write_from_iter
  - cifs_send_async_read
  - cifs_read
  - cifs_readpages

- add TCP_Server_Info *server param argument to:
  - cifs_send_recv
  - compound_send_recv
  - SMB2_open_init
  - SMB2_query_info_init
  - SMB2_set_info_init
  - SMB2_close_init
  - SMB2_ioctl_init
  - smb2_iotcl_req_init
  - SMB2_query_directory_init
  - SMB2_notify_init
  - SMB2_flush_init
  - build_qfs_info_req
  - smb2_hdr_assemble
  - smb2_reconnect
  - fill_small_buf
  - smb2_plain_req_init
  - __smb2_plain_req_init

The read/write codepath is different than the rest as it is using
pages, io iterators and async calls. To deal with those we add a
server pointer in the cifs_writedata/cifs_readdata/cifs_io_parms
context struct and set it in:

- cifs_writepages      (wdata)
- cifs_write_from_iter (wdata)
- cifs_readpages       (rdata)
- cifs_send_async_read (rdata)

The [rw]data->server pointer is eventually copied to
cifs_io_parms->server to pass it down to SMB2_read/SMB2_write.
If SMB2_read/SMB2_write is called from a different place that doesn't
set the server field it will pick a channel.

Some places do not pick a channel and just use ses->server or
cifs_ses_server(ses). All cifs_ses_server(ses) calls are in codepaths
involving negprot/sess.setup.

- SMB2_negotiate         (binding channel)
- SMB2_sess_alloc_buffer (binding channel)
- SMB2_echo              (uses provided one)
- SMB2_logoff            (uses master)
- SMB2_tdis              (uses master)

(list not exhaustive)

Signed-off-by: Aurelien Aptel <aaptel@suse.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
2020-06-04 13:50:55 -05:00
Aurelien Aptel 5f68ea4aa9 cifs: multichannel: move channel selection in function
This commit moves channel picking code in separate function.

Signed-off-by: Aurelien Aptel <aaptel@suse.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
2020-06-02 09:58:41 -05:00
Joe Perches a0a3036b81 cifs: Standardize logging output
Use pr_fmt to standardize all logging for fs/cifs.

Some logging output had no CIFS: specific prefix.

Now all output has one of three prefixes:

o CIFS:
o CIFS: VFS:
o Root-CIFS:

Miscellanea:

o Convert printks to pr_<level>
o Neaten macro definitions
o Remove embedded CIFS: prefixes from formats
o Convert "illegal" to "invalid"
o Coalesce formats
o Add missing '\n' format terminations
o Consolidate multiple cifs_dbg continuations into single calls
o More consistent use of upper case first word output logging
o Multiline statement argument alignment and wrapping

Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
2020-06-01 00:10:18 -05:00
Paulo Alcantara e4af35fa55 cifs: handle hostnames that resolve to same ip in failover
In order to support reconnect to hostnames that resolve to same ip
address, besides relying on the currently set hostname to match DFS
targets, attempt to resolve the targets and then match their addresses
with the reconnected server ip address.

For instance, if we have two hostnames "FOO" and "BAR", and both
resolve to the same ip address, we would be able to handle failover in
DFS paths like

    \\FOO\dfs\link1 -> [ \BAZ\share2 (*), \BAR\share1 ]
    \\FOO\dfs\link2 -> [ \BAZ\share2 (*), \FOO\share1 ]

so when "BAZ" is no longer accessible, link1 and link2 would get
reconnected despite having different target hostnames.

Signed-off-by: Paulo Alcantara (SUSE) <pc@cjr.nz>
Reviewed-by: Aurelien Aptel <aaptel@suse.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
2020-06-01 00:10:18 -05:00
Paulo Alcantara (SUSE) bacd704a95 cifs: handle prefix paths in reconnect
For the case where we have a DFS path like below and we're currently
connected to targetA:

    //dfsroot/link -> //targetA/share/foo, //targetB/share/bar

after failover, we should make sure to update cifs_sb->prepath so the
next operations will use the new prefix path "/bar".

Besides, in order to simplify the use of different prefix paths,
enforce CIFS_MOUNT_USE_PREFIX_PATH for DFS mounts so we don't have to
revalidate the root dentry every time we set a new prefix path.

Signed-off-by: Paulo Alcantara (SUSE) <pc@cjr.nz>
Acked-by: Ronnie Sahlberg <lsahlber@redhat.com>
Reviewed-by: Aurelien Aptel <aaptel@suse.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
2020-03-22 22:49:09 -05:00
Aurelien Aptel 86f740f2ae cifs: fix rename() by ensuring source handle opened with DELETE bit
To rename a file in SMB2 we open it with the DELETE access and do a
special SetInfo on it. If the handle is missing the DELETE bit the
server will fail the SetInfo with STATUS_ACCESS_DENIED.

We currently try to reuse any existing opened handle we have with
cifs_get_writable_path(). That function looks for handles with WRITE
access but doesn't check for DELETE, making rename() fail if it finds
a handle to reuse. Simple reproducer below.

To select handles with the DELETE bit, this patch adds a flag argument
to cifs_get_writable_path() and find_writable_file() and the existing
'bool fsuid_only' argument is converted to a flag.

The cifsFileInfo struct only stores the UNIX open mode but not the
original SMB access flags. Since the DELETE bit is not mapped in that
mode, this patch stores the access mask in cifs_fid on file open,
which is accessible from cifsFileInfo.

Simple reproducer:

	#include <stdio.h>
	#include <stdlib.h>
	#include <sys/types.h>
	#include <sys/stat.h>
	#include <fcntl.h>
	#include <unistd.h>
	#define E(s) perror(s), exit(1)

	int main(int argc, char *argv[])
	{
		int fd, ret;
		if (argc != 3) {
			fprintf(stderr, "Usage: %s A B\n"
			"create&open A in write mode, "
			"rename A to B, close A\n", argv[0]);
			return 0;
		}

		fd = openat(AT_FDCWD, argv[1], O_WRONLY|O_CREAT|O_SYNC, 0666);
		if (fd == -1) E("openat()");

		ret = rename(argv[1], argv[2]);
		if (ret) E("rename()");

		ret = close(fd);
		if (ret) E("close()");

		return ret;
	}

$ gcc -o bugrename bugrename.c
$ ./bugrename /mnt/a /mnt/b
rename(): Permission denied

Fixes: 8de9e86c67 ("cifs: create a helper to find a writeable handle by path name")
CC: Stable <stable@vger.kernel.org>
Signed-off-by: Aurelien Aptel <aaptel@suse.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
Reviewed-by: Paulo Alcantara (SUSE) <pc@cjr.nz>
2020-02-24 14:20:38 -06:00
Steve French 87f93d82e0 smb3: fix problem with null cifs super block with previous patch
Add check for null cifs_sb to create_options helper

Signed-off-by: Steve French <stfrench@microsoft.com>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Reviewed-by: Aurelien Aptel <aaptel@suse.com>
2020-02-05 06:32:19 -06:00
Amir Goldstein 0f060936e4 SMB3: Backup intent flag missing from some more ops
When "backup intent" is requested on the mount (e.g. backupuid or
backupgid mount options), the corresponding flag was missing from
some of the operations.

Change all operations to use the macro cifs_create_options() to
set the backup intent flag if needed.

Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
2020-02-03 16:12:47 -06:00
Steve French 643fbceef4 smb3: fix default permissions on new files when mounting with modefromsid
When mounting with "modefromsid" mount parm most servers will require
that some default permissions are given to users in the ACL on newly
created files, files created with the new 'sd context' - when passing in
an sd context on create, permissions are not inherited from the parent
directory, so in addition to the ACE with the special SID which contains
the mode, we also must pass in an ACE allowing users to access the file
(GENERIC_ALL for authenticated users seemed like a reasonable default,
although later we could allow a mount option or config switch to make
it GENERIC_ALL for EVERYONE special sid).

CC: Stable <stable@vger.kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Reviewed-By: Ronnie Sahlberg <lsahlber@redhat.com>
Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
2020-01-26 19:24:17 -06:00
Ronnie Sahlberg 37478608f0 cifs: use compounding for open and first query-dir for readdir()
Combine the initial SMB2_Open and the first SMB2_Query_Directory in a compound.
This shaves one round-trip of each directory listing, changing it from 4 to 3
for small directories.

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
2020-01-26 19:24:16 -06:00
Steve French fdef665ba4 smb3: fix mode passed in on create for modetosid mount option
When using the special SID to store the mode bits in an ACE (See
http://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx)
which is enabled with mount parm "modefromsid" we were not
passing in the mode via SMB3 create (although chmod was enabled).
SMB3 create allows a security descriptor context to be passed
in (which is more atomic and thus preferable to setting the mode
bits after create via a setinfo).

This patch enables setting the mode bits on create when using
modefromsid mount option.  In addition it fixes an endian
error in the definition of the Control field flags in the SMB3
security descriptor. It also makes the ACE type of the special
SID better match the documentation (and behavior of servers
which use this to store mode bits in SMB3 ACLs).

Signed-off-by: Steve French <stfrench@microsoft.com>
Acked-by: Ronnie Sahlberg <lsahlber@redhat.com>
Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
2019-12-06 14:15:52 -06:00
Aurelien Aptel d70e9fa558 cifs: try opening channels after mounting
After doing mount() successfully we call cifs_try_adding_channels()
which will open as many channels as it can.

Channels are closed when the master session is closed.

The master connection becomes the first channel.

,-------------> global cifs_tcp_ses_list <-------------------------.
|                                                                  |
'- TCP_Server_Info  <-->  TCP_Server_Info  <-->  TCP_Server_Info <-'
      (master con)           (chan#1 con)         (chan#2 con)
      |      ^                    ^                    ^
      v      '--------------------|--------------------'
   cifs_ses                       |
   - chan_count = 3               |
   - chans[] ---------------------'
   - smb3signingkey[]
      (master signing key)

Note how channel connections don't have sessions. That's because
cifs_ses can only be part of one linked list (list_head are internal
to the elements).

For signing keys, each channel has its own signing key which must be
used only after the channel has been bound. While it's binding it must
use the master session signing key.

For encryption keys, since channel connections do not have sessions
attached we must now find matching session by looping over all sessions
in smb2_get_enc_key().

Each channel is opened like a regular server connection but at the
session setup request step it must set the
SMB2_SESSION_REQ_FLAG_BINDING flag and use the session id to bind to.

Finally, while sending in compound_send_recv() for requests that
aren't negprot, ses-setup or binding related, use a channel by cycling
through the available ones (round-robin).

Signed-off-by: Aurelien Aptel <aaptel@suse.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
2019-11-25 01:16:30 -06:00
Aurelien Aptel f780bd3fef cifs: add server param
As we get down to the transport layer, plenty of functions are passed
the session pointer and assume the transport to use is ses->server.

Instead we modify those functions to pass (ses, server) so that we
can decouple the session from the server.

Signed-off-by: Aurelien Aptel <aaptel@suse.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
2019-11-25 01:16:30 -06:00
Dave Wysochanski d46b0da7a3 cifs: Fix cifsInodeInfo lock_sem deadlock when reconnect occurs
There's a deadlock that is possible and can easily be seen with
a test where multiple readers open/read/close of the same file
and a disruption occurs causing reconnect.  The deadlock is due
a reader thread inside cifs_strict_readv calling down_read and
obtaining lock_sem, and then after reconnect inside
cifs_reopen_file calling down_read a second time.  If in
between the two down_read calls, a down_write comes from
another process, deadlock occurs.

        CPU0                    CPU1
        ----                    ----
cifs_strict_readv()
 down_read(&cifsi->lock_sem);
                               _cifsFileInfo_put
                                  OR
                               cifs_new_fileinfo
                                down_write(&cifsi->lock_sem);
cifs_reopen_file()
 down_read(&cifsi->lock_sem);

Fix the above by changing all down_write(lock_sem) calls to
down_write_trylock(lock_sem)/msleep() loop, which in turn
makes the second down_read call benign since it will never
block behind the writer while holding lock_sem.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
Suggested-by: Ronnie Sahlberg <lsahlber@redhat.com>
Reviewed--by: Ronnie Sahlberg <lsahlber@redhat.com>
Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
2019-10-24 21:35:04 -05:00
Steve French c3ca78e217 smb3: pass mode bits into create calls
We need to populate an ACL (security descriptor open context)
on file and directory correct.  This patch passes in the
mode.  Followon patch will build the open context and the
security descriptor (from the mode) that goes in the open
context.

Signed-off-by: Steve French <stfrench@microsoft.com>
Reviewed-by: Aurelien Aptel <aaptel@suse.com>
2019-09-26 02:06:42 -05:00
Ronnie Sahlberg 496902dc17 cifs: add a helper to find an existing readable handle to a file
and convert smb2_query_path_info() to use it.
This will eliminate the need for a SMB2_Create when we already have an
open handle that can be used. This will also prevent a oplock break
in case the other handle holds a lease.

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
2019-09-16 11:43:38 -05:00
Ronnie Sahlberg 8de9e86c67 cifs: create a helper to find a writeable handle by path name
rename() takes a path for old_file and in SMB2 we used to just create
a compound for create(old_path)/rename/close().
If we already have a writable handle we can avoid the create() and close()
altogether and just use the existing handle.

For this situation, as we avoid doing the create()
we also avoid triggering an oplock break for the existing handle.

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
2019-09-16 11:43:37 -05:00
Steve French e2f8fbfb8d cifs: get mode bits from special sid on stat
When mounting with "modefromsid" retrieve mode bits from
special SID (S-1-5-88-3) on stat.  Subsequent patch will fix
setattr (chmod) to save mode bits in S-1-5-88-3-<mode>

Note that when an ACE matching S-1-5-88-3 is not found, we
default the mode to an approximation based on the owner, group
and everyone permissions (as with the "cifsacl" mount option).

See See e.g.
    https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/hh509017(v=ws.10)

Signed-off-by: Steve French <stfrench@microsoft.com>
2019-09-16 11:43:37 -05:00
Ronnie Sahlberg 340625e618 cifs: replace various strncpy with strscpy and similar
Using strscpy is cleaner, and avoids some problems with
handling maximum length strings.  Linus noticed the
original problem and Aurelien pointed out some additional
problems. Fortunately most of this is SMB1 code (and
in particular the ASCII string handling older, which
is less common).

Reported-by: Linus Torvalds <torvalds@linux-foundation.org>
Reviewed-by: Aurelien Aptel <aaptel@suse.com>
Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
2019-08-27 17:25:12 -05:00
Paulo Alcantara (SUSE) 5072010ccf cifs: Fix DFS cache refresher for DFS links
As per MS-DFSC, when a DFS cache entry is expired and it is a DFS
link, then a new DFS referral must be sent to root server in order to
refresh the expired entry.

This patch ensures that all new DFS referrals for refreshing the cache
are sent to DFS root.

Signed-off-by: Paulo Alcantara (SUSE) <paulo@paulo.ac>
Signed-off-by: Steve French <stfrench@microsoft.com>
2019-05-07 23:24:54 -05:00