smbd: only open full fd for directories if needed
authorRalph Boehme <slow@samba.org>
Tue, 29 Jun 2021 10:47:34 +0000 (12:47 +0200)
committerJule Anger <janger@samba.org>
Mon, 9 Aug 2021 12:05:34 +0000 (12:05 +0000)
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14700
RN: File owner not available when file unreadable

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Mon Aug  2 18:05:04 UTC 2021 on sn-devel-184

(cherry picked from commit 6d928eb1e8ea44f0d0aea4ec9b1b7c385a281193)

Autobuild-User(v4-15-test): Jule Anger <janger@samba.org>
Autobuild-Date(v4-15-test): Mon Aug  9 12:05:34 UTC 2021 on sn-devel-184

source3/smbd/open.c

index 2427774af1f74b0224041d51b2c3f768f4b2b2e9..968dd8ecb00802ba430fad0b429a14a7c1dfe8cb 100644 (file)
@@ -4404,6 +4404,7 @@ static NTSTATUS open_directory(connection_struct *conn,
        struct timespec mtimespec;
        int info = 0;
        bool ok;
+       uint32_t need_fd_access;
 
        if (is_ntfs_stream_smb_fname(smb_dname)) {
                DEBUG(2, ("open_directory: %s is a stream name!\n",
@@ -4596,12 +4597,25 @@ static NTSTATUS open_directory(connection_struct *conn,
        */
        mtimespec = make_omit_timespec();
 
-       status = reopen_from_fsp(fsp, O_RDONLY|O_DIRECTORY, 0, NULL);
-       if (!NT_STATUS_IS_OK(status)) {
-               DBG_INFO("Could not open fd for%s (%s)\n",
-                        smb_fname_str_dbg(smb_dname),
-                        nt_errstr(status));
-               return status;
+       /*
+        * Obviously for FILE_LIST_DIRECTORY we need to reopen to get an fd
+        * usable for reading a directory. SMB2_FLUSH may be called on
+        * directories opened with FILE_ADD_FILE and FILE_ADD_SUBDIRECTORY so
+        * for those we need to reopen as well.
+        */
+       need_fd_access =
+               FILE_LIST_DIRECTORY |
+               FILE_ADD_FILE |
+               FILE_ADD_SUBDIRECTORY;
+
+       if (access_mask & need_fd_access) {
+               status = reopen_from_fsp(fsp, O_RDONLY | O_DIRECTORY, 0, NULL);
+               if (!NT_STATUS_IS_OK(status)) {
+                       DBG_INFO("Could not open fd for [%s]: %s\n",
+                                smb_fname_str_dbg(smb_dname),
+                                nt_errstr(status));
+                       return status;
+               }
        }
 
        status = vfs_stat_fsp(fsp);