Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

determine file permissions for the current user

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.

like image 942
matejcik Avatar asked Nov 21 '25 16:11

matejcik


2 Answers

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.

like image 124
sarnold Avatar answered Nov 23 '25 07:11

sarnold


Use access() to check for permissions.

like image 37
unwind Avatar answered Nov 23 '25 07:11

unwind



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!