1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-24 10:50:22 +03:00

smbd: fix handling of sentinel timestamp values

This implements two core changes:

* use NTTIME instead of struct timespec at the database layer

* use struct timespec { .tv_nsec = SAMBA_UTIME_OMIT } as special sentinel
  value in smbd when processing timestamps

Using NTTIME at the database layer is only done to avoid storing the special
struct timespec sentinel values on disk. Instead, with NTTIME the sentinel value
for an "unset" timestamp is just 0 on-disk.

The NTTIME value of 0 gets translated by nt_time_to_full_timespec() to the
struct timespec sentinel value { .tv_nsec = SAMBA_UTIME_OMIT }.

The function is_omit_timespec() can be used to check this.

Beside nt_time_to_full_timespec(), there are various other new time conversion
functions with *full* in their name that can be used to safely convert between
different types with the changed sentinel value.

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

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
This commit is contained in:
Ralph Boehme 2019-12-02 16:30:50 +01:00 committed by Jeremy Allison
parent 6e58cfab98
commit 69691dd0cd
23 changed files with 114 additions and 107 deletions

View File

@ -1,10 +0,0 @@
^samba3.smb2.timestamps.time_t_4294967295\(ad_dc\)
^samba3.smb2.timestamps.time_t_4294967295\(nt4_dc\)
^samba3.smb2.timestamps.time_t_0\(nt4_dc\)
^samba3.smb2.timestamps.time_t_0\(ad_dc\)
^samba3.smb2.timestamps.time_t_-1\(nt4_dc\)
^samba3.smb2.timestamps.time_t_-1\(ad_dc\)
^samba3.smb2.timestamps.time_t_-2\(nt4_dc\)
^samba3.smb2.timestamps.time_t_-2\(ad_dc\)
^samba3.smb2.timestamps.time_t_1968\(nt4_dc\)
^samba3.smb2.timestamps.time_t_1968\(ad_dc\)

View File

@ -287,6 +287,7 @@
Use SMB_VFS_UNLINKAT(.., AT_REMOVEDIR) instead. */
/* Version 42 - Remove SMB_VFS_CHOWN */
/* Version 42 - Remove struct write_cache *wcp from files_struct */
/* Version 42 - SMB_VFS_NTIMES() receives null times based on UTIMES_OMIT */
#define SMB_VFS_INTERFACE_VERSION 42

View File

@ -61,8 +61,8 @@ interface open_files
uint32 num_share_modes;
uint32 num_delete_tokens;
[size_is(num_delete_tokens)] delete_token delete_tokens[];
timespec old_write_time;
timespec changed_write_time;
NTTIME old_write_time;
NTTIME changed_write_time;
[skip] boolean8 fresh;
[skip] boolean8 modified;
[ignore] file_id id; /* In memory key used to lookup cache. */
@ -105,7 +105,7 @@ interface open_files
boolean8 update_write_time_triggered;
boolean8 update_write_time_on_close;
boolean8 write_time_forced;
timespec close_write_time;
NTTIME close_write_time;
vfs_default_durable_stat stat_info;
} vfs_default_durable_cookie;

View File

