diff options
author | Jeremy Allison <jra@samba.org> | 2014-06-24 14:19:30 -0700 |
---|---|---|
committer | David Disseldorp <ddiss@samba.org> | 2014-06-25 11:22:12 +0200 |
commit | 31b3427a417217e5e869baafdf63e633efc39d12 (patch) | |
tree | 1cc81fcb418a2de5c24b4d5358ceca8264e0c3f2 | |
parent | 457d79f2cb83f3f5c3f8d64ed99f9b1ea0185d3f (diff) | |
download | samba-31b3427a417217e5e869baafdf63e633efc39d12.tar.gz samba-31b3427a417217e5e869baafdf63e633efc39d12.tar.xz samba-31b3427a417217e5e869baafdf63e633efc39d12.zip |
s3: smbd - Prevent file truncation on an open that fails with share mode violation.
Fix from Volker, really - just tidied up a little.
The S_ISFIFO check may not be strictly neccessary,
but doesn't hurt (might make the code a bit more complex
than it needs to be).
Fixes bug #10671 - Samba file corruption as a result of failed lock check.
https://bugzilla.samba.org/show_bug.cgi?id=10671
Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
Reviewed-by: David Disseldorp <ddiss@samba.org>
-rw-r--r-- | source3/smbd/open.c | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/source3/smbd/open.c b/source3/smbd/open.c index b913c9c576..687caee6ab 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -840,8 +840,11 @@ static NTSTATUS open_file(files_struct *fsp, } } - /* Actually do the open */ - status = fd_open_atomic(conn, fsp, local_flags, + /* + * Actually do the open - if O_TRUNC is needed handle it + * below under the share mode lock. + */ + status = fd_open_atomic(conn, fsp, local_flags & ~O_TRUNC, unx_mode, p_file_created); if (!NT_STATUS_IS_OK(status)) { DEBUG(3,("Error opening file %s (%s) (local_flags=%d) " @@ -2676,6 +2679,21 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn, return status; } + /* Should we atomically (to the client at least) truncate ? */ + if (!new_file_created) { + if (flags2 & O_TRUNC) { + if (!S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) { + int ret = vfs_set_filelen(fsp, 0); + if (ret != 0) { + status = map_nt_error_from_unix(errno); + TALLOC_FREE(lck); + fd_close(fsp); + return status; + } + } + } + } + grant_fsp_oplock_type(fsp, lck, oplock_request); /* |