From b20fd15e04ce9292f90a7f70f4184e43034b4b9d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 25 Apr 2019 14:57:33 +0200 Subject: [PATCH] smbd: implement SMB_FILE_NORMALIZED_NAME_INFORMATION handling Windows 10 (1803 and higher) support and use SMB_FILE_NORMALIZED_NAME_INFORMATION calls over the network. As a fallback (in case the server don't support it) the client traverses all path components, which is very expensive. Implementing SMB_FILE_NORMALIZED_NAME_INFORMATION is very cheap for us as the open already went through unix_convert() and we have the information the client is asking for. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13919 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison Autobuild-User(master): Jeremy Allison Autobuild-Date(master): Wed May 1 18:33:00 UTC 2019 on sn-devel-184 --- selftest/knownfail.d/smb2-getinfo | 1 - source3/smbd/smb2_getinfo.c | 9 +++++ source3/smbd/trans2.c | 57 +++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 1 deletion(-) delete mode 100644 selftest/knownfail.d/smb2-getinfo diff --git a/selftest/knownfail.d/smb2-getinfo b/selftest/knownfail.d/smb2-getinfo deleted file mode 100644 index 10ee423e55a..00000000000 --- a/selftest/knownfail.d/smb2-getinfo +++ /dev/null @@ -1 +0,0 @@ -^samba3.smb2.getinfo.normalized diff --git a/source3/smbd/smb2_getinfo.c b/source3/smbd/smb2_getinfo.c index 9ec252c172b..006f313c63f 100644 --- a/source3/smbd/smb2_getinfo.c +++ b/source3/smbd/smb2_getinfo.c @@ -318,6 +318,15 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, break; } + switch (file_info_level) { + case SMB_FILE_NORMALIZED_NAME_INFORMATION: + if (smb2req->xconn->protocol < PROTOCOL_SMB3_11) { + tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED); + return tevent_req_post(req, ev); + } + break; + } + if (fsp->fake_file_handle) { /* * This is actually for the QUOTA_FAKE_FILE --metze diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 017ad068877..fe406adb58f 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -5214,6 +5214,63 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, break; } + case SMB_FILE_NORMALIZED_NAME_INFORMATION: + { + char *nfname = NULL; + + if (!fsp->conn->sconn->using_smb2) { + return NT_STATUS_INVALID_LEVEL; + } + + nfname = talloc_strdup(mem_ctx, smb_fname->base_name); + if (nfname == NULL) { + return NT_STATUS_NO_MEMORY; + } + + if (ISDOT(nfname)) { + nfname[0] = '\0'; + } + string_replace(nfname, '/', '\\'); + + if (smb_fname->stream_name != NULL) { + const char *s = smb_fname->stream_name; + const char *e = NULL; + size_t n; + + SMB_ASSERT(s[0] != '\0'); + + /* + * smb_fname->stream_name is in form + * of ':StrEam:$DATA', but we should only + * append ':StrEam' here. + */ + + e = strchr(&s[1], ':'); + if (e == NULL) { + n = strlen(s); + } else { + n = PTR_DIFF(e, s); + } + nfname = talloc_strndup_append(nfname, s, n); + if (nfname == NULL) { + return NT_STATUS_NO_MEMORY; + } + } + + status = srvstr_push(dstart, flags2, + pdata+4, nfname, + PTR_DIFF(dend, pdata+4), + STR_UNICODE, &len); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NORMALIZED_NAME_INFORMATION\n")); + data_size = 4 + len; + SIVAL(pdata,0,len); + *fixed_portion = 8; + break; + } + case SMB_FILE_ALLOCATION_INFORMATION: case SMB_QUERY_FILE_ALLOCATION_INFO: DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n")); -- 2.47.3