Допустим, есть такая файловая система ext4 с точкой монтирования /ILYA, в которой находится файловое хранилище, и как пример, абсолютный путь к одному из файлов.
/ILYA/Music/W.A.S.P/1984 - W.A.S.P/01 - I wanna be somebody.flac
Возникла необходимость сделать так, чтобы никто кроме меня, знающего пароль root-а, не мог удалять существующие файлы, но при этом мог создавать/править/удалять свои, причём даже в тех директориях, где присутствуют мои.
Попробовал просто заменить владельца этих файлов root-ом.
p='/ILYA' && sudo chown -R root:root "$p" && sudo chmod -R =r,u+w,+X "$p" && chown user "$p"
Но, оказывается, пользователь user без проблем удаляет любой файл, принадлежащий пользователю root, если он владелец родительской директории /ILYA, а в директории /ILYA/Music он уже не может удалять, но и не может создавать. Вариант не сработал.
Добавил stickybit.
p='/ILYA' && sudo chown -R root:root "$p" && sudo chmod -R =r,u+w,+X,+t "$p" && chown user "$p"
Но это вообще ничего не изменило.
Подскажите, как решить эту задачу, или что я недосмотрел, или, хотя бы, куда мне копать?
Ответ.
Основная моя ошибка была в том, что я считал атрибуты chmod =r,u+w,+X,+t и a=trX,u+w эквивалентными на основании того, что =r было эквивалентно a=r. Запись с a= и короче, и красивее, и понятнее, а главное выполняет то, что от неё требуется. (Сбросить все привилегии и заново установить для всех пользователей стикибит, чтение, и если это директория, то и выполнение, а для владельца, по мимо этого, ещё установить запись)
И так моя задаче решается такой командой, к сожалению, без find не обойтись.
p='/ILYA' && sudo chown -R root:users "$p" && sudo chmod -R go-w "$p" && sudo find "$p" -type d -exec chmod a+t,g+w "{}" \;
Вернуть назад.
p='/ILYA' && sudo chown -R user:users "$p" && sudo chmod -R a-t,g-w "$p"
А также, в случае, если нужно запретить удалять даже root-у, тогда нужно использовать chattr + find только на файлы, пропуская директории.
p='/ILYA' && sudo find "$p" -type f -exec chattr +i "{}" \;
В этом случае эти файлы, причём уже совершенно не важно кто ими владеет, не сможет удалить даже root, пока root не снимет атрибут i, j, обратной командой.
p='/ILYA' && sudo find "$p" -type f -exec chattr -i "{}" \;
Ответ
выдержка из man chattr
A file with the `i' attribute cannot be modified: it cannot be deleted or renamed, no link can be created to this file and no data can be written to the file. Only the superuser or a process possessing the CAP_LINUX_IMMUTABLE capability can set or clear this attribute.
вольный перевод:
файл с атрибутом i не может быть модифицирован: он не может быть удалён или переименован, на него невозможно создать «жёсткую» ссылку (hardlink) и в него невозможно записать информацию. только суперпользователь или процесс, обладающий «возможностью» (capability) CAP_LINUX_IMMUTABLE может установить или удалить этот атрибут.
пример. создадим от имени рядового пользователя файл:
$ touch file
он принадлежит «рядовому» пользователю:
$ ls -l file
-rw-r--r-- 1 user user 0 Jul 29 20:42 file
и не имеет (пока) никаких спецатрибутов:
$ lsattr file
---------------- file
установим атрибут i
$ sudo chattr +i file
$ lsattr file
----i----------- file
попробуем удалить:
$ rm file
rm: remove write-protected regular empty file `file'? y
rm: cannot remove `file': Operation not permitted
даже суперпользователь этого не сможет сделать:
$ sudo rm file
rm: cannot remove `file': Operation not permitted
пока не снимем атрибут i
$ sudo chattr -i file
теперь и «рядовой» владелец сможет его удалить:
$ rm file
можно установить этот атрибут и на каталог. тогда всё содержимое каталога (но не подкаталогов, у которых атрибут не установлен) станет (частично) неизменяемым: нельзя будет создавать/удалять/переименовывать файлы/каталоги, но можно будет изменять содержимое файлов.
Комментариев нет:
Отправить комментарий