sudo in php exec()
Asked Answered
L

9

45

I don't know what the deal is here…

So I want to run an applescript: sudo osascript myscript.scpt

This works fine in the terminal, but not when I execute it via PHP's exec(); nothing happens. The console says

no tty present and no askpass program specified ; TTY=unknown ; …

I did my research, and it seems I'm missing the password for the sudo command. I tried a couple different ways to get around this, including:

  • writing %admin ALL=(ALL) ALL in /etc/sudoers
  • and proc_open() instead of exec()

none of which seem to be working, consequently driving me CrAzY!

So basically, is there a clear-cut way to get PHP to execute a simple terminal command?

EDIT: to clarify, myscript.scpt is a simple appleScript that changes the onscreen UI (for a larger project). In theory, simply osascript myscript.scpt should be enough, however the sudo is for some reason necessary to invoke some response from the system. If the sudo could be somehow eliminated, I don't think I would be having this permissions problem.

Lomasi answered 3/7, 2010 at 23:32 Comment(2)
There are ways to address this, but the best way is to probably make myscript.script run without root privileges.Snub
Any way you could go about this is technically a bad idea. You either give PHP access to sudo without needing a password, or use a setuid helper script that always runs with root privileges. Neither one is quite sane when dealing with a PHP front end. Can you update your question to tell us what myscript.scpt is actually accomplishing ?Thaxter
S
18

It sounds like you need to set up passwordless sudo. Try:

%admin ALL=(ALL) NOPASSWD: osascript myscript.scpt

Also comment out the following line (in /etc/sudoers via visudo), if it is there:

Defaults    requiretty
Strop answered 3/7, 2010 at 23:46 Comment(6)
I tried adding this to etc/sudoers, but no dice. I still get "no tty present and no askpass program specified"Lomasi
Did you have any luck commenting out the requiretty line?Strop
Nope. it wasn't in the file at all. I'm starting to agree with Matchu (below) about all this security stuff. If my system makes it this difficult, it's probably for a good security reason.Lomasi
I think that is a wise decision :) Despite me trying to help answer your original question, I do think that using sudo in a webapp has the potential to intoduce a lot of security headaches.Strop
Where in need to put %admin ALL=(ALL) NOPASSWD: ALLDues
@SunilBhawsar in /etc/sudoers via vi sudo. but it's not working for meHardi
S
8

I think you can bring specific access to user and command with visudo something like this:

nobody ALL = NOPASSWD: /path/to/osascript myscript.scpt

and with php:

@exec("sudo /path/to/osascript myscript.scpt ");

supposing nobody user is running apache.

Salmanazar answered 10/5, 2013 at 17:24 Comment(0)
W
4

php: the bash console is created, and it executes 1st script, which call sudo to the second one, see below:

$dev = $_GET['device'];
$cmd = '/bin/bash /home/www/start.bash '.$dev;
echo $cmd;
shell_exec($cmd);
  1. /home/www/start.bash

    #!/bin/bash
    /usr/bin/sudo /home/www/myMount.bash $1
    
  2. myMount.bash:

    #!/bin/bash
    function error_exit
    {
      echo "Wrong parameter" 1>&2
      exit 1
    }
    ..........
    

oc, you want to run script from root level without root privileges, to do that create and modify the /etc/sudoers.d/mount file:

www-data ALL=(ALL:ALL) NOPASSWD:/home/www/myMount.bash

dont forget to chmod:

sudo chmod 0440 /etc/sudoers.d/mount
Winzler answered 1/6, 2012 at 7:16 Comment(0)
S
2

I recently published a project that allows PHP to obtain and interact with a real Bash shell. Get it here: https://github.com/merlinthemagic/MTS The shell has a pty (pseudo terminal device, same as you would have in i.e. a ssh session), and you can get the shell as root if desired. Not sure you need root to execute your script, but given you mention sudo it is likely.

After downloading you would simply use the following code:

$shell    = \MTS\Factories::getDevices()->getLocalHost()->getShell('bash', true);
$return1  = $shell->exeCmd('/path/to/osascript myscript.scpt');
Shelter answered 18/5, 2016 at 10:26 Comment(0)
S
1

Run sudo visudo command then set -%sudo ALL=(ALL:ALL) to %sudo ALL=(ALL:ALL) NOPASSWD: ALL it will work.

Skijoring answered 6/7, 2017 at 7:31 Comment(0)
H
1

You can alternatively use passthru to validate sudo before you actually use it:

passthru('sudo -v');
exec('sudo osascript myscript.scpt', $output, $status);
Hullabaloo answered 2/8, 2023 at 12:6 Comment(0)
A
0

I had a similar situation trying to exec() a backend command and also getting no tty present and no askpass program specified in the web server error log. Original (bad) code:

$output = array();
$return_var = 0;
exec('sudo my_command', $output, $return_var);

A bash wrapper solved this issue, such as:

$output = array();
$return_var = 0;
exec('sudo bash -c "my_command"', $output, $return_var);

Not sure if this will work in every case. Also, be sure to apply the appropriate quoting/escaping rules on my_command portion.

Amieeamiel answered 13/11, 2018 at 21:25 Comment(0)
Z
0

The best secure method is to use the crontab. ie Save all your commands in a database say, mysql table and create a cronjob to read these mysql entreis and execute via exec() or shell_exec(). Please read this link for more detailed information.

          • killProcess.php
Zonked answered 6/2, 2019 at 10:16 Comment(0)
I
0

I think directly calling a sudo command might be difficult because you are setting up the whole server to work without a password.
Perhaps as an alternative you could setup a CRONjob as root and monitor a flag file. Once the flag file exists it will run the osascript myscript.scpt and then delete the flag file. This way you will keep SUDO secure from a config point of view and the server safer. To run the script you just need to touch the flag file from PHP. It would of course introduce a delay of however many minutes you running the CRON job. It would also mean that you would have to redirect the output to a file and have a async monitor of the output, but it will depend on your application if this is a problem or not.

But it is an alternative that might protect the server.

Inconspicuous answered 7/1, 2022 at 9:38 Comment(1)
I am not sure about storing commands in the database as this too could be abused. I prefer to keep things more tight. Running any command as root should be as secure as possible.Inconspicuous

© 2022 - 2024 — McMap. All rights reserved.