s3: Plumb smb_filename through SMB_VFS_NTIMES
authorTim Prouty <tprouty@samba.org>
Thu, 2 Jul 2009 20:39:20 +0000 (13:39 -0700)
committerTim Prouty <tprouty@samba.org>
Mon, 6 Jul 2009 22:38:42 +0000 (15:38 -0700)
17 files changed:
examples/VFS/skel_opaque.c
examples/VFS/skel_transparent.c
source3/include/proto.h
source3/include/vfs.h
source3/modules/onefs_streams.c
source3/modules/vfs_cap.c
source3/modules/vfs_default.c
source3/modules/vfs_full_audit.c
source3/modules/vfs_onefs.c
source3/modules/vfs_onefs_shadow_copy.c
source3/modules/vfs_recycle.c
source3/modules/vfs_shadow_copy2.c
source3/smbd/close.c
source3/smbd/dosmode.c
source3/smbd/reply.c
source3/smbd/trans2.c
source3/torture/cmd_vfs.c

index 54f7ce8cf2abae7600a34fa645a9ef099997b96d..a0cb533eb8aa98ac74bde2024c6fbbced84ec759 100644 (file)
@@ -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)
index 09a926ad43af313dc82a2b3d71629ce5aa15edd9..cce1d13d8de38960569e28c1ecd88a04182c350b 100644 (file)
@@ -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)
index 6bd37efc5748b19dfcb8459957067ceba09f9c4b..dfcb38d22d6d2c8ce732f2fcc1c2e03525fc56fd 100644 (file)
@@ -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);
index cfa3403e82c5ddb90667a60ed2cd3b857e8d6065..91bda47ac65859325ba7ed393107f174ece517af 100644 (file)
 /* 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);
index 2a31036862fef5f2e5cad0a8de72466d8e7802a7..2be490f52d0b60d4f74f781d08b4e01f5a09ceb1 100644 (file)
@@ -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;
+       }
+
+       dirfd = get_stream_dir_fd(handle->conn, smb_fname->base_name, NULL);
+       if (dirfd < -1) {
+               ret = -1;
+               goto out;
+       }
 
-       END_PROFILE(syscall_ntimes);
+       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;
 }
 
index 9348ab9554c718b5df8870faacab1a789d0b5b9f..7e363b6be77ef6ca3201c35fdc877fe43d09ce8e 100644 (file)
@@ -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;
 }
 
 
index c95c68fe0f1bffa7f2e1caffdc0940891fc67bfa..7565e7bb65fb0cd5fa5f19968aa930b7e386eee3 100644 (file)
@@ -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, &times);
+               result = utime(smb_fname->base_name, &times);
        } 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;
 }
index 1f5e8333b90b7ef927c337de112eeec77c46f900..e8702aa2c8fb06744c47db86ab6d8a4aec18652a 100644 (file)
@@ -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;
 }
index 8ca3795e27b07f7d36e32b08bac8069be849a450..1a37622bea3d24e270f345439fa2dadf4d3cc647 100644 (file)
@@ -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)
index 1a43e0671a949b223381948d16ce7b4a2ffba497..651e20a875d9b47d4cfd27d86592e7a8fc5d57f0 100644 (file)
@@ -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);
 
 }
 
index 24166d12668116617d8d005c6dd6a023cc10cb57..771189ca7364fa4787f263ca62ee6fe4e7bcebab 100644 (file)
@@ -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);
 }
 
 /**
index 05a8b67f71954c51b1cab13e537c580e48a26d49..1f300a055caf34dde35da58387c14bea6dcfb141 100644 (file)
@@ -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,
index 537394c48128f6625abf6899423590c300750b2e..a0672f3949faa3a35f09d2acda7bf8e262de660e 100644 (file)
@@ -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)
index 97d788218d56b68c5c31f4eca7b9e1d0df0ce6c6..76034db164af63de29fe57337e3920675ae3aa6d 100644 (file)
@@ -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;
 }
index 4a5610e5e1331f9eefc9a407deb904bad51ed405..87001468599b71177382c5babaeb345f422e4330 100644 (file)
@@ -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;
 }
index e93d3138218ecb2c6bc8deec011766dfda2f7ba3..e5f8039e6e8eae6b1707580b7ca75bd3b4e2852e 100644 (file)
@@ -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;
-
-               status = create_synthetic_smb_fname_split(talloc_tos(), fname,
-                                                         psbuf, &smb_fname);
-               if (!NT_STATUS_IS_OK(status)) {
-                       return status;
-               }
-
-               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);
+       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));
+
+               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;
                }
-               *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;
                }
 
index e6a3940f4f229e9b3280a1d63f005bc44d34dbb4..33ced8fa54ee548b1f14635ddb46a724ea75113e 100644 (file)
@@ -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;
 }