return ret;
}
-static int streams_xattr_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 streams_xattr_config *config = NULL;
- NTSTATUS status;
- int ret = -1;
- char *src_xattr_name = NULL;
- char *src_raw_stream_name = NULL;
- char *dst_xattr_name = NULL;
- char *dst_raw_stream_name = NULL;
- bool src_is_stream, dst_is_stream;
- ssize_t oret;
- ssize_t nret;
- char *val = NULL;
- struct smb_filename *pathref_src = NULL;
- struct smb_filename *pathref_dst = NULL;
- struct smb_filename *full_src = NULL;
- struct smb_filename *full_dst = NULL;
- bool is_default;
-
- SMB_VFS_HANDLE_GET_DATA(handle,
- config,
- struct streams_xattr_config,
- goto fail;);
-
- src_is_stream = is_ntfs_stream_smb_fname(smb_fname_src);
- dst_is_stream = is_ntfs_stream_smb_fname(smb_fname_dst);
-
- if (!src_is_stream && !dst_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;
- }
-
- /* Don't rename if the streams are identical. */
- if (strequal(smb_fname_src->stream_name, smb_fname_dst->stream_name)) {
- goto done;
- }
-
- /* Get the xattr names. */
- ret = streams_xattr_get_name(handle,
- talloc_tos(),
- smb_fname_src->stream_name,
- &src_raw_stream_name,
- &is_default,
- &src_xattr_name);
- if (ret != 0) {
- errno = ret;
- goto fail;
- }
- ret = streams_xattr_get_name(handle,
- talloc_tos(),
- smb_fname_dst->stream_name,
- &dst_raw_stream_name,
- &is_default,
- &dst_xattr_name);
- if (ret != 0) {
- errno = ret;
- goto fail;
- }
-
- full_src = full_path_from_dirfsp_atname(talloc_tos(),
- src_dirfsp,
- smb_fname_src);
- if (full_src == NULL) {
- errno = ENOMEM;
- goto fail;
- }
- full_dst = full_path_from_dirfsp_atname(talloc_tos(),
- dst_dirfsp,
- smb_fname_dst);
- if (full_dst == NULL) {
- errno = ENOMEM;
- goto fail;
- }
-
- /* Get a pathref for full_src (base file, no stream name). */
- status = synthetic_pathref(talloc_tos(),
- handle->conn->cwd_fsp,
- full_src->base_name,
- NULL,
- NULL,
- full_src->twrp,
- full_src->flags,
- &pathref_src);
- if (!NT_STATUS_IS_OK(status)) {
- errno = ENOENT;
- goto fail;
- }
-
- /* Read the old stream from the base file fsp. */
- ret = streams_xattr_get_ea_value_fsp(talloc_tos(),
- config,
- pathref_src->fsp,
- src_raw_stream_name,
- &val);
- if (ret != 0) {
- errno = ret;
- goto fail;
- }
-
- /* Get a pathref for full_dst (base file, no stream name). */
- status = synthetic_pathref(talloc_tos(),
- handle->conn->cwd_fsp,
- full_dst->base_name,
- NULL,
- NULL,
- full_dst->twrp,
- full_dst->flags,
- &pathref_dst);
- if (!NT_STATUS_IS_OK(status)) {
- errno = ENOENT;
- goto fail;
- }
-
- /* (Over)write the new stream on the base file fsp. */
- nret = fsetxattr_multi(config,
- pathref_dst->fsp,
- dst_raw_stream_name,
- val,
- talloc_get_size(val),
- 0);
- if (nret < 0) {
- if (errno == ENOATTR) {
- errno = ENOENT;
- }
- goto fail;
- }
-
- /*
- * Remove the old stream from the base file fsp.
- */
- oret = fremovexattr_multi(config,
- pathref_src->fsp,
- src_raw_stream_name);
- if (oret < 0) {
- if (errno == ENOATTR) {
- errno = ENOENT;
- }
- goto fail;
- }
-
- done:
- errno = 0;
- ret = 0;
- fail:
- TALLOC_FREE(pathref_src);
- TALLOC_FREE(pathref_dst);
- TALLOC_FREE(full_src);
- TALLOC_FREE(full_dst);
- TALLOC_FREE(src_xattr_name);
- TALLOC_FREE(dst_xattr_name);
- return ret;
-}
-
static int streams_xattr_rename_stream(struct vfs_handle_struct *handle,
struct files_struct *src_fsp,
const char *dst_name,
.pwrite_send_fn = streams_xattr_pwrite_send,
.pwrite_recv_fn = streams_xattr_pwrite_recv,
.unlinkat_fn = streams_xattr_unlinkat,
- .renameat_fn = streams_xattr_renameat,
.rename_stream_fn = streams_xattr_rename_stream,
.ftruncate_fn = streams_xattr_ftruncate,
.fallocate_fn = streams_xattr_fallocate,