getgroups(2)

NAZWA
getgroups, setgroups - pobiera/ustawia listę identyfikatorów grup dodatkowych

BIBLIOTEKA
Standardowa biblioteka C (libc, -lc)

SKŁADNIA
#include <unistd.h>

int getgroups(int size, gid_t list[_Nullable size]);

#include <grp.h>

int setgroups(size_t size, const gid_t list[size]);

    Wymagane ustawienia makr biblioteki glibc (patrz feature_test_macros(7)):

setgroups():
    Od glibc 2.19:
        _DEFAULT_SOURCE
    glibc 2.19 i wcześniejsze:
        _BSD_SOURCE

OPIS
getgroups() zwraca w list identyfikatory grup dodatkowych dla wywołującego procesu. Argument size powinien być ustawiony na maksymalną liczbę elementów, jakie mogą być przechowywane w buforze, na który wskazuje list. Jeśli wywołujący proces jest członkiem więcej niż size grup dodatkowych, wystąpi błąd.

Nie jest określone, czy efektywny ID grupy procesu wywołującego będzie znajdować się na zwróconej liście (zatem aplikacja powinna wywołać również getegid(2) i dodać lub usunąć otrzymaną wartość).

Jeśli size jest równe zero, to list nie jest modyfikowane, lecz zwracana jest ogólna liczba dodatkowych grup procesu. Pozwala to wywołującemu określić rozmiar dynamicznie przydzielanej list, do użycia w kolejnych wywołaniach do getgroups(2).

setgroups() ustawia identyfikatory grup dodatkowych procesu wywołującego. Konieczne są odpowiednie przywileje (zob. opis błędu EPERM poniżej). Argument size określa liczbę identyfikatorów grup dodatkowych w buforze, na który wskazuje list. Proces może porzucić wszystkie swoje grupy dodatkowe poniższym wywołaniem:

    setgroups(0, (gid_t [0]){});

WARTOŚĆ ZWRACANA
Po pomyślnym zakończeniu getgroups() zwraca liczbę grup dodatkowych. Po błędzie zwracane jest -1 i ustawiane errno wskazując błąd.

Po pomyślnym zakończeniu setgroups() zwraca zero. Po błędzie zwracane jest -1 i ustawiane errno wskazując błąd.

BŁĘDY

EFAULT
    list ma nieprawidłowy adres.

getgroups() może dodatkowo zawieść z następującym błędem:

EINVAL
    size jest mniejsze niż liczba grup dodatkowych, ale niezerowe.

setgroups() może dodatkowo zawieść z następującymi błędami:

EINVAL
    size jest większe niż NGROUPS_MAX (32 przed Linuksem 2.6.4; 65536 od Linuksa 2.6.4).

ENOMEM
    Brak pamięci.

EPERM
    Proces wywołujący ma niewystarczające przywileje (wywołujący nie posiada przywileju (ang. capability) CAP_SETGID w przestrzeni nazw użytkownika, w której występuje).

EPERM (od Linuksa 3.19)
    Odmówiono użycia setgroups() w tej przestrzeni nazw użytkownika. Więcej informacji w opisie /proc/pid/setgroups w user_namespaces(7).

WERSJE

  Różnice biblioteki C/jądra
Na poziomie jądra, identyfikatory użytkownika i grupy są atrybutami przynależnymi wątkowi. Jednak POSIX wymaga, aby wszystkie wątki procesu dzieliły te same poświadczenia. Implementacja wątkowania NPTL obsługuje wymagania POSIX za pomocą funkcji opakowujących dla różnych wywołań systemowych zmieniających UID-y i GID-y procesów. Te funkcje opakowujące (w tym te dla setgroups()) wykorzystują technikę opartą na sygnałach aby zapewnić, że gdy jeden wątek zmieni swe poświadczenia, wszystkie inne wątki procesu również to uczynią. Więcej szczegółów w podręczniku nptl(7).

STANDARDY

getgroups()
    POSIX.1-2024.

setgroups()
    Brak.

HISTORIA

getgroups()
    4.3BSD, SVr4, POSIX.1-1988.

setgroups()
    SVr4, 4.3BSD. Ponieważ setgroups() wymaga przywileju, nie jest opisana w POSIX.1.

Pierwotne linuksowe wywołania systemowe getgroups() obsługiwały jedynie 16-bitowe identyfikatory grup. Następnie, w Linuksie 2.4 dodano getgroups32(), obsługujące identyfikatory 32-bitowe. Funkcja opakowująca getgroups() biblioteki glibc obsługuje te warianty pomiędzy wersjami jądra w sposób przezroczysty.

UWAGI
Proces może posiadać maksymalnie NGROUPS_MAX grup dodatkowych oprócz efektywnego ID grupy. Stała NGROUPS_MAX jest definiowana w <limits.h>. Zbiór grup dodatkowych jest dziedziczony po procesie rodzicielskim i jest zachowywany na przestrzeni execve(2).

Maksymalna liczba grup dodatkowych może być odnaleziona w czasie uruchomienia za pomocą sysconf(3):

    long ngroups_max;
    ngroups_max = sysconf(_SC_NGROUPS_MAX);

Maksymalna zwracana wartość getgroups() nie może być większa od powyższej. Od Linuksa 2.6.4, maksymalna liczba grup dodatkowych jest również ujawniana w typowo linuksowym pliku tylko do odczytu: /proc/sys/kernel/ngroups_max.

PRZYKŁADY
    #include <err.h>
    #include <stddef.h>
    #include <stdint.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <unistd.h>

    #define MALLOC(n, T)  ((T *) reallocarray(NULL, n, sizeof(T)))

    static gid_t *agetgroups(size_t *ngids);

    int
    main(void)
    {
        gid_t   *gids;
        size_t  n;

        gids = agetgroups(&n);
        if (gids == NULL)
            err(EXIT_FAILURE, "agetgroups");

        if (n != 0) {
            printf("%jd", (intmax_t) gids[0]);
            for (size_t i = 1; i < n; i++)
                printf(" %jd", (intmax_t) gids[i]);
        }
        puts("");

        free(gids);
        exit(EXIT_SUCCESS);
    }

    static gid_t *
    agetgroups(size_t *ngids)
    {
        int    n;
        gid_t  *gids;

        n = getgroups(0, NULL);
        if (n == -1)
            return NULL;

        gids = MALLOC(n, gid_t);
        if (gids == NULL)
            return NULL;

        n = getgroups(n, gids);
        if (n == -1) {
            free(gids);
            return NULL;
        }

        *ngids = n;
        return gids;
    }

ZOBACZ TAKŻE
getgid(2), setgid(2), getgrouplist(3), group_member(3), initgroups(3), capabilities(7), credentials(7)

TŁUMACZENIE
Tłumaczenie niniejszej strony podręcznika: Przemek Borys <pborys@dione.ids.pl>, Andrzej Krzysztofowicz <ankry@green.mf.pg.gda.pl> i Michał Kułach <michal.kulach@gmail.com>

Niniejsze tłumaczenie jest wolną dokumentacją. Bliższe informacje o warunkach licencji można uzyskać zapoznając się z GNU General Public License w wersji 3 (https://www.gnu.org/licenses/gpl-3.0.html) lub nowszej. Nie przyjmuje się ŻADNEJ ODPOWIEDZIALNOŚCI.

Błędy w tłumaczeniu strony podręcznika prosimy zgłaszać na adres listy dyskusyjnej manpages-pl-list@lists.sourceforge.net.