source3/smbd: Update timestamps after a successful SMB_VFS_FNTIMES
authorAnoop C S <anoopcs@samba.org>
Fri, 22 Mar 2024 06:08:08 +0000 (11:38 +0530)
committerAnoop C S <anoopcs@samba.org>
Mon, 1 Apr 2024 14:19:39 +0000 (14:19 +0000)
When an open file handle is used to change timestamps we fail to return
updated values to clients until next open is issued. Unless we fill in
the timestamps subsequent calls like GETINFO cannot see the latest value
causing incorrect results. Therefore copy those timestamp values as soon
as it is set on the backend.

Signed-off-by: Anoop C S <anoopcs@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
source3/include/proto.h
source3/lib/system.c
source3/smbd/dosmode.c

index 389bb2fc935bba922bde6ec254143a639ef43494..d98bd3c09cb07d4dcf1b20220a487f5bb5ab7ca4 100644 (file)
@@ -173,6 +173,7 @@ void update_stat_ex_mtime(struct stat_ex *dst, struct timespec write_ts);
 void update_stat_ex_create_time(struct stat_ex *dst, struct timespec create_time);
 void update_stat_ex_from_saved_stat(struct stat_ex *dst,
                                    const struct stat_ex *src);
+void copy_stat_ex_timestamps(files_struct *fsp, const struct smb_file_time *ft);
 int sys_stat(const char *fname, SMB_STRUCT_STAT *sbuf,
             bool fake_dir_create_times);
 int sys_fstat(int fd, SMB_STRUCT_STAT *sbuf,
index 1ec0ae9b1d538fec7e0ceed5089ac177f70e328b..2006edbed6575b38652825048e30c1436bf0154c 100644 (file)
@@ -249,6 +249,25 @@ void update_stat_ex_from_saved_stat(struct stat_ex *dst,
        }
 }
 
+void copy_stat_ex_timestamps(files_struct *fsp, const struct smb_file_time *ft)
+{
+       if (!is_omit_timespec(&ft->atime)) {
+               fsp->fsp_name->st.st_ex_atime = ft->atime;
+       }
+
+       if (!is_omit_timespec(&ft->create_time)) {
+               fsp->fsp_name->st.st_ex_btime = ft->create_time;
+       }
+
+       if (!is_omit_timespec(&ft->ctime)) {
+               fsp->fsp_name->st.st_ex_ctime = ft->ctime;
+       }
+
+       if (!is_omit_timespec(&ft->mtime)) {
+               fsp->fsp_name->st.st_ex_mtime = ft->mtime;
+       }
+}
+
 void init_stat_ex_from_stat (struct stat_ex *dst,
                            const struct stat *src,
                            bool fake_dir_create_times)
index 4d897d6d7a13b02fc4d4f8e5f812b4a021f56124..674a13076e1d98d4ed557fd631e4a5186235e574 100644 (file)
@@ -1189,7 +1189,8 @@ int file_ntimes(connection_struct *conn,
        }
 
        if (SMB_VFS_FNTIMES(fsp, ft) == 0) {
-               return 0;
+               ret = 0;
+               goto done;
        }
 
        if((errno != EPERM) && (errno != EACCES)) {
@@ -1214,6 +1215,11 @@ int file_ntimes(connection_struct *conn,
                unbecome_root();
        }
 
+done:
+       if (ret == 0) {
+               copy_stat_ex_timestamps(fsp, ft);
+       }
+
        return ret;
 }