我的目录中其他用户的非空子目录是否可以安全删除?

我的目录中其他用户的非空子目录是否可以安全删除?

在以下情况下ls -alh

total 0
drwxrwx--- 1 user http  20 Nov 30 08:08 .
drwxrws--- 1 user http 310 Nov 30 08:07 ..
drwx------ 1 http http  10 Nov 30 08:08 empty-subdir
drwx------ 1 http http  12 Nov 30 08:08 non-empty-subdir

其中存在两个子目录(不属于我),我将其列出为:

sudo ls empty-subdir -alh
total 0
drwx------ 1 http http 10 Nov 30 08:08 .
drwxrwx--- 1 user http 20 Nov 30 08:08 ..

sudo ls non-empty-subdir -alh
total 0
drwx------ 1 http http 12 Nov 30 08:08 .
drwxrwx--- 1 user http 20 Nov 30 08:08 ..
drwx------ 1 http http  0 Nov 30 08:08 subdir

两个子目录之间的区别在于非空子目录non-empty-subdir包含一个文件夹。

我的问题是,尝试rm -rf删除子目录是否是故意的,我得到的结果是:

$ rm empty-subdir -rf
$ rm non-empty-subdir -rf
rm: cannot remove 'non-empty-subdir': Permission denied
$ ls -alh
total 0
drwxrwx---+ 1 user http  10 Nov 30 08:14 .
drwxrws---+ 1 user http 310 Nov 30 08:07 ..
drwx------+ 1 http http  12 Nov 30 08:08 non-empty-subdir

似乎允许对目录具有写权限的用户删除文件的条目或其他用户的空子目录,但不允许删除非空子目录。

这个问题的理想答案将提供以下信息:

  • 确认所概述的行为可以在其他机器上重现(而不仅仅是我搞砸的盒子的怪癖)
  • 解释该行为的基本原理(例如是否有用例?)
  • 系统(BSD、Linux...)之间是否存在差异的概述

更新:关于 Ipor Sircer 的评论,我确实重新测试了该场景,没有任何 ACL 功能,结果是一样的。因此,我修改了问题,+从列表中删除 es,以免产生该行为可能与 ACL 相关的想法。

答案1

rmdir()仅当目录为空时才可以删除该目录(通过系统调用)。

rm -r dir删除目录及其中的所有文件,从目录树的叶子开始,一直向上到根 ( dir)。

要删除文件(对于rmdir()目录和unlink()其他类型的文件或*at()变体),重要的不是文件本身的权限,而是要从中删除文件的目录的权限(注意t权限中的位,例如对于/tmp,增加了进一步的复杂性)。

首先,您并没有真正删除文件,您正在取消它与目录的链接(当它是您要删除的最后一个链接时,该文件最终会被删除),也就是说,您正在修改目录,因此您需要修改对该目录的(写)权限。

您无法删除的原因non-empty-dir是您无法subdir先取消链接,因为您无权修改non-empty-dir.您有权取消non-empty-dir与主目录的链接,因为您对该主目录具有写入/修改权限,只是您无法删除不为空的目录。

在您的情况下,正如 @PeterCordes 在注释中指出的那样,rmdir()系统调用失败并显示ENOTEMPTY(Directory notempty) 错误代码,但因为您没有目录的权限,rm甚至无法找出subdir需要取消链接的文件和目录(包括 )才能清空它(并不是说它知道就可以取消链接,因为它没有写权限)。

您还可能遇到以下情况rm 可以如果目录能够找出其中包含哪些文件,则删除一个目录,就像只写目录的情况一样:

$ mkdir dir
$ touch dir/file
$ chmod a=,u=wx dir
$ ls -ld dir
d-wx------ 2 me me 4096 Nov 30 19:43 dir/
$ rm -rf dir
rm: cannot remove 'dir': Permission denied

尽管如此,我还是能够删除它,因为我碰巧知道它只包含一个file文件:

$ rm dir/file
$ rmdir dir
$

另请注意,对于现代的 Unices,您可以重命名它non-empty-dir,但在 Linux 或 FreeBSD(但不是 Solaris)等一些系统上,不是将其移动到不同的目录,即使您也对该目录具有写权限,如(我认为对于Linux,正如建议的那样相关代码的注释)这样做将涉及修改non-empty-dir..其中的条目将指向不同的目录)。

有人可能会说,删除 yourempty-dir还涉及删除其中的...条目,因此要修改它,但系统仍然允许您这样做。

答案2

忽略 ACL 带来的潜在变化,我可以确认我的系统(没有 ACL)的这种行为。

观察到的行为是两个原则的逻辑结果:

1) 目录的权限决定了谁可以更改目录,即删除目录中的条目。该目录中条目的权限在此不起作用。

2)删除文件可能需要删除和清理相关信息,即索引节点、块分配列表等。这就是为什么在没有清理它包含的所有文件的情况下不能删除非空子目录的原因,因为否则它包含的文件将变得无法访问,但相关信息不会被清除。

因此您可以删除empty-subdir,因为您有权写入它所在的目录。您无法删除non-empty-subdir,因为您无权首先清理该子目录中包含的文件。

这确实没有任何理由或用例。人们可以在内核中构建子目录的递归清理,但是原始的 Unix 使一切变得简单,并且当可以使用用户空间实用程序来实现递归清理时,它会变得太复杂。

我无法提供不同风格之间的全面概述,但这是原始 Unix 中的行为,我希望它在每个 Unix 风格中都是相同的,如果有 Unix 风格,我会感到惊讶表现不同。

答案3

我尝试重现您所描述的内容,然后运行strace rm -rf ./nonempty。揭示的内容如下:

unlinkat(4, "subdir", AT_REMOVEDIR)     = -1 EACCES (Permission denied)

并根据unlinkat手册(在Linux上与相同unlink(2),重点是我添加的):

EACCES 进程的有效 UID 不允许对包含路径名的目录进行写访问,或者 路径名中的目录之一不允许搜索权限。 (另请参见 path_resolution(7)。)

由于父目录nonempty不授予userx(搜索)权限,因此根据无法删除EACCES的描述,这是有意义的。subdir

相关内容