文件权限如何应用于符号链接?

n0p*_*0pe 113 linux unix symbolic-link permissions file-permissions

假设你有这个结构:

+ directory
-- file1
-- file2
-- file3 -> /tmp/file3
Run Code Online (Sandbox Code Playgroud)

file3是指向系统上其他file3地方的另一个链接。

现在假设我chmod 777是目录和其中的所有内容。我的file3in是否/tmp收到这些权限?另外,假设我们有相同的情况,但情况相反。

/tmp/file3 -> /directory/file3
Run Code Online (Sandbox Code Playgroud)

如果我对链接到的文件应用权限,这对链接有何影响?

pet*_*eth 111

这取决于您的调用方式chmod和运行的平台。

例如,在 Linux 系统上,这样man chmod说:

chmod 从不改变符号链接的权限;该chmod 系统调用不能改变他们的权限。这不是问题,因为符号链接的权限从未使用过。但是,对于命令行上列出的每个符号链接,都会chmod更改指向文件的权限。相反, chmod忽略在递归目录遍历期间遇到的符号链接。

但是,在 Mac 上, chmod 可用于使用以下选项修改符号链接的权限(来自man chmod):

-h 如果文件是符号链接,则更改链接本身的模式,而不是链接指向的文件。

作为示例,让我们假设您在本答案的其余部分使用 Linux 机器。

如果在第一种情况下您运行chmod -R 777 directory递归更改权限,则链接目标不会受到影响,但如果您这样做chmod 777 directory/*,则会受到影响。

如果您直接更改链接目标的权限,这些权限将继续存在(因为正如手册页和baraboom所说,实际的链接权限不会用于任何事情)。


用于说明的测试日志:

$ mkdir dir && touch dir/file{1,2} /tmp/file3 && ln -s {/tmp,dir}/file3
$ ls -l dir/* /tmp/file3
-rw-r--r-- 1 user group  0 2011-06-27 22:02 /tmp/file3
-rw-r--r-- 1 user group  0 2011-06-27 22:02 dir/file1
-rw-r--r-- 1 user group  0 2011-06-27 22:02 dir/file2
lrwxrwxrwx 1 user group 10 2011-06-27 22:02 dir/file3 -> /tmp/file3

$ chmod -R 777 dir && ls -l dir/* /tmp/file3
-rw-r--r-- 1 user group  0 2011-06-27 22:02 /tmp/file3
-rwxrwxrwx 1 user group  0 2011-06-27 22:02 dir/file1
-rwxrwxrwx 1 user group  0 2011-06-27 22:02 dir/file2
lrwxrwxrwx 1 user group 10 2011-06-27 22:02 dir/file3 -> /tmp/file3

$ chmod 700 dir/* && ls -l dir/* /tmp/file3
-rwx------ 1 user group  0 2011-06-27 22:02 /tmp/file3
-rwx------ 1 user group  0 2011-06-27 22:02 dir/file1
-rwx------ 1 user group  0 2011-06-27 22:02 dir/file2
lrwxrwxrwx 1 user group 10 2011-06-27 22:02 dir/file3 -> /tmp/file3
Run Code Online (Sandbox Code Playgroud)

  • 这对我来说也是一个惊喜。下一个问题:谁拥有符号链接的权限*意思*? (4认同)
  • @EdwardFalk 符号链接权限不是非限制性的,因为所有内容都需要能够遍历它才能从链接文件中获取权限。 (3认同)

ast*_*lue 11

baraboom 和 peth 的答案都是正确的:符号链接本身的权限位无关紧要(macOS 除外;见下文),并且更改符号链接的权限 - 通过chmod命令行工具或chmod()系统调用 - 将简单地充当如果它是针对符号链接的目标执行的。

引用SUSv4/POSIX.1-2008 对 symlink() 系统调用的描述

创建的符号链接的文件模式位的值是未指定的。POSIX.1-2008 指定的所有接口都应该表现为符号链接的内容总是可以读取的,除了在stat结构的st_mode字段中返回的文件模式位的是未指定的。

在这里,“未指定”为每个实现留下了解释空间。规格:

  • 在 Linux 上(使用 ext4fs 测试),无论创建符号链接时的 umask 是什么,都stat()返回st_mode=0777ls -l因此总是显示lrwxrwxrwx符号链接。
  • 在 macOS (HFS) 和 FreeBSD(UFS 和 ZFS)上,符号链接确实有自己的权限:chmod -h上面提到的命令可以更改此链接权限(内部使用非 POSIXlchown()系统调用来实现此目的),并且stat()系统调用为 返回此值st_mode

Linux 和 FreeBSD 上的符号链接始终可以按照 POSIX 的规定进行跟踪。特别是在 FreeBSD 上,这意味着符号链接的文件模式对访问控制完全没有影响。

另一方面,macOS 稍微打破了 POSIX。尽管符号链接可以不管其读取权限而被跟踪,但如果用户没有读取权限,则会readlink()失败EACCES(权限被拒绝):

$ sudo ln -shf target symlink
$ sudo chmod -h 444 symlink
$ ls -l symlink
lr--r--r--  1 root  staff  1 Mar 14 13:05 symlink -> target
$ sudo chmod -h 000 symlink
$ ls -l symlink

ls: symlink: Permission denied
l---------  1 root  staff  1 Mar 14 13:05 symlink
$ echo kthxbye > target
$ cat symlink
kthxbye
Run Code Online (Sandbox Code Playgroud)

(请注意,-> target第二个ls -l命令的输出中缺少该部分,即使用户没有读取权限,该部分cat symlink仍然成功并打印了target文件的内容symlink。)

NetBSD 显然提供了一个特殊的挂载选项symperm,如果设置,会导致符号链接读取/执行权限来控制readlink()和链接遍历。