Issue
I'm setting up Tomcat on Centos according to https://www.digitalocean.com/community/tutorials/how-to-install-apache-tomcat-8-on-centos-7 , but with a twist: I put Tomcat in /opt/apache-tomcat-8.5.6
and then set up a symbolic link:
sudo ln -s /opt/apache-tomcat-8.5.6 /opt/tomcat
Now I change the group ownership of /opt/tomcat
to tomcat
:
sudo chgrp -R tomcat /opt/tomcat/conf
Then I give the tomcat
group write access to the configuration directory:
sudo chmod g+rwx /opt/tomcat/conf
But here is the problem: I try to give the tomcat
group read access to all the configuration files:
sudo chmod g+r /opt/tomcat/conf/*
That gives me an error: chmod: cannot access ‘/opt/tomcat/conf/*’: No such file or directory
What? Does chmod
not accept wildcards? Or does it not look inside symbolic links? What's going on?
Note that I got around it by doing this:
sudo chmod g+r -R /opt/tomcat/conf
Does that give me effectively the same thing? (I know that it additionally makes the directory readable by the group, but that seems inconsequential --- the group could already read the directory.) Why doesn't the wildcard version work?
Solution
Globs are expanded by the current shell. This happens before sudo and chown are ever invoked.
If the current shell doesn't have access to list the files, the glob will be treated as unmatched and just left alone. This makes chmod
try to access a file literally named *
, which fails.
root# echo /root/.*
/root/.bash_history /root/.bashrc ...
user$ sudo echo /root/.*
/root/.*
The same is true for command substitution, process substitution and other expansions, which are similarly unaffected by sudo:
root# echo $(whoami)
root
user$ sudo echo $(whoami)
user
The shell is also responsible for pipes and redirects, which are also set up before sudo ever runs:
root# echo 60 > /proc/sys/vm/swappiness
(command exits successfully)
user$ sudo echo 60 > /proc/sys/vm/swappiness
bash: /proc/sys/vm/swappiness: Permission denied
In Unix terms, sudo
is wrapper for execve(2)
, and therefore can't help with anything that you can't do through an execve
call. If you need shell functionality from the target user, you need to manually invoke that shell:
user$ sudo sh -c 'chmod g+r /opt/tomcat/conf/*'
Answered By - that other guy