diff mbox series

[SMB3] check for and properly advertise directory lease support

Message ID CAH2r5mtRfg+1NyJ1VwqdL9J9_6zMP8F-1K61i6mEcaKNkttqvQ@mail.gmail.com
State New
Headers show
Series [SMB3] check for and properly advertise directory lease support | expand

Commit Message

Steve French Aug. 31, 2018, 8:24 p.m. UTC
Although servers will typically ignore unsupported features,
we should advertise the support for directory leases (as
Windows e.g. does) in the negotiate protocol capabilities we
pass to the server, and should check for the server capability
(CAP_DIRECTORY_LEASING) before sending a lease request for an
open of a directory.  This will prevent us from accidentally
sending directory leases to SMB2.1 or SMB2 server for example.

Signed-off-by: Steve French <stfrench@microsoft.com>
CC: Stable <stable@vger.kernel.org>
---
 fs/cifs/smb2ops.c | 10 +++++-----
 fs/cifs/smb2pdu.c |  3 +++
 2 files changed, 8 insertions(+), 5 deletions(-)

                        oparms->fid->lease_key, oplock);

Comments

ronnie sahlberg Aug. 31, 2018, 8:35 p.m. UTC | #1
Reviewed-by: Ronnie Sahlberg <lsahlber@redhat.com>


