symlink(7)

NAZWA
symlink - obsługa dowiązań symbolicznych

OPIS
Dowiązania symboliczne są plikami, które działają jak wskaźniki do innych plików. Aby zrozumieć ich działanie, konieczne jest wcześniejsze poznanie mechanizmu działania dowiązań zwykłych.

Dowiązanie zwykłe do pliku jest nierozróżnialne od pierwotnego pliku, ponieważ jest odniesieniem do samego obiektu, do którego odnosi się pierwotna nazwa pliku (precyzyjniej: każde z dowiązań zwykłych do pliku odnosi się do tego samego numeru i-węzła: gdzie numer i-węzła jest numerem indeksu w tablicy i-węzłów, zawierającej metadane o wszystkich plikach w systemie plików. Zob. stat(2)). Zmiany w pliku są niezależne od nazwy, jaka odnosi się do pliku. Dowiązania zwykłe nie odnoszą się do katalogów (aby uniemożliwić wystąpienie pętli w drzewie systemu plików, które zmyliłyby wiele programów) i nie mogą odnosić się do plików w innych systemach plików (ponieważ numery i-węzłów nie są unikalne pomiędzy systemami plików).

Dowiązanie symboliczne jest specjalnym typem pliku, którego zawartość jest łańcuchem, będącym ścieżką innego pliku — pliku na który wskazuje dowiązanie (zawartość dowiązania symbolicznego można odczytać za pomocą readlink(2)). Innymi słowy, dowiązanie symboliczne jest wskaźnikiem do innej nazwy, a nie do samego obiektu. Z tego powodu, dowiązania symboliczne mogą odnosić się do katalogów i mogą przekraczać granice systemu plików.

Nie ma wymagania aby ścieżka, do której odnosi się dowiązanie symboliczne, musiała istnieć. Dowiązanie symboliczne odnoszące się do nieistniejącej ścieżki jest nazywane dowiązaniem wiszącym.

Dowiązanie symboliczne i obiekt, do którego się odnosi, istnieją jednocześnie w przestrzeni nazw systemu plików, zatem może dojść do problemów w rozróżnieniu samego dowiązania i obiektu na który ono wskazuje. W dawnych systemach, polecenia i wywołania systemowe zaadoptowały swoje własne, dość przypadkowe konwencje, dotyczące podążania za dowiązaniami. Tutaj opisano nieco bardziej spójne podejście, opisujące sposób implementacji w systemie Linux i innych. Jest ważne, aby lokalne aplikacje w systemie również przestrzegały tych reguł tak, aby interfejs użytkownika był jak najbardziej spójny.

  Dowiązania magiczne
