简体   繁体   中英

How to sudo or su to other user as www-data

I am trying to set up a webpage that runs scripts. The thing is, these scripts must be run using another user. It is not a permissions issue, I can physically run the scripts as www-data but the scripts rely on a whole framework and environment variables set by the user.

I am hoping to sudo or su to the user and run the scripts after.

The webpage calls a php file that runs:

$cmd1 = "sudo login -f otheruser";
$cmd2 = "whoami";
echo exec(escapeshellcmd($cmd1), $output, $status);
foreach($output as $line) echo "$line\n";
echo exec(escapeshellcmd($cmd2), $output, $status);
foreach($output as $line) echo "$line\n";

I have tried using both "sudo login -f otheruser" and "su - otheruser" and I set it so logins from www-data to otheruser don't require a password (/etc/pam.d/su)

The first command returns nothing, the second one returns: www-data so evidently it is not logging into the otheruser.

Any ideas on how this can be done, or alternatives of how I can run scripts as another user?

EDIT: So after looking at this some more, it's because of a number of things.

First off, let me say that there is most likely a better solution than giving Apache HTTPD sudoers access.

Secondly, I'm going to make some assumptions that you're using some flavor of Ubuntu if your user is www-data .

So here's how to make it work... The first place I looked was the log files. journalctl -u apache2 -f to tail the httpd log file. You'll see a lot of entries like this:

Nov 02 15:27:17 ubuntu sudo[23541]: pam_unix(sudo:auth): conversation failed
Nov 02 15:27:17 ubuntu sudo[23541]: pam_unix(sudo:auth): auth could not identify password for [www-data]
Nov 02 15:27:17 ubuntu sudo[23541]: www-data : command not allowed ; TTY=unknown ; PWD=/var/www/html ; USER=postgres ; COMMAND=/var/www/html/test2.sh

So let's first create a couple of files to test. We're going to go into this with the mindset of securing this as much as possible. So I'll create two test files, one we want to give permission to execute and one we don't.

cd /var/www/html
echo -e "#\x21/bin/bash\necho \"Running command: \$0\"\n"  | tee test.sh test2.sh
chown postgres:postgres test*.sh
chmod 700 test*.sh

Now we want to give the www-data user access to sudo . However, we only want it to be able to execute the command /var/www/html/test.sh and not /var/www/html/test2.sh . So let's create the following file:

www-data ALL=(ALL) NOPASSWD:/var/www/html/test.sh
echo 'www-data ALL=(ALL) NOPASSWD:/var/www/html/test.sh' > /etc/sudoers.d/www-data

I updated your sample PHP script a bit to give some more output:

<?php
$cmd1 = "sudo -u postgres /var/www/html/test.sh";
$cmd2 = "sudo -u postgres /var/www/html/test2.sh";
$cmd3 = "whoami";
echo "Executing command 1: $cmd1\n";
exec(escapeshellcmd($cmd1), $output, $status);
foreach($output as $line) echo "$line\n";
unset($output);
echo "\nExecuting command 2: $cmd2\n";
exec(escapeshellcmd($cmd2), $output, $status);
foreach($output as $line) echo "$line\n";
unset($output);
echo "\nExecuting command 3: $cmd3\n";
exec(escapeshellcmd($cmd3), $output, $status);
foreach($output as $line) echo "$line\n";
?>

Now, I get the following:

$ curl localhost
Executing command 1: sudo -u postgres /var/www/html/test.sh
Running command: /var/www/html/test.sh

Executing command 2: sudo -u postgres /var/www/html/test2.sh

Executing command 3: whoami
www-data

Command 2 generates no output because the www-data user doesn't have permissions to execute it. You should see the following in the log entry:

Nov 02 15:27:17 ubuntu sudo[23541]: pam_unix(sudo:auth): conversation failed
Nov 02 15:27:17 ubuntu sudo[23541]: pam_unix(sudo:auth): auth could not identify password for [www-data]
Nov 02 15:27:17 ubuntu sudo[23541]: www-data : command not allowed ; TTY=unknown ; PWD=/var/www/html ; USER=postgres ; COMMAND=/var/www/html/test2.sh

Original Answer:

I used sudo su -c and I was able to get the expected output. See the following:

$cmd1 = "sudo su -c 'whoami' postgres";
$cmd2 = "whoami";
echo exec(escapeshellcmd($cmd1), $output, $status);
foreach($output as $line) echo "$line\n";
echo exec(escapeshellcmd($cmd2), $output, $status);
foreach($output as $line) echo "$line\n";

Outputs

$ ./test.php
postgrespostgres
myuserpostgres
myuser

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM