The branch, master has been updated via e06f86bbd93 smbd: use fsp->conn->session_info for the initial delete-on-close token via aa1f09cda0a selftest: add a test that verifies unlink works when "force user" is set via f3f8fdfbf10 selftest: add force_user_error_inject share in maptoguest env via c44dad3ac2e vfs_error_inject: add unlinkat hook from 17a8fa6d242 rpc_server: Add CLOEXEC to the listening sockets
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit e06f86bbd93d024c70016e1adcf833db85742aca Author: Ralph Boehme <s...@samba.org> Date: Sat Jan 23 18:36:23 2021 +0100 smbd: use fsp->conn->session_info for the initial delete-on-close token There's a correctly set up session_info at fsp->conn->session_info, we can just use that. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14617 Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> Autobuild-User(master): Jeremy Allison <j...@samba.org> Autobuild-Date(master): Tue Jan 26 04:04:14 UTC 2021 on sn-devel-184 commit aa1f09cda0a097617e34dd0a8b1b0acc7a37bca8 Author: Ralph Boehme <s...@samba.org> Date: Mon Jan 25 11:48:32 2021 +0100 selftest: add a test that verifies unlink works when "force user" is set BUG: https://bugzilla.samba.org/show_bug.cgi?id=14617 Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit f3f8fdfbf10f690bc8d972a13d6f74f1fb0fb375 Author: Ralph Boehme <s...@samba.org> Date: Mon Jan 25 11:47:45 2021 +0100 selftest: add force_user_error_inject share in maptoguest env BUG: https://bugzilla.samba.org/show_bug.cgi?id=14617 Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit c44dad3ac2eb36fc5eb5a9f80a9ef97183be26ef Author: Ralph Boehme <s...@samba.org> Date: Mon Jan 25 11:46:30 2021 +0100 vfs_error_inject: add unlinkat hook Note that a failure is only injected if the owner of the parent directory is not the same as the current user. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14617 Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> ----------------------------------------------------------------------- Summary of changes: selftest/target/Samba3.pm | 10 ++++++ source3/modules/vfs_error_inject.c | 44 ++++++++++++++++++++++++++ source3/script/tests/test_force_user_unlink.sh | 40 +++++++++++++++++++++++ source3/selftest/tests.py | 5 +++ source3/smbd/close.c | 25 +++------------ 5 files changed, 103 insertions(+), 21 deletions(-) create mode 100755 source3/script/tests/test_force_user_unlink.sh Changeset truncated at 500 lines: diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm index b3f0bca0110..b0910433940 100755 --- a/selftest/target/Samba3.pm +++ b/selftest/target/Samba3.pm @@ -1766,12 +1766,22 @@ $ret->{USERNAME} = KTEST\\Administrator sub setup_maptoguest { my ($self, $path) = @_; + my $prefix_abs = abs_path($path); + my $libdir="$prefix_abs/lib"; + my $share_dir="$prefix_abs/share"; + my $errorinjectconf="$libdir/error_inject.conf"; print "PROVISIONING maptoguest..."; my $options = " map to guest = bad user ntlm auth = yes + +[force_user_error_inject] + path = $share_dir + vfs objects = acl_xattr fake_acls xattr_tdb error_inject + force user = user1 + include = $errorinjectconf "; my $vars = $self->provision( diff --git a/source3/modules/vfs_error_inject.c b/source3/modules/vfs_error_inject.c index 2230b8a2991..31257cc1d00 100644 --- a/source3/modules/vfs_error_inject.c +++ b/source3/modules/vfs_error_inject.c @@ -30,6 +30,7 @@ struct unix_error_map { { "ESTALE", ESTALE }, { "EBADF", EBADF }, { "EINTR", EINTR }, + { "EACCES", EACCES }, }; static int find_unix_error_from_string(const char *err_str) @@ -123,10 +124,53 @@ static int vfs_error_inject_openat(struct vfs_handle_struct *handle, return SMB_VFS_NEXT_OPENAT(handle, dirfsp, smb_fname, fsp, flags, mode); } +static int vfs_error_inject_unlinkat(struct vfs_handle_struct *handle, + struct files_struct *dirfsp, + const struct smb_filename *smb_fname, + int flags) +{ + struct smb_filename *full_fname = NULL; + struct smb_filename *parent_fname = NULL; + int error = inject_unix_error("unlinkat", handle); + int ret; + bool ok; + + if (error == 0) { + return SMB_VFS_NEXT_UNLINKAT(handle, dirfsp, smb_fname, flags); + } + + full_fname = full_path_from_dirfsp_atname(talloc_tos(), + dirfsp, + smb_fname); + if (full_fname == NULL) { + return -1; + } + + ok = parent_smb_fname(full_fname, full_fname, &parent_fname, NULL); + if (!ok) { + TALLOC_FREE(full_fname); + return -1; + } + + ret = SMB_VFS_STAT(handle->conn, parent_fname); + if (ret != 0) { + TALLOC_FREE(full_fname); + return -1; + } + + if (parent_fname->st.st_ex_uid == get_current_uid(dirfsp->conn)) { + return SMB_VFS_NEXT_UNLINKAT(handle, dirfsp, smb_fname, flags); + } + + errno = error; + return -1; +} + static struct vfs_fn_pointers vfs_error_inject_fns = { .chdir_fn = vfs_error_inject_chdir, .pwrite_fn = vfs_error_inject_pwrite, .openat_fn = vfs_error_inject_openat, + .unlinkat_fn = vfs_error_inject_unlinkat, }; static_decl_vfs; diff --git a/source3/script/tests/test_force_user_unlink.sh b/source3/script/tests/test_force_user_unlink.sh new file mode 100755 index 00000000000..86076535497 --- /dev/null +++ b/source3/script/tests/test_force_user_unlink.sh @@ -0,0 +1,40 @@ +#!/bin/sh +# +# Test unlink on share with "force user" +# +# Copyright (C) 2021 Ralph Boehme + +incdir=$(dirname $0)/../../../testprogs/blackbox +. $incdir/subunit.sh +. $incdir/common_test_fns.inc + +smbclient="$BINDIR/smbclient" +error_inject_conf=$(dirname ${SMB_CONF_PATH})/error_inject.conf +failed=0 + +test_forced_user_can_delete() { + out=$($smbclient -U $DOMAIN/$USERNAME%$PASSWORD //$SERVER_IP/force_user_error_inject -c "rm dir/file") + if [ $? -ne 0 ] ; then + echo $out + return 1 + fi + tmp=$(echo $out | grep NT_STATUS_ ) + if [ $? -eq 0 ] ; then + return 1 + fi + return 0 +} + +echo "error_inject:unlinkat = EACCES" > ${error_inject_conf} + +$smbclient -U $DOMAIN/$USERNAME%$PASSWORD //$SERVER_IP/force_user_error_inject -c "mkdir dir" || failed=`expr $failed + 1` +$smbclient -U $DOMAIN/$USERNAME%$PASSWORD //$SERVER_IP/force_user_error_inject -c "put WHATSNEW.txt dir/file" || failed=`expr $failed + 1` + +testit "test_forced_user_can_delete" test_forced_user_can_delete || failed=`expr $failed + 1` + +rm ${error_inject_conf} + +# Clean up after ourselves. +$smbclient -U $DOMAIN/$USERNAME%$PASSWORD //$SERVER_IP/force_user_error_inject -c "del dir/file; rmdir dir" + +testok $0 $failed diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py index 0250eb11684..6f65bf5ef9d 100755 --- a/source3/selftest/tests.py +++ b/source3/selftest/tests.py @@ -1189,6 +1189,11 @@ plantestsuite( "bin/samba-tool", '$DNSNAME']) +plantestsuite("samba3.blackbox.force-user-unlink", + "maptoguest:local", + [os.path.join(samba3srcdir, + "script/tests/test_force_user_unlink.sh")]) + def planclusteredmembertestsuite(tname, prefix): '''Define a clustered test for the clusteredmember environment''' diff --git a/source3/smbd/close.c b/source3/smbd/close.c index 97d13473082..f05619d1886 100644 --- a/source3/smbd/close.c +++ b/source3/smbd/close.c @@ -342,21 +342,13 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, if (fsp->fsp_flags.initial_delete_on_close && !is_delete_on_close_set(lck, fsp->name_hash)) { - struct auth_session_info *session_info = NULL; - /* Initial delete on close was set and no one else * wrote a real delete on close. */ - status = smbXsrv_session_info_lookup(conn->sconn->client, - fsp->vuid, - &session_info); - if (!NT_STATUS_IS_OK(status)) { - return NT_STATUS_INTERNAL_ERROR; - } fsp->fsp_flags.delete_on_close = true; set_delete_on_close_lck(fsp, lck, - session_info->security_token, - session_info->unix_token); + fsp->conn->session_info->security_token, + fsp->conn->session_info->unix_token); } delete_file = is_delete_on_close_set(lck, fsp->name_hash) && @@ -1175,24 +1167,15 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp, } if (fsp->fsp_flags.initial_delete_on_close) { - struct auth_session_info *session_info = NULL; - /* Initial delete on close was set - for * directories we don't care if anyone else * wrote a real delete on close. */ - status = smbXsrv_session_info_lookup(fsp->conn->sconn->client, - fsp->vuid, - &session_info); - if (!NT_STATUS_IS_OK(status)) { - return NT_STATUS_INTERNAL_ERROR; - } - send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx, fsp->fsp_name->base_name); set_delete_on_close_lck(fsp, lck, - session_info->security_token, - session_info->unix_token); + fsp->conn->session_info->security_token, + fsp->conn->session_info->unix_token); fsp->fsp_flags.delete_on_close = true; } -- Samba Shared Repository