10.2.3. Идентификатор uid файловой системы
В очень специальных случаях программе может понадобиться сохранять свои права root для всего, кроме доступа к файловой системе, при котором она использует пользовательский uid. Изначально использовавшийся в Linux NFS-сервер пространства пользователя может служить иллюстрацией проблемы, которая возникает, когда процесс предполагает применение пользовательского uid. Хотя NFS-сервер в прошлом применял setreuid()
для переключения uid при доступе к файловой системе, такое поведение позволяло пользователю, чей uid совпадает с uid NFS-сервера, уничтожать NFS-сервер. В конечном итоге, пользователь получал владение процессом NFS-сервера. Чтобы предотвратить проблемы подобного рода, Linux использует uid файловой системы(fsuid) для контроля доступа к файловой системе.
Всякий раз когда изменяется эффективный uid процесса, его fsuid устанавливается равным новому эффективному идентификатору пользователя, что делает fsuid прозрачным для большинства приложений. Те приложения, которые нуждаются в дополнительных возможностях, предоставляемых отличающимся значением fsuid, должны применять вызов setfsuid()
для явной установки fsuid.
int setfsuid(uid_t uid);
Значение fsuid может быть установлено равным текущим эффективному, сохраненному или действительному идентификаторам пользователя. В дополнение следует сказать, что setfsuid()
выполняется успешно, если fsuid остается неизменным или эффективный uid процесса равен 0.
10.2.4. Резюме по идентификаторам пользователей и групп
Подведем итоги обо всех системных вызовах, которые модифицируют права доступа выполняющегося процесса. Большинство перечисленных здесь функций, имеющих отношение к идентификаторам пользователей, уже детально рассматривались в настоящей главе, но те, что относятся к группам — еще нет. Поскольку эти функции отражают соответствующие функции, модифицирующие идентификаторы пользователя, их поведение должно быть понятно.
Все эти функции возвращают -1
в случае ошибки и 0
— в случае успеха, если только не указано иначе. Большинство их прототипов находятся в . Те, что расположены где-то еще, отмечены ниже.
int setreuid(uid_t ruid, uid_t euid); |
Устанавливает действительный uid текущего процесса в ruid и эффективный uid процесса в euid . Если оба параметра равны -1 , то uid остаются неизменными. |
int setregid(gid_t rgid, gid_t egid); |
Устанавливает действительный gid текущего процесса в rgid и эффективный gid процесса в egid. Если оба параметра равны -1 , то gid остаются неизменными. |
int setuid(uid t uid); |
Если применяется обычным пользователем, то устанавливает эффективный uid текущего процесса в значение параметра uid . Если используется процессом с эффективным uid, равным 0, то устанавливает действительный, эффективный и сохраненный uid в значение параметра uid . |
int setgid(gid_t gid); |
Если применяется обычным пользователем, то устанавливает эффективный gid текущего процесса в значение параметра gid . Если используется процессом с эффективным gid, равным 0, то устанавливает действительный, эффективный и сохраненный gid в значение параметра gid . |
int seteuid(uid_t uid); |
Эквивалент setreuid(-1, uid) . |
int setegid(gid_t gid); |
Эквивалент setregid(-1, gid) . |
int setfsuid(uid_t fsuid); |
Устанавливает fsuid текущего процесса в значение параметра fsuid . Прототип находится в . Возвращает предшествующий fsuid. |
int setfsgid(gid_t fsgid); |
Устанавливает fsgid текущего процесса в значение параметра fsgid . Прототип находится в . Возвращает предшествующий fsgid. |
int setgroups(size_t num, const gid_t * list); |
Устанавливает дополнительные группы текущего процесса из списка, переданного в массиве list , который должен содержать num элементов. Макрос SC_NGROUPS_MAX указывает, сколько групп может быть в списке (от 32 до 65536, в зависимости от работающей у вас версии Linux). |
uid_t getuid(); |
Возвращает действительный uid процесса. |
uid_t geteuid(); |
Возвращает эффективный uid процесса. |
gid_t getgid(); |
Возвращает действительный gid процесса. |
gid_t getegid(); |
Возвращает эффективный gid процесса. |
size_t getgroups (size_t size, gid_t list[]); |
Возвращает текущий набор дополнительных групп процесса в массиве list . Параметр size сообщает, сколько элементов типа gid_t может содержать list . Если размер list недостаточен, чтобы вместить все группы, возвращается -1 , а errno устанавливается в EINVAL . В противном случае возвращается фактическое количество групп в list . Если size равен 0 , возвращается количество групп, но list не затрагивается. Прототип функции getgroups() находится в . |
10.3. Информация о процессе
Читать дальше