diff options
author | Jeremy Allison <jra@samba.org> | 2012-07-10 10:15:07 -0700 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2012-07-10 21:57:33 +0200 |
commit | 6d903bf1899987adaeaaf6608ac318aca4588590 (patch) | |
tree | f15b7a7807569754e0efa4893fc8934e04e50231 /source3/smbd | |
parent | 69a3e947b60397c9bb9175cf52fe009b6b057350 (diff) | |
download | samba-6d903bf1899987adaeaaf6608ac318aca4588590.tar.gz samba-6d903bf1899987adaeaaf6608ac318aca4588590.tar.bz2 samba-6d903bf1899987adaeaaf6608ac318aca4588590.zip |
Cope with a (non-security) open race we've had for ever as NTCreateX isn't atomic on POSIX.
On open without create, the file did exist, but some
other (local or NFS) process either renamed/unlinked
and re-created the file with different dev/ino after
we walked the path, but before we did the open. We
could retry the open but it's a rare enough case it's
easier to just fail the open to prevent creating any
problems in the open file db having the wrong dev/ino
key.
Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Tue Jul 10 21:57:33 CEST 2012 on sn-devel-104
Diffstat (limited to 'source3/smbd')
-rw-r--r-- | source3/smbd/open.c | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 79f8305836..0f4a588999 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -1810,6 +1810,7 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn, uint32 open_access_mask = access_mask; NTSTATUS status; char *parent_dir; + SMB_STRUCT_STAT saved_stat = smb_fname->st; if (conn->printer) { /* @@ -2349,6 +2350,30 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn, return fsp_open; } + if (file_existed && !check_same_dev_ino(&saved_stat, &smb_fname->st)) { + /* + * The file did exist, but some other (local or NFS) + * process either renamed/unlinked and re-created the + * file with different dev/ino after we walked the path, + * but before we did the open. We could retry the + * open but it's a rare enough case it's easier to + * just fail the open to prevent creating any problems + * in the open file db having the wrong dev/ino key. + */ + TALLOC_FREE(lck); + fd_close(fsp); + DEBUG(1,("open_file_ntcreate: file %s - dev/ino mismatch. " + "Old (dev=0x%llu, ino =0x%llu). " + "New (dev=0x%llu, ino=0x%llu). Failing open " + " with NT_STATUS_ACCESS_DENIED.\n", + smb_fname_str_dbg(smb_fname), + (unsigned long long)saved_stat.st_ex_dev, + (unsigned long long)saved_stat.st_ex_ino, + (unsigned long long)smb_fname->st.st_ex_dev, + (unsigned long long)smb_fname->st.st_ex_ino)); + return NT_STATUS_ACCESS_DENIED; + } + if (!file_existed) { struct share_mode_entry *batch_entry = NULL; struct share_mode_entry *exclusive_entry = NULL; |