Эта функция делает для эффективного ID группы то, что seteuid()
делает для эффективного ID пользователя.
Следующий набор функций предлагает первоначальный API Unix для изменения действительных и эффективных UID и GID. В модели POSIX эти функции являются тем. что должна использовать программа с setuid-root для постоянного изменения действительного или эффективного UID:
int setuid(uid_t uid)
Для обычного пользователя эта функция также устанавливает лишь эффективный UID. Как и для seteuid()
, значением эффективного UID может быть любое из текущих значений действительного, эффективного иди сохраненного set-user ID. Изменение не постоянно; эффективный UID может быть изменен последующим вызовом на другое значение (из того же исходного набора).
Однако, для root
эта функция устанавливает в данное значение все три значения для действительного, эффективного и сохраненного set-user ID. Более того, изменение постоянно; прежнее ID нельзя восстановить. (Это имеет смысл: раз изменился сохраненный set-user ID, нет другого ID для восстановления.)
int setgid(gid_t gid)
Эта функция делает для эффективного ID группы то же, что setuid()
делает для эффективного ID пользователя. Используется то же разграничение между обычными пользователями и root
.
ЗАМЕЧАНИЕ. Возможность изменения ID группы зависит от эффективного ID пользователя. Эффективный GID, равный 0, не имеет особых привилегий.
Наконец, POSIX представляет для исторической совместимости две функции из BSD 4.2. В новом коде их лучше не использовать. Однако, поскольку вы, вероятно, увидите использующий эти функции старый код, мы их здесь опишем.
int setreuid(uid_t ruid, uid_t euid)
Устанавливает данные значения в качестве действительного и эффективного UID. Значение -1 для ruid
или euid
оставляет соответствующие ID без изменения. (Это похоже на chown()
; см. раздел 5.5.1 «Смена владельца файла: chown()
, fchown()
и lchown()
».)
root
может устанавливать в качестве действительного и эффективного ID любое значение. В соответствии с POSIX пользователи, не являющиеся root
, могут изменять лишь эффективный ID; то, что случится, если обычный пользователь попытается изменить действительный UID, «не определено». Однако, справочная страница GNU/Linux
int setregid(gid_t rgid, gid_t egid)
Делает для действительных и эффективных ID групп то же, что setreuid()
делает для действительных и эффективных ID пользователя. Используется то же разграничение между обычными пользователями и root
.
Сохраненный set-user ID в модели BSD не существует, поэтому лежащей в основе setreuid()
и setregid()
идеей было упростить переключение между действительным и эффективным ID:
setreuid(geteuid(), getuid()); /* обмен действительным и эффективным */
Однако, с принятием POSIX модели сохранения set-user ID и функций seteuid()
и setegid()
функции BSD не следует использовать в новом коде. Даже документация BSD 4.4 помечает эти функции как устаревшие, рекомендуя вместо них seteuid()
/setuid()
и setegid()
/setgid()
.
11.6.3. Использование битов setuid и setgid
Есть важные случаи, в которых действующая как root
программа должна login
, которую вы используете (либо непосредственно, либо удаленно) каждый раз при регистрации в системе GNU/Linux или Unix. Имеется иерархия программ, как очерчено на рис. 11.1.
Рис. 11.1. От init
через getty
через login
к shell
Код для login
слишком сложен, чтобы показать здесь, поскольку он имеет дело с рядом задач, не имеющих отношения к текущему обсуждению. Но мы можем очертить шаги, которые происходят во время регистрации, следующим образом:
1. init
является самым первым процессом. Его PID равен 1. Все другие процессы являются его потомками. Ядро вручную создает процесс 1 во время загрузки и запускает в нем init
. Он действует с действительным и эффективным UID, равными нулю, т.е. как root
.