mirror of
https://github.com/samba-team/samba.git
synced 2025-03-26 18:50:30 +03:00
s3: Plumb smb_filename through SMB_VFS_NTIMES
This commit is contained in:
parent
f39232a8fb
commit
3cb0e521e1
@ -237,9 +237,11 @@ static char *skel_getwd(vfs_handle_struct *handle, char *buf)
|
||||
return vfswrap_getwd(NULL, buf);
|
||||
}
|
||||
|
||||
static int skel_ntimes(vfs_handle_struct *handle, const char *path, struct smb_file_time *ft)
|
||||
static int skel_ntimes(vfs_handle_struct *handle,
|
||||
const struct smb_filename *smb_fname,
|
||||
struct smb_file_time *ft)
|
||||
{
|
||||
return vfswrap_ntimes(NULL, path, ft);
|
||||
return vfswrap_ntimes(NULL, smb_fname, ft);
|
||||
}
|
||||
|
||||
static int skel_ftruncate(vfs_handle_struct *handle, files_struct *fsp, SMB_OFF_T offset)
|
||||
|
@ -230,9 +230,11 @@ static char *skel_getwd(vfs_handle_struct *handle, char *buf)
|
||||
return SMB_VFS_NEXT_GETWD(handle, buf);
|
||||
}
|
||||
|
||||
static int skel_ntimes(vfs_handle_struct *handle, const char *path, struct smb_file_time *ft)
|
||||
static int skel_ntimes(vfs_handle_struct *handle,
|
||||
const struct smb_filename *smb_fname,
|
||||
struct smb_file_time *ft)
|
||||
{
|
||||
return SMB_VFS_NEXT_NTIMES(handle, path, ft);
|
||||
return SMB_VFS_NEXT_NTIMES(handle, smb_fname, ft);
|
||||
}
|
||||
|
||||
static int skel_ftruncate(vfs_handle_struct *handle, files_struct *fsp, SMB_OFF_T offset)
|
||||
|
@ -6241,8 +6241,8 @@ int dos_attributes_to_stat_dos_flags(uint32_t dosmode);
|
||||
uint32 dos_mode(connection_struct *conn, const char *path, const SMB_STRUCT_STAT *sbuf);
|
||||
int file_set_dosmode(connection_struct *conn, struct smb_filename *smb_fname,
|
||||
uint32 dosmode, const char *parent_dir, bool newfile);
|
||||
int file_ntimes(connection_struct *conn, const char *fname,
|
||||
struct smb_file_time *ft, const SMB_STRUCT_STAT *psbuf);
|
||||
int file_ntimes(connection_struct *conn, const struct smb_filename *smb_fname,
|
||||
struct smb_file_time *ft);
|
||||
bool set_sticky_write_time_path(struct file_id fileid,
|
||||
const struct timespec mtime);
|
||||
bool set_sticky_write_time_fsp(struct files_struct *fsp, const struct timespec mtime);
|
||||
@ -7047,8 +7047,7 @@ NTSTATUS hardlink_internals(TALLOC_CTX *ctx,
|
||||
const struct smb_filename *smb_fname_new);
|
||||
NTSTATUS smb_set_file_time(connection_struct *conn,
|
||||
files_struct *fsp,
|
||||
const char *fname,
|
||||
const SMB_STRUCT_STAT *psbuf,
|
||||
const struct smb_filename *smb_fname,
|
||||
struct smb_file_time *ft,
|
||||
bool setting_write_time);
|
||||
void reply_findclose(struct smb_request *req);
|
||||
|
@ -119,7 +119,7 @@
|
||||
/* Leave at 25 - not yet released. Add strict locking calls. -- drichards. */
|
||||
/* Changed to version 26 - Plumb struct smb_filename to SMB_VFS_CREATE_FILE,
|
||||
SMB_VFS_OPEN, SMB_VFS_STAT, SMB_VFS_LSTAT,
|
||||
SMB_VFS_RENAME, SMB_VFS_UNLINK. */
|
||||
SMB_VFS_RENAME, SMB_VFS_UNLINK, SMB_VFS_NTIMES. */
|
||||
|
||||
#define SMB_VFS_INTERFACE_VERSION 26
|
||||
|
||||
@ -375,7 +375,9 @@ 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, struct smb_file_time *ft);
|
||||
int (*ntimes)(struct vfs_handle_struct *handle,
|
||||
const struct smb_filename *smb_fname,
|
||||
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);
|
||||
|
@ -508,15 +508,15 @@ int onefs_unlink(vfs_handle_struct *handle,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int onefs_vtimes_streams(vfs_handle_struct *handle, const char *fname,
|
||||
int onefs_vtimes_streams(vfs_handle_struct *handle,
|
||||
const struct smb_filename *smb_fname,
|
||||
int flags, struct timespec times[3])
|
||||
{
|
||||
struct smb_filename *smb_fname_onefs = NULL;
|
||||
int ret;
|
||||
bool is_stream;
|
||||
char *base;
|
||||
char *stream;
|
||||
int dirfd;
|
||||
int saved_errno;
|
||||
NTSTATUS status;
|
||||
|
||||
START_PROFILE(syscall_ntimes);
|
||||
|
||||
@ -524,23 +524,40 @@ int onefs_vtimes_streams(vfs_handle_struct *handle, const char *fname,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!is_stream) {
|
||||
ret = vtimes(fname, times, flags);
|
||||
if (!is_ntfs_stream_smb_fname(smb_fname)) {
|
||||
ret = vtimes(smb_fname->base_name, times, flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dirfd = get_stream_dir_fd(handle->conn, base, NULL);
|
||||
if (dirfd < -1) {
|
||||
status = onefs_stream_prep_smb_fname(talloc_tos(), smb_fname,
|
||||
&smb_fname_onefs);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
errno = map_errno_from_nt_status(status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = enc_vtimesat(dirfd, stream, ENC_DEFAULT, times, flags);
|
||||
/* Default stream (the ::$DATA was just stripped off). */
|
||||
if (!is_ntfs_stream_smb_fname(smb_fname_onefs)) {
|
||||
ret = vtimes(smb_fname_onefs->base_name, times, flags);
|
||||
goto out;
|
||||
}
|
||||
|
||||
END_PROFILE(syscall_ntimes);
|
||||
dirfd = get_stream_dir_fd(handle->conn, smb_fname->base_name, NULL);
|
||||
if (dirfd < -1) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = enc_vtimesat(dirfd, smb_fname_onefs->stream_name, ENC_DEFAULT,
|
||||
times, flags);
|
||||
|
||||
saved_errno = errno;
|
||||
close(dirfd);
|
||||
errno = saved_errno;
|
||||
|
||||
out:
|
||||
END_PROFILE(syscall_ntimes);
|
||||
TALLOC_FREE(smb_fname_onefs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -301,16 +301,36 @@ 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,
|
||||
static int cap_ntimes(vfs_handle_struct *handle,
|
||||
const struct smb_filename *smb_fname,
|
||||
struct smb_file_time *ft)
|
||||
{
|
||||
char *cappath = capencode(talloc_tos(), path);
|
||||
struct smb_filename *smb_fname_tmp = NULL;
|
||||
char *cappath = NULL;
|
||||
NTSTATUS status;
|
||||
int ret;
|
||||
|
||||
cappath = capencode(talloc_tos(), smb_fname->base_name);
|
||||
|
||||
if (!cappath) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
return SMB_VFS_NEXT_NTIMES(handle, cappath, ft);
|
||||
|
||||
/* Setup temporary smb_filename structs. */
|
||||
status = copy_smb_filename(talloc_tos(), smb_fname,
|
||||
&smb_fname_tmp);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
errno = map_errno_from_nt_status(status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
smb_fname_tmp->base_name = cappath;
|
||||
|
||||
ret = SMB_VFS_NEXT_NTIMES(handle, smb_fname_tmp, ft);
|
||||
|
||||
TALLOC_FREE(smb_fname_tmp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -789,34 +789,42 @@ static char *vfswrap_getwd(vfs_handle_struct *handle, char *path)
|
||||
system will support.
|
||||
**********************************************************************/
|
||||
|
||||
static int vfswrap_ntimes(vfs_handle_struct *handle, const char *path,
|
||||
static int vfswrap_ntimes(vfs_handle_struct *handle,
|
||||
const struct smb_filename *smb_fname,
|
||||
struct smb_file_time *ft)
|
||||
{
|
||||
int result;
|
||||
int result = -1;
|
||||
|
||||
START_PROFILE(syscall_ntimes);
|
||||
|
||||
if (smb_fname->stream_name) {
|
||||
errno = ENOENT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
#if defined(HAVE_UTIMES)
|
||||
if (ft != NULL) {
|
||||
struct timeval tv[2];
|
||||
tv[0] = convert_timespec_to_timeval(ft->atime);
|
||||
tv[1] = convert_timespec_to_timeval(ft->mtime);
|
||||
result = utimes(path, tv);
|
||||
result = utimes(smb_fname->base_name, tv);
|
||||
} else {
|
||||
result = utimes(path, NULL);
|
||||
result = utimes(smb_fname->base_name, NULL);
|
||||
}
|
||||
#elif defined(HAVE_UTIME)
|
||||
if (ft != NULL) {
|
||||
struct utimbuf times;
|
||||
times.actime = convert_timespec_to_time_t(ft->atime);
|
||||
times.modtime = convert_timespec_to_time_t(ft->mtime);
|
||||
result = utime(path, ×);
|
||||
result = utime(smb_fname->base_name, ×);
|
||||
} else {
|
||||
result = utime(path, NULL);
|
||||
result = utime(smb_fname->base_name, NULL);
|
||||
}
|
||||
#else
|
||||
errno = ENOSYS;
|
||||
result = -1;
|
||||
#endif
|
||||
out:
|
||||
END_PROFILE(syscall_ntimes);
|
||||
return result;
|
||||
}
|
||||
|
@ -1011,13 +1011,15 @@ static char *smb_full_audit_getwd(vfs_handle_struct *handle,
|
||||
}
|
||||
|
||||
static int smb_full_audit_ntimes(vfs_handle_struct *handle,
|
||||
const char *path, struct smb_file_time *ft)
|
||||
const struct smb_filename *smb_fname,
|
||||
struct smb_file_time *ft)
|
||||
{
|
||||
int result;
|
||||
|
||||
result = SMB_VFS_NEXT_NTIMES(handle, path, ft);
|
||||
result = SMB_VFS_NEXT_NTIMES(handle, smb_fname, ft);
|
||||
|
||||
do_log(SMB_VFS_OP_NTIMES, (result >= 0), handle, "%s", path);
|
||||
do_log(SMB_VFS_OP_NTIMES, (result >= 0), handle, "%s",
|
||||
smb_fname_str_do_log(smb_fname));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -200,7 +200,8 @@ done:
|
||||
return result;
|
||||
}
|
||||
|
||||
static int onefs_ntimes(vfs_handle_struct *handle, const char *fname,
|
||||
static int onefs_ntimes(vfs_handle_struct *handle,
|
||||
const struct smb_filename *smb_fname,
|
||||
struct smb_file_time *ft)
|
||||
{
|
||||
int flags = 0;
|
||||
@ -230,7 +231,7 @@ static int onefs_ntimes(vfs_handle_struct *handle, const char *fname,
|
||||
ft->create_time.tv_nsec));
|
||||
}
|
||||
|
||||
return onefs_vtimes_streams(handle, fname, flags, times);
|
||||
return onefs_vtimes_streams(handle, smb_fname, flags, times);
|
||||
}
|
||||
|
||||
static uint32_t onefs_fs_capabilities(struct vfs_handle_struct *handle)
|
||||
|
@ -394,12 +394,13 @@ onefs_shadow_copy_chdir(vfs_handle_struct *handle, const char *path)
|
||||
}
|
||||
|
||||
static int
|
||||
onefs_shadow_copy_ntimes(vfs_handle_struct *handle, const char *path,
|
||||
onefs_shadow_copy_ntimes(vfs_handle_struct *handle,
|
||||
const struct smb_filename *smb_fname,
|
||||
struct smb_file_time *ft)
|
||||
{
|
||||
SHADOW_NEXT(NTIMES,
|
||||
(handle, cpath ?: path, ft),
|
||||
int);
|
||||
SHADOW_NEXT_SMB_FNAME_CONST(NTIMES,
|
||||
(handle, smb_fname_tmp, ft),
|
||||
int);
|
||||
|
||||
}
|
||||
|
||||
|
@ -417,7 +417,6 @@ static void recycle_do_touch(vfs_handle_struct *handle,
|
||||
{
|
||||
struct smb_filename *smb_fname_tmp = NULL;
|
||||
struct smb_file_time ft;
|
||||
char *fname = NULL;
|
||||
NTSTATUS status;
|
||||
int ret, err;
|
||||
|
||||
@ -438,22 +437,16 @@ static void recycle_do_touch(vfs_handle_struct *handle,
|
||||
/* mtime */
|
||||
ft.mtime = touch_mtime ? ft.atime : smb_fname_tmp->st.st_ex_mtime;
|
||||
|
||||
status = get_full_smb_filename(talloc_tos(), smb_fname_tmp, &fname);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
become_root();
|
||||
ret = SMB_VFS_NEXT_NTIMES(handle, fname, &ft);
|
||||
ret = SMB_VFS_NEXT_NTIMES(handle, smb_fname_tmp, &ft);
|
||||
err = errno;
|
||||
unbecome_root();
|
||||
if (ret == -1 ) {
|
||||
DEBUG(0, ("recycle: touching %s failed, reason = %s\n",
|
||||
smb_fname_str_dbg(smb_fname_tmp), strerror(err)));
|
||||
}
|
||||
|
||||
out:
|
||||
TALLOC_FREE(fname);
|
||||
TALLOC_FREE(smb_fname_tmp);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -446,9 +446,19 @@ static int shadow_copy2_chdir(vfs_handle_struct *handle,
|
||||
}
|
||||
|
||||
static int shadow_copy2_ntimes(vfs_handle_struct *handle,
|
||||
const char *fname, struct smb_file_time *ft)
|
||||
const struct smb_filename *smb_fname_in,
|
||||
struct smb_file_time *ft)
|
||||
{
|
||||
SHADOW2_NEXT(NTIMES, (handle, name, ft), int, -1);
|
||||
struct smb_filename *smb_fname = NULL;
|
||||
NTSTATUS status;
|
||||
|
||||
status = copy_smb_filename(talloc_tos(), smb_fname_in, &smb_fname);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
errno = map_errno_from_nt_status(status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
SHADOW2_NEXT_SMB_FNAME(NTIMES, (handle, smb_fname, ft), int, -1);
|
||||
}
|
||||
|
||||
static int shadow_copy2_readlink(vfs_handle_struct *handle,
|
||||
|
@ -499,12 +499,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 smb_filename *smb_fname = NULL;
|
||||
struct smb_file_time ft;
|
||||
NTSTATUS status;
|
||||
int ret = -1;
|
||||
|
||||
ZERO_STRUCT(sbuf);
|
||||
ZERO_STRUCT(ft);
|
||||
|
||||
if (!fsp->update_write_time_on_close) {
|
||||
@ -515,36 +514,44 @@ static NTSTATUS update_write_time_on_close(struct files_struct *fsp)
|
||||
fsp->close_write_time = timespec_current();
|
||||
}
|
||||
|
||||
/* XXX: Remove when fsp->fsp_name is converted to smb_filename. */
|
||||
status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name,
|
||||
NULL, &smb_fname);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Ensure we have a valid stat struct for the source. */
|
||||
if (fsp->fh->fd != -1) {
|
||||
ret = SMB_VFS_FSTAT(fsp, &sbuf);
|
||||
ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
|
||||
} else {
|
||||
if (fsp->posix_open) {
|
||||
ret = vfs_lstat_smb_fname(fsp->conn, fsp->fsp_name,
|
||||
&sbuf);
|
||||
ret = SMB_VFS_LSTAT(fsp->conn, smb_fname);
|
||||
} else {
|
||||
ret = vfs_stat_smb_fname(fsp->conn, fsp->fsp_name,
|
||||
&sbuf);
|
||||
ret = SMB_VFS_STAT(fsp->conn, smb_fname);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == -1) {
|
||||
return map_nt_error_from_unix(errno);
|
||||
status = map_nt_error_from_unix(errno);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!VALID_STAT(sbuf)) {
|
||||
if (!VALID_STAT(smb_fname->st)) {
|
||||
/* if it doesn't seem to be a real file */
|
||||
return NT_STATUS_OK;
|
||||
status = NT_STATUS_OK;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ft.mtime = fsp->close_write_time;
|
||||
status = smb_set_file_time(fsp->conn, fsp, fsp->fsp_name,
|
||||
&sbuf, &ft, true);
|
||||
status = smb_set_file_time(fsp->conn, fsp, smb_fname, &ft, true);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
goto out;
|
||||
}
|
||||
|
||||
return NT_STATUS_OK;
|
||||
out:
|
||||
TALLOC_FREE(smb_fname);
|
||||
return status;
|
||||
}
|
||||
|
||||
static NTSTATUS ntstatus_keeperror(NTSTATUS s1, NTSTATUS s2)
|
||||
|
@ -722,11 +722,9 @@ int file_set_dosmode(connection_struct *conn, struct smb_filename *smb_fname,
|
||||
than POSIX.
|
||||
*******************************************************************/
|
||||
|
||||
int file_ntimes(connection_struct *conn, const char *fname,
|
||||
struct smb_file_time *ft, const SMB_STRUCT_STAT *psbuf)
|
||||
int file_ntimes(connection_struct *conn, const struct smb_filename *smb_fname,
|
||||
struct smb_file_time *ft)
|
||||
{
|
||||
struct smb_filename *smb_fname = NULL;
|
||||
NTSTATUS status;
|
||||
int ret = -1;
|
||||
|
||||
errno = 0;
|
||||
@ -749,7 +747,7 @@ int file_ntimes(connection_struct *conn, const char *fname,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(SMB_VFS_NTIMES(conn, fname, ft) == 0) {
|
||||
if(SMB_VFS_NTIMES(conn, smb_fname, ft) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -767,21 +765,13 @@ int file_ntimes(connection_struct *conn, const char *fname,
|
||||
(as DOS does).
|
||||
*/
|
||||
|
||||
status = create_synthetic_smb_fname_split(talloc_tos(), fname, psbuf,
|
||||
&smb_fname);
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check if we have write access. */
|
||||
if (can_write_to_file(conn, smb_fname)) {
|
||||
/* We are allowed to become root and change the filetime. */
|
||||
become_root();
|
||||
ret = SMB_VFS_NTIMES(conn, fname, ft);
|
||||
ret = SMB_VFS_NTIMES(conn, smb_fname, ft);
|
||||
unbecome_root();
|
||||
}
|
||||
TALLOC_FREE(smb_fname);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1179,7 +1179,7 @@ void reply_setatr(struct smb_request *req)
|
||||
req->flags2 & FLAGS2_DFS_PATHNAMES,
|
||||
fname,
|
||||
&smb_fname,
|
||||
&fname);
|
||||
NULL);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
|
||||
reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
|
||||
@ -1190,7 +1190,8 @@ void reply_setatr(struct smb_request *req)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (fname[0] == '.' && fname[1] == '\0') {
|
||||
if (smb_fname->base_name[0] == '.' &&
|
||||
smb_fname->base_name[1] == '\0') {
|
||||
/*
|
||||
* Not sure here is the right place to catch this
|
||||
* condition. Might be moved to somewhere else later -- vl
|
||||
@ -1203,8 +1204,7 @@ void reply_setatr(struct smb_request *req)
|
||||
mtime = srv_make_unix_date3(req->vwv+1);
|
||||
|
||||
ft.mtime = convert_time_t_to_timespec(mtime);
|
||||
status = smb_set_file_time(conn, NULL, fname,
|
||||
&smb_fname->st, &ft, true);
|
||||
status = smb_set_file_time(conn, NULL, smb_fname, &ft, true);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
reply_unixerror(req, ERRDOS, ERRnoaccess);
|
||||
goto out;
|
||||
@ -1225,7 +1225,8 @@ void reply_setatr(struct smb_request *req)
|
||||
|
||||
reply_outbuf(req, 0, 0);
|
||||
|
||||
DEBUG( 3, ( "setatr name=%s mode=%d\n", fname, mode ) );
|
||||
DEBUG(3, ("setatr name=%s mode=%d\n", smb_fname_str_dbg(smb_fname),
|
||||
mode));
|
||||
out:
|
||||
TALLOC_FREE(smb_fname);
|
||||
END_PROFILE(SMBsetatr);
|
||||
@ -2148,8 +2149,7 @@ void reply_mknew(struct smb_request *req)
|
||||
}
|
||||
|
||||
ft.atime = smb_fname->st.st_ex_atime; /* atime. */
|
||||
status = smb_set_file_time(conn, fsp, fsp->fsp_name, &smb_fname->st,
|
||||
&ft, true);
|
||||
status = smb_set_file_time(conn, fsp, smb_fname, &ft, true);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
END_PROFILE(SMBcreate);
|
||||
goto out;
|
||||
@ -2168,9 +2168,10 @@ void reply_mknew(struct smb_request *req)
|
||||
CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
|
||||
}
|
||||
|
||||
DEBUG( 2, ( "reply_mknew: file %s\n", fsp->fsp_name ) );
|
||||
DEBUG( 3, ( "reply_mknew %s fd=%d dmode=0x%x\n",
|
||||
fsp->fsp_name, fsp->fh->fd, (unsigned int)fattr ) );
|
||||
DEBUG(2, ("reply_mknew: file %s\n", smb_fname_str_dbg(smb_fname)));
|
||||
DEBUG(3, ("reply_mknew %s fd=%d dmode=0x%x\n",
|
||||
smb_fname_str_dbg(smb_fname), fsp->fh->fd,
|
||||
(unsigned int)fattr));
|
||||
|
||||
out:
|
||||
TALLOC_FREE(smb_fname);
|
||||
@ -7582,9 +7583,9 @@ void reply_readbs(struct smb_request *req)
|
||||
void reply_setattrE(struct smb_request *req)
|
||||
{
|
||||
connection_struct *conn = req->conn;
|
||||
struct smb_filename *smb_fname = NULL;
|
||||
struct smb_file_time ft;
|
||||
files_struct *fsp;
|
||||
SMB_STRUCT_STAT sbuf;
|
||||
NTSTATUS status;
|
||||
|
||||
START_PROFILE(SMBsetattrE);
|
||||
@ -7592,18 +7593,23 @@ void reply_setattrE(struct smb_request *req)
|
||||
|
||||
if (req->wct < 7) {
|
||||
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
|
||||
END_PROFILE(SMBsetattrE);
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
fsp = file_fsp(req, SVAL(req->vwv+0, 0));
|
||||
|
||||
if(!fsp || (fsp->conn != conn)) {
|
||||
reply_doserror(req, ERRDOS, ERRbadfid);
|
||||
END_PROFILE(SMBsetattrE);
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* XXX: Remove when fsp->fsp_name is converted to smb_filename. */
|
||||
status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name,
|
||||
NULL, &smb_fname);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
reply_nterror(req, status);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert the DOS times into unix times.
|
||||
@ -7625,34 +7631,30 @@ void reply_setattrE(struct smb_request *req)
|
||||
|
||||
/* Ensure we have a valid stat struct for the source. */
|
||||
if (fsp->fh->fd != -1) {
|
||||
if (SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
|
||||
if (SMB_VFS_FSTAT(fsp, &smb_fname->st) == -1) {
|
||||
status = map_nt_error_from_unix(errno);
|
||||
reply_nterror(req, status);
|
||||
END_PROFILE(SMBsetattrE);
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
int ret = -1;
|
||||
|
||||
if (fsp->posix_open) {
|
||||
ret = vfs_lstat_smb_fname(conn, fsp->fsp_name, &sbuf);
|
||||
ret = SMB_VFS_LSTAT(conn, smb_fname);
|
||||
} else {
|
||||
ret = vfs_stat_smb_fname(conn, fsp->fsp_name, &sbuf);
|
||||
ret = SMB_VFS_STAT(conn, smb_fname);
|
||||
}
|
||||
if (ret == -1) {
|
||||
status = map_nt_error_from_unix(errno);
|
||||
reply_nterror(req, status);
|
||||
END_PROFILE(SMBsetattrE);
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
status = smb_set_file_time(conn, fsp, fsp->fsp_name,
|
||||
&sbuf, &ft, true);
|
||||
status = smb_set_file_time(conn, fsp, smb_fname, &ft, true);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
reply_doserror(req, ERRDOS, ERRnoaccess);
|
||||
END_PROFILE(SMBsetattrE);
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
DEBUG( 3, ( "reply_setattrE fnum=%d actime=%u modtime=%u "
|
||||
@ -7662,7 +7664,7 @@ void reply_setattrE(struct smb_request *req)
|
||||
(unsigned int)ft.mtime.tv_sec,
|
||||
(unsigned int)ft.create_time.tv_sec
|
||||
));
|
||||
|
||||
out:
|
||||
END_PROFILE(SMBsetattrE);
|
||||
return;
|
||||
}
|
||||
|
@ -4935,27 +4935,28 @@ NTSTATUS hardlink_internals(TALLOC_CTX *ctx,
|
||||
|
||||
NTSTATUS smb_set_file_time(connection_struct *conn,
|
||||
files_struct *fsp,
|
||||
const char *fname,
|
||||
const SMB_STRUCT_STAT *psbuf,
|
||||
const struct smb_filename *smb_fname,
|
||||
struct smb_file_time *ft,
|
||||
bool setting_write_time)
|
||||
{
|
||||
struct smb_filename *smb_fname_base = NULL;
|
||||
uint32 action =
|
||||
FILE_NOTIFY_CHANGE_LAST_ACCESS
|
||||
|FILE_NOTIFY_CHANGE_LAST_WRITE;
|
||||
NTSTATUS status;
|
||||
|
||||
if (!VALID_STAT(*psbuf)) {
|
||||
if (!VALID_STAT(smb_fname->st)) {
|
||||
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
}
|
||||
|
||||
/* get some defaults (no modifications) if any info is zero or -1. */
|
||||
if (null_timespec(ft->atime)) {
|
||||
ft->atime= psbuf->st_ex_atime;
|
||||
ft->atime= smb_fname->st.st_ex_atime;
|
||||
action &= ~FILE_NOTIFY_CHANGE_LAST_ACCESS;
|
||||
}
|
||||
|
||||
if (null_timespec(ft->mtime)) {
|
||||
ft->mtime = psbuf->st_ex_mtime;
|
||||
ft->mtime = smb_fname->st.st_ex_mtime;
|
||||
action &= ~FILE_NOTIFY_CHANGE_LAST_WRITE;
|
||||
}
|
||||
|
||||
@ -4979,8 +4980,8 @@ NTSTATUS smb_set_file_time(connection_struct *conn,
|
||||
*/
|
||||
|
||||
{
|
||||
struct timespec mts = psbuf->st_ex_mtime;
|
||||
struct timespec ats = psbuf->st_ex_atime;
|
||||
struct timespec mts = smb_fname->st.st_ex_mtime;
|
||||
struct timespec ats = smb_fname->st.st_ex_atime;
|
||||
if ((timespec_compare(&ft->atime, &ats) == 0) &&
|
||||
(timespec_compare(&ft->mtime, &mts) == 0)) {
|
||||
return NT_STATUS_OK;
|
||||
@ -5010,21 +5011,29 @@ NTSTATUS smb_set_file_time(connection_struct *conn,
|
||||
}
|
||||
} else {
|
||||
set_sticky_write_time_path(
|
||||
vfs_file_id_from_sbuf(conn, psbuf), ft->mtime);
|
||||
vfs_file_id_from_sbuf(conn, &smb_fname->st),
|
||||
ft->mtime);
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG(10,("smb_set_file_time: setting utimes to modified values.\n"));
|
||||
|
||||
if (fsp && fsp->base_fsp) {
|
||||
fname = fsp->base_fsp->fsp_name;
|
||||
/* Always call ntimes on the base, even if a stream was passed in. */
|
||||
status = create_synthetic_smb_fname(talloc_tos(), smb_fname->base_name,
|
||||
NULL, &smb_fname->st,
|
||||
&smb_fname_base);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
|
||||
if(file_ntimes(conn, fname, ft, psbuf)!=0) {
|
||||
if(file_ntimes(conn, smb_fname_base, ft)!=0) {
|
||||
TALLOC_FREE(smb_fname_base);
|
||||
return map_nt_error_from_unix(errno);
|
||||
}
|
||||
notify_fname(conn, NOTIFY_ACTION_MODIFIED, action, fname);
|
||||
TALLOC_FREE(smb_fname_base);
|
||||
|
||||
notify_fname(conn, NOTIFY_ACTION_MODIFIED, action,
|
||||
smb_fname->base_name);
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
@ -5033,25 +5042,26 @@ NTSTATUS smb_set_file_time(connection_struct *conn,
|
||||
****************************************************************************/
|
||||
|
||||
static NTSTATUS smb_set_file_dosmode(connection_struct *conn,
|
||||
files_struct *fsp,
|
||||
const char *fname,
|
||||
SMB_STRUCT_STAT *psbuf,
|
||||
uint32 dosmode)
|
||||
const struct smb_filename *smb_fname,
|
||||
uint32 dosmode)
|
||||
{
|
||||
if (!VALID_STAT(*psbuf)) {
|
||||
struct smb_filename *smb_fname_base = NULL;
|
||||
NTSTATUS status;
|
||||
|
||||
if (!VALID_STAT(smb_fname->st)) {
|
||||
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (fsp) {
|
||||
if (fsp->base_fsp) {
|
||||
fname = fsp->base_fsp->fsp_name;
|
||||
} else {
|
||||
fname = fsp->fsp_name;
|
||||
}
|
||||
/* Always operate on the base_name, even if a stream was passed in. */
|
||||
status = create_synthetic_smb_fname(talloc_tos(), smb_fname->base_name,
|
||||
NULL, &smb_fname->st,
|
||||
&smb_fname_base);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
|
||||
if (dosmode) {
|
||||
if (S_ISDIR(psbuf->st_ex_mode)) {
|
||||
if (S_ISDIR(smb_fname_base->st.st_ex_mode)) {
|
||||
dosmode |= aDIR;
|
||||
} else {
|
||||
dosmode &= ~aDIR;
|
||||
@ -5061,29 +5071,27 @@ static NTSTATUS smb_set_file_dosmode(connection_struct *conn,
|
||||
DEBUG(6,("smb_set_file_dosmode: dosmode: 0x%x\n", (unsigned int)dosmode));
|
||||
|
||||
/* check the mode isn't different, before changing it */
|
||||
if ((dosmode != 0) && (dosmode != dos_mode(conn, fname, psbuf))) {
|
||||
struct smb_filename *smb_fname = NULL;
|
||||
NTSTATUS status;
|
||||
if ((dosmode != 0) && (dosmode != dos_mode(conn,
|
||||
smb_fname_base->base_name,
|
||||
&smb_fname_base->st))) {
|
||||
DEBUG(10,("smb_set_file_dosmode: file %s : setting dos mode "
|
||||
"0x%x\n", smb_fname_str_dbg(smb_fname_base),
|
||||
(unsigned int)dosmode));
|
||||
|
||||
status = create_synthetic_smb_fname_split(talloc_tos(), fname,
|
||||
psbuf, &smb_fname);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
if(file_set_dosmode(conn, smb_fname_base, dosmode, NULL,
|
||||
false)) {
|
||||
DEBUG(2,("smb_set_file_dosmode: file_set_dosmode of "
|
||||
"%s failed (%s)\n",
|
||||
smb_fname_str_dbg(smb_fname_base),
|
||||
strerror(errno)));
|
||||
status = map_nt_error_from_unix(errno);
|
||||
goto out;
|
||||
}
|
||||
|
||||
DEBUG(10,("smb_set_file_dosmode: file %s : setting dos mode 0x%x\n",
|
||||
fname, (unsigned int)dosmode ));
|
||||
|
||||
if(file_set_dosmode(conn, smb_fname, dosmode, NULL, false)) {
|
||||
DEBUG(2,("smb_set_file_dosmode: file_set_dosmode of %s failed (%s)\n",
|
||||
fname, strerror(errno)));
|
||||
TALLOC_FREE(smb_fname);
|
||||
return map_nt_error_from_unix(errno);
|
||||
}
|
||||
*psbuf = smb_fname->st;
|
||||
TALLOC_FREE(smb_fname);
|
||||
}
|
||||
return NT_STATUS_OK;
|
||||
status = NT_STATUS_OK;
|
||||
out:
|
||||
TALLOC_FREE(smb_fname_base);
|
||||
return status;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -5783,8 +5791,7 @@ static NTSTATUS smb_set_info_standard(connection_struct *conn,
|
||||
const char *pdata,
|
||||
int total_data,
|
||||
files_struct *fsp,
|
||||
const char *fname,
|
||||
const SMB_STRUCT_STAT *psbuf)
|
||||
const struct smb_filename *smb_fname)
|
||||
{
|
||||
struct smb_file_time ft;
|
||||
ZERO_STRUCT(ft);
|
||||
@ -5803,14 +5810,9 @@ static NTSTATUS smb_set_info_standard(connection_struct *conn,
|
||||
ft.mtime = interpret_long_date(pdata + 16);
|
||||
|
||||
DEBUG(10,("smb_set_info_standard: file %s\n",
|
||||
fname ? fname : fsp->fsp_name ));
|
||||
smb_fname_str_dbg(smb_fname)));
|
||||
|
||||
return smb_set_file_time(conn,
|
||||
fsp,
|
||||
fname,
|
||||
psbuf,
|
||||
&ft,
|
||||
true);
|
||||
return smb_set_file_time(conn, fsp, smb_fname, &ft, true);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -5821,8 +5823,7 @@ static NTSTATUS smb_set_file_basic_info(connection_struct *conn,
|
||||
const char *pdata,
|
||||
int total_data,
|
||||
files_struct *fsp,
|
||||
const char *fname,
|
||||
SMB_STRUCT_STAT *psbuf)
|
||||
const struct smb_filename *smb_fname)
|
||||
{
|
||||
/* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
|
||||
struct timespec write_time;
|
||||
@ -5840,7 +5841,7 @@ static NTSTATUS smb_set_file_basic_info(connection_struct *conn,
|
||||
|
||||
/* Set the attributes */
|
||||
dosmode = IVAL(pdata,32);
|
||||
status = smb_set_file_dosmode(conn, fsp, fname, psbuf, dosmode);
|
||||
status = smb_set_file_dosmode(conn, smb_fname, dosmode);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
@ -5872,15 +5873,11 @@ static NTSTATUS smb_set_file_basic_info(connection_struct *conn,
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG(10,("smb_set_file_basic_info: file %s\n",
|
||||
fname ? fname : fsp->fsp_name ));
|
||||
DEBUG(10, ("smb_set_file_basic_info: file %s\n",
|
||||
smb_fname_str_dbg(smb_fname)));
|
||||
|
||||
return smb_set_file_time(conn,
|
||||
fsp,
|
||||
fname,
|
||||
psbuf,
|
||||
&ft,
|
||||
setting_write_time);
|
||||
return smb_set_file_time(conn, fsp, smb_fname, &ft,
|
||||
setting_write_time);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -6353,8 +6350,7 @@ static NTSTATUS smb_set_file_unix_basic(connection_struct *conn,
|
||||
|
||||
status = smb_set_file_time(conn,
|
||||
fsp,
|
||||
smb_fname->base_name,
|
||||
&sbuf,
|
||||
smb_fname,
|
||||
&ft,
|
||||
false);
|
||||
if (modify_mtime) {
|
||||
@ -7072,8 +7068,7 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
|
||||
pdata,
|
||||
total_data,
|
||||
fsp,
|
||||
fname,
|
||||
&sbuf);
|
||||
smb_fname);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -7094,8 +7089,7 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
|
||||
pdata,
|
||||
total_data,
|
||||
fsp,
|
||||
fname,
|
||||
&sbuf);
|
||||
smb_fname);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -903,6 +903,9 @@ 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 smb_file_time ft;
|
||||
struct smb_filename *smb_fname = NULL;
|
||||
NTSTATUS status;
|
||||
|
||||
if (argc != 4) {
|
||||
printf("Usage: utime <path> <access> <modify>\n");
|
||||
return NT_STATUS_OK;
|
||||
@ -912,11 +915,20 @@ static NTSTATUS cmd_utime(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
|
||||
|
||||
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) {
|
||||
|
||||
status = create_synthetic_smb_fname_split(mem_ctx, argv[1],
|
||||
NULL, &smb_fname);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
|
||||
if (SMB_VFS_NTIMES(vfs->conn, smb_fname, &ft) != 0) {
|
||||
printf("utime: error=%d (%s)\n", errno, strerror(errno));
|
||||
TALLOC_FREE(smb_fname);
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
TALLOC_FREE(smb_fname);
|
||||
printf("utime: ok\n");
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user