Question:
Let's say there is such an ext4 filesystem with the / ILYA mount point, which contains the file storage, and as an example, the absolute path to one of the files.
/ILYA/Music/W.A.S.P/1984 - W.A.S.P/01 - I wanna be somebody.flac
There was a need to make sure that no one except me, who knows the root password, could delete existing files, but at the same time could create / edit / delete their own, even in those directories where mine are present.
-
I tried to simply replace the owner of these files with
root
.p='/ILYA' && sudo chown -R root:root "$p" && sudo chmod -R =r,u+w,+X "$p" && chown user "$p"
But it turns out that the user
user
easily deletes any file owned by theroot
if he is the owner of the parent directory/ILYA
, and in the/ILYA/Music
directory he can no longer delete, but he can not create either. The option didn't work. -
Added stickybit.
p='/ILYA' && sudo chown -R root:root "$p" && sudo chmod -R =r,u+w,+X,+t "$p" && chown user "$p"
But that didn't change anything at all.
Tell me how to solve this problem, or what I overlooked, or, at least, where should I dig?
Answer.
My main mistake was that I considered the attributes chmod
=r,u+w,+X,+t
and a=trX,u+w
to be equivalent on the basis that =r
was equivalent to a=r
. The notation with a=
shorter, more beautiful, and clearer, and most importantly, it does what is required of it. (Reset all privileges and re-install for all users stickbit, read, and if this is a directory, then execution, and for the owner, in addition, set the record)
And so my task is solved by such a command, unfortunately, find
is indispensable.
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 "{}" \;
To bring back.
p='/ILYA' && sudo chown -R user:users "$p" && sudo chmod -R a-t,g-w "$p"
And also, if you need to prohibit deleting even root , then you need to use chattr
+ find
only on files, skipping directories.
p='/ILYA' && sudo find "$p" -type f -exec chattr +i "{}" \;
In this case, these files, and it does not matter at all who owns them, can not even be deleted by root until root
removes the i
, j attribute with the reverse command.
p='/ILYA' && sudo find "$p" -type f -exec chattr -i "{}" \;
Answer:
excerpt from 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.
free translation:
attribute file
i
can not be modified: it can not be deleted or renamed, it is impossible to create a "rigid" link (hardlink) and it is impossible to write information to it. only the superuser or process with theCAP_LINUX_IMMUTABLE
capability can set or remove this attribute.
example. create a file on behalf of an ordinary user:
$ touch file
it belongs to an "ordinary" user:
$ ls -l file
-rw-r--r-- 1 user user 0 Jul 29 20:42 file
and does not (yet) have any special attributes:
$ lsattr file
---------------- file
set attribute i
:
$ sudo chattr +i file
$ lsattr file
----i----------- file
let's try to remove:
$ rm file
rm: remove write-protected regular empty file `file'? y
rm: cannot remove `file': Operation not permitted
even the superuser cannot do this:
$ sudo rm file
rm: cannot remove `file': Operation not permitted
until we remove the i
attribute:
$ sudo chattr -i file
now the "ordinary" owner will be able to delete it:
$ rm file
you can set this attribute on the directory as well. then the entire contents of the directory (but not subdirectories for which the attribute is not set) will become (partially) immutable: it will not be possible to create / delete / rename files / directories, but it will be possible to change the contents of files.