• Имеющиеся в glibc реализации seteuid() и setegid() также позволяют устанавливать для действующего идентификатора такое же значение, какое у него и было, но эта особенность в SUSv3 не упоминается.
• Если при вызовах setreuid() и setregid() как привилегированными, так и непривилегированными процессами, до осуществления вызовов значение r (реального идентификатора) не равно –1 или для e (действующего идентификатора) указано значение, отличное от значения реального идентификатора, то сохраненный установленный пользовательский или сохраненный установленный групповой ID также устанавливаются на то же значение, что и у нового действующего идентификатора. (В SUSv3 не указано, что setreuid() и setregid() вносят изменения в сохраненные установленные ID.)
• Когда изменяется действующий пользовательский (групповой) идентификатор, характерный для Linux пользовательский (групповой) идентификатор файловой системы изменяется, принимая то же самое значение.
• Вызовы setresuid() всегда изменяют пользовательский идентификатор файловой системы, присваивая ему такое же значение, что и у действующего пользовательского ID, независимо от того, изменяется ли вызовом действующий пользовательский идентификатор. Вызовы setresgid() делают то же самое в отношении групповых идентификаторов файловой системы.
Рис. 9.1.
9.7.5. Пример: вывод на экран идентификаторов процесса
Программа, показанная в листинге 9.1, использует системные вызовы и библиотечные функции, рассмотренные на предыдущих страницах, для извлечения всех пользовательских и групповых идентификаторов процесса и вывода их на экран.
Листинг 9.1. Отображение на экране всех пользовательских и групповых идентификаторов процесса
proccred/idshow.c
#define _GNU_SOURCE
#include
#include
#include
#include "ugid_functions.h" /* userNameFromId() и groupNameFromId() */
#include "tlpi_hdr.h"
#define SG_SIZE (NGROUPS_MAX + 1)
int
main(int argc, char *argv[])
{
uid_t ruid, euid, suid, fsuid;
gid_t rgid, egid, sgid, fsgid;
gid_t suppGroups[SG_SIZE];
int numGroups, j;
char *p;
if (getresuid(&ruid, &euid, &suid) == -1)
errExit("getresuid");
if (getresgid(&rgid, &egid, &sgid) == -1)
errExit("getresgid");
/* Попытки изменения идентификаторов файловой системы для непривилегированных
процессов всегда игнорируются, но даже при этом следующие вызовы
возвращают текущие идентификаторы файловой системы */
fsuid = setfsuid(0);
fsgid = setfsgid(0);
printf("UID: ");
p = userNameFromId(ruid);
printf("real=%s (%ld); ", (p == NULL)?"???": p, (long) ruid);
p = userNameFromId(euid);
printf("eff=%s (%ld); ", (p == NULL)?"???": p, (long) euid);
p = userNameFromId(suid);
printf("saved=%s (%ld); ", (p == NULL)?"???": p, (long) suid);
p = userNameFromId(fsuid);
printf("fs=%s (%ld); ", (p == NULL)?"???": p, (long) fsuid);
printf("\n");
printf("GID: ");
p = groupNameFromId(rgid);
printf("real=%s (%ld); ", (p == NULL)?"???": p, (long) rgid);
p = groupNameFromId(egid);
printf("eff=%s (%ld); ", (p == NULL)?"???": p, (long) egid);
p = groupNameFromId(sgid);
printf("saved=%s (%ld); ", (p == NULL)?"???": p, (long) sgid);
p = groupNameFromId(fsgid);
printf("fs=%s (%ld); ", (p == NULL)?"???": p, (long) fsgid);
printf("\n");
numGroups = getgroups(SG_SIZE, suppGroups);
if (numGroups == -1)
errExit("getgroups");
printf("Supplementary groups (%d): ", numGroups);
for (j = 0; j < numGroups; j++) {
p = groupNameFromId(suppGroups[j]);
printf("%s (%ld) ", (p == NULL)?"???": p, (long) suppGroups[j]);
}
printf("\n");
exit(EXIT_SUCCESS);
}
proccred/idshow.c
У каждого процесса имеется несколько пользовательских и групповых идентификаторов. Реальные идентификаторы определяют принадлежность процесса. В большинстве реализаций UNIX для определения полномочий процесса при доступе к таким ресурсам, как файлы, применяются действующие идентификаторы. Но в Linux для определения полномочий доступа к файлам используются идентификаторы файловой системы, а действующие идентификаторы предназначены для проверки других полномочий. (Поскольку идентификаторы файловой системы обычно имеют такие же значения, как и соответствующие действующие идентификаторы, Linux при проверке полномочий доступа к файлам ведет себя точно так же, как и другие реализации UNIX.) Права доступа процесса также определяются с помощью дополнительных групповых идентификаторов — набора групп, в которые входит данный процесс. Извлекать и изменять его пользовательские и групповые ID процессу позволяют различные системные вызовы и библиотечные функции.