Обычно действующие идентификаторы пользователя и группы имеют точно такие же значения, что и у соответствующих реальных ID, но есть два способа, позволяющие действующим идентификаторам принимать другие значения. Один из способов связан с использованием системных вызовов (рассматриваются в разделе 9.7). Второй способ связан с выполнением программ с установленным идентификатором пользователя и установленным идентификатором группы.
Программа с установленным идентификатором пользователя позволяет процессу получить полномочия, которые он обычно не получает, путем установки действующего ID пользователя на то же значение, которое имеется у идентификатора пользователя (владельца) исполняемого файла. Программа с установленным ID группы выполняет аналогичную задачу для принадлежащего процессу действующего идентификатора группы. (Выражения
Как и любой другой файл, файл исполняемой программы имеет связанный с ним идентификатор пользователя и идентификатор группы, которые определяют принадлежность файла. Кроме того, у исполняемого файла имеется два специальных бита полномочий: бит установленного идентификатора пользователя (set-user-ID) и бит установленного идентификатора группы (set-group-ID). (В действительности эти два бита полномочий есть у каждого файла, но нас здесь интересует их использование применительно к исполняемым файлам.) Эти биты полномочий устанавливаются командой chmod. Непривилегированный пользователь может устанавливать эти биты для тех файлов, которыми он владеет. Привилегированный пользователь (CAP_FOWNER) может устанавливать эти биты для любого файла. Рассмотрим пример:
$ su
Password:
# ls — l prog
— rwxr-xr-x 1 root root 302585 Jun 26 15:05 prog
# chmod u+s prog
# chmod g+s prog
Как показано в этом примере, у программы могут быть установлены оба этих бита, хотя такое встречается нечасто. Когда для вывода списка полномочий программы, имеющей установленный бит set-user-ID или set-group-ID, используется команда ls — l, в нем буква x, которая обычно применяется для демонстрации установки полномочия на выполнение, заменяется буквой s:
# ls — l prog
— rwsr-sr-x 1 root root 302585 Jun 26 15:05 prog
Когда set-user-ID-программа запускается (то есть загружается в память процесса с помощью команды exec()), ядро устанавливает для действующего пользовательского ID точно такое же значение, что и у пользовательского ID исполняемого файла. Запуск программы с полномочиями setgid имеет такой же эффект относительно действующего группового идентификатора процесса. Изменение действующего пользовательского или группового ID таким способом дает процессу (а иными словами, пользователю, для которого выполняется программа) полномочия, которые он не имел бы при других обстоятельствах. Например, если исполняемый файл принадлежит пользователю по имени root (привилегированному пользователю) и имеет установленный бит set-user-ID, то процесс при запуске программы обретает полномочия суперпользователя.
Программы с полномочиями setuid и setgid могут также использоваться с целью смены действующих идентификаторов процесса на какие-либо другие, отличные от root. Например, чтобы предоставить доступ к защищенному файлу (или к другому системному ресурсу), может быть достаточно создать специально предназначенный для этого ID пользователя (группы) с полномочиями, требуемыми для доступа к файлу, и создать программу с полномочиями setuid (setgid), изменяющую действующий пользовательский (групповой) ID на этот идентификатор. Это даст программе полномочия по доступу к файлу без предоставления ей всех полномочий привилегированного пользователя.
Иногда мы будем использовать выражение set-user-ID-root, чтобы отличать set-user-ID-программу, владельцем которой является root, от программы, которой владеет другой пользователь и которая просто дает процессу полномочия, предоставляемые этому пользователю.