Scroll to navigation

path_resolution(7) Miscellaneous Information Manual path_resolution(7)

NAZWA

path_resolution - sposób rozwiązywania ścieżki do pliku

OPIS

Część wywołań systemowych Uniksa/Linuksa posiada jako parametr jedną lub więcej nazw pliku. Nazwa pliku (lub ścieżka) jest rozwiązywana w opisany poniżej sposób.

Krok 1: początek procesu rozwiązywania

Jeśli ścieżka zaczyna się znakiem „/”, początkowym katalogiem wyszukiwania jest katalog główny procesu wywołującego. Proces ten dziedziczy swój katalog główny od procesu macierzystego. Zwykle będzie to korzeń hierarchii plików. Proces może uzyskać odmienny katalog główny za pomocą wywołania systemowego chroot(2) lub tymczasowo korzystać z odmiennego katalogu głównego używając openat2(2), z ustawionym znacznikiem RESOLVE_IN_ROOT.

Proces może posiadać całkowicie prywatną przestrzeń nazw montowania, jeśli był on (lub jeden z jego przodków) uruchomiony za pomocą wywołania systemowego clone(2) z ustawionym znacznikiem CLONE_NEWNS. Na tym wyczerpaliśmy opis obsługi fragmentu ścieżki „/”.

Jeśli ścieżka nie zaczyna się znakiem „/”, początkowym katalogiem wyszukiwania w procesie rozwiązywania będzie bieżący katalog roboczy procesu lub, w przypadku wywołań systemowych z grupy openat(2), argument dfd (lub bieżący katalog roboczy, jeśli jako dfd poda się AT_FDCWD). Bieżący katalog roboczy jest dziedziczony od procesu macierzystego i można go zmienić za pomocą wywołania systemowego chdir(2).

Ścieżki zaczynające się znakiem „/” są nazywane ścieżkami absolutnymi. Ścieżki nie zaczynające się znakiem „/” są nazywane ścieżkami względnymi.

Krok 2: przejście przez ścieżkę

Następuje ustawienie bieżącego katalogu wyszukiwania na początkowy katalog wyszukiwania. Teraz, każda niekońcowa składowa ścieżki, gdzie składową ścieżki jest podłańcuch ograniczony znakami „/”, jest wyszukiwana w bieżącym katalogu wyszukiwania.

Jeśli proces nie posiada uprawnień wyszukiwania w bieżącym katalogu wyszukiwania, zwracany jest błąd EACCES („Odmówiono dostępu”).

Jeśli składowa ścieżki nie zostanie odnaleziona, zwracany jest błąd ENOENT („Brak podanego pliku lub katalogu”).

Jeśli składowa ścieżki jest odnaleziona, ale nie jest katalogiem ani dowiązaniem symbolicznym, zwracany jest błąd ENOTDIR („Nie jest katalogiem”).

Jeśli składowa ścieżki jest odnaleziona i jest katalogiem, bieżący katalog wyszukiwania jest ustawiony na ten katalog i następuje przejście do następnej składowej ścieżki.

Jeśli składowa ścieżki jest odnaleziona i jest dowiązaniem symbolicznym, to najpierw jest ona rozwiązywana (jako początkowy katalog wyszukiwania używany jest bieżący katalog wyszukiwania). W razie wystąpienia błędu, jest on zwracany. Jeśli wynik rozwiązania nie jest katalogiem, zwracany jest błąd ENOTDIR. Jeśli proces rozwiązywania dowiązania symbolicznego powiedzie się, zwracając katalog, bieżący katalog wyszukiwania jest ustawiony na ten katalog i następuje przejście do następnej składowej ścieżki. Proszę zauważyć, że proces rozwiązywania może być rekurencyjny, jeśli część przedrostkowa („dirname”) ścieżki zawiera nazwę pliku będącego dowiązaniem symbolicznym wskazującym na katalog (gdzie część przedrostkowa tego katalogu może znów zawierać dowiązanie symboliczne itd.). Aby zabezpieczyć jądro przed przepełnieniem stosu oraz zapobiec odmówieniu usługi, występują ograniczenia maksymalnej głębokości rekurencji oraz maksymalnej liczby dowiązań symbolicznych, za którymi następuje podążanie. Po przekroczeniu tych ograniczeń zwracany jest błąd ELOOP („Zbyt wiele poziomów dowiązań symbolicznych”).

Obecna implementacja w Linuksie przewiduje maksymalną liczbę 40 dowiązań symbolicznych, za którymi następuje podążanie przy rozwiązywaniu ścieżki. Przed Linuksem 2.6.18 limit głębokości rekurencji wynosił 5. Od Linuksa 2.6.18 limit podniesiono do 8. W Linuksie 4.2, kod rozwiązujący ścieżki na poziomie jądra został zmodyfikowany, aby wykluczyć użycie rekurencji, dzięki czemu jedynym pozostającym limitem jest 40 podążań na całą ścieżkę.

Rozwiązywanie dowiązań symbolicznych na tym etapie można zablokować za pomocą openat2(2), z ustawionym znacznikiem RESOLVE_NO_SYMLINKS.

Krok 3: odnalezienie ostatniego wpisu

Wyszukanie ostatniej składowej ścieżki przebiega tak jak to opisano we wcześniejszych etapach dotyczących innych jej składowych, z dwiema różnicami: (i) końcowa składowa nie może być katalogiem (przynajmniej z punktu widzenia procesu rozwiązywania ścieżki – ze względu na wymagania danego wywołania systemowego być może musi być to katalog lub niekatalog) oraz (ii) jeśli ostatnia składowa ścieżki nie zostanie odnaleziona, nie musi być to błąd – być może jest właśnie tworzona. Detale traktowania ostatniego wpisu są opisane w podręczniku systemowym danego wywołania systemowego.

