From: Aurelien Aptel <aaptel-IBi9RG/b67k@public.gmane.org>
To: linux-cifs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: Aurelien Aptel <aaptel-IBi9RG/b67k@public.gmane.org>
Subject: [PATCH v3 6/7] CIFS: use DFS pathnames in SMB2+ Create requests
Date: Tue, 28 Feb 2017 19:40:33 +0100 [thread overview]
Message-ID: <20170228184034.18771-7-aaptel@suse.com> (raw)
In-Reply-To: <20170228184034.18771-1-aaptel-IBi9RG/b67k@public.gmane.org>
When connected to a DFS capable share, the client must set the
SMB2_FLAGS_DFS_OPERATIONS flag in the SMB2 header and use
DFS path names: "<server>\<share>\<path>" *without* leading \\.
Sources:
[MS-SMB2] 3.2.5.5 Receiving an SMB2 TREE_CONNECT Response
> TreeConnect.IsDfsShare MUST be set to TRUE, if the SMB2_SHARE_CAP_DFS
> bit is set in the Capabilities field of the response.
[MS-SMB2] 3.2.4.3 Application Requests Opening a File
> If TreeConnect.IsDfsShare is TRUE, the SMB2_FLAGS_DFS_OPERATIONS flag
> is set in the Flags field.
[MS-SMB2] 2.2.13 SMB2 CREATE Request, NameOffset:
> If SMB2_FLAGS_DFS_OPERATIONS is set in the Flags field of the SMB2
> header, the file name includes a prefix that will be processed during
> DFS name normalization as specified in section 3.3.5.9. Otherwise, the
> file name is relative to the share that is identified by the TreeId in
> the SMB2 header.
Signed-off-by: Aurelien Aptel <aaptel-IBi9RG/b67k@public.gmane.org>
---
fs/cifs/smb2pdu.c | 93 +++++++++++++++++++++++++++++++++++++++++++++----------
1 file changed, 77 insertions(+), 16 deletions(-)
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index 2fd93ee..059da05 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -1528,6 +1528,48 @@ add_durable_context(struct kvec *iov, unsigned int *num_iovec,
return 0;
}
+static int
+alloc_path_with_tree_prefix(__le16 **out_path, int *out_size, int *out_len,
+ const char *treename, const __le16 *path)
+{
+ int treename_len, path_len;
+ const __le16 sep[] = {cpu_to_le16('\\'), cpu_to_le16(0x0000)};
+
+ /*
+ * skip leading "\\"
+ */
+ treename_len = strlen(treename);
+ if (treename_len < 2 || !(treename[0] == '\\' && treename[1] == '\\'))
+ return -EINVAL;
+
+ treename += 2;
+ treename_len -= 2;
+
+ path_len = UniStrnlen((wchar_t *)path, PATH_MAX);
+
+ /*
+ * make room for one path separator between the treename and
+ * path
+ */
+ *out_len = treename_len + 1 + path_len;
+
+ /*
+ * final path needs to be null-terminated UTF16 with a
+ * size aligned to 8
+ */
+
+ *out_size = roundup((*out_len+1)*2, 8);
+ *out_path = kzalloc(*out_size, GFP_KERNEL);
+ if (!*out_path)
+ return -ENOMEM;
+
+ cifs_strtoUTF16(*out_path, treename, treename_len, load_nls_default());
+ UniStrcat(*out_path, sep);
+ UniStrcat(*out_path, path);
+
+ return 0;
+}
+
int
SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
__u8 *oplock, struct smb2_file_all_info *buf,
@@ -1576,30 +1618,49 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
req->ShareAccess = FILE_SHARE_ALL_LE;
req->CreateDisposition = cpu_to_le32(oparms->disposition);
req->CreateOptions = cpu_to_le32(oparms->create_options & CREATE_OPTIONS_MASK);
- uni_path_len = (2 * UniStrnlen((wchar_t *)path, PATH_MAX)) + 2;
- /* do not count rfc1001 len field */
- req->NameOffset = cpu_to_le16(sizeof(struct smb2_create_req) - 4);
iov[0].iov_base = (char *)req;
/* 4 for rfc1002 length field */
iov[0].iov_len = get_rfc1002_length(req) + 4;
-
- /* MUST set path len (NameLength) to 0 opening root of share */
- req->NameLength = cpu_to_le16(uni_path_len - 2);
/* -1 since last byte is buf[0] which is sent below (path) */
iov[0].iov_len--;
- if (uni_path_len % 8 != 0) {
- copy_size = uni_path_len / 8 * 8;
- if (copy_size < uni_path_len)
- copy_size += 8;
-
- copy_path = kzalloc(copy_size, GFP_KERNEL);
- if (!copy_path)
- return -ENOMEM;
- memcpy((char *)copy_path, (const char *)path,
- uni_path_len);
+
+ req->NameOffset = cpu_to_le16(sizeof(struct smb2_create_req) - 4);
+
+ /* [MS-SMB2] 2.2.13 NameOffset:
+ * If SMB2_FLAGS_DFS_OPERATIONS is set in the Flags field of
+ * the SMB2 header, the file name includes a prefix that will
+ * be processed during DFS name normalization as specified in
+ * section 3.3.5.9. Otherwise, the file name is relative to
+ * the share that is identified by the TreeId in the SMB2
+ * header.
+ */
+ if (tcon->share_flags & SHI1005_FLAGS_DFS) {
+ int name_len;
+
+ req->hdr.sync_hdr.Flags |= SMB2_FLAGS_DFS_OPERATIONS;
+ rc = alloc_path_with_tree_prefix(©_path, ©_size,
+ &name_len,
+ tcon->treeName, path);
+ if (rc)
+ return rc;
+ req->NameLength = cpu_to_le16(name_len * 2);
uni_path_len = copy_size;
path = copy_path;
+ } else {
+ uni_path_len = (2 * UniStrnlen((wchar_t *)path, PATH_MAX)) + 2;
+ /* MUST set path len (NameLength) to 0 opening root of share */
+ req->NameLength = cpu_to_le16(uni_path_len - 2);
+ if (uni_path_len % 8 != 0) {
+ copy_size = roundup(uni_path_len, 8);
+ copy_path = kzalloc(copy_size, GFP_KERNEL);
+ if (!copy_path)
+ return -ENOMEM;
+ memcpy((char *)copy_path, (const char *)path,
+ uni_path_len);
+ uni_path_len = copy_size;
+ path = copy_path;
+ }
}
iov[1].iov_len = uni_path_len;
--
2.10.2
next prev parent reply other threads:[~2017-02-28 18:40 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-02-28 18:40 [PATCH v3 0/7] Add support for DFS in SMB2+ Aurelien Aptel
[not found] ` <20170228184034.18771-1-aaptel-IBi9RG/b67k@public.gmane.org>
2017-02-28 18:40 ` [PATCH v3 1/7] CIFS: move DFS response parsing out of SMB1 code Aurelien Aptel
[not found] ` <20170228184034.18771-2-aaptel-IBi9RG/b67k@public.gmane.org>
2017-03-01 1:58 ` Pavel Shilovsky
2017-02-28 18:40 ` [PATCH v3 2/7] CIFS: add build_path_from_dentry_optional_prefix() Aurelien Aptel
[not found] ` <20170228184034.18771-3-aaptel-IBi9RG/b67k@public.gmane.org>
2017-03-01 2:35 ` Pavel Shilovsky
2017-02-28 18:40 ` [PATCH v3 3/7] CIFS: add use_ipc flag to SMB2_ioctl() Aurelien Aptel
[not found] ` <20170228184034.18771-4-aaptel-IBi9RG/b67k@public.gmane.org>
2017-03-01 2:36 ` Pavel Shilovsky
2017-02-28 18:40 ` [PATCH v3 4/7] CIFS: let ses->ipc_tid hold smb2 TreeIds Aurelien Aptel
[not found] ` <20170228184034.18771-5-aaptel-IBi9RG/b67k@public.gmane.org>
2017-03-01 2:36 ` Pavel Shilovsky
2017-02-28 18:40 ` [PATCH v3 5/7] CIFS: set signing flag in SMB2+ TreeConnect if needed Aurelien Aptel
[not found] ` <20170228184034.18771-6-aaptel-IBi9RG/b67k@public.gmane.org>
2017-03-01 2:37 ` Pavel Shilovsky
2017-02-28 18:40 ` Aurelien Aptel [this message]
[not found] ` <20170228184034.18771-7-aaptel-IBi9RG/b67k@public.gmane.org>
2017-03-01 2:40 ` [PATCH v3 6/7] CIFS: use DFS pathnames in SMB2+ Create requests Pavel Shilovsky
2017-02-28 18:40 ` [PATCH v3 7/7] CIFS: implement get_dfs_refer for SMB2+ Aurelien Aptel
[not found] ` <20170228184034.18771-8-aaptel-IBi9RG/b67k@public.gmane.org>
2017-03-01 2:42 ` Pavel Shilovsky
2017-06-22 23:03 ` Pavel Shilovsky
[not found] ` <CAKywueTx4b4+MDYeTm+jBsUZfmYe+Sa1HT9cUx-d4043hKxr+A-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-06-22 23:05 ` Pavel Shilovsky
[not found] ` <CAKywueSy1Y1PNLHkRnDbxgc+Kf1qe_H65DPkWpX-=k=Enu-VUw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-06-23 9:19 ` Aurélien Aptel
2017-03-02 4:41 ` [PATCH v3 0/7] Add support for DFS in SMB2+ Steve French
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170228184034.18771-7-aaptel@suse.com \
--to=aaptel-ibi9rg/b67k@public.gmane.org \
--cc=linux-cifs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox