Листинг 10.2. ( stat-perm.c ) Проверка того, имеет ли владелец право записи в файл
#include
#include
int main(int argc, char* argv[]) {
const char* const filename = argv[1];
struct stat buf;
/* Получение информации о файле. */
stat(filename, &buf);
/* Если владельцу разрешена запись в файл,
отображаем сообщение. */
if (buf.st_mode & S_IWUSR)
printf("Owning user can write '%s'.\n", filename);
return 0;
}
Если запустить программу с файлом hello
, будет выдано следующее:
% ./stat-perm hello
Owning user can write 'hello'.
Константа S_IWUSR
соответствует праву записи для владельца. Для каждого бита в строке режима существует своя константа. Например, константа S_IRGRP
обозначает право чтения для группы, а константа S_IXOTH
— право выполнения для остальных пользователей. Если невозможно получить информацию о файле, функция stat()
возвращает -1 и помещает код ошибки в переменную errno
.
С помощью функции chmod()
можно менять режим доступа к существующему файлу. Функции передаётся имя файла и набор флагов, соответствующих устанавливаемым битам доступа. Например, в следующей строке файл hello
делается доступным для чтения и выполнения владельцу, а права группы и остальных пользователей отменяются:
chmod("hello", S_IRUSR | S_IXUSR);
Те же самые права доступа действуют и в отношении каталогов, но имеют несколько иной смысл. Если у пользователя есть право чтения каталога, то это означает разрешение на получение списка содержимого каталога. Право записи означает возможность добавлять и удалять файлы в каталоге. Пользователь, которому разрешена запись в каталог, может удалять из него файлы даже в том случае, когда у него нет права доступа к этим файлам. Право выполнения применительно к каталогам называется правом поиска. Пользователю. имеющему это право, разрешается входить в каталог и обращаться к его файлам. Если пользователь не может перейти в каталог, то ему не удастся получить доступ к находящимся в нем файлам независимо от их собственных прав доступа.
Подводя итог, рассмотрим, как ядро определяет, имеет ли процесс право обратиться к заданному файлу. Сначала выясняется, кем является пользователь, запустивший процесс: владельцем файла, членом его группы или кем-то другим. В зависимости от категории пользователя проверяется соответствующий набор битов чтения/записи/выполнения и на его основании принимается окончательное решение. [32] Ядро может отклонить запрос на доступ к файлу, если один из каталогов на пути к нему недоступен данному пользователю. Например, если процессу не разрешено обращаться к каталогу /tmp/private , то он не сможет получить доступ к файлу /tmp/private/data .
Есть, правда, одно важное исключение: процессы, запускаемые пользователем root (его идентификатор равен нулю), всегда получают доступ к требуемым файлам независимо от их атрибутов.
10.3.1. Проблема безопасности: программы без права выполнения
Есть один хороший пример того, как обмануть неопытного пользователя, пытающегося защитить свои программы от несанкционированного запуска. Сброс бита выполнения файла еще не означает, что файл нельзя будет запустить. Дело в том, что при копировании файла копия переходит в распоряжение нового владельца. Как вы понимаете, ему не составляет никакого труда изменить права доступа к скопированному файлу и снова сделать его исполняемым. Вывод: защищайте программы не от несанкционированного запуска, а от несанкционированного копирования!
Помимо обычных битов режима есть один особый бит, называемый sticky-битом ("липучкой"). [33] Название бита является анахронизмом. Оно возникло в те далекие времена, когда наличие этого бита означало запрет на выгрузку программы из памяти по окончании выполнения.
Он применим только в отношении каталогов.
Обычно удалять файлы могут пользователи, имеющие право записи в каталог. Каталог, для которого установлен sticky-бит, допускает удаление файла только в том случае, когда пользователь является владельцем этого файла или самого каталога и имеет право записи в каталог.
В типичной Linux-системе есть несколько таких каталогов. Один из них — каталог /tmp
, в котором любой пользователь может размещать временные файлы. Этот каталог специально сделан доступным для всех пользователей, поэтому он полностью открыт для записи. Однако нельзя допустить, чтобы пользователи удаляли чужие файлы, поэтому для каталога /tmp
установлен sticky-бит.
Читать дальше