Aus Linux-Magazin 06/2015

Abgefragt: Feinheiten des Unix-Rechtemanagements

© Sebastian Gauert, 123RF

Wer einen neuen IT-Job an Land ziehen möchte, sollte sich darauf einstellen, dass er im Einstellungsgespräch womöglich die beliebte Frage nach dem Sticky-Bit bei Unix-Betriebssystemen gestellt bekommt. Zumindest hier zahlt es sich aus, Bescheid zu wissen.

Eine gängige Frage bei Einstellungsgesprächen ist die nach dem so genannten Sticky-Bit. Ich persönlich stelle diese Frage nie, wenn ich einen Kandidaten durchleuchte, denn ich denke, wer die Antwort weiß, zeichnet sich höchstens durch gute Gesprächsvorbereitung aus. Ein Beweis für Fachkompetenz lässt sich daraus nicht ableiten. Aber viele große Firmen im Silicon Valley haben die Frage im Katalog, und als Spieler in der A-Klasse der Software-Industrie muss man selbstverständlich auch auf unnütze Fragen eine Antwort wissen.

Deshalb nimmt sich diesmal der Perl-Snapshot das Thema vor: Wozu ist das Sticky-Bit da? Wie immer, wenn es um knifflige Unix-Fragen geht, hilft das Buch von Michael Kerrisk [2] weiter. Der Wälzer mit mehr als 1500 Seiten ist als Papierbuch nur von praktizierenden Bodybuildern handhabbar, aber als E-Book leicht überallhin mitzunehmen.

Wer denkt, er wüsste schon alles über die Feinheiten der Programmierung unter Unix, kippt bei der Lektüre dieses Jahrhundertwerks aus den Schuhen: Selbst graubärtige Unix-Gurus fördern aus den Tiefen dieses Schinkens immer wieder verblüffende Tatsachen hervor.

Wer hätte zum Beispiel gewusst, dass ein User auf einem Unix-System eine Datei aus einem Verzeichnis löschen kann, obwohl er keine Schreibrechte an dieser Datei hat? Richtig: Erforderlich sind nur Schreib- und Ausführungsrechte für das Verzeichnis, in dem die Datei liegt. Listing 1 legt zu Demonstrationszwecken ein neues Verzeichnis »test« im aktuellen Verzeichnis an und gibt ihm mit dem oktalen Wert »0333« die Rechte »-wx-wx-wx« .

Listing 1

file-rm

01 #!/usr/local/bin/perl -w
02 use strict;
03 use Sysadm::Install qw( blurt );
04 use File::Path qw( rmtree );
05
06 mkdir "test";
07 blurt "data", "test/abc";
08 chmod 0333, "test";
09 chmod 0444, "test/abc";
10
11 # d-wx-wx-wx test
12 # -r--r--r-- test/abc
13
14 unlink "test/abc"
15 or die "unlink failed: $!";
16
17 rmtree "test";

Löschen ohne Rechte

Der anschließend mit »blurt()« aus dem CPAN-Modul Sysadm::Install erzeugten Datei »abc« weist die »chmod« -Anweisung in Zeile 9 mit »0444« die Rechte »-r–r–r–« zu. Alle User dürfen sie also lesen, aber nicht beschreiben. Dennoch läuft die »unlink« -Anweisung in Zeile 14 ohne Meckern durch, auch ein »rm -f test/abc« auf der Kommandozeile löscht die Datei ohne Rückfrage oder Fehler. Genau so ist es auch tatsächlich gemeint: Schreibrechte an einer Datei unter Unix erlauben das Modifizieren des Inhalts der Datei, Löschrechte hingegen regelt das Verzeichnis, in dem die Datei liegt, nicht die Datei selber.

Als weitere interessante Feinheit der Unix-Programmierung fällt im Listing 1 auf, dass das Verzeichnis »test« allen Usern mit »-wx-wx-wx« zwar Schreib- und Ausführungsrechte gewährt, aber keine Leserechte. Nach diesen Vorschriften kann das Skript das Verzeichnis also durchqueren und dabei schreibend darauf zugreifen, die in ihm enthaltenen Dateien jedoch nicht auflisten.

