I need to execute a Ruby file via PHP on Debian 8 & Apache server.
The current code looks like
exec('/usr/local/rvm/rubies/ruby-2.1.1/bin/ruby /var/www/project/_backend/pull-data.rb clients', $null, $returnVal);
echo intval($returnVal);
In this example, $returnVal (see exec()) returns 1 which could be missing permissions for executing the specific file.
The current permissions for pull-data.rb:
-rwxr-xr-x 1 www-data www-data pull-data.rb
Watching the Apache error log a Load Error occures when the php scripts calls the ruby exec command:
`require': cannot load such file -- mysql2 (LoadError)
The MySQL2 gem is installed and executing the Ruby file via the shell ruby command just works fine.
Thanks,
Roman
Related
EDIT - Adding new info at the top for visibility. The www-data user can't use the exec() command. All attempts return a 127 error.
I setup a simple script that is just this
<?php
$res = exec("echo EXEC", $res1, $res2);
var_dump($res);
var_dump($res1);
var_dump($res2);
?>
When executed via the application (which of course runs as www-data) this returns the 127 error code.
When executed via this command it runs flawlessly sudo -u root php testExec.php
When executed via this command it again returns the 127 error code sudo -u www-data php testExec.php
Original Question
I can only seem to get the error code 127 back when trying to use the exec command in php. I'm trying to use the https://github.com/rialto-php/puphpeteer package to generate pdfs and it was working flawlessly but I can't find what changed that is causing it to fail now.
I've been using /usr/local/.nvm/versions/node/v14.2.0/bin/node as the path to node but I also tried copying it here /node/v16.14.2/bin so I could give the entire directory structure execute permissions. In either/both places node is owned by www-data (the user that php runs as) and has execute permissions (755).
Running '/node/v16.14.2/bin/node' '/var/www/html/vendor/nesk/puphpeteer/src/get-puppeteer-version.js' (the initial command that puphpeteer generates) from the command line works just fine and returns the expected result "5.5.0" so node is there and executable and the get-puppeteer-version script exists.
After troubleshooting that I decided to just test exec and discovered that that doesn't work for any commands. I've tried just running exec("date"); and exec("echo EXEC") and these also return the same exit code 127.
The disable_functions ini setting is empty (confirmed via empty result from ini_get('disable_functions')). Safe mode is not enabled (confirmed via false result from ini_get('safe_mode')).
If anyone has any insight into why exec won't work at all would be great!
Environment:
Ubuntu 18.04.4
PHP 8.1
So after further investigation.. I found that this was indeed a permissions issue. I had double checked that node and everything in the /bin folder had appropriate execute permissions..
What I had missed (and am not sure how it got changed) was that the /bin folder itself didn't have the appropriate execute permissions. Adding those immediately fixed my issue.
I want to run a binary say, ./blastn (which is inside a bin directory within the doc root of the web app) from my PHP web application. I have used PHP function exec() for this as below:
exec("echo -e {$input_seq} | ./blastn -db XXXX_NT",$cmd_output,$cmd_status);
When I try to run, it gives the return status 126 and the following error message in the logs
sh: line 13: ./blastn: Permission denied
It executes when I set the sebool httpd_unified to 1. Is it possible to do this without setting this SELinux bool.
System details : Apache 2.4.6 on Centos 7, PHP 7.3.12
I need some help as my script doesn't create a file. I want to run this script at cronjob. I am using Debian Linux with PHP and Apache.
My script is locate at /var/www/myapplication folder. I want to create / write a file at /var/www/myapplication/testfolder.
The commands I use in the php script is:
echo `whoami`;
exec ('whatever >> testfolder/testing.txt');
Folder rights:
drwxrwxrwx 2 www-data www-data 4096 Jul 27 09:55 testfolder
When I run the script directly from browser (http://127.0.0.1/myscript.php)
it doesn't create the file (testing.txt)
echo whoami says: www-data
When I run the script from the server with root rights (su):
php -q /var/www/myapplication/myscript.php >>log3.txt
it creates the file (testing.txt)
echo whoami says: root
log3.txt is created at /var/www/myapplication folder
When I run the script from crontab:
/usr/bin/php -q /var/www/myapplication/myscript.php >>log3.txt
it doesn't create the file (testing.txt)
echo whoami says: root
log3.txt is created at /root folder
Why isn't testing.txt created my I run my script from crontab as a cronjob ?
You shouldn't be executing operating system commands directly, there are already functions and objects avaliable in PHP for writing and read files. As well, you shouldn't be giving them permission to be writing files to /. Even though you're running it from localhost, if you ever expose the service you're allowing public users to run operating system commands.
You also mention in your comment that you want to redirect the output of 'whatever' to a file, but I still don't see why you couldn't do this with the PHP provided functions.
Regardless, to answer the original question when you run the script via localhost you're accessing it via Apache which means the user www-data is running the PHP script. When you access it via your cronjob you're calling PHP from the commandline and another user is accessing the service.
You can see the error that is being returned from attempting to write to the file by logging in with the user running the cronjob and using echo exec(...).
I am trying to run a command line file conversion using open office.
openoffice pdf filename.doc 2>&1
when i execute in command line as root it works fine and the file is converted. However when i pass the above command in a PHP file as apache user, it does not execute.
I tried all three PHP command line execution:
$command_output=system($command_line,$rtnval);
$command_output=exec($command_line,$rtnval);
$command_output=passthru($command_line,$rtnval);
Also,
echo print_r($rtnval);
echo print_r($command_output);
$rtnval returns 1 and $command_output 1. I am confused unable to know what is the linux (centos) response to above command passed. It is very frustration because unable to know what the system response when i try to execute the command.
I also included /etc/suders permission for apache to run the open office command.
apache ALL: (ALL) NOPASSWD: /path/to/openoffice
still the command is not execute in PHP as apache user.
What am i missing for PHP as apache user not to execute this command?
It could be that openoffice is not in PATH. Try to execute it with the full path.
To run your command as if you were the apache user, just try this in a shell:
# switch to superuser
sudo su -
# then switch to the apache user
su - www-data
You will find yourself in a quite restricted shell, from which it is usually not possible to start openoffice. Indeed, it requires a lot of environment, that would be unsafe to completely set up for apache anyway.
AFAIK, better create a dedicated user that is allowed to run your command (eg a regular "www-runner" user), then "su" to it from PHP. Other security measures include chroot'ing the dedidacted user, or using apparmor to limit what and where it is allowed to run. In any case, never let www-data run something as root by adding www-data to the sudoers: this is way too dangerous!
You can also have a look at libapache2-mod-suphp (a suid apache module to run php scripts with the owner permissions).It is easier to use than the dedicated suEXEC apache beast (http://httpd.apache.org/docs/2.0/suexec.html). The latter really is not for a quick fix ;)
It is possible that your php in apache runs in safe mode or what's it called, in which system() function and alike are disabled.
This answer, actually, assumes that what you call "running as apache user" is in fact running in apache environment, whatever it is.
I'm trying to run a Python script using exec() from within PHP. My command works fine when I run it directly using a cmd window, but it produces an error when I run it from exec() in PHP.
My Python script uses NTLK to find proper nouns. Example command:
"C:\Python25\python.exe" "C:\wamp\projects\python\trunk\tests\find_proper_nouns.py" "I went to London this morning"
returns [London] when I run it from cmd, but throws an error in the Apache log when I run the same command from exec().The script is defintely getting run OK - if I change the python script to be print "Hello World" that is returned fine.
I know it's a big ask for anyone to know how to fix this NLTK error, but I could really do with any pointers as to why running it from exec is different to cmd. (The command is identical).
I'm running WAMP on Windows 7 with Apache 2.2.11.
Here's the error in the Apache log:
Traceback (most recent call last):
File "C:\wamp\projects\python\trunk\tests\find_proper_nouns_command_line.py", line 6, in <module>
parts = nltk.pos_tag(text)
File "C:\Python25\lib\site-packages\nltk\tag\__init__.py", line 62, in pos_tag
tagger = nltk.data.load(_POS_TAGGER)
File "C:\Python25\lib\site-packages\nltk\data.py", line 590, in load
resource_val = pickle.load(_open(resource_url))
File "C:\Python25\lib\site-packages\nltk\data.py", line 669, in _open
return find(path).open()
File "C:\Python25\lib\site-packages\nltk\data.py", line 451, in find
raise LookupError(resource_not_found)
LookupError:
**********************************************************************
Resource 'taggers/maxent_treebank_pos_tagger/english.pickle' not
found. Please use the NLTK Downloader to obtain the resource:
>>> nltk.download().
Searched in:
- 'C:\\nltk_data'
- 'D:\\nltk_data'
- 'E:\\nltk_data'
- 'C:\\Python25\\nltk_data'
- 'C:\\Python25\\lib\\nltk_data'
- 'C:\\Windows\\system32\\config\\systemprofile\\AppData\\Roaming\\nltk_data'
**********************************************************************
You have to run nltk.download() and choose 'maxent_treebank_pos_tagger'. You must make a python script and in it put:
#!/usr/bin/python
import nltk
nltk.download('maxent_treebank_pos_tagger');
then run it from command line. It will install the data files for the POS tagges, which you don't have installed yet.
After you do this it should work.
Your web server likely runs with other privileges than yourself. Possible problems include:
Path/file permission: can the web server user access the files it needs?
Different environment: are all necessary environment variables (PATH, Python-specific stuff, …) set?
Configuration: are there per-user configurations for Python or the module?
Tip: execute set in both the command prompt and from the PHP process and check the differences.
From the shell/terminal, you can use:
sudo python -m nltk.downloader maxent_treebank_pos_tagger
It will install maxent_treebank_pos_tagger (i.e. the standard treebank POS tagger in NLTK).