smbd: add and use vfs_fget_dos_attributes()
authorRalph Boehme <slow@samba.org>
Thu, 11 Aug 2022 15:18:13 +0000 (17:18 +0200)
committerJule Anger <janger@samba.org>
Tue, 6 Sep 2022 07:54:13 +0000 (07:54 +0000)
Commit d71ef1365cdde47aeb3465699181656b0655fa04 caused a regression where the
creation date on streams wasn't updated anymore on the stream fsp.

By adding a simple wrapper vfs_fget_dos_attributes() that takes care of

- passing only the base_fsp to the VFS, so the VFS can be completely agnostic of
  all the streams related complexity like fake fds,

- propagating any updated btime from the base_fsp->fsp_name to the
  stream_fsp->fsp_name

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15126
MR: https://gitlab.com/samba-team/samba/-/merge_requests/2643

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
(backported from commit 3f7d8db9945a325020e4d1574289dea9e8331c29)
[slow@samba.org: also update itime and file_id]

selftest/knownfail.d/smb2.streams [deleted file]
source3/include/proto.h
source3/smbd/dosmode.c
source3/smbd/open.c
source3/smbd/vfs.c

diff --git a/selftest/knownfail.d/smb2.streams b/selftest/knownfail.d/smb2.streams
deleted file mode 100644 (file)
index 9dcebb0..0000000
+++ /dev/null
@@ -1 +0,0 @@
-^samba3.smb2.streams streams_xattr.attributes2
index 19a9c6b8a015a4ff646d19fb178e8d81e8ac4aa9..81357968bf62c5bb433273d81c5ea3f3a0294001 100644 (file)
@@ -82,6 +82,9 @@ NTSTATUS vfs_at_fspcwd(TALLOC_CTX *mem_ctx,
                       struct connection_struct *conn,
                       struct files_struct **_fsp);
 
+NTSTATUS vfs_fget_dos_attributes(struct files_struct *fsp,
+                                uint32_t *dosmode);
+
 #include "source3/lib/interface.h"
 
 /* The following definitions come from lib/ldap_debug_handler.c  */
index 0cf418330492cc5952375ca4d72b92e478701ac0..b7d1052e86c9279d1713eb9c30ec911c00d1e3f6 100644 (file)
@@ -754,8 +754,7 @@ uint32_t fdos_mode(struct files_struct *fsp)
        }
 
        /* Get the DOS attributes via the VFS if we can */
-       status = SMB_VFS_FGET_DOS_ATTRIBUTES(
-               fsp->conn, metadata_fsp(fsp), &result);
+       status = vfs_fget_dos_attributes(fsp, &result);
        if (!NT_STATUS_IS_OK(status)) {
                /*
                 * Only fall back to using UNIX modes if we get NOT_IMPLEMENTED.
index a3392add1e82a2b0f9492aab34fb0288c8ab8a3f..7cc7f3b0678a52c6617cc15adf4b527d6250b36b 100644 (file)
@@ -3569,8 +3569,7 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
                         */
                        uint32_t attr = 0;
 
-                       status = SMB_VFS_FGET_DOS_ATTRIBUTES(
-                               conn, metadata_fsp(smb_fname->fsp), &attr);
+                       status = vfs_fget_dos_attributes(smb_fname->fsp, &attr);
                        if (NT_STATUS_IS_OK(status)) {
                                existing_dos_attributes = attr;
                        }
index cd412a3d57a4b7698cb59e4491fbca4baddf7245..f1d2a1a477c7477071f9357703ed01a6c4de8328 100644 (file)
@@ -1508,6 +1508,60 @@ NTSTATUS vfs_at_fspcwd(TALLOC_CTX *mem_ctx,
        return NT_STATUS_OK;
 }
 
+NTSTATUS vfs_fget_dos_attributes(struct files_struct *fsp,
+                                uint32_t *dosmode)
+{
+       NTSTATUS status;
+
+       /*
+        * First make sure to pass the base_fsp to the VFS
+        */
+       status = SMB_VFS_FGET_DOS_ATTRIBUTES(
+               fsp->conn, metadata_fsp(fsp), dosmode);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       /*
+        * If this isn't a stream fsp we're done, ...
+        */
+       if (!fsp_is_alternate_stream(fsp)) {
+               return NT_STATUS_OK;
+       }
+
+       /*
+        * ...otherwise the VFS might have updated the btime, propagate the
+        * btime from the base_fsp to the stream fsp.
+        */
+
+       if (!(fsp->base_fsp->fsp_name->st.st_ex_iflags &
+             ST_EX_IFLAG_CALCULATED_BTIME))
+       {
+               update_stat_ex_create_time(
+                       &fsp->fsp_name->st,
+                       fsp->base_fsp->fsp_name->st.st_ex_btime);
+       }
+
+       if (!(fsp->base_fsp->fsp_name->st.st_ex_iflags &
+             ST_EX_IFLAG_CALCULATED_ITIME))
+       {
+               update_stat_ex_itime(
+                       &fsp->fsp_name->st,
+                       fsp->base_fsp->fsp_name->st.st_ex_itime);
+       }
+
+       if (!(fsp->base_fsp->fsp_name->st.st_ex_iflags &
+             ST_EX_IFLAG_CALCULATED_FILE_ID))
+       {
+               update_stat_ex_file_id(
+                       &fsp->fsp_name->st,
+                       fsp->base_fsp->fsp_name->st.st_ex_file_id);
+       }
+
+
+       return NT_STATUS_OK;
+}
+
 int smb_vfs_call_connect(struct vfs_handle_struct *handle,
                         const char *service, const char *user)
 {