mirror of
https://github.com/samba-team/samba.git
synced 2025-01-12 09:18:10 +03:00
Fix bug 6529 - Offline files conflict with Vista and Office 2003
On filesystems that can't store less than one second timestamps, round the incoming timestamp set requests so the client can't discover that a time set request has been truncated by the filesystem. Needs backporting to 3.4, 3.3, 3.2 and (even) 3.0. Jeremy
This commit is contained in:
parent
47c7063dc6
commit
1af0aa92b3
@ -1044,6 +1044,7 @@ struct timespec timespec_current(void);
|
||||
struct timespec timespec_min(const struct timespec *ts1,
|
||||
const struct timespec *ts2);
|
||||
int timespec_compare(const struct timespec *ts1, const struct timespec *ts2);
|
||||
void round_timespec(struct timespec *ts);
|
||||
struct timespec interpret_long_date(const char *p);
|
||||
void cli_put_dos_date(struct cli_state *cli, char *buf, int offset, time_t unixdate);
|
||||
void cli_put_dos_date2(struct cli_state *cli, char *buf, int offset, time_t unixdate);
|
||||
|
@ -557,6 +557,9 @@ typedef struct connection_struct {
|
||||
bool ipc;
|
||||
bool read_only; /* Attributes for the current user of the share. */
|
||||
bool admin_user; /* Attributes for the current user of the share. */
|
||||
bool hires_timestamps_avail; /* Does this filesystem honor
|
||||
sub second timestamps on files
|
||||
and directories ? */
|
||||
char *connectpath;
|
||||
char *origpath;
|
||||
|
||||
|
@ -467,6 +467,17 @@ int timespec_compare(const struct timespec *ts1, const struct timespec *ts2)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Round up a timespec if nsec > 500000000, round down if lower,
|
||||
then zero nsec.
|
||||
****************************************************************************/
|
||||
|
||||
void round_timespec(struct timespec *ts)
|
||||
{
|
||||
ts->tv_sec += ts->tv_nsec >= 500000000 ? 1 : 0;
|
||||
ts->tv_nsec = 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Interprets an nt time into a unix struct timespec.
|
||||
Differs from nt_time_to_unix in that an 8 byte value of 0xffffffffffffffff
|
||||
|
@ -3284,8 +3284,12 @@ static NTSTATUS create_file_unixpath(connection_struct *conn,
|
||||
/* Try and make a create timestamp, if required. */
|
||||
if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
|
||||
if (lp_store_create_time(SNUM(conn))) {
|
||||
struct timespec ts = smb_fname->st.st_ex_btime;
|
||||
if (!conn->hires_timestamps_avail) {
|
||||
round_timespec(&ts);
|
||||
}
|
||||
set_create_timespec_ea(conn, fsp,
|
||||
smb_fname, smb_fname->st.st_ex_btime);
|
||||
smb_fname, ts);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1015,6 +1015,19 @@ connection_struct *make_connection_snum(struct smbd_server_connection *sconn,
|
||||
goto err_root_exit;
|
||||
}
|
||||
|
||||
if (smb_fname_cpath->st.st_ex_mtime.tv_nsec ||
|
||||
smb_fname_cpath->st.st_ex_atime.tv_nsec ||
|
||||
smb_fname_cpath->st.st_ex_ctime.tv_nsec) {
|
||||
/* If any of the normal UNIX directory timestamps
|
||||
* have a non-zero tv_nsec component assume
|
||||
* we can fully store hires timestamps. We need
|
||||
* to make a runtime/share level distinction
|
||||
* as on Linux ext3 doesn't have hires timestamps, but
|
||||
* ext4 does, so a compile time test won't work. JRA.
|
||||
*/
|
||||
conn->hires_timestamps_avail = true;
|
||||
}
|
||||
|
||||
string_set(&conn->origpath,conn->connectpath);
|
||||
|
||||
#if SOFTLINK_OPTIMISATION
|
||||
|
@ -5402,6 +5402,15 @@ NTSTATUS smb_set_file_time(connection_struct *conn,
|
||||
action &= ~FILE_NOTIFY_CHANGE_LAST_WRITE;
|
||||
}
|
||||
|
||||
if (!conn->hires_timestamps_avail) {
|
||||
/* We can't store sub second timestamps
|
||||
* on this share. Round to seconds. */
|
||||
round_timespec(&ft->create_time);
|
||||
round_timespec(&ft->ctime);
|
||||
round_timespec(&ft->atime);
|
||||
round_timespec(&ft->mtime);
|
||||
}
|
||||
|
||||
DEBUG(5,("smb_set_filetime: actime: %s\n ",
|
||||
time_to_asc(convert_timespec_to_time_t(ft->atime))));
|
||||
DEBUG(5,("smb_set_filetime: modtime: %s\n ",
|
||||
|
Loading…
Reference in New Issue
Block a user