I have a php script calling a bash script like this:

    $result = exec('sudo /bin/bash /var/www/my_bash_script.sh /var/www/vhosts/testsite/htdocs/');

This is the contents of my_bash_script.sh:

svn export --force --no-auth-cache --username myusername --password mypassword $1 2>&1
find $1 -print0 -type d | xargs -0 -n 1 -0 chown -R -v root:root 2>&1
find $1'storage' -print0 -type d | xargs -0 -n 1 chown -R -v apache 2>&1
find $1'shared' -print0 -type d | xargs -0 -n 1 chown -R -v apache 2>&1

The purpose of the script is to do an export from my svn repo and set user permissions correctly.

PHP runs as the apache user.

In order to grant PHP permission to run this script I have added the following line to sudoers:


Now obviously this gives PHP too much power, so I want to restrict PHP to just run this specific bash script, but I can't seem to get the syntax right:

apache ALL=(ALL) NOPASSWD:/var/www/my_bash_script.sh

The above just returns an empty string (to the $result PHP variable) - what am I doing wrong?


Edit: - I have already commented out #Defaults requiretty in sudoers.

  • 1
    Why does this need to run from a PHP script? – Michael Hampton Apr 22 '16 at 8:25
  • Unfortunately we have to make this feature client facing so it has to run from our web interface. – bbeckford Apr 22 '16 at 8:42
  • Can do it as better outlined here: unix.stackexchange.com/questions/130906/… – Dan Armstrong Apr 22 '16 at 9:10
  • Lets just hope that storage and shared dont symlink to / as that might have some pretty negative consequences. – Matthew Ife Apr 22 '16 at 9:35
  • @MatthewIfe They don't :) – bbeckford Apr 22 '16 at 12:19

I may be wrong, but I believe that sudoers also restricts parameters that can be passed to a command/script, not just the command itself.

If you try to run your .sh without the parameter it will likely work e.g.

  sudo /bin/bash /var/www/my_bash_script.sh

So, to tell sudoers to allow that script to be run with any parameters (by apache), you would need to adjust the line like so:

  apache ALL=(ALL) NOPASSWD:/var/www/my_bash_script.sh *

The wildcard would allow apache to run that script with any parameters.

You may also need /bin/bash in that line but I'm not certain

  apache ALL=(ALL) NOPASSWD: /bin/bash /var/www/my_bash_script.sh *

If anyone can confirm or refute my understanding of this it would be much appreciated

  • That did it!! I changed the line to: apache ALL=(ALL) NOPASSWD: /bin/bash /var/www/cp_svn.sh * Thanks for all your help guys :) – bbeckford Apr 22 '16 at 12:17

You can use the following settings

Cmnd_Alias SVNUP = /root/webhooks/svn_update.sh

Create simple test script

# cat test.sh

set -u
echo "Param1: $1"

Make simple tests

$ id alex
uid=506(alex) gid=506(alex) groups=506(alex)

$ cat /root/webhooks/test.sh
cat: /root/webhooks/test.sh: Permission denied

$ sudo /root/webhooks/test.sh val1
Param1: val1

$ sudo /root/webhooks/test.sh
/root/webhooks/test.sh: line 5: $1: unbound variable

But you must be a really careful due to variable expansions, for e.g.

$ sudo /root/webhooks/test.sh "$(rm -fr ~/*)"

P.S. As alternative you can use mpm-itk with apache and run this particular vhosts with specific user.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.