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.
access(2)will perform the full suite of permissions tests for you, in the kernel:Some sample output:
EDIT
Note that
access(2)is vulnerable to a TOCTTOU Time-of-check-to-time-of-use race condition. You shouldn’t useaccess(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, usesetfsuid(2)before doing anyopen(2)orexec*()calls.