setuid -
устанавливает
идентификатор
пользователя
Standard C library (
libc,
-lc)
#include <unistd.h>
int setuid(uid_t uid);
Вызов
setuid()
устанавливает
эффективный
идентификатор
пользователя
вызвавшего
процесса.
Если
вызывающий
процесс
имеет
права
(мандат
CAP_SETUID в
своём
пространстве
имён
пользователя),
то также
устанавливаются
действительный
и
сохраненный
идентификаторы
пользователя.
В Linux
setuid()
реализован
как и в
стандарте POSIX
с
возможностью
_POSIX_SAVED_IDS. Это
позволяет
setuid-программам
(не setuid-root)
сбрасывать
все
привилегии,
делать
непривилегированную
работу, а
затем
безопасным
путём
возвращать
себе
исходный
эффективный
идентификатор
пользователя.
Если
пользователь
root или
программа
установлена
как setuid root, при
работе
требуется
особая
осторожность:
функция
setuid()
проверяет
эффективный
идентификатор
вызвавшего
пользователя
и, если это
суперпользователь,
то все
устанавливаемые
значения
идентификаторов
равны
uid.
После
этого
программа
уже
никаким
образом не
сможет
вернуть
права
пользователя
root.
Таким
образом,
программа,
принадлежащая
root и с
установленным
битом setuid,
собирающаяся
временно
сбросить
права root и
поработать
с правами
непривилегированного
пользователя,
а затем
восстановить
права root, не
сможет
использовать
setuid().
Требуемого
результата
можно
достичь с
помощью
вызова
seteuid(2).
On success, zero is returned. On error, -1 is returned, and
errno is set
to indicate the error.
Замечание:
есть
случаи,
когда
setuid()
может
завершиться
с ошибкой
даже когда UID
вызывающего
равен 0; это
серьёзная
ошибка
безопасности
— не
проверять
возвращаемое
значение
setuid().
- EAGAIN
- Вызов
изменил бы
настоящего
реальный UID
вызывающего
(т. е. uid не
совпадает
с реальным
UID
вызывающего),
но
возникла
временная
ошибка при
выделении
памяти под
необходимые
структуры
ядра.
- EAGAIN
- Значение
uid не
совпадает
с реальным
UID
вызывающего
и этот
вызов
создал был
превышение
количества
процессов,
принадлежащих
пользователю
с реальным
ID ruid сверх
ограничителя
ресурсы
RLIMIT_NPROC
вызывающего.
Начиная с Linux
3.1 эта
ошибка
больше не
возникает
(но
корректное
приложение
должно
проверять
эту
ошибку);
смотрите
описание
EAGAIN в execve(2).
- EINVAL
- Идентификатор
пользователя,
заданный в
uid,
некорректен
в этом
пользовательском
пространстве
имён.
- EPERM
- Пользователь
не
является
суперпользователем
(Linux: нет
мандата CAP_SETUID
в
пользовательском
пространстве
имён), а uid не
совпадает
с
действительным
или
сохранённым
идентификатором
пользователя
вызывающего
процесса.
POSIX.1-2001, POSIX.1-2008, SVr4. Этот
системный
вызов не
полностью
совместим
с 4.4BSD, который
устанавливает
действительный,
эффективный
и
сохранённый
идентификаторы
пользователя.
Linux
поддерживает
идентификатор
пользователя
файловой
системы,
обычно
совпадающий
с
эффективным
идентификатором.
Системный
вызов
setuid()
также
устанавливает
идентификатор
пользователя
файловой
системы
вызывающего
процесса.
См.
setfsuid(2).
Если
uid
отличается
от старого
эффективного
идентификатора,
то
процессу
нельзя
будет
создавать
core-файлы.
Первоначальная
версия
системного
вызова
setuid() в
Linux
поддерживала
только
16-битные
идентификаторы
пользователя.
Позднее в Linux 2.4
был
добавлен
вызов
setuid32(),
поддерживающий
32-битные
идентификаторы.
В glibc
обёрточная
функция
setuid()
работает
одинаково
вне
зависимости
от версий
ядра.
На уровне
ядра ID
пользователя
и группы
являются
атрибутами
нити.
Однако в POSIX
требуется,
чтобы все
нити в
процессе
имели
одинаковые
права. В
реализации
нитей NPTL
требования
POSIX
реализованы
через
обёрточные
функции
для
различных
системных
вызовов,
которые
изменяют UID и
GID процесса. В
этих
функциях
(включая и
setuid())
используется
алгоритмы
на основе
сигналов,
которые
следят за
тем, что
когда у
одной нити
изменяются
права, эти
изменения
выполняются
и для
остальных
нитей
процесса.
Подробное
описание
смотрите в
nptl(7).
getuid(2),
seteuid(2),
setfsuid(2),
setreuid(2),
capabilities(7),
credentials(7),
user_namespaces(7)
Русский
перевод
этой
страницы
руководства
был сделан
Alexander Golubev <
[email protected]>, Azamat Hackimov
<
[email protected]>, Hotellook, Nikita
<
[email protected]>, Spiros Georgaras <
[email protected]>, Vladislav
<
[email protected]>, Yuri Kozlov <
[email protected]>
и Иван
Павлов <
[email protected]>
Этот
перевод
является
бесплатной
документацией;
прочитайте
Стандартную
общественную
лицензию GNU
версии 3
или более
позднюю,
чтобы
узнать об
условиях
авторского
права. Мы не
несем
НИКАКОЙ
ОТВЕТСТВЕННОСТИ.
Если вы
обнаружите
ошибки в
переводе
этой
страницы
руководства,
пожалуйста,
отправьте
электронное
письмо на
[email protected]