Cannot exec R script in shell using php - php

I'm trying to build an interface which allows entering a query that is to be passed to an R script (found in the same folder) which does some calculation and prints the output:
<?php
$author=$_POST['data'];
echo $author."<br>";
$output = shell_exec("Rscript --vanilla h-index.R '$author' ");
echo "<pre>$output</pre>";
?>
Yet for some reason the script won't fire.. I gave it exec permissions and tested it via the command line and it works.
Any ideas?

OK, I figured out thanks to rickdenhaan that shell did not recognise the 'Rscript' command and using the absolute path /usr/local/bin/Rscript it worked

Most likely the process running php has in its .ini file the directive disabled_functions="shell_exec" and perhaps also others.
This is done for security reasons. Check with your hosting provider whether this is the case.
Note that they most likely won't be willing to change this setting though.
The command line version of php has a different .ini file than the webserver or process manager for php. This is most likely the reason you could use shell_exec when invoking from the command line.
As a side note: You should perform at least some sanitisation on the argument you accept in the $_POST variable.

Related

Why won't shell_exec execute files but does execute simple commands?

Is there any reason why I can not complied files in PHP's shell_exec/exec/system function?
Example of something that does work in command line and PHP's shell_exec function:
<?php
$data = shell_exec("ls");
echo $data;
?>
Example of something that does not work in PHP's shell_exec function but will work in command line (I can confirm that):
<?php
$data = shell_exec("./c-compiled-file argv1 argv2 argv3");
echo $data;
?>
Is there anything I can do on my server so this will work? I've looked everywhere and no solutions I found fixed the problem. The compiled file is in the same directory as the PHP script as well, it just won't execute it. Also if you're asking, yes I have tried this with SSH2 and it still will not execute.
Also PHP is not in safe mode and NO functions are disabled.
Some common glitches when executing external commands from PHP that work fine from shell:
Command uses relative paths but PHP is launched from an arbitrary location:
Use getcwd() / chdir() to get/set working directory
PHP and shell run with different user credentials. This is often the case when PHP runs through a web server.
PHP and shell run different commands. Many people call stuff like exec("foo $bar") and doesn't even check what "foo $bar" contains.
No error checking is done. The bare minimum is to capture and print standard output, standard error, status code and, of course, all PHP error messages including warnings and notices.
You can redirect stderr to sdtout
You can use a PHP function that allows to capture more information, such as exec()
The web server is disallowed to execute the command at operating system level.
Lookout for SELinux or similar tools.
Just a guess, but the binary you're trying to execute might not have the proper permissions. Prepeding it with ./ in the command line forces it to execute, but PHP probably strips that for security purposes. Try this:
chmod +x c-compiled-file
You want to use system in the second case, and not shell_exec.
system executes an external program and displays the output.
shell_exec executes a command via shell and returns the complete output as a string.
and for good measure:
exec simply executes an external program.
Furthermore you want to make sure your external program is executable and (though you have stated it, I'll restate this) has execute permissions for the user which is running the web server. You also want to make sure the directory your external program is running in has the ability to write to its directory or /tmp or whatever output directory you have set.
Finally you should always use absolute paths for executing things like this in cron or php or whatever... so don't use ./c-compiled-file argv1 argv2 argv3, but instead use /home/username/c-compiled-file argv1 argv2 argv3 or whatever the full path is.

exec function does not work out

<?php
exec("whoami");
?>
I can be more explicit with the code . Although When I'm trying to call the php file with my browser nothing happens (of course I'm using apache and the whole).
Note : The safe_mode is activated, I'm using php5, php interpreter seems to be nice when running other functions, I'm a ubuntu user.
Then what is wrong?
I think you're looking for the echo function. Executing whoami using the exec function will run the program but show you nothing… you want to spit out the result too.
echo exec("whoami");
You have to echo the output of the exec command somewhere.
PHP documentation for exec function contains the example with whoami, look at the echo.
Right in the docs for exec:
When safe mode is enabled, you can only execute files within the safe_mode_exec_dir. For practical reasons, it is currently not allowed to have .. components in the path to the executable.
If possible, turn off safe mode. Safes you lots of headaches.
Otherwise, is the php file owned by the same user that Apache runs as?
On Ubuntu, this will usually be www-data.
Try:
sudo chown www-data /path/to/you/script.php
Then run again.

Problem using PHP exec command to execute a batch file

