确定当前用户的文件权限

发布于 2024-09-16 12:02:56 字数 758 浏览 6 评论 0原文

我正在寻找一种方法来确定 POSIX 兼容系统上当前用户(即进程的 UID)的文件权限。我不想尝试打开该文件 - 这可能会弄乱目录和各种特殊文件。

我正在编译指定目录的目录列表,对于每个文件,报告一堆信息:文件名、大小、类型(文件/目录/其他)、权限(可以读取、可以写入)。对于大小和类型,我已经有了 stat 调用的结果。

这就是我想到的:

if ((dirent->st_uid == getuid() && dirent->st_mode & S_IRUSR)
 || (dirent->st_gid == getgid() && dirent->st_mode & S_IRGRP)
 || (dirent->st_mode && S_IROTH)) entry->perm |= PERM_READ;
if ((dirent->st_uid == getuid() && dirent->st_mode & S_IWUSR)
 || (dirent->st_gid == getgid() && dirent->st_mode & S_IWGRP)
 || (dirent->st_mode && S_IWOTH)) entry->perm |= PERM_WRITE;

我是否必须这样做,或者是否有一个简单的调用/宏可以完成同样的事情? ACL 支持的奖励积分,尽管目前这并不是绝对必要的。

I am looking for a way to determine file permissions for the current user (i.e. the process's UID) on POSIX-compliant systems. I don't want to try opening the file - that could get messy with directories and all kinds of special files.

I am compiling a directory listing of a specified directory, and for each file, reporting a bunch of things: filename, size, type (file/directory/other), permissions (you can read, you can write). For size and type, i already have results of stat call available.

Here's what i came up with:

if ((dirent->st_uid == getuid() && dirent->st_mode & S_IRUSR)
 || (dirent->st_gid == getgid() && dirent->st_mode & S_IRGRP)
 || (dirent->st_mode && S_IROTH)) entry->perm |= PERM_READ;
if ((dirent->st_uid == getuid() && dirent->st_mode & S_IWUSR)
 || (dirent->st_gid == getgid() && dirent->st_mode & S_IWGRP)
 || (dirent->st_mode && S_IWOTH)) entry->perm |= PERM_WRITE;

Do i have to do this way, or is there a simple call/macro that would accomplish the same thing? Bonus points for ACL support, although that is not strictly necessary at this point.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不打扰别人 2024-09-23 12:02:56

access(2) 将在内核中为您执行全套权限测试:

#include <unistd.h>
#include <stdio.h>

int main(int argc, char* argv[]) {
    int i;

    for (i=0;i<argc;i++) {
            if(access(argv[i], R_OK)) {
                    printf("%s\n", argv[i]);
                    perror("R_OK");
            }
            if(access(argv[i], W_OK)) {
                    printf("%s\n", argv[i]);
                    perror("W_OK");
            }
    }

    return 0;
}

一些示例输出:

$ ./foo ./foo /etc/passwd /etc/shadow
/etc/passwd
W_OK: Permission denied
/etc/shadow
R_OK: Permission denied
/etc/shadow
W_OK: Permission denied

编辑

请注意 access(2) 容易受到 TOCTTOU Time-of 的影响-检查使用时间竞争条件。您不应使用 access(2) 授予或拒绝特权进程中的用户对文件的访问权限,您的程序将容易受到可能被利用的竞争条件的影响。如果这就是您想要测试的目的,请在执行任何 open(2)exec*() 调用之前使用 setfsuid(2)

access(2) will perform the full suite of permissions tests for you, in the kernel:

#include <unistd.h>
#include <stdio.h>

int main(int argc, char* argv[]) {
    int i;

    for (i=0;i<argc;i++) {
            if(access(argv[i], R_OK)) {
                    printf("%s\n", argv[i]);
                    perror("R_OK");
            }
            if(access(argv[i], W_OK)) {
                    printf("%s\n", argv[i]);
                    perror("W_OK");
            }
    }

    return 0;
}

Some sample output:

$ ./foo ./foo /etc/passwd /etc/shadow
/etc/passwd
W_OK: Permission denied
/etc/shadow
R_OK: Permission denied
/etc/shadow
W_OK: Permission denied

EDIT

Note that access(2) is vulnerable to a TOCTTOU Time-of-check-to-time-of-use race condition. You shouldn't use access(2) to grant or deny access to files to a user from a privileged process, your program would be vulnerable to a race condition that could be exploited. If this is what you want the test for, use setfsuid(2) before doing any open(2) or exec*() calls.

吻风 2024-09-23 12:02:56

使用 access() 检查权限。

Use access() to check for permissions.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文