I have this script,
<?php
exec('/usr/local/bin/antiword /var/www/html/rezyme_2015.doc', $output);
var_dump($output);
?>
but in browser I see:
array (size=0)
empty
I have in /usr/bin/antiword and I copy to /usr/local/bin/antiword. If I run in console:
php antiword.php
Output is
[0] =>
string(0) ""
[1] =>
string(52) "hello"
[2] =>
string(0) ""
In one forum, I saw the exact problem reported. The person that has this problem says that he solved this problem. Here is the quotation:
"Yes, it turned out to be the accessibility of the map files - they weren't world readable, once I changed permissions, it worked great. Thanks all"
However, I did not unnderstand how he solved the problem and how also I can reach and allow those map files of antiword.
And I found:
Maybe the user apache or www-data or nobody or whatever your webuser is
called, has no permissions to execute it?
You can simply check this by:
1) sudo su www-data (or whatever etc.etc see above)
2) call the script as you do in your exec() command
Or you blocked exec() in PHP.ini.
I not found in PHP.ini in /etc/php5/apache2/ and /etc/php5/cli/ this blocked exec() or exec()
And I run in my terminal:
sudo su www-data
This account is currently not available.
My question, why in my browser this script not correctly work:
array (size=0)
empty
When I get chmod 777 -R for file.doc then I have return array, but how do right ?
and what I need for fix this problem, step-by-step, whats create, whats change, help please.
Related
I am trying to execute a couple of scripts by using a remote interface. The environment is Raspbian on a Raspberry Pi (although I will be using Debian later as well) running LAMP.
The files are test.php and test.sh in the root directory of the webserver (say example.com)
test.sh
#!/bin/bash
sudo pkill chromium-browse
sudo reboot
test.php
<?php
$output=null;
$resultCode=null;
exec("./test.sh", $output, $resultCode);
// $ouptut = shell_exec('./test.sh 2>&1'); //tried this too
// echo shell_exec("./test.sh"); // as well as this
echo "Returned with status $resultCode and output:\n";
print_r($output);
?>
Initially, I had used
chmod u+x test.sh
but got an error code of 126. So I did this:
chmod 777 test.sh
Now I get an error code of 1, but it still doesn't execute. I have also tried
sudo visudo
then added
pi ALL=(ALL) NOPASSWD: ALL
(pi is the current loggedin user)
Currently I am getting this:
Array
(
[0] =>
[1] => We trust you have received the usual lecture from the local System
[2] => Administrator. It usually boils down to these three things:
[3] =>
[4] => #1) Respect the privacy of others.
[5] => #2) Think before you type.
[6] => #3) With great power comes great responsibility.
[7] =>
[8] => sudo: no tty present and no askpass program specified
)
Note: I use sudo all the time at the command line without being asked for a password.
I do have another php file in the same directory that executes an actual system command successfully. It has this line:
$uptime = exec("uptime");
which works just fine, so I know system commands are possible. Is there any way to do this? I have seen other similar questions on SO and other sites, but none of those answers have worked for me.
Any help appreciated.
I'm trying to run this command within a PHP file on a localhost webpage that runs on apache and PHP:
echo exec("/usr/bin/killall mplayer 2>&1", $result);
But it does not work, this command print_r($result); gives this output:
mplayer: no process found
Array ( [0] => mplayer(5003): Operation not permitted [1] => mplayer(5004): Operation not permitted [2] => mplayer: no process found )
Things I have tried are adding this to the /etc/sudoers
www-data ALL=(ALL:ALL) ALL
%www-data ALL=(ALL:ALL) ALL
This is a device that runs on an internal network in my home, so not a security risk.
I'm pretty sure it is a file/permission/ownership issue, but not sure what to do to allow it to run.
Any ideas? Thanks.
I can't write files in my apache webserver directory. I'm using CentOS 7. I'm trying to execute git commands from a PHP file using exec:
exec("/usr/local/bin/git -C ../myRepo fetch 2>&1", $output, $exec_return_value);
By printing the output I see that the error manifests as:
error: cannot open .git/FETCH_HEAD: Permission denied
I discovered (with help from this blog: http://jondavidjohn.com/git-pull-from-a-php-script-not-so-simple/) that this is "expected" because Apache will execute using a different user that what I use via ssh. So I need to make sure my permissions allow that user to have write access.
I determined that my Apache installation executes as a user named "apache" by printing the output of this in my php file:
exec("whoami", $debugOutput, $debugRetVal);
I also set up SSH as recommended in that same link. But unfortunately I was still getting the same error in PHP file:
error: cannot open .git/FETCH_HEAD: Permission denied
The thing that really threw me is that I don't have any permissions issues when I run as apache from my ssh session using:
sudo -u apache /usr/local/bin/git -C ../myRepo fetch
The user "apache" seemingly has different permissions when it's executing from PHP. Can someone help me figure this out?
The behavior I was seeing where the user "apache" seemed to have different permissions when executing from PHP vs executing from my SSH, was the result of SELinux. When SELinux is in its "enforcing" mode (which it is by default in CentOS 7) it essentially "layers" an access protection scheme on top of the standard linux user permissions. In a simplistic sense, the user "apache" actually did have different permissions when it was executing out of the httpd process.
To get more detailed the html directory that apache "serves" has an SELinux context type of "httpd_sys_content_t". So my git repo was inheriting that same context. But the way the SELinux security policy works is that httpd only has read access to the context type "httpd_sys_content_t". In order for httpd to have write access to the files I needed to change the context to "httpd_sys_rw_content_t". I did this using:
sudo chcon -R -t httpd_sys_rw_content_t ../myRepo
This finally solved my original error! Unfortunately it surfaced a new error that the link from the question also mentioned:
array(5) { [0]=> string(68) "ssh: connect to host PRIVATEGITHOST: Permission denied" [1]=> string(45) "fatal: Could not read from remote repository." [2]=> string(0) "" [3]=> string(51) "Please make sure you have the correct access rights" [4]=> string(26) "and the repository exists." }
But as I mentioned in my question I already set up an ssh key for the "apache" user as the blog suggested. So this was actually a different error. An error once again originating from SELinux.
By default there is an SELinux boolean called "httdp_can_network_connect" that is set to off. This prevents httpd from making external connections of it's own. Which is what you want if all you're doing is serving the content that exists on your server. For my purposes I needed to set that boolean to on using:
sudo setsebool httpd_can_network_connect on
And after 2 days of pulling my hair out. I can fianlly do a "git fetch" from a php file.
I debugged the final error with the boolean using the "audit2allow" tool which looks at some SELinux logs and tells you in more or less plain english how to solve the issue.
sudo audit2allow -a
OUTPUT:
#============= httpd_t ==============
#!!!! This avc can be allowed using one of the these booleans:
# nis_enabled, httpd_can_network_connect
allow httpd_t unreserved_port_t:tcp_socket name_connect;
If anyone is having SELinux issues relating to apache/httpd I highly recommend looking at that tool.
For the sake of completeness, I wanted to point out that changing the file context of my repository as I did above is a "temporary change" and will not persist through a system reset. In order to permanently change the context type I used:
sudo semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/html/myRepo(/.*)?"
Similarly I used this to permanently change the boolean:
sudo setsebool -P httpd_can_network_connect on
I'm attempting to use realpath() to avoid a directory traversal attack, and I can't quite figure out why it's returning false on a file that definitely exists.
The files are being hosted on an NFS share that the Apache user has access to. The entire hierarchy is 755, except for the file itself which is 777.
Here's a code snippet:
$path = "/mnt/share/path/to/20160111-133552-msg0000.wav";
$path = realpath($path);
var_dump($path);
The result is:
bool(false)
The file is definitely there. I su-ed into the Apache user and ran:
bash-4.2$ ls -lah /mnt/share/path/to/20160111-133552-msg0000.wav
-rwxrwxrwx. 1 1001 1001 77K Jan 11 13:35 /mnt/share/path/to/3000-20160111-133552-msg0000.wav
One other observation: When I remove the filename from the $path variable:
$path = "/mnt/share/path/to/
it works just fine:
string(39) "/mnt/share/path/to"
Anyone ran into this behavior before?
I think I figured this one out on my own! Good ol' selinux was preventing httpd from accessing the file:
type=AVC msg=audit(1452550767.071:18495): avc: denied { read } for pid=10397 comm="httpd" name="3000-20160111-133552-msg0000.wav" dev="0:41" ino=12483 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:nfs_t:s0 tclass=file
Was caused by:
One of the following booleans was set incorrectly.
Description:
Allow httpd to use nfs
Allow access by executing:
# setsebool -P httpd_use_nfs 1
I only discovered this when I tried to do a readfile() on the .wav file in question and got a permission denied error, which didn't make sense on a 777 file. Checked /var/log/audit/audit.log and it was obvious.
Running setsebool -P httpd_use_nfs 1 fixed it right up for me.
Don't take the following for true: this answer was written based on a misremember of the detailed combination of the access rights: 755 already allows execution for all!
You said:
The entire hierarchy is 755, except for the file itself which is 777.
While the PHP manual page says:
The running script must have executable permissions on all directories in the hierarchy, otherwise realpath() will return FALSE.
So you'd set the entire hierarchy to 777 to this realpath()to work.
For example instead of getting the following
post:Array (
"a" => "b",
"c" => "d"
)
I just get this:
post:Array (\n "a" => "b",\n "c" => "d"\n)
It's really uncomfortable to read this while debugging my code. So if you have any suggestion on why this couldn't work alright, tell me.
I am running it in a Windows7 Putty connected to an Ubuntu virtual server, which runs supposedly it's default Apache/PHP configuration. (well probably not, but as always nobody in the team remembers to have changed anything)
edit: Someone requested the code that writes to the error.log:
<?php
error_log(print_r(array("a"=>"b","c"=>"d"),1));
?>
The commands to view the error log are:
sudo tail -f /var/log/apache2/error.log
sudo vim /var/log/apache2/error.log
sudo cat /var/log/apache2/error.log
In all instances the problem occurs that \n is not executed as expected.
I also faced the same problem, but after spending a few minutes I got a solution.
When you do tail, use as below:
sudo tail -f /var/log/apache2/error.log | sed -e 's/\\n/\n/g'
If you want, you can create a file. Give it some name and paste the above command and place that in the /usr/bin/ folder.
For example
vi tailme
With the contents:
#!/bin/bash
tail -f /var/log/apache2/error.log | sed -ue 's/\\n/\n/g'
And put this in /usr/bin/. Now you can use tailme as a command.
In some cases (e.g. Mac) using Perl might work better:
tail -100f /var/log/apache2/error.log | perl -pe 's/\\n/\n/g'
The problem is caused when the Apache process can't write into the error_log file, so the syslog writes into the file instead. The syslog messes up the line breaks.
So just do:
chmod 777 error.log
This should solve your problem. Source.
When calling error_log, you can force PHP to log directly instead of passing it to Apache which is the default behavior. To do that, just specify 3 as the second argument and a file path as the third argument.
error_log("error message", 3, $logFileLocation);
For more information, check out PHP error_log documentation.
If you are viewing the output in the browser, try wrapping your output statement with the <pre> tags.
<?php
$post = Array("a" => "b", "c" => "d");
echo "<pre>";
print_r($post);
echo "</pre>";
?>
outputs to a browser a formatted array:
Array
(
[a] => b
[c] => d
)