I'm attempting to get PHP to call a batch file which will take an RTF file and convert it to a PDF using an OpenOffice macro. I've tested the batch file on the command line and it works fine, but I'm not having any luck calling and using the same batch file from PHP.
My machine OS is XP professional SP 3. I'm running IIS 6 and PHP version 5.2.9.
I've granted execute permissions to the internet user on c:\windows\system32\cmd.exe.
I specified the full path to the batch file being executed and the full path to the RTF file to be converted.
The PHP looks like this where $arg is the RTF to be converted:
$arg = "C:\\web_root\\whatever\\tempOutput.rtf";
$command = "c:\\windows\\system32\\cmd.exe /c c:\\web_root\\whatever\\convert.bat $arg";
Then inside a try-catch I call the exec command:
exec("$command 2>&1 && exit", $ret, $err);
I echo the results after the catch:
echo "ret: ";
print_r ($ret);
print "<br>";
echo "err is ";
echo $err;
print "<br>";
echo "DONE!";
And this is what I see:
ret: Array ( )
err is 0
DONE!
The RTF file does not get converted and I'm not seeing the errors. Any ideas on what I can try next? Thanks!!!
I'm going to bet this is about permissions.
In a typical setup, PHP runs as apache - so you'll want to make sure apache has the rights to execute the batch file.
also, check this relevant SO question, and this google search.
Looks like the output array is empty. Is your batch script supposed to have output?
Also, escapeshellcmd and escapeshellarg should be used
Are you using IIS as your webserver? If so, the PHP exec function will not work by default and you should NOT circumvent the security measures that prevent it from running.
Check your event viewer and you should find some errors pertaining to your problem. Run a query through google for: IIS PHP exec. This should give you a large selection of information about the problem.
Basically, the PHP exec function tries to fork a new cmd.exe instance. IIS prohibits this because it could open a security hole in the system.
The best solution that I have come up with is to have your php script either write the command that you want to execute to a flat file or make a database entry. You will then need to write a seperate script that is launched by the windows scheduler to run every 10 minutes or so that will check your flat file or database for commands to run. The new script will then run the commands and then place either the results or an execution confirmation that your web app will be able to access at a later time.
It's a kludge for sure.
Is PHP running in safe-mode? If so, shell commands are escaped with escapeshellcmd. Perhaps this is the problem?
Do you have control of the server running the PHP script?

Get apache linux user from php

I'm on a foreign linux system and need to determine the user that apache runs on (and so does php).
The aim:
I need to get the owner of the script (this is no problem as I can use SplFileInfo) and compare it to the owner of the apache process.
I'm open to any alternative proposals.
Regards,
Mario
Edit:
Additional info:
The script is a thumbnail generator, that uses an XML file to generate thumbs from larger images. The script needs to create folders and write files. As I cannot influence the php configuration and I do not have any shell access, this has to be done very silently.
The creation process stopps via exception and sends a mail on failue. As most of php's function cannot throw exceptions on failue, I need some manual checks to determine the environment I'm in. Therefore I need the apache user to compare it to some directory or fileowner.
You can call the php exec function to execute whoami:
<?php echo exec('whoami'); ?>
see posix_getuid() and posix_getpwuid()
Some complicated answers here.
This works for me:
$user = getenv('APACHE_RUN_USER');
Not sure if this is just a new thing that been added to apache since this question was asked but it's definitely there now.
phpinfo will dump a lot of system information. For apache2 installs, there is a section that displays the apache user and group ids. Try creating a php script that just has one line, a call to phpinfo(), and open it in your web browser.
Some php script must be run on apache user (cli), whoami is not appropriate in that case.
Here is my solution :
$output = exec('apachectl -S 2>/dev/null | grep User');
$apacheUser = preg_match('/name="([^"]+)"/', $output, $match) ? $match[1] : 'www-data';

illegal command error code 127 in php exec function

I am using this php code:
exec("unrar e file.rar",$ret,$code);
and getting an error code of illegal command ie 127 ... but when I am using this command through ssh its working ... because unrar is installed on the server ... so can anyone guess why exec is not doing the right stuff?
Try using the direct path of the application (/usr/bin/unrar of whatever), it sounds like php can't find the application.
If you have chrooted apache and php, you will also want to put /bin/sh into the chrooted environment. Otherwise, the exec() or passthru() will not function properly, and will produce error code 127, file not found.
Since this comes up as a top answer in google, I wanted to share my fix:
The simple fix I had was to disable safe_mode in the php.ini file
; Safe Mode
; http://www.php.net/manual/en/ini.sect.safe-mode.php#ini.safe-mode
safe_mode = Off
thanx all for your response!!
I tried this
//somedir is inside the directory where php file is
chdir("somedir");
exec("/home/username/bin/unrar e /home/path/to/dir/file.rar");
and now it returned no exit code ... oher commands are doing file .. i tried mkdir etc .. :s
Just in case somebody else still gets this problem, take a look at the post here:
http://gallery.menalto.com/node/2639#comment-8638
Quote:
I found the problem. The problem was my security-paranoid OpenBSD. When upgrading from 3.1 to 3.2 they added:
Apache runs chroot'd by default. To disable this, see the new -u option.
The chroot prevented Apache from accessing anything outside of a directory, so I moved everything into the apache directory including netpbm. Everything was accessible and executable, but I guess it was still in some sort of "safe mode" because the exec() always returned 127.
Anyway, running httpd with the -u option went back to the less secure non chroot'd apache startup, which allowed the exec() to work again.
ohkiee guyz thanx ... and yes there might be some errors with $PATH ... but with given full path its working :)
exec("/home/user/bin/unrar e /home/user/xxx/yyy/file.rar");
I did not find the solution for my problem of the same type so sharing what was the cause of it in my Linux setup.
For whatever reason I needed an apache module loaded before other modules and so apache was started with LD_PRELOAD. As exec inherits the environment of the parent process LD_PRELOAD was used for starting the exec-ed program (through sh). Now the preloaded module uses some bindings to apache functions and of course they are not to be present in sh. The result of the php exec was an exit status of 127. The solution was to have in my php file a putenv("LD_PRELOAD") that gets executed before any exec calls.

Categories