From 9f4e9b426a8498716f003952b06e2a0a48f5eb8b Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 10 Sep 2014 00:31:25 +0200 Subject: [PATCH 1/2] s3:smbd: fix a race in open code The race is when a file vanishes between existence check and acl check. In this case, open_file_ncreate() returns OBJECT_NAME_NOT_FOUND even if the create was called with disposition OPEN_IF. But in this case, the file should be created. Signed-off-by: Michael Adam Reviewed-by: Jeremy Allison (cherry picked from commit 8ae8c63da19459fd4f1166e11406da2c919b7ed0) BUG: https://bugzilla.samba.org/show_bug.cgi?id=10809 --- source3/smbd/open.c | 59 ++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 42 insertions(+), 17 deletions(-) diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 16d4307..cc6e080 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -818,24 +818,49 @@ static NTSTATUS open_file(files_struct *fsp, smb_fname, false, access_mask); - } else if (local_flags & O_CREAT){ - status = check_parent_access(conn, - smb_fname, - SEC_DIR_ADD_FILE); - } else { - /* File didn't exist and no O_CREAT. */ - return NT_STATUS_OBJECT_NAME_NOT_FOUND; + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("open_file: " + "smbd_check_access_rights " + "on file %s returned %s\n", + smb_fname_str_dbg(smb_fname), + nt_errstr(status))); + } + + if (!NT_STATUS_IS_OK(status) && + !NT_STATUS_EQUAL(status, + NT_STATUS_OBJECT_NAME_NOT_FOUND)) + { + return status; + } + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("open_file: " + "file %s vanished since we " + "checked for existence.\n", + smb_fname_str_dbg(smb_fname))); + file_existed = false; + SET_STAT_INVALID(fsp->fsp_name->st); + } } - if (!NT_STATUS_IS_OK(status)) { - DEBUG(10,("open_file: " - "%s on file " - "%s returned %s\n", - file_existed ? - "smbd_check_access_rights" : - "check_parent_access", - smb_fname_str_dbg(smb_fname), - nt_errstr(status) )); - return status; + + if (!file_existed) { + if (!(local_flags & O_CREAT)) { + /* File didn't exist and no O_CREAT. */ + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + + status = check_parent_access(conn, + smb_fname, + SEC_DIR_ADD_FILE); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("open_file: " + "check_parent_access on " + "file %s returned %s\n", + smb_fname_str_dbg(smb_fname), + nt_errstr(status) )); + return status; + } } } -- 1.9.1 From dfe008f00f4c9e47214ffa5dd576e0ea0d2f4e5d Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 10 Sep 2014 21:58:04 +0200 Subject: [PATCH 2/2] s3:smbd:open_file: use a more natural check. As suggested by Jeremy Allison . Signed-off-by: Michael Adam Reviewed-by: Jeremy Allison (cherry picked from commit 9da09b52e8cc0453e694d85fc2bd82994138e20b) BUG: https://bugzilla.samba.org/show_bug.cgi?id=10809 --- source3/smbd/open.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source3/smbd/open.c b/source3/smbd/open.c index cc6e080..a2733dc 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -834,7 +834,9 @@ static NTSTATUS open_file(files_struct *fsp, return status; } - if (!NT_STATUS_IS_OK(status)) { + if (NT_STATUS_EQUAL(status, + NT_STATUS_OBJECT_NAME_NOT_FOUND)) + { DEBUG(10, ("open_file: " "file %s vanished since we " "checked for existence.\n", -- 1.9.1