Sind die nicht leeren Unterverzeichnisse eines anderen Benutzers vor dem Löschen in meinem Verzeichnis geschützt?

7

In der folgenden Situation ls -alh

total 0
drwxrwx--- 1 user http  20 Nov 30 08:08 .
drwxrws--- 1 user http 310 Nov 30 08:07 ..
drwx------ 1 http http  10 Nov 30 08:08 empty-subdir
drwx------ 1 http http  12 Nov 30 08:08 non-empty-subdir

wo zwei Unterverzeichnisse existieren (nicht in meinem Besitz), die ich aufführe als:

sudo ls empty-subdir -alh
total 0
drwx------ 1 http http 10 Nov 30 08:08 .
drwxrwx--- 1 user http 20 Nov 30 08:08 ..

sudo ls non-empty-subdir -alh
total 0
drwx------ 1 http http 12 Nov 30 08:08 .
drwxrwx--- 1 user http 20 Nov 30 08:08 ..
drwx------ 1 http http  0 Nov 30 08:08 subdir

Der Unterschied zwischen den beiden Unterverzeichnissen besteht darin, dass das nicht leere Verzeichnis non-empty-subdireinen Ordner enthält.

Meine Frage ist, ob rm -rfich beim Versuch , die Unterverzeichnisse zu entfernen, beabsichtigt Ergebnisse erhalte:

$ rm empty-subdir -rf
$ rm non-empty-subdir -rf
rm: cannot remove 'non-empty-subdir': Permission denied
$ ls -alh
total 0
drwxrwx---+ 1 user http  10 Nov 30 08:14 .
drwxrws---+ 1 user http 310 Nov 30 08:07 ..
drwx------+ 1 http http  12 Nov 30 08:08 non-empty-subdir

Es scheint, dass der Benutzer mit Schreibberechtigungen für ein Verzeichnis einen Eintrag für eine Datei oder ein leeres Unterverzeichnis eines anderen Benutzers entfernen darf, jedoch kein nicht leeres Unterverzeichnis.

Eine ideale Antwort auf diese Frage würde Informationen liefern wie:

  • eine Bestätigung, dass das beschriebene Verhalten auf anderen Maschinen reproduzierbar ist (und nicht nur Macken meiner vermasselten Box)
  • eine Begründung, um dieses Verhalten zu erklären (z. B. gibt es Anwendungsfälle?)
  • eine Übersicht, wenn es Unterschiede zwischen Systemen gibt (BSD, Linux ....)

Update : In Bezug auf den Kommentar von Ipor Sircer habe ich das Szenario ohne ACL-Funktionen erneut getestet und es ist dasselbe. Ich habe daher die Frage geändert, um die +es aus den Auflistungen zu entfernen, damit nicht die Idee entsteht, dass das Verhalten mit ACLs zusammenhängt.

Menschlichkeit UND Frieden
quelle
3
Das nachfolgende +Zeichen bedeutet, dass ACLs (Access Control List) -Berechtigungen vorhanden sind, die von aufgelistet werden können getfacl <directory>.
Ipor Sircer
@IporSircer danke für die Info. Ich habe dieses Verhalten zum ersten Mal in einem Ordner festgestellt und reproduziert, in dem zufällig ACL aktiviert ist. Wie ich in der Aktualisierung / bearbeiten auf die Frage gesagt wurde das Verhalten nicht von der ACL beeinflusst (die ohnehin nur war für neu erstellte Dateien eine Standardgruppe aufzuzwingen)
humanityANDpeace

Antworten:

14

Ein Verzeichnis (mit dem rmdir()Systemaufruf) kann nur entfernt werden, wenn es leer ist.

rm -r dirEntfernt das Verzeichnis und alle darin enthaltenen Dateien, beginnend mit den Blättern des Verzeichnisbaums und bis zum Stammverzeichnis ( dir).

Um eine Datei zu entfernen (mit rmdir()für Verzeichnisse und unlink()für andere Dateitypen oder *at()Varianten), ist es nicht die Berechtigung der Datei selbst, sondern die des Verzeichnisses, aus dem Sie die Datei entfernen (beachten Sie das tBit in den Berechtigungen, wie z für /tmp, fügt dem weitere Komplikationen hinzu).

Vor allem entfernen Sie die Datei nicht wirklich, sondern trennen sie aus einem Verzeichnis (und wenn es der letzte Link ist, den Sie entfernen, wird die Datei in der Folge gelöscht), das heißt, Sie sind es Wenn Sie das Verzeichnis ändern, müssen Sie die Berechtigungen für dieses Verzeichnis ändern (schreiben).

Der Grund, den Sie nicht entfernen können, non-empty-dirist, dass Sie die Verknüpfung nicht zuerst trennen subdirkönnen, da Sie nicht das Recht haben, Änderungen vorzunehmen non-empty-dir. Sie haben das Recht, die Verknüpfung zu non-empty-dirIhrem Ausgangsverzeichnis aufzuheben, da Sie über eine Schreib- / Änderungsberechtigung für dieses Verzeichnis verfügen. Sie können jedoch kein Verzeichnis entfernen, das nicht leer ist.

