smbd: fix handling of sentinel timestamp values
authorRalph Boehme <slow@samba.org>
Mon, 2 Dec 2019 15:30:50 +0000 (16:30 +0100)
committerJeremy Allison <jra@samba.org>
Fri, 6 Dec 2019 00:17:36 +0000 (00:17 +0000)
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>
23 files changed:
selftest/knownfail.d/samba3.smb2 [deleted file]
source3/include/vfs.h
source3/librpc/idl/open_files.idl
source3/locking/locking.c
source3/locking/share_mode_lock.c
source3/modules/vfs_ceph.c
source3/modules/vfs_default.c
source3/modules/vfs_fruit.c
source3/modules/vfs_glusterfs.c
source3/modules/vfs_gpfs.c
source3/modules/vfs_recycle.c
source3/smbd/close.c
source3/smbd/dir.c
source3/smbd/dosmode.c
source3/smbd/durable.c
source3/smbd/fileio.c
source3/smbd/files.c
source3/smbd/open.c
source3/smbd/reply.c
source3/smbd/smb2_create.c
source3/smbd/smb2_query_directory.c
source3/smbd/trans2.c
source3/torture/cmd_vfs.c

diff --git a/selftest/knownfail.d/samba3.smb2 b/selftest/knownfail.d/samba3.smb2
deleted file mode 100644 (file)
index 8346ce9..0000000
+++ /dev/null
@@ -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\)
index a6c57c6bcbc3d2912e80908d4e884b4e8e9db9e5..28a3ce6054379e21beb19a5f5418970cb9d1004c 100644 (file)
                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
 
index 8742a38dfa6832def22eb53d640642b0a86aa5d5..4bfadb5656a1e6efba93b90c63c57e7e4f980431 100644 (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;
 
index 7822c2b3665844c16b5e87c47a0d1d99c9cf5e35..1220cb3a2be1656b2dc07e1979771190612bf008 100644 (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 {
index edf47274d29389c024139d6f3d9bfbc539022e71..4697b6d9eee84d5567bf85d590adb001658ba3d3 100644 (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;
index 8864b42400849e4297a3ffdb985180c881d99458..82bcb154f77271e0277f559103e0b5d58eed3ce9 100644 (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);
        }
index 368f1e255665d8875c150281d65c06771a547acc..5666e09f60b5a1392b3f5a05e8dd111f22fb060a 100644 (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);
index 265abdcb304ab5f5b2f5664e7f7d378b5632cc4a..ebf3e18af2f25a22db2f7d9b1012b992f1caed81 100644 (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);
        }
index d67ba89391c650f218b90589ffc5c74aba376771..6c3995b716819c597c980c0341997ebaa7988218 100644 (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 {
index 558f57c2417b9261090e60e738f4324461d38d7a..25df3266902a180a722cabc53c725979711ab5c1 100644 (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;
         }
index 6c8c6a76f30f37eb840e9644268ad046f436577c..a1d32bf10cbdc7973f11c0d7d141a8d3ef81d2fc 100644 (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) {
index 6b63ea2c64eee076f44ccd2fb7c0f5da09cb0768..f45371e656c70887c51caf3a32dd5be4fb574b03 100644 (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);
index 49e8dd17451ee0aac53d2365a1f5a1cf2b60096c..8314f4084c0faf822693b48d2a5302272d4d3117 100644 (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);
                        }
index b4ca23741181ab65b89e74f4b36c82e62ac946b4..322bf4476d6b466495ccc65498485054183884a7 100644 (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;
        }
 
index 9a2e639bdcd0910bc529a62ec2ff9b51014e02fe..9a4ebfb12d289b26153794d00fbea15a3de4ff81 100644 (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)) {
index b03f86d49d67235a6e89539205f591a9fadce19e..029965282f1b6317875a01b8f465e245c3f46d3c 100644 (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);
index 077610cad75437e5cd55e702e85cfd753eea4e8c..979477531705e05fa417f306c531822b9065bfde 100644 (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;
index d7202d015cb1802f8372d8be2b3a7b0f9701a31e..d3d77cee6319bc2ec5c3dc57b899c1407e52ca6a 100644 (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);
                }
        }
index 5c173539aad9fb382b88a3aa09c0135888db686c..f2d0b878e202146995352b19dca51acea65118e3 100644 (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);
index 1a3af78acf2d4c24af9f736cf6348c7523f58300..bf0c3912c076aadef58469fe03b36b87487555b9 100644 (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;
index 94d2144ad26c243a915d0f9c890fd754b0f53f08..79a46e005cfe6896fd100e98ae20db322b2f691a 100644 (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;
        }
index ed5a52beb86916803eb0a4fc47fa6efc3556723b..9c77b32ee68b97fb6df2756078f7fb5f2dccd658 100644 (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;
        }
 
index fb9615e26a356300d4538f69c750845c50ae51fb..81068fb84a015314771b4ecda958ba70b8adb6c0 100644 (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],