在写入操作期间更改文件所有权

在写入操作期间更改文件所有权

默认情况下,umask 为 0022:

usera@cmp$ touch somefile; ls -l
total 0
-rw-r--r-- 1 usera usera 0 2009-09-22 22:30 somefile

该目录/home/shared/用于存放共享文件,应归组所有rootshared此处创建的文件usern(任何用户)自动归shared组所有。有一个 cron-job 负责每天更改一次(任何移动文件的)拥有用户和拥有组:

usera@cmp$ cat /etc/cron.daily/sharedscript

#!/bin/bash

chown -R root:shared /home/shared/
chmod -R 770 /home/shared/

我正在写非常大文件写入共享目录。我 ( usera) 为所有者用户,shared组为组所有者。在写入操作期间,cron 作业已运行,我仍然没有问题完成写入过程。

你看。我以为会发生这样的事情:

  1. 我正在写入文件。该文件的文件权限和所有权数据如下所示:-rw-r--r-- usera shared
  2. cron 任务开始执行!chown 行已处理完毕,现在该文件归用户rootshared组所有。
  3. 由于拥有者组仅对文件具有读取权限,因此我收到文件写入错误!砰!故事结束。

为什么操作会成功?如果能提供一些参考文档链接来支持该原因,那就太好了(因为我可以用它来研究更多细节)。

答案1

AFAIK,POSIX 1003.1仅要求 fopen 在权限不足时返回 [EACCES] 错误。后续操作(如 fputc)可能会返回 [EBADF] 错误文件描述符错误,但我认为这并不意味着涵盖文件打开时的权限更改。

几年前,我在一家公司工作,我们在那里设置了 AIX 服务器,以便他们使用该属性使日志文件更安全。当服务启动时,root 会触碰 /var/log/service.log,然后将其 chown 为 serveruser:servergroup,su - 启动服务(它将以追加模式打开文件),然后将文件 chown 回 root。因此,服务可以附加到自己的日志文件,但不能删除或覆盖它,因此如果攻击者设法破坏服务,他无法篡改过去的日志条目。

类似的技巧也适用于临时文件:打开文件,然后删除它。目录条目消失了,文件也不可见了,但由于文件句柄仍处于打开状态,因此 inode 仍然存在。关闭文件后,链接计数将变为零,操作系统将回收磁盘空间。

答案2

我认为原因是当 cron 启动时,您仍然拥有该文件的有效句柄,因此您可以正常使用它。换句话说,系统仅在您尝试打开它时检查您的权限,而不是在每次文件操作时检查您的权限。

答案3

正如 Joril 所说,权限在文件打开时是相关的;此后不会再检查它们。

请记住,您可以创建一个具有 400(或 444 或 000)权限的文件以供写入。当然,您需要在目录中创建文件的权限,但您可以对文件拥有写入权限,而其他人(root 除外)都无法修改该文件。

还要注意,可以通过在保存目录上设置 SGID 位来默认设置组:

chmod g+s /home/shared

目录中创建的所有文件都将属于拥有该目录的组,/home/shared直到组发生更改。在 MacOS X 上,系统的行为就像在每个目录上都设置了 SGID 位一样 - 当将文件复制到目录时,组将设置为拥有该目录的组。

相关内容