summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/modules/vfs_streams_depot.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/source3/modules/vfs_streams_depot.c b/source3/modules/vfs_streams_depot.c
index 80c693190c..f8a8d97743 100644
--- a/source3/modules/vfs_streams_depot.c
+++ b/source3/modules/vfs_streams_depot.c
@@ -498,6 +498,78 @@ static int streams_depot_unlink(vfs_handle_struct *handle, const char *fname)
return SMB_VFS_NEXT_UNLINK(handle, fname);
}
+static int streams_depot_rename(vfs_handle_struct *handle,
+ const char *oldname,
+ const char *newname)
+{
+ TALLOC_CTX *frame = NULL;
+ 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;
+
+ 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);
+ }
+
+ if (!(old_is_stream && new_is_stream)) {
+ errno = ENOSYS;
+ return -1;
+ }
+
+ frame = talloc_stackframe();
+
+ 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(), oldname,
+ &nbase, &nsname))) {
+ errno = ENOMEM;
+ goto done;
+ }
+
+ /* for now don't allow renames from or to the default stream */
+ if (!osname || !nsname) {
+ errno = ENOSYS;
+ goto done;
+ }
+
+ if (StrCaseCmp(obase, nbase) != 0) {
+ errno = ENOSYS;
+ goto done;
+ }
+
+ ostream_fname = stream_name(handle, oldname, false);
+ if (ostream_fname == NULL) {
+ return -1;
+ }
+
+ nstream_fname = stream_name(handle, newname, false);
+ if (nstream_fname == NULL) {
+ return -1;
+ }
+
+ ret = SMB_VFS_NEXT_RENAME(handle, ostream_fname, nstream_fname);
+
+done:
+ TALLOC_FREE(frame);
+ return ret;
+}
+
static bool add_one_stream(TALLOC_CTX *mem_ctx, unsigned int *num_streams,
struct stream_struct **streams,
const char *name, SMB_OFF_T size,
@@ -648,6 +720,8 @@ static vfs_op_tuple streams_depot_ops[] = {
SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(streams_depot_unlink), SMB_VFS_OP_UNLINK,
SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(streams_depot_rename), SMB_VFS_OP_RENAME,
+ SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(streams_depot_streaminfo), SMB_VFS_OP_STREAMINFO,
SMB_VFS_LAYER_OPAQUE},
{SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}