ОБЗОР
#include <grp.h>
int getgrouplist(const char *user, gid_t group,
gid_t *groups, int *ngroups);
Требования макроса тестирования свойств для glibc (см. feature_test_macros(7)):
getgrouplist(): _BSD_SOURCE
ОПИСАНИЕ
Функция getgrouplist() просматривает базу данных групп (смотрите group(5)) для составления списка групп, в которые входит пользователь user. В возвращаемом массиве groups может быть до *ngroups групп.Если в базе данных групп отсутствуют группы, определённые для user, то в список групп, возвращаемый getgrouplist(), включается group; обычно, это аргумент задаётся в виде ID группы из записи пароля user.
Аргумент ngroups является аргументом-результатом: при возврате в нём всегда содержится количество группы, найденных для user включая group; данное значение может быть больше, чем количество групп, хранящихся в groups.
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
Если количество групп, в которых user является членом, меньше или равно *ngroups, то возвращается значение *ngroups.Если пользователь является членом более чем *ngroups групп, то getgrouplist() возвращает -1. В этом случае значение, возвращаемое в *ngroups, можно использовать для подстройки размера буфера, передаваемого в последующий вызов getgrouplist().
ВЕРСИИ
Эта функция доступна в glibc с версии 2.2.4.АТРИБУТЫ
Описание терминов данного раздела смотрите в attributes(7).Интерфейс | Атрибут | Значение |
getgrouplist() | безвредность в нитях | безвредно (MT-Safe locale) |
СООТВЕТСТВИЕ СТАНДАРТАМ
Эта функция является нестандартной; она присутствует в большинстве BSD.ДЕФЕКТЫ
В glibc до версии 2.3.3 в реализации этой функции содержится ошибка переполнения буфера: она возвращает полный список групп для user в массиве groups даже когда количество групп превышает *ngroups.ПРИМЕР
Программа, показанная далее, печатает список групп для пользователя из первого аргумента командной строки. Во втором аргументе задаётся значение ngroups, передаваемое getgrouplist(). Вот примеры работы этой программы:
$ ./a.out cecilia 0 getgrouplist() вернула -1; ngroups = 3 $ ./a.out cecilia 3 ngroups = 3 16 (dialout) 33 (video) 100 (users)
Исходный код программы
#include <stdio.h> #include <stdlib.h> #include <grp.h> #include <pwd.h> int main(int argc, char *argv[]) { int j, ngroups; gid_t *groups; struct passwd *pw; struct group *gr; if (argc != 3) { fprintf(stderr, "Использование: %s <пользователь> <ngroups>\n", argv[0]); exit(EXIT_FAILURE); } ngroups = atoi(argv[2]); groups = malloc(ngroups * sizeof (gid_t)); if (groups == NULL) { perror("malloc"); exit(EXIT_FAILURE); } /* получаем структуру passwd (содержит ID первичной группы пользователя) */ pw = getpwnam(argv[1]); if (pw == NULL) { perror("getpwnam"); exit(EXIT_SUCCESS); } /* получаем список групп */ if (getgrouplist(argv[1], pw->pw_gid, groups, &ngroups) == -1) { fprintf(stderr, "getgrouplist() вернула -1; ngroups = %d\n", ngroups); exit(EXIT_FAILURE); } /* печатаем список полученных групп вместе с именами групп */ fprintf(stderr, "ngroups = %d\n", ngroups); for (j = 0; j < ngroups; j++) { printf("%d", groups[j]); gr = getgrgid(groups[j]); if (gr != NULL) printf(" (%s)", gr->gr_name); printf("\n"); } exit(EXIT_SUCCESS); }