The branch, master has been updated via 1654eae11b9 s3: smbd: Add IS_VETO_PATH checks to openat_pathref_fsp_case_insensitive(). via 1c293060204 s3: smbd: Add IS_VETO_PATH check to openat_pathref_dirfsp_nosymlink(). via c6933673222 s3: tests: Add samba3.blackbox.test_veto_files. from 076c22fbd7e selftest/Samba3: let nt4_dc* use vfs_default:VFS_OPEN_HOW_RESOLVE_NO_SYMLINKS=no
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 1654eae11b9c13308b2b78f70309eb3a56960619 Author: Jeremy Allison <j...@samba.org> Date: Thu Aug 11 10:03:58 2022 -0700 s3: smbd: Add IS_VETO_PATH checks to openat_pathref_fsp_case_insensitive(). Returns NT_STATUS_OBJECT_NAME_NOT_FOUND for final component. Note we have to call the check before each call to openat_pathref_fsp(), as each call may be using a different filesystem name. The first name is the one passed into openat_pathref_fsp_case_insensitive() by the caller, the second one is a name retrieved from get_real_filename_cache_key(), and the third one is the name retrieved from get_real_filename_at(). The last two calls may have demangled the client given name into a veto'ed path on the filesystem. Remove knownfail. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15143 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> Autobuild-User(master): Stefan Metzmacher <me...@samba.org> Autobuild-Date(master): Tue Aug 16 08:26:54 UTC 2022 on sn-devel-184 commit 1c293060204d96bf94427f91eb20eb9decc29a41 Author: Jeremy Allison <j...@samba.org> Date: Thu Aug 11 09:55:56 2022 -0700 s3: smbd: Add IS_VETO_PATH check to openat_pathref_dirfsp_nosymlink(). Returns NT_STATUS_OBJECT_PATH_NOT_FOUND for directory component. Note IS_VETO_PATH only looks at the last component, so we must do it during the directory walk on each component. Note, we also have to check after a call to get_real_filename_at() as it may have demangled the client sent name into a filesystem name that matches the "veto files" parameter. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15143 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit c6933673222ea9ae2eb74d5586c9495269f51ea0 Author: Jeremy Allison <j...@samba.org> Date: Thu Aug 11 09:51:11 2022 -0700 s3: tests: Add samba3.blackbox.test_veto_files. Shows we currently don't look at smb.conf veto files parameter when opening a file or directory. Checks multi-component paths. Also checks veto files that might be hidden behind a mangled name. Add knownfail. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15143 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> ----------------------------------------------------------------------- Summary of changes: selftest/target/Samba3.pm | 4 + source3/script/tests/test_veto_files.sh | 201 ++++++++++++++++++++++++++++++++ source3/selftest/tests.py | 4 + source3/smbd/filename.c | 20 ++++ source3/smbd/files.c | 18 +++ 5 files changed, 247 insertions(+) create mode 100755 source3/script/tests/test_veto_files.sh Changeset truncated at 500 lines: diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm index 387856e07a0..88898807428 100755 --- a/selftest/target/Samba3.pm +++ b/selftest/target/Samba3.pm @@ -1916,6 +1916,10 @@ sub setup_fileserver path = $veto_sharedir delete veto files = yes +[veto_files] + path = $veto_sharedir + veto files = /veto_name*/ + [delete_yes_unwrite] read only = no path = $delete_unwrite_sharedir diff --git a/source3/script/tests/test_veto_files.sh b/source3/script/tests/test_veto_files.sh new file mode 100755 index 00000000000..9f0526bd54c --- /dev/null +++ b/source3/script/tests/test_veto_files.sh @@ -0,0 +1,201 @@ +#!/bin/sh +# +# Check smbclient cannot get a file that matches a veto files +# parameter, or inside a directory that matches a veto files +# parameter. +# +# BUG: https://bugzilla.samba.org/show_bug.cgi?id=15143 +# + +if [ $# -lt 6 ]; then + cat <<EOF +Usage: $0 SERVER SERVER_IP USERNAME PASSWORD SHAREPATH SMBCLIENT +EOF + exit 1 +fi + +SERVER=${1} +SERVER_IP=${2} +USERNAME=${3} +PASSWORD=${4} +SHAREPATH=${5} +SMBCLIENT=${6} +shift 6 +SMBCLIENT="$VALGRIND ${SMBCLIENT}" +ADDARGS="$@" + +incdir=$(dirname "$0")/../../../testprogs/blackbox +. "$incdir"/subunit.sh + +failed=0 + +# +# Cleanup function. +# +do_cleanup() +{ + ( + #subshell. + rm -rf "$SHAREPATH/dir_1" + rm -rf "$SHAREPATH/veto_name_dir" + rm -rf "$SHAREPATH/veto_name_dir\"mangle" + rm -f "$SHAREPATH/veto_name_file" + rm -f "$SHAREPATH/veto_name_file\"mangle" + ) +} + +# +# smbclient function given path and expected error. +# +smbclient_get_expect_error() +{ + filename1="$1" + expected_error="$2" + tmpfile=$PREFIX/smbclient_interactive_prompt_commands + cat >"$tmpfile" <<EOF +get $filename1 got_file +quit +EOF + rm -f got_file + + cmd='CLI_FORCE_INTERACTIVE=yes $SMBCLIENT -U$USERNAME%$PASSWORD //$SERVER/veto_files -I$SERVER_IP < $tmpfile 2>&1' + eval echo "$cmd" + out=$(eval "$cmd") + ret=$? + rm -f "$tmpfile" + rm -f got_file + + if [ $ret != 0 ]; then + printf "%s\n" "$out" + printf "failed accessing veto_files share with error %s\n" "$ret" + return 1 + fi + + if [ "$expected_error" = "NT_STATUS_OK" ]; then + printf "%s" "$out" | grep "NT_STATUS_" | wc -l | grep '^0$' + else + printf "%s" "$out" | grep "$expected_error" + fi + ret=$? + if [ $ret != 0 ]; then + printf "%s\n" "$out" + printf "failed - should get %s doing \"get %s got_file\"\n" "$expected_error" "$filename1" + return 1 + fi +} + +# +# Using the share "[veto_files]" ensure we +# cannot fetch a veto'd file or file in a veto'd directory. +# +test_get_veto_file() +{ + # toplevel + smbclient_get_expect_error "veto_name_file" "NT_STATUS_OBJECT_NAME_NOT_FOUND" || return 1 + smbclient_get_expect_error "veto_name_dir/file_inside_dir" "NT_STATUS_OBJECT_PATH_NOT_FOUND" || return 1 + smbclient_get_expect_error "veto_name_dir/testdir/file_inside_dir" "NT_STATUS_OBJECT_PATH_NOT_FOUND" || return 1 + + # toplevel mangle names + smbclient_get_expect_error "VHXE5P~M" "NT_STATUS_OBJECT_NAME_NOT_FOUND" || return 1 + smbclient_get_expect_error "VF5SKC~B/file_inside_dir" "NT_STATUS_OBJECT_PATH_NOT_FOUND" || return 1 + smbclient_get_expect_error "VF5SKC~B/testdir/file_inside_dir" "NT_STATUS_OBJECT_PATH_NOT_FOUND" || return 1 + + # depth1 + smbclient_get_expect_error "dir1/veto_name_file" "NT_STATUS_OBJECT_NAME_NOT_FOUND" || return 1 + smbclient_get_expect_error "dir1/veto_name_dir/file_inside_dir" "NT_STATUS_OBJECT_PATH_NOT_FOUND" || return 1 + smbclient_get_expect_error "dir1/veto_name_dir/testdir/file_inside_dir" "NT_STATUS_OBJECT_PATH_NOT_FOUND" || return 1 + + # depth1 mangle names + smbclient_get_expect_error "dir1/VHXE5P~M" "NT_STATUS_OBJECT_NAME_NOT_FOUND" || return 1 + smbclient_get_expect_error "dir1/VF5SKC~B/file_inside_dir" "NT_STATUS_OBJECT_PATH_NOT_FOUND" || return 1 + smbclient_get_expect_error "dir1/VF5SKC~B/testdir/file_inside_dir" "NT_STATUS_OBJECT_PATH_NOT_FOUND" || return 1 + + # depth2 + smbclient_get_expect_error "dir1/dir2/veto_name_file" "NT_STATUS_OBJECT_NAME_NOT_FOUND" || return 1 + smbclient_get_expect_error "dir1/dir2/veto_name_dir/file_inside_dir" "NT_STATUS_OBJECT_PATH_NOT_FOUND" || return 1 + smbclient_get_expect_error "dir1/dir2/veto_name_dir/testdir/file_inside_dir" "NT_STATUS_OBJECT_PATH_NOT_FOUND" || return 1 + + # depth2 mangle names + smbclient_get_expect_error "dir1/dir2/VHXE5P~M" "NT_STATUS_OBJECT_NAME_NOT_FOUND" || return 1 + smbclient_get_expect_error "dir1/dir2/VF5SKC~B/file_inside_dir" "NT_STATUS_OBJECT_PATH_NOT_FOUND" || return 1 + smbclient_get_expect_error "dir1/dir2/VF5SKC~B/testdir/file_inside_dir" "NT_STATUS_OBJECT_PATH_NOT_FOUND" || return 1 + + # depth3 + smbclient_get_expect_error "dir1/dir2/dir3/veto_name_file" "NT_STATUS_OBJECT_NAME_NOT_FOUND" || return 1 + smbclient_get_expect_error "dir1/dir2/dir3/veto_name_dir/file_inside_dir" "NT_STATUS_OBJECT_PATH_NOT_FOUND" || return 1 + smbclient_get_expect_error "dir1/dir2/dir3/veto_name_dir/testdir/file_inside_dir" "NT_STATUS_OBJECT_PATH_NOT_FOUND" || return 1 + + # depth3 mangle names + smbclient_get_expect_error "dir1/dir2/dir3/VHXE5P~M" "NT_STATUS_OBJECT_NAME_NOT_FOUND" || return 1 + smbclient_get_expect_error "dir1/dir2/dir3/VF5SKC~B/file_inside_dir" "NT_STATUS_OBJECT_PATH_NOT_FOUND" || return 1 + smbclient_get_expect_error "dir1/dir2/dir3/VF5SKC~B/testdir/file_inside_dir" "NT_STATUS_OBJECT_PATH_NOT_FOUND" || return 1 + + return 0 +} + +do_cleanup + +# Using hash2, veto_name_file\"mangle == VHXE5P~M +# Using hash2, veto_name_dir\"mangle == VF5SKC~B + +# I think a depth of 3 should be enough. +# toplevel +touch "$SHAREPATH/veto_name_file" +mkdir "$SHAREPATH/veto_name_dir" +touch "$SHAREPATH/veto_name_dir/file_inside_dir" +mkdir "$SHAREPATH/veto_name_dir/testdir" +touch "$SHAREPATH/veto_name_dir/testdir/file_inside_dir" +# toplevel mangle names. +touch "$SHAREPATH/veto_name_file\"mangle" +mkdir "$SHAREPATH/veto_name_dir\"mangle" +touch "$SHAREPATH/veto_name_dir\"mangle/file_inside_dir" +mkdir "$SHAREPATH/veto_name_dir\"mangle/testdir" +touch "$SHAREPATH/veto_name_dir\"mangle/testdir/file_inside_dir" + +#depth1 +mkdir "$SHAREPATH/dir1" +touch "$SHAREPATH/dir1/veto_name_file" +mkdir "$SHAREPATH/dir1/veto_name_dir" +touch "$SHAREPATH/dir1/veto_name_dir/file_inside_dir" +mkdir "$SHAREPATH/dir1/veto_name_dir/testdir" +touch "$SHAREPATH/dir1/veto_name_dir/testdir/file_inside_dir" +# depth1 mangle names. +touch "$SHAREPATH/dir1/veto_name_file\"mangle" +mkdir "$SHAREPATH/dir1/veto_name_dir\"mangle" +touch "$SHAREPATH/dir1/veto_name_dir\"mangle/file_inside_dir" +mkdir "$SHAREPATH/dir1/veto_name_dir\"mangle/testdir" +touch "$SHAREPATH/dir1/veto_name_dir\"mangle/testdir/file_inside_dir" + +#depth2 +mkdir "$SHAREPATH/dir1/dir2" +touch "$SHAREPATH/dir1/dir2/veto_name_file" +mkdir "$SHAREPATH/dir1/dir2/veto_name_dir" +touch "$SHAREPATH/dir1/dir2/veto_name_dir/file_inside_dir" +mkdir "$SHAREPATH/dir1/dir2/veto_name_dir/testdir" +touch "$SHAREPATH/dir1/dir2/veto_name_dir/testdir/file_inside_dir" +# depth2 mangle names. +touch "$SHAREPATH/dir1/dir2/veto_name_file\"mangle" +mkdir "$SHAREPATH/dir1/dir2/veto_name_dir\"mangle" +touch "$SHAREPATH/dir1/dir2/veto_name_dir\"mangle/file_inside_dir" +mkdir "$SHAREPATH/dir1/dir2/veto_name_dir\"mangle/testdir" +touch "$SHAREPATH/dir1/dir2/veto_name_dir\"mangle/testdir/file_inside_dir" + +#depth3 +mkdir "$SHAREPATH/dir1/dir2/dir3" +touch "$SHAREPATH/dir1/dir2/dir3/veto_name_file" +mkdir "$SHAREPATH/dir1/dir2/dir3/veto_name_dir" +touch "$SHAREPATH/dir1/dir2/dir3/veto_name_dir/file_inside_dir" +mkdir "$SHAREPATH/dir1/dir2/dir3/veto_name_dir/testdir" +touch "$SHAREPATH/dir1/dir2/dir3/veto_name_dir/testdir/file_inside_dir" +# depth3 mangle names. +touch "$SHAREPATH/dir1/dir2/dir3/veto_name_file\"mangle" +mkdir "$SHAREPATH/dir1/dir2/dir3/veto_name_dir\"mangle" +touch "$SHAREPATH/dir1/dir2/dir3/veto_name_dir\"mangle/file_inside_dir" +mkdir "$SHAREPATH/dir1/dir2/dir3/veto_name_dir\"mangle/testdir" +touch "$SHAREPATH/dir1/dir2/dir3/veto_name_dir\"mangle/testdir/file_inside_dir" + +testit "get_veto_file" test_get_veto_file || failed=$(("$failed" + 1)) + +do_cleanup + +exit "$failed" diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py index 6b8e7f774f2..afb326029dc 100755 --- a/source3/selftest/tests.py +++ b/source3/selftest/tests.py @@ -641,6 +641,10 @@ for env in ["fileserver"]: '$SERVER', '$SERVER_IP', '$USERNAME', '$PASSWORD', '$LOCAL_PATH/local_symlinks', '$PREFIX', smbclient3]) + plantestsuite("samba3.blackbox.test_veto_files", env, + [os.path.join(samba3srcdir, "script/tests/test_veto_files.sh"), + '$SERVER', '$SERVER_IP', '$USERNAME', '$PASSWORD', '$LOCAL_PATH/veto', smbclient3]) + # # tar command tests # diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index f362aee9452..ca94b7ec7f9 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -836,6 +836,13 @@ static NTSTATUS openat_pathref_fsp_case_insensitive( SET_STAT_INVALID(smb_fname_rel->st); + /* Check veto files - only looks at last component. */ + if (IS_VETO_PATH(dirfsp->conn, smb_fname_rel->base_name)) { + DBG_DEBUG("veto files rejecting last component %s\n", + smb_fname_str_dbg(smb_fname_rel)); + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + status = openat_pathref_fsp(dirfsp, smb_fname_rel); if (NT_STATUS_IS_OK(status)) { @@ -895,6 +902,13 @@ static NTSTATUS openat_pathref_fsp_case_insensitive( return NT_STATUS_NO_MEMORY; } + if (IS_VETO_PATH(dirfsp->conn, smb_fname_rel->base_name)) { + DBG_DEBUG("veto files rejecting last component %s\n", + smb_fname_str_dbg(smb_fname_rel)); + TALLOC_FREE(cache_key.data); + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + status = openat_pathref_fsp(dirfsp, smb_fname_rel); if (NT_STATUS_IS_OK(status)) { TALLOC_FREE(cache_key.data); @@ -919,6 +933,12 @@ lookup: TALLOC_FREE(smb_fname_rel->base_name); smb_fname_rel->base_name = found_name; + if (IS_VETO_PATH(dirfsp->conn, smb_fname_rel->base_name)) { + DBG_DEBUG("veto files rejecting last component %s\n", + smb_fname_str_dbg(smb_fname_rel)); + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + status = openat_pathref_fsp(dirfsp, smb_fname_rel); } diff --git a/source3/smbd/files.c b/source3/smbd/files.c index af135d6e95a..a6c41f2b928 100644 --- a/source3/smbd/files.c +++ b/source3/smbd/files.c @@ -817,6 +817,14 @@ NTSTATUS openat_pathref_dirfsp_nosymlink( goto fail; } + /* Check veto files. */ + if (IS_VETO_PATH(conn, rel_fname.base_name)) { + DBG_DEBUG("%s contains veto files path component %s\n", + path_in, rel_fname.base_name); + status = NT_STATUS_OBJECT_PATH_NOT_FOUND; + goto fail; + } + rel_fname.base_name = next; } @@ -903,6 +911,8 @@ next: &how); if ((fd == -1) && (errno == ENOENT)) { + const char *orig_base_name = rel_fname.base_name; + status = get_real_filename_at( dirfsp, rel_fname.base_name, @@ -915,6 +925,14 @@ next: goto fail; } + /* Name might have been demangled - check veto files. */ + if (IS_VETO_PATH(conn, rel_fname.base_name)) { + DBG_DEBUG("%s contains veto files path component %s => %s\n", + path_in, orig_base_name, rel_fname.base_name); + status = NT_STATUS_OBJECT_PATH_NOT_FOUND; + goto fail; + } + fd = SMB_VFS_OPENAT( conn, dirfsp, -- Samba Shared Repository