# 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, от программы, которой владеет другой пользователь и которая просто дает процессу полномочия, предоставляемые этому пользователю.
Теперь мы станем употреблять слово «привилегированный» в двух разных смыслах. Первый мы определили ранее: это процесс с действующим идентификатором пользователя со значением 0, у которого имеются все полномочия, присущие пользователю по имени root. Но, когда речь заходит о set-user-ID-программе, владельцем которой является другой, не root-пользователь, то мы называем процесс наделенным полномочиями, соответствующими идентификатору пользователя set-user-ID-программы. Какой именно смысл вкладывается в понятие «привилегированный», в каждом случае будет понятно из контекста.
По причинам, объясняемым в разделе 38.3, биты полномочий set-user-ID и set-group-ID не оказывают никакого влияния на используемые в Linux сценарии оболочки.
В качестве примеров часто используемых в Linux set-user-ID-программ можно привести passwd(1), изменяющую пользовательский пароль, mount(8) и umount(8), которые занимаются монтированием и размонтированием файловых систем, и su(1), которая позволяет пользователю запускать оболочку под различными UID. В качестве примера программы с полномочиями setgid можно привести wall(1), которая записывает сообщение на все терминалы, владельцами которых является группа tty (обычно она является владельцем каждого терминала).
В разделе 8.5 уже отмечалось, что программа из листинга 8.2 должна быть запущена под учетной записью root, чтобы получить доступ к файлу /etc/shadow. Эту программу можно сделать запускаемой любым пользователем, назначив ее set-user-ID-root-программой:
$ su
Password:
# chown root check_password Закрепление владения этой программой за root
# chmod u+s check_password С установленным битом set-user-ID
# ls — l check_password
— rwsr-xr-x 1 root users 18150 Oct 28 10:49 check_password
# exit
$ whoami Это непривилегированный пользователь
mtk
$ ./check_password Но теперь мы можем получить доступ к файлу
Username: avr теневых паролей, используя эту программу
Password:
Successfully authenticated: UID=1001
Технология set-user-ID/set-group-ID является полезным и эффективным средством, но при недостаточно тщательно спроектированных приложениях может создать бреши в системе безопасности. Практические наработки, которых следует придерживаться при написании программ с полномочиями setuid и setgid, перечисляются в главе 38.
Сохраненный установленный идентификатор пользователя (set-user-ID) и сохраненный установленный идентификатор группы (set-group-ID) предназначены для применения с программами с полномочиями setuid и setgid. При выполнении программы наряду со многими другими происходят и следующие действия.