path_resolution - Wie ein Pfadname zu einer Datei aufgelöst wird
Einige UNIX/Linux-Systemaufrufe haben als Parameter einen oder mehrere
Dateinamen. Ein Dateiname (oder Pfadname) wird wie folgt aufgelöst:
Falls der Pfadname mit dem Zeichen »/« beginnt, wird das
Wurzelverzeichnis des aufrufenden Prozesses als Startverzeichnis beim
Nachschlagen verwandt. Ein Prozess erbt sein Wurzelverzeichnis von seinem
Elternprozess. Normalerweise wird dies das Wurzelverzeichnis der
Dateihierarchie sein. Durch die Verwendung des Systemaufrufs
chroot(2)
kann ein Prozess ein anderes Wurzelverzeichnis erhalten oder er kann mittels
openat2(2) mit dem gesetzten Schalter
RESOLVE_IN_ROOT
temporär ein anderes Wurzelverzeichnis erhalten.
Ein Prozess kann einen komplett privaten Einhängenamensraum erhalten,
falls er–oder einer seiner Vorgänger–durch einen
Systemaufruf von
clone(2) mit gesetztem Schalter
CLONE_NEWNS
gestartet wurde. Dieser handhabt den »/«-Anteil des Pfadnamens.
Falls der Pfadname nicht mit dem Zeichen »/« beginnt, ist das
Nachschlage-Startverzeichnis für den Pfadauflösungsprozess das
aktuelle Arbeitsverzeichnis des Prozesses – oder im Falle von
Systemaufrufen im Stil von
openat(2), das Argument
dfd (oder das
aktuelle Arbeitsverzeichnis, falls
AT_FDCWD als Argument
dfd
übergeben wurde). Das aktuelle Arbeitsverzeicnis wird vom Elternprozess
geerbt und kann mittels des Systemaufrufs
chdir(2) geändert
werden.
Pfadnamen, die mit dem Zeichen »/« beginnen, werden absolute
Pfadnamen genannt. Alle anderen Pfadnamen heißen relative Pfadnamen.
Das aktuelle Nachschlageverzeichnis wird auf das Nachschlage-Startverzeichnis
gesetzt. Jetzt wird für jede nicht abschließende Komponente des
Pfadnamens diese im aktuellen Nachschlageverzeichnis nachgeschlagen. Hierbei
ist eine Komponente eine Teilzeichenkette, die durch das Zeichen
»/« abgetrennt wird.
Falls der Prozess über keine Suchberechtigungen im aktuellen
Nachschlage-Verzeichnis verfügt, wird der Fehler
EACCES
(»Keine Berechtigung«) zurückgeliefert.
Falls die Komponente nicht gefunden wird, wird der Fehler
ENOENT
(»Datei oder Verzeichnis nicht gefunden«)
zurückgeliefert.
Falls eine Komponente gefunden wird, aber weder ein Verzeichnis noch ein
symbolischer Link ist, wird der Fehler
ENOTDIR (»Ist kein
Verzeichnis«) zurückgeliefert.
Falls die Komponente gefunden wird und ein Verzeichnis ist, wird das aktuelle
Nachschlage-Verzeichnis auf dieses Verzeichnis gesetzt und zur nächsten
Komponenten gewechselt.
Falls die Komponente gefunden wird und ein symbolischer Link ist, wird zuerst
dieser symbolische Link aufgelöst (mit dem anfänglichen
Nachschlage-Verzeichnis). Im Fehlerfall wird dieser Fehler
zurückgeliefert. Falls das Ergebnis kein Verzeichnis ist, wird der
Fehler
ENOTDIR zurückgeliefert. Falls die Auflösung des
symbolischen Links erfolgreich ist und ein Verzeichnis zurückliefert,
wird das aktuelle Nachschlage-Verzeichnis auf dieses Verzeichnis gesetzt und
zur nächsten Komponente gewechselt. Bachten Sie, dass dieser
Auflösungsprozess Rekursionen enthalten kann, falls die
Präfixkomponente (»dirname«) eines Pfadnamens einen
Dateinamen enthält, der ein symbolischer Link ist, der sich auf ein
Verzeichnis auflöst (wobei die Präfixkomponente dieses
Verzeichnisses einen symbolischen Link enthalten könnte und so weiter).
Um den Kernel gegen eine Stapelüberlauf und auch eine
Diensteverweigerung zu schützen, gibt es Begrenzungen zur
Rekursionstiefe und der maximalen Anzahl an gefolgten symbolischen Links. Ein
Fehler
ELOOP wird zurückgeliefert, wenn das Maximum
überschritten wurde (»Zu viele Ebenen aus symbolischen
Links«).
Derzeit ist in Linux die maximale Anzahl von beim Auflösen von Pfadnamen
gefolgten symbolischen Links auf 40 begrenzt. In Linux vor 2.6.18 war die
Begrenzung der Rekursionstiefe 5. Seit Linux 2.6.18 wurde diese Begrenzung auf
8 erhöht. In Linux 4.2 wurde der Code für die
Pfadnamenauflösung überarbeitet, um die Verwendung von Rekursion
zu beseitigen, so dass die einzige verbliebene Begrenzung die maximalen 40
Auflösungen für den gesamten Pfadnamen ist.
Die Auflösung symbolischer Links während dieser Stufe kann mittels
openat2(2) durch den gesetzten Schalter
RESOLVE_NO_SYMLINKS
verhindert werden.
Das Nachschlagen der finalen Komponente des Pfadnamens erfolgt genau wie der von
allen anderen Komponenten, wie im vorherigen Schritt beschrieben, mit zwei
Unterschieden: (i) die finale Komponente muss kein Verzeichnis sein (zumindest
soweit, wie der Pfadauflösungsprozess betroffen ist – es mag ein
Verzeichnis oder keines sein müssen, abhängig von den
Anforderungen des spezifischen Systemaufrufs) und (ii) es ist nicht unbedingt
ein Fehler, falls die Komponente nicht gefunden wird – vielleicht wird
sie gerade erstellt. Die Details der Behandlung des abschließenden
Eintrags werden in den Handbuchseiten der jeweiligen Systemaufrufe
beschrieben.
Herkömmlicherweise hat jedes Verzeichnis zwei Einträge
(».« und »..«), die sich auf das Verzeichnis
selbst bzw. sein übergeordnetes Verzeichnis beziehen.
Der Pfadauflösungsprozess wird annehmen, dass diese zwei Einträge
ihre konventionelle Bedeutung haben, unabhängig davon, ob sie im
physischen Dateisystem tatsächlich vorhanden sind.
Sie können nicht höher als die Wurzel aufsteigen:
»/..« ist zu »/« identisch.
Nach einem Befehl
mount Gerät Pfad bezieht sich der Pfadname
»Pfad« auf die Wurzel der Dateisystemhierarchie auf dem
Gerät »Gerät« und nicht auf etwas, worauf es sich
vorher bezog.
Sie können sich außerhalb des eingehängten Dateisystems
bewegen: »Pfad/..« bezieht sich auf das übergeordnete
Verzeichnis von »Pfad« außerhalb der
Dateisystemhierarchie von »Gerät«.
Durchlauf von Einhängepunkten kann mittels
openat2(2) mit dem
gesetzten Schalter
RESOLVE_NO_XDEV verhindert werden (beachten Sie
allerdings, dass dies auch den Durchlauf von Bind-Einhängungen
beschränkt).
Falls ein Pfadname mit einem »/« endet, der die Auflösung
der vorherigen Komponente gemäß Schritt 2 erzwingt: die
Komponente vor dem Schrägstrich existiert entweder und wird zu einem
Verzeichnis aufgelöst oder sie benennt ein Verzeichnis, das sofort nach
der Auflösung des Pfadnamens erstellt werden soll. Andernfalls wird ein
abschließender »/« ignoriert.
Falls die letzte Komponente des Pfadnamens ein symbolischer Link ist,
hängt es vom Systemaufruf ab, ob die Datei, auf die referenziert wird,
ein symbolischer Link ist oder das Ergebnis der Pfadauflösung seiner
Inhalte. Beispielsweise wird der Systemaufruf
lstat(2) auf einem
symbolischen Link agieren, während
stat(2) auf der Datei agiert,
auf die der symbolische Link zeigt.
Es gibt eine maximale Länge für Pfadnamen. Falls der Pfadname
(oder ein Zwischenpfadname, der beim Auflösen von symbolischen Links
erhalten wurde) zu lang ist, wird ein Fehler
ENAMETOOLONG
zurückgeliefert (»Der Dateiname ist zu lang«).
Im ursprünglichen UNIX bezogen sich leere Pfadnamen auf das aktuelle
Verzeichnis. Heutzutage beschließt POSIX, dass ein leerer Pfadname
nicht erfolgreich aufgelöst werden darf. Linux liefert in diesem Fall
ENOENT zurück.
Die Berechtigungsbits einer Datei bestehen aus drei Gruppen von drei Bits: siehe
chmod(1) und
stat(2). Die erste Gruppe der drei wird verwandt,
wenn die effektive Benutzerkennung des aufrufenden Prozesses identisch zu der
Eigentümerkennung der Datei ist. Die zweite Gruppe der drei wird
verwandt, wenn die Gruppenkennung der Datei entweder mit der effektiven
Gruppenkennung des aufrufenden Prozesses übereinstimmt oder eine der
ergänzenden Gruppenkennungen des aufrufenden Prozesses ist (wie durch
setgroups(2) gesetzt). Falls nichts davon zutrifft, wird die dritte
Gruppe verwandt.
Von den drei verwandten Bits bestimmt das erste Bit die Leseberechtigung, das
zweite die Schreibberechtigung und das letzte die Ausführberechtigung
im Falle von gewöhnlichen Dateien oder die Suchberechtigung im Falle
von Verzeichnissen.
Linux verwendet fsuid anstelle der effektiven Benutzerkennung bei
Berechtigungsprüfungen. Normalerweise ist die fsuid identisch mit der
effektiven Benutzerkennung, aber die fsuid kann mit dem Systemaufruf
setfsuid(2) geändert werden.
(Hier steht »fsuid« für etwas wie
»Dateisystembenutzerkennung«. Das Konzept wurde für die
Implementierung von NFS-Servern im Benutzerbereich zu einem Zeitpunkt
benötigt, zu dem ein Prozess ein Signal zu einem anderen Prozess mit
der gleichen effektiven Benutzerkennung senden konnte. Dies ist jetzt
veraltet. Niemand sollte
setfsuid(2) verwenden.)
Auf ähnliche Weise verwendet Linux die fsgid
(»Dateisystemgruppenkennung«) anstelle der effektiven
Gruppenkennung. Siehe
setfsgid(2).
Auf einem traditionellen UNIX-System ist der Superuser (
root,
Benutzerkennung 0) allmächtig und umgeht alle
Berechtigungseinschränkungen beim Zugriff auf Dateien.
Unter Linux sind die Superuser-Privilegien in Capabilitys aufgeteilt (siehe
capabilities(7)). Zwei Capabilitys sind für
Dateiberechtigungsüberprüfungen relevant:
CAP_DAC_OVERRIDE und
CAP_DAC_READ_SEARCH. (Ein Prozess hat diese
Capabilitys, falls seine fsuid 0 ist.)
Die Capability
CAP_DAC_OVERRIDE setzt alle Berechtigungsprüfungen
außer Kraft, aber gewährt die Ausführberechtigung nur,
falls mindestens eines der drei Ausführ-Berechtigungs-Bits der Datei
gesetzt ist.
Die Capability
CAP_DAC_READ_SEARCH gewährt Lese- und
Suchberechtigungen für Verzeichnisse und Leseberechtigungen für
gewöhnliche Dateien.
readlink(2),
capabilities(7),
credentials(7),
symlink(7)
Die deutsche Übersetzung dieser Handbuchseite wurde von Helge Kreutzmann
<
[email protected]> erstellt.
Diese Übersetzung ist Freie Dokumentation; lesen Sie die
GNU
General Public License Version 3 oder neuer bezüglich der
Copyright-Bedingungen. Es wird KEINE HAFTUNG übernommen.
Wenn Sie Fehler in der Übersetzung dieser Handbuchseite finden, schicken
Sie bitte eine E-Mail an die
Mailingliste
der Übersetzer