15.4.7. Изменение прав доступа к файлу: системные вызовы chmod() и fchmod()

Системные вызовы chmod() и fchmod() изменяют права доступа к файлу.

#include

int chmod(const char *pathname, mode_t mode);

#define _XOPEN_SOURCE 500 /* Или #define _BSD_SOURCE */

#include

int fchmod(int fd, mode_t mode);

Оба вызова возвращают 0 при успешном завершении и –1 при ошибке

Системный вызов chmod() изменяет права доступа к файлу, указанному в аргументе pathname. Если данный аргумент является символической ссылкой, то системный вызов chmod() изменяет права доступа к файлу, на который она указывает, а не права доступа к самой ссылке. (Символическая ссылка всегда создается с правами доступа на чтение, запись и выполнение, предоставленными всем пользователям, и эти права нельзя изменить. Они игнорируются при разыменовании ссылки.)

Системный вызов fchmod() изменяет права доступа к файлу, указанному с помощью открытого файлового дескриптора fd.

Аргумент mode задает новые права доступа к файлу как число (восьмеричное) либо в виде маски, сформированной с помощью операции ИЛИ (|) из битов прав доступа, приведенных в табл. 15.4. Для изменения прав доступа к файлу необходимо, чтобы процесс был привилегированным (CAP_FOWNER) либо чтобы его действующий UID совпадал с владельцем (UID) для файла. (Если абсолютно точно, то в Linux в случае непривилегированного процесса с идентификатором пользователя файла должен совпадать пользовательский идентификатор в файловой системе процесса, а не его действующий UID, как описано в разделе 9.5.)

Чтобы предоставить всем пользователям только право доступа на чтение файла, можно использовать следующий системный вызов:

if (chmod("myfile", S_IRUSR | S_IRGRP | S_IROTH) == -1)

errExit("chmod");

/* Или эквивалент — chmod("myfile", 0444); */

Порядок изменения избранных битов прав доступа к файлу таков: сначала следует извлечь существующие значения, применив системный вызов stat(), изменить необходимые биты, а затем выполнить системный вызов chmod(), чтобы обновить права доступа:

struct stat sb;

mode_t mode;

if (stat("myfile", &sb) == -1)

errExit("stat");

mode = (sb.st_mode | S_IWUSR) & ~S_IROTH;

/* Разрешить владельцу запись, другим пользователям запретить чтение,

остальные биты не менять */

if (chmod("myfile", mode) == -1)

errExit("chmod");

Приведенный выше код эквивалентен следующей команде оболочки:

$ chmod u+w,o-r myfile

В подразделе 15.3.1 мы отметили: если каталог размещен в файловой системе ext2, смонтированной с параметром — o bsdgroups, или в какой-либо файловой системе, смонтированной с параметром — o sysvgroups, и для этого каталога установлен бит прав доступа set-group-ID, то создаваемые в данном каталоге новые файлы наследуют свою принадлежность от родительского каталога, а не от действующего GID создающего процесса. Но может случиться так, что идентификатор группы для такого файла не совпадает ни с одним из GID создающего процесса. По этой причине, когда непривилегированный процесс (то есть не обладающий возможностью CAP_FSETID) совершает системный вызов chmod() (или fchmod()) для файла, идентификатор группы которого не совпадает с действующим GID или идентификатором добавочной группы для процесса, ядро всегда очищает бит прав доступа set-group-ID. Это мера безопасности, призванная запретить пользователю создание программы с правами доступа set-group-ID для группы, к которой он не принадлежит. Следующие команды оболочки демонстрируют попытку взлома, которая пресекается данной мерой:

$ mount | grep test Каталог /test смонтирован с параметром — o bsdgroups

/dev/sda9 on /test type ext3 (rw,bsdgroups)

$ ls — ld /test Каталог имеет корневой идентификатор

GID, который доступен для записи всем

drwxrwxrwx 3 root root 4096 Jun 30 20:11 /test

$ id Я обычный пользователь, не входящий в корневую группу

uid=1000(mtk) gid=100(users) groups=100(users),101(staff),104(teach)

$ cd /test

$ cp ~/myprogСкопируем сюда несколько вредоносных программ

$ ls — l myprog Здорово! Они в корневой группе!

— rwxr-xr-x 1 mtk root 19684 Jun 30 20:43 myprog

$ chmod g+s myprog Смогу ли я присвоить корневые права доступа?

$ ls — l myprog Хм, никак…

— rwxr-xr-x 1 mtk root 19684 Jun 30 20:43 myprog

15.5. Флаги индексного дескриптора (расширенные атрибуты файла в файловой системе ext2)

Ряд файловых систем Linux допускают устанавливать для файлов и каталогов различные флаги индексного дескриптора. Эта функция является нестандартным расширением Linux.

Перейти на страницу:

Похожие книги