GETGROUPLIST(3)

ИМЯ
getgrouplist - возвращает список групп, в которые входит пользователь

ОБЗОР
#include <grp.h>

int getgrouplist(const char *user, gid_t group,
gid_t *groups, int *ngroups);

Требования макроса тестирования свойств для glibc (см. feature_test_macros(7)):

getgrouplist():
    начиная с glibc 2.19:
        _DEFAULT_SOURCE
    в glibc 2.19 и старее:
        _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);
    }

СМОТРИТЕ ТАКЖЕ
getgroups(2), setgroups(2), getgrent(3), group_member(3), group(5), passwd(5)