• Чтобы избежать таких проблем, можно было бы сделать запись ACL_GROUP_OBJ ограничивающим набором для всех записей ACL_USER и ACL_GROUP. Однако это означало бы, что права доступа ACL_GROUP_OBJ необходимо устанавливать в сочетании со всеми правами, предоставляемыми записями ACL_USER и ACL_GROUP. Это конфликтовало бы с использованием записи ACL_GROUP_OBJ для определения прав доступа, согласующихся с группой файла.
Для решения данных проблем предназначена запись ACL_MASK. Она обеспечивает механизм, позволяющий реализовать традиционное назначение операций chmod(), не разрушая семантики прав доступа к файлу, заданной приложениями, применяющими ACL-списки. Когда ACL-список имеет запись ACL_MASK:
• все изменения в традиционных правах доступа группы с помощью системного вызова chmod() изменяют параметры записи ACL_MASK (а не записи ACL_GROUP_OBJ);
• вызов stat() возвращает права доступа ACL_MASK (а не права доступа ACL_GROUP_OBJ), указанные в битах прав доступа для группы в поле st_mode (см. рис. 15.1).
В то время как запись ACL_MASK обеспечивает способ сохранения ACL-информации, которая видна для приложений, не использующих ACL-списки, обратное не гарантировано. Допустим, к примеру, что мы снабдили файл следующим ACL-списком:
user::rw-,group::-,mask::-,other::r—
Если затем мы выполним команду chmod g+rw для этого файла, то ACL-список станет таким:
user::rw-,group::-,mask::rw-,other::r—
В данном случае у группы по-прежнему нет доступа к файлу. Одним из обходных вариантов является изменение записи ACL для группы, чтобы предоставить все права доступа. Вследствие этого группа всегда будет получать все права доступа, которые предоставляет запись ACL_MASK.
В сеансе оболочки можно использовать команду getfacl, чтобы увидеть ACL-список для файла.
$ umask 022
$ touch tfile
$ getfacl tfile
# file: tfile
# owner: mtk
# group: users
user::rwgroup::
r–
other::r–
Из результатов работы команды getfacl видно, что новый файл создается с минимальным ACL-списком. При выводе данного списка в текстовой форме команда getfacl предваряет его записи тремя строками, в которых показаны имя и принадлежность данного файла. Можно отменить вывод этих строк, если указать параметр — omit — header.
Продемонстрируем теперь, что изменения прав доступа к файлу, выполняемые с помощью обычной команды chmod, «пропускаются» через ACL-список.
$ chmod u=rwx,g=rx,o=x tfile
$ getfacl — omit-header tfile
user::rwx
group::r-x
other::-x
Команда setfacl модифицирует ACL-список для файла. Здесь мы используем команду setfacl — m, чтобы добавить записи ACL_USER и ACL_GROUP в список прав доступа:
$ setfacl — m u: paulh: rx,g: teach: x tfile
$ getfacl — omit-header tfile
user::rwx
user: paulh: r-x
group::r-x
group: teach:-x
mask::r-x
other::-x
Команда setfacl с параметром — m изменяет существующие записи ACL-списка или добавляет новые записи, если соответствующие записи с указанным типом тега и спецификатором еще не существуют. Можно дополнительно применить параметр — R, чтобы рекурсивно применить указанный ACL-список для всех файлов в дереве каталогов.
Из результатов работы команды getfacl видно, что параметр setfacl автоматически создал запись ACL_MASK для данного ACL-списка.
Добавление записей ACL_USER и ACL_GROUP превращает данный ACL-список в расширенный, и команда ls — l подтверждает это, поскольку после традиционной маски прав доступа следует знак +:
$ ls — l tfile
— rwxr-x — x+ 1 mtk users 0 Dec 3 15:42 tfile
Продолжим использование параметра setfacl, отключив все права доступа, кроме выполнения, в записи ACL_MASK, а затем просмотрим ACL-список еще раз с помощью команды getfacl:
$ setfacl — m m::x tfile
$ getfacl — omit-header tfile
user::rwx
user: paulh: r-x #effective:-x
group::r-x #effective:-x
group: teach:-x
mask::-x
other::-x
Комментарии #effective:, которые команда getfacl выводит после записей, относящихся к пользователю paulh и к группе файла (group::), информируют нас о том, что после применения маски (операция И) к записи ACL_MASK фактические права доступа, предоставляемые каждой из этих записей, окажутся меньше указанных в записи.
Используем теперь команду ls — l для повторного просмотра традиционных битов прав доступа к файлу. Видно, что показанные биты прав доступа для класса группы отражают права доступа в маске ACL_MASK (-x), а не права из записи ACL_GROUP (r-x).
$ ls — l tfile
— rwx — x — x+ 1 mtk users 0 Dec 3 15:42 tfile
Команду setfacl — x можно применять для удаления записей из ACL-списка. Удалим записи, относящиеся к пользователю paulh и к группе teach (при удалении права доступа не указывают):