确定当前用户的文件权限

mat*_*cik 3 c unix posix file-permissions

我正在寻找一种方法来确定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;
Run Code Online (Sandbox Code Playgroud)

我必须这样做,还是有一个简单的调用/宏可以完成同样的事情?ACL支持的加分点,虽然此时并非严格必要.

sar*_*old 8

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;
}
Run Code Online (Sandbox Code Playgroud)

一些示例输出:

$ ./foo ./foo /etc/passwd /etc/shadow
/etc/passwd
W_OK: Permission denied
/etc/shadow
R_OK: Permission denied
/etc/shadow
W_OK: Permission denied
Run Code Online (Sandbox Code Playgroud)

编辑

请注意,access(2)易受TOCTTOU使用时间检查竞争条件的影响.您不应该使用access(2)授权或拒绝从特权进程向用户访问文件,您的程序将容易受到可能被利用的竞争条件的影响.如果这是你想要的测试,使用setfsuid(2)做任何之前open(2)exec*()通话.