Warum kann ich eine schreibgeschützte Datei ändern?


42

Kurze Frage:

Warum können wir eine schreibgeschützte Datei in Vim manipulieren mit :+ w+ q+ !auch ohne einen Administrator zu sein?

Lange Frage:

Ich habe eine Textdatei (myFile.txt), die für alle schreibgeschützt ist:

navid@navid-ThinkPad-T530:~/ubuntuTest$ ls -l myFile.txt 
-r--r--r-- 1 navid navid 26 Aug 22 21:21 myFile.txt

Ich kann es mit Vim öffnen, ohne über Administratorrechte zu verfügen:

navid@navid-ThinkPad-T530:~/ubuntuTest$ vi myFile.txt 

Ich ändere es und drücke: Esc+ :+ w+ q+ Enterund ich sehe diese Fehlermeldung:

E45: 'readonly' option is set (add ! to override)

Bisher macht alles Sinn. Aber wenn ich drücke: Esc+ :+ w+ q+ !+ Enter, speichert Vim die Änderungen.

Ich benutze Ubuntu 16.04 und VIM 7.4.


1
@Zanna Besitzen Sie das Verzeichnis, in dem sich die Datei befindet?
Rob

Ja, das wäre sonst ein RIESIGES Problem :)
Rob

11
Das Ändern einer Datei und das Ersetzen einer Datei sind zwei verschiedene Dinge mit unterschiedlichen Berechtigungsanforderungen.
David Schwartz

1
Vielleicht haben Sie einen Blick auf haben wollen dies . Es beantwortet im Grunde Ihre Frage und als @DavidSchwartz richtig darauf hingewiesen :Modifying a file and replacing a file are two different things
Panagiotis Tabakis

@ PanagiotisTabakis Sehr schön finden, dass dies brillant ist .. chmod, um die Datei Lese- und Schreibzugriff zu machen und wieder zurück, wenn Sie es besitzen .. LIEBE ES :)
Rob

Antworten:


58

Wie @Rob bereits erwähnt , können Sie dies nur tun, wenn Sie Schreibzugriff auf das Verzeichnis haben, in dem sich die Datei befindet. Der Versuch, dieselbe Aktion beispielsweise für eine Datei in auszuführen, /etcschlägt fehl.

Was , wie vim dies tut, löscht er die Datei neu erstellt. Um dies zu testen, habe ich eine Datei erstellt, die root gehört:

echo foo | sudo tee fff

Anschließend bearbeiten Sie die Datei vimwie beschrieben, hängen den Prozess jedoch an, um stracezu sehen, was passiert:

strace vim fff 2> strace.out

Ich habe dann nachgesehen strace.outund festgestellt:

unlink("fff")                           = 0
open("fff", O_WRONLY|O_CREAT|O_TRUNC, 0644) = 4
write(4, "foasdasdao\n", 11)            = 11

Also wurde die Datei zuerst gelöscht ( unlink("fff")), dann wurde eine neue Datei mit dem gleichen Namen erstellt ( open("fff", O_WRONLY|O_CREAT|O_TRUNC, 0644)) und die von mir vorgenommenen Änderungen wurden darauf geschrieben ( write(4, "foasdasdao\n", 11)). Wenn Sie dies zu Hause versuchen, werden Sie feststellen vim, dass die Datei nach dem Bearbeiten mit Ihnen gehört und nicht mehr root.

vimBearbeiten Sie also streng genommen keine Datei, auf die Sie keinen Schreibzugriff haben. Sie löschen eine Datei aus einem Verzeichnis, auf das Sie Schreibzugriff haben, und erstellen dann eine neue Datei, auf die Sie ebenfalls Schreibzugriff haben.



8
@CCJ es ist eine Schreiboperation für das Verzeichnis, aber nicht für die Datei, nein. Schreibvorgänge für Dateien ändern den Inhalt der Datei. Ebenso sind das Erstellen / Löschen von Dateien Schreibvorgänge für das Verzeichnis, da Sie dessen Inhalt ändern.
Terdon

2
Auch das ist eine gefährliche Reihenfolge. Es wäre sicherer, die Ersetzung in einen neuen Dateinamen zu schreiben und dann rename(2)die alte Datei zu ersetzen. Dann gibt es kein Zeitfenster, in dem Ihre Daten nicht auf der Festplatte vorhanden sind.
Peter Cordes

5
@PeterCordes ähm, OK. Möglicherweise möchten Sie Ihre Beschwerden jedoch an die VIM-Entwickler richten. Ich benutze das Ding nicht einmal, ich bin im Emacs-Lager.
Terdon

