web-dev-qa-db-fra.com

Pourquoi puis-je modifier un fichier en lecture seule?

Question courte:

Pourquoi pouvons-nous manipuler un fichier en lecture seule dans Vim en utilisant : + w + q + ! même sans être administrateur?

Question longue:

J'ai un fichier texte (myFile.txt) qui est en lecture seule pour tout le monde:

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

Je peux l'ouvrir avec Vim sans avoir les privilèges d'administrateur:

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

Je le modifie et appuie sur: Esc + : + w + q + Enter et je vois ce message d'erreur:

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

Jusqu'à présent, tout est logique. Mais quand j'appuie sur: Esc + : + w + q + ! + Enter, Vim enregistre les modifications.

J'utilise Ubuntu 16.04 et VIM 7.4.

42
Navid Vafaei

Comme @Rob déjà mentionné , vous ne pouvez le faire que si vous avez un accès en écriture au répertoire contenant le fichier. Si vous tentez de faire la même chose pour un fichier, par exemple, /etc échouera.

En ce qui concerne , comment vim, il supprime le fichier et le recrée. Pour tester cela, j'ai créé un fichier appartenant à root:

echo foo | Sudo tee fff

Et ensuite procédé pour éditer le fichier avec vim de la manière que vous décrivez, mais en joignant le processus à strace pour voir ce qui se passe:

strace vim fff 2> strace.out

J'ai ensuite vérifié strace.out et trouvé:

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

Ainsi, le fichier a d'abord été supprimé (unlink("fff")), puis un nouveau fichier du même nom a été créé (open("fff", O_WRONLY|O_CREAT|O_TRUNC, 0644)) et les modifications que j'ai apportées y ont été écrites (write(4, "foasdasdao\n", 11)). Si vous essayez ceci à la maison, vous verrez qu'après l'avoir édité avec vim, le fichier vous appartiendra maintenant et non à la racine.

Donc, à proprement parler, vim n'édite pas un fichier auquel vous n'avez pas accès en écriture. Il s'agit de supprimer un fichier d'un répertoire auquel vous avez un accès en écriture, puis de créer un nouveau fichier auquel, encore une fois, vous avez un accès en écriture.

58
terdon

En utilisant w!, vous supprimez le fichier d'origine (ce que vous êtes autorisé à faire) et écrivez votre version à la place.

Lorsque vous avez un accès en écriture à un répertoire, vous pouvez: créer, déplacer ou supprimer des fichiers de ce répertoire.

$ 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

Maintenant, permettez-moi de changer d'utilisateur et de changer le fichier

$ 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

Maintenant, voyez ce qu'il y a dedans:

$ cat foo/file
bye
16
Ravexina

Tant que vous possédez le répertoire parent, vous pouvez supprimer ou remplacer un fichier, quelle que soit l'autorisation, car vous pouvez modifier le contenu du répertoire :).

Essayez-le avec une autre commande comme rm, il vous y invitera mais vous pouvez toujours le faire. Rendre le répertoire non accessible en écriture et cela devrait l'arrêter.

Une addition:

Juste essayé mais tant que je possède le fichier, je peux toujours le modifier, même avec le dossier en lecture seule. Cependant, lorsque je change de propriétaire en root: root, il ne peut pas ouvrir le fichier en écriture. Résout donc la modification des fichiers appartenant à root (ou à quelqu'un d'autre)

16
Rob

Voir :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).

Étant donné que vous disposez d'autorisations en écriture sur le répertoire (ce qui signifie que vous pouvez créer, supprimer ou renommer des fichiers), le système l'autorise.


La valeur par défaut de cpoptions ne contient pas W:

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

Le processus de votre éditeur vim et votre fichier portent tous deux votre

 getpwnam("navid")->pw_uid

la propriété afin que vous puissiez également Shell sur

 :!chmod +w %

et vous pourriez deviner qu'il était une fois le plus simple encore

 :!rm %

(ne nécessitant que + w, u-t dissocier la permission sur. et même pas la propriété) est devenu trop fréquent pour que quelqu'un puisse taper, de sorte que vim a été reprogrammé pour offrir automatiquement et sur demande effectuer automatiquement une telle opération.

Essayez de remplacer votre grande soeur

 /home/whoopi/.profile

comme simple navid et paris sont votre vim vous donne votre refus souhaité.

2
Roman Czyborra