Istnieje specjalna klasa obiektów dowiązaniopodobnych™ zwanych „dowiązaniami magicznymi”, które występują w określonych pseudosystemach plików, takich jak proc(5) (np. /proc/pid/exe i /proc/pid/fd/*). W przeciwieństwie do standardowych dowiązań symbolicznych, dowiązania magiczne nie są rozwiązywane za pomocą podążania za ścieżką, lecz są bezpośrednimi odniesieniami do własnych reprezentacji jądra wobec uchwytów plików. Jako takie, dowiązania magiczne umożliwiają użytkownikom dostęp do plików, do których nie mogą odnosić się zwykłe ścieżki (np. do odlinkowanych plików, do których wciąż odnosi się działający program).

Dowiązania magiczne mogą pomijać standardowe ograniczenia wynikające z przestrzeni nazw montowań (mount_namespaces(7)), dlatego były już wektorem ataków stosowanym przez różne exploity.

  Własności, uprawnienia i znaczniki czasowe dowiązań symbolicznych
Właściciela i grupę istniejącego dowiązania symbolicznego można zmienić za pomocą lchown(2). Własność dowiązania symbolicznego ma znaczenie, gdy dowiązanie jest usuwane lub zmieniane w katalogu, który ma ustawiony bit lepkości (zob. inode(7)) oraz gdy ustawiona jest kontrolka systemowa fs.protected_symlinks (zob. proc(5)).

Znaczniki czasowe ostatniego dostępu i ostatniej modyfikacji dowiązania symbolicznego można zmienić za pomocą utimensat(2) lub lutimes(3).

W Linuksie, uprawnienia standardowego dowiązania symbolicznego nie są używane przy żadnych operacjach; uprawnienia są ustawione zawsze na 0777 (odczyt, zapis i wykonanie dla wszystkich kategorii użytkowników) i nie mogą być zmieniane.

Dowiązania magiczne nie przestrzegają jednak tej reguły. Mogą mieć tryb inny niż 0777, choć nie jest to obecnie używane przy żadnych sprawdzeniach uprawnień.

  Pozyskiwanie deskryptora pliku odnoszącego się do dowiązania symbolicznego
Łącząc w open(2) znaczniki O_PATH i O_NOFOLLOW można uzyskać deskryptor pliku, które można przekazać jako argument dirfd wywołaniom systemowym, takim jak: fstatat(2), fchownat(2), fchmodat(2), linkat(2) i readlinkat(2), aby działać na samym dowiązaniu symbolicznym (a nie na pliku, do którego się ono odnosi).

Domyślnie (tj. bez znacznika AT_SYMLINK_FOLLOW) jeśli do dowiązania symbolicznego zastosuje się name_to_handle_at(2), to zwróci ono uchwyt do dowiązania symbolicznego (a nie pliku, do którego się ono odnosi). Można następnie uzyskać deskryptor pliku samego dowiązania symbolicznego (a nie pliku, do którego się ono odnosi), podając znacznik O_PATH w kolejnym wywołaniu do open_by_handle_at(2). Ten deskryptor pliku można użyć w opisanych wcześniej wywołaniach systemowych, aby działać na samym dowiązaniu symbolicznym.

  Obsługa dowiązań symbolicznych przez polecenia i wywołania systemowe
Działania wobec dowiązań symbolicznych są dokonywane albo na samym dowiązaniu, albo na obiekcie, do którego odnosi się dowiązanie. W tym drugim przypadku mówi się, że aplikacja lub wywołanie systemowe podąża za dowiązaniem. Dowiązania symboliczne może odnosić się do kolejnych dowiązań symbolicznych; wówczas dowiązania są rozwiązywane do momentu: odnalezienia obiektu niebędącego dowiązaniem symbolicznym, odnalezienia dowiązania symbolicznego odnoszącego się do nieistniejącego pliku albo wykrycia pętli (pętle są wykrywane poprzez nałożenie górnego limitu na kolejne podążanie za dowiązaniami i wystąpieniu błędu po jego przekroczeniu).

Konieczne jest omówienie trzech odrębnych przypadków. Oto one:

•   Dowiązania symboliczne będące argumentami do wywołań systemowych.

•   Dowiązania symboliczne będące argumentami wiersza poleceń do narzędzi, które nie przechodzą przez drzewo plików.

•   Dowiązania symboliczne, na które napotkają narzędzia przechodzące przez drzewo plików (albo podane w wierszu poleceń, albo napotkane przy przechodzeniu przez drzewo plików).

Przed opisem traktowania dowiązań symbolicznych przez polecenia i wywołania systemowe, konieczne będzie zdefiniowanie pewnych pojęć. Zakładając, że ścieżka ma postać a/b/c, część poprzedzająca ostatni ukośnik (tj. a/b) jest nazywana składową dirname (katalogową), a część po ostatnim ukośniku (tj. c) jest nazywana składową basename (podstawową).

  Traktowanie dowiązań symbolicznych w wywołaniach systemowych
Pierwszy przypadek dotyczy dowiązań symbolicznych, użytych jako argumenty z nazwą pliku w wywołaniach systemowych.

Dowiązania symboliczne w ścieżce przekazywanej do wywołania systemowego są traktowane następująco:

(1) W składowej dirname (katalogowej) ścieżki, podąża się za dowiązaniami symbolicznymi zawsze, w niemal każdym wywołaniu systemowym (jest to prawdziwe również dla poleceń). Jedynym wyjątkiem jest openat2(2), które udostępnia znaczniki, mogące być użyte do wyłączenia podążania za dowiązaniami symbolicznymi w składowej dirname (katalogowej).

(2) Poza wyjątkami opisanymi poniżej, wszystkie wywołania systemowe podążają za dowiązaniami symbolicznymi w składowej basename (podstawowej) ścieżki. Przykładowo, jeśli istniałoby dowiązanie symboliczne slink wskazujące na plik o nazwie afile, to wywołanie systemowe open("slink" ...) zwróciłoby deskryptor pliku odnoszący się do pliku afile.

Istnieją wywołania systemowe, które nie podążają za dowiązaniami w składowej basename (podstawowej) ścieżki, lecz działają na samym dowiązaniu symbolicznym. Są to: lchown(2), lgetxattr(2), llistxattr(2), lremovexattr(2), lsetxattr(2), lstat(2), readlink(2), rename(2), rmdir(2) oraz unlink(2).

Pewne inne wywołania systemowe opcjonalnie podążają za dowiązaniami symbolicznymi w składowej basename (podstawowej) ścieżki. Są to: faccessat(2), fchownat(2), fstatat(2), linkat(2), name_to_handle_at(2), open(2), openat(2), open_by_handle_at(2) i utimensat(2); więcej szczegółów w innych podręcznikach systemowych. Jako że remove(3) jest aliasem unlink(2), ta funkcja biblioteczna nie podąża za dowiązaniami symbolicznymi. Gdy do dowiązania symbolicznego zastosuje się rmdir(2), to wywołanie zawiedzie z błędem ENOTDIR.

link(2) zasługuje na odrębny opis. POSIX.1-2001 określa, że link(2) powinno rozwiązywać oldpath, jeśli jest to dowiązanie symboliczne. Linux tego jednak nie robi (domyślnie Solaris zachowuje się tak samo, ale zachowanie z POSIX.1-2001 można uzyskać odpowiednimi opcjami kompilatora). W POSIX.1-2008 zmieniono normę, zezwalając w implementacji na oba zachowania.

  Polecenia nieprzechodzące przez drzewo plików
Drugim przypadkiem są dowiązania symboliczne, podawane jako argumenty nazwy pliku w wierszu polecenia poleceniom, które nie przechodzą przez drzewo plików.

Z wyjątkami opisanymi poniżej, polecenia podążają za dowiązaniami symbolicznymi, podanymi jako argumenty w wierszu poleceń. Na przykład, jeśli istniałoby dowiązanie symboliczne slink wskazujące na plik o nazwie afile, polecenie cat slink wyświetliłoby zawartość pliku afile.

Jest istotne, aby uświadomić sobie, że reguła ta obejmuje polecenia, które mogą opcjonalnie przechodzić przez drzewo plików np. reguła ta dotyczy polecenia chown file, natomiast nie dotyczy polecenia chown -R file, ponieważ przechodzi ono przez drzewo plików (to ostatnie stanowi trzeci przypadek, opisany w podrozdziale poniżej).

Jeśli wyraźnym zamiarem jest działanie polecenia na samym dowiązaniu symbolicznym, zamiast podążanie za nim — np. jeśli chce się zmienić za pomocą chown slink własność pliku slink, niezależnie od tego, czy jest to dowiązanie symboliczne, czy też nie — powinno się zastosować opcję -h. W powyższym przykładzie chown root slink zmieniłoby własność pliku, do którego odnosi się slink, natomiast chown -h root slink zmieniłoby własność samego slink.

Od tej reguły istnieją pewne wyjątki:

•   Polecenia mv(1) i rm(1) nie podążają za dowiązaniami symbolicznymi podanymi jako argumenty, lecz próbują je, odpowiednio, przemianować i usunąć (proszę zauważyć, że jeśli dowiązanie symboliczne odnosi się do pliku przez ścieżkę względną, przeniesienie go do innego katalogu może równie dobrze spowodować, że przestanie ono działać, ponieważ ścieżka może nie być już poprawna).

•   Polecenie ls(1) również jest wyjątkiem od tej reguły. Ze względu na kompatybilność z dawnymi systemami (gdy ls(1) nie przechodzi przez drzewo — tj. nie podano opcji -R), polecenie ls(1) podąża za dowiązaniami symbolicznymi podanymi jako argumenty, jeśli podano opcje -H lub -L, albo gdy nie podano opcji -F, -d lub -l (polecenie ls(1) jest jedynym poleceniem, gdzie opcje -H i -L wpływają na jego zachowanie, nawet gdy nie jest dokonywane przejście przez drzewo plików).

•   Polecenie file(1) również jest wyjątkiem od tej reguły. Polecenie file(1) nie podąża za dowiązaniami symbolicznymi, podanymi jako argument. Polecenie file(1) podąża za dowiązaniami symbolicznymi podanymi jako argument, gdy podano opcję -L.

  Polecenia przechodzące przez drzewo plików
Polecenia, które albo opcjonalnie, albo zawsze przechodzą przez drzewo plików: chgrp(1), chmod(1), chown(1), cp(1), du(1), find(1), ls(1), pax(1), rm(1) i tar(1).

Jest istotne aby uświadomić sobie, że poniższe reguły stosują się zarówno do dowiązań symbolicznych napotkanych przy przechodzeniu przez drzewo plików, jak i do dowiązań symbolicznych podanych jako argumenty wiersza poleceń.

Pierwsza reguła stosuje się do dowiązań symbolicznych, odnoszących się do plików innych niż katalogi. Operacje, które dotyczą dowiązań symbolicznych, są wykonywane na samych dowiązaniach symbolicznych, lecz poza tym, dowiązania są ignorowane.

Polecenie rm -r slink directory usunie slink, oraz wszelkie dowiązania symboliczne napotkane przy przechodzeniu drzewa katalogu directory, ponieważ dowiązania symboliczne mogą być usuwane. W żadnym przypadku rm(1) nie będzie dotyczyć pliku wskazywanego przez slink.

Druga reguła dotyczy dowiązań symbolicznych, odnoszących się do katalogów. Domyślnie, nigdy nie podąża się za dowiązaniami symbolicznymi wskazującymi na katalogi. Często nazywane jest to przejściem „fizycznym”, w odróżnieniu od przejścia „logicznego” (gdy podąża się za dowiązaniami symbolicznymi odnoszącymi się do katalogów).

Istnieją pewne konwencje, które są (a przynajmniej powinny być) przestrzegane, przez programy dokonujące przejścia przez drzewo plików, tak ściśle, jak to możliwe:

•   Można sprawić, aby polecenie podążało za wszelkimi dowiązaniami symbolicznymi podanymi w wierszu poleceń, niezależnie od typu pliku, do jakiego się odnoszą, podając opcję -H (od ang „half-logical” — „półlogiczny”). Opcja ta ma na celu upodobnienie przestrzeni nazw wiersza poleceń do logicznej przestrzeni nazw (proszę zauważyć, że w przypadku poleceń, które nie zawsze przechodzą przez drzewo plików, opcja -H zostanie zignorowana, jeśli nie podano również -R).

    Dla przykładu, polecenie chown -HR user slink przejdzie przez hierarchię plików zakorzenionych w pliku, na który wskazuje slink. Proszę zauważyć, że -H nie jest tym samym, co opisywana wcześniej opcja -h. Opcja -H powoduje, że dowiązania symboliczne podane w wierszu poleceń są rozwiązywane w celu zarówno przeprowadzenia akcji, jak i przejścia przez drzewo, i jest to to samo, co podanie przez użytkownika nazwy pliku, na którą wskazuje dowiązanie symboliczne.

•   Można spowodować, aby polecenie podążało za dowiązaniami symbolicznymi podanymi w wierszu poleceń, jak również wszelkimi dowiązaniami symbolicznymi napotkanymi przy przejściu przez drzewo plików, niezależnie od typu plików, na które wskazują, podając opcję -L („logiczny”). Opcja ta ma na celu upodobnienie całej przestrzeni nazw do logicznej przestrzeni nazw (proszę zauważyć, że w przypadku poleceń, które nie zawsze przechodzą przez drzewo plików, opcja -L zostanie zignorowana, jeśli nie podano również -R).

    Dla przykładu, polecenie chown -LR user slink zmieni właściciela pliku, do którego odnosi się slink. Jeśli slink wskazuje na katalog, chown przejdzie przez hierarchię plików zakorzenionych w katalogu, na który on wskazuje. Dodatkowo, wszelkie dowiązania symboliczne napotkane w dowolnym drzewie plików, przez który przejdzie chown, zostaną potraktowane w ten sam sposób co slink.

•   Można sprawić, aby polecenie zachowało się w sposób domyślny podając opcję -P (od ang. „physical” — „fizyczny”). Opcja ta ma na celu upodobnienie całej przestrzeni nazw do fizycznej przestrzeni nazw.

W przypadku poleceń, które domyślnie nie przechodzą przez drzewo plików, opcje -H, -L i -P są ignorowane, jeśli nie poda się równocześnie opcji -R. Dodatkowo, można podać opcje -H, -L i -P więcej niż raz; podana jako ostatnia określa zachowanie polecenia. Ma to na celu umożliwienie utworzenia aliasów poleceń, korzystających z tych opcji, a jednocześnie umożliwienie późniejszego przesłonienie zachowania podanego w aliasie, z wiersza poleceń.

Polecenia ls(1) i rm(1) mają wyjątki do tych reguł:

•   Polecenie rm(1) działa na samym dowiązaniu symbolicznym, a nie na pliku, na który ono wskazuje, zatem nigdy nie podąża za dowiązaniem symbolicznym. Polecenie rm(1) nie obsługuje opcji -H, -L ani -P.

•   Aby zachować kompatybilność z dawnymi systemami, polecenie ls(1) działa nieco odmiennie. Jeśli nie poda się opcji -F, -d lub -l, ls(1) będzie podążało za dowiązaniami symbolicznymi podanymi w wierszu poleceń. Jeśli poda się opcję -L, ls(1) podąża za wszelkimi dowiązaniami symbolicznymi, niezależnie od ich typu i tego, czy zostały podane w wierszu poleceń, czy napotkane przy przejściu przez drzewo.

ZOBACZ TAKŻE
chgrp(1), chmod(1), find(1), ln(1), ls(1), mv(1), namei(1), rm(1), lchown(2), link(2), lstat(2), readlink(2), rename(2), symlink(2), unlink(2), utimensat(2), lutimes(3), path_resolution(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.