I have some log files that I'm trying to delete through PHP and, despite what appear to be proper permissions, PHP's unlink command fails with a "Permission denied" error.
<?php
$path = 'foo/bar.log';
echo 'user = ' . get_current_user() . '<br/>';
echo 'owner = ' . fileowner($path) . '<br/>';
echo 'fileperms = ' . substr(sprintf('%o',fileperms($path)), -4) . '<br/>';
@unlink($path);
print_r(error_get_last());
?>
Output:
user = apache
owner = 48 ← apache
fileperms = 0664
Array ( [type] => 2 [message] => > unlink(foo/bar.log): Permission denied
[file] => /var/www/html/test.php [line] => 6 )
Containing folder permissions look okay (writable by apache):
$ ls -l /var/www/html/
drwxrwxr-x. 2 apache apache 407 Dec 29 22:55 foo
File permissions look okay:
$ ls -l /var/www/html/foo/
-rw-rw-r--. 1 apache apache 407 Dec 29 22:04 foo/bar.log
I stopped apache and ran in debug mode (apachectl -X
), found its PID, ran strace -p PID
, and opened test.php in my browser, and got this output:
setitimer(ITIMER_PROF, {it_interval={0, 0}, it_value={30, 0}}, NULL) = 0
lstat("/var/www/html/test.php", {st_mode=S_IFREG|0644, st_size=74, ...}) = 0
open("/var/www/html/test.php", O_RDONLY) = 16
fstat(16, {st_mode=S_IFREG|0644, st_size=74, ...}) = 0
fstat(16, {st_mode=S_IFREG|0644, st_size=74, ...}) = 0
fstat(16, {st_mode=S_IFREG|0644, st_size=74, ...}) = 0
mmap(NULL, 74, PROT_READ, MAP_SHARED, 16, 0) = 0x7fad849f6000
munmap(0x7fad849f6000, 74) = 0
close(16) = 0
unlink("foo/bar.log") = -1 EACCES (Permission denied)
write(9, "[Sun Dec 29 12:40:39 2013] [erro"..., 188) = 188
chdir("/var/www/html") = 0
Two things made it work:
su apache -c "php test.php"
Neither of those help me, since the PHP script needs to be run from httpd. Other things I've tried:
Is there some reason that PHP's unlink would fail with a permissions error even when permissions are correct? Why would running test.php as apache directly work but fail with a permissions error for httpd when it's running as user apache as well?
The log files are created by a java process, but I don't think it's part of the issue – i.e., I killed the java process just in case it was doing something with the log files and PHP's unlink still fails.
Thanks for any tips on debugging PHP unlink permission denied errors.
I'm using CentOS 6.5, PHP 5.3.3.