Ceci est un avertissement de VIM qui pourrait vous être relativement important compte tenu du fonctionnement des autorisations dans UNIX. Cela semble peu intuitif, car les systèmes de fichiers UNIX disposent d'autorisations pour les fichiers stockés dans i-node du fichier. La structure des répertoires est en quelque sorte séparée et ne lie que ces i-nœuds. Les répertoires ont également leurs autorisations qui indiquent si vous pouvez lier/dissocier des fichiers, ou le lire ou le parcourir dans des sous-répertoires. Cette conception permet qu'un même fichier puisse apparaître à plusieurs endroits différents de la structure de répertoires (par le biais de liens physiques). En disant "ajouter! Pour remplacer" VIM essaie de vous avertir que le fichier d'origine sera dissocié (il restera donc dans tous les autres emplacements intacts) et que le nouveau fichier sera créé et lié au fichier d'origine. placer dans la structure de répertoire. Si le nombre de liens du fichier d'origine est réduit à zéro, le fichier d'origine sera libéré, mais dans le cas contraire, vous clonez effectivement le fichier. L’ouverture du fichier est également considérée comme un lien. Par conséquent, si un programme a ouvert le fichier et que vous acceptez d’ajouter "au remplacement", il ne verra pas les modifications que vous avez apportées au fichier avec VIM. Le fichier est uniquement dissocié du répertoire par VIM et, après fermeture du fichier par un autre programme, le fichier est libéré, sauf s'il a été lié ailleurs.

Veuillez noter que dans Windows, les autorisations pour les fichiers sont stockées dans un répertoire. Par conséquent, du point de vue du paradigme des autorisations Windows, ce comportement de vim peut en effet paraître étrange. Logiquement, pour écrire dans le fichier, il peut également vérifier certaines autorisations de répertoire, même les autorisations de super-répertoire. Comme indiqué ci-dessus, sous UNIX, les autorisations de répertoire ne sont pas pertinentes pour la manipulation du fichier, dans la mesure où vous avez pu le répertorier et l'ouvrir (c'est-à-dire qu'il y avait x pour tous les super-répertoires). Un fichier ouvert sous UNIX peut même ne plus avoir de nom de fichier s'il n'a pas été lié à tous les répertoires après son ouverture.

Par exemple, vous avez le fichier/home/user1/foo et c’est le même fichier que (c.-à-d. Un lien fixe)/home/user2/foo et le fichier n’est pas accessible en écriture pour personne et est actuellement ouvert par le programme P (ouvert en lecture-écriture par programme lancé par root). Si l'utilisateur1 l'ouvre avec vim et remplace, il crée sa propre copie et ne voit plus le fichier d'origine. Si, par la suite, l'utilisateur2 ouvre son lien avec vim et y écrit, le lien sera de nouveau dissocié et il en créera une autre copie. Le programme P verra toujours le fichier original et pourra librement lire ou écrire dessus. Dès que le programme ferme le fichier, le fichier disparaîtra (sera libéré par le système de fichiers).

2
ludvik02

Ce n'est pas exactement une réponse, mais si vous voulez vraiment définir un fichier afin que personne ne puisse le modifier ou le supprimer, vous pouvez le rendre immuable.

Normalement, même lorsqu'un fichier appartient à root, vous pouvez toujours supprimer le fichier si vous disposez des autorisations d'écriture sur le dossier. Mais lorsque vous rendez le fichier immuable, même root ne peut ni le modifier ni le supprimer.

Pour rendre un fichier immuable (vous avez besoin de Sudo):

Sudo chattr +i myFile.txt

Vous pouvez le voir avec lsattr (la lettre i dans le résultat):

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

Pour que le fichier redevienne normal:

Sudo chattr -i myFile.txt

Pour clarifier: lorsqu'un fichier est immuable, il ne peut pas être supprimé, renommé, modifié ou même lié en dur.

Cela vaut la peine de lire man chattr, car les fichiers peuvent avoir un certain nombre d'attributs utiles.

Vous pourriez également trouver utile "suppression restreinte". S'il est placé dans un dossier (pas un fichier), cela signifie que quiconque crée un fichier dans le dossier est autorisé à modifier ou supprimer ce fichier, mais personne d'autre ne l'est (à l'exception de la racine). Le dossier /tmp a cet indicateur défini. Vous pouvez le voir avec l'indicateur t sur /tmp:

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

Pour définir ou supprimer l'indicateur de suppression restreinte sur un dossier:

chmod +t myFolder      # Add the restricted deletion flag.
chmod -t myFolder      # Remove the restricted deletion flag.
1
Paddy Landau