run shell command as other user called by PHP

I have a PHP script which is called by HTTP and not as command line script. This script should call a shell command as an other user than the current webserver user www-data.

Example:

<?php
echo shell_exec('sudo -u myusername -S /usr/bin/whoami'); // returns nothing :(
echo shell_exec('whoami'); // returns www-data

When calling this 2 commands sudo -u myusername -S /usr/bin/whoami and whoami directly on the commandline they return

myusername
www-data 

Also no result on this:

<?php
echo shell_exec('echo "mypass" | sudo -u myusername -S /usr/bin/whoami');

For me it seems that sudo does not work at all together with PHPs shell_exec().


Firstly, I don't understand the sudo command you're running. sudo -u username is supposed to allow you, as user one, to sudo a command as user two, by saying (as user one, in this example, to run the command ls):

sudo -u usertwo ls

I apologise if you've tried to sanitise your commands above by substituting username for the real username, but I can't be sure you have done, so I need to raise this point first.

Secondly, sudo has to be configured to let a user perform a range of commands as another user. Let's start by allowing www-data to sudo the ls command as user fribble; you could test this by putting

www-data        ALL = (fribble) NOPASSWD: ls

in your sudoers file (substituting a real user as fribble). Then try doing, say, ls -la /tmp from inside your PHP script and see if you get a directory listing.

I agree with James Lawrie that it's not a good idea to allow the www-data user to sudo arbitrary commands, as arbitrary users, passwordlessly, but if you clarify what commands you're trying to get www-data to run, this may be a sensible way to do it.

Edit:

you have tried with ls in the sudoers file and sudo -u user2 ls -al /tmp in the PHP script, and you get a directory listing, which strongly suggests that sudo works fine with PHP.

To be sure, could you allow /bin/touch in the sudoers file, put sudo -u user2 touch /tmp/TESTFILE in the PHP script, then execute that? If a file /tmp/TESTFILE appears, owned by user2, we can be sure that sudo and PHP work fine togther.

I must confess that if I had known that you were trying to sudo java, I would never have answered the original question, because I think java is a giant unpredictable sack of crap, which behaves like a complete baby if it doesn't get the environment it requires (and sudo fairly rigorously sanitises the environment). But at least the test above should help you be sure that, whatever the problem here is, it's not an issue with PHP and sudo not playing nicely together.


Don't allow the webserver user sudo access, you're just asking for trouble. Look into the setuid bit instead:
chmod u+s some_file_that_needs_executing_as_another_user.pl
Whenever that file is executed, it will be effectively executed by the user who created it.
On a side note, I'm pretty sure you can't pipe a password into sudo or passwd.