GETGROUPLIST(3) Руководство программиста Linux 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)

2019-03-06 GNU