Da das Skript aber weiß, dass die Datei »test/abc« darin liegt, darf es sie auch löschen. Gehört die Datei einem anderen User, ändert sich nichts daran, dass Unix sie rücksichtslos löscht, wenn das Verzeichnis, in dem sie liegt, seine Zustimmung gegeben hat. Das führt naturgemäß zu Problemen, zu deren Behebung die Unix-Väter in grauer Vorzeit eine recht zusammengeschusterte Lösung fanden, aber davon später.

Wegerecht

Was bedeutet das »x« , wenn ein Verzeichnis die Rechte »-wx-wx-wx« anzeigt? Es regelt das Wegerecht zum Durchqueren des Verzeichnisses. Egal ob ein Kommando auf den Inhalt einer Datei »sub/file« schreibend oder lesend zugreift oder mit »sub/sub1« in ein im Verzeichnis »sub« liegendes Unterverzeichnis »sub1« hinabsteigt – es benötigt Ausführungsrechte am Verzeichnis »sub« .

Wie Listing 2 zeigt, heißt das aber nicht, dass ein Kommando, das auf das Verzeichnis »top/sub/sub1« zugreift, Ausführungsrechte an allen Pfadkomponenten »top« , »sub« und »sub1« benötigt. Hat ein Skript etwa sein aktuelles Verzeichnis vor dem Einrichten der Zugangssperre mit »chdir()« auf »top/sub/sub2« gesetzt, kann es mit der relativen Pfadangabe »../sub1« sehr wohl auch dann auf »sub1« zugreifen, wenn später »top« die »x« -Rechte wie in Zeile 21 in Listing 2 entzogen bekommt (Abbildung 1).

Listing 2

dir-traverse

01 #!/usr/local/bin/perl -w
02 use strict;
03 use Test::More;
04 use Test::Exception;
05 use File::Temp qw( tempdir );
06 use Sysadm::Install qw( blurt slurp
07 cd cdback );
08
09 my $ROOT_DIR = tempdir( CLEANUP => 1 );
10
11 # Read via a relative path while the abso-
12 # lute path doesn't have traversal rights.
13 dirmk( "top", 0700 );
14 dirmk( "top/sub", 0700 );
15 dirmk( "top/sub/sub1", 0700 );
16 dirmk( "top/sub/sub2", 0700 );
17
18 blurt "content",
19 "$ROOT_DIR/top/sub/sub1/file";
20 cd "$ROOT_DIR/top/sub/sub2";
21 chmod 0600, "$ROOT_DIR/top";
22
23 throws_ok
24 { slurp( "$ROOT_DIR/top/sub/sub1/file" ) }
25 qr/Permission denied/, "abs path fails";
26
27 is slurp( "../sub1/file" ),
28 "content", "rel path ok";
29
30 cdback;
31 done_testing();
32
33 ###########################################
34 sub dirmk {
35 ###########################################
36 my( $dir, $perm ) = @_;
37
38 my $path = "$ROOT_DIR/$dir";
39 mkdir $path or die "$!";
40 chmod $perm, $path or die "$!";
41 }
Abbildung 1: Gewährt das Verzeichnis »top« kein Wegerecht, schlägt der Zugriff auf »sub1« über den absoluten Pfad zwar fehl, doch der relative Pfad von »sub2« nach »sub1« ist passierbar.

Abbildung 1: Gewährt das Verzeichnis »top« kein Wegerecht, schlägt der Zugriff auf »sub1« über den absoluten Pfad zwar fehl, doch der relative Pfad von »sub2« nach »sub1« ist passierbar.

Listing 2 zeigt eine mit Test::More implementierte Testsuite zum Verifizieren dieser Tatsache. Die Funktion »throws_ok()« in Zeile 23 stammt aus dem CPAN-Modul Test::Exception. Sie fängt auftretende Fehler ab und erlaubt es, sie mittels regulärer Ausdrücke mit Fehlern zu vergleichen, die die Testsuite erwartet. So tritt beim Zugriff über den absoluten Pfad vorhersehbar ein “Permission denied”-Fehler auf, während eine relative Pfadangabe wie in Zeile 27 zum Erfolg führt:

$ ./dir-traverse
ok 1 - abs path fails
ok 2 - rel path ok
1..2

