setuid(2)

NAZWA
setuid - ustawia identyfikator użytkownika

BIBLIOTEKA
Standardowa biblioteka C (libc, -lc)

SKŁADNIA
#include <unistd.h>

int setuid(uid_t uid);

OPIS
setuid() ustawia efektywny identyfikator użytkownika procesu wywołującego. Jeśli proces wywołujący jest uprzywilejowany (precyzyjniej: jeśli proces ma przywilej CAP_SETUID w swojej przestrzeni nazw użytkownika) ustawiany jest również rzeczywisty UID oraz zapisany set-user-ID.

W Linuksie setuid() jest zaimplementowany tak, jak wersja POSIX, z funkcją _POSIX_SAVED_IDS. Pozwala to programom set-user-ID (innym niż root) porzucić wszystkie swoje przywileje użytkownika, wykonać jakąś nieuprzywilejowaną pracę, a następnie odzyskać pierwotny efektywny identyfikator użytkownika w bezpieczny sposób.

Jeśli użytkownik jest rootem albo program jest typu set-user-ID-root, konieczne jest zachowanie specjalnej uwagi: setuid() sprawdza efektywny identyfikator użytkownika wywołującego i jeśli jest on superużytkownikiem, wszystkie identyfikatory użytkownika związane z procesem są ustawiane na uid. Po tym, gdy to nastąpi, program nie będzie w stanie odzyskać uprawnień roota.

Z tego względu program typu set-user-ID-root chcący tymczasowo porzucić przywileje roota, przyjmujący tożsamość użytkownika nieuprzywilejowanego, a następnie odzyskujący przywileje roota nie może korzystać z setuid(). Można tego dokonać za pomocą seteuid(2).

WARTOŚĆ ZWRACANA
Po pomyślnym zakończeniu zwracane jest zero. Po błędzie zwracane jest -1 i ustawiane errno, wskazując błąd.

Uwaga: są przypadki, gdy setuid() może zawieść nawet wówczas, gdy wywołujący ma UID 0. Pominięcie sprawdzenia zwrotu niepowodzenia z setuid() jest poważnym zagrożeniem bezpieczeństwa.

BŁĘDY

EAGAIN
    Wywołanie mogłoby zmienić rzeczywisty UID wywołującego (tzn. uid nie pasowałby do rzeczywistego UID wywołującego), lecz wystąpiło tu tymczasowe niepowodzenie w przydzieleniu niezbędnych struktur danych jądra.

EAGAIN
    uid nie pasuje do rzeczywistego identyfikatora użytkownika wywołującego, a to wywołanie spowodowałoby przekroczenie limitu zasobów RLIMIT_NPROC wywołującego przez liczbę procesów należących do rzeczywistego ID użytkownika uid. Od Linuksa 3.1 błąd ten już się nie pojawia (lecz solidne aplikacje powinny dokonywać jego sprawdzenia); zob. opis EAGAIN w execve(2).

EINVAL
    Identyfikator użytkownika podany w uid nie jest prawidłowy w tej przestrzeni nazw użytkownika.

EPERM
    Użytkownik nie jest uprzywilejowany (Linux: nie ma przywileju CAP_SETUID w swej przestrzeni nazw użytkownika), a uid nie pasuje do rzeczywistego UID-u lub zapisanego set-user-ID procesu wywołującego.

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 setuid()) 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
POSIX.1-2024.

HISTORIA
POSIX.1-2001, SVr4.

Nie jest w pełni kompatybilne z wywołaniem z 4.4BSD, które ustawia wszystkie identyfikatory użytkownika: rzeczywisty, zapisany i efektywny.

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

UWAGI
W Linuksie istnieje koncept identyfikatora użytkownika systemu plików, zwykle równego efektywnemu identyfikatorowi użytkownika. Wywołanie setuid() ustawia również ID użytkownika systemu plików procesu wywołującego. Zob. setfsuid(2).

Jeśli uid jest różny od starego efektywnego UID-u, to procesowi zostanie uniemożliwione pozostawienie zrzutu rdzenia.

ZOBACZ TAKŻE
getuid(2), seteuid(2), setfsuid(2), setreuid(2), capabilities(7), credentials(7), user_namespaces(7)

TŁUMACZENIE
Tłumaczenie niniejszej strony podręcznika: 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.