In Ihrem Fall rmdir()schlägt der Systemaufruf , wie von @PeterCordes in den Kommentaren angegeben, mit einem ENOTEMPTYFehlercode (Verzeichnis nicht leer) fehl. Da Sie jedoch keine Leseberechtigung für das Verzeichnis haben, rmkönnen Sie nicht einmal herausfinden, welche Dateien und Verzeichnisse (einschließlich subdir) Es müsste die Verknüpfung aufheben, um es leeren zu können (nicht, dass es die Verknüpfung aufheben könnte, wenn es wüsste, da es keine Schreibberechtigungen hat).

Sie können auch in Situationen geraten, in denen ein Verzeichnis entfernt werden rm könnte , wenn nur herausgefunden werden könnte, welche Dateien sich darin befinden, wie im Fall eines Nur-Schreib-Verzeichnisses:

$ mkdir dir
$ touch dir/file
$ chmod a=,u=wx dir
$ ls -ld dir
d-wx------ 2 me me 4096 Nov 30 19:43 dir/
$ rm -rf dir
rm: cannot remove 'dir': Permission denied

Trotzdem kann ich es entfernen, da ich zufällig weiß, dass es nur eine fileDatei enthält :

$ rm dir/file
$ rmdir dir
$

Beachten Sie auch, dass Sie dies mit modernen Unices umbenennen können non-empty-dir, aber unter Linux oder FreeBSD (aber nicht mit Solaris) nicht in ein anderes Verzeichnis verschieben können, selbst wenn Sie auch Schreibberechtigung für dieses Verzeichnis hatten, wie (glaube ich und für Linux) , wie im Kommentar für den entsprechenden Code vorgeschlagen , würde dies eine Änderung beinhalten non-empty-dir(der ..Eintrag darin würde auf ein anderes Verzeichnis verweisen).

Man könnte argumentieren, dass das Entfernen Ihrer empty-dirauch das Entfernen der ..und .Einträge darin beinhaltet, also ändern Sie es, aber dennoch können Sie dies vom System tun.

Stéphane Chazelas
quelle
Übrigens, ich denke, die Fehlermeldung rm: cannot remove 'non-empty-subdir': Permission deniedist, dass das OP keine Leseberechtigung für das Verzeichnis hat und daher rmnicht einmal seinen Inhalt auflisten konnte , um zu versuchen , seinen Inhalt zu entfernen. Wenn es die o+rErlaubnis hätte (zB 755 oder sogar 744), wäre die Fehlermeldung leuchtender gewesen, wie z ... 'non-empty-subdir/subdir': Permission denied. Aus diesem Grund habe ich die Frage positiv bewertet.
Peter Cordes
Ich denke, Ihr letzter Absatz sollte darauf hinweisen, dass ich rmnicht einmal sehen kann, dass non-empty-dirdas nicht leer ist. Die Anzahl der Links in den OPs ist ls -alhalle 1, auch für Verzeichnisse (Schein), aber wenn das Verzeichnis ein Nicht-Verzeichnis enthalten hätte, könnten Sie immer noch nicht den Unterschied zwischen einem leeren und einem nicht leeren Verzeichnis erkennen, wenn Sie es nicht lesen können. (Außer durch den Versuch, es zu entfernen.)
Peter Cordes
Vielleicht interessant darauf hinzuweisen, dass das OP renamedas Verzeichnis könnte, das sie nicht besitzen, weil (ohne das tSticky-Bit) dies nur eine Schreibberechtigung für das Verzeichnis erfordert, das sie besitzen.
Peter Cordes
1
@ PeterCordes, gute Punkte. Siehe Bearbeiten.
Stéphane Chazelas
5

Wenn ich die mögliche Änderung durch die ACLs ignoriere, kann ich dieses Verhalten für mein System (ohne ACLs) bestätigen.

Das beobachtete Verhalten ist die logische Konsequenz zweier Prinzipien:

1) Die Rechte für ein Verzeichnis bestimmen, wer das Verzeichnis ändern kann, dh Einträge im Verzeichnis löschen. Die Rechte der Einträge in diesem Verzeichnis spielen dabei keine Rolle.

2) Das Entfernen einer Datei erfordert möglicherweise das Entfernen und Bereinigen der zugehörigen Informationen, z. B. Inodes, Blockzuweisungslisten usw. Aus diesem Grund können Sie eine nicht leere Unterverzeichnis nicht entfernen, ohne alle darin enthaltenen Dateien bereinigt zu haben, da sonst die darin enthaltenen Dateien bereinigt würden unzugänglich werden, aber die zugehörigen Informationen wären nicht bereinigt worden.

Sie können also entfernen empty-subdir, weil Sie die Rechte haben, in das Verzeichnis zu schreiben, in dem es sich befindet. Sie können nicht entfernen non-empty-subdir, weil Sie nicht die Rechte haben, die in diesem Unterverzeichnis enthaltenen Dateien zuerst zu bereinigen.

