diff options
author | todd stecher <todd.stecher@gmail.com> | 2009-01-23 14:40:19 -0800 |
---|---|---|
committer | Tim Prouty <tprouty@samba.org> | 2009-01-23 21:05:38 -0800 |
commit | 48b0016cff4bad621b94fc0bf678ec15260dd7d7 (patch) | |
tree | 960f825709d1a8eb2af5fb0afb31553262ee290f /source3 | |
parent | 7bb3860f49cd8b09c2015f6646c07fe5ebaa0de3 (diff) | |
download | samba-48b0016cff4bad621b94fc0bf678ec15260dd7d7.tar.gz samba-48b0016cff4bad621b94fc0bf678ec15260dd7d7.tar.bz2 samba-48b0016cff4bad621b94fc0bf678ec15260dd7d7.zip |
Extend NTIMES to allow setting create_time
1) Add in smb_file_time struct to clarify code and make room for createtime.
2) Get and set create time from SMB messages.
3) Fixup existing VFS modules + examples Some OS'es allow for the
setting of the birthtime through kernel interfaces. This value is
generically used for Windows createtime, but is not settable in the
code today.
Diffstat (limited to 'source3')
-rw-r--r-- | source3/include/proto.h | 5 | ||||
-rw-r--r-- | source3/include/smb.h | 7 | ||||
-rw-r--r-- | source3/include/vfs.h | 4 | ||||
-rw-r--r-- | source3/modules/vfs_cap.c | 5 | ||||
-rw-r--r-- | source3/modules/vfs_catia.c | 4 | ||||
-rw-r--r-- | source3/modules/vfs_default.c | 15 | ||||
-rw-r--r-- | source3/modules/vfs_full_audit.c | 6 | ||||
-rw-r--r-- | source3/modules/vfs_recycle.c | 10 | ||||
-rw-r--r-- | source3/modules/vfs_shadow_copy2.c | 4 | ||||
-rw-r--r-- | source3/smbd/close.c | 8 | ||||
-rw-r--r-- | source3/smbd/dosmode.c | 13 | ||||
-rw-r--r-- | source3/smbd/reply.c | 46 | ||||
-rw-r--r-- | source3/smbd/trans2.c | 99 | ||||
-rw-r--r-- | source3/torture/cmd_vfs.c | 11 |
14 files changed, 141 insertions, 96 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h index 1554bfdb25..1414ba89ec 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -6688,7 +6688,8 @@ int file_set_dosmode(connection_struct *conn, const char *fname, uint32 dosmode, SMB_STRUCT_STAT *st, const char *parent_dir, bool newfile); -int file_ntimes(connection_struct *conn, const char *fname, const struct timespec ts[2]); +int file_ntimes(connection_struct *conn, const char *fname, + struct smb_file_time *ft); bool set_sticky_write_time_path(connection_struct *conn, const char *fname, struct file_id fileid, const struct timespec mtime); bool set_sticky_write_time_fsp(struct files_struct *fsp, const struct timespec mtime); @@ -7424,7 +7425,7 @@ NTSTATUS smb_set_file_time(connection_struct *conn, files_struct *fsp, const char *fname, const SMB_STRUCT_STAT *psbuf, - struct timespec ts[2], + struct smb_file_time *ft, bool setting_write_time); void reply_findclose(struct smb_request *req); void reply_findnclose(struct smb_request *req); diff --git a/source3/include/smb.h b/source3/include/smb.h index 19d2208ada..aa2db693a3 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -1901,4 +1901,11 @@ struct smb_extended_info { */ #define CFF_DOS_PATH 0x00000001 +/* time info */ +struct smb_file_time { + struct timespec mtime; + struct timespec atime; + struct timespec create_time; +}; + #endif /* _SMB_H */ diff --git a/source3/include/vfs.h b/source3/include/vfs.h index d02d14b854..5df71da905 100644 --- a/source3/include/vfs.h +++ b/source3/include/vfs.h @@ -111,6 +111,7 @@ /* Changed to version 24 - make security descriptor const in fset_nt_acl. JRA. */ /* Changed to version 25 - Jelmer's change from SMB_BIG_UINT to uint64_t. */ /* Leave at 25 - not yet released. Add create_file call. -- tprouty. */ +/* Leave at 25 - not yet released. Add create time to ntimes. -- tstecher. */ #define SMB_VFS_INTERFACE_VERSION 25 @@ -137,6 +138,7 @@ struct security_descriptor; struct vfs_statvfs_struct; struct smb_request; struct ea_list; +struct smb_file_time; /* Available VFS operations. These values must be in sync with vfs_ops struct @@ -348,7 +350,7 @@ struct vfs_ops { int (*lchown)(struct vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid); int (*chdir)(struct vfs_handle_struct *handle, const char *path); char *(*getwd)(struct vfs_handle_struct *handle, char *buf); - int (*ntimes)(struct vfs_handle_struct *handle, const char *path, const struct timespec ts[2]); + int (*ntimes)(struct vfs_handle_struct *handle, const char *path, struct smb_file_time *ft); int (*ftruncate)(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_OFF_T offset); bool (*lock)(struct vfs_handle_struct *handle, struct files_struct *fsp, int op, SMB_OFF_T offset, SMB_OFF_T count, int type); int (*kernel_flock)(struct vfs_handle_struct *handle, struct files_struct *fsp, uint32 share_mode); diff --git a/source3/modules/vfs_cap.c b/source3/modules/vfs_cap.c index 6950ab2168..ac85d3a804 100644 --- a/source3/modules/vfs_cap.c +++ b/source3/modules/vfs_cap.c @@ -208,7 +208,8 @@ static int cap_chdir(vfs_handle_struct *handle, const char *path) return SMB_VFS_NEXT_CHDIR(handle, cappath); } -static int cap_ntimes(vfs_handle_struct *handle, const char *path, const struct timespec ts[2]) +static int cap_ntimes(vfs_handle_struct *handle, const char *path, + struct smb_file_time *ft) { char *cappath = capencode(talloc_tos(), path); @@ -216,7 +217,7 @@ static int cap_ntimes(vfs_handle_struct *handle, const char *path, const struct errno = ENOMEM; return -1; } - return SMB_VFS_NEXT_NTIMES(handle, cappath, ts); + return SMB_VFS_NEXT_NTIMES(handle, cappath, ft); } diff --git a/source3/modules/vfs_catia.c b/source3/modules/vfs_catia.c index 47d178a33f..d0c341fdd3 100644 --- a/source3/modules/vfs_catia.c +++ b/source3/modules/vfs_catia.c @@ -252,9 +252,9 @@ static char *catia_getwd(vfs_handle_struct *handle, char *buf) } static int catia_ntimes(vfs_handle_struct *handle, - const char *path, const struct timespec ts[2]) + const char *path, struct smb_file_time *ft) { - return SMB_VFS_NEXT_NTIMES(handle, path, ts); + return SMB_VFS_NEXT_NTIMES(handle, path, ft); } static bool catia_symlink(vfs_handle_struct *handle, diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index 61e1deb81e..a9aabab768 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -682,25 +682,26 @@ static char *vfswrap_getwd(vfs_handle_struct *handle, char *path) system will support. **********************************************************************/ -static int vfswrap_ntimes(vfs_handle_struct *handle, const char *path, const struct timespec ts[2]) +static int vfswrap_ntimes(vfs_handle_struct *handle, const char *path, + struct smb_file_time *ft) { int result; START_PROFILE(syscall_ntimes); #if defined(HAVE_UTIMES) - if (ts != NULL) { + if (ft != NULL) { struct timeval tv[2]; - tv[0] = convert_timespec_to_timeval(ts[0]); - tv[1] = convert_timespec_to_timeval(ts[1]); + tv[0] = convert_timespec_to_timeval(ft->atime); + tv[1] = convert_timespec_to_timeval(ft->mtime); result = utimes(path, tv); } else { result = utimes(path, NULL); } #elif defined(HAVE_UTIME) - if (ts != NULL) { + if (ft != NULL) { struct utimbuf times; - times.actime = convert_timespec_to_time_t(ts[0]); - times.modtime = convert_timespec_to_time_t(ts[1]); + times.actime = convert_timespec_to_time_t(ft->atime); + times.modtime = convert_timespec_to_time_t(ft->mtime); result = utime(path, times); } else { result = utime(path, NULL); diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c index 1d9983a753..73758a2d9d 100644 --- a/source3/modules/vfs_full_audit.c +++ b/source3/modules/vfs_full_audit.c @@ -172,7 +172,7 @@ static int smb_full_audit_chdir(vfs_handle_struct *handle, static char *smb_full_audit_getwd(vfs_handle_struct *handle, char *path); static int smb_full_audit_ntimes(vfs_handle_struct *handle, - const char *path, const struct timespec ts[2]); + const char *path, struct smb_file_time *ft); static int smb_full_audit_ftruncate(vfs_handle_struct *handle, files_struct *fsp, SMB_OFF_T len); static bool smb_full_audit_lock(vfs_handle_struct *handle, files_struct *fsp, @@ -1426,11 +1426,11 @@ static char *smb_full_audit_getwd(vfs_handle_struct *handle, } static int smb_full_audit_ntimes(vfs_handle_struct *handle, - const char *path, const struct timespec ts[2]) + const char *path, struct smb_file_time *ft) { int result; - result = SMB_VFS_NEXT_NTIMES(handle, path, ts); + result = SMB_VFS_NEXT_NTIMES(handle, path, ft); do_log(SMB_VFS_OP_NTIMES, (result >= 0), handle, "%s", path); diff --git a/source3/modules/vfs_recycle.c b/source3/modules/vfs_recycle.c index cb985e1be2..2b0edcdb4a 100644 --- a/source3/modules/vfs_recycle.c +++ b/source3/modules/vfs_recycle.c @@ -391,19 +391,21 @@ static void recycle_do_touch(vfs_handle_struct *handle, const char *fname, bool touch_mtime) { SMB_STRUCT_STAT st; - struct timespec ts[2]; + struct smb_file_time ft; int ret, err; + ZERO_STRUCT(ft); + if (SMB_VFS_NEXT_STAT(handle, fname, &st) != 0) { DEBUG(0,("recycle: stat for %s returned %s\n", fname, strerror(errno))); return; } - ts[0] = timespec_current(); /* atime */ - ts[1] = touch_mtime ? ts[0] : get_mtimespec(&st); /* mtime */ + ft.atime = timespec_current(); /* atime */ + ft.mtime = touch_mtime ? ft.atime : get_mtimespec(&st); /* mtime */ become_root(); - ret = SMB_VFS_NEXT_NTIMES(handle, fname, ts); + ret = SMB_VFS_NEXT_NTIMES(handle, fname, &ft); err = errno; unbecome_root(); if (ret == -1 ) { diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c index c95600b642..56dd6ea8d8 100644 --- a/source3/modules/vfs_shadow_copy2.c +++ b/source3/modules/vfs_shadow_copy2.c @@ -393,9 +393,9 @@ static int shadow_copy2_chdir(vfs_handle_struct *handle, } static int shadow_copy2_ntimes(vfs_handle_struct *handle, - const char *fname, const struct timespec ts[2]) + const char *fname, struct smb_file_time *ft) { - SHADOW2_NEXT(NTIMES, (handle, name, ts), int, -1); + SHADOW2_NEXT(NTIMES, (handle, name, ft), int, -1); } static int shadow_copy2_readlink(vfs_handle_struct *handle, diff --git a/source3/smbd/close.c b/source3/smbd/close.c index abcd651d93..2fb8ec2bb5 100644 --- a/source3/smbd/close.c +++ b/source3/smbd/close.c @@ -465,11 +465,11 @@ void set_close_write_time(struct files_struct *fsp, struct timespec ts) static NTSTATUS update_write_time_on_close(struct files_struct *fsp) { SMB_STRUCT_STAT sbuf; - struct timespec ts[2]; + struct smb_file_time ft; NTSTATUS status; ZERO_STRUCT(sbuf); - ZERO_STRUCT(ts); + ZERO_STRUCT(ft); if (!fsp->update_write_time_on_close) { return NT_STATUS_OK; @@ -495,9 +495,9 @@ static NTSTATUS update_write_time_on_close(struct files_struct *fsp) return NT_STATUS_OK; } - ts[1] = fsp->close_write_time; + ft.mtime = fsp->close_write_time; status = smb_set_file_time(fsp->conn, fsp, fsp->fsp_name, - &sbuf, ts, true); + &sbuf, &ft, true); if (!NT_STATUS_IS_OK(status)) { return status; } diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index ade5e66e86..555718bd83 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -704,7 +704,8 @@ int file_set_dosmode(connection_struct *conn, const char *fname, than POSIX. *******************************************************************/ -int file_ntimes(connection_struct *conn, const char *fname, const struct timespec ts[2]) +int file_ntimes(connection_struct *conn, const char *fname, + struct smb_file_time *ft) { SMB_STRUCT_STAT sbuf; int ret = -1; @@ -713,9 +714,11 @@ int file_ntimes(connection_struct *conn, const char *fname, const struct timespe ZERO_STRUCT(sbuf); DEBUG(6, ("file_ntime: actime: %s", - time_to_asc(convert_timespec_to_time_t(ts[0])))); + time_to_asc(convert_timespec_to_time_t(ft->atime)))); DEBUG(6, ("file_ntime: modtime: %s", - time_to_asc(convert_timespec_to_time_t(ts[1])))); + time_to_asc(convert_timespec_to_time_t(ft->mtime)))); + DEBUG(6, ("file_ntime: createtime: %s", + time_to_asc(convert_timespec_to_time_t(ft->create_time)))); /* Don't update the time on read-only shares */ /* We need this as set_filetime (which can be called on @@ -728,7 +731,7 @@ int file_ntimes(connection_struct *conn, const char *fname, const struct timespe return 0; } - if(SMB_VFS_NTIMES(conn, fname, ts) == 0) { + if(SMB_VFS_NTIMES(conn, fname, ft) == 0) { return 0; } @@ -750,7 +753,7 @@ int file_ntimes(connection_struct *conn, const char *fname, const struct timespe if (can_write_to_file(conn, fname, &sbuf)) { /* We are allowed to become root and change the filetime. */ become_root(); - ret = SMB_VFS_NTIMES(conn, fname, ts); + ret = SMB_VFS_NTIMES(conn, fname, ft); unbecome_root(); } diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 28836144c2..52dab0a013 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -1063,7 +1063,7 @@ void reply_getatr(struct smb_request *req) void reply_setatr(struct smb_request *req) { - struct timespec ts[2]; + struct smb_file_time ft; connection_struct *conn = req->conn; char *fname = NULL; int mode; @@ -1075,7 +1075,7 @@ void reply_setatr(struct smb_request *req) START_PROFILE(SMBsetatr); - ZERO_STRUCT(ts); + ZERO_STRUCT(ft); if (req->wct < 2) { reply_nterror(req, NT_STATUS_INVALID_PARAMETER); @@ -1133,9 +1133,9 @@ void reply_setatr(struct smb_request *req) mode = SVAL(req->vwv+0, 0); mtime = srv_make_unix_date3(req->vwv+1); - ts[1] = convert_time_t_to_timespec(mtime); + ft.mtime = convert_time_t_to_timespec(mtime); status = smb_set_file_time(conn, NULL, fname, - &sbuf, ts, true); + &sbuf, &ft, true); if (!NT_STATUS_IS_OK(status)) { reply_unixerror(req, ERRDOS, ERRnoaccess); END_PROFILE(SMBsetatr); @@ -1924,7 +1924,7 @@ void reply_mknew(struct smb_request *req) connection_struct *conn = req->conn; char *fname = NULL; uint32 fattr = 0; - struct timespec ts[2]; + struct smb_file_time ft; files_struct *fsp; int oplock_request = 0; SMB_STRUCT_STAT sbuf; @@ -1936,6 +1936,7 @@ void reply_mknew(struct smb_request *req) TALLOC_CTX *ctx = talloc_tos(); START_PROFILE(SMBcreate); + ZERO_STRUCT(ft); if (req->wct < 3) { reply_nterror(req, NT_STATUS_INVALID_PARAMETER); @@ -1946,8 +1947,8 @@ void reply_mknew(struct smb_request *req) fattr = SVAL(req->vwv+0, 0); oplock_request = CORE_OPLOCK_REQUEST(req->inbuf); - ts[1] = convert_time_t_to_timespec(srv_make_unix_date3(req->vwv+1)); - /* mtime. */ + /* mtime. */ + ft.mtime = convert_time_t_to_timespec(srv_make_unix_date3(req->vwv+1)); srvstr_get_path_req(ctx, req, &fname, (const char *)req->buf + 1, STR_TERMINATE, &status); @@ -1999,8 +2000,8 @@ void reply_mknew(struct smb_request *req) return; } - ts[0] = get_atimespec(&sbuf); /* atime. */ - status = smb_set_file_time(conn, fsp, fsp->fsp_name, &sbuf, ts, true); + ft.atime = get_atimespec(&sbuf); /* atime. */ + status = smb_set_file_time(conn, fsp, fsp->fsp_name, &sbuf, &ft, true); if (!NT_STATUS_IS_OK(status)) { END_PROFILE(SMBcreate); reply_openerror(req, status); @@ -7115,12 +7116,13 @@ void reply_readbs(struct smb_request *req) void reply_setattrE(struct smb_request *req) { connection_struct *conn = req->conn; - struct timespec ts[2]; + struct smb_file_time ft; files_struct *fsp; SMB_STRUCT_STAT sbuf; NTSTATUS status; START_PROFILE(SMBsetattrE); + ZERO_STRUCT(ft); if (req->wct < 7) { reply_nterror(req, NT_STATUS_INVALID_PARAMETER); @@ -7138,14 +7140,15 @@ void reply_setattrE(struct smb_request *req) /* - * Convert the DOS times into unix times. Ignore create - * time as UNIX can't set this. + * Convert the DOS times into unix times. */ - ts[0] = convert_time_t_to_timespec( - srv_make_unix_date2(req->vwv+3)); /* atime. */ - ts[1] = convert_time_t_to_timespec( - srv_make_unix_date2(req->vwv+5)); /* mtime. */ + ft.atime = convert_time_t_to_timespec( + srv_make_unix_date2(req->vwv+3)); + ft.mtime = convert_time_t_to_timespec( + srv_make_unix_date2(req->vwv+5)); + ft.create_time = convert_time_t_to_timespec( + srv_make_unix_date2(req->vwv+1)); reply_outbuf(req, 0, 0); @@ -7172,17 +7175,20 @@ void reply_setattrE(struct smb_request *req) } status = smb_set_file_time(conn, fsp, fsp->fsp_name, - &sbuf, ts, true); + &sbuf, &ft, true); if (!NT_STATUS_IS_OK(status)) { reply_doserror(req, ERRDOS, ERRnoaccess); END_PROFILE(SMBsetattrE); return; } - DEBUG( 3, ( "reply_setattrE fnum=%d actime=%u modtime=%u\n", + DEBUG( 3, ( "reply_setattrE fnum=%d actime=%u modtime=%u " + " createtime=%u\n", fsp->fnum, - (unsigned int)ts[0].tv_sec, - (unsigned int)ts[1].tv_sec)); + (unsigned int)ft.atime.tv_sec, + (unsigned int)ft.mtime.tv_sec, + (unsigned int)ft.create_time.tv_sec + )); END_PROFILE(SMBsetattrE); return; diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 52340d5370..1b161d5338 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -1430,7 +1430,8 @@ static bool get_lanman2_dir_entry(TALLOC_CTX *ctx, mdate_ts = get_mtimespec(&sbuf); adate_ts = get_atimespec(&sbuf); - create_date_ts = get_create_timespec(&sbuf,lp_fake_dir_create_times(SNUM(conn))); + create_date_ts = get_create_timespec(&sbuf, + lp_fake_dir_create_times(SNUM(conn))); if (ask_sharemode) { struct timespec write_time_ts; @@ -1453,7 +1454,8 @@ static bool get_lanman2_dir_entry(TALLOC_CTX *ctx, mdate = convert_timespec_to_time_t(mdate_ts); adate = convert_timespec_to_time_t(adate_ts); - DEBUG(5,("get_lanman2_dir_entry: found %s fname=%s\n",pathreal,fname)); + DEBUG(5,("get_lanman2_dir_entry: found %s fname=%s\n", + pathreal,fname)); found = True; @@ -4892,7 +4894,7 @@ NTSTATUS smb_set_file_time(connection_struct *conn, files_struct *fsp, const char *fname, const SMB_STRUCT_STAT *psbuf, - struct timespec ts[2], + struct smb_file_time *ft, bool setting_write_time) { uint32 action = @@ -4904,23 +4906,29 @@ NTSTATUS smb_set_file_time(connection_struct *conn, } /* get some defaults (no modifications) if any info is zero or -1. */ - if (null_timespec(ts[0])) { - ts[0] = get_atimespec(psbuf); + if (null_timespec(ft->atime)) { + ft->atime= get_atimespec(psbuf); action &= ~FILE_NOTIFY_CHANGE_LAST_ACCESS; } - if (null_timespec(ts[1])) { - ts[1] = get_mtimespec(psbuf); + if (null_timespec(ft->mtime)) { + ft->mtime = get_mtimespec(psbuf); action &= ~FILE_NOTIFY_CHANGE_LAST_WRITE; } if (!setting_write_time) { - /* ts[1] comes from change time, not write time. */ + /* ft->mtime comes from change time, not write time. */ action &= ~FILE_NOTIFY_CHANGE_LAST_WRITE; } - DEBUG(6,("smb_set_file_time: actime: %s " , time_to_asc(convert_timespec_to_time_t(ts[0])) )); - DEBUG(6,("smb_set_file_time: modtime: %s ", time_to_asc(convert_timespec_to_time_t(ts[1])) )); + 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)))); + if (!null_timespec(ft->create_time)) { + DEBUG(5,("smb_set_file_time: createtime: %s\n ", + time_to_asc(convert_timespec_to_time_t(ft->create_time)))); + } /* * Try and set the times of this file if @@ -4930,7 +4938,8 @@ NTSTATUS smb_set_file_time(connection_struct *conn, { struct timespec mts = get_mtimespec(psbuf); struct timespec ats = get_atimespec(psbuf); - if ((timespec_compare(&ts[0], &ats) == 0) && (timespec_compare(&ts[1], &mts) == 0)) { + if ((timespec_compare(&ft->atime, &ats) == 0) && + (timespec_compare(&ft->mtime, &mts) == 0)) { return NT_STATUS_OK; } } @@ -4947,18 +4956,19 @@ NTSTATUS smb_set_file_time(connection_struct *conn, */ DEBUG(10,("smb_set_file_time: setting pending modtime to %s\n", - time_to_asc(convert_timespec_to_time_t(ts[1])) )); + time_to_asc(convert_timespec_to_time_t(ft->mtime)))); if (fsp != NULL) { if (fsp->base_fsp) { - set_sticky_write_time_fsp(fsp->base_fsp, ts[1]); + set_sticky_write_time_fsp(fsp->base_fsp, + ft->mtime); } else { - set_sticky_write_time_fsp(fsp, ts[1]); + set_sticky_write_time_fsp(fsp, ft->mtime); } } else { set_sticky_write_time_path(conn, fname, vfs_file_id_from_sbuf(conn, psbuf), - ts[1]); + ft->mtime); } } @@ -4968,7 +4978,7 @@ NTSTATUS smb_set_file_time(connection_struct *conn, fname = fsp->base_fsp->fsp_name; } - if(file_ntimes(conn, fname, ts)!=0) { + if(file_ntimes(conn, fname, ft)!=0) { return map_nt_error_from_unix(errno); } notify_fname(conn, NOTIFY_ACTION_MODIFIED, action, fname); @@ -5677,16 +5687,21 @@ static NTSTATUS smb_set_info_standard(connection_struct *conn, const char *fname, const SMB_STRUCT_STAT *psbuf) { - struct timespec ts[2]; + struct smb_file_time ft; + ZERO_STRUCT(ft); if (total_data < 12) { return NT_STATUS_INVALID_PARAMETER; } + /* create time */ + ft.create_time = interpret_long_date(pdata); + /* access time */ - ts[0] = convert_time_t_to_timespec(srv_make_unix_date2(pdata+l1_fdateLastAccess)); + ft.atime = interpret_long_date(pdata + 8); + /* write time */ - ts[1] = convert_time_t_to_timespec(srv_make_unix_date2(pdata+l1_fdateLastWrite)); + ft.mtime = interpret_long_date(pdata + 16); DEBUG(10,("smb_set_info_standard: file %s\n", fname ? fname : fsp->fsp_name )); @@ -5695,7 +5710,7 @@ static NTSTATUS smb_set_info_standard(connection_struct *conn, fsp, fname, psbuf, - ts, + &ft, true); } @@ -5713,47 +5728,49 @@ static NTSTATUS smb_set_file_basic_info(connection_struct *conn, /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */ struct timespec write_time; struct timespec changed_time; + struct smb_file_time ft; uint32 dosmode = 0; - struct timespec ts[2]; NTSTATUS status = NT_STATUS_OK; bool setting_write_time = true; + ZERO_STRUCT(ft); + if (total_data < 36) { return NT_STATUS_INVALID_PARAMETER; } /* Set the attributes */ dosmode = IVAL(pdata,32); - status = smb_set_file_dosmode(conn, - fname, - psbuf, - dosmode); + status = smb_set_file_dosmode(conn, fname, psbuf, dosmode); if (!NT_STATUS_IS_OK(status)) { return status; } - /* Ignore create time at offset pdata. */ /* access time */ - ts[0] = interpret_long_date(pdata+8); + ft.atime = interpret_long_date(pdata+8); write_time = interpret_long_date(pdata+16); changed_time = interpret_long_date(pdata+24); /* mtime */ - ts[1] = timespec_min(&write_time, &changed_time); + ft.mtime = timespec_min(&write_time, &changed_time); - if ((timespec_compare(&write_time, &ts[1]) == 1) && !null_timespec(write_time)) { - ts[1] = write_time; + /* create time */ + ft.create_time = interpret_long_date(pdata); + + if ((timespec_compare(&write_time, &ft.mtime) == 1) && + !null_timespec(write_time)) { + ft.mtime = write_time; } /* Prefer a defined time to an undefined one. */ - if (null_timespec(ts[1])) { + if (null_timespec(ft.mtime)) { if (null_timespec(write_time)) { - ts[1] = changed_time; + ft.mtime = changed_time; setting_write_time = false; } else { - ts[1] = write_time; + ft.mtime = write_time; } } @@ -5764,7 +5781,7 @@ static NTSTATUS smb_set_file_basic_info(connection_struct *conn, fsp, fname, psbuf, - ts, + &ft, setting_write_time); } @@ -6012,7 +6029,7 @@ static NTSTATUS smb_set_file_unix_basic(connection_struct *conn, const char *fname, SMB_STRUCT_STAT *psbuf) { - struct timespec ts[2]; + struct smb_file_time ft; uint32 raw_unixmode; mode_t unixmode; SMB_OFF_T size = 0; @@ -6022,6 +6039,8 @@ static NTSTATUS smb_set_file_unix_basic(connection_struct *conn, bool delete_on_fail = False; enum perm_type ptype; + ZERO_STRUCT(ft); + if (total_data < 100) { return NT_STATUS_INVALID_PARAMETER; } @@ -6039,8 +6058,8 @@ static NTSTATUS smb_set_file_unix_basic(connection_struct *conn, #endif /* LARGE_SMB_OFF_T */ } - ts[0] = interpret_long_date(pdata+24); /* access_time */ - ts[1] = interpret_long_date(pdata+32); /* modification_time */ + ft.atime = interpret_long_date(pdata+24); /* access_time */ + ft.mtime = interpret_long_date(pdata+32); /* modification_time */ set_owner = (uid_t)IVAL(pdata,40); set_grp = (gid_t)IVAL(pdata,48); raw_unixmode = IVAL(pdata,84); @@ -6083,8 +6102,8 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", /* Ensure we don't try and change anything else. */ raw_unixmode = SMB_MODE_NO_CHANGE; size = get_file_size(*psbuf); - ts[0] = get_atimespec(psbuf); - ts[1] = get_mtimespec(psbuf); + ft.atime = get_atimespec(psbuf); + ft.mtime = get_mtimespec(psbuf); /* * We continue here as we might want to change the * owner uid/gid. @@ -6172,7 +6191,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", fsp, fname, psbuf, - ts, + &ft, true); } diff --git a/source3/torture/cmd_vfs.c b/source3/torture/cmd_vfs.c index d984dd661c..31eb27b756 100644 --- a/source3/torture/cmd_vfs.c +++ b/source3/torture/cmd_vfs.c @@ -795,14 +795,17 @@ static NTSTATUS cmd_getwd(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, static NTSTATUS cmd_utime(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - struct timespec ts[2]; + struct smb_file_time ft; if (argc != 4) { printf("Usage: utime <path> <access> <modify>\n"); return NT_STATUS_OK; } - ts[0] = convert_time_t_to_timespec(atoi(argv[2])); - ts[1] = convert_time_t_to_timespec(atoi(argv[3])); - if (SMB_VFS_NTIMES(vfs->conn, argv[1], ts) != 0) { + + ZERO_STRUCT(ft); + + ft.atime = convert_time_t_to_timespec(atoi(argv[2])); + ft.mtime = convert_time_t_to_timespec(atoi(argv[3])); + if (SMB_VFS_NTIMES(vfs->conn, argv[1], &ft) != 0) { printf("utime: error=%d (%s)\n", errno, strerror(errno)); return NT_STATUS_UNSUCCESSFUL; } |