【问题标题】:Why can I 'touch' a write-protected file?为什么我可以“触摸”一个写保护的文件?
【发布时间】:2010-11-02 16:51:53
【问题描述】:

为什么可以touch 写保护文件?

下面不应该报错吗?

$ touch test.txt
$ chmod a-w test.txt
$ ls -l test.txt
-r--r--r-- 1 name group 0 Jun 13 09:14 test.txt
$ touch test.txt && echo OK
OK
$ ls -l test.txt
-r--r--r-- 1 name group 0 Jun 13 09:15 test.txt

touch 是否更改权限、触摸文件并更改权限?为什么要这么做?

鉴于这种行为,如果我真的想保护文件,以便我(我的用户)将来永远不会(无意)更改、删除或更改其时间戳,我该怎么做?

(抱歉,不是严格与编程相关,但有一点点,可能很多程序员都会感兴趣。)

【问题讨论】:

  • 在我看来,这听起来像是一个更适合 serverfault.com 的问题。
  • 这样做时时间戳会改变吗?
  • 是的。添加了上面更改的时间戳。

标签: linux permissions touch


【解决方案1】:

通俗地说,使用 touch 命令将更新或创建文件,而无需编辑/修改其内容。因为该命令不会(也不能)从文件中写入或擦除任何内容,所以它可以用于写保护文件。有关更多信息,请参阅有关 touch 命令的 wiki:http://en.wikipedia.org/wiki/Touch_(Unix)

【讨论】:

    【解决方案2】:

    文件包含的目录的执行权限决定了删除或修改与文件关联的目录中条目的 inode 信息的能力。

    正如下面的评论所表明的那样,我掩盖了技术原因,而是提供了为什么行为可能不符合预期的原因。由于您可以在目录中执行,因此您可以做很多事情来修改文件,我将保留它。

    如果您想阻止除 root 以外的任何人修改文件,最好的方法是在文件上使用 chattr +i 文件名。如果不运行 chattr -i ,即使 root 也无法对其执行任何操作。这适用于 Linux 所以 YMMV。

    【讨论】:

    • 如果该用户对该目录具有执行权限,该用户是否可以触摸其他人拥有的只读文件?
    • 您可以删除您有执行权限的目录中无法读取的文件。可以进行很多实验和变体,但事实仍然是文件的权限并不是最终的结果,所有这些都表明您有权执行的操作。
    • 需要对目录执行权限才能在目录中指定文件名,但仅此一项不允许“触摸”。对于“触摸”,您必须是文件的所有者(如此处),或者具有写入权限,或者是 root。
    • -1 错误信息。在目录上执行控制遍历/cd/search,而不是删除/修改文件 inode 的权限。这是由目录的写入权限决定的。 OP 从不费心指定他的目录权限。这种行为意味着该目录对他有 +w。
    【解决方案3】:

    如果您拥有文件,则可以更新修改时间,无论写入权限如何。 (与目录的任何权限无关。)

    从 POSIX.1-2008:

    只有有效用户 ID 等于文件的用户 ID、或对文件具有写访问权限或具有适当权限的进程才能使用带有空指针的 futimens()utimensat() 作为时间参数或将两个 tv_nsec 字段设置为特殊值 UTIME_NOW。只有有效用户 ID 等于文件的用户 ID 或具有适当权限的进程才能使用 futimens()utimensat() 和一个非空时间参数,该参数没有将两个 tv_nsec 字段都设置为 UTIME_NOW并且没有将两个 tv_nsec 字段都设置为 UTIME_OMIT。如果tv_nsec 两个字段都设置为UTIME_OMIT,则不会对该文件执行所有权或权限检查,但仍可能检测到其他错误情况(包括与路径前缀相关的[EACCES]错误)。

    【讨论】:

      【解决方案4】:

      以下是 strace "touch test.txt" 的相关输出

      open("test.txt", O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK|O_LARGEFILE, 0666) = -1 EACCES (Permission denied)
      futimesat(AT_FDCWD, "test.txt", NULL)   = 0
      

      它确实在有关 EACCES 的 open(2) 系统调用上收到“权限被拒绝错误”。请参阅 utimes(2) 手册页中的相关部分。

      但是,它确实成功地使用futimesat(2) 系统调用更新了时间戳。

      正如其他人所指出的,目录权限似乎拥有更新访问/制作时间戳的权利。

      但是,您可以使用以下方法将文件的属性更改为不可变:

      chattr +i test.txt
      

      注意:只有 root 可以做到这一点,这是一种非常苛刻的方式来禁用对文件的访问。但在极端情况下,它可能很有用。此外,这是一个 ext2/3/4 功能,据我所知,其他文件系统不可用。

      【讨论】:

      • 你打败了我汤姆,“与编程无关”我的帽子 :) OP 可能想检查手册页中的 EACCES 段落中的 utimes(2) 或 futimesat(2),更不用说触摸的源泉(1)。
      • 感谢 Martin,我在答案中添加了 utimes(2) 链接。
      【解决方案5】:

      来自touch (coreutils) 文档:

      如果同时更改访问权限和 修改时间到当前 时间,`touch' 可以改变 用户文件的时间戳 运行它不拥有但有写 许可。否则,用户 必须拥有这些文件。

      【讨论】:

      • 这似乎只涵盖所有权 - 问题是关于写访问,所以我相信@objlass 是正确的 - 时间戳保存在目录条目中,而不是文件中,所以对目录的写访问就足够了改变它们。
      • 这可能会更清楚一点。是说如果您可以touch 具有 w-perms 所有权的文件吗?
      • 是的,如果用户在目录上有 +W 的话,可以使用其中任何一个
      猜你喜欢
      • 1970-01-01
      • 2021-04-08
      • 2013-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-08
      • 2014-09-05
      相关资源
      最近更新 更多