Es gibt wirklich keine Gründe oder Anwendungsfälle dafür. Man hätte eine rekursive Bereinigung eines Unterverzeichnisses in den Kernel einbauen können, aber das ursprüngliche Unix hielt alles einfach, und eine rekursive Bereinigung wäre zu kompliziert gewesen, wenn sie mit einem User-Space-Dienstprogramm erreicht werden könnte.

Ich kann keinen umfassenden Überblick zwischen verschiedenen Geschmacksrichtungen geben, aber dies war das Verhalten in der ursprünglichen Unix-Version, und ich würde erwarten, dass es in jeder Unix-Variante gleich ist, und ich wäre überrascht, wenn es eine Unix-Variante gäbe das verhielt sich anders.

dirkt
quelle
3
Beachten Sie, dass das ursprüngliche Unix keine Verzeichnisse hatte rm -rund mkdirund rmdirnicht (das Erstellen (mit mknod(2))) und Entfernen (mit Gleichem unlink(2)für andere Dateitypen) Verzeichnisse war und das Verknüpfen und Aufheben der Verknüpfung von "." - und ".." -Einträgen in ihnen wurde im Benutzerraum durchgeführt, die Zugriffskontrolle wurde auch im Benutzerraum von den Dienstprogrammen mkdirund durchgeführt rmdir).
Stéphane Chazelas
@ StéphaneChazelas: Oh, daher stammen die historischen Erwähnungen von Systemen, auf denen Sie ein Verzeichnis als reguläre Datei öffnen und lesen können (anstatt readdirdie Kernel-Listeneinträge zu haben)? Faszinierend.
Peter Cordes
@ PeterCordes: Aber beachte, dass dies unter sehr frühem Unix war.
Dirkt
Ich glaube, ich habe es in (alten Versionen von) Linux-Manpages als historische Fußnote erwähnt gesehen. Ich habe es nicht wiedergefunden, als ich jetzt gesucht habe.
Peter Cordes
1
@PeterCordes, wenn es nur ein Dateisystem gab, war es wenig sinnvoll, das Verzeichnislayout für den Benutzer zu abstrahieren. Ein Readdir war nur ein Einlesen in ein Strukturverzeichnis.
Stéphane Chazelas
3

Ich habe versucht zu reproduzieren, was Sie beschreiben, und bin gelaufen strace rm -rf ./nonempty. Was dies offenbart, ist Folgendes:

unlinkat(4, "subdir", AT_REMOVEDIR)     = -1 EACCES (Permission denied)

und laut unlinkatHandbuch (was unter Linux dasselbe ist wie unlink(2), Hervorhebung von mir hinzugefügt):

EACCES Der Schreibzugriff auf das Verzeichnis mit dem Pfadnamen ist für die effektive UID des Prozesses nicht zulässig, oder eines der Verzeichnisse im Pfadnamen hat keine Suchberechtigung zugelassen . (Siehe auch path_resolution (7).)

Da das übergeordnete Verzeichnis nonemptykeine userx-Berechtigung (Suche) erteilt, ist es sinnvoll, basierend auf der EACCESBeschreibung, subdirdie nicht entfernt werden kann.

Sergiy Kolodyazhnyy
quelle
Nein, Sie benötigen keine Berechtigung für das zu entfernende Verzeichnis, sondern schreiben nur die Berechtigung in das enthaltende Verzeichnis. Der Punkt über die Suchberechtigung bedeutet die dazwischenliegenden Verzeichnisse, dh foound bar, aber nicht somein /foo/bar/some. Sie können dies versuchen : mkdir d; chmod 0 d; rmdir d, es sollte in Ordnung funktionieren. Natürlich non-empty-subdirpassiert dies ohne Suchberechtigung , aber ohne Schreibberechtigung würde es trotzdem passieren. Außerdem: Suchberechtigung ist das xBit, es ist nicht dasselbe wie Leseberechtigung
ilkkachu
@ilkkachu Sinnvoll. Ich habe die Antwort bearbeitet, um dies widerzuspiegeln.
Sergiy Kolodyazhnyy
Sie müssen mit einem non-empty-subdirlesbaren, aber nicht beschreibbaren Test getestet haben . Der rmBefehl des OP konnte nicht einmal herausfinden, dass sich darin ein Inhalt befindet subdir, da sie keine Leseberechtigung haben (beachten Sie, dass sie sudoden Inhalt aufgelistet haben). Siehe die aktualisierte Antwort von Stéphane Chazelas.
Peter Cordes
@PeterCordes Ich habe beide non-emptyund subdir700 Berechtigungen festgelegt, genau wie im Beispiel von OP, und chownbeide so bearbeitet , dass sie einem anderen Benutzer und seiner Gruppe gehören.
Sergiy Kolodyazhnyy
Wie rm -rf ./nonemptykonnte man dann einen unlinkat(4, "subdir", AT_REMOVEDIR)Systemaufruf tätigen , wenn er nicht einmal lesen konnte ./nonempty, um den Namen zu finden subdir?
Peter Cordes