1

So I have hosted a webpage on my apache server and I'm trying to run some python and bash scripts when the user presses a button via PHP and AJAX.

Now my php file executes at python script (located in /var/www/html) which in turn executes a bash file (located in root/files).

On doing this manually in terminal, everything works perfectly fine.

But when I try to this via the webpage, the bash script isn't executed.

(I can't place the bash script in /var/www/html because it has the command to clone a git repository to the server and it gives private key shouldn't be public error when placed there)

I already tried suggestions in this answer by adding www-data to sudoers but it is still not working as expected.

Any help on this would be appreciated. Thanks

PHP file :

if(isset($_POST['timestamp']))
{
$uid = $_POST['timestamp'];
echo "Please wait while the app is being generated".$uid;
exec("python /var/www/html/appgenserver.py $uid");

appgenserver.py

#! /usr/bin/env python
import os
import json,sys
from firebase import firebase
import requests
import subprocess


arg = sys.argv[1]
# Path to be created
path = "/root/files/"+str(arg)
print path
if not os.path.exists(path):
os.makedirs(path)     #Gets executed
subprocess.call(['/root/Final/clone.sh', path)   #Not getting executed
8
  • Can you paste the php code you're using to run bash script? Commented Jun 10, 2016 at 19:08
  • Please check the edit @VinodKumar Commented Jun 10, 2016 at 19:13
  • OK, try to use the full path of python in exec funtion Commented Jun 10, 2016 at 19:15
  • 1
    Why are you involving Python? Especially if you intend to only call a bash script? Commented Jun 10, 2016 at 19:28
  • 1
    Have you tried putting full path of python executable? Commented Jun 10, 2016 at 19:47

1 Answer 1

1

Most likeley because a bash script in its self won't be executable, it's just a plain textfile.
Your bash (and perhaps even appgenserver.py?) might be located under /root and apache probably runs as a non-priviliged user such as www-data, that user won't be able to access either your python script and in turn not the bash that the python would run.

Consider instead calling bash with the script as a parameter.

#! /usr/bin/env python
import os
import json,sys
from firebase import firebase
import requests
import subprocess


arg = sys.argv[1]
path = "/root/files/"+str(arg)
print path
if not os.path.exists(path):
    os.makedirs(path)
subprocess.call(['/bin/bash', '/root/Final/clone.sh', path)

Now, this is NOT the most pretty of solutions.
But what you got before was probably a generic "Permission denied" error in the background (check your /var/log/apache/error.log).

What this does is start /bin/bash as a subprocess with the first parameter being the script you want to execute.

But you have zero error handling here and you can't interract with the process very much.

Consider doing something like this instead:

import subprocess

handle = subprocess.Popen(['/bin/bash', '/root/Final/clone.sh', 'parameter'], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.STDOUT)
while handle.poll() is None:
    print(handle.stdout.read()) # There's some optimizations here to be done as well so it's not a blocking call etc.

handle.stdout.close()
handle.stdin.close()

And one last tip is not to place stuff in /root/ at all if you're integrating it into a web front-end/backend type of thing.
You're asking for trouble : )

Another way is to make use of sudo

If you modify your exec() in PHP to run exec("sudo ...") and enable your web-user to run the scripts without a password prompt it could work.

Bare in mind, it's not recommended to give www-data sudo access, rather do something like this:

# useradd -m -G www-data -s /bin/bash wwwexec
# echo "myuser ALL=NOPASSWD: /usr/bin/python" >> /etc/sudoers

and change your PHP script to have the following:

exec("sudo -u wwwexec python /var/www/html/appgenserver.py $uid");

That way at least your entire web service isn't given root access via the default username.

The way to do it

Would be to place your appgenserver.py under /var/www/cgi-bin/ instead, and create a CGI hook for .py in your apache configuration and hand over the user to the URL prividing you access to the CGI script.

That way everything should be according to best practices even tho, in theory, you could get your original solution to work.

For instance, this guide should get you started.

Sign up to request clarification or add additional context in comments.

29 Comments

@HarshitDwivedi Humm, Ok what does your /var/log/apache/error.log say?
@HarshitDwivedi Also if you do sudo -i -u www-data and then python yourscript.py will it still worK? Because I'm guessing the www-data user (or whatever your apache is running as) can't access /root stuff?
@HarshitDwivedi What folder was appgenserver.py located in when you tried? Because if you're standing in /root as root, trying to execute that the user won't be available in that context because it doesn't have permission to be there : ) If i'm not mistaken.
@HarshitDwivedi Hate debian based distros.. try this su - www-data -c 'python yourscript.py. The account www-data probably doesn't have a home folder on your system so the system doesn't let the user live in a logged in session.
@HarshitDwivedi There is one nasty thing you could do in your PHP script, exec('sudo -u myuser python appgenserver.py ...'); and if you add your myuser to the sudoers file as myuser ALL=NOPASSWD: /usr/bin/python. There's all kinds of red flags here but might work. Don't forget to do sudo useradd -m -G www-data -s /usr/bin/nologin myuser also.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.