smbd: Only check dev/inode in open_directory, not the full stat()
authorAndrew Bartlett <abartlet@samba.org>
Fri, 11 Mar 2016 01:27:53 +0000 (14:27 +1300)
committerKarolin Seeger <kseeger@samba.org>
Mon, 21 Mar 2016 14:33:32 +0000 (15:33 +0100)
This is needed because the smb2.create.mkdir-dup test creates a race,
and against an AD DC this can cause a flapping test if the lstat() and
stat() calls are made either side of the chown() due to creation of a
file by administrator.

Fix based on original patches by myself, by Douglas Bagnall
<douglas.bagnall@catalyst.net.nz>.  and Jeremy Allison <jra@samba.org>

BUG: https://bugzilla.samba.org/show_bug.cgi?id=11780

Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Sat Mar 12 09:43:21 CET 2016 on sn-devel-144

(cherry picked from commit 5fc6d2dabdf2aeef74fdefaa67eae0348bbf7a44)

Autobuild-User(v4-2-test): Karolin Seeger <kseeger@samba.org>
Autobuild-Date(v4-2-test): Mon Mar 21 15:33:32 CET 2016 on sn-devel-104

source3/smbd/open.c

index eb4323afc5789422ce3173b7e0c26c21c2ef0f5d..c4489b8139116628fa4dfa2030b470f90baeff5d 100644 (file)
@@ -3621,8 +3621,18 @@ static NTSTATUS open_directory(connection_struct *conn,
                return status;
        }
 
-       /* Ensure there was no race condition. */
-       if (!check_same_stat(&smb_dname->st, &fsp->fsp_name->st)) {
+       if(!S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
+               DEBUG(5,("open_directory: %s is not a directory !\n",
+                        smb_fname_str_dbg(smb_dname)));
+                fd_close(fsp);
+                file_free(req, fsp);
+               return NT_STATUS_NOT_A_DIRECTORY;
+       }
+
+       /* Ensure there was no race condition.  We need to check
+        * dev/inode but not permissions, as these can change
+        * legitimately */
+       if (!check_same_dev_ino(&smb_dname->st, &fsp->fsp_name->st)) {
                DEBUG(5,("open_directory: stat struct differs for "
                        "directory %s.\n",
                        smb_fname_str_dbg(smb_dname)));