smbd: handle fake file handles in dos_mode()
authorRalph Boehme <slow@samba.org>
Fri, 4 Jun 2021 14:58:20 +0000 (16:58 +0200)
committerKarolin Seeger <kseeger@samba.org>
Mon, 19 Jul 2021 06:18:12 +0000 (06:18 +0000)
This ensures SMB requests on the quote fake file "$Extend/$Quota" don't hit the
VFS, where specifically in vfs_gpfs we log an error message if we fail to read
the DOS attributes for a file with

  vfs_gpfs_get_dos_attributes: Getting winattrs failed for $Extend/$Quota

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14731

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/smbd/dosmode.c

index 4012d6e64c9727e440bbc9674f7035d3d50e2fb2..a6b8f1701922a874c3946fe62ff55d6cedac9079 100644 (file)
@@ -27,6 +27,7 @@
 #include "smbd/smbd.h"
 #include "lib/param/loadparm.h"
 #include "lib/util/tevent_ntstatus.h"
+#include "fake_file.h"
 
 static NTSTATUS get_file_handle_for_metadata(connection_struct *conn,
                                const struct smb_filename *smb_fname,
@@ -754,6 +755,7 @@ uint32_t dos_mode(connection_struct *conn, struct smb_filename *smb_fname)
 {
        uint32_t result = 0;
        NTSTATUS status = NT_STATUS_OK;
+       enum FAKE_FILE_TYPE fake_file_type;
 
        DEBUG(8,("dos_mode: %s\n", smb_fname_str_dbg(smb_fname)));
 
@@ -761,6 +763,24 @@ uint32_t dos_mode(connection_struct *conn, struct smb_filename *smb_fname)
                return 0;
        }
 
+       fake_file_type = is_fake_file(smb_fname);
+
+       switch (fake_file_type) {
+       case FAKE_FILE_TYPE_NAMED_PIPE_PROXY:
+       case FAKE_FILE_TYPE_NAMED_PIPE:
+               return FILE_ATTRIBUTE_NORMAL;
+
+       case FAKE_FILE_TYPE_QUOTA:
+               /* From Windows 2016 */
+               return FILE_ATTRIBUTE_HIDDEN
+                       | FILE_ATTRIBUTE_SYSTEM
+                       | FILE_ATTRIBUTE_DIRECTORY
+                       | FILE_ATTRIBUTE_ARCHIVE;
+
+       case FAKE_FILE_TYPE_NONE:
+               break;
+       }
+
        /* Get the DOS attributes via the VFS if we can */
        status = SMB_VFS_GET_DOS_ATTRIBUTES(conn, smb_fname, &result);
        if (!NT_STATUS_IS_OK(status)) {