PHP can't find file even though it exists

Viewed 1146

I'm running PHP 7.4.9 on Ubuntu 18.04 with Apache 2.

I'm getting this error on my PHP error log:

"PHP Fatal error: require_once(): Failed opening required 'HTMLPurifier.auto.php' (include_path='(other dirs):/usr/share/php:(other dirs)') in /var/www/testing.php on line 8, referer: http://localhost:8080/testing.php"

So I checked if the file exists in /usr/share/php:

# ls -lah /usr/share/php
> -rwxrwxrwx   1 www-data www-data  274 Aug 15 15:53 HTMLPurifier.auto.php

So it's there. The permissions are 777 because I changed them while trying to fix the problem.

I then visited a phpinfo(); file in the browser and checked that the dir is in the include path and that open_basedir is empty:

Directive       Local Value   Master Value
include_path    (other dirs)  .:/usr/share/php
open_basedir    no value      no value

I then created another PHP file and wrote this to check if php can see the file:

<?php

clearstatcache();

$dir = '/usr/share/php/';
$filename = 'HTMLPurifier.auto.php';
$fullpath = $dir . $filename;

var_dump($dir);
var_dump($filename);
var_dump($fullpath);

var_dump(is_dir($dir));

$all_files = scandir($dir);

var_dump($all_files);
var_dump(file_exists($fullpath));
var_dump(file_exists($dir . $all_files[12]));

When I visit it in the browser I get:

string(15) "/usr/share/php/" // $dir

string(21) "HTMLPurifier.auto.php" // $filename

string(36) "/usr/share/php/HTMLPurifier.auto.php" // $fullpath

bool(true) // is_dir($dir)

// $all_files
array(40) {
  (other files)
  [12]=> string(21) "HTMLPurifier.auto.php"
}

bool(false) // file_exists($fullpath)

bool(false) // file_exists($dir . $all_files[12])

So PHP can scan the directory, can see the file there, but says it (or any other file in the dir) doesn't exists. I tested passing a file inside /var/www to file_exists and it worked. I also tried renaming the file, but got nothing.

What gives?


Edit: Running the above script with strace php test.php (as suggested by @Progman) gives me:

access("/usr/share/php/HTMLPurifier.auto.php", F_OK) = -1 EACCES (Permission denied)
write(1, "bool(false)\n", 12bool(false)
)           = 12

access("/usr/share/php/HTMLPurifier.auto.php", F_OK) = -1 EACCES (Permission denied)
write(1, "bool(false)\n", 12bool(false)
)           = 12 

So it's a permission issue. Running the script as root works.

$ ls -lah /user/share
drw-rw-rw-  20 root root 4.0K Aug 16 11:52 php

So I tried sudo chmod 777 /usr/share/php and the script works. Anything less (e.g. 776) and I get permission denied. Any idea how I should set these permissions?

1 Answers

In linux a regular user like your normal working user or the webserver assigned user needs the directory permission "search", which is --x or the bit mask 1, to access the files inside the directory. The permission -r- or the bit mask 2 will give you only the ability to read the file names inside a directory.

To solve the problem you have to change the chmod of the directory /usr/share/php to 755.

Related