Начиная с версии ядра 2.0, в Linux приняты установленные SUSv3 правила относительно разрешений на отправку сигналов. Эти правила не касаются действующего ID пользователя целевого процесса (см. раздел 20.5). Таким образом, наличие идентификатора файловой системы утратило свою актуальность (теперь процесс может удовлетворить возникающие потребности, изменив значение действующего пользовательского ID на ID привилегированного пользователя (и обратно) путем разумного применения системных вызовов, рассматриваемых далее в этой главе). Но эта возможность по-прежнему предусмотрена для сохранения совместимости с существующим программным обеспечением.
Поскольку идентификаторы файловой системы теперь уже считаются некой экзотикой и обычно значения совпадают с соответствующими действующими идентификаторами, во всем остальном тексте книги описания различных проверок полномочий по доступу к файлам, а также установок прав на владение новыми файлами будут даваться в понятиях действующих пользовательских ID процесса. Хотя в Linux по-прежнему для этих целей реально используются принадлежащие процессу идентификаторы файловой системы, на практике их наличие редко вносит в действия какую-либо существенную разницу.
Дополнительные групповые идентификаторы представляют собой набор дополнительных групп, которым принадлежит процесс. Новый процесс наследует эти идентификаторы от своего родительского процесса. Оболочка входа в систему получает свои дополнительные идентификаторы групп из файла групп системы. Как уже ранее отмечалось, эти идентификаторы используются в совокупности с действующими идентификаторами и идентификаторами файловой системы для определения полномочий по доступу к файлам, IPC-объектам System V и другим системным ресурсам.
В Linux для извлечения и изменения различных пользовательских и групповых идентификаторов, рассматриваемых в данной главе, предоставляется ряд системных вызовов и библиотечных функций. В SUSv3 определяется только часть этих API. Из оставшихся некоторые широко доступны в иных реализациях UNIX, а другие характерны только для Linux. По мере рассмотрения каждого интерфейса мы также будем обращать внимание на вопросы портируемости. Ближе к концу главы в табл. 9.1 мы перечислим операции всех интерфейсов, используемых для изменения идентификаторов процессов.
В качестве альтернативы применения системных вызовов, описываемых на следующих страницах, идентификаторы любого процесса могут быть определены путем анализа строк Uid, Gid и Groups, предоставляемых Linux-файлом /proc/PID/status. В строках Uid и Gid перечисляются идентификаторы в следующем порядке: реальный, действующий, сохраненный установленный и идентификатор файловой системы.
В следующих разделах будет использоваться традиционное определение привилегированного процесса как одного из процессов, чей действительный идентификатор пользователя имеет значение 0. Но, как описывается в главе 39, в Linux понятие полномочий привилегированного пользователя разбивается на отдельные составляющие. К рассмотрению нашего вопроса относительно всех системных вызовов, применяемых для изменения пользовательских и групповых идентификаторов процесса, имеют отношение две характеристики.
• CAP_SETUID позволяет процессу произвольно менять свои пользовательские идентификаторы.
• CAP_SETGID позволяет процессу произвольно изменять свои групповые идентификаторы.
9.7.1. Извлечение и изменение реальных, действующих и сохраненных установленных идентификаторов
В следующих абзацах мы рассмотрим системные вызовы, извлекающие и изменяющие реальные, действующие и сохраненные установленные идентификаторы. Существует несколько системных вызовов, выполняющих эти задачи, и в некоторых случаях их функциональные возможности перекрываются, отражая тот факт, что различные системные вызовы произошли от разных реализаций UNIX.