无法统计文件的符号链接

无法统计文件的符号链接

背景 我正在尝试解决 html 如何无法通过符号链接访问文件的问题。我进行了以下简单的实验,试图了解 apache 如何尝试统计/访问通过 simlink 指向的文件,但我无法理解为什么它不起作用。

作为用户 jzhu,我的主目录中有一个符号链接,指向根目录中名为 other 的目录,其中包含文件 anaconda-ks.cfg,我希望能够在 vi 中统计/读取该文件。但是,当我运行 stat 命令时,我得到以下结果。

[jzhu@localhost ~]$ stat /home/jzhu/other/anaconda-ks.cfg
stat: cannot stat `/home/jzhu/other/anaconda-ks.cfg': Permission denied

这是 /home/jzhu/other 符号链接的 stat 命令,以便您可以进一步了解我的设置方式。

[jzhu@localhost ~]$ stat /home/jzhu/other
  File: `/home/jzhu/other' -> `/root/other/'
  Size: 12          Blocks: 0          IO Block: 4096   symbolic link
Device: fd00h/64768d    Inode: 43313       Links: 1
Access: (0777/lrwxrwxrwx)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2013-11-03 08:52:20.602126433 +0000
Modify: 2013-11-03 08:52:20.187918394 +0000
Change: 2013-11-03 08:52:20.187918394 +0000

查找 lstat 的手册页,我看到以下引用:

这些函数返回有关文件的信息。文件本身不需要任何权限,但在 stat() 和 lstat() 的情况下,需要对通向该文件的路径中的所有目录具有执行(搜索)权限。

据我了解, stat 命令不需要 /root 本身的可执行权限,因为与 lstat 不同,它启动的根目录是它运行的当前目录,这意味着它不会使用“/”的完整路径root/other/”,但将使用路径“/home/jzhu/other/”。我通过 strace 确认了这一点,并给出了以下相关输出

lstat("/home/jzhu/other/anaconda-ks.cfg", 0x7fff14d5a7c0) = -1 EACCES (Permission denied)

因此,为了让我统计这个文件,我需要的只是 /home /home/jzhu 和 /home/jzhu/other 的可执行权限

作为 jzhu,我对 /home 和 /home/jzhu 运行了统计,以确认我具有可执行权限。如下所示

[jzhu@localhost ~]$ stat /home/
  File: `/home/'
  Size: 4096        Blocks: 8          IO Block: 4096   directory
Device: fd00h/64768d    Inode: 2278        Links: 4
Access: (0755/drwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2013-11-03 08:52:13.797724760 +0000
Modify: 2013-11-04 00:03:45.377150769 +0000
Change: 2013-11-04 00:03:45.377150769 +0000
[jzhu@localhost ~]$ stat /home/jzhu
  File: `/home/jzhu'
  Size: 4096        Blocks: 8          IO Block: 4096   directory
Device: fd00h/64768d    Inode: 43317       Links: 3
Access: (0700/drwx------)  Uid: (  500/    jzhu)   Gid: (  500/    jzhu)
Access: 2013-11-04 00:00:30.809916040 +0000
Modify: 2013-11-03 23:49:54.781060426 +0000
Change: 2013-11-03 23:49:54.781060426 +0000

但是我无法将 /home/jzhu/other 统计为 jzhu:

[jzhu@localhost ~]$ stat /home/jzhu/other/
stat: cannot stat `/home/jzhu/other/': Permission denied

也改回来并在目录上运行 stat。我很困惑为什么我无法将目录设置为 jzhu。如下所示,other 对该目录具有读取和可执行权限。

[root@localhost jzhu]# stat /home/jzhu/other/
  File: `/home/jzhu/other/'
  Size: 4096        Blocks: 8          IO Block: 4096   directory
Device: fd00h/64768d    Inode: 32674       Links: 2
Access: (0755/drwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2013-11-03 08:50:36.935318703 +0000
Modify: 2013-11-03 08:50:35.772737444 +0000
Change: 2013-11-03 08:50:35.772737444 +0000
[root@localhost jzhu]# stat /home/jzhu/other/anaconda-ks.cfg 
  File: `/home/jzhu/other/anaconda-ks.cfg'
  Size: 985         Blocks: 8          IO Block: 4096   regular file
Device: fd00h/64768d    Inode: 43297       Links: 1
Access: (0777/-rwxrwxrwx)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2013-11-03 08:50:35.772737444 +0000
Modify: 2013-11-03 08:50:35.781741701 +0000
Change: 2013-11-03 08:54:50.814196796 +0000

所以我想问的两个问题如下。

  1. 为什么我无法 stat /home/jzhu/other/ 即使我对该目录中的 other 具有读取和可执行权限?
  2. 为什么我无法统计 anaconda-ks.cfg 文件?

答案1

您的答案在于您提供的第一个输出:

$ stat /home/jzhu/other
  File: `/home/jzhu/other' -> `/root/other/'

这表明这/home/jzhu/other是一个符号链接/root/other

因此,基本上要访问/home/jzhu/other/您体内的任何内容都需要访问/root/other.这意味着您的用户必须对/root和都具有执行权限/root/other


接下来让我们继续执行这个命令:

$ stat /home/jzhu/other/
stat: cannot stat `/home/jzhu/other/': Permission denied

这个失败而上面的成功的原因是因为尾随/.在任何使用路径的命令上,如果该路径的最后一个组成部分(例如:other)是符号链接,并且路径以尾随 结尾/,则对该路径进行操作的任何系统调用都将尝试取消引用该符号链接,并操作符号链接指向什么而不是符号链接本身。


解决方案:

对此有两种可能的解决方案。

1. 更改权限/root/other

如前所述,为 和 都添加执行/root能力/root/other。您可以使用基本或扩展文件系统属性来执行此操作。

  • 您可以将jzhu用户添加到root组 ( usermod -a -G root jzhu) 并将组执行添加到路径 ( chmod g+x /root; chmod g+x /root/other)。
    这不是一个理想的解决方案,因为它允许您访问仅限于该root组的任何内容。

  • 使用文件系统 ACL。

    setfacl -mu:jzhu:x /root
    setfacl -R -mu:jzhu:x /root/其他
    setfacl -d -R -mu:jzhu:x /root/other
    

    这使得您的特定用户可以获得对其/root/other及其内部任何内容的执行访问权限。
    这仍然不理想,因为这些资源是共享的,它们不应该位于根目录的主目录中。

请注意,在这两个解决方案中,我们仅授予执行 ( x) 位。目录上需要执行位,用户才能访问该目录内的任何内容。但是,您还需要读取 ( r) 位才能列出 ( ls) 目录。这意味着如果没有读取位,您必须确切知道/root/other文件的位置。如果要允许读取,只需将x最后 2 个setfacl命令中的 更改为rx(例如-m u:jzhu:rx)。

2、将资源转移到外面/root/other

这是首选解决方案。您可以删除 处的符号链接/home/jzhu/other并在其位置创建一个目录,或者将它们放在系统上其他位置的共享位置(不知道它是什么,但我不能推荐一个好的位置)。

这是首选解决方案的原因是,如果这些资源在用户之间共享,那么它们不属于特定用户,也不应该位于该用户的主目录中。

相关内容