summaryrefslogtreecommitdiff
path: root/source3/modules/vfs_streams_depot.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/modules/vfs_streams_depot.c')
-rw-r--r--source3/modules/vfs_streams_depot.c106
1 files changed, 54 insertions, 52 deletions
diff --git a/source3/modules/vfs_streams_depot.c b/source3/modules/vfs_streams_depot.c
index 5f850174d8..f1b9a504b9 100644
--- a/source3/modules/vfs_streams_depot.c
+++ b/source3/modules/vfs_streams_depot.c
@@ -206,6 +206,7 @@ static char *stream_dir(vfs_handle_struct *handle,
}
if (SMB_VFS_NEXT_STAT(handle, smb_fname_hash) == 0) {
+ struct smb_filename *smb_fname_new = NULL;
char *newname;
if (!S_ISDIR(smb_fname_hash->st.st_ex_mode)) {
@@ -230,15 +231,25 @@ static char *stream_dir(vfs_handle_struct *handle,
goto fail;
}
- if (SMB_VFS_NEXT_RENAME(handle, result, newname) == -1) {
+ status = create_synthetic_smb_fname(talloc_tos(), newname,
+ NULL, NULL,
+ &smb_fname_new);
+ TALLOC_FREE(newname);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = map_errno_from_nt_status(status);
+ goto fail;
+ }
+
+ if (SMB_VFS_NEXT_RENAME(handle, smb_fname_hash,
+ smb_fname_new) == -1) {
+ TALLOC_FREE(smb_fname_new);
if ((errno == EEXIST) || (errno == ENOTEMPTY)) {
- TALLOC_FREE(newname);
goto again;
}
goto fail;
}
- TALLOC_FREE(newname);
+ TALLOC_FREE(smb_fname_new);
}
if (!create_it) {
@@ -561,8 +572,7 @@ static int streams_depot_open(vfs_handle_struct *handle,
int ret = -1;
if (!is_ntfs_stream_smb_fname(smb_fname)) {
- ret = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
- return ret;
+ return SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
}
/* If the default stream is requested, just open the base file. */
@@ -669,80 +679,72 @@ static int streams_depot_unlink(vfs_handle_struct *handle, const char *fname)
}
static int streams_depot_rename(vfs_handle_struct *handle,
- const char *oldname,
- const char *newname)
+ const struct smb_filename *smb_fname_src,
+ const struct smb_filename *smb_fname_dst)
{
- TALLOC_CTX *frame = NULL;
+ struct smb_filename *smb_fname_src_stream = NULL;
+ struct smb_filename *smb_fname_dst_stream = NULL;
+ struct smb_filename *smb_fname_dst_mod = NULL;
+ bool src_is_stream, dst_is_stream;
+ NTSTATUS status;
int ret = -1;
- bool old_is_stream;
- bool new_is_stream;
- char *obase = NULL;
- char *osname = NULL;
- char *nbase = NULL;
- char *nsname = NULL;
- char *ostream_fname = NULL;
- char *nstream_fname = NULL;
- char *newname_full = NULL;
DEBUG(10, ("streams_depot_rename called for %s => %s\n",
- oldname, newname));
-
- old_is_stream = is_ntfs_stream_name(oldname);
- new_is_stream = is_ntfs_stream_name(newname);
-
- if (!old_is_stream && !new_is_stream) {
- return SMB_VFS_NEXT_RENAME(handle, oldname, newname);
- }
+ smb_fname_str_dbg(smb_fname_src),
+ smb_fname_str_dbg(smb_fname_dst)));
- frame = talloc_stackframe();
+ src_is_stream = is_ntfs_stream_smb_fname(smb_fname_src);
+ dst_is_stream = is_ntfs_stream_smb_fname(smb_fname_dst);
- if (!NT_STATUS_IS_OK(split_ntfs_stream_name(talloc_tos(), oldname,
- &obase, &osname))) {
- errno = ENOMEM;
- goto done;
- }
-
- if (!NT_STATUS_IS_OK(split_ntfs_stream_name(talloc_tos(), newname,
- &nbase, &nsname))) {
- errno = ENOMEM;
- goto done;
+ if (!src_is_stream && !dst_is_stream) {
+ return SMB_VFS_NEXT_RENAME(handle, smb_fname_src,
+ smb_fname_dst);
}
/* for now don't allow renames from or to the default stream */
- if (!osname || !nsname) {
+ if (is_ntfs_default_stream_smb_fname(smb_fname_src) ||
+ is_ntfs_default_stream_smb_fname(smb_fname_dst)) {
errno = ENOSYS;
goto done;
}
- ostream_fname = stream_name(handle, oldname, false);
- if (ostream_fname == NULL) {
- return -1;
+ status = stream_smb_fname(handle, smb_fname_src, &smb_fname_src_stream,
+ false);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = map_errno_from_nt_status(status);
+ goto done;
}
/*
* Handle passing in a stream name without the base file. This is
* exercised by the NTRENAME streams rename path.
*/
- if (StrCaseCmp(nbase, "./") == 0) {
- newname_full = talloc_asprintf(talloc_tos(), "%s:%s", obase,
- nsname);
- if (newname_full == NULL) {
- errno = ENOMEM;
+ if (StrCaseCmp(smb_fname_dst->base_name, "./") == 0) {
+ status = create_synthetic_smb_fname(talloc_tos(),
+ smb_fname_src->base_name,
+ smb_fname_dst->stream_name,
+ NULL, &smb_fname_dst_mod);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = map_errno_from_nt_status(status);
goto done;
}
}
- nstream_fname = stream_name(handle,
- newname_full ? newname_full : newname,
- false);
- if (nstream_fname == NULL) {
- return -1;
+ status = stream_smb_fname(handle, (smb_fname_dst_mod ?
+ smb_fname_dst_mod : smb_fname_dst),
+ &smb_fname_dst_stream, false);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = map_errno_from_nt_status(status);
+ goto done;
}
- ret = SMB_VFS_NEXT_RENAME(handle, ostream_fname, nstream_fname);
+ ret = SMB_VFS_NEXT_RENAME(handle, smb_fname_src_stream,
+ smb_fname_dst_stream);
done:
- TALLOC_FREE(frame);
+ TALLOC_FREE(smb_fname_src_stream);
+ TALLOC_FREE(smb_fname_dst_stream);
+ TALLOC_FREE(smb_fname_dst_mod);
return ret;
}