Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top


Suppose the directory permission is 700, and the file under the directory is 570

Then the effective permission of the file is 500

Is there such a command that lists the effective permission by recursively checking parent permissions?

share|improve this question

migrated from Dec 13 '12 at 18:08

This question came from our site for professional and enthusiast programmers.

This is not so very easy to solve. Especially, the "effective" file permissions (a concept which is in this context unknown to me) is not so easy to determine.

You can access a file if all the directories leading to it are "executable". If you know the file's names, you do not need read access.

(E. g., sometimes, I make home directories 710 in order to give x access to other members of the same group. So no one else sees what I have in my ~, but they can use it if I tell them what is there.)

If the question is about accessing an existing file, the answer is different from creating or removing a file. In the latter case, the parent directory of the file(-to-be) bust be writable.

OTOH, if I do not have the x of a directory in the file's path, I cannot even determine if the file exists, and thus also not which permissions the file has. You can argue that then the effective permission would be 0, but I don't find it sensible to tell something about file permissions when I don't even know if the file exists.

But if you want so, you take the mask of each directory, do & 0111, & the masks together, and if there is a 0 where a 1 should be, you put a 0 into the file's "effective permission".

For creating and removing, you determine the parent directory's effective permission and look if it is writable and executable.

So in a 700 directory, a 570 becomes 500.

share|improve this answer
What’s your point? To quote you, “This scenario says that I – as owner – … cannot modify the file.” In other words, the owner has read+execute permission. Everybody else has no access — hence, the effective permission is 500. The fact that a different set of parameters (directory = 500, file = 600) has a different result doesn’t invalidate the example that the OP gave. – Scott Dec 14 '12 at 0:51
@Scott My point is that this is a bad example, because it might suggest that you just have to AND together the mask and get the result. This is not the case. But maybe I just got this wrong from my understanding... – glglgl Dec 14 '12 at 7:11
@Scott I made more thoughts about it and rephrased the complete answer. – glglgl Dec 14 '12 at 7:21
Well, systems that have ACLs (including *nix and Windows) have a concept of “effective permission(s)”, but they generally deal only with the interaction of ACEs within one ACL, and not with the directories leading up (down?) to the target. – Scott Dec 14 '12 at 20:51

There is no such command and no simple way to do it, especially as both the file and the directories might have ACLs set in addition to the traditional permissions making the effective file permissions more complex to compute and display. Moreover, your question assumes there is a single path to the file but symbolic links potentially presents in the path should be first resolved as their permissions do not matter, the file might also have multiple hard-links so might be reachable from another directory. The user might also be able to access it through a different path if either loopback/bind mounts are in place or the user is running in a chrooted environment.

In any case, what you can do is to impersonate a user and check if the file while accessed through a given path is readable, writable and/or executable by him/her.

Something like:

[[ $# != 2 ]] && { echo Usage $0 user file; exit ; }
dir=$(\cd $(dirname "$2");/bin/pwd)
file=$(basename "$2")
su $1 ksh -c '
cd $2 2>/dev/null || { echo "---" ; exit ; }
[[ -r "$3" ]] && p=r || p=-
[[ -w "$3" ]] && p=${p}w || p=${p}-
[[ -x "$3" ]] && p=${p}x || p=${p}-
printf "%s %s/%s\n" $p "$2" "$3"
' "$1" "$dir" "$file"

This will show the effective rights for the user on that particular file using the traditional rwx syntax. Note that this script might give false negative results if the user launching has not root privileges (or equivalent) and has no read access on the target directory.

share|improve this answer
You make several excellent points: Different hard links to the same inode can have different “effective permissions” if they are in different directories. Users can access directories through chroot or mount points that they wouldn’t be able to access directly. (Of course this applies to remote network mounts as well as loopback mounts.) One caveat: the user should use your script with an absolute path. If I cd deep into my directory structure and then run your script on a relative filename, that will defeat the point. – Scott Dec 14 '12 at 20:52
@Scott, thanks for the comment, script updated to fix that issue. – jlliagre Dec 15 '12 at 7:21
I’m not sure that works. Consider (1) I type cd ~/private/dir1, where private is 700 and dir1 is 755, and type foo fred myfile, where foo is your script and myfile is 644. Your script will su to fred, (successfully) cd to ., and report r–– — even though fred has no access to ~/scott/private. (2) I cd ~/dir2/dir3, where dir2 and dir3 are 755, and type foo fred ../myfile2, where myfile2 is a file in dir2. Your script will cd to .. (dir2) and then try to access ../myfile2 — which doesn’t exist, relative to dir2. – Scott Dec 17 '12 at 22:48
@Scott, you are right again. Fixed. – jlliagre Dec 17 '12 at 23:10

The other answers are correct. However you can use a bash one-liner to list the permissions of the directory hierarchy. First change to the directory in question, and then run:

pushd .; while [ `pwd` != / ]; do ls -ld `pwd`; cd ..; done; popd
share|improve this answer

You must log in to answer this question.