From 764c09e6bc92d8ccd33b44d6cc80e82a9b4d76f0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 18 Oct 2009 14:19:27 +1100 Subject: s4-streams: fixed handling of stream rename and overwrite --- source4/ntvfs/posix/pvfs_rename.c | 3 ++- source4/ntvfs/posix/pvfs_setfileinfo.c | 3 ++- source4/ntvfs/posix/pvfs_streams.c | 24 +++++++++++++++++------- 3 files changed, 21 insertions(+), 9 deletions(-) (limited to 'source4') diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c index 0616d38bee..d963357cba 100644 --- a/source4/ntvfs/posix/pvfs_rename.c +++ b/source4/ntvfs/posix/pvfs_rename.c @@ -515,7 +515,8 @@ static NTSTATUS pvfs_rename_stream(struct ntvfs_module_context *ntvfs, NT_STATUS_NOT_OK_RETURN(status); status = pvfs_stream_rename(pvfs, name1, -1, - ren->ntrename.in.new_name+1); + ren->ntrename.in.new_name+1, + true); NT_STATUS_NOT_OK_RETURN(status); return NT_STATUS_OK; diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index c70b44def0..b40ae9c9de 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -108,7 +108,8 @@ static NTSTATUS pvfs_setfileinfo_rename_stream(struct pvfs_state *pvfs, status = pvfs_stream_rename(pvfs, name, fd, - info->rename_information.in.new_name+1); + info->rename_information.in.new_name+1, + info->rename_information.in.overwrite); return status; } diff --git a/source4/ntvfs/posix/pvfs_streams.c b/source4/ntvfs/posix/pvfs_streams.c index 6b39fb6066..4da95432c1 100644 --- a/source4/ntvfs/posix/pvfs_streams.c +++ b/source4/ntvfs/posix/pvfs_streams.c @@ -240,7 +240,7 @@ static NTSTATUS pvfs_stream_update_size(struct pvfs_state *pvfs, struct pvfs_fil rename a stream */ NTSTATUS pvfs_stream_rename(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd, - const char *new_name) + const char *new_name, bool overwrite) { struct xattr_DosStreams *streams; int i, found_old, found_new; @@ -289,17 +289,27 @@ NTSTATUS pvfs_stream_rename(struct pvfs_state *pvfs, struct pvfs_filename *name, struct xattr_DosStream *s = &streams->streams[found_old]; s->name = new_name; } else { - /* remove the old one and replace with the new one */ - streams->streams[found_old].name = new_name; - memmove(&streams->streams[found_new], - &streams->streams[found_new+1], - sizeof(streams->streams[0]) * - (streams->num_streams - (found_new+1))); + if (!overwrite) { + return NT_STATUS_OBJECT_NAME_COLLISION; + } + if (found_old != found_new) { + /* remove the old one and replace with the new one */ + streams->streams[found_old].name = new_name; + memmove(&streams->streams[found_new], + &streams->streams[found_new+1], + sizeof(streams->streams[0]) * + (streams->num_streams - (found_new+1))); + streams->num_streams--; + } } status = pvfs_streams_save(pvfs, name, fd, streams); talloc_free(streams); + /* update the in-memory copy of the name of the open file */ + talloc_free(name->stream_name); + name->stream_name = talloc_strdup(name, new_name); + return status; } -- cgit