Читать книгу 📗 "Linux программирование в примерах - Роббинс Арнольд"
#include <grp.h>int setgroups(size_t size, const gid_t *list);Параметр
sizelistВ отличие от функций для манипулирования значениями действительных и эффективных UID и GID, эту функцию может вызвать лишь процесс, действующий как
rootsetgroups()/bin/login/bin/sshdssh11.6.2. Изменение действительного и эффективного ID
Работа с двумя различными ID пользователей представляет для программиста приложения проблему. Могут быть вещи, которые программе нужно сделать, работая с эффективным UID, а другие вещи — работая с действительным UID.
Например, до того, как в системах Unix появилось управление заданиями, многие программы предоставляли переходы в оболочку, т.е. способ запуска команды или интерактивной оболочки из текущей программы. Хорошим примером этого является редактор
ed!!shТаким образом, имеется явная потребность в возможности замены эффективного UID действительным UID. Более того, полезна возможность обратного переключения эффективного UID на первоначальный. (В этом причина необходимости наличия сохраненного set-user ID; появляется возможность восстановления первоначальных привилегий, которые были у процесса при его запуске.)
Как и для множества Unix API, различные системы решили проблему разными способами, иногда с использованием одного и того же API, но с другой семантикой, а иногда введением другого API. Погружение в исторические подробности годится лишь для создания головной боли, поэтому мы не будем с этим беспокоиться. Вместо этого мы рассмотрим, что предоставляет POSIX и как работает каждый API. Более того, наше обсуждение фокусируется на значениях действительных и эффективных UID; значения GID работают аналогичным образом, поэтому мы не будем хлопотать с повторением подробностей для этих системных вызовов. Функции следующие:
#include <sys/types.h> /* POSIX */#include <unistd.h>int seteuid(uid_t euid); /* Установка эффективного ID */int setegid(gid_t egid);int setuid(uid_t uid); /* Установка эффективного ID, root устанавливает все */int setgid(gid_t gid);int setreuid(uid_t ruid, uid_t euid); /* Совместимость с BSD, устанавливаются оба */int setregid(gid_t rgid, gid_t egid);Есть три набора функций. Первые два были созданы POSIX:
int seteuid(uid_t euid)Эта функция устанавливает лишь эффективный UID. Обычный пользователь (не
rootПроцесс с эффективным UID, равным нулю, может установить в качестве эффективного UID любое значение. Поскольку в качестве значения эффективного UID можно установить также сохраненный set-user ID, процесс может восстановить свои привилегии root с помощью другого вызова
seteuid()int setegid(gid_t egid)Эта функция делает для эффективного ID группы то, что
seteuid()Следующий набор функций предлагает первоначальный API Unix для изменения действительных и эффективных UID и GID. В модели POSIX эти функции являются тем. что должна использовать программа с setuid-root для постоянного изменения действительного или эффективного UID:
int setuid(uid_t uid)Для обычного пользователя эта функция также устанавливает лишь эффективный UID. Как и для
seteuid()Однако, для
rootint setgid(gid_t gid)Эта функция делает для эффективного ID группы то же, что
setuid()rootЗАМЕЧАНИЕ. Возможность изменения ID группы зависит от эффективного ID пользователя. Эффективный GID, равный 0, не имеет особых привилегий.
Наконец, POSIX представляет для исторической совместимости две функции из BSD 4.2. В новом коде их лучше не использовать. Однако, поскольку вы, вероятно, увидите использующий эти функции старый код, мы их здесь опишем.
int setreuid(uid_t ruid, uid_t euid)Устанавливает данные значения в качестве действительного и эффективного UID. Значение -1 для
ruideuidchown()chown()fchown()lchown()rootroot