summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2009-10-18 14:19:27 +1100
committerAndrew Tridgell <tridge@samba.org>2009-10-18 15:06:13 +1100
commit764c09e6bc92d8ccd33b44d6cc80e82a9b4d76f0 (patch)
treed591e33e4f3689552d0e5bf80f3742414971af4b
parent44612c74a6de8becd8f8dc51590616ba792ca13f (diff)
downloadsamba-764c09e6bc92d8ccd33b44d6cc80e82a9b4d76f0.tar.gz
samba-764c09e6bc92d8ccd33b44d6cc80e82a9b4d76f0.tar.bz2
samba-764c09e6bc92d8ccd33b44d6cc80e82a9b4d76f0.zip
s4-streams: fixed handling of stream rename and overwrite
-rw-r--r--source4/ntvfs/posix/pvfs_rename.c3
-rw-r--r--source4/ntvfs/posix/pvfs_setfileinfo.c3
-rw-r--r--source4/ntvfs/posix/pvfs_streams.c24
3 files changed, 21 insertions, 9 deletions
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;
}