. i ..

Zgodnie z konwencją, każdy katalog posiada wpisy „.” i „..”, odnoszące się, odpowiednio: do samego katalogu oraz do jego katalogu nadrzędnego.

Proces rozwiązywania ścieżki założy, że wpisy te mają znaczenie zgodne z opisaną konwencją, niezależnie od tego, czy są aktualnie obecne w fizycznym systemie plików.

Nie da się wyjść poza katalog główny: „/..” ma to samo znaczenie co „/”.

Punkty montowania

Po wykonaniu polecenia mount urządzenie ścieżka, „ścieżka” odnosi się do korzenia hierarchii systemu plików na „urządzeniu”, a nie do tego, do czego odnosiła się wcześniej.

Można wyjść poza zamontowany system: „ścieżka/..” odnosi się do katalogu nadrzędnego „ścieżki”, poza hierarchią systemu plików na „urządzeniu”.

Przekraczanie punktów montowania można zablokować za pomocą openat2(2), z ustawionym znacznikiem RESOLVE_NO_XDEV (choć dotknie to również przekraczania punktów montowań przez podpięcie (bind)).

Końcowe ukośniki

Jeśli ścieżka kończy się na „/”, wymusza to rozwiązanie poprzedzającej jej składowej jak w Kroku 2: składowa poprzedzająca ukośnik albo istnieje i rozwiązuje się na katalog, albo nazywa katalog, który ma być utworzony natychmiast po rozwiązaniu ścieżki. Poza tym, końcowy „/” jest ignorowany.

Końcowe dowiązanie symboliczne

Jeśli ostatnia składowa ścieżki jest dowiązaniem symbolicznym, to od wywołania systemowego zależy, czy za docelowy plik zostanie uznane samo dowiązanie symboliczne, czy plik będący wynikiem rozwiązania ścieżki, na który wskazuje dowiązanie. Przykładowo, wywołanie systemowe lstat(2) będzie działać na samym dowiązaniu symbolicznym, a stat(2) na pliku, na który wskazuje dowiązanie symboliczne.

Ograniczenie długości

Występuje maksymalna długość ścieżki. Jeśli ścieżka (lub ścieżka pośrednia, uzyskana w trakcie rozwiązywania dowiązań symbolicznych) jest zbyt długa, zwracany jest błąd ENAMETOOLONG („Nazwa pliku zbyt długa”).

Pusta ścieżka

W pierwotnym systemie UNIX, pusta ścieżka odnosiła się do bieżącego katalogu. Obecnie POSIX nakazuje, aby pusta ścieżka nie była pomyślnie rozwiązywana. Linux zwraca w takim przypadku błąd ENOENT.

Uprawnienia

Bity uprawnień pliku składają się z trzech trzybitowych grup; zob. chmod(1) i stat(2). Pierwsza trzybitowa grupa jest używana, gdy efektywny identyfikator użytkownika procesu wywołującego jest równy identyfikatorowi właściciela pliku. Druga trzybitowa grupa jest używana, gdy identyfikator grupy pliku albo równa się efektywnemu identyfikatorowi grupy procesu wywołującego, albo jest jednym z identyfikatorów grupy uzupełniającej procesu wywołującego (jak ustawionej przez setgroups(2)). Jeśli żadna z dwóch opisanych sytuacji nie ma miejsca, używana jest trzecia grupa.

Z trzech używanych bitów, pierwszy określa uprawnienie do odczytu, drugi do zapisu, a ostatni uprawnienie wykonania w przypadku zwykłych plików albo uprawnienie przeszukania w przypadku katalogów.

Linux używa fsuid zamiast efektywnego identyfikatora użytkownika przy sprawdzaniu uprawnień. Standardowo fsuid powinien równać się identyfikatorowi efektywnemu użytkownika, ale fsuid można zmienić wywołaniem systemowym setfsuid(2).

(Tu „fsuid” oznacza coś jak „identyfikator użytkownika systemu plików” (ang. filesystem UID). Koncept ten był wymagany przez implementację serwera NFS w przestrzeni użytkownika, w czasie, gdy procesy mogły wysyłać sygnały do procesów z tym samym efektywnym identyfikatorem użytkownika. Jest to przestarzałe. Obecnie nie należy używać setfsuid(2))

Podobnie, Linux używa fsgid „identyfikatora grupy systemu plików” (ang. filesystem GID) zamiast efektywnego identyfikatora grupy. Zob. setfsgid(2).

Pomijanie sprawdzenia uprawnień: superużytkownik i przywileje

W tradycyjnym systemie UNIX, superużytkownik (root, użytkownik o identyfikatorze 0) był wszechmocny i omijał wszelkie ograniczenia wynikające z uprawnień przy dostępie do plików.

W Linuksie, moce superużytkownika podzielono na przywileje (zob. capabilities(7)). Do sprawdzenia uprawnień pliku istotne są dwa przywileje: CAP_DAC_OVERRIDE i CAP_DAC_READ_SEARCH (proces posiada te przywileje, jeśli jego fsuid wynosi 0).

Przywilej CAP_DAC_OVERRIDE przesłania wszelkie sprawdzenia uprawnień, lecz nadaje uprawnienie wykonania tylko wówczas, gdy ustawiony jest przynajmniej jeden z trzech bitów wykonania pliku.

Przywilej CAP_DAC_READ_SEARCH nadaje uprawnienia odczytu i przeszukania katalogów oraz uprawnienia odczytu zwykłych plików.

ZOBACZ TAKŻE

readlink(2), capabilities(7), credentials(7), symlink(7)

TŁUMACZENIE

Autorami polskiego tłumaczenia niniejszej strony podręcznika są: 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 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.

2 maja 2024 r. Linux man-pages (niewydane)