I've set up a small web app that passes user data to a python script. Python is supposed to go to work, create a file on the webserver, and allow the user to download it. However, the script execution seems to stop where the Python write() command is issued.
Python:
print("Writing to '" + filename + "'")
f = open('backups/' + filename, 'w')
f.write(self.output())
f.close()
print("Done!")
PHP:
$user = escapeshellarg($_POST['user']);
$password = escapeshellarg($_POST['password']);
$command = './backup.py '.$user.' '.$password;
print(exec($command));
Actual result:
Python does create a file in the desired directory but it remains empty. 2. Python never outputs "Done!" (Because permissions are denied)
Expected result:
Python creates a file with data
Python proceeds to print "Done!" which is output to the calling PHP script
I've done the following:
www-data has group write permissions (drwxrwsr-x) for the directory ./backup
The #!/usr/bin/env python3 shebang is present in the python file
The python file is executable
When I change to user www-data with sudo su www-data and then start the php commandline, and enter the above command invoking my Python script, the file is created correctly!
If I start a builtin php server, it also works fine, only if the php script is handled through apache, it doesn't work
I have officially wasted an entire day of my life on this.
The permissions were all right.
What was happening is that the python script failed ONLY if it was being invoked through my php script and ONLY if that was being served by Apache.
Looking through the Apache error log revealed that the python script failed because it could not write bytes to the file and ascii conversion failed because there was unicode data in the output.
So doing f = open(filename, 'wb') solved the issue.
This behaviour was not observed on my development machine or through the built-in PHP server. Still wonder why there's a difference in file handling. Would appreciate an answer if anyone has one.
Related
I have a python script that prints out the program names that are currently in the volume mixer in Windows 10.
This works fine when I run it in the cmd.
C:\wamp\www\Volume>py test.py
firefox.exe,Spotify.exe,Microsoft.Photos.exe,Steam.exe,
and here is my python script.
import sys
from pycaw.pycaw import AudioUtilities
def main():
list = ''
sessions = AudioUtilities.GetAllSessions()
for session in sessions:
volume = session.SimpleAudioVolume
if session.Process and session.Process.name():
list += session.Process.name() + ','
sys.stdout.write(list)
if __name__ == "__main__":
main()
And my PHP:
$python = "py";
$script = "test.py";
exec("$python $script 2>&1", $output);
print_r($output);
But when I run it in PHP using WAMP, I don't get any output from that script, nothing is outputted.
If I change my python script to only contain "print("TESTING")" then I can read that output fine in PHP which makes me think that my python code is failing perhaps due to permissions. So I changed the user from SYSTEM to my own user so when I use:
echo exec("whoami") // Outputs my user account name
I thought maybe my PHP script was off, so I tried running it though the command line, but the results are what I want:
C:\wamp\www\Volume>php index.php
Array
(
[0] => firefox.exe,Spotify.exe,Microsoft.Photos.exe,Steam.exe,
)
So I'm at a loss as to why when I execute my PHP code through my browser, I am not getting any output unless my python script only contains :
print("TESTING")
What could possibly be going wrong?
EDIT
So I decided to debug this further by altering my python script to create a .txt file on my desktop, this works fine when running it through the command line. But again, when I run it through my browser/PHP, that file isn't created. So maybe I need to grant special permissions to my python script? I'm not sure why I need to do that though as I have given PHP my user account
So I think I found out why I'm not getting any output from my python script, thanks to #Torxed.
It seems like when I run the Python script through WAMP/PHP it must run as a different user/environment which doesn't have any Audio.
This is odd however as I've set 'wampapache64' to run as my user account, even after a restart I'm still getting the same results.
I've even tried
runas /savecred /noprofile /user:<USER>
But that just returns the password prompt which I won't be able to fill out in PHP.
This project looks like a dead end for now.
I have a php script which calls a shell script as below -
#!/bin/bash
timestamp=$(date +"%d-%m-%Y %H:%M:%S")
echo $timestamp >> results
The php script -
<?php
$mycmd = exec('/bin/bash exectest.sh',$op,$er);
var_dump($mycmd);
var_dump($op);
echo $er."\n";
?>
The php script returns error code 1 for $er but when i tried to modify the shell script to just print instead of writing to a file. the Php script then returns 0 and succeeds.
Any ideas of where I need to fix this?
I have tried giving the full path for the script and also this is the same case when i tried using a python script in place of a shell script.
Your observation indicates that this is most likely a permission problem, e.g. the user running PHP does not have write permission to either the results file in its current working directory or the directory itself (if the file does not exist yet).
It happened to be running on an AFS machine hence required afs priviledges for httpd.
fs sa . http write
sorted the issue.
I want to run pdflatex from php on user request.
Running from terminal works fine [php file.php] and creates pdf file. But when I try to run from browser by sending request to php, It gives this error "I can't find the format file `pdflatex.fmt'!"
I am working with php5.2.6, OS is Fedora 9, and safe_mode is turned off.
Code -
$cmd = "/usr/bin/pdflatex /home/deep/public_html/resume/Folder/deependra.tex 2>&1";
$output = exec($cmd);
echo $output;
the pdflatex.fmt must be readable by the web browser in order to be accessible for the exec command, also the server might be chrooted and if so, the chroot folder might not have access to all the pdflatex parts. check it...
I have a python file that I would want to execute whenever a php page is called. The python file is in the same folder as the php file. The python script on execution edits a textfile that the php file accesses.
I have the following code:
<?php
exec("python somefile.py",$output);
$file = fopen("test.txt",'r');
....
For some reason, the python script never gets executed. I know this certainly as I can see it from the changes in the text file.
Since I was not sure if the script was made executable, so I included "python" on the command.
I also ran:
chmod +x somefile.py
just to make sure this was not the reason. But this did not help too.
What should I change to make the php page execute the python script whenever it is called?
This is most likely a permission issue.
Try
echo exec("whoami");
This will let you know who php is running as. Then you need to verify this user can run the python script. If the file was not created by the same daemon that runs python, you will most likely be denied permission.
Update
This will let you know who owns all the files you are working with. The file being written to needs to be writable by the user that is running python. If you are running python from ssh, that is most likely not the same user as when you run python from exec.
echo exec('whoami') . "<br>";
echo exec("ls -l test.txt") . "<br>";
echo exec("ls -l somefile.py") . "<br>";
Update 2
Because I constantly forget this exists.
passthru('python somefile.py 1 2>&1');
This will exec your python file, and output stderr to stdout.
I am trying to programmatically append an RSA public key to the authorized_keys file through a website and haven't been able to make any solutions I found work. I have tried using PHP's file_put_contents() function but I run into a permission denied error, and I have a python script that works, but I cannot seem to get PHP to execute it with either the exec() command or shell_exec(). Here's the relevant PHP code:
if(#$_POST['action']=='submit'){
$key = $_POST['key_field'];
//file_put_contents("/home/biosproject/.ssh/authorized_keys", $key, FILE_APPEND);
$test = "/usr/bin/python savetofile.py \"".$key."\"";
$tmp = shell_exec($test);
}
I'm aware that I need to sanitize the input but the site is currently in development so I'm just testing it like this in the meantime. Right now I'm using XAMPP which runs Apache. Is there something I'm missing or could try? For the PHP exec/shell_exec, I have tried using the full pathnames for all parts of the command, but nothing has worked yet. The python script is as follows:
#!usr/bin/python
import sys
key = sys.argv[1]
with open("/home/biosproject/.ssh/authorized_keys","a") as append:
diditwork = append.write(key)
print key
As I mentioned before, this script is functional, but I can't call it from the PHP script.
EDIT:
My authorized_keys file looks like so: -rw-rw-rw- 1 biosproject www-data 1200 Apr 15 13:17 /home/biosproject/.ssh/authorized_keys
UPDATE:
I fixed the problem by bypassing permissions using a cron job that appends the necessary information from a database entry instead. Works great now!
The Python script won't help you here - it's a permissions issue with the /home/biosproject/.ssh/authorized_keys file, i.e. Apache doesn't have permission to modify it, and nor will any process it spawns, which would include your Python script.
Simplest fix would be to change the file permissions so it's writable by Apache. Assuming apache runs as group www-data, do...
sudo chgrp www-data /home/biosproject/.ssh/authorized_keys
sudo chmod g+w /home/biosproject/.ssh/authorized_keys
...although I forget if ssh complains if authorized_keys is set to g+w.
Update
It occurs to me that www-data will also need +x access to all parent directories of /home/biosproject/.ssh/authorized_keys to be able to change it, although I'm pretty sure that ssh will complain if you change the .ssh directory permissions in this way.
You'll either have to run apache with the same UID as the owner of the /home/biosproject/.ssh directory, or use a setuid script to make the changes.
Explanation about my inline code:
$text = "nice text to append :P";
// open a file handler with a+ flag that means "open file for append and if it does not exist, create it"
$fo = fopen("filename.ext", "a+");
// append $text to file handler with a \n at the end
fwrite($fo, $text . PHP_EOL);