]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3:smbd: make sure vfs_ChDir() always sets conn->cwd_fsp->fh->fd = AT_FDCWD
authorStefan Metzmacher <metze@samba.org>
Wed, 1 Jul 2020 07:38:58 +0000 (09:38 +0200)
committerKarolin Seeger <kseeger@samba.org>
Thu, 9 Jul 2020 13:04:14 +0000 (13:04 +0000)
This is what all consumers of conn->cwd_fsp->fh->fd expect!

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

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
(cherry picked from commit f3f330f61db983f6d213a097d9a4d91b1057ecb1)

Autobuild-User(v4-12-test): Karolin Seeger <kseeger@samba.org>
Autobuild-Date(v4-12-test): Thu Jul  9 13:04:14 UTC 2020 on sn-devel-184

selftest/knownfail.d/bug14427 [deleted file]
source3/smbd/vfs.c

diff --git a/selftest/knownfail.d/bug14427 b/selftest/knownfail.d/bug14427
deleted file mode 100644 (file)
index e136465..0000000
+++ /dev/null
@@ -1 +0,0 @@
-^samba3.smb2.delete-on-close-perms.BUG14427
index 7c8f99bbd414f460004b053e125360438408f9ce..411999c3856165bcb0df3047cab88e0510045650 100644 (file)
@@ -876,12 +876,47 @@ int vfs_ChDir(connection_struct *conn, const struct smb_filename *smb_fname)
        }
 
        if (ISDOT(smb_fname->base_name)) {
+               /*
+                * passing a '.' is a noop,
+                * and we only expect this after
+                * everything is initialized.
+                *
+                * So the first vfs_ChDir() on a given
+                * connection_struct must not be '.'.
+                *
+                * Note: conn_new() sets
+                * conn->cwd_fsp->fh->fd = -1
+                * and vfs_ChDir() leaves with
+                * conn->cwd_fsp->fh->fd = AT_FDCWD
+                * on success!
+                */
+               if (conn->cwd_fsp->fh->fd != AT_FDCWD) {
+                       /*
+                        * This should never happen and
+                        * we might change this to
+                        * SMB_ASSERT() in future.
+                        */
+                       DBG_ERR("Called with '.' as first operation!\n");
+                       log_stack_trace();
+                       errno = EINVAL;
+                       return -1;
+               }
                return 0;
        }
 
        if (smb_fname->base_name[0] == '/' &&
            strcsequal(LastDir,smb_fname->base_name))
        {
+               /*
+                * conn->cwd_fsp->fsp_name and the kernel
+                * are already correct, but conn->cwd_fsp->fh->fd
+                * might still be -1 as initialized in conn_new().
+                *
+                * This can happen when a client made a 2nd
+                * tree connect to a share with the same underlying
+                * path (may or may not the same share).
+                */
+               conn->cwd_fsp->fh->fd = AT_FDCWD;
                return 0;
        }