@ -36,6 +36,7 @@
*/
#include "includes.h"
#include "lib/util/time_basic.h"
#include "system/filesys.h"
#include "lib/util/server_id.h"
#include "locking/proto.h"
@ -637,7 +638,7 @@ void get_file_infos(struct file_id id,
}
if (write_time) {
ZERO_STRUCTP(write_time);
*write_time = make_omit_timespec();
}
if (!(lck = fetch_share_mode_unlocked(talloc_tos(), id))) {
@ -990,10 +991,11 @@ bool set_sticky_write_time(struct file_id fileid, struct timespec write_time)
{
struct share_mode_lock *lck;
struct file_id_buf ftmp;
struct timeval_buf tbuf;
NTTIME nt = full_timespec_to_nt_time(&write_time);
DBG_INFO("%s id=%s\n",
timestring(talloc_tos(),
convert_timespec_to_time_t(write_time)),
timespec_string_buf(&write_time, true, &tbuf),
file_id_str_buf(fileid, &ftmp));
lck = get_existing_share_mode_lock(talloc_tos(), fileid);
@ -1001,9 +1003,9 @@ bool set_sticky_write_time(struct file_id fileid, struct timespec write_time)
return False;
}
if (timespec_compare(&lck->data->changed_write_time, &write_time) != 0) {
if (lck->data->changed_write_time != nt) {
lck->data->modified = True;
lck->data->changed_write_time = write_time;
lck->data->changed_write_time = nt;
}
TALLOC_FREE(lck);
@ -1014,10 +1016,11 @@ bool set_write_time(struct file_id fileid, struct timespec write_time)
{
struct share_mode_lock *lck;
struct file_id_buf idbuf;
struct timeval_buf tbuf;
NTTIME nt = full_timespec_to_nt_time(&write_time);
DBG_INFO("%s id=%s\n",
timestring(talloc_tos(),
convert_timespec_to_time_t(write_time)),
timespec_string_buf(&write_time, true, &tbuf),
file_id_str_buf(fileid, &idbuf));
lck = get_existing_share_mode_lock(talloc_tos(), fileid);
@ -1025,9 +1028,9 @@ bool set_write_time(struct file_id fileid, struct timespec write_time)
return False;
}
if (timespec_compare(&lck->data->old_write_time, &write_time) != 0) {
if (lck->data->old_write_time != nt) {
lck->data->modified = True;
lck->data->old_write_time = write_time;
lck->data->old_write_time = nt;
}
TALLOC_FREE(lck);
@ -1038,10 +1041,10 @@ struct timespec get_share_mode_write_time(struct share_mode_lock *lck)
{
struct share_mode_data *d = lck->data;
if (!null_timespec(d->changed_write_time)) {
return d->changed_write_time;
if (!null_nttime(d->changed_write_time)) {
return nt_time_to_full_timespec(d->changed_write_time);
}
return d->old_write_time;
return nt_time_to_full_timespec(d->old_write_time);
}
struct file_has_open_streams_state {

View File

@ -505,7 +505,7 @@ static struct share_mode_data *fresh_share_mode_lock(
if (d->servicepath == NULL) {
goto fail;
}
d->old_write_time = *old_write_time;
d->old_write_time = full_timespec_to_nt_time(old_write_time);
d->modified = false;
d->fresh = true;
return d;

View File

@ -782,15 +782,15 @@ static int cephwrap_ntimes(struct vfs_handle_struct *handle,
int result;
int mask = 0;
if (!null_timespec(ft->atime)) {
if (!is_omit_timespec(&ft->atime)) {
stx.stx_atime = ft->atime;
mask |= CEPH_SETATTR_ATIME;
}
if (!null_timespec(ft->mtime)) {
if (!is_omit_timespec(&ft->mtime)) {
stx.stx_mtime = ft->mtime;
mask |= CEPH_SETATTR_MTIME;
}
if (!null_timespec(ft->create_time)) {
if (!is_omit_timespec(&ft->create_time)) {
stx.stx_btime = ft->create_time;
mask |= CEPH_SETATTR_BTIME;
}
@ -899,17 +899,17 @@ static int cephwrap_ntimes(struct vfs_handle_struct *handle,
struct utimbuf buf;
int result;
if (null_timespec(ft->atime)) {
if (is_omit_timespec(&ft->atime)) {
buf.actime = smb_fname->st.st_ex_atime.tv_sec;
} else {
buf.actime = ft->atime.tv_sec;
}
if (null_timespec(ft->mtime)) {
if (is_omit_timespec(&ft->mtime)) {
buf.modtime = smb_fname->st.st_ex_mtime.tv_sec;
} else {
buf.modtime = ft->mtime.tv_sec;
}
if (!null_timespec(ft->create_time)) {
if (!is_omit_timespec(&ft->create_time)) {
set_create_timespec_ea(handle->conn, smb_fname,
ft->create_time);
}

View File

@ -2332,15 +2332,15 @@ static int vfswrap_ntimes(vfs_handle_struct *handle,
}
if (ft != NULL) {
if (null_timespec(ft->atime)) {
if (is_omit_timespec(&ft->atime)) {
ft->atime= smb_fname->st.st_ex_atime;
}
if (null_timespec(ft->mtime)) {
if (is_omit_timespec(&ft->mtime)) {
ft->mtime = smb_fname->st.st_ex_mtime;
}
if (!null_timespec(ft->create_time)) {
if (!is_omit_timespec(&ft->create_time)) {
set_create_timespec_ea(handle->conn,
smb_fname,
ft->create_time);

View File

@ -3801,7 +3801,7 @@ static int fruit_ntimes(vfs_handle_struct *handle,
return -1);
if ((config->meta != FRUIT_META_NETATALK) ||
null_timespec(ft->create_time))
is_omit_timespec(&ft->create_time))
{
return SMB_VFS_NEXT_NTIMES(handle, smb_fname, ft);
}

View File

@ -1418,7 +1418,7 @@ static int vfs_gluster_ntimes(struct vfs_handle_struct *handle,
START_PROFILE(syscall_ntimes);
if (null_timespec(ft->atime)) {
if (is_omit_timespec(&ft->atime)) {
times[0].tv_sec = smb_fname->st.st_ex_atime.tv_sec;
times[0].tv_nsec = smb_fname->st.st_ex_atime.tv_nsec;
} else {
@ -1426,7 +1426,7 @@ static int vfs_gluster_ntimes(struct vfs_handle_struct *handle,
times[0].tv_nsec = ft->atime.tv_nsec;
}
if (null_timespec(ft->mtime)) {
if (is_omit_timespec(&ft->mtime)) {
times[1].tv_sec = smb_fname->st.st_ex_mtime.tv_sec;
times[1].tv_nsec = smb_fname->st.st_ex_mtime.tv_nsec;
} else {

View File

@ -1934,7 +1934,7 @@ static int vfs_gpfs_lstat(struct vfs_handle_struct *handle,
static void timespec_to_gpfs_time(struct timespec ts, gpfs_timestruc_t *gt,
int idx, int *flags)
{
if (!null_timespec(ts)) {
if (!is_omit_timespec(&ts)) {
*flags |= 1 << idx;
gt[idx].tv_sec = ts.tv_sec;
gt[idx].tv_nsec = ts.tv_nsec;
@ -2004,7 +2004,7 @@ static int vfs_gpfs_ntimes(struct vfs_handle_struct *handle,
return -1;
}
if(null_timespec(ft->create_time)){
if (is_omit_timespec(&ft->create_time)){
DEBUG(10,("vfs_gpfs_ntimes:Create Time is NULL\n"));
return 0;
}

View File

@ -417,7 +417,7 @@ static void recycle_do_touch(vfs_handle_struct *handle,
struct smb_file_time ft;
int ret, err;
ZERO_STRUCT(ft);
init_smb_file_time(&ft);
smb_fname_tmp = cp_smb_filename(talloc_tos(), smb_fname);
if (smb_fname_tmp == NULL) {

View File

@ -313,13 +313,16 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
}
if (fsp->write_time_forced) {
struct timespec ts;
DEBUG(10,("close_remove_share_mode: write time forced "
"for file %s\n",
fsp_str_dbg(fsp)));
set_close_write_time(fsp, lck->data->changed_write_time);
ts = nt_time_to_full_timespec(lck->data->changed_write_time);
set_close_write_time(fsp, ts);
} else if (fsp->update_write_time_on_close) {
/* Someone had a pending write. */
if (null_timespec(fsp->close_write_time)) {
if (is_omit_timespec(&fsp->close_write_time)) {
DEBUG(10,("close_remove_share_mode: update to current time "
"for file %s\n",
fsp_str_dbg(fsp)));
@ -548,7 +551,7 @@ void set_close_write_time(struct files_struct *fsp, struct timespec ts)
{
DEBUG(6,("close_write_time: %s" , time_to_asc(convert_timespec_to_time_t(ts))));
if (null_timespec(ts)) {
if (is_omit_timespec(&ts)) {
return;
}
fsp->write_time_forced = false;
@ -562,13 +565,13 @@ static NTSTATUS update_write_time_on_close(struct files_struct *fsp)
NTSTATUS status;
struct share_mode_lock *lck = NULL;
ZERO_STRUCT(ft);
init_smb_file_time(&ft);
if (!fsp->update_write_time_on_close) {
return NT_STATUS_OK;
}
if (null_timespec(fsp->close_write_time)) {
if (is_omit_timespec(&fsp->close_write_time)) {
fsp->close_write_time = timespec_current();
}
@ -603,7 +606,7 @@ static NTSTATUS update_write_time_on_close(struct files_struct *fsp)
/* Close write times overwrite sticky write times
so we must replace any sticky write time here. */
if (!null_timespec(lck->data->changed_write_time)) {
if (!null_nttime(lck->data->changed_write_time)) {
(void)set_sticky_write_time(fsp->file_id, fsp->close_write_time);
}
TALLOC_FREE(lck);

View File

@ -899,7 +899,7 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx,
fileid = vfs_file_id_from_sbuf(conn,
&smb_fname.st);
get_file_infos(fileid, 0, NULL, &write_time_ts);
if (!null_timespec(write_time_ts)) {
if (!is_omit_timespec(&write_time_ts)) {
update_stat_ex_mtime(&smb_fname.st,
write_time_ts);
}

View File

@ -313,7 +313,7 @@ NTSTATUS parse_dos_attribute_blob(struct smb_filename *smb_fname,
if ((dosattrib.info.info3.valid_flags & XATTR_DOSINFO_CREATE_TIME) &&
!null_nttime(dosattrib.info.info3.create_time)) {
struct timespec create_time =
nt_time_to_unix_timespec(
nt_time_to_full_timespec(
dosattrib.info.info3.create_time);
update_stat_ex_create_time(&smb_fname->st,
@ -336,7 +336,7 @@ NTSTATUS parse_dos_attribute_blob(struct smb_filename *smb_fname,
{
struct timespec creat_time;
creat_time = nt_time_to_unix_timespec(info->create_time);
creat_time = nt_time_to_full_timespec(info->create_time);
update_stat_ex_create_time(&smb_fname->st, creat_time);
DBG_DEBUG("file [%s] creation time [%s]\n",
@ -492,13 +492,13 @@ NTSTATUS set_ea_dos_attribute(connection_struct *conn,
dosattrib.info.info4.valid_flags = XATTR_DOSINFO_ATTRIB |
XATTR_DOSINFO_CREATE_TIME;
dosattrib.info.info4.attrib = dosmode;
dosattrib.info.info4.create_time = unix_timespec_to_nt_time(
smb_fname->st.st_ex_btime);
dosattrib.info.info4.create_time = full_timespec_to_nt_time(
&smb_fname->st.st_ex_btime);
if (!(smb_fname->st.st_ex_iflags & ST_EX_IFLAG_CALCULATED_ITIME)) {
dosattrib.info.info4.valid_flags |= XATTR_DOSINFO_ITIME;
dosattrib.info.info4.itime = unix_timespec_to_nt_time(
smb_fname->st.st_ex_itime);
dosattrib.info.info4.itime = full_timespec_to_nt_time(
&smb_fname->st.st_ex_itime);
}
DEBUG(10,("set_ea_dos_attributes: set attribute 0x%x, btime = %s on file %s\n",
@ -1270,7 +1270,7 @@ int file_ntimes(connection_struct *conn, const struct smb_filename *smb_fname,
bool set_sticky_write_time_path(struct file_id fileid, struct timespec mtime)
{
if (null_timespec(mtime)) {
if (is_omit_timespec(&mtime)) {
return true;
}
@ -1288,7 +1288,7 @@ bool set_sticky_write_time_path(struct file_id fileid, struct timespec mtime)
bool set_sticky_write_time_fsp(struct files_struct *fsp, struct timespec mtime)
{
if (null_timespec(mtime)) {
if (is_omit_timespec(&mtime)) {
return true;
}

View File

@ -104,7 +104,8 @@ NTSTATUS vfs_default_durable_cookie(struct files_struct *fsp,
cookie.update_write_time_triggered = fsp->update_write_time_triggered;
cookie.update_write_time_on_close = fsp->update_write_time_on_close;
cookie.write_time_forced = fsp->write_time_forced;
cookie.close_write_time = fsp->close_write_time;
cookie.close_write_time = full_timespec_to_nt_time(
&fsp->close_write_time);
cookie.stat_info.st_ex_dev = fsp->fsp_name->st.st_ex_dev;
cookie.stat_info.st_ex_ino = fsp->fsp_name->st.st_ex_ino;
@ -205,19 +206,20 @@ NTSTATUS vfs_default_durable_disconnect(struct files_struct *fsp,
if (lck != NULL) {
struct smb_file_time ft;
ZERO_STRUCT(ft);
init_smb_file_time(&ft);
if (fsp->write_time_forced) {
ft.mtime = lck->data->changed_write_time;
ft.mtime = nt_time_to_full_timespec(
lck->data->changed_write_time);
} else if (fsp->update_write_time_on_close) {
if (null_timespec(fsp->close_write_time)) {
if (is_omit_timespec(&fsp->close_write_time)) {
ft.mtime = timespec_current();
} else {
ft.mtime = fsp->close_write_time;
}
}
if (!null_timespec(ft.mtime)) {
if (!is_omit_timespec(&ft.mtime)) {
round_timespec(conn->ts_res, &ft.mtime);
file_ntimes(conn, fsp->fsp_name, &ft);
}
@ -253,7 +255,8 @@ NTSTATUS vfs_default_durable_disconnect(struct files_struct *fsp,
cookie.update_write_time_triggered = fsp->update_write_time_triggered;
cookie.update_write_time_on_close = fsp->update_write_time_on_close;
cookie.write_time_forced = fsp->write_time_forced;
cookie.close_write_time = fsp->close_write_time;
cookie.close_write_time = full_timespec_to_nt_time(
&fsp->close_write_time);
cookie.stat_info.st_ex_dev = fsp->fsp_name->st.st_ex_dev;
cookie.stat_info.st_ex_ino = fsp->fsp_name->st.st_ex_ino;
@ -748,7 +751,8 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn,
fsp->update_write_time_triggered = cookie.update_write_time_triggered;
fsp->update_write_time_on_close = cookie.update_write_time_on_close;
fsp->write_time_forced = cookie.write_time_forced;
fsp->close_write_time = cookie.close_write_time;
fsp->close_write_time = nt_time_to_full_timespec(
cookie.close_write_time);
status = fsp_set_smb_fname(fsp, smb_fname);
if (!NT_STATUS_IS_OK(status)) {

View File

@ -178,6 +178,8 @@ void trigger_write_time_update_immediate(struct files_struct *fsp)
{
struct smb_file_time ft;
init_smb_file_time(&ft);
if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) {
/* Don't use delayed writes on POSIX files. */
return;
@ -199,7 +201,7 @@ void trigger_write_time_update_immediate(struct files_struct *fsp)
fsp->update_write_time_triggered = true;
fsp->update_write_time_on_close = false;
ft = (struct smb_file_time) { .mtime = timespec_current() };
ft.mtime = timespec_current();
/* Update the time in the open file db. */
(void)set_write_time(fsp->file_id, ft.mtime);

View File

@ -65,6 +65,7 @@ NTSTATUS fsp_new(struct connection_struct *conn, TALLOC_CTX *mem_ctx,
fsp->fnum = FNUM_FIELD_INVALID;
fsp->conn = conn;
fsp->close_write_time = make_omit_timespec();
DLIST_ADD(sconn->files, fsp);
sconn->num_files += 1;

View File

@ -4035,7 +4035,7 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
*/
struct timespec write_time = get_share_mode_write_time(lck);
if (!null_timespec(write_time)) {
if (!is_omit_timespec(&write_time)) {
update_stat_ex_mtime(&fsp->fsp_name->st, write_time);
}
}
@ -4398,7 +4398,7 @@ static NTSTATUS open_directory(connection_struct *conn,
we only update timestamps on file writes.
See bug #9870.
*/
ZERO_STRUCT(mtimespec);
mtimespec = make_omit_timespec();
#ifdef O_DIRECTORY
status = fd_open(conn, fsp, O_RDONLY|O_DIRECTORY, 0);
@ -4523,7 +4523,7 @@ static NTSTATUS open_directory(connection_struct *conn,
*/
struct timespec write_time = get_share_mode_write_time(lck);
if (!null_timespec(write_time)) {
if (!is_omit_timespec(&write_time)) {
update_stat_ex_mtime(&fsp->fsp_name->st, write_time);
}
}

View File

@ -1449,7 +1449,7 @@ void reply_getatr(struct smb_request *req)
ZERO_STRUCT(write_time_ts);
fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
get_file_infos(fileid, 0, NULL, &write_time_ts);
if (!null_timespec(write_time_ts)) {
if (!is_omit_timespec(&write_time_ts)) {
update_stat_ex_mtime(&smb_fname->st, write_time_ts);
}
}
@ -1503,6 +1503,7 @@ void reply_setatr(struct smb_request *req)
TALLOC_CTX *ctx = talloc_tos();
START_PROFILE(SMBsetatr);
init_smb_file_time(&ft);
if (req->wct < 2) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
@ -1565,9 +1566,7 @@ void reply_setatr(struct smb_request *req)
}
}
ft = (struct smb_file_time) {
.mtime = convert_time_t_to_timespec(mtime)
};
ft.mtime = time_t_to_full_timespec(mtime);
status = smb_set_file_time(conn, NULL, smb_fname, &ft, true);
if (!NT_STATUS_IS_OK(status)) {
@ -2688,7 +2687,7 @@ void reply_mknew(struct smb_request *req)
TALLOC_CTX *ctx = talloc_tos();
START_PROFILE(SMBcreate);
ZERO_STRUCT(ft);
init_smb_file_time(&ft);
if (req->wct < 3) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
@ -2707,7 +2706,7 @@ void reply_mknew(struct smb_request *req)
}
/* mtime. */
ft.mtime = convert_time_t_to_timespec(srv_make_unix_date3(req->vwv+1));
ft.mtime = time_t_to_full_timespec(srv_make_unix_date3(req->vwv+1));
srvstr_get_path_req(ctx, req, &fname, (const char *)req->buf + 1,
STR_TERMINATE, &status);
@ -5633,7 +5632,7 @@ void reply_close(struct smb_request *req)
*/
t = srv_make_unix_date3(req->vwv+1);
set_close_write_time(fsp, convert_time_t_to_timespec(t));
set_close_write_time(fsp, time_t_to_full_timespec(t));
}
if (fsp->num_aio_requests != 0) {
@ -5770,7 +5769,7 @@ void reply_writeclose(struct smb_request *req)
numtowrite = SVAL(req->vwv+1, 0);
startpos = IVAL_TO_SMB_OFF_T(req->vwv+2, 0);
mtime = convert_time_t_to_timespec(srv_make_unix_date3(req->vwv+4));
mtime = time_t_to_full_timespec(srv_make_unix_date3(req->vwv+4));
data = (const char *)req->buf + 1;
/*
@ -8791,7 +8790,7 @@ void reply_setattrE(struct smb_request *req)
NTSTATUS status;
START_PROFILE(SMBsetattrE);
ZERO_STRUCT(ft);
init_smb_file_time(&ft);
if (req->wct < 7) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
@ -8809,11 +8808,11 @@ void reply_setattrE(struct smb_request *req)
* Convert the DOS times into unix times.
*/
ft.atime = convert_time_t_to_timespec(
ft.atime = time_t_to_full_timespec(
srv_make_unix_date2(req->vwv+3));
ft.mtime = convert_time_t_to_timespec(
ft.mtime = time_t_to_full_timespec(
srv_make_unix_date2(req->vwv+5));
ft.create_time = convert_time_t_to_timespec(
ft.create_time = time_t_to_full_timespec(
srv_make_unix_date2(req->vwv+1));
reply_outbuf(req, 0, 0);

View File

@ -1325,8 +1325,8 @@ static void smbd_smb2_create_after_exec(struct tevent_req *req)
if (state->mxac != NULL) {
NTTIME last_write_time;
last_write_time = unix_timespec_to_nt_time(
state->result->fsp_name->st.st_ex_mtime);
last_write_time = full_timespec_to_nt_time(
&state->result->fsp_name->st.st_ex_mtime);
if (last_write_time != state->max_access_time) {
uint8_t p[8];
uint32_t max_access_granted;

View File

@ -930,7 +930,7 @@ static void fetch_write_time_done(struct tevent_req *subreq)
write_time = get_share_mode_write_time(lck);
TALLOC_FREE(lck);
if (null_timespec(write_time)) {
if (is_omit_timespec(&write_time)) {
tevent_req_done(req);
return;
}

View File

@ -26,6 +26,7 @@
#include "includes.h"
#include "ntioctl.h"
#include "system/filesys.h"
#include "lib/util/time_basic.h"
#include "version.h"
#include "smbd/smbd.h"
#include "smbd/globals.h"
@ -5220,7 +5221,9 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
dstart = pdata;
dend = dstart + data_size - 1;
if (!null_timespec(write_time_ts) && !INFO_LEVEL_IS_UNIX(info_level)) {
if (!is_omit_timespec(&write_time_ts) &&
!INFO_LEVEL_IS_UNIX(info_level))
{
update_stat_ex_mtime(psbuf, write_time_ts);
}
@ -6500,6 +6503,7 @@ NTSTATUS smb_set_file_time(connection_struct *conn,
bool setting_write_time)
{
struct smb_filename smb_fname_base;
struct timeval_buf tbuf[4];
uint32_t action =
FILE_NOTIFY_CHANGE_LAST_ACCESS
|FILE_NOTIFY_CHANGE_LAST_WRITE
@ -6510,15 +6514,15 @@ NTSTATUS smb_set_file_time(connection_struct *conn,
}
/* get some defaults (no modifications) if any info is zero or -1. */
if (null_timespec(ft->create_time)) {
if (is_omit_timespec(&ft->create_time)) {
action &= ~FILE_NOTIFY_CHANGE_CREATION;
}
if (null_timespec(ft->atime)) {
if (is_omit_timespec(&ft->atime)) {
action &= ~FILE_NOTIFY_CHANGE_LAST_ACCESS;
}
if (null_timespec(ft->mtime)) {
if (is_omit_timespec(&ft->mtime)) {
action &= ~FILE_NOTIFY_CHANGE_LAST_WRITE;
}
@ -6535,14 +6539,14 @@ NTSTATUS smb_set_file_time(connection_struct *conn,
round_timespec(conn->ts_res, &ft->atime);
round_timespec(conn->ts_res, &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 ",
time_to_asc(convert_timespec_to_time_t(ft->mtime))));
DEBUG(5,("smb_set_filetime: ctime: %s\n ",
time_to_asc(convert_timespec_to_time_t(ft->ctime))));
DEBUG(5,("smb_set_file_time: createtime: %s\n ",
time_to_asc(convert_timespec_to_time_t(ft->create_time))));
DBG_DEBUG("smb_set_filetime: actime: %s\n ",
timespec_string_buf(&ft->atime, true, &tbuf[0]));
DBG_DEBUG("smb_set_filetime: modtime: %s\n ",
timespec_string_buf(&ft->mtime, true, &tbuf[1]));
DBG_DEBUG("smb_set_filetime: ctime: %s\n ",
timespec_string_buf(&ft->ctime, true, &tbuf[2]));
DBG_DEBUG("smb_set_file_time: createtime: %s\n ",
timespec_string_buf(&ft->create_time, true, &tbuf[3]));
if (setting_write_time) {
/*
@ -6555,8 +6559,8 @@ NTSTATUS smb_set_file_time(connection_struct *conn,
* away and will set it on file close and after a write. JRA.
*/
DEBUG(10,("smb_set_file_time: setting pending modtime to %s\n",
time_to_asc(convert_timespec_to_time_t(ft->mtime))));
DBG_DEBUG("setting pending modtime to %s\n",
timespec_string_buf(&ft->mtime, true, &tbuf[0]));
if (fsp != NULL) {
if (fsp->base_fsp) {
@ -7780,7 +7784,7 @@ static NTSTATUS smb_set_file_basic_info(connection_struct *conn,
uint32_t dosmode = 0;
NTSTATUS status = NT_STATUS_OK;
ZERO_STRUCT(ft);
init_smb_file_time(&ft);
if (total_data < 36) {
return NT_STATUS_INVALID_PARAMETER;
@ -7830,18 +7834,18 @@ static NTSTATUS smb_set_info_standard(connection_struct *conn,
NTSTATUS status;
struct smb_file_time ft;
ZERO_STRUCT(ft);
init_smb_file_time(&ft);
if (total_data < 12) {
return NT_STATUS_INVALID_PARAMETER;
}
/* create time */
ft.create_time = convert_time_t_to_timespec(srv_make_unix_date2(pdata));
ft.create_time = time_t_to_full_timespec(srv_make_unix_date2(pdata));
/* access time */
ft.atime = convert_time_t_to_timespec(srv_make_unix_date2(pdata+4));
ft.atime = time_t_to_full_timespec(srv_make_unix_date2(pdata+4));
/* write time */
ft.mtime = convert_time_t_to_timespec(srv_make_unix_date2(pdata+8));
ft.mtime = time_t_to_full_timespec(srv_make_unix_date2(pdata+8));
DEBUG(10,("smb_set_info_standard: file %s\n",
smb_fname_str_dbg(smb_fname)));
@ -8122,7 +8126,7 @@ static NTSTATUS smb_set_file_unix_basic(connection_struct *conn,
struct file_id id;
SMB_STRUCT_STAT sbuf;
ZERO_STRUCT(ft);
init_smb_file_time(&ft);
if (total_data < 100) {
return NT_STATUS_INVALID_PARAMETER;
@ -8281,7 +8285,7 @@ static NTSTATUS smb_set_file_unix_basic(connection_struct *conn,
}
/* Deal with any time changes. */
if (null_timespec(ft.mtime) && null_timespec(ft.atime)) {
if (is_omit_timespec(&ft.mtime) && is_omit_timespec(&ft.atime)) {
/* No change, don't cancel anything. */
return status;
}
@ -8303,7 +8307,7 @@ static NTSTATUS smb_set_file_unix_basic(connection_struct *conn,
* we need. Just remember if we modified
* mtime and send the notify ourselves.
*/
if (null_timespec(ft.mtime)) {
if (is_omit_timespec(&ft.mtime)) {
modify_mtime = false;
}

View File

@ -1003,10 +1003,10 @@ static NTSTATUS cmd_utime(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
return NT_STATUS_OK;
}
ZERO_STRUCT(ft);
init_smb_file_time(&ft);
ft.atime = convert_time_t_to_timespec(atoi(argv[2]));
ft.mtime = convert_time_t_to_timespec(atoi(argv[3]));
ft.atime = time_t_to_full_timespec(atoi(argv[2]));
ft.mtime = time_t_to_full_timespec(atoi(argv[3]));
smb_fname = synthetic_smb_fname_split(mem_ctx,
argv[1],