Возможно, вы заметили, что для получения сохраненных значений set-user ID или set-group ID нет вызовов. Это просто первоначальные значения эффективных UID и GID. Таким образом, для получения шести значений в начале программы вы можете использовать код наподобие этого:
uid_t ruid, euid, saved_uid;
gid_t rgid, egid, saved_gid;
int main(int argc, char **argv) {
ruid = getuid();
euid = saved_uid = geteuid();
rgid = getgid();
egid = saved_gid = getegid();
/* ...оставшаяся программа... */
}
Вот пример получения набора групп. В качестве расширения gawk
awk
к значениям действительных и эффективных UID и GID и дополнительному набору групп. Для этого он должен получить набор групп. Следующая функция из main.c
в дистрибутиве gawk
3.1.3:1080 /* init_groupset --- инициализация набора групп */
1081
1082 static void
1083 init_groupset()
1084 {
1085 #if defined(HAVE_GETGROUPS) && defined(NGROUPS_MAX) && NGROUPS_MAX > 0
1086 #ifdef GETGROUPS_NOT_STANDARD
1087 /* Для систем, которые не отвечают стандарту, используйте старый способ */
1088 ngroups = NGROUPS_MAX;
1089 #else
1090 /*
1091 * Если оба аргумента при вызове равны 0, возвращаемое
1092 * значение является общим числом групп.
1093 */
1094 ngroups = getgroups(0, NULL);
1095 #endif
1096 if (ngroups == -1)
1097 fatal(_("could not find groups: %s"), strerror(errno));
1098 else if (ngroups == 0)
1099 return;
1100
1101 /* заполнить группы */
1102 emalloc(groupset, GETGROUPS_T*, ngroups * sizeof(GETGROUPS_T), "init_groupset");
1103
1104 ngroups = getgroups(ngroups, groupset);
1105 if (ngroups == -1)
1106 fatal(_("could not find groups: %s"), strerror(errno));
1107 #endif
1108 }
Переменные ngroups
groupset
глобальные; их объявления не показаны. Макрос GETGROUPS_T
(строка 1102) является типом для использования со вторым аргументом: на системе POSIX это gid_t
, в противном случае int
.Строки 1085 и 1107 заключают в скобки все тело функции; на древних системах, в которых вообще нет наборов групп, тело функции пустое.
Строки 1086–1088 обрабатывают не-POSIX системы; до компиляции программы механизмом конфигурации определяется GETGROUPS_NOT_STANDARD
NGROUPS_MAX
, как описано выше. (Даже а 2004 г. такие системы все еще существуют и используются; хотя, слава богу, число их уменьшается.)Строки 1089–1094 для систем POSIX, причем нулевой параметр size
Строки 1096–1099 осуществляют проверку ошибок. Если возвращаемое значение 0, дополнительных групп нет, поэтому init_groupset()
Наконец, строка 1102 для выделения массива достаточного размера использует malloc()
11.3. Проверка для действительного пользователя: access()
В большинстве случаев значения эффективного и действительного UID и GID являются одними и теми же. Таким образом, не имеет значения, что проверка прав доступа к файлу осуществляется по эффективному ID, а не по действительному.
Однако, при написании приложения с setuid или setgid вы можете иногда захотеть проверить, является ли операция, разрешенная для эффективных UID и GID, также разрешенной для
access()
:#include
int access(const char *path, int amode);
Аргумент path
amode
содержит объединение побитовым ИЛИ одного или нескольких из следующих значений:R_OK
W_OK