root
我可以使用以下权限将拥有的 /etc/passwd 文件复制到我的主目录:
-rw-r--r--. 1 root root 2751 Dec 24 21:26 /etc/passwd
我不能这样做:
-rw-------. 1 root root 43591 Dec 27 18:32 /var/log/messages
所以我猜测读取权限others
使复制成为可能?
为了制作硬链接,我在我的主目录中将 file1 创建为 root 用户,并尝试以普通用户的身份创建硬链接。我没能。
-rw-r--r--. 1 root root 0 Dec 27 18:39 file1
是什么阻止了硬链接的创建?
file1所在的目录权限为:
drwx------. 18 student student 4096 Dec 27 18:42 .
我可以将file1重命名为file2,所以我猜,与复制一样,读取权限others
是否会发生这种情况?
最后,我无法将 file2 移动到其他位置。为什么?
编辑:我看过一个解释硬链接权限的问题,但我不明白复制、移动和重命名其他用户的文件和目录需要什么权限。
基本隐喻:目录不是文件夹
要理解的基本概念是目录的概念。这很重要:Unix 没有文件夹,它有目录。
这种区别很重要:文件夹包含东西。目录列出事物。如果您想到文件夹,那么您的脑海中就会出现错误的比喻。想想你在办公楼大厅找到的公司目录:目录不包含办公室,它列出了它们。同样,您的电话簿不包含您的朋友,它列出了他们。另一方面,(物理)文件夹实际上确实包含它所保存的(物理)文件。
文件序列号
在 Unix 中,文件没有名称。文件只有一个文件序列号 (FSN)。FSN 在单个文件系统中是唯一的:同一文件系统上没有两个文件具有相同的 FSN,并且单个文件在其生命周期内只有一个 FSN。但是请注意,不同文件系统上的文件可以具有相同的 FSN。
索引节点
注意:您可能会遇到术语inode。它本质上意味着同样的事情。文件序列号是为 Unix 标准化而发明的名称,因为inode实际上是某些文件系统的实现细节,许多现代文件系统甚至不再有inode……但它们仍然需要有 FSN。此外,许多现代 Unices 允许挂载外部文件系统,这些文件系统显然也没有 inode,因为这纯粹是 Unix 的东西(例如,在 Linux 中挂载 FAT、exFAT 或 NTFS 文件系统)。不过,这些外部文件系统的 Unix 驱动程序仍然需要合成 FSN,因为大部分文件系统 API 都是基于 FSN。
目录
目录是将名称与FSN相关联的特殊文件。在非常早期、非常简单的 Unix 文件系统中,目录实际上只是一个文件(类似于文本文件),看起来像
当然,现代文件系统要复杂得多,但从概念上讲,即使在最复杂的文件系统中,它今天仍然是这样工作的。
三个基本概念
如果你理解了这三个概念,你就理解了你需要知道的关于 Unix 文件系统和 Unix 权限的一切:
想想我们的电话系统是如何工作的:我们只有号码,但我们有目录(电话簿、黄页,或者在更现代的时代,我们手机上的联系人应用程序)将姓名与这些号码相关联。
(硬)链接
名称和FSN之间的关联称为链接,有时称为硬链接(在可能与符号链接/软链接混淆的上下文中)。
三个基本概念的后果
一旦你内化了这三个概念,其他一切都应该到位。
现在应该很明显,没有什么可以阻止您在不同目录甚至同一目录中为同一 FSN 创建多个名称→FSN 链接。换句话说,同一个文件可以有多个名称并存在于多个路径中。
很明显,这很容易导致分层目录结构:由于目录与任何其他文件一样只是文件,因此它们与任何其他文件一样具有 FSN,因此,我可以在目录中列出目录。
了解该
rm
实用程序实际上并没有删除文件不太明显但很重要!它删除了一个链接,换句话说,它删除了目录中的一个条目。rm
实际调用的库函数和内核系统调用unlink
。事实上,您实际上无法在 Unix 中删除文件。如果没有指向它们的链接(换句话说,如果它们的名称为 0)并且文件没有打开的文件句柄,则文件将被自动删除。这也解释了许多 Windows 用户感到困惑的事情:我怎么可能删除在某些应用程序中仍然打开的文件?该应用程序如何不崩溃?好吧,根据我们在上一段中学到的知识,答案很简单:他们没有删除文件,他们只是删除了名称。该文件仍然存在。它仍然可以有其他名称,但即使这是姓氏,该文件也不会被删除,直到应用程序关闭它。事实上,创建一个临时文件,打开它然后立即再次“删除”它是 Unix 应用程序的一种常见设计模式,这些应用程序需要临时存储数据,但又不想让临时文件使文件系统混乱。
将概念应用于权限
如果您了解目录是文件,并且目录将名称与数字相关联,那么权限就会变得清晰:
w
rite 权限,但对文件没有任何访问权限。实际上,重命名实际上与文件本身根本没有任何关系,它只涉及不是文件本身属性的名称。r
对该目录具有读取权限。w
对目录的权限。等等。具体例子
考虑到我们的三个核心概念,我们应该能够回答您的所有问题:
复制
那是对的。想一想“复制文件”实际上是什么意思:您正在创建一个与原始文件具有相同内容的新文件(这也自动意味着您需要为其命名,即在目标目录中创建一个链接条目)文件。
为此,您需要两个权限:
w
目标目录的 rite 权限才能创建指向新创建文件的硬链接。r
原始文件的读取权限才能读取其内容,因为如果您无法读取其内容,那么您如何重新创建它?关联
标准 Unix 权限模型中没有任何内容阻止您创建硬链接。您所需要的只是
w
对该目录的权限。该文件的权限无关紧要,因为您不需要触摸它。我刚刚在我的操作系统(macOS 12.1“Monterey”)上的 APFS 文件系统上对其进行了测试,它工作得很好。
fs.protected_hardlinks
Unix 权限系统中没有任何内容。但是,由于您使用的是 Linux,因此有一个特定于 Linux 的配置选项可能会阻止您这样做:
fs.protected_hardlinks
sysctl。引用官方 sysctl 文档[粗体强调我的]:
看起来您已将其配置为
1
(受限)。检查/proc/sys/fs/protected_hardlinks
确定。改名
对于rename,您只需要
w
对您拥有的目录的 rite 权限。您永远不会触摸文件的内容,因此,它的权限是无关紧要的。移动
这取决于您所说的“移动”究竟是什么意思,以及“不同位置”究竟是什么意思,以及“不能”到底是什么意思。
有两种方法可以解释“移动”:
如果您使用该
mv
实用程序,它实际上可以执行其中任何一项,所以让我们看看它们。#2 只是重命名:您需要
w
对源目录具有 rite 权限才能删除链接,您需要w
对目标目录具有 rite 权限才能创建链接。您在任何时候都不需要触摸文件或访问其内容,因此权限无关紧要。事实上,mv
将rename
为此使用系统调用。mv
将尽可能地尝试做#2。那么,#2 什么时候不可能呢?好吧,请记住 FSN 仅在一个文件系统中是唯一的。此外,文件只存在于文件系统中。
因此,应该清楚#2 只有在源目录和目标目录位于同一文件系统上时才可能。如果它们位于不同的文件系统上,
mv
则将文件复制到目标,然后取消链接原始文件。这意味着,正如我们上面所讨论的,除了对w
源目录的w
rite 访问和对目标目录的 rite 访问之外,它还需要r
对原始文件的 ead 访问。执行权限
注意:到目前为止,我们只查看了
r
ead 和w
rite 权限,而完全忽略了 ex
ecute 权限。… 对于常规文件
对于常规文件, e
x
ecute 权限相当明显:它授予执行文件的权限。(不,真的吗?)但是,请注意“执行”在这里有一个特定的含义:它的意思是“将它传递给内核执行”。特别是,您不需要e
x
ecute 权限即可将文件传递给脚本解释器。因此,如果您有一个脚本文件myscript
,它以一种名为 MyLanguage 的虚构语言调用,看起来像这样:然后,如果您像这样执行它,您确实需要 e
x
ecute 权限:但是,如果您像这样执行它,则不需要e
x
ecute 权限:语言解释器只需要
r
读取权限,就可以读取脚本文件的内容。或者,更准确地说,系统不要求您具有 e
x
ecute 权限,但mylanguage
解释器可以根据需要检查您是否具有 ex
ecute 权限。事实上,有些口译员会这样做,有些则不会。… 用于目录
e
x
ecute 权限对目录意味着什么?这里正在执行什么?对于目录,e
x
ecute 权限被解释为“进入”权限或“查找”权限。换句话说,ex
ecute 权限允许您在给定名称的情况下向目录询问 FSN。您可以将目录视为一个非常简单的程序,它以名称作为参数并返回FSN,那么“e
x
ecute 权限”的想法是有道理的。但这是一个非常艰巨的想法。只需忽略 e ecute的x
代表这一事实,并考虑目录的“查找”或“输入”的含义。x
x
其他种类的特殊文件
目录不是唯一一种特殊文件。还有五个:
符号链接
在这五个中,您最常遇到的是符号链接或符号链接。
符号链接本质上是一个包含路径的文件。在非常早期的非常简单的 Unix 文件系统中,符号链接实际上只是包含路径的文本文件。这或多或少仍然是您今天可以想到的方式。
一旦理解了这一点,就应该清楚,为了创建指向某个地方的符号链接,您需要做的就是创建文件。您不需要访问您放入文件的路径。事实上,这条路甚至不必存在!
例如,假设您完全可以创建文件,您可以轻松地做到
这是一个完全有效的符号链接:
google
是一个完全有效的名称,https://www.google.com/
也是一个完全有效的路径(它的意思是“在当前目录内命名www.google.com
的目录内命名https:
的目录),但当然它并不指向实际存在的文件,尽管你可以做如果你想让它指向某个地方:
复制文件只是读取文件内容、创建新文件并在其中写入数据。您需要读取原始文件的权限,以及对新文件目录的写入权限才能创建它。请参阅执行与读取位。Linux 中的目录权限是如何工作的?
可能是硬链接创建 - 权限
fs.protected_hardlinks
中提到的 sysctl ?. 如果设置,则只有在您拥有该文件或对该文件具有读写权限时才能创建硬链接,此外还有对新链接目录的写入权限。如果未设置,您只需要对新链接目录的写入权限。符号链接有一个类似的旋钮,
fs.protected_hardlinks
. 两者都旨在阻止特权进程遵循可由非特权进程修改的链接的各种漏洞,例如在/tmp
. 旋钮在proc(5)
手册页中进行了描述。就像评论中提到的那样,符号链接/硬链接保护很可能在大多数常见的 Linux 发行版中默认启用。
在单个文件系统中移动文件与重命名文件相同。您需要对旧目录和新目录都具有写入权限,如果移动目录,则需要对目录本身具有写入权限。(跨文件系统“移动”文件需要创建一个新文件、复制内容并删除原始文件。)系统调用的手册页
rename()
至少描述了 EACCES 和 EPERM 错误描述中的一些要求。这里的共同主题是目录的数据是文件名(或“硬”链接),然后指向描述实际文件的 inode 。目录的访问权限控制对该数据的访问,因此更改文件名。因此,创建、删除、移动和重命名文件需要对包含受影响文件名的目录或目录的写入权限。
x
在所有情况下,您还需要在受影响文件/文件名的路径上的所有目录的搜索/访问权限(位)。(见path_resolution(7)
)硬链接链接到文件的存储并且将具有相同的 inode。因此,除非“其他人”具有写入权限,否则您无法进行硬链接。
如果文件是 646 perms,那么您就可以硬链接到该文件。最后,输入硬链接和原始文件的 ls -i 文件名。您将看到它们具有相同的 inode。