Приведем еще один пример на основе рис. 17.1. Допустим, у нас есть процесс с GID 102, причем среди идентификаторов дополнительных групп есть также идентификатор 103. Для такого процесса вызовы access(file, R_OK) и access(file, W_OK) завершились бы успешно, поскольку они соответствовали бы записи ACL_GROUP для идентификаторов 102 и 103. С другой стороны, системный вызов access(file, R_OK | W_OK) привел бы к ошибке, так как здесь нет совпадающей записи ACL_GROUP, которая предоставляла бы права доступа на чтение и запись одновременно.
При манипулировании ACL-списками с помощью команд setfacl и getfacl (мы опишем их очень скоро) или некоторых библиотечных функций указывают текстовые представления записей ACL-списка. Для таких текстовых представлений допускаются два формата.
• ACL-список в
• ACL-списки в
В обеих формах каждая запись состоит из трех частей, разделенных двоеточиями:
tag-type: [tag-qualifier]: permissions
Часть tag-type содержит одно из значений, показанных в первом столбце табл. 17.1. Далее может следовать необязательная часть tag-qualifier, которая идентифицирует пользователя или группу по имени или числовому ID. Эта часть присутствует только для записей ACL_USER и ACL_GROUP. Ниже приведены все краткие текстовые формы ACL-списков, соответствующие традиционной маске прав доступа 0650:
u::rw-,g::r-x,o::-
u::rw,g::rx,o::-
user::rw,group::rx,other::-
В следующей краткой текстовой форме ACL-списка присутствуют два имени пользователей, имя группы и запись маски:
u::rw,u: paulh: rw,u: annabel: rw,g::r,g: teach: rw,m::rwx,o::-
Таблица 17.1. Расшифровка текстовых форм записи ACL-списка
Текстовые формы тега — Есть ли тег-спецификатор? — Соответствующий тип тега — Запись для…
u, user — Нет — ACL_USER_OBJ — Владельца файла (пользователя)
u, user — Да — ACL_USER — Указанного пользователя
g, group — Нет — ACL_GROUP_OBJ — Группы файла
g, group — Да — ACL_GROUP — Указанной группы
m, mask — Нет — ACL_MASK — Маски класса группы
o, other — Нет — ACL_OTHER — Остальных пользователей
Если ACL-список содержит запись ACL_USER или ACL_GROUP, то должен включать запись ACL_MASK. Если же не содержит этих двух записей, то запись ACL_MASK является необязательной.
Запись ACL_MASK действует подобно верхней границе прав доступа, предоставляемых записями ACL-списка в так называемом
Цель записи ACL_MASK — обеспечить согласованное поведение при запуске приложений, которые не используют ACL-списки. В качестве примера, демонстрирующего необходимость записи с маской, предположим, что ACL-список файла содержит следующие записи:
user::rwx # ACL_USER_OBJ
user: paulh: r-x # ACL_USER
group::r-x # ACL_GROUP_OBJ
group: teach:-x # ACL_GROUP
other::-x # ACL_OTHER
Предположим теперь, что программа выполняет следующий системный вызов chmod():
chmod(pathname, 0700); /* Установить права доступа rwx- */
Для приложения, не работающего с ACL-списками, это означает «Запретить доступ всем, кроме владельца файла». Такая семантика должна сохраняться даже при наличии ACL-списков. В случае отсутствия записи ACL_MASK данное поведение можно реализовать различными способами, но каждый из них сталкивается с трудностями (представлены ниже).
• Простого изменения записей ACL_GROUP_OBJ и ACL_USER_OBJ так, чтобы у них была маска —, окажется недостаточно, поскольку у пользователя paulh и у группы teach по-прежнему остались бы некоторые права доступа к файлу.
• Другой возможностью могло бы стать применение новой группы с иным набором прав доступа (то есть с полным запретом доступа) для всех записей ACL_USER, ACL_GROUP, ACL_GROUP_OBJ и ACL_OTHER в списке ACL:
user::rwx # ACL_USER_OBJ
user: paulh:- # ACL_USER
group::- # ACL_GROUP_OBJ
group: teach:- # ACL_GROUP
other::- # ACL_OTHER
Проблема такого подхода заключается в том, что приложение, которое не использует ACL-списки, могло бы непреднамеренно нарушить семантику прав доступа, установленную приложениями, применяющими ACL-списки, поскольку (например) следующий вызов не вернул бы записи ACL_USER и ACL_GROUP ACL-списка в их исходное состояние:
chmod(pathname, 751);