3
@CCJ Das Löschen einer Datei ist ein Schreibvorgang in das Verzeichnis, in dem sie enthalten ist, und nicht in die Datei selbst. Es ist vollkommen intuitiv, dass Sie, wenn Sie für ein Verzeichnis verantwortlich sind (dh Schreibzugriff darauf haben), steuern können sollten, was sich darin befindet, und der Eigentümer einer einzelnen Datei Sie nicht überschreiben darf.
Fkraiem

16

Solange Sie das übergeordnete Verzeichnis besitzen, können Sie eine Datei unabhängig von der Berechtigung entfernen oder ersetzen, da Sie den Inhalt des Verzeichnisses ändern können :).

Versuchen Sie es mit einem anderen Befehl wie rm, es wird Sie dazu auffordern, aber Sie können es trotzdem tun. Machen Sie das Verzeichnis nicht beschreibbar und das sollte es stoppen.

Zusatz:

Habe es gerade ausprobiert, aber solange ich die Datei besitze, kann ich sie immer noch ändern, auch wenn der Ordner schreibgeschützt ist. Wenn ich jedoch den Besitzer in root ändere, kann die Datei nicht zum Schreiben geöffnet werden. Behebt also die Änderungen an Dateien, die root (oder einer anderen Person) gehören.


7
Es hört sich so an, als würde VIM aus mehreren Strategien auswählen, einschließlich "Rewrite-In-Place" oder "Unlink" + "Write" einer neuen Datei.
Peter Cordes

3
@PeterCordes Ja, es wird anscheinend sehr schwer sein, das zu tun, was du sagst :) sehr listig. :)
Rob

16

Mit w!entfernen Sie die Originaldatei ( was Ihnen gestattet ist ) und schreiben stattdessen Ihre Version.

Wenn Sie Schreibzugriff auf ein Verzeichnis haben, können Sie: Dateien in diesem Verzeichnis erstellen, verschieben oder löschen.

$ mkdir foo
$ echo hi > foo/file
$ chmod 777 foo
$ chmod 700 foo/file
$ ls -l foo/file 
-rwx------ 1 ravexina ravexina 7 Aug 31 03:19 foo/file

Lassen Sie mich jetzt meinen Benutzer wechseln und die Datei ändern

$ sudo -u user2 -s
$ vi foo/a # save using w! (I wrote into the file bye)
$ ls -l foo/a
-rwx------ 1 user2 user2 7 Aug 31 03:20 foo/file

Nun sehen Sie, was da drin ist:

$ cat foo/file
bye

10

Siehe :help write-readonly:

                                                        write-readonly
When the 'cpoptions' option contains 'W', Vim will refuse to overwrite a
readonly file.  When 'W' is not present, ":w!" will overwrite a readonly file,
if the system allows it (the directory must be writable).

Da Sie über Schreibberechtigungen für das Verzeichnis verfügen (dh, Sie können darin Dateien erstellen, löschen oder umbenennen), lässt das System dies zu.


Der Standardwert von cpoptionsenthält nicht W:

                                                'cpoptions' 'cpo' cpo
'cpoptions' 'cpo'       string  (Vim default: "aABceFs",
                                 Vi default:  all flags)
                        global

2

Dies ist die Warnung von VIM für Sie, die im Hinblick auf die Funktionsweise von Berechtigungen in UNIX möglicherweise relativ wichtig ist. Offensichtlich ist dies nicht intuitiv, da UNIX-Dateisysteme über Berechtigungen für Dateien verfügen, die im i-node der Datei gespeichert sind. Die Verzeichnisstruktur ist irgendwie getrennt und verbindet nur diese i-Knoten. Verzeichnisse haben auch die Berechtigungen, die angeben, ob Sie Dateien darin verknüpfen oder die Verknüpfung aufheben, es lesen oder in Unterverzeichnisse wechseln können. Dieses Design ermöglicht, dass dieselbe Datei an mehreren verschiedenen Stellen in der Verzeichnisstruktur (über feste Links) angezeigt wird. Mit "Add! To Override" (Hinzufügen! Zum Überschreiben) warnt VIM Sie, dass die ursprüngliche Datei nicht verknüpft wird (sodass sie an allen anderen Stellen unberührt bleibt) und die neue Datei erstellt und mit der ursprünglichen Stelle in der Verzeichnisstruktur verknüpft wird. Wenn die Anzahl der Verknüpfungen der Originaldatei auf Null sinkt, wird die Originaldatei freigegeben. Andernfalls wird die Datei effektiv geklont. Das Öffnen der Datei zählt auch als Verknüpfung. Wenn also ein Programm die Datei geöffnet hat und Sie zustimmen, "Zum Überschreiben hinzufügen!" Die Verknüpfung der Datei mit dem Verzeichnis wird nur von VIM aufgehoben. Nach dem Schließen der Datei durch ein anderes Programm wird die Datei freigegeben, sofern sie nicht anderweitig verknüpft wurde.

