【问题标题】:How do I create a file in UNIX /tmp directory so that all users can read and write to it?如何在 UNIX /tmp 目录中创建一个文件,以便所有用户都可以读取和写入它?
【发布时间】:2010-09-17 22:27:28
【问题描述】:

我正在尝试在/tmp 目录中创建一个文件(在 Linux UBUNTU 7.10 上工作),该文件对任何用户都具有读/写/执行权限。

所以我正在使用

open(fileName,O_CREAT|O_RDWR,0777)

user1 帐户中创建文件(来自C 程序)的函数,我希望user2 能够写入特定文件。

但是,当我检查 /tmp 目录时,使用

ls -l

我发现我没有user2写访问权限(考虑到user1 创建它的事实,我对user1 有写访问权限,但是user2,被视为“其他人”的人没有任何访问权限)。

我尝试在open 函数中使用模式0766(以及76 的这种组合模式),这样我就可以获得user2 的写访问权限,但我仍然没有'没有所需的访问权限。

【问题讨论】:

    标签: c unix security


    【解决方案1】:

    你必须将你的 umask 设置为 000。umask 上的位会从你选择的权限中删除,默认的 umask 通常是 022 或 002。

    请注意,默认 ACL 和 SELinux 标签等内容也可能会影响文件的可读性和可写性。使用 getfacl 查看 ACL,使用 ls -Z 查看 SELinux 标签;对于 SELinux,您还必须知道哪些策略处于活动状态以及它们有什么影响。 ACL 的存在也可以在 ls -l 上看到为权限后的 + 字符。

    【讨论】:

    • 您可能希望使用 chmod(2) 对文件设置显式权限,而不是更改 umask。
    • 使用[f]chmod() 是正确的答案。设置进程范围的umask 不是线程安全的。
    【解决方案2】:

    正如 CesarB 所说,Unix 会取消设置进程的 umask 中设置的位,因此要获得完全访问权限,您必须暂时取消设置 umask。

     mode_t oldmask = umask(0);
     fd = open(...);
     oldmask = umask(oldmask);
     assert(oldmask == 0);
    

    (好的;您不必进行断言;它不会触发。)

    正如 Pistos 所说,在 /tmp 中创建文件是一个令人担忧的过程。如果您认为该文件不应该存在,请添加 O_EXCL 以防止以下符号链接到意外位置。

    最后一点 - 为什么要使文件可执行?我认为您应该只针对 666 权限,而不是 777 或 766。您当然不应该执行其他人可以随时更改的程序(因此所有者不应该对其他人可以写入的文件具有执行权限),并且该小组的成员可能也不会真正欣赏这种慷慨。如果执行该文件,其他人也许会得到他们应得的——但这仍然不是很好。

    【讨论】:

      【解决方案3】:

      FWIW,在 /tmp(或 /var/tmp 等)中使用固定名称创建任何内容都会带来安全风险。可以在 /tmp 中设置一个指向任何东西的同名符号链接,如果运行您的程序的用户有权这样做,您的程序将销毁目标文件。

      在 /tmp 中以编程方式创建的内容应随机命名,但最好不要使用该目录,除非您的整个系统是安全的(没有潜在的恶意用户)。

      【讨论】:

      • 这是我正在为大学的安全编程课程做的任务的一部分,所以我正在研究安全问题:)
      【解决方案4】:

      您唯一能做的就是在创建文件后对文件进行 chmod:

      #include <sys/types.h>
      #include <sys/stat.h>
      #include <fcntl.h>
      
      int main() {
        creat("/tmp/foo", 0);
        chmod("/tmp/foo", 0666);
      }
      

      无论如何,拥有这种文件是不安全的。

      【讨论】:

      • 这不是你能做的“唯一”事情。不过,这是一种有效的技术。
      • 此外,现代 POSIX 不需要#include ,尽管我认为它仍然是明智的。如果您从 creat() 中获取了值,您也可以使用 fchmod() 来获得良好的效果。不过,我必须承认,我不再使用 creat() - 我使用 open() 的三参数版本。
      【解决方案5】:

      我假设您正在尝试执行一些 IPC。您是否考虑过使用其他方法来实现此目的,例如使用 dbus 或为此目的设计的其他系统?

      【讨论】:

        猜你喜欢
        • 2015-06-25
        • 1970-01-01
        • 1970-01-01
        • 2011-09-10
        • 2014-04-16
        • 1970-01-01
        • 1970-01-01
        • 2021-04-09
        • 1970-01-01
        相关资源
        最近更新 更多