Como resolvo um erro do PHP “Falha na abertura necessária” em um contexto de link simbólico?

3

Estou executando o Apache / PHP no MacOS X Lion 10.7.4. Minha estrutura de diretórios está configurada da seguinte forma:

/Users/achan/Sites/
lrwxrwx---   1 achan  staff    23B Apr 27 16:21 epwbst@ -> /Users/achan/dev/epwbst'

onde epwbst/ é um link simbólico dentro de ~/Sites .

Se eu colocar test.php dentro do diretório Sites/ , o Apache exibe o arquivo corretamente; vomita phpinfo() como deveria. Se eu colocar o mesmo arquivo no symlink, recebo este erro:

[Mon May 28 14:47:13 2012] [error] [client ::1] PHP Warning:  Unknown: failed to open stream: No such file or directory in Unknown on line 0
[Mon May 28 14:47:13 2012] [error] [client ::1] PHP Fatal error:  Unknown: Failed opening required '/Users/achan/Sites/epwbst/test.php' (include_path='.:/usr/lib/php/pear') in Unknown on line 0

Só para ter certeza de que o Apache estava funcionando, criei um arquivo html de teste em ~/Sites/epwbst/ e o Apache serviu como esperado.

Por que o Apache não pode executar o php no meu diretório com links simbólicos?

Eu colei minha configuração do php aqui: link

    
por Avery Chan 28.05.2012 / 09:34

1 resposta

6

Ok, isso me deixou louca por horas . é um problema de permissões, mas não como se pode pensar. O problema está nas permissões do próprio link simbólico:

/Users/achan/Sites/
lrwxrwx---   1 achan  staff23B Apr 27 16:21 epwbst@ -> /Users/achan/dev/epwbst'

Aqui está o problema: chmod normalmente não altera as permissões nos links simbólicos, porque (com a aparente exceção de php5_module e alguns outros casos além do escopo desta resposta) essas permissões são irrelevantes, já que são ignorado em quase todos os contextos. Aqui está a correção:

chmod -h 755 /Users/achan/Sites/epwbst

Observe o -h . Na página do manual:

...
-h  If the file is a symbolic link, change the mode of the link itself
rather than the file that the link points to.
...

Por algum motivo, php5_module realmente presta atenção às permissões no link simbólico. Se eles forem muito restritivos, php5_module se recusará a ver o destino, mesmo que o usuário httpd possa ler e executar o mesmo destino usando /usr/bin/php .

Considere o seguinte:

% umask 027
% cd ~/Sites
% mkdir bar
% chmod 755 bar
% ln -sv bar foo
foo -> bar
% ls -al ~/Sites/foo
lrwxr-x---  1 xyz  xyz  3 Apr 22 13:17 foo -> bar
% ls -adl ~/Sites/foo/.
drwxr-xr-x  2 xyz  xyz  68 Apr 22 13:17 /Users/xyz/Sites/foo/.
% echo 'Hello!' >bar/hello.txt
% chmod 644 bar/hello.txt
% curl http://localhost/~xyz/bar/hello.txt
Hello!
% curl http://localhost/~xyz/foo/hello.txt
Hello!

Até agora, tudo bem. Agora considere:

% echo '<?php phpinfo(); ?>' >bar/info.php
% chmod 644 bar/info.php
% curl http://localhost/~xyz/bar/info.php
<html xmlns="http://www.w3.org/1999/xhtml"><head>
...
</div></body></html>
% curl http://localhost/~xyz/foo/info.php
<br />
<b>Warning</b>:  Unknown: failed to open stream: No such file or directory in <b>Unknown</b> on line <b>0</b><br />
<br />
<b>Fatal error</b>:  Unknown: Failed opening required '/Users/xyz/Sites/foo/info.php' (include_path='.:') in <b>Unknown</b> on line <b>0</b><br />

Hmmm. Meu httpd é executado como usuário _www , então vamos verificar se esse usuário pode ler .../foo/info.php :

% sudo sudo -u _www cat ~/Sites/foo/info.php
Password:
<?php phpinfo(); ?>

Sim. Agora vamos ver se esse usuário pode executar .../foo/info.php :

% sudo sudo -u _www /usr/bin/php ~/Sites/foo/info.php
Password:
phpinfo()
PHP Version => 5.4.24
...
If you did not receive a copy of the PHP license, or have any
questions about PHP licensing, please contact [email protected].

Sim ?! WTF ?! Grrr! Agora repare:

% chmod -h 755 foo
% curl http://localhost/~xyz/foo/info.php
<html xmlns="http://www.w3.org/1999/xhtml"><head>
...
</div></body></html>

Bang. Feito.

Então, sim. Parece que php5_module faz algo paranóico e não padrão. Isso pode ter sido ignorado, já que umask geralmente usa 022 , que pelo menos criará links simbólicos com 755 . Além disso, muitos sistemas de arquivos (não o HFS +) impõem as permissões de nível de kernel do 777 durante a criação de links simbólicos, independentemente de umask .

Você e eu parecemos ser as duas pessoas no sistema solar que executam o Apache + PHP no HFS + enquanto definimos nosso umask para algo mais restritivo que o padrão. Eu aposto que você também usa o HFS + com distinção entre maiúsculas e minúsculas. o)

    
por 22.04.2014 / 23:07