Beachten Sie, dass in Windows die Berechtigungen für Dateien im Verzeichnis gespeichert sind. Aus Sicht des Windows-Berechtigungsparadigmas kann dieses VIM-Verhalten in der Tat seltsam aussehen. Zum Schreiben in die Datei prüft Windows möglicherweise logischerweise auch einige Verzeichnisberechtigungen, sogar übergeordnete Verzeichnisberechtigungen. Wie oben erwähnt, sind unter UNIX die Verzeichnisberechtigungen für die Manipulation mit der Datei irrelevant, sofern Sie sie auflisten und öffnen konnten (dh es gab x für alle Superverzeichnisse). In UNIX geöffnete Dateien haben möglicherweise nicht einmal mehr den Dateinamen, wenn sie nach dem Öffnen aus allen Verzeichnissen entfernt wurden.

Zum Beispiel haben Sie die Datei / home / user1 / foo und es ist dieselbe Datei wie (dh fest verbunden mit) / home / user2 / foo und die Datei ist für niemanden beschreibbar und wird derzeit von Programm P geöffnet (geöffnet von Lese- / Schreibzugriff) Programm gestartet von root). Wenn Benutzer1 es mit vim öffnet und überschreibt, erstellt er eine eigene Kopie und sieht die Originaldatei nicht mehr. Wenn Benutzer2 anschließend seinen Link mit vim öffnet und darin schreibt, wird die Verknüpfung wieder aufgehoben und eine weitere Kopie erstellt. Das Programm P sieht weiterhin die Originaldatei und kann diese frei lesen oder beschreiben. Sobald das Programm die Datei schließt, verschwindet die Datei (wird vom Dateisystem freigegeben).


2

Sowohl Ihr VIM-Editor-Prozess als auch Ihre Datei enthalten Ihre

 getpwnam("navid")->pw_uid

Eigentum, so dass Sie auch berappen könnten

 :!chmod +w %

und Sie könnten vermuten, dass es einmal noch einfacher war

 :!rm %

Es wurde zu häufig, dass jemand etwas eintippte, sodass vim neu programmiert wurde, um eine solche Operation automatisch anzubieten und auf Anfrage automatisch durchzuführen.

Versuchen Sie, die Ihrer großen Schwester zu überschreiben

 /home/whoopi/.profile

als bloße navid und Wetten gibt Ihnen Ihr vim Ihre gewünschte Ablehnung.


Vielen Dank an @Zanna für die Bearbeitung des Codes, auch wenn es mich Anfängern zu Recht ein wenig an Ansehen gekostet hat.
Roman Czyborra

1

Dies ist keine exakte Antwort, aber wenn Sie eine Datei wirklich so einrichten möchten, dass niemand sie ändern oder löschen kann, können Sie sie unveränderlich machen.

Normalerweise können Sie die Datei auch dann löschen, wenn eine Datei im Besitz von root ist, wenn Sie über Schreibberechtigungen für den Ordner verfügen. Wenn Sie die Datei jedoch unveränderlich machen, kann sie auch root nicht ändern oder löschen.

Um eine Datei unveränderlich zu machen (Sie brauchen sudo):

sudo chattr +i myFile.txt

Sie können dies mit lsattr(dem Buchstaben iim Ergebnis) sehen:

$ lsattr myFile.txt
----i--------e-- myFile.txt

Um die Datei wieder normal zu machen:

sudo chattr -i myFile.txt

Zur Verdeutlichung: Wenn eine Datei unveränderlich ist, kann sie nicht gelöscht, umbenannt, geändert oder sogar fest verknüpft werden.

Es lohnt sich zu lesen man chattr, da Dateien eine Reihe nützlicher Attribute haben können.

Möglicherweise ist auch "eingeschränktes Löschen" hilfreich. Wenn es sich um einen Ordner (keine Datei) handelt, bedeutet dies, dass jeder, der eine Datei innerhalb des Ordners erstellt, diese Datei ändern oder löschen darf, aber niemand anderes (außer root). Der Ordner /tmphat dieses Flag gesetzt. Sie können dies mit der tFlagge sehen /tmp:

$ ls -l --directory /tmp
drwxrwxrwt 10 root root 4096 Sep  6 09:00 /tmp

So setzen oder entfernen Sie das eingeschränkte Löschflag für einen Ordner:

chmod +t myFolder      # Add the restricted deletion flag.
chmod -t myFolder      # Remove the restricted deletion flag.
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.