access(2) System Calls Manual access(2) NAZWA access, faccessat, faccessat2 - sprawdza prawa uzytkownika do pliku BIBLIOTEKA Standardowa biblioteka C (libc, -lc) SKLADNIA #include int access(const char *pathname, int mode); #include /* Definicja stalych AT_* */ #include int faccessat(int dirfd, const char *pathname, int mode, int flags); /* Roznice miedzy biblioteka C a jadrem opisano ponizej */ #include /* Definicja stalych AT_* */ #include /* Definicja stalych SYS_* */ #include int syscall(SYS_faccessat2, int dirfd, const char *pathname, int mode, int flags); Wymagane ustawienia makr biblioteki glibc (patrz feature_test_macros(7)): faccessat(): Od glibc 2.10: _POSIX_C_SOURCE >= 200809L Przed glibc 2.10: _ATFILE_SOURCE OPIS access() sprawdza, czy wywolujacy proces ma dostep do pliku pathname. Jesli pathname jest dowiazaniem symbolicznym, jest rozwiazywana. Mode okresla jakie sprawdzenia dostepnosci maja byc wykonane i jest albo wartoscia F_OK albo maska zawierajaca sume logiczna jednego lub wiecej z R_OK, W_OK i X_OK. F_OK sprawdza istnienie pliku. R_OK, W_OK i X_OK sprawdzaja pod katem istnienia pliku i, odpowiednio, uprawnien odczytu, zapisu i wykonania. Sprawdzenie jest wykonywane za pomoca prawdziwych identyfikatorow uzytkownika i grupy procesu, zamiast identyfikatorow efektywnych, jak dzieje sie przy rzeczywistej probie wykonania operacji (np. open(2)) na pliku. Podobnie, w przypadku uzytkownika root, sprawdzenie uzywa zestawu przywilejow (ang. capabilities) dozwolonych zamiast zestawu przywilejow efektywnych; w przypadku uzytkownikow innych niz root, sprawdzenie uzywa pustego zestawu przywilejow. Pozwala to programom korzystajacym z ustawienia ID uzytkownika podczas wykonania (suid) oraz programom obslugujacym przywileje (ang. capabilities) na latwe okreslenie uprawnien wywolujacego uzytkownika. Innymi slowy, access() nie odpowiada na pytanie "czy moge odczytac/zapisac/wykonac ten plik?". Odpowiada na nieco inne "(zakladajac, ze jestem plikiem wykonywalnym korzystajacym z suid) czy uzytkownik, ktory mnie wywolal moze odczytac/zapisac/wykonac ten plik?". Daje to programom korzystajacym z suid mozliwosc uniemozliwienia zmuszania ich przez zlosliwych uzytkownikow do odczytywania plikow, ktorych ci uzytkownicy nie powinni moc odczytywac. Jesli wywolujacy proces jest uprzywilejowany (tzn. jego identyfikator uzytkownika wynosi zero), to sprawdzenie X_OK konczy sie sukcesem, jesli zwykly plik posiada uprawnienie wykonania dla dowolnego wlasciciela pliku, grupy itp. faccessat() Wywolanie systemowe faccessat() operuje w dokladnie taki sam sposob jak access(), z wyjatkiem roznic opisanych tutaj. Jesli sciezka podana w pathname jest wzgledna, jest to interpretowane w odniesieniu do katalogu do ktorego odnosi sie deskryptor pliku dirfd (zamiast w odniesieniu do biezacego katalogu roboczego procesu wywolujacego, jak w stosunku do sciezek wzglednych robi to access()). Jesli pathname jest wzgledna a dirfd ma wartosc specjalna AT_FDCWD, to pathname jest interpretowana w odniesieniu do biezacego katalogu roboczego procesu wywolujacego (jak access()). Jesli sciezka pathname jest bezwzgledna, to dirfd jest ignorowane. Parametr flags jest tworzony jako suma logiczna (OR) zera lub wiekszej liczby nastepujacych wartosci: AT_EACCESS Przeprowadza sprawdzenie za pomoca efektywnych identyfikatorow uzytkownika i grupy. Domyslnie faccessat() uzywa identyfikatorow rzeczywistych (jak access()). AT_EMPTY_PATH (od Linuksa 5.8) Jesli pathname jest pustym lancuchem, dziala na pliku do ktorego odnosi sie dirfd (ktory mogl byc pozyskany za pomoca znacznika O_PATH open(2)). W tym przypadku dirfd moze odnosic sie do dowolnego typu pliku, a nie tylko katalogu. Jesli dirfd wynosi AT_FDCWD, to wywolanie dziala na biezacym katalogu roboczym. Znacznik ten jest charakterystyczny dla Linuksa; nalezy zdefiniowac _GNU_SOURCE, aby pozyskac jego definicje. AT_SYMLINK_NOFOLLOW Jesli pathname jest dowiazaniem symbolicznym, nie rozwiazuje go: w zamian zwraca informacje o samym dowiazaniu. Wiecej informacji o potrzebie wprowadzenia faccessat() mozna znalezc w podreczniku openat(2). faccessat2() Powyzszy opis faccessat() odnosi sie do POSIX.1 i implementacji dostarczonej przez glibc. Implementacja glibc nie byla jednak wiernym odwzorowaniem (zob. USTERKI), ktora przeslizgnela sie nad faktem, ze surowe wywolanie linuksowe faccessat() nie posiadalo argumentu flags. W celu poprawnej implementacji, Linux 5.8 dodal wywolanie systemowe faccessat2(), ktore obsluguje argument flags i pozwala na prawidlowa implementacje funkcji opakowujacej faccessat(). WARTOSC ZWRACANA Gdy wszystko pojdzie dobrze (wszystkie zadane prawa sa zapewnione, lub mode wynosi F_OK i plik istnieje), zwracane jest zero. W wypadku bledu (przynajmniej jeden bit z zadanych w mode uprawnien nie jest ustawiony, mode wynosi F_OK i plik nie istnieje lub wystapily inne bledy), zwracane jest -1 i ustawiane jest errno wskazujac blad. BLEDY EACCES Brak uprawnien dla zadanego dostepu do pliku, albo brak uprawnien do przegladania ktoregos z katalogow w sciezce pathname (zob. tez path_resolution(7)). EBADF (faccessat()) pathname jest wzgledne, lecz dirfd nie wynosi ani AT_FDCWD (faccessat()), ani nie jest prawidlowym deskryptorem pliku. EFAULT pathname wskazuje poza dostepna dla uzytkownika przestrzen adresowa. EINVAL mode zostalo nieprawidlowo podane. EINVAL (faccessat()) Podano nieprawidlowa opcje w flags. EIO Wystapil blad wejscia/wyjscia. ELOOP Podczas rozwiazywania pathname napotkano zbyt wiele dowiazan symbolicznych. ENAMETOOLONG Sciezka pathname jest zbyt dluga. ENOENT Skladnik pathname nie istnieje lub jest wiszacym dowiazaniem symbolicznym. ENOMEM Brak pamieci jadra. ENOTDIR Skladnik pathname, ktory powinien byc katalogiem w rzeczywistosci katalogiem nie jest. ENOTDIR (faccessat()) pathname jest wzgledna a dirfd jest deskryptorem pliku odnoszacym sie do pliku zamiast do katalogu. EPERM Zadano zapisu do pliku z ustawionym znacznikiem niezmiennosci. Zob. tez ioctl_iflags(2). EROFS Zadano zapisu do pliku polozonego w systemie plikow tylko do odczytu. ETXTBSY Wystapila proba dostepu z prawem zapisu do pliku aktualnie uruchomionego programu. WERSJE Jesli proces posiada odpowiednie uprawnienia (tj. jest superuzytkownikiem), POSIX.1-2001 zezwala na implementacje wskazujaca pomyslne zakonczenie dla sprawdzenia X_OK nawet wtedy, gdy nie jest ustawiony zaden z bitow uruchamialnosci w prawach dostepu do pliku. Linux tego nie czyni. Roznice biblioteki C/jadra Surowe wywolanie systemowe faccessat() przyjmuje jedynie trzy pierwsze argumenty. Znaczniki AT_EACCESS i AT_SYMLINK_NOFOLLOW sa faktycznie zaimplementowane w opakowujacej funkcji glibc do faccessat(). Jesli nie podano zadnego z tych znacznikow, funkcja opakowujaca uzywa fstatat(2) do okreslenia uprawnien dostepu, zob. jednak USTERKI. Uwagi dla glibc Na starszych wersjach jadra Linux, gdzie faccessat() nie jest dostepne (i gdzie znaczniki AT_EACCESS oraz AT_SYMLINK_NOFOLLOW nie sa okreslone), funkcja opakowujaca z glibc wraca do uzywania access(). Gdy pathname jest wzgledna sciezka, glibc konstruuje sciezke na bazie dowiazania symbolicznego w /proc/self/fd, ktore odpowiada argumentowi dirfd. STANDARDY access() faccessat() POSIX.1-2008. faccessat2() Linux. HISTORIA access() SVr4, 4.3BSD, POSIX.1-2001. faccessat() Linux 2.6.16, glibc 2.4. faccessat2() Linux 5.8. UWAGI Ostrzezenie: Uzycie tych wywolan w celu sprawdzenia, czy uzytkownik ma uprawnienia na przyklad do otwarcia pliku, przed otwarciem tego pliku za pomoca open(2) tworzy luke bezpieczenstwa, poniewaz uzytkownik moze wykorzystac krotki moment pomiedzy sprawdzeniem pliku a otwarciem go do manipulacji na pliku. Z tego powodu nalezy unikac uzywania niniejszego wywolania systemowego (w opisanym wlasnie przykladzie, bezpieczniejsza alternatywa byloby tymczasowe przelaczenie efektywnego identyfikatora uzytkownika na jego identyfikator rzeczywisty, a nastepnie wywolanie open(2)). access() zawsze podaza za dowiazaniami symbolicznymi. Jesli konieczne jest sprawdzenie uprawnien samego dowiazania symbolicznego, nalezy uzyc faccessat() ze znacznikiem AT_SYMLINK_NOFOLLOW. Te wywolania zwracaja blad, jesli jakikolwiek z zadanych w mode rodzajow dostepu zostanie odmowiony, nawet jesli pozostale typy dostepu z mode sa dozwolone. Plik jest dostepny tylko wowczas, gdy uprawnienia kazdego z katalogow w jego sciezce pathname przyznaja dostep do przeszukiwania (tj. wykonania). Jesli dowolny katalog jest niedostepny, to wywolanie access() zawiedzie, niezaleznie od uprawnien samego pliku. Sprawdzane sa jedynie bity dostepu, nie zawartosc pliku czy jego typ. Dlatego, jesli katalog okazuje sie "zapisywalny", znaczy to prawdopodobnie, ze mozna w nim tworzyc pliki, a nie, ze do katalogu mozna pisac jak do pliku. Podobnie, plik dosowy moze zostac zgloszony jako "wykonywalny", lecz funkcja execve(2) mimo to zawiedzie. Wywolania te moga nie dzialac prawidlowo na systemach plikow NFSv2 z wlaczonym mapowaniem UID, poniewaz mapowanie to jest dokonywane na serwerze i ukryte przed klientem sprawdzajacym prawa dostepu (NFS w wersji 3 i wyzszej dokonuja sprawdzen na serwerze). Podobny problem moze wystapic przy montowaniach FUSE. USTERKI Ze wzgledu na to, ze wywolanie systemowe jadra Linux faccessat() nie obsluguje argumentu flags, funkcja opakowujaca faccessat() z glibc udostepniona w glibc 2.32 i wczesniejszych, emuluje wymagana funkcjonalnosc za pomoca polaczenia wywolania systemowego faccessat() oraz fstatat(2). Jednak emulacja ta nie bierze pod uwage ACL-i (list kontroli dostepu do plikow). Poczawszy od glibc 2.33, funkcja opakowujaca obchodzi te usterke, wykorzystujac wywolanie systemowe faccessat2(), tam gdzie jest ono zapewnione przez jadro. W Linuksie 2.4 (i wczesniejszych) obsluga testow X_OK dla superuzytkownika jest nieco dziwna. Jesli wszystkie kategorie uprawnien wykonania sa wylaczone dla pliku niebedacego katalogiem, to jedynym testem access() zwracajacym -1 jest sytuacja, gdy podany mode wynosi tylko X_OK; jesli w mode okreslono rowniez R_OK lub W_OK, to access() zwroci dla takich plikow 0. Wczesny Linux 2.6 (do Linuksa 2.6.3 wlacznie) zachowywal sie rowniez w ten sam sposob jak Linux 2.4. Przed Linuksem 2.6.20, wywolania te ignorowaly wplyw znacznika MS_NOEXEC, jesli byl on uzywany do wykonania mount(2) na systemie plikow. Od Linuksa 2.6.20, znacznik MS_NOEXEC jest uwzgledniany. ZOBACZ TAKZE chmod(2), chown(2), open(2), setgid(2), setuid(2), stat(2), euidaccess(3), credentials(7), path_resolution(7), symlink(7) TLUMACZENIE Autorami polskiego tlumaczenia niniejszej strony podrecznika sa: Przemek Borys , Andrzej Krzysztofowicz i Michal Kulach Niniejsze tlumaczenie jest wolna dokumentacja. Blizsze informacje o warunkach licencji mozna uzyskac zapoznajac sie z GNU General Public License w wersji 3 lub nowszej. Nie przyjmuje sie ZADNEJ ODPOWIEDZIALNOSCI. Bledy w tlumaczeniu strony podrecznika prosimy zglaszac na adres listy dyskusyjnej . Linux man-pages 6.06 1 stycznia 2024 r. access(2)