Da ich nun schon öfters darauf angesprochen wurde und auch leider kein Link auf der Projektseite existiert, habe ich mich mal eben hingesetzt, um den Neulingen unter den Unix-Anwendern das Konzept der Dateirechte unter Unix näher zu bringen.
Jede Datei und jedes Verzeichnis hat unter Unix verschiedene Zugriffsrechte.
Lässt man sich mal ein Verzeichnis mit ls -l
anzeigen, so hat die Ausgabe ungefähr folgendes Aussehen:
philipp@P150:/home/philipp/gdi1 > ls -l total 60 -rw-r--r-- 1 philipp users 23215 Feb 27 22:17 objio.zip drwxr-xr-x 5 philipp users 1024 Feb 27 22:24 project/ -rw-r--r-- 1 philipp users 34816 Feb 27 1995 x.tar lrwxrwxrwx 1 philipp users 18 Feb 27 22:00 test -> /test -rwxr-xr-- 2 philipp student 135 Jan 12 13:55 help.perl
Das bedeutet in etwa folgendes:
Spalte | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|
Bedeutung | Rechte | Hardlinks | Besitzer | Gruppe | Größe | Datum | Dateiname |
Beispiel | -rwxr-xr-- | 5 | philipp | student | 1024 | Feb 27 1995 | objio.zip |
Wir wollen uns aber zunächst nur mit den Rechten, dem Besitzer und der Gruppe beschäftigen.
Jede Datei bzw. jedes Verzeichnis gehört einem Besitzer. Er kann die Rechte für eine andere Gruppe und alle übrigen Benutzer festlegen.
Beachte die Unterscheidung zwischen Besitzer einer Datei und deren Benutzer: Der Besitzer stellt eine Ressource (Programm,Information) zur Verfügung, die dann von anderen Benutzern genutzt werden kann. Der Besitzer entscheidet deswegen auch, wer wie was mit seiner Ressource machen darf.
Zunächst gehört jeder Benutzer (mindestens) einer Gruppe an. Diese Gruppenzugehörigkeit wird meistens so eingerichtet, das Personen, die am gleichen Projekt arbeiten, in einer gemeinsamen Gruppe sind. Jede Datei ist exakt einer Gruppe zugeordnet, für deren Mitglieder (bis auf den Besitzer dann die sog. Gruppenrechte der Datei gelten.
Die 1. Angabe ist noch einmal in verschiedene Sparten unterteilt:
t rwx rwx rwx
Die 1. Spalte gibt den Typ des Eintrags an:
|
So dann folgen 3 Blöcke à 3 Zeichen. Der 1. Block gibt dabei die Rechte für den Besitzer an, der 2. Block die Rechte für die Benutzer, die zu der Gruppe gehören, und der 3. Block gibt die Rechte für alle übrigen Benutzer an.
Jeder dieser 3 Blöcke hat dabei folgende Bedeutung:
Zeichen | Bedeutung | Oktal | Beschreibung |
---|---|---|---|
r | Leserechte | 0444 | Der Benutzer kann sich die Datei und das Verzeichnis anzeigen lassen |
w | Schreibrechte | 0222 | Der Benutzer kann die Datei verändern und überschreiben bzw. Dateien in dem Verzeichnis anlegen oder dieses löschen |
Dateien | |||
x | Ausführrechte | 0111 | Die Datei ist ein Programm, das direkt ausgeführt werden kann. Für Binär-Programme (ELF,COEFF,…) reicht alleine das Ausführrechte, Skript-Programme (Shell,Perl,Python,…) müssen zusätzlich auch das Leserecht haben! |
s | Start als Besitzer | 4000 | Das Programm wird so gestartet, als ob es der Besitzer der Datei starten würde |
s | Start als Gruppe | 2000 | Das Programm wird so gestartet, als ob ein Gruppenmitglied die Datei aufrufen würde |
Verzeichnisse | |||
x | Suchrecht | 0111 | Der Anwender darf in das Verzeichnis wechseln und auf Einträge zugreifen, die er bereits (anderweitig) kennt |
s | Gruppenbesitz | 2000 | Alle Dateien, die in das Verzeichnis geschrieben werden, gehören automatisch der Gruppe, der auch das Verzeichnis gehört |
t | Löschschutz | 1000 | Nur der Besitzer der Dateien kann diese löschen, auch wenn andere Benutzer Schreibrechte auf das Verzeichnis haben |
Die Zugriffsrechte können statt in der symbolischen Schreibweise auch direkt als Oktalwert angeben: Im Gegensatz zu dem sonst übliche Zehner-System mit den Ziffern 0 bis 9 nutzt das Oktal-System nur die Ziffern 0 bis 7. Damit lassen sich 8 Zustände kodieren, was genau den 8 Möglichkeiten der Rechte pro Besitzer, Gruppe und Anderen entspricht. Die 4. (vorderste Stelle links) kodiert dabei ggf. die zusätzlichen SUID, SGID und Sticky-Bits, die im nächsten Abschnitt genauer beschrieben werden. Für die Berechnung des Oktalwertes müssen lediglich pro Block jeweils die Werte 4 für das Leserecht, 2 für das Schreibrecht und 1 für das Ausführ- bzw. Suchrecht addiert werden.
Die SUID- (Set User Identifier) bzw. SGID-Funktionalität (Set Group Identifier) ist eigentlich nur für Programme interessant, ist aber auch nicht ungefährlich. Bei einigen Anwendungsfällen kann es sein, daß die Rechte, die ein normaler Benutzer hat, nicht ausreichen. Durch das Setzen des SUID-Bits erhält das Programm bei Ausführung die Rechte, die der Besitz des Programms normalerweise hat. Das SGID-Bit dagegen sorgt dafür, das das Programm bei Ausführung zusätzlich in die Gruppe aufgenommen wird, die die Datei hat. Für Verzeichnisse ergibt lediglich das SGID-Bit Sinn, hat dort aber eine gänzlich andere Bedeutung; dazu später mehr.
Klassisches Beispiel ist die Datei /etc/shadow, in der die Passwörter gespeichert sind: Normale Benutzter sollen sie nicht auslesen oder beliebig verändern können, wollen aber dennoch ihr eigenes Passwort ändern können. Deshalb gehört die Datei dem Benutzer root, ist der Gruppe shadow zugeordnet und hat die Rechte 0640. Damit hat zunächst nur root die notwendigen Rechte, die Datei zu verändern.
Damit auch andere Personen ihr Passwort ändern können, hat root das vertrauenswürdige Programm
/usr/bin/passwd
installiert. Vertrauenswürdig heißt hier, daß dieses Programm ein sehr begrenztes Funktionsspektrum besitzt und nur eine Aufgabe ausführt, die aber sehr sicher. Es überprüft neben dem aufrufenden Benutzer auch die Dateirechte und den Dateiinhalt von /etc/shadow, damit es nicht fälschlicherweise ausgetickst oder missbraucht wird, um andere Benutzerpasswörter oder Dateien zu verändern.Jeder Benutzer kann dieses Programm aufrufen, da es die Rechte 4755 hat. Ohne das SUID-Bit würden allerdings die Rechte des aufrufenden Benutzers gelten, der /etc/shadow nicht einmal lesend öffnen darf. Durch das gesetzte SUID-Bit hat root allerdings seine Rechte an das Programm delegiert: Bei der Ausführung wird so getan, als ob root das Programm selber ausführen würde, wodurch das Programm die nötigen Rechte hat, /etc/shadow auch zu verändern. So hat jeder Benutzer die Möglichkeit, sein Passwort zu ändern.
Da SUID- und SGID-Bit nur bei Programmen mit Ausführrecht bzw. SGID auch bei Verzeichnissen mit Suchrecht Sinn ergibt, werden die gesetzten Bits dadurch angezeigt, daß das Benutzer-x
-Bit bzw. Gruppen-x
-Bit durch jeweils ein kleines s
ersetzt werden.
Sind die zugehörigen x
-Bits jedoch nicht gesetzt, wird stattdessen ein großes S
angezeigt.
Man sollte verstehen, daß Linux zwischen der Datei selbst und ihren Namen unterscheidet.
Jede Datei hat zunächst nur eine eindeutige Nummer, die sog. INode-Nummer.
Über diese Nummer kann man eine Datei nicht direkt ansprechen, sie dient nur innerhalb des Betriebssystemkerns für die Identifizierung der Datei.
Damit auf ein solches Dateiobjekt zugegriffen werden kann, werden dem Dateiobjekt ein oder auch mehrere Namen zugewiesen.
(Mich gibt es nur einmal, aber ich nenne mich ich
, meine Eltern nennen mich Sohn
, meine Schwestern mich Bruder
und alle anderen rufen mich Philipp
.)
Diese Namen werden als Verzeichniseinträge bezeichnet und sind nicht viel mehr als eine simple Zuordnung von einem Namen zu einer INode-Nummer.
(Wenn ich xyz
sage, meine ich die Datei mit der Nummer 123
.)
Hat ein Dateiobjekt mehr als einen Namen, nennt man diese Einträge auch Hardlinks.
Alle Namenseinträge müssen allerdings auch irgendwo gespeichert werden, nämlich in einem Verzeichnis (vergleichbar einem Telefonbuch). Dieses Verzeichnis ist aber selber auch wieder ein Dateiobjekt, hat also auch eine eigene INode(-Nummer) und einen Namen. (Im Unterschied zu normalen Dateien dürfen Verzeichnisse nur einen Namen haben, damit es keine Zyklen zwischen diesen gibt.)
Daraus ergeben sich auch, warum man zum Löschen einer Datei keine Rechte an der zu löschenden Datei selbst braucht: Beim Löschen wird lediglich der Verzeichniseintrag entfernt, und dazu braucht man eben das Schreibrecht für das Verzeichnis. Erst wenn ein Dateiobjekt alle seine Namen verloren hat, d.h. alle Verzeichniseinträge gelöscht wurden, wird es wirklich gelöscht.
Das Sticky-Bit (Löschschutz, o=t
, 1000
) bietet noch einen zusätzlichen Schutz, der z.B. beim Verzeichnissen wie /tmp Anwendung findet:
Jeder Benutzer soll darin eigene Dateien anlegen können (er benötigt also Schreibrechte für das Verzeichnis, um den Namen eintragen zu können), aber nur er selbst soll sie auch wieder löschen dürfen (alle anderen Benutzer haben zwar auch Schreibrechte auf dem Verzeichnis, dürfen dies aber trotzdem nicht ausüben).
Durch das Setzen des t
-Bits wird genau diese Zusatzfunktion realisiert: Zum Löschen muß der Benutzer nicht nur das Schreibrecht für das Verzeichnis haben, sondern er muß zusätzlich auch der Besitzer der zu löschenden Datei sein.
Bei ls
wird das gesetzte t
-Bit ähnlich wie bei den s
-Bits mit dem x
-Bit verschmolzen:
Ein kleines t
steht für gesetztes Sticky-Bit bei vorhandenen Suchrechten, ein großes T
bei fehlenden Suchrechten.
Um die Rechte einer Datei oder eines Verzeichnisses zu ändern, gibt es das Unix-Kommando chmod
(von CHangeMODus).
Dabei kann man entweder die symbolische Schreibweise verwenden oder direkt den oktalen Wert angeben.
chmod MODUS[,MODUS] DATEIEN
Da sich die Zugriffsrechte in drei Sparten teilen, gibt es in der symbolischen Schreibweise noch folgende Zeichen mit Zusatzbedeutungen:
u | Einstellungen betreffen nur den Benutzer |
---|---|
g | Einstellungen betreffen nur die Gruppe |
o | Einstellungen betreffen nur den Rest |
a | Einstellungen betreffen Alle |
= | Rechte setzen |
+ | Rechte hinzufügen |
- | Rechte entfernen |
Mann kann die Rechte entweder direkt für alle angeben oder aber auch nur die Änderungen zum jetzigen Stand angeben. Um z.B. dem Benutzer alle Rechte, der Gruppe Lese- und Ausführrechte und dem Rest nur Leserechte auf die Datei meinProgramm zu geben, kann man folgende äquivalenten Befehle ausführen:
chmod 754 meinProgramm
chmod u=rwx,g=rx,o=r meinProgramm
Will man alle Dateien im aktuellen Verzeichnis für dir Gruppe les-/schreibbar machen und allen anderen Personen den Lesezugriff verweigern, ohne andere Einstellungen zu verändern, kann man das mit chmod g+rw,o-r *
erledigen.
Achtung:
Es gibt eine seltsame Ausnahme, wo die oktale Schreibweise nicht funktioniert, und zwar beim Entfernen des SGID-Bits von Verzeichnissen.
Dieses kann nur per chmod g-w ./dir
entfernt werden, nicht aber z.B. mit chmod 0755 ./dir
.
Benutzer gönnen auch mehreren Gruppen angehören. Diese statische Zugehörigkeit zu weiteren Gruppen wird über die Datei /etc/group festgelegt. Zusätzlich können aber weitere Gruppen dynamisch hinzukommen, z.B. kann PAM Benutzern Zugriff auf solche Gruppen wie floppy, cdrom, audio, video gewähren, nur wenn diese sich direkt an der Konsole eines Rechners anmelden.
Um diese Gruppen aufzulisten, gibt es u.a. den Befehl groups
.
Je nach Betriebssystem kann man sich das auch mit id
anzeigen lassen.
Ersterer Befehl zeigt deswegen alle Gruppen an, die der aktuell angemeldete Benutzer mit diesem Prozess hat.
Letzterer Befehl gibt dagegen nur die statische Zugehörigkeit an, zusätzlicher aber auch, zu welcher Gruppe man primär gehört.
Standardmäßig gehören alle Dateien, die man anlegt, zu dieser Primärgruppe.
Man kann jedoch mit newgrp
die Primärgruppe temporär fur Kindprozesse wechseln, so das ab dann alle neu angelegten Dateien zu der neuen Gruppe gehören.
Um nachträglich die Gruppenzugehörigkeit einer Datei zu ändern, gibt es den chgrp
-Befehl (von CHangeGRouP).
Als 1. Parameter übergibt man die neue Gruppe, danach folgen die zu verändernden Dateien.
chgrp inf1g18 *.java
Eine Ausnahme betrifft allerdings das Anlegen von neuen Einträgen in Verzeichnissen, deren SGID-Bit gesetzt ist. Sinnvoll ist dies z.B. für ein Projektverzeichnis, in dem mehrere Benutzer gemeinsam arbeiten und gegenseitig auf die Dateien zugreifen können sollen. Neuen Dateien werden dann nicht der Primärgruppe zugeordnet, sondern der Gruppe des übergeordneten Verzeichnisses. Für Verzeichnisse gilt sinngemäß das Selbe, zusätzlich vererbt sich aber auch das gesetzte SGID-Bit auf diese.
Genauso wie man die Gruppenzugehörigkeit ändern kann, kann man auch den Besitzer einer Datei ändern. Allerdings darf dies nur der Administrator root tun, da man ansonsten in Systemen, wo Benutzer nur eine begrenzte Menge an Speicherplatz zur Verfügung haben, seine Dateien einfach jemand anderes übertragen könnte.
Ähnlich dem Befehl zum Verändern von Gruppenzugehörigkeiten heißt der Befehl hierzu chown
(von CHangeOWNer).
Als 1. Parameter folgt der neue Benutzer, danach die zu verändernden Verzeichnisse und Dateien.
chown fmattern garbage.* NochEineDatei
Bei einigen Systemen kann man chown
und chgrp
zusammenfassen, indem man chown user:group *
ausführt.
Neue Dateien werden standardmäßig mit Lese- und Schreibrechten für alle (0666), Verzeichnisse zusätzlich mit Suchrechten für alle (0777) angelegt.
Mit dem Befehl umask
lassen sich diese Standardrechte einschränken.
Dabei ist zu beachten, das die als Oktalzahl angegebenen Rechte gerade nicht erteilt werden, d.h. die angegebenen Rechte werden von 0666
für Dateien und 0777
für Verzeichnisse sozusagen abgezogen (genauer: negiert Und-Verknüpft).
z.B. erhält man durch eine umask 077
nur alleine Rechte an neuen Dateien, während eine umask 027
zusätzlich der Gruppe Schreib- und bei Verzeichnissen auch noch Suchrechte lässt.
Wem es zu kompliziert ist, das selber auszurechnen, der kann auch direkt die gewünschten Rechte symbolisch angeben.
umask u=rw,g=rw,o=
ermöglicht nur dem Benutzer und seiner Gruppe Lese- und Schreibrechte und entspricht umask 0117
.
Zu beachten dabei ist aber immer, daß durch die umask
nie mehr Rechte vergeben werden als standardmäßig, sonder immer nur weniger.
d.h. beim Anlegen einer Datei mit umask 0000
wird diese Datei dadurch nicht plötzlich Ausführrechte erhalten.
Beispiel:chage
muß lediglich die Informationen aus/etc/shadow
lesen können, soll die Datei aber nicht verändern dürfen.-rw-r----- … root shadow … /etc/shadow -rwxr-sr-x … root shadow … /usr/bin/chage
/tmp
umask
sollte so eingestellt sein, daß neue Dateien auch für die Gruppe schreibbar bleiben (umask 0007
oder umask 0002
). Aus diesem Grund ist es sinnvoll, daß jeder Benutzer auch seine eigene primäre Gruppe hat: Seine neuen Dateien gehören erstmal seiner eigenen Gruppe an und bleiben so nur für ihn schreibbar. Befindet er sich aber in so einem solchen Projektverzeichnis, so können auch andere Gruppenmitglieder diese Dateien bearbeiten.
Wem das noch nicht reicht, es gibt auch noch so genannte Access Control Lists (ACL), du deutsch Zugriffskontrollisten.
Mit deren Hilfe kann man einzelnen Benutzern oder weiteren Gruppen noch weitergehende Lese-/Schreib-/Ausführungsrechte einräumen kann.
Allerdings funktioniert das nicht auf allen Computern und mit allen Dateisystemen.
Wer sich dafür interessiert, der möge einen Blick auf das Kommando chacl
bzw. setfacl
werfen.
Zu beachten ist, dass es zwei Implementierungen von ACLs gibt:
Beide Varianten sind nicht deckungsgleich und eine verlustfreie Übersetzung der einen Variante in die andere ist nicht möglich. Im folgenden geht es darum ausschließlich um POSIX-ACLs.
Unter Solaris unterstützt das UFS-Dateisystem ACLs, was auch über NFS funktionieren sollte. Linux werden unterstützen inzwischen viele moderne Dateisysteme ACLs:
Neben dem bereits oben beschriebenen Benutzer, einer Benutzergruppe und dem Rest der Welt können über ACLs weiteren Benutzern und Gruppen weitere Rechte eingeräumt werden. Dabei werden die gleichen Rechte für Lesen, Schreiben und Ausführen/Durchsuchen wie oben verwendet.
setfacl -m u:$USER:$PERM ./datei
gibt dem genannten Benutzer die angegebenen Rechte bezüglich der Datei.
Lässt man $USER weg, wird standardmäßig der Besitzer der Datei verwendet.
Das u: darf man auch mit user: ausschreiben oder es sogar weglassen.
setfacl -m g:$GROUP:$PERM ./datei
gibt einer Gruppe die angegebenen Rechte.
Lässt man $GROUP weg, wir standardmäßig die Gruppe der Datei verwendet.
Das g: darf man auch mit group: ausschreiben.
setfacl
kann als Ersatz für chmod
verwendet werden, denn mit setfacl -m o:$PERM ./datei
kann man auch die Berechtigungen für den Rest der Welt ändern.
Auch hier kann man das o: mit other: ausschreiben.
ACL-Einträge lassen sich per setfacl -x u:$USER
bzw. setfacl -x g:$GROUP
einzeln wieder entfernen.
Mit setfacl -b
dagegen kann man alle ACLs entfernen; zurück bleiben dann nur die standard UNIX-Rechte.
Bei der Anzeige von Verzeichnissen mittels ls -l
zeigt sich ein entscheidenden Unterschied:
$ touch foo bar $ setfacl -m u:rw- foo $ ls -l insgesamt 0 -rw-rw-r-- 1 philipp users 0 14. Jul 06:57 bar -rw-rw-r--+ 1 philipp users 0 14. Jul 06:57 foo
Bei der Datei Datei foo steht am Ende der Berechtigungen ein Plus: Dies ist ein Zeichen dafür, dass für diese Datei ACLs gesetzt sind. Gleichzeitig bedeutet dies, dass der mittlere Teil, in dem bisher die Berechtigungen für die Gruppe angezeigt wurden, eine andere Bedeutung hat: Dort wird nun die sog. Maske angezeigt, die die effektive Rechte für alle zusätzlichen Benutzer und Gruppen limitiert. Durch das (nachträgliche) ändern der Maske kann man also z.B. allen Benutzern auf einen Schlag das Schreibrecht nehmen oder später auch wieder erlauben.
Geändert wird die Maske über das Ändern der Gruppenberechtigung:
Ein chmod g-w ./foo
entfernt das Schreibrecht aus der Maske, was sich indirekt dann auch auf die Gruppe users auswirkt und denen das Schreibrecht entfernt.
Das selbe erreicht man über ein setfacl -m m:r-- ./foo
, wobei man hier auch das m: mit mask: ausschreiben kann.
Zusätzlich wirkt es sich aber auch auf alle anderen Benutzer und Gruppen aus, so dass danach auch der Benutzer nobody kein Schreibrecht mehr auf diese Datei besitzt.
Zu sehen ist das deutlich, wenn man sich die ACLs mit getfacl
anzeigen lässt:
$ getfacl foo # file: foo # owner: philipp # group: users user::rw- user:nobody:rw- #effective:r-- group::rw- #effective:r-- mask::r-- other::r--
Will man dagegen nur der Gruppe users die Schreibrecht entfernen, muss man dafür setfacl -m g:users:r-- ./foo
verwenden.
ls -l
zeigt an der bisherigen Stelle der Gruppenrechte weiterhin rw-, obwohl dir Gruppe nobody effektiv weniger Rechte hat.
An Verzeichnissen kann man zusätzlich Default-ACL notieren, die sich automatisch auf alle neuen Einträge vererben, die innerhalb dieses Verzeichnisses neu angelegt werden.
Vergleichbar ist das mit den Projektverzeichnissen von oben, wo das SGID-Bit diese Rolle übernommen hat.
Gesetzt, geändert und gelöscht werden können diese Default-ACL ebenfalls über setfacl
:
Jedem ACL-Eintrag muss dafür ein d: bzw. default: vorangestellt werden.
Zu beachten dabei ist, das eine nachträgliche Änderung dieser Default-ACLs sich nicht auf bereits bestehende Dateien oder Verzeichnisse auswirkt; dafür müssen diese gesondert angepasst werden.
$ mkdir ./project $ setfacl -m d:u:nobody:rw- ./project $ touch ./project/foo $ getfacl --omit-header --skip-base --recursive ./project user::rwx group::rwx other::r-x default:user::rwx default:user:nobody:rw- default:group::rwx default:mask::rwx default:other::r-x user::rw- user:nobody:rw- group::rwx #effective:rw- mask::rw- other::r--