Дополнительные групповые идентификаторы представляют собой набор дополнительных групп, которым принадлежит процесс. Новый процесс наследует эти идентификаторы от своего родительского процесса. Оболочка входа в систему получает свои дополнительные идентификаторы групп из файла групп системы. Как уже ранее отмечалось, эти идентификаторы используются в совокупности с действующими идентификаторами и идентификаторами файловой системы для определения полномочий по доступу к файлам, 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.
Извлечение реальных и действующих идентификаторов
Системные вызовы getuid() и getgid() возвращают соответственно реальный пользовательский идентификатор и реальный идентификатор группы вызывающего процесса. Системные вызовы geteuid() и getegid() выполняют соответствующие задачи для действующих идентификаторов. Эти системные вызовы всегда завершаются успешно.
#include
uid_t getuid(void);
Возвращает реальный идентификатор пользователя вызывающего процесса
uid_t geteuid(void);
Возвращает действительный идентификатор пользователя вызывающего процесса
gid_t getgid(void);
Возвращает реальный идентификатор группы вызывающего процесса
gid_t getegid(void);
Возвращает действующий идентификатор группы вызывающего процесса
Изменение действующих идентификаторов
Системный вызов setuid() изменяет действующий идентификатор пользователя, и, возможно, реальный ID пользователя и сохраненный установленный ID пользователя вызывающего процесса, присваивая значение, заданное его аргументом uid. Системный вызов setgid() выполняет аналогичную задачу для соответствующих идентификаторов группы.
#include
int setuid(uid_t
int setgid(gid_t
Оба возвращают 0 при успешном завершении и –1 — при ошибке
Правила, согласно которым процесс может вносить изменения в свои полномочия с помощью setuid() и setgid(), зависят от того, привилегированный ли он (то есть имеет ли он действующий пользовательский идентификатор, равный 0). К системному вызову setuid() применяются следующие правила.