Приложение может также определить предельное значение NGROUPS_MAX в ходе своего выполнения следующими способами:
• вызвать sysconf(_SC_NGROUPS_MAX) (использование sysconf() рассматривается в разделе 11.2);
• считать ограничение из предназначенного только для чтения и характерного только для Linux файла /proc/sys/kernel/ngroups_max. Этот файл предоставляется ядрами, начиная с версии 2.6.4.
Кроме этого, приложение может выполнить вызов getgroups(), указав в качестве аргумента gidsetsize значение 0. В этом случае grouplist не изменяется, но возвращаемое вызовом значение содержит количество групп, в которые входит процесс.
Значение, полученное любым из этих способов, применяемых в ходе выполнения приложения, может затем использоваться для динамического выделения памяти под массив grouplist с целью последующего вызова getgroups().
Привилегированный процесс может изменить свой набор дополнительных групповых идентификаторов, выполнив setgroups() и initgroups().
#define _BSD_SOURCE
#include
int setgroups(size_t
int initgroups(const char *
Оба возвращают при успешном завершении 0, а при ошибке —1
Системный вызов setgroups() может заменить дополнительные групповые идентификаторы вызывающего процесса набором, заданным в массиве grouplist. Количество групповых идентификаторов в массиве аргумента grouplist указывается в аргументе gidsetsize.
Функция initgroups() инициализирует дополнительные групповые идентификаторы вызывающего процесса путем сканирования файла /etc/group и создания списка групп, в которые входит указанный пользователь. Кроме того, к набору дополнительных групповых идентификаторов процесса добавляется групповой идентификатор, указанный в аргументе group.
В основном initgroups() используется программами, создающими сеансы входа в систему. Например login(1) устанавливает различные атрибуты процесса перед запуском оболочки входа пользователя в систему. Такие программы обычно получают значение, используемое для аргумента group, путем считывания поля идентификатора группы из пользовательской записи в файле паролей. Это создает небольшую путаницу, поскольку идентификатор группы из файла паролей на самом деле не относится к дополнительным групповым идентификаторам, но, как бы то ни было, initgroups() именно так обычно и применяется.
Хотя в SUSv3 системные вызовы setgroups() и initgroups() не фигурируют, они доступны во всех реализациях UNIX.
9.7.4. Сводный обзор вызовов, предназначенных для изменения идентификаторов процесса
В табл. 9.1 дается сводная информация о действиях различных системных вызовов и библиотечных функций, используемых для изменения идентификаторов и полномочий процесса.
Таблица 9.1. Сводные данные по интерфейсам, используемым для изменения идентификаторов процесса
Интерфейс
Назначение и действие в:
Портируемость
Непривилегированном процессе
Привилегированном процессе
setuid(u)
setgid(g)
Изменение действующего ID на такое же значение, что и у текущего реального или сохраненного установленного ID
Изменение реального, действующего и сохраненного установленного ID на любое (единое) значение
Вызовы указываются в SUSv3; у вызовов, берущих происхождение от BSD, другая семантика
seteuid(e)
setegid(e)
Изменение действующего ID на такое же значение, что и у текущего реального или сохраненного установленного ID
Изменение действующего ID на любое значение
Вызовы указываются в SUSv3
setreuid(r, e)
setregid(r, e)
(Независимое) изменение реального ID на такое же значение, что и у текущего реального или действующего ID, и действующего ID на такое же значение, что у текущего реального, действующего или сохраненного установленного ID
(Независимое) изменение реального и действующего ID на любое значение
Вызовы указываются в SUSv3, но в различных реализациях работают по-разному
setresuid(r, e, s)
setresgid(r, e, s)
Изменение ID файловой системы на то же значение, что и у текущего реального, действительного, сохраненного установленного ID или ID файловой системы
Изменение ID файловой системы на любое значение
Вызовы характерны только для Linux
setgroups(n, l)
Этот системный вызов не может быть сделан из непривилегированных процессов
Установка для дополнительных групповых ID любых значений
Этот системный вызов в SUSv3 не фигурирует, но доступен во всех реализациях UNIX
На рис. 9.1 представлен графический обзор той же информации, которая приводится в табл. 9.1. Отображенная на схеме информация касается вызовов, изменяющих пользовательские идентификаторы, но к изменениям групповых идентификаторов применяются точно такие же правила. Обратите внимание на следующую информацию, дополняющую сведения, изложенные в табл. 9.1.