В Linux владелец и права на объекты файловой системы задаются и определяются рядом факторов, которые хорошо поддаются систематизации и не допускают неоднозначности толкования. Давайте по-порядку разберёмся с ними на конкретных примерах. Я думаю, что многие, прочитав эту статью, будут по крайней мере удивлены, что с правами в Linux всё обстоит гораздо сложнее, чем они себе это представляли ранее.
Прежде всего, отметим привилегированного пользователя root, для которого права других пользователей не играют роли вообще: ему позволено делать с созданными ими объектами всё что угодно. Речь пойдёт о непривилегированных пользователях.
В системе существует 2 основных объекта файловой системы: файлы и папки (директории). И если права на папку задаются её владельцем:группой и 4-мя триадами битов разрешений (superbits:user:group:others), то для определения прав доступа к файлу необходимо учитывать ровно в два раза больше данных: для самого файла и для папки, в которой он находится. Последнее обстоятельство нередко ускользает из поля зрения при анализе прав доступа к файлам.
Определение прав доступа для файлов
В связи с вышесказанным я предлагаю записывать права доступа на файлы в два ряда — вверху права на родительскую папку, а внизу — на сам файл. Причём и вверху и внизу будет присутствовать лишь одна триада, а сами эти права мы назовём эффективными. Пояснения будут даны ниже.
В следующие таблице сведены воедино основные операции с файлами и те необходимые и достаточные условия, которые позволяют их выполнять.
- Прочерком обозначено отсутствие изменений (неизменность исходных параметров).
- Очевидно, что во всех случаях для доступа к объектам внутри папки должен быть установлен execution бит «x«, то есть без этого бита ни о каких операциях над её объектами речи быть не может.
- Обратите внимание, что при удалении, переименовании и перемещении файла его собственные права не играют никакой роли — учитываются лишь права на папку, в которой он находится.
- Кроме того, изменение владельца файла происходит лишь в том случае, когда изменяется его i-node. Поэтому при переименовании и перемещении файлов сохраняются права их оригинальных владельцев, тогда как при копировании владелец и группа меняются на того, кто копирует.
- Права доступа на вновь создаваемый файл определяются маской umask, которая задаётся отдельно для каждого пользователя системы. Владельцем файла становится его создатель, а группой — первичная группа создателя. Исключением является случай, когда на папке, в которой находится файл, установлен бит SGID (2000): вновь создаваемые файлы и папки будут иметь группу папки, а не первичную группу создателя. Это полезно, если группа пользователей работает над неким проектом и важно, чтобы все файлы проекта принадлежали одной и той же группе.
- Следует также отметить и Sticky bit (1000), который устанавливается на папку для того, чтобы пользователи не могли удалять чужие файлы даже при наличии на это формальных полномочий. Ярким примером является директория /tmp.
- При копировании непривилегированными пользователями биты SUID и SGID сбрасываются, хотя остальные триады прав сохраняются.
Теперь я подробно расскажу, в чём состоит суть эффективных прав на примере определения прав доступа некоторого пользователя к файлу. Алгоритм следующий:
- Сначала необходимо определить совместимость триад прав по владельцу и группе для субъекта доступа и папки, в которой находится файл. В результате останется одна релевантная триада (верхняя клетка).
- Затем аналогичным образом необходимо определить совместимость триады прав для файла (нижняя клетка).
- И, наконец, по выбранным триадам, то есть эффективным правам доступа, мы определяем окончательные права с помощью таблицы.
Пример 1. Имеется файл samfile в папке testfolder с указанной принадлежностью и правами. Необходимо определить, что сможет сделать с ним пользователь den, если и он и sam входят в группу admins.
- Выясняем соответствие триад прав «den — папка»
- Пользователь den не совпадает с владельцем папки root, поэтому первая триада отбрасывается.
- Пользователь den входит в группу admins, следовательно мы имеем соответствие прав во второй триаде и останавливаемся на ней. Триада прав по папке: rwx.
- Выясняем соответствие триад прав «den — файл»
- Пользователь den не совпадает с владельцем файла samfile, поэтому первая триада отбрасывается.
- Пользователь den не входит в группу sam, поэтому вторая триада тоже отбрасывается.
- Остаётся третья триада, поскольку den для этого файла относится к категории «другие». Триада прав по файлу: r--
- Теперь, совмещая эти триады прав мы можем определить, что den может делать с файлом samfile всё, кроме редактирования, поскольку для редактирования триада прав на файл должна быть не менее -wx.
Пример 2. Теперь предположим, что пользователь den не входит в группу admins.
Тогда мы должны выбрать последнюю триаду прав по папке: r-x.
Совмещая триады прав по папке и файлу получаем, что den может лишь читать файл samfile, но ничего более делать с ним не может.
Резюмируя, можно сказать, что эффективные права доступа могут формироваться из разнородных триад: релевантная триада для папки может оказаться групповой, а триада для файла — «для других». Поэтому навскидку не всегда удаётся определить их правильно.
Обратите внимание также на то, что в определении прав доступа участвуют целых три стороны: субъект, владелец:группа папки и владелец:группа файла.
Альтернативный выбор прав в триадах
Пользователь может быть как владельцем объекта, так и входить в его группу. В этих случаях предпочтение отдаётся триаде пользователя, а триада группы игнорируется.
Пример 1. Сможет ли sam удалить файл samfile, если он входит в группу admins?
- Выясняем соответствие триад прав «sam — папка»
- Пользователь sam совпадает с владельцем папки samfolder, но также входит в группу admins. В этом случае следует отдать предпочтение триаде пользователя rwx.
- Выясняем соответствие триад прав «sam — файл»
- Пользователь sam совпадает с владельцем файла samfile и входит в группу sam. Здесь также необходимо выбрать триаду пользователя ---.
Исходя из полученных триад для папки и файла, можно сделать вывод, что пользователь sam не сможет ни прочитать файл, ни отредактировать его, но сможет удалить, переименовать или переместить.
Каким образом сделать файл редактируемым и читабельным для пользователя sam? Он был бы таковым, если бы «победила» групповая триада rw-. Очевидно, чтобы групповая триада «сработала», достаточно просто поменять владельца файла, тогда первая триада перестанет быть релевантной пользователю sam и отпадёт сама собой. В самом деле, сменив владельца файла на любого другого, например, root, можно убедиться в том, что файл стал для sam-а читабельным и редактируемым.
Определение прав доступа для папок
Права доступа к папкам выглядят аналогично, только эффективные права образуются триадами родительской (вверху) и целевой (внизу) папки.
Операции редактирования содержимого для папок как такового нет, поэтому эта строка опущена.
Наиболее тривиально определяются права на корневые папки, поскольку для них нет родительских.
Стоит также отметить, что удаление папки предполагает сперва удаление всех вложенных в неё объектов, а потом и её самой. Связано это с тем, что каждая вложенная папка первого уровня создаёт жёсткую ссылку на родительскую папку, а, как известно, чтобы удалить файл, на который сделано несколько жёстких ссылок, нужно сначала удалить все эти ссылки.
Важно понимать, что права на папки в Linux не наследуются. Это значит, что если вы не имеете доступа в некоторую папку, то это не запрещает доступа в подпапку этой папки, если для вложенной папки выставлены соответствующие права.
Расширение прав доступа в Linux с помощью Posix ACL
Списки доступа согласно стандартам Posix позволяют явным образом переопределить права на любой объект для любого пользователя и, фактически, подменяют собой функционал традиционной системы прав Linux. Они позволяют сделать с правами на объекты практически всё, что не удаётся сделать путём традиционных манипуляций с включением пользователей в разные группы и перетасовкой их триад прав.
Вы можете ознакомиться с примером применения Posix ACL для решения конкретной задачи.