Читать книгу 📗 "Linux программирование в примерах - Роббинс Арнольд"
244 /* Возвращает 1, если PATH является годным к использованию245 каталогом, 0 если нет, 2 если он не существует. */246247 static int248 dir_ok(const char *path)249 {250 struct stat stats;251252 if (stat (path, &stats)) /* Nonzero return = failure */253 return 2;254255 if (!S_ISDIR(stats.st_mode))256 {257 error(0, 0, _("'%s" is not a directory"), path);258 return 0;259 }260261 /* Используйте access для проверки прав доступа на поиск,262 поскольку при проверке битов прав доступа st_mode они могут263 потеряться новыми механизмами управления доступом. Конечно,264 доступ теряется, если вы используете setuid. */265 if (access (path, X_OK) != 0)266 {267 if (errno == EACCES)268 error (0, 0, _("directory '%s' is not searchable"), path);269 else270 error(0, errno, "%s", path);271 return 0;272 }273274 return 1;275 }Код прост. Строки 252–253 проверяют, существует ли файл. Если
stat()Комментарий в строках 261–264 объясняет использование
access()st_modeaccesserrno11.4. Проверка для эффективного пользователя:
euidaccess()GLIBC предоставляет дополнительную функцию, которая работает подобно
access()#include <unistd.h> /* CLIBC */int euidaccess(const char *path, int amode);Аргументы и возвращаемое значение имеют тот же смысл, как для
access()euidaccess()access()В противном случае
euidaccess()stat()Если вы пишете переносимую программу, но предпочитаете использовать этот интерфейс, достаточно просто извлечь исходный файл из архива GLIBC и приспособить его для общего использования.
11.5. Установка дополнительных битов доступа для каталогов
На современных системах setgid и «липкий» биты имеют особое значение при применении к каталогам.
11.5.1. Группа по умолчанию для новых файлов и каталогов
В оригинальной системе Unix, когда
open()creat()V7, BSD вплоть до BSD 4.1 и System V вплоть до Release 3 все трактовали каталоги как файлы. Однако, с добавлением дополнительного набора групп в BSD 4.2 способ создания новых каталогов изменился: новые каталоги наследовали группу родительского каталога. Более того, новые файлы также наследовали ID группы родительского каталога, а не эффективный GID создающего процесса.
Идея, лежащая в основе множества групп и каталогов, которые работают таким способом, была в усилении группового взаимодействия. У каждого проекта организации, использующего систему, была бы отдельная назначенная ему группа. Для каждой такой группы в группе этого проекта был бы каталог верхнего уровня, и все файлы проекта имели бы доступ на чтение и запись (а при необходимости и на исполнение). Вдобавок, новые файлы автоматически получают группу родительского каталога. Состоя одновременно в нескольких группах (наборе групп), пользователь мог бы как угодно перемещаться между проектами с помощью простой команды
cdЧто происходит на современных системах? Ну, это еще один из немногих случаев, когда можно поймать двух зайцев. SunOS 4.0 придумал механизм, который был включен в System V Release 4; сегодня он используется по крайней мере в Solaris и GNU/Linux. Эти системы придают биту setgid родительского каталога нового файла или каталога следующее значение:
Бит setgid родительского каталога сброшен
Новые файлы и каталоги получают эффективный GID создающего процесса.
Бит setgid родительского каталога установлен
Новые файлы и каталоги получают GID родительского каталога. Новые каталоги наследуют также установленный бит setgid.
(До SunOS 4.0 бит setgid для каталогов не имел определенного значения.) Следующий сеанс показывает бит setgid в действии:
$ <b>cd /tmp</b> /* Перейти в /tmp */$ <b>ls -ld .</b> /* Проверить его права доступа */drwxrwxrwt 8 root root 4096 Oct 16 17:40 .$ <b>id</b> /* Отметить текущие группы */uid=2076(arnold) gid=42(devel) groups=19(floppy),42(devel),2076(arnold)$ <b>mkdir d1 ; ls -ld d1</b> /* Создать новый каталог */