summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2009-02-19 11:19:10 -0800
committerKarolin Seeger <kseeger@samba.org>2009-02-20 08:53:30 +0100
commit9f5ab2af11fbef878956e3e6ef6a1c5c511c707e (patch)
treea972ab7f688c31e7e255b57a55148c0d493c8b89
parent7480b88af9bd1ed36abb816c85f69746d444dadc (diff)
downloadsamba-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.h1
-rw-r--r--source/smbd/close.c2
-rw-r--r--source/smbd/open.c14
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