On Sat, Sep 1, 2018 at 6:24 AM, Steve French <smfrench@gmail.com> wrote:
> Although servers will typically ignore unsupported features,
> we should advertise the support for directory leases (as
> Windows e.g. does) in the negotiate protocol capabilities we
> pass to the server, and should check for the server capability
> (CAP_DIRECTORY_LEASING) before sending a lease request for an
> open of a directory.  This will prevent us from accidentally
> sending directory leases to SMB2.1 or SMB2 server for example.
>
> Signed-off-by: Steve French <stfrench@microsoft.com>
> CC: Stable <stable@vger.kernel.org>
> ---
>  fs/cifs/smb2ops.c | 10 +++++-----
>  fs/cifs/smb2pdu.c |  3 +++
>  2 files changed, 8 insertions(+), 5 deletions(-)
>
> diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
> index 32cae6e49ea2..23118b7a2bbc 100644
> --- a/fs/cifs/smb2ops.c
> +++ b/fs/cifs/smb2ops.c
> @@ -3654,7 +3654,7 @@ struct smb_version_values smb21_values = {
>  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,
> +    .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING
> | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES |
> SMB2_GLOBAL_CAP_ENCRYPTION | SMB2_GLOBAL_CAP_DIRECTORY_LEASING,
>      .large_lock_type = 0,
>      .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
>      .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
> @@ -3675,7 +3675,7 @@ struct smb_version_values smb3any_values = {
>  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,
> +    .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING
> | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES |
> SMB2_GLOBAL_CAP_ENCRYPTION | SMB2_GLOBAL_CAP_DIRECTORY_LEASING,
>      .large_lock_type = 0,
>      .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
>      .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
> @@ -3696,7 +3696,7 @@ struct smb_version_values smbdefault_values = {
>  struct smb_version_values smb30_values = {
>      .version_string = SMB30_VERSION_STRING,
>      .protocol_id = SMB30_PROT_ID,
> -    .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING
> | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES |
> SMB2_GLOBAL_CAP_ENCRYPTION,
> +    .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING
> | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES |
> SMB2_GLOBAL_CAP_ENCRYPTION | SMB2_GLOBAL_CAP_DIRECTORY_LEASING,
>      .large_lock_type = 0,
>      .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
>      .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
> @@ -3717,7 +3717,7 @@ struct smb_version_values smb30_values = {
>  struct smb_version_values smb302_values = {
>      .version_string = SMB302_VERSION_STRING,
>      .protocol_id = SMB302_PROT_ID,
> -    .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING
> | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES |
> SMB2_GLOBAL_CAP_ENCRYPTION,
> +    .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING
> | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES |
> SMB2_GLOBAL_CAP_ENCRYPTION | SMB2_GLOBAL_CAP_DIRECTORY_LEASING,
>      .large_lock_type = 0,
>      .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
>      .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
> @@ -3738,7 +3738,7 @@ struct smb_version_values smb302_values = {
>  struct smb_version_values smb311_values = {
>      .version_string = SMB311_VERSION_STRING,
>      .protocol_id = SMB311_PROT_ID,
> -    .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING
> | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES |
> SMB2_GLOBAL_CAP_ENCRYPTION,
> +    .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING
> | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES |
> SMB2_GLOBAL_CAP_ENCRYPTION | SMB2_GLOBAL_CAP_DIRECTORY_LEASING,
>      .large_lock_type = 0,
>      .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
>      .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
> diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
> index 2ddee7c9c7bf..f6b27bd9b788 100644
> --- a/fs/cifs/smb2pdu.c
> +++ b/fs/cifs/smb2pdu.c
> @@ -2178,6 +2178,9 @@ SMB2_open_init(struct cifs_tcon *tcon, struct
> smb_rqst *rqst, __u8 *oplock,
>      if (!(server->capabilities & SMB2_GLOBAL_CAP_LEASING) ||
>          *oplock == SMB2_OPLOCK_LEVEL_NONE)
>          req->RequestedOplockLevel = *oplock;
> +    else if (!(server->capabilities & SMB2_GLOBAL_CAP_DIRECTORY_LEASING) &&
> +          (oparms->create_options & CREATE_NOT_FILE))
> +        req->RequestedOplockLevel = *oplock; /* no srv lease support */
>      else {
>          rc = add_lease_context(server, iov, &n_iov,
>                         oparms->fid->lease_key, oplock);
> --
> 2.17.1
>
>
> --
> Thanks,
>
> Steve
diff mbox series

Patch

From d51874112b4f557c11efcd49c81c23ef69d639a2 Mon Sep 17 00:00:00 2001
From: Steve French <stfrench@microsoft.com>
Date: Fri, 31 Aug 2018 15:12:10 -0500
Subject: [PATCH] smb3: check for and properly advertise directory lease
 support

Although servers will typically ignore unsupported features,
we should advertise the support for directory leases (as
Windows e.g. does) in the negotiate protocol capabilities we
pass to the server, and should check for the server capability
(CAP_DIRECTORY_LEASING) before sending a lease request for an
open of a directory.  This will prevent us from accidentally
sending directory leases to SMB2.1 or SMB2 server for example.

Signed-off-by: Steve French <stfrench@microsoft.com>
CC: Stable <stable@vger.kernel.org>
---
 fs/cifs/smb2ops.c | 10 +++++-----
 fs/cifs/smb2pdu.c |  3 +++
 2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index 32cae6e49ea2..23118b7a2bbc 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -3654,7 +3654,7 @@  struct smb_version_values smb21_values = {
 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,
+	.req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION | SMB2_GLOBAL_CAP_DIRECTORY_LEASING,
 	.large_lock_type = 0,
 	.exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
 	.shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
@@ -3675,7 +3675,7 @@  struct smb_version_values smb3any_values = {
 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,
+	.req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION | SMB2_GLOBAL_CAP_DIRECTORY_LEASING,
 	.large_lock_type = 0,
 	.exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
 	.shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
@@ -3696,7 +3696,7 @@  struct smb_version_values smbdefault_values = {
 struct smb_version_values smb30_values = {
 	.version_string = SMB30_VERSION_STRING,
 	.protocol_id = SMB30_PROT_ID,
-	.req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION,
+	.req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION | SMB2_GLOBAL_CAP_DIRECTORY_LEASING,
 	.large_lock_type = 0,
 	.exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
 	.shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
@@ -3717,7 +3717,7 @@  struct smb_version_values smb30_values = {
 struct smb_version_values smb302_values = {
 	.version_string = SMB302_VERSION_STRING,
 	.protocol_id = SMB302_PROT_ID,
-	.req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION,
+	.req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION | SMB2_GLOBAL_CAP_DIRECTORY_LEASING,
 	.large_lock_type = 0,
 	.exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
 	.shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
@@ -3738,7 +3738,7 @@  struct smb_version_values smb302_values = {
 struct smb_version_values smb311_values = {
 	.version_string = SMB311_VERSION_STRING,
 	.protocol_id = SMB311_PROT_ID,
-	.req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION,
+	.req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION | SMB2_GLOBAL_CAP_DIRECTORY_LEASING,
 	.large_lock_type = 0,
 	.exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
 	.shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index 2ddee7c9c7bf..f6b27bd9b788 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -2178,6 +2178,9 @@  SMB2_open_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, __u8 *oplock,
 	if (!(server->capabilities & SMB2_GLOBAL_CAP_LEASING) ||
 	    *oplock == SMB2_OPLOCK_LEVEL_NONE)
 		req->RequestedOplockLevel = *oplock;
+	else if (!(server->capabilities & SMB2_GLOBAL_CAP_DIRECTORY_LEASING) &&
+		  (oparms->create_options & CREATE_NOT_FILE))
+		req->RequestedOplockLevel = *oplock; /* no srv lease support */
 	else {
 		rc = add_lease_context(server, iov, &n_iov,
 				       oparms->fid->lease_key, oplock);
-- 
2.17.1