6

I have created a file test.sh which looks like this:

#!/bin/sh
mkdir /testDir

If I run the script on the command line like: sudo /path/to/test.sh it successfully creates the directory.

I have added the sudo permissions like this in the visudo:

www-data ALL=NOPASSWD: /path/to/test.sh

and I am running the script like this in my .php file:

shell_exec('sh /path/to/test.sh');

But no directory is being created!

What am I doing wrong?!


Correct user for sudo permissions?

When I run shell_exec('whoami') on the php file I get:

www-data

Correct path to script from php?

I have tested the shell script by adding an echo statement like:

#!/bin/sh
mkdir /testDir
echo "hello"

And when I run the .php command like:

echo shell_exec('sh /path/to/test.sh');

the .php page returns

hello

I have also tried in the test.sh:

output=$( mkdir /testDir )
echo "$output"

but nothing is returned


Update

If I add this to the visudo:

www-data ALL=(ALL) NOPASSWD: ALL

it works!! But when I do:

www-data ALL=(ALL) NOPASSWD: /path/to/test.sh

It doesn't... As you know already know.


I have found a good way to debug by also changing the PHP to

echo shell_exec('sh /path/to/test.sh  2>&1 1> /dev/null');

and it returns the error:

sudo: no tty present and no askpass program specified

So I have tried:

  • adding Defaults:www-data !requiretty to the visudo but no luck!!!!

  • adding -t and -A to the sudo command... (ie sudo -t ...)

  • adding export SUDO_ASKPASS=/usr/lib/openssh/gnome-ssh-askpass before the sudo command and that then just leads to a whole new world of errors.

I have no idea about this requiretty as it does not seem to be anywhere on my ubuntu system. It is not mentioned once in the visudo?


I have spent too long on this!

Can someone tell me what the problems that I could come across if I did just do:

www-data ALL=(ALL) NOPASSWD: ALL

?

Community
  • 1
  • 1
maxisme
  • 3,974
  • 9
  • 47
  • 97
  • 1
    Have you looked in other places, like the webserver root for the `/testDir/? It may be `chroot` so that `/` isn't really `/`. This could be time for an `updatedb` and `locate` – Eric Renouf May 06 '15 at 00:24
  • I want it to be the root folder. I tried `sudo find / -name "testDir"` but no luck – maxisme May 06 '15 at 00:30
  • Does the `mkdir` report success? If that's in a shell script you should be able to do an `echo $?` after to see its return value, or put it in an `if` statement to get something meaningful from it. – Eric Renouf May 06 '15 at 00:38
  • Hmm, it occurs to me that though you're giving sudo permission to execute the script, that doesn't mean that user will have write permission to `/` so you may also want to check that. – Eric Renouf May 06 '15 at 00:50
  • but doesn't sudo have write permissions everywhere? – maxisme May 06 '15 at 13:43
  • yeah, I think you're right. . . do you have selinux or something similar running? It may be preventing web processes from running outside their typical areas – Eric Renouf May 06 '15 at 13:55
  • No I don't... Have you seen my edit? So strange! – maxisme May 06 '15 at 14:35
  • Hello try to change #!/bin/sh to #!/bin/bash – dyachenko May 06 '15 at 15:36
  • 1
    Is it working from console? `su www-data -s /bin/bash` and `php -f phpfile.php` – take May 07 '15 at 09:49
  • @take `su www-data -s /bin/bash` asks for password which does not exist. Yes it works when I do `php -f phpfile.php` (without sudo may I add from root user) – maxisme May 07 '15 at 09:51
  • If you su from `root` there souldn't be a password request. and of course, after su'ing to www-data, it should be `sudo php -f phpfile.php` – take May 07 '15 at 09:52
  • Okay so I have 'logged in' to `su www-data -s /bin/bash` and when I do `sudo php -f phpfile.php` it asks for a password (which I don't have)? – maxisme May 07 '15 at 09:56
  • Note you are running `sh /path/to/test.sh` from php, which is different from the `/path/to/test.sh` you added in sudoers or even `/bin/sh /path/to/test.sh` that was suggested. What if you say `/bin/sh /path/to/test.sh` in your php script and add `www-data ALL=(ALL) NOPASSWD: /bin/sh /path/to/test.sh` in your sudoers? That is, use the exact same syntax, otherwise sudoers won't accept it. – fedorqui May 07 '15 at 10:15
  • @fedorqui done exactly that and no luck – maxisme May 07 '15 at 10:20
  • I would also try with `www-data ALL = NOPASSWD: ...`, that is, without the `(ALL)`. – fedorqui May 07 '15 at 10:25
  • Not working :( aghh so weird!! – maxisme May 07 '15 at 12:51

3 Answers3

1

If

www-data ALL=(ALL) NOPASSWD: ALL

works, but

www-data ALL=(ALL) NOPASSWD: /path/to/test.sh

does not, then clearly the executed command does not match /path/to/test.sh.
And looking at your code, you are actually not invoking /path/to/test.sh:

sh /path/to/test.sh

You are invoking sh! With /path/to/test.sh as first argument, but still.
You either need to invoke the script directly (if that works):

shell_exec('/path/to/test.sh');

or update your sudoers file accordingly (note the full path of sh):

www-data ALL=(ALL) NOPASSWD: /bin/sh /path/to/test.sh
Siguza
  • 21,155
  • 6
  • 52
  • 89
  • Unfortunately neither removing `sh` from `shell_exec()` or adding `/bin/sh` to the `visudo` are working!!! – maxisme May 07 '15 at 10:06
  • Could you try to insert a `while true; do true; done;` into your shell script, then run the PHP script as `www-data` and use `ps aux | grep www-data` to find what your full script path actually looks like? – Siguza May 07 '15 at 10:32
0

This worked for me: Added this to my ubuntu > sudoers file www-data ALL=/etc/path-to-my/script.sh

Hope this solves yours too

0

Some tips I would try:

  • try using exec instead of shell_exec
  • try disabling selinux if enabled
  • try to remove the /bin/sh prefix and use the shebang inside the script instead
  • become www-data (su www-data -s /bin/bash) and do your tests on the CLI

I hope this helps

Francesco Gasparetto
  • 1,819
  • 16
  • 20