определить права доступа к файлу для текущего пользователя - PullRequest
3 голосов
/ 01 сентября 2010

Я ищу способ определения прав доступа к файлу для текущего пользователя (то есть UID процесса) в POSIX-совместимых системах. Я не хочу пытаться открыть файл - это может запутаться в каталогах и всяких специальных файлах.

Я составляю список каталогов указанного каталога и для каждого файла сообщаю о множестве вещей: имя файла, размер, тип (файл / каталог / другое), разрешения (вы можете читать, вы можете писать). По размеру и типу у меня уже есть результаты 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, хотя в этом нет особой необходимости.

Ответы [ 2 ]

8 голосов
/ 01 сентября 2010

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 Время проверки на время использования.Вы не должны использовать access(2) для предоставления или запрета доступа к файлам для пользователя из привилегированного процесса, ваша программа будет уязвима для состояния гонки, которое может быть использовано.Если это то, для чего вы хотите выполнить тест, используйте setfsuid(2) перед выполнением любых вызовов open(2) или exec*().

3 голосов
/ 01 сентября 2010

Используйте <a href="http://linux.die.net/man/2/access" rel="nofollow noreferrer">access()</a> для проверки прав доступа.

...