【问题标题】:When is umask() useful?umask() 什么时候有用?
【发布时间】:2011-09-06 02:49:45
【问题描述】:
umask(0);

fd = open("/dev/null", O_RDWR);

这里是man 2 umask

umask() sets the calling process’s file mode creation mask (umask) to mask & 0777.

但这对我来说没有意义,因为当我们调用open时,我们还会提供一个模式参数。

那么umask 的意义何在?

【问题讨论】:

标签: c umask


【解决方案1】:

umask 应用于文件系统操作中使用的所有模式。来自手册open(2)

创建文件的权限为(mode & ~umask)

因此,只需一次调用 umask,您就可以影响所有创建文件的模式。

这通常在程序希望用户允许否决它创建的文件/目录的默认授权时使用。偏执的用户(或 root)可以将 umask 设置为 0077,这意味着即使您在 open(2) 中指定 0777,也只有当前用户可以访问。

【讨论】:

  • 如果umask是777,那么没有人可以修改呢?
  • 好像open不带mode参数也可以调用,int open(const char *pathname, int flags);,这种情况下创建文件的权限是什么?
  • 是的。没有多大意义,但没有什么能阻止您创建自己无法访问的文件。实际上,我用它来停止程序以使用chmod 0 .configdir 创建/修改不需要的文件和文件夹
  • re open without mode:这取决于你的Unix风格。在我的 Linux 上,使用O_CREAT 时必须指定模式。一些 Unix 从包含新文件的目录的模式构建模式。有关详细信息,请阅读文档。
  • @FábioRobertoTeodoro 是的,你可以这样看。在我看来,它禁用了umask() 的效果。
【解决方案2】:

我知道这是个老问题,但这是我的两分钱:

共享内存对象的权限

我试图创建一个共享内存对象,使用:

int shm_open(const char *name, int oflag, mode_t mode); 

生成的共享内存在 mode 参数中没有设置权限,所以我阅读了 shm_open 手册页,它引导我打开函数 man page,上面写着:

mode 指定在创建新文件时使用的权限。在标志中指定 O_CREAT 时必须提供此参数;如果未指定 O_CREAT,则忽略模式。有效权限由进程的umask以通常的方式修改:创建文件的权限为(mode & ~umask)。请注意,此模式仅适用于以后对新创建文件的访问

所以我尝试修改umask:

mode_t umask(mode_t mask); 

但它也不起作用,所以在更多谷歌之后,我在 gnu.org 中找到了这个 Setting Permission 文档

推荐:

当您的程序需要创建文件并绕过 umask 以获得访问权限时,最简单的方法是在打开文件后使用 fchmod,而不是更改 umask。实际上,更改 umask 通常只能通过 shell 来完成。他们使用 umask 函数。

使用 fchmod 我的功能可以按我的意愿工作 :) 她是这样的:

int open_signals_shmem(struct signal_shmem **shmem, int size)
{
    int fd, ret;
    void *ptr;

    *shmem = NULL;
    ret = 1;

    fd = shm_open(SIGNALS_SHMEM_NAME, O_RDWR | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO);
    if (fd == -1)
    {
        printf("error: signals shmem could not be allocated (%s, errno=%d)\n", SIGNALS_SHMEM_NAME, errno);
    }
    else
    {
        // Change permissions of shared memory, so every body can access it
        fchmod(fd, S_IRWXU | S_IRWXG | S_IRWXO);

        if (ftruncate(fd, size) == -1)
        {
            printf("error: signals shmem could not be truncated (%s, errno=%d)\n", SIGNALS_SHMEM_NAME, errno);
        }
        else
        {
            ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
            if (ptr == MAP_FAILED)
            {
                printf("error: signals shmem could not be mapped (%s, errno=%d)\n", SIGNALS_SHMEM_NAME, errno);
            }
            else
            {
                *shmem = ptr;
                ret = 0;
            }
        }
    }
    return ret;
}

【讨论】:

  • 您可能只想在创建共享内存时调用 fchmod(尝试使用 RDWR 打开,然后检查 ENOENT 的 errno,然后执行 O_RDWR|O_CREAT 和 fchmod),因为您不能 fchmod 另一个即使拥有 777 权限,用户的共享内存也是如此。否则,如果您尝试打开由其他用户创建的共享内存对象,您将收到权限错误。
【解决方案3】:

引用this article:

umask 的目的是允许 用户影响权限 赋予新创建的文件和 目录。守护进程不应允许 自己受此影响 设置,因为什么是合适的 用户不一定会 适合守护进程。

在某些情况下可能更多 方便将umask设置为 一个非零值。这同样 可以接受:重点是 守护进程已控制 价值,而不仅仅是 接受给予的东西。

【讨论】:

  • @Blagovest Buyukliev,我还是看不出umask的用途,不是已经在open的参数中了吗?
  • open 的第二个参数指定打开文件的模式,即返回的描述符上可以进行哪些操作。另一方面,umask 指定将为每个新创建的文件设置的文件系统权限。
  • @Blagovest Buyukliev,那不是也可以吗? int creat(const char *pathname, mode_t mode);
  • creat 是旧的、已弃用的创建新空文件的方法。它与带有标志O_CREATopen 相同。
  • @Blagovest Buyukliev,我的意思是,creatopen 的参数为 modeflag,umask 对我来说仍然没用。
【解决方案4】:

大多数 Mac 开发人员(以及大多数软件测试人员),从他们还是婴儿的时候起,就将其放在他们的 .cshrc 中

umask 002

但是,大多数最终用户并不了解 umask,因此如果他们在计算机上创建一个新用户并运行您的应用程序,您可能会创建一堆日志文件,而没有组读/写权限。 然后他们再次切换用户,突然您的应用程序无法运行。 出于这个原因,我们将其添加到我们所有的应用程序中。 我们在安全方面的经验法则是“我们希望用户能够使用我们的软件”。

#import <sys/types.h>
#import <sys/stat.h>
int main(int argc, char *argv[])
{
    // set permissions for newly created files to ug+rwX,o+rX
    umask(0002); 

【讨论】:

    猜你喜欢
    • 2011-09-28
    • 2012-08-07
    • 2012-04-05
    • 1970-01-01
    • 2010-12-26
    • 2012-08-18
    • 1970-01-01
    • 2011-05-06
    • 2012-05-24
    相关资源
    最近更新 更多