smbd: implement SMB_FILE_NORMALIZED_NAME_INFORMATION handling
authorStefan Metzmacher <metze@samba.org>
Thu, 25 Apr 2019 12:57:33 +0000 (14:57 +0200)
committerJeremy Allison <jra@samba.org>
Wed, 1 May 2019 18:33:00 +0000 (18:33 +0000)
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 <metze@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Wed May  1 18:33:00 UTC 2019 on sn-devel-184

selftest/knownfail.d/smb2-getinfo [deleted file]
source3/smbd/smb2_getinfo.c
source3/smbd/trans2.c

diff --git a/selftest/knownfail.d/smb2-getinfo b/selftest/knownfail.d/smb2-getinfo
deleted file mode 100644 (file)
index 10ee423..0000000
+++ /dev/null
@@ -1 +0,0 @@
-^samba3.smb2.getinfo.normalized
index 9ec252c172b8df44261baf8429b0f27b45f55903..006f313c63fad83f375633832e6e5c2a87875dc5 100644 (file)
@@ -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
index 017ad068877e1d146975e548238bdf6a7e81bd42..fe406adb58f56c3b29da09fbb7181a9ba4ee9677 100644 (file)
@@ -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"));