Wer übrigens denkt, dass der Trick mit dem relativen Pfad auch funktioniert, falls nicht »top« , sondern »top/sub« das Wegerecht storniert, irrt: Wenn ein Skript sich in »top/sub/sub2« befindet und mittels »../sub1« auf »top/sub/sub1« zugreift, durchschreitet es »top/sub« und benötigt deshalb dort das Wegerecht.

Klebriges Zeug

Das eingangs erwähnte Kuriosum, dass ein User eine Datei löschen darf, auch wenn ihm die Datei selbst keine Schreibrechte gewährt, führt zu Problemen, falls sich mehrere User ein Verzeichnis teilen. Legen zum Beispiel die User A und B die Dateien »file-a« und »file-b« in »/tmp« ab, sollte es A verwehrt bleiben, »file-b« zu löschen. Doch wie soll das gehen, wenn nicht die Datei selbst, sondern das enthaltende Verzeichnis den Löschzugriff regelt?

Damit jeder User auf »/tmp« zugreifen darf, sind dessen Rechte auf »rwxrwxrwx« eingestellt. Dies eröffnet allerdings auch beliebigen Usern Löschrechte an allen dort eingestellten Dateien, und deshalb behalfen sich die Unix-Väter mit einem Trick: Sie erfanden ein spezielles Sticky-Bit, das

chmod +t /tmp

setzt und daran zu erkennen ist, dass das »ls« -Kommando die Verzeichnisrechte folgendermaßen anzeigt:

$ ls -ld /tmp
drwxrwxrwt 7 root root 4096 Apr 13 00:17 /tmp

Statt eines abschließenden »rwx« steht nun ein »rwt« in der Zugriffskennung, und Unix stellt deswegen die Zugriffsregeln in diesem Verzeichnis auf den Kopf. Auf einmal darf nun nicht mehr jeder beliebige User Einträge löschen, sondern nur noch der Eigentümer des jeweiligen Eintrags.

Genau deshalb setzt jedes Unix-System im Verzeichnis »/tmp« das Sticky-Bit. Es verhindert, dass User sich gegenseitig ihre temporären Dateien weglöschen. Schreib- und Leserechte am Verzeichnis sind nach wie vor für alle vorhanden.

Bonuspunkte

Bonuspunkte erhält der Kandidat beim Einstellungsgespräch übrigens, falls er erklären kann, wann Unix das Sticky-Bit eines Verzeichnisses mit »t« und wann mit »T« anzeigt. Mit dem abschließenden »t« in »rwt« verdeckt der Hack mit dem Sticky-Bit nämlich jenes Bit, das eigentlich Ausführungsrechte der Allgemeinheit am Verzeichnis anzeigt. Es lässt sich nicht mehr sagen, ob vor dem Setzen des Sticky-Bits »rw-« oder »rwx« eingestellt war. Deshalb zeigt Unix »rwt« an, falls »rwx« vorlag, und »rwT« , falls die Ausführungsrechte fehlen, also vorher »rw-« dort stand.

Wer auch noch weiß, dass nicht nur Verzeichnisse, sondern auch Dateien ein Sticky-Bit führen können, das aber etwas völlig anderes regelt, beweist, dass er die Vorbereitung ernst genommen und Kerrisks Standardwerk studiert hat. Der Kandidat erhält 100 Punkte und kommt sicher in die nächste Runde!

Online PLUS

Im Screencast demonstriert Michael Schilli das Beispiel: https://www.linux-magazin.de/Ausgaben/2015/06/plus

Infos

  1. Listings zu diesem Artikel: ftp://www.linux-magazin.de/pub/listings/magazin/2015/06/Perl
  2. Michael Kerrisk, “The Linux Programming Interface: A Linux and UNIX System Programming Handbook”: No Starch Press, 2010

Der Autor

Michael Schilli arbeitet als Software-Engineer bei Yahoo in Sunnyvale, Kalifornien. In seiner seit 1997 erscheinenden Kolumne forscht er jeden Monat nach praktischen Anwendungen der Skriptsprache Perl. Unter mailto:mschilli@perlmeister.com beantwortet er gerne Fragen.

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDFUmfang: 3 HeftseitenPreis €0,99
(inkl. 19% MwSt.)
LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben