diff options
author | Jeremy Allison <jra@samba.org> | 2009-02-19 11:19:10 -0800 |
---|---|---|
committer | Karolin Seeger <kseeger@samba.org> | 2009-02-20 08:53:30 +0100 |
commit | 9f5ab2af11fbef878956e3e6ef6a1c5c511c707e (patch) | |
tree | a972ab7f688c31e7e255b57a55148c0d493c8b89 | |
parent | 7480b88af9bd1ed36abb816c85f69746d444dadc (diff) | |
download | samba-9f5ab2af11fbef878956e3e6ef6a1c5c511c707e.tar.gz |
Backport the semantics of when to delete alternate data streams on a file truncate.
Needed to fully support stream semantics.
Jeremy.
(cherry picked from commit 5a68f1e2c1fd16d315b1e303a90eb6475bbe7b15)
-rw-r--r-- | source/include/proto.h | 1 | ||||
-rw-r--r-- | source/smbd/close.c | 2 | ||||
-rw-r--r-- | source/smbd/open.c | 14 |
3 files changed, 16 insertions, 1 deletions
diff --git a/source/include/proto.h b/source/include/proto.h index 716f1771072..edb0009dd9c 100644 --- a/source/include/proto.h +++ b/source/include/proto.h @@ -8690,6 +8690,7 @@ void msg_close_file(struct messaging_context *msg_ctx, uint32_t msg_type, struct server_id server_id, DATA_BLOB *data); +NTSTATUS delete_all_streams(connection_struct *conn, const char *fname); /* The following definitions come from smbd/conn.c */ diff --git a/source/smbd/close.c b/source/smbd/close.c index 25552e37ab3..d5861160aa8 100644 --- a/source/smbd/close.c +++ b/source/smbd/close.c @@ -167,7 +167,7 @@ static void notify_deferred_opens(struct share_mode_lock *lck) Delete all streams ****************************************************************************/ -static NTSTATUS delete_all_streams(connection_struct *conn, const char *fname) +NTSTATUS delete_all_streams(connection_struct *conn, const char *fname) { struct stream_struct *stream_info; int i; diff --git a/source/smbd/open.c b/source/smbd/open.c index 716b9ff4925..bbf1b40c2f8 100644 --- a/source/smbd/open.c +++ b/source/smbd/open.c @@ -1358,6 +1358,7 @@ static NTSTATUS open_file_ntcreate_internal(connection_struct *conn, bool def_acl = False; bool posix_open = False; bool new_file_created = False; + bool clear_ads = false; struct file_id id; NTSTATUS fsp_open = NT_STATUS_ACCESS_DENIED; mode_t new_unx_mode = (mode_t)0; @@ -1490,12 +1491,14 @@ static NTSTATUS open_file_ntcreate_internal(connection_struct *conn, /* If file exists replace/overwrite. If file doesn't * exist create. */ flags2 |= (O_CREAT | O_TRUNC); + clear_ads = true; break; case FILE_OVERWRITE_IF: /* If file exists replace/overwrite. If file doesn't * exist create. */ flags2 |= (O_CREAT | O_TRUNC); + clear_ads = true; break; case FILE_OPEN: @@ -1520,6 +1523,7 @@ static NTSTATUS open_file_ntcreate_internal(connection_struct *conn, return NT_STATUS_OBJECT_NAME_NOT_FOUND; } flags2 |= O_TRUNC; + clear_ads = true; break; case FILE_CREATE: @@ -1953,6 +1957,16 @@ static NTSTATUS open_file_ntcreate_internal(connection_struct *conn, SMB_ASSERT(lck != NULL); + /* Delete streams if create_disposition requires it */ + if (file_existed && clear_ads && !is_ntfs_stream_name(fname)) { + status = delete_all_streams(conn, fname); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(lck); + fd_close(fsp); + return status; + } + } + /* note that we ignore failure for the following. It is basically a hack for NFS, and NFS will never set one of these only read them. Nobody but Samba can ever set a deny |