I often have the problem that a program - e.g. apache - may not access a certain file or directory.
Solving the problem means to manually check the file and every single directory in the path up to root, and see if the program's user or group may access it. This is tedious.
Which program is able to automatically tell me where the problem is?
I imagine I tell the program the path, user and group - and it shows me where in the tree the problem is. Note that I'm aware of problems like symlinks vs. Apache's -FollowSymLinks
directive which cannot be detected that way.
Assuming you have the root permissions on the system, you can use this
where USER and GROUP should be replaced with the username and groupname whose access is to be assessed and ROOTDIR is the top directory of the directory tree under which to perform the assessment.
Caveats
Note that
sudo
must be appropriately configured, meaning that root should be allowed to act as any user as well as any group.How it works
The command works by executing the
test
utility for all files and directories under ROOTDIR. The options passed to the utility make it return success (zero) exit code whenever it can not access a given file or directory. This exit code is then use byfind
to determine whether to print the name of the file or directory (-ls
).Output
Output is the list of files and directories to which USER:GROUP does not have access with extra information about each file and directory similar to the output of
ls -l
(i.e. with permissions, ownership, modification time etc).Useful things you can tweak
You can test for different kinds of permissions by replacing
-r
with a different option, see man test. You can replace-ls
with-print
if you don't want the extra information about each file and directory, but just their name. Note that if the command finds directories which it cannot traverse it will also complain on stderr. Depending on what you pass totest
this may be superficial and can be dropped by redirection.I've put together this simple shell[*] script. Works best when being root:
It still requires some human post-processing, but I don't know any elegant way to check if a specific user has x permission on a directory (it would require either
su -c "test -x"
or tedious parsing ofstat -t
).[*] works in both bash and ksh
The command
tree
will help you with this task.From
man tree
:I built a simple example to demonstrate this use:
You can run
tree
as the user in question to see where the problem starts. You'd have to fix the found problem and re-run the program until there were no errors to use this as a repair tool, but as you can usetree -if
to remove indentation and print full paths, you could hack up a script that runs tree, greps for "error opening dir", grantsapache
access to that directory, and restarts itself.