summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Adam <obnox@samba.org>2014-09-10 00:31:25 +0200
committerJeremy Allison <jra@samba.org>2014-09-10 19:24:13 +0200
commit8ae8c63da19459fd4f1166e11406da2c919b7ed0 (patch)
tree73ef9c54cd6c9926f3e2523c9d7c57d610f1ab42
parent551ae16ab3be301ce5402e60f63f736960335d9f (diff)
downloadsamba-8ae8c63da19459fd4f1166e11406da2c919b7ed0.tar.gz
samba-8ae8c63da19459fd4f1166e11406da2c919b7ed0.tar.xz
samba-8ae8c63da19459fd4f1166e11406da2c919b7ed0.zip
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 <obnox@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org>
-rw-r--r--source3/smbd/open.c59
1 files changed, 42 insertions, 17 deletions
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index 67ba25e254..a33cce19ad 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -819,24 +819,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;
+ }
}
}