summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2014-06-24 14:19:30 -0700
committerKarolin Seeger <kseeger@samba.org>2014-07-17 08:54:06 +0200
commitf8af6870a061758a37bb6c63d09ce23ab971c6ce (patch)
tree4f2785492cd9c073e830dbde044baaf8d09aca88 /source3
parent610320ee67ff1430ebd72bcd187953b6f9127045 (diff)
downloadsamba-f8af6870a061758a37bb6c63d09ce23ab971c6ce.tar.gz
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> (cherry picked from commit 31b3427a417217e5e869baafdf63e633efc39d12) [ddiss@samba.org: 4.1 backport]
Diffstat (limited to 'source3')
-rw-r--r--source3/smbd/open.c22
1 files changed, 20 insertions, 2 deletions
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index 5f7bff9a8d3..72b8b598310 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -839,8 +839,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) "
@@ -2646,6 +2649,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,
oplock_request,
got_level2_oplock,