7

I am having difficulty with the PHP exec() function. It seems to not be calling certain functions. For instance, the code echo exec('ls'); produces no output whatsoever (it should, there are files in the directory). That main reason this is a problem for me is that I'm trying execute a .jar from a PHP exec() call.

As far as I know I'm calling the java program properly, but I'm not getting any of the output. The .jar can be executed from the command line on the server. (For the record, it's an apache server).

My php for the .jar execute looks like this:

$output = array();
exec('java -jar testJava.jar', $output);
print_r($output);

All I get for output from this exec() call is Array().

I have had success with exec() executing 'whoami' and 'pwd'. I can't figure out why some functions are working and some aren't. I'm not the most experienced person with PHP either, so I'm not too sure how to diagnose the issue. Any and all help would be appreciated.

13
  • What is the exact error? And also, you might want to use something like this: new BufferedWriter(new FileWriter(new File("out.txt"))); Commented Jun 21, 2012 at 22:24
  • The error is actually a FileNotFoundException for out.txt . My understanding is that the file's not being created, hence why it's not being found. Commented Jun 21, 2012 at 22:25
  • 4
    You may also need to change the permissions of the directory that the jar is attempting to write the file to. Not just the permissions of the jar file itself. Commented Jun 21, 2012 at 22:26
  • Yeah, that seems like it. You could also try to wrap it around with a File. Commented Jun 21, 2012 at 22:27
  • @AlexLynch Hey, that worked - now the .jar executes from the command line no problem. I'll try it in PHP now and update my question. Commented Jun 21, 2012 at 22:27

5 Answers 5

4

The reason why you are not able to execute ls is because of permissions.

If you are running the web server as user A , then you can only ls only those directories which have permissions for user A.

You can either change the permission of the directory or you can change the user under which the server is running by changing the httpd.conf file(i am assuming that you are using apache).

If you are changing the permissions of the directory, then make sure that you change permissions of parent directories also.

To change the web server user, follow following steps:

Open the following file:

vi /etc/httpd/conf/httpd.conf

Search for

User apache
Group apache

Change the user and group name. After changing the user and group, restart the server using following command.

/sbin/service httpd restart

Then you will be able to execute all commands which can be run by that user.

EDIT:

The 'User' should be a non-root user in httpd.conf. Apache by default doesnot serve pages when run as root. You have to set user as a non-root user or else you will get error. If you want to force apache to run as root, then you have to set a environment variable as below:

env CFLAGS=-DBIG_SECURITY_HOLE

Then you have to rebuild apache before you can run it as root.

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

3 Comments

That didn't quite work - I followed your steps and got an error asking that I add a -DBIG_SECURITY_HOLE CFLAG to the env variables. I'm not too familiar with CFLAGs as they pertain to Apache.
@MattS I have edited my answer to explain why you are getting this error. My suggestion is that you run the apache as a non-root user instead of rebuilding apache.
I changed the user/group to be the administrator user (just below root), and it still didn't work.
3

I have found the issue - SELinux was blocking PHP from accessing certain functions. Putting SELinux into permissive mode has fixed the issues (although, I'd rather not have to leave SELinux in permissive mode; I'd rather find a way of allowing certain functions if I can).

1 Comment

Try using the audit2allow -a command to analyze the log and show what permissions would need to be used.
3

I have a solution: command runs from console, but not from php via exec/system/passthru. The issue is the path to command. It works with the absolute path to command

So that:

wkhtmltopdf "htm1Eufn7.htm" "pdfIZrNcb.pdf"

becomes:

/usr/local/bin/wkhtmltopdf "htm1Eufn7.htm" "pdfIZrNcb.pdf"

And now, it's works from php via exec Where command binary you can see via whereis wkhtmltopdf

Comments

2

Tore my hair out trying to work out why PHP exec works from command line but not from Apache. At the end, I found the following permissions:

***getsebool -a | grep httpd*** ----> 
    **httpd_setrlimit --> off
    httpd_ssi_exec --> off
    httpd_sys_script_anon_write --> off**

USE: setsebool -P httpd_ssi_exec 1

SEE: https://linux.die.net/man/8/httpd_selinux

Comments

-1

Your problem is not an execution issue but the syntax of the exec command. The second argument is always returned as an array and contains a single line of the output in each index. The return value of the exec function will contain the final line of the commands output. To show the output you can use:

foreach($output as $line) echo "$line\n";

See http://php.net/manual/en/function.exec.php for details. You can also get the command's exit value with a third argument.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.