允许用户在没有 sudo 的情况下更改特定文件的文件所有权

Eli*_*ias 4 permissions sudo chown

假设我们有这种情况:

-rwxrwx-r- 1 user1 mygroup  0 Sep 12 16:53 testfile
Run Code Online (Sandbox Code Playgroud)

一组开发人员正在开发同一个 VM (Linux)。我需要模拟结帐/签到的概念。如果用户签出一个文件,在他签入之前,任何人都不能写入文件。

我尝试更改文件所有者;每次用户想要签出时,他都会成为文件所有者并防止其他人写入文件,然后通过将文件所有者更改为默认值并将文件权限设置回默认值来签入。这意味着我需要chownchmod但这些命令需要sudo,我不能授予sudo开发人员权限。

我可以给用户的可能性chownchmod只有特定的文件?

Zan*_*nna 6

你可以这样做,尽管我认为可能有一个更实用的解决方案专为这种协作而设计。

无论如何,这是要做的:

创建一个组,将用户添加到该组中,并授予该组对父目录的写权限。然后他们将能够在不使用的情况下chownchmod文件sudo

示范:

sudo addgroup devs
sudo adduser zanna devs
sudo adduser pixie devs
mkdir development
chmod g+w development 
sudo chown root:devs development 
touch development/testfile
cd development
sudo chown root:devs testfile
Run Code Online (Sandbox Code Playgroud)

这样设置就完成了。让我们测试一下:

zanna@xubi:~/development$ chown $USER testfile
$ stat -C "%U %G" testfile
zanna devs
$ chmod 600 testfile
$ stat -c %a testfile
600
$ su pixie
[enter password...]
pixie@xubi:/home/zanna/development$ chown $USER testfile
$ stat -c %U testfile
pixie
Run Code Online (Sandbox Code Playgroud)

等等...但是这只会在所有如果人们检查权限或尝试写入文件,它们开始之前的工作chownchmod,这可能是不直观...如果他们有写权限的父目录,他们将始终能够强制写入文件,尽管他们应该收到一些警告,具体取决于他们使用的编辑器。


mur*_*uru 6

您必须编写一个脚本来检查条件,然后让您的用户单独sudo访问脚本。就像是:

#! /bin/bash
set -e
die()
{
    printf "%s\n" "$@"
    exit 1
}

if [[ $EUID != 0 ]]
then
    die "This script must be run with sudo."
fi

DEFAULT_USER=nobody
SOURCE_DIR=/some/dir

cd "$SOURCE_DIR"

# Get path of file relative to the source directory
# Then we can check if it is actually in the directory.
FILE=$(realpath -e --relative-base="$SOURCE_DIR" "${1?}")    
if [[ $FILE == /* ]]
then
    die "$1 is outside $SOURCE_DIR."
fi

FILE_OWNER=$(stat -c %U "$FILE")

case $FILE_OWNER in
    $DEFAULT_USER)
        # checkout
        echo "Checking out $FILE..."
        chown "$SUDO_USER" "$FILE"
        ;;
    $SUDO_USER)
        # checkin
        echo "Checking in $FILE..."
        chown nobody "$FILE"
        ;;
    *)
        die "Sorry, this file is checked out by $FILE_OWNER."
        ;;
esac
Run Code Online (Sandbox Code Playgroud)

将其另存为,例如/usr/local/bin/check,添加以下sudoers规则:

%dev ALL = (root) /usr/local/bin/check
Run Code Online (Sandbox Code Playgroud)

那是假设:

  • 开发人员都在dev组中(如果不是,请相应地使用用户名或组)。
  • 文件在/some/dir. 相应地修改$SOURCE_DIR
  • 默认用户是nobody,未选中的文件归默认用户所有。
  • 除了 root 之外,没有人对源目录有写权限。

然后开发人员可以这样做:

sudo check some/file
Run Code Online (Sandbox Code Playgroud)

签出/some/dir/some/file,然后再次运行以签入。