Why is a file with 400 permissions seen writable by root but read-only by user?
I think you have have misunderstood what -w
does. It does not check to see if the file has "Write permissions", it checks to see if the file is writable by the invoking user.
More specifically, it calls access(2)
or similar.
eg if a script has if [ -w /etc/shadow ]
then if you run strace
on the script you may see a line similar to
faccessat(AT_FDCWD, "/etc/shadow", W_OK)
Since root
can write to the file then it returns 0.
eg as a normal user:
faccessat(AT_FDCWD, "/etc/shadow", W_OK) = -1 EACCES (Permission denied)
As root
faccessat(AT_FDCWD, "/etc/shadow", W_OK) = 0
This, despite the fact that /etc/shadow
has permission 000
on my machine.
---------- 1 root root 4599 Jan 29 20:08 /etc/shadow
Now what you want to do gets interesting and isn't so simple.
If you want to check the simple permissions then check the ls
output, or call stat
or similar. But realize that ACLs can over-ride these permissions. Just because a file is permission 400 doesn't stop it from being writable...
test -w
aka [ -w
doesn't check the file mode. It checks if it's writable. For root, it is.
$ help test | grep '\-w'
-w FILE True if the file is writable by you.
The way I would test would be to do a bitwise comparison against the output of stat(1)
("%a
Access rights in octal").
(( 0$(stat -c %a somefile) & 0200 )) && echo rw || echo ro
Note the subshell $(...)
needs a 0
prefixed so that the output of stat
is interpreted as octal by (( ... ))
.