return ret;
}
-static int streams_depot_renameat(vfs_handle_struct *handle,
- files_struct *src_dirfsp,
- const struct smb_filename *smb_fname_src,
- files_struct *dst_dirfsp,
- const struct smb_filename *smb_fname_dst,
- const struct vfs_rename_how *how)
-{
- struct connection_struct *conn = handle->conn;
- struct smb_filename smb_fname_src_stream = {};
- struct smb_filename smb_fname_dst_stream = {};
- struct smb_filename *src_basename = NULL;
- struct smb_filename dst_basename = {};
- struct stat_ex dst_st;
- bool src_is_stream, dst_is_stream;
- struct smb_filename *stream_dir = NULL;
- NTSTATUS status;
- int ret = -1;
-
- DEBUG(10, ("streams_depot_renameat called for %s => %s\n",
- smb_fname_str_dbg(smb_fname_src),
- smb_fname_str_dbg(smb_fname_dst)));
-
- src_is_stream = is_ntfs_stream_smb_fname(smb_fname_src);
- dst_is_stream = is_ntfs_stream_smb_fname(smb_fname_dst);
- SMB_ASSERT(src_is_stream == dst_is_stream);
-
- if (!src_is_stream) {
- return SMB_VFS_NEXT_RENAMEAT(handle,
- src_dirfsp,
- smb_fname_src,
- dst_dirfsp,
- smb_fname_dst,
- how);
- }
-
- if (how->flags != 0) {
- errno = EINVAL;
- goto done;
- }
-
- /* for now don't allow renames from or to the default stream */
- if (is_ntfs_default_stream_smb_fname(smb_fname_src) ||
- is_ntfs_default_stream_smb_fname(smb_fname_dst))
- {
- errno = ENOSYS;
- goto done;
- }
-
- src_basename = cp_smb_filename_nostream(talloc_tos(), smb_fname_src);
- if (src_basename == NULL) {
- errno = ENOMEM;
- goto done;
- }
-
- status = openat_pathref_fsp(src_dirfsp, src_basename);
- if (!NT_STATUS_IS_OK(status)) {
- ret = -1;
- errno = map_errno_from_nt_status(status);
- goto done;
- }
-
- dst_basename = (struct smb_filename){
- .base_name = smb_fname_src->base_name,
- .flags = smb_fname_src->flags,
- .twrp = smb_fname_src->twrp,
- };
-
- ret = SMB_VFS_FSTATAT(
- conn, dst_dirfsp, &dst_basename, &dst_st, AT_SYMLINK_NOFOLLOW);
- if (ret == -1) {
- goto done;
- }
-
- if (!check_same_dev_ino(&src_basename->st, &dst_st)) {
- ret = -1;
- errno = ENOSYS;
- goto done;
- }
-
- ret = stream_dir_pathref(talloc_tos(),
- handle,
- src_basename,
- &src_basename->st,
- false,
- &stream_dir);
- if (ret != 0) {
- errno = ret;
- ret = -1;
- goto done;
- }
-
- ret = stream_name(talloc_tos(),
- smb_fname_src->stream_name,
- &smb_fname_src_stream.base_name);
- if (ret != 0) {
- errno = ret;
- ret = -1;
- goto done;
- }
-
- ret = stream_name(talloc_tos(),
- smb_fname_dst->stream_name,
- &smb_fname_dst_stream.base_name);
- if (ret != 0) {
- errno = ret;
- ret = -1;
- goto done;
- }
-
- /*
- * We must use handle->conn->cwd_fsp as
- * srcfsp and dstfsp directory handles here
- * as we used the full pathname from the cwd dir
- * to calculate the streams directory and filename
- * within.
- */
- ret = SMB_VFS_NEXT_RENAMEAT(handle,
- stream_dir->fsp,
- &smb_fname_src_stream,
- stream_dir->fsp,
- &smb_fname_dst_stream,
- how);
-done:
- {
- int err = errno;
- TALLOC_FREE(stream_dir);
- TALLOC_FREE(smb_fname_src_stream.base_name);
- TALLOC_FREE(smb_fname_dst_stream.base_name);
- errno = err;
- }
- return ret;
-}
-
static int streams_depot_rename_stream(struct vfs_handle_struct *handle,
struct files_struct *src_fsp,
const char *dst_name,
.lstat_fn = streams_depot_lstat,
.fstatat_fn = streams_depot_fstatat,
.unlinkat_fn = streams_depot_unlinkat,
- .renameat_fn = streams_depot_renameat,
.rename_stream_fn = streams_depot_rename_stream,
.fstreaminfo_fn = streams_depot_fstreaminfo,
};