Почему я могу изменить файл только для чтения?

41

Короткий вопрос:

Почему мы можем манипулировать файлом только для чтения в Vim, используя : + w + q + ! даже не будучи администратором?

Долгосрочный вопрос:

У меня есть текстовый файл (myFile.txt), который доступен только для чтения:

[email protected]:~/ubuntuTest$ ls -l myFile.txt 
-r--r--r-- 1 navid navid 26 Aug 22 21:21 myFile.txt

Я могу открыть его с помощью Vim без прав администратора:

[email protected]:~/ubuntuTest$ vi myFile.txt 

Я изменяю его и нажимаю: Esc + : + w + q + Введите и я вижу это сообщение об ошибке:

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

До сих пор все имеет смысл. Но когда я нажимаю: Esc + : + w + q + ! + Введите , Vim сохранит изменения.

Я использую Ubuntu 16.04 и VIM 7.4.

    
задан Navid Vafaei 23.08.2016 в 17:06
источник

7 ответов

57

Как уже отмечалось в @Rob уже , вы можете сделать это, только если у вас есть доступ на запись в каталог, содержащий файл. Попытка сделать то же самое в файле, например, в /etc не удастся.

Что касается , как vim делает это, он удаляет файл и воссоздает его. Чтобы проверить это, я создал файл, принадлежащий root:

echo foo | sudo tee fff

И затем приступил к редактированию файла с vim в том виде, который вы описываете, но привязывая процесс к strace , чтобы посмотреть, что происходит:

strace vim fff 2> strace.out

Затем я проверил strace.out и нашел:

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

Итак, файл был сначала удален ( unlink("fff") ), затем был создан новый файл с таким же именем ( open("fff", O_WRONLY|O_CREAT|O_TRUNC, 0644) ), и изменения, которые я сделал, были написаны ( write(4, "foasdasdao\n", 11) ). Если вы попробуете это дома, вы увидите, что после редактирования с vim файл теперь будет принадлежать вам, а не root.

Итак, строго говоря, vim не редактирует файл, на который у вас нет доступа для записи. Он удаляет файл из каталога, в котором у вас есть доступ на запись, а затем создается новый файл, к которому у вас также есть доступ на запись.     

ответ дан terdon 23.08.2016 в 17:40
источник
15

Пока у вас есть родительский каталог, который вы можете удалить или заменить файл независимо от разрешения, так как вы можете изменить содержимое каталога:).

Попробуйте с помощью другой команды, например, rm, она предложит вам, но вы все равно можете это сделать. Сделайте каталог недоступным для записи и который должен его остановить.

Дополнение:

Просто попробовал, но пока я владею файлом, я все еще могу его изменить, даже если папка только для чтения. Однако при изменении права собственности на root: root он не может открыть файл для записи. Поэтому решает модифицирующие файлы, принадлежащие root (или кому-то еще)

    
ответ дан Rob 23.08.2016 в 17:34
15

Используя w! , вы удаляете исходный файл (, который вам разрешено делать ), и вместо этого записывайте свою версию.

Когда у вас есть доступ к записи в каталог, вы можете: создавать, перемещать или удалять файлы в этом каталоге.

$ 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

Теперь позвольте мне переключить пользователя и изменить файл

$ 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

Теперь посмотрим, что там есть:

$ cat foo/file
bye
    
ответ дан Ravexina 31.08.2017 в 04:48
9

См. :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).

Поскольку у вас есть права на запись в каталоге (это означает, что вы можете создавать, удалять или переименовывать файлы в нем), система действительно разрешает это.

Значение по умолчанию cpoptions не содержит W :

                                                'cpoptions' 'cpo' cpo
'cpoptions' 'cpo'       string  (Vim default: "aABceFs",
                                 Vi default:  all flags)
                        global
    
ответ дан muru 31.08.2017 в 04:57
2

