-1

I've seen a few of these exec/shell_exec questions but I can't tell what I'm doing incorrectly.

I'm making an embedded web application that will allow a user to change the ip address of the device they are connected to. I have a bash script that works from an SSH terminal, but not from exec() or shell_exec() in PHP. This is all running on a Raspberrypi, Nginx, and PHP 7.3.

Here is the bash script:

#! /bin/bash

# GLOBAL
regex_selector=".*"
file_name="/etc/dhcpcd.conf"

# IP
ip=$1
ip_flag="static ip_address="
new_ip="$ip_flag$ip"
command="s!$ip_flag$regex_selector!$new_ip!g"
echo "$command"
sudo sed -i "${command}" "$file_name"

# ROUTER
# router=$2
# router_flag="static routers="
# new_router="$router_flag$router"
# command="s!$router_flag$regex_selector!$new_router!g"
# echo "$command"
# sudo sed -i "$command" "$file_name"

# DONE
echo "settings updated"
sudo reboot

Here is the PHP:

...
$ip = $input_[1];
$command = "bash change_ip_settings.sh ".$ip;
$output = [];
exec($command, $output);
foreach($output as $key => $value) {
    echo("$key: $value<br>");
}
echo("<br>");
var_dump($output);
...

Here is the output on the page:

0: s!static ip_address=.*!static ip_address=192.168.200.2!g
1: settings updated

array(2) { [0]=> string(56) "s!static ip_address=.*!static ip_address=192.168.200.2!g" [1]=> string(16) "settings updated" }

As you can see, the various echo commands before and after the sed are executing. Also, there is no error message returned from exec(). Finally, this same script does run when called from an ssh terminal.

I know this is some permission issue but I'm not sure what to do. The bash file, php file, and target file all have 777 permissions (given by chmod).

enter image description here

enter image description here

Thanks for any help.

UPDATE:

I've followed the advice given in this post but sed still does not work when used in a bash script being called by php via exec(). I have added www-data to my sudoers file using visudo. I know the user is www-data because I ran a whoami in my bash script file and echoed the results. I have tried to remove sudo from the bash scrip line with sed but that has had no effect. All indications are that the script executes, there are no errors in the output of exec(), but when I check the file, the target line has not changed. Again, the script does work when run from both an ssh and local terminal so I know this must be some sort of permissions issue. I'm thinking I may also need to add the path to sed in sudoers which is what I will try next.

Sudoers:

www-data ALL=NOPASSWD: /path/to/my/script

Thanks again for any help.

SOLUTION:

I resolved this issue by not using a bash script for the sed operation. Initially, I wanted to separate the system file functions from PHP and use bash. However, I could not get PHP to use sed inside a bash script. So, I just called sed directly in exec() and it works fine. This is not ideal as far as I'm concerned because I don't want my page script to parse my system files but I'll have to look into granting www-data the correct permissions to use sed in a bash file.

Here is what I had:

...
$ip = $input_[1];
$command = "bash change_ip_settings.sh ".$ip;
$output = [];
exec($command, $output);
...

Here is what works:

...
$file_name = "/etc/dhcpcd.conf";
$parser = new DHCPCDParser($file_name);
$line_number = $parser->get_line_number($interface, "static ip_address");
$command = $line_number."s!.*!static ip_address=$input_[1]!";
$command = "sudo sed -i '$command' $file_name";
exec($command, $output, $result);
exec("sudo reboot");
...

And the changes I had to make to /etc/sudoers:

...
www-data ALL=(ALL) NOPASSWD: /usr/bin/   # needed for sed
www-data ALL=(ALL) NOPASSWD: /usr/sbin/  # needed for reboot
...
John
  • 19
  • 3
  • I've just added a variable for the results parameter of exec() and it does return a 1, not a 0. However, my php error logs, /var/log/nginx/error.log does not have anything in it. – John Aug 03 '23 at 19:59
  • 1
    You need to make sure "who" is executing what to check for permissions. Include a `whomai` and then set appropriate permissions/groups. `exit(0)` means ok, any other means error. – Markus Zeller Aug 03 '23 at 20:13
  • Your web server can't run `sudo` unless you configure your system to allow that. Also, why run bash when it's already in the script's shebang? DO NOT give things 777 permissions if you don't know what you're doing, especially to system configuration files. Finally, use `escapeshellarg()` on ANY variable data being put into a command ESPECIALLY if it comes from users. – miken32 Aug 03 '23 at 21:28
  • @MarkusZeller Thanks for the whoami suggestion. I used that to add a line to sudoers with visudo but it still does not work. I no longer get an result of 1; that is now 0 so it must be closer. However, the sed function still does not perform the way it does when I execute the bash script from the command line. I'll edit the post with updated info. Thanks again. – John Aug 03 '23 at 23:50
  • @miken32 First, if you were the one who closed the question, thanks to the link to the similar question. It seemed to help a little but ultimately didn't solve my problem. Second shebang or no shebang, I've never been able to run a bash script on a raspberrypi for the five years I've been buying them. Everytime I try to run it without bas either from the terminal, via ssh, or via an exec()/shell_exec() I always get a bash: xxx.sh: command not found. So thanks for wasting my time by telling me something I already knew and never bothered to look into. – John Aug 03 '23 at 23:54
  • @miken32 Third, I'll give anything any permissions I want on my development pi. You don't know anything about my application, the platform it will run on, or the interfaces available. You don't know what it is doing and what my plans are for deployment. You don't know about how I need to validate my input. I intentionally left that out because this question has nothing to do with it. If you don't have anything productive to add, do not reply. All you do is get in the way with responses like this. – John Aug 03 '23 at 23:56
  • 1
    A `command not found` could imply you are in the wrong directory or your environment of the executing user is different from that where you manually run this. – Markus Zeller Aug 04 '23 at 07:07
  • @MarkusZeller I'm sure there is a "fix" for this but its simply not an issue. I deploy to debian 11 and I don't need to use bash there, the shebang works properly. – John Aug 04 '23 at 15:33
  • I would recommend to read this: https://askubuntu.com/questions/978451/how-do-i-run-commands-as-a-non-root-user-in-a-script-started-with-root-permissio and you could execute the bash script via sudo. That is not nice, but a workaround. Also try a sh instead of bash. Maybe that is sufficent for your environment. – Markus Zeller Aug 04 '23 at 15:50

0 Answers0