chown 无法取消引用,权限被拒绝

chown 无法取消引用,权限被拒绝

鉴于,

touch /tmp/abc
ln -vs abc /tmp/def

$ ls -l /tmp/???
-rw-rw-r-- 1 ubuntu ubuntu 0 Apr 10 22:10 /tmp/abc
lrwxrwxrwx 1 ubuntu ubuntu 3 Apr 10 22:10 /tmp/def -> abc

为什么我得到:

$ sudo chown syslog: /tmp/def
chown: cannot dereference '/tmp/def': Permission denied

$ sudo chown --dereference syslog: /tmp/def
chown: cannot dereference '/tmp/def': Permission denied

参考:
庄(1):

--dereference

    影响每个符号链接的引用(这是默认值),而不是符号链接本身

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 20.04.6 LTS
Release:        20.04
Codename:       focal

答案1

这个答案假设这是适当的:

# sysctl fs.protected_symlinks 
fs.protected_symlinks = 1

root 用户(以下安全功能特别旨在影响)与任何其他用户一样,受到 sysctlfs.protected_symlinks中描述的影响proc(5)

/proc/sys/fs/protected_symlinks(从 Linux 3.6 开始)

当该文件中的值为 0 时,对后面的符号链接没有限制(即,这是 Linux 3.6 之前的历史行为)。当该文件中的值为 1 时,仅在以下情况下才会遵循符号链接:

• 链接后面的进程的文件系统UID 与符号链接的所有者(UID) 匹配(如凭证(7) 中所述,进程的文件系统UID 通常与其有效UID 相同);

• 链接不在全局可写的粘性目录中;或者

• 符号链接及其父目录具有相同的所有者 (UID)

由于上述限制而无法遵循符号链接的系统调用会在 errno 中返回错误 EACCES。

这里:

  • root != ubuntu : 失败
  • /tmp是一个粘性的世界可写目录:失败
  • /tmpdef 的所有者 (ubuntu) 与的所有者 (root)不同:失败

因此EACCESS=权限被拒绝

这里还有另外两种可行的情况:

  • 防止第一个条件失败

    sudo chown --no-dereference root: /tmp/def # this must be root, not syslog
    

    现在符号链接由 root 拥有,第一个条件不会失败,允许运行:

     sudo chown syslog: /tmp/def
    

    才能成功影响/tmp/abc.

    如果有这样的意图,def可以改回其以前的所有者或也可以syslog

    sudo chown --no-dereference ubuntu: /tmp/def
    

    或者

    sudo chown --no-dereference syslog: /tmp/def
    
  • 防止第二个条件失败

    在非粘性目录中进行相同的实验(即使它是全局可写的):

    sudo mkdir -m 777 /tmp/notsticky
    sudo mv /tmp/abc /tmp/def /tmp/notsticky/.
    

    现在允许运行:

    sudo chown syslog: /tmp/notsticky/def
    

    如果有这样的意图,它们可以被移回:

    sudo mv /tmp/notsticky/abc /tmp/notsticky/def /tmp/
    sudo rmdir /tmp/notsticky
    

此外,如评论中建议,可以通过从原始用户进行查找来再次防止第一个条件失败ubuntu,因为它已经是符号链接的所有者。例如使用:

realpath -z /tmp/def | xargs -0 sudo chown syslog:

\n或者如果目标文件名末尾没有特殊字符,例如换行符 (LF / )(这将被 shell 解释器删除),就像 OP 的情况一样,只需:

sudo chown syslog: "$(realpath /tmp/def)"

相关内容