From: Anoop C S Date: Fri, 22 Mar 2024 06:08:08 +0000 (+0530) Subject: source3/smbd: Update timestamps after a successful SMB_VFS_FNTIMES X-Git-Tag: tdb-1.4.11~1297 X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=f3c185a6294d4d92c43687a0ebe64f9cf59a4a2a;p=thirdparty%2Fsamba.git source3/smbd: Update timestamps after a successful SMB_VFS_FNTIMES 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 Reviewed-by: Ralph Boehme --- diff --git a/source3/include/proto.h b/source3/include/proto.h index 389bb2fc935..d98bd3c09cb 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -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, diff --git a/source3/lib/system.c b/source3/lib/system.c index 1ec0ae9b1d5..2006edbed65 100644 --- a/source3/lib/system.c +++ b/source3/lib/system.c @@ -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) diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 4d897d6d7a1..674a13076e1 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -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; }