Это предупреждение VIM, которое может быть относительно важным, учитывая, как разрешения работают в UNIX. Очевидная неинтуитивность этого заключается в том, что файловые системы UNIX имеют разрешения на файл, хранящийся в i-узле файла. Структура каталога как-то раздельна и связывает только эти i-узлы. У каталогов также есть свои разрешения, которые говорят, можете ли вы связать / отменить связь с файлами в нем или прочитать его или перейти в подкаталоги. Эта конструкция позволяет отображать один и тот же файл в нескольких разных местах структуры каталогов (через жесткие ссылки). Говоря «add! To override», VIM пытается предупредить вас, что исходный файл будет отсоединен (так что он останется во всех других местах нетронутым), и новый файл будет создан и привязан к исходному месту в структуре каталогов. Если счетчик ссылок исходного файла уменьшается до нуля, исходный файл будет освобожден, но если нет, вы эффективно клонируете файл. Открытие файла также считается ссылкой, поэтому, если какая-то программа открыла файл, и вы соглашаетесь «добавить! Переопределить», программа не увидит изменений, внесенных вами в файл с помощью VIM. Файл только отсоединяется от каталога с помощью VIM и после закрытия файла другой программой файл будет освобожден, если только он не был связан где-то в другом месте.

Обратите внимание, что в Windows разрешения на файлы хранятся в каталоге, поэтому с точки зрения парадигмы разрешений Windows это поведение vim действительно может показаться странным. Для записи в файл Windows логически может также проверять некоторые разрешения на доступ к каталогам, даже разрешения суперкаталогов. Как было сказано выше, в UNIX права на каталоги не имеют отношения к манипуляции с файлом, насколько вы могли его перечислить и открыть (т. Е. Были х для всех супер-каталогов). Открытый файл в UNIX может не иметь даже больше имени файла, если он был отсоединен от всех каталогов после открытия.

Например, у вас есть файл / home / user1 / foo, и это тот же файл, что (например, hardlinked to) / home / user2 / foo, и файл не доступен для записи кем-либо и в настоящее время открыт программой P (открытое чтение -write при запуске программы с помощью root). Если user1 открывает его с помощью vim и перезаписывает, он создает свою собственную копию и больше не видит исходный файл. Если впоследствии user2 откроет свою связь с vim и запишет в нее, он снова отключится, и он создаст другую копию. Программа P по-прежнему будет видеть исходный файл и может свободно читать или записывать в него. Как только программа закроет файл, файл исчезнет (освободится файловой системой).     

ответ дан ludvik02 25.08.2016 в 12:18
2

Оба процесса редактирования vim и ваш файл несут ваш

 getpwnam("navid")->pw_uid

, чтобы вы могли также разорвать

 :!chmod +w %

, и вы можете догадаться, что когда-то еще более простой

 :!rm %

(требуется только + w, u-t отменить разблокирование и даже право собственности) стало слишком частым для того, чтобы кто-то набрал так, чтобы vim был запрограммирован автоматически, и по запросу автоматически выполнил такую ​​операцию.

Попробуйте перезаписать свою старшую сестру

 /home/whoopi/.profile

как простой navid и ставки - ваш vim дает вам желаемый отказ.

    
ответ дан Roman Czyborra 24.08.2016 в 21:43
1

Это не совсем ответ, но если вы действительно хотите установить файл, чтобы никто не мог его изменить или удалить, вы можете сделать его неизменным.

Обычно, даже если файл принадлежит root, вы все равно можете удалить файл, если у вас есть права на запись в папку. Но когда вы делаете файл неизменным, даже root не может его изменять или удалять.

Чтобы сделать файл неизменным (вам нужно sudo ):

sudo chattr +i myFile.txt

Вы можете увидеть это с помощью lsattr (буква i в результате):

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

Чтобы снова сделать файл нормальным:

sudo chattr -i myFile.txt

Чтобы уточнить: когда файл является неизменным, его нельзя удалить, переименовать, изменить или даже сложно связать.

Стоит прочитать man chattr , потому что файлы могут иметь несколько полезных атрибутов.

Вы также можете найти «ограниченное удаление». Если он помещен в папку (а не файл), это означает, что тому, кто создает файл в папке, разрешено изменять или удалять этот файл, но никто не является (кроме root). В папке /tmp установлен этот флаг. Вы можете увидеть это с помощью флага t на /tmp :

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

Чтобы установить или удалить флаг ограниченной блокировки в папке:

chmod +t myFolder      # Add the restricted deletion flag.
chmod -t myFolder      # Remove the restricted deletion flag.
    
ответ дан Paddy Landau 06.09.2017 в 10:11