From 2d211fb198428c5f349eabc627ba919f0e85d3b0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 7 Oct 2021 14:08:48 -0700 Subject: [PATCH 1/2] s3: selftest: Add regression test to show the $cwd cache is misbehaving when we connect as a different user on a share. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14682 Signed-off-by: Jeremy Allison --- selftest/knownfail.d/chdir-cache | 1 + source3/script/tests/test_chdir_cache.sh | 102 +++++++++++++++++++++++ source3/selftest/tests.py | 9 ++ 3 files changed, 112 insertions(+) create mode 100644 selftest/knownfail.d/chdir-cache create mode 100755 source3/script/tests/test_chdir_cache.sh diff --git a/selftest/knownfail.d/chdir-cache b/selftest/knownfail.d/chdir-cache new file mode 100644 index 00000000000..571701dcb14 --- /dev/null +++ b/selftest/knownfail.d/chdir-cache @@ -0,0 +1 @@ +^samba3.blackbox.chdir-cache.* diff --git a/source3/script/tests/test_chdir_cache.sh b/source3/script/tests/test_chdir_cache.sh new file mode 100755 index 00000000000..6287d17354a --- /dev/null +++ b/source3/script/tests/test_chdir_cache.sh @@ -0,0 +1,102 @@ +#!/bin/bash +# +# Ensure we get a chdir_current_service error if CHDIR fails with EACCESS +# for an SMB2 request. +# +# BUG:https://bugzilla.samba.org/show_bug.cgi?id=14682 +# +# Copyright (C) 2021 Jeremy Allison + +if [ $# -lt 5 ]; then + echo Usage: test_chdir_user.sh \ + --configfile=SERVERCONFFILE SMBCLIENT SMBCONTROL SERVER SHARE +exit 1 +fi + +CONF=$1; shift 1 +SMBCLIENT=$1; shift 1 +SMBCONTROL=$1; shift 1 +SERVER=$1; shift 1 +SHARE=$1; shift 1 + +# Do not let deprecated option warnings muck this up +SAMBA_DEPRECATED_SUPPRESS=1 +export SAMBA_DEPRECATED_SUPPRESS + +conf_dir=$(dirname ${SERVERCONFFILE}) + +log_file=${conf_dir}/../smbd_test.log + +error_inject_conf=${conf_dir}/error_inject.conf +> ${error_inject_conf} + +incdir=$(dirname $0)/../../../testprogs/blackbox +. $incdir/subunit.sh + +failed=0 + +cd $SELFTEST_TMPDIR || exit 1 + +rm -f smbclient-stdin smbclient-stdout smbclient-stderr +mkfifo smbclient-stdin smbclient-stdout smbclient-stderr + +CLI_FORCE_INTERACTIVE=1; export CLI_FORCE_INTERACTIVE + +${SMBCLIENT} //${SERVER}/${SHARE} ${CONF} -U${USER}%${PASSWORD} \ + < smbclient-stdin > smbclient-stdout 2>smbclient-stderr & +CLIENT_PID=$! + +# Count the number of chdir_current_service: vfs_ChDir.*failed: Permission denied +# errors that are already in the log (should be zero). +num_errs=`grep "chdir_current_service: vfs_ChDir.*failed: Permission denied" ${log_file} | wc -l` + +sleep 1 + +exec 100>smbclient-stdin 101&100 + +# consume the smbclient output +head -n 4 <&101 + +# Now change user to user2, and connect to the share. +# This should leave us in the same share directory. +echo "logon user2 ${PASSWORD}" >&100 +echo "tcon ${SHARE}" >&100 + +# consume the smbclient output +head -n 4 <&101 + +# Ensure any chdir will give EACCESS. +echo "error_inject:chdir = EACCES" > ${error_inject_conf} +${SMBCONTROL} ${CONF} 0 reload-config + +sleep 1 + +# Do an 'ls' as user2. Changing users should have +# deleted the CHDIR cache, so we should now see +# a chdir_current_service: vfs_ChDir.*failed: Permission denied +# error message in the log. +echo 'ls' >&100 + +kill ${CLIENT_PID} +rm -f smbclient-stdin smbclient-stdout smbclient-stderr + +# Remove the chdir inject. +> ${error_inject_conf} +${SMBCONTROL} ${CONF} 0 reload-config + +# Now look for chdir_current_service: vfs_ChDir.*failed: Permission denied +# in the smb log. There should be one more than before. + +num_errs1=`grep "chdir_current_service: vfs_ChDir.*failed: Permission denied" ${log_file} | wc -l` + +testit "Verify we got at least one chdir error" \ + test $num_errs1 -gt $num_errs || failed=$(expr $failed + 1) + +testok $0 $failed diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py index 500ddddfc7d..32eebe76178 100755 --- a/source3/selftest/tests.py +++ b/source3/selftest/tests.py @@ -1078,6 +1078,15 @@ plantestsuite("samba3.blackbox.open-eintr", "simpleserver:local", '$SERVER_IP', "error_inject"]) +plantestsuite("samba3.blackbox.chdir-cache", "simpleserver:local", + [os.path.join(samba3srcdir, + "script/tests/test_chdir_cache.sh"), + configuration, + os.path.join(bindir(), "smbclient"), + os.path.join(bindir(), "smbcontrol"), + '$SERVER_IP', + "error_inject"]) + plantestsuite("samba3.blackbox.netfileenum", "simpleserver:local", [os.path.join(samba3srcdir, "script/tests/test_netfileenum.sh"), -- 2.30.2 From d9c0f85c0dbbc2c102fdf85b5e178d88c5a4e662 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 7 Oct 2021 14:11:25 -0700 Subject: [PATCH 2/2] s3: smbd: Ensure when we change security context we delete any $cwd cache. This will ensure we *always* call into the VFS_SMB_CHDIR backends on security context switch. The $cwd was an optimization that was only looking at the raw filesystem path. We could delete it completely but that is a patch for another day. Remove knownfail on regression test. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14682 Signed-off-by: Jeremy Allison --- selftest/knownfail.d/chdir-cache | 1 - source3/smbd/sec_ctx.c | 8 ++++++++ 2 files changed, 8 insertions(+), 1 deletion(-) delete mode 100644 selftest/knownfail.d/chdir-cache diff --git a/selftest/knownfail.d/chdir-cache b/selftest/knownfail.d/chdir-cache deleted file mode 100644 index 571701dcb14..00000000000 --- a/selftest/knownfail.d/chdir-cache +++ /dev/null @@ -1 +0,0 @@ -^samba3.blackbox.chdir-cache.* diff --git a/source3/smbd/sec_ctx.c b/source3/smbd/sec_ctx.c index d6fd11cd4a3..4ccda709528 100644 --- a/source3/smbd/sec_ctx.c +++ b/source3/smbd/sec_ctx.c @@ -360,6 +360,14 @@ static void set_sec_ctx_internal(uid_t uid, gid_t gid, current_user.ut.ngroups = ngroups; current_user.ut.groups = groups; current_user.nt_user_token = ctx_p->token; + + /* + * Delete any ChDir cache. We can't assume + * the new uid has access to current working + * directory. + * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14682 + */ + SAFE_FREE(LastDir); } void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups, const struct security_token *token) -- 2.30.2