Reputation:
Why is it possible to touch
a write-protected file?
Shouldn't the following give an error?
$ touch test.txt
$ chmod a-w test.txt
$ ls -l test.txt
-r--r--r-- 1 name group 0 Jun 13 09:14 test.txt
$ touch test.txt && echo OK
OK
$ ls -l test.txt
-r--r--r-- 1 name group 0 Jun 13 09:15 test.txt
Does touch
change permissions, touch the file, and change permissions back? Why would it do that?
Given this behavior, if I really want to protect a file so that I (my user) will never (unintentionally) change, remove or change its timestamp in the future -- how can I do it?
(Sorry, not strictly programming-related, but slightly, and probably of interest to many programmers.)
Upvotes: 7
Views: 3933
Reputation: 16
In layman's terms, using the touch command will update or create a file without editing/modifying its contents. Because the command doesn't(and can't) write or erase anything from the file, it can be used on write-protected files. See the wiki on the touch command for more information: http://en.wikipedia.org/wiki/Touch_(Unix)
Upvotes: 0
Reputation: 21630
The execution permissions of the directory that the file contains dictates the ability to delete or modify the inode information for the entry in the directory that is associated with the file.
As the comment below indicates I have glossed over the technical reason but instead offered a reasoning why the behavior might not be as expected. Since you can execute in the directory there are a number of things you can do to tinker with the file and I am going to leave it at that.
If you want to stop anyone but root from modifying a file the best method is to use the chattr +i filename on the file. Even root will not be able to perform any actions on it without running chattr -i on it. This applies to Linux so YMMV.
Upvotes: 6
Reputation: 60993
You can update the modification time if you own the file, regardless of write permission. (It is not related to any permission on the directory.)
From POSIX.1-2008:
Only a process with the effective user ID equal to the user ID of the file, or with write access to the file, or with appropriate privileges may use
futimens()
orutimensat()
with a null pointer as the times argument or with bothtv_nsec
fields set to the special valueUTIME_NOW
. Only a process with the effective user ID equal to the user ID of the file or with appropriate privileges may usefutimens()
orutimensat()
with a non-null times argument that does not have bothtv_nsec
fields set toUTIME_NOW
and does not have bothtv_nsec
fields set toUTIME_OMIT
. If bothtv_nsec
fields are set toUTIME_OMIT
, no ownership or permissions check shall be performed for the file, but other error conditions may still be detected (including [EACCES] errors related to the path prefix).
Upvotes: 5
Reputation: 21406
Here's the relevant output from : strace "touch test.txt"
open("test.txt", O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK|O_LARGEFILE, 0666) = -1 EACCES (Permission denied)
futimesat(AT_FDCWD, "test.txt", NULL) = 0
It indeed gets a "Permission denied error" on the open(2) system call regarding EACCES. See relevant section in utimes(2) man page.
However, it does succeed in updating the timestamp using the futimesat(2) system call.
As others have indicated, it looks like the directory permissions hold the rights to update access/moficiation timestamps.
You can, however change the attribute of a file to immutable using:
chattr +i test.txt
Note: Only root can do this, and it's a very harsh way to disable access to files. But in extreme cases, it can be useful. In addition, this is an ext2/3/4 feature, not available on other filesystems as far as I know.
Upvotes: 5
Reputation: 42704
From the touch
(coreutils) documentation:
If changing both the access and modification times to the current time, `touch' can change the timestamps for files that the user running it does not own but has write permission for. Otherwise, the user must own the files.
Upvotes: 6