Como as permissões de arquivo se aplicam a links simbólicos?

81

Digamos que você tenha essa estrutura:

+ directory
-- file1
-- file2
-- file3 -> /tmp/file3

file3 é um link para outro file3 em algum outro lugar do sistema.

Agora digamos que eu chmod 777 do diretório e todo o conteúdo dentro dele. Meu file3 in /tmp recebe essas permissões? Além disso, digamos que temos a mesma situação, mas invertemos.

/tmp/file3 -> /directory/file3

Se eu aplicar as permissões no arquivo que está sendo vinculado, como isso afeta o link?

    
por n0pe 27.06.2011 / 22:42

3 respostas

81

Depende de como você chama chmod e da plataforma em que você está executando.

Por exemplo, em um sistema Linux, man chmod diz isto:

chmod never changes the permissions of symbolic links; the chmod system call cannot change their permissions. This is not a problem since the permissions of symbolic links are never used. However, for each symbolic link listed on the command line, chmod changes the permissions of the pointed-to file. In contrast, chmod ignores symbolic links encountered during recursive directory traversals.

No entanto, em um Mac, chmod pode ser usado para modificar as permissões de um link simbólico usando opções como essa (de man chmod ):

-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 exemplo, vamos supor que você está em uma máquina Linux pelo resto desta resposta.

Se no primeiro caso você executar chmod -R 777 directory para alterar as permissões de forma recursiva, o destino do link não será afetado, mas se você usar chmod 777 directory/* , isso ocorrerá.

Se você alterar as permissões diretamente no destino do link, essas permissões serão executadas (como man page e baraboom digamos, as permissões de link reais não são usadas para nada).

Log de teste para ilustração:

$ mkdir dir && touch dir/file{1,2} /tmp/file3 && ln -s {/tmp,dir}/file3
$ ls -l dir/* /tmp/file3
-rw-r--r-- 1 user group  0 2011-06-27 22:02 /tmp/file3
-rw-r--r-- 1 user group  0 2011-06-27 22:02 dir/file1
-rw-r--r-- 1 user group  0 2011-06-27 22:02 dir/file2
lrwxrwxrwx 1 user group 10 2011-06-27 22:02 dir/file3 -> /tmp/file3

$ chmod -R 777 dir && ls -l dir/* /tmp/file3
-rw-r--r-- 1 user group  0 2011-06-27 22:02 /tmp/file3
-rwxrwxrwx 1 user group  0 2011-06-27 22:02 dir/file1
-rwxrwxrwx 1 user group  0 2011-06-27 22:02 dir/file2
lrwxrwxrwx 1 user group 10 2011-06-27 22:02 dir/file3 -> /tmp/file3

$ chmod 700 dir/* && ls -l dir/* /tmp/file3
-rwx------ 1 user group  0 2011-06-27 22:02 /tmp/file3
-rwx------ 1 user group  0 2011-06-27 22:02 dir/file1
-rwx------ 1 user group  0 2011-06-27 22:02 dir/file2
lrwxrwxrwx 1 user group 10 2011-06-27 22:02 dir/file3 -> /tmp/file3
    
por 27.06.2011 / 23:23
2

As respostas de baraboom e peth estão corretas: Os bits de permissão nos links simbólicos em si são irrelevantes (exceto no macOS; veja abaixo) e alteram a permissão em um link simbólico - pela ferramenta de linha de comando chmod ou pelo chmod() system call - irá simplesmente agir como se tivesse sido executado contra o alvo do link simbólico.

Para citar a descrição do SUSv4 / POSIX.1-2008 da chamada de sistema symlink () :

The values of the file mode bits for the created symbolic link are unspecified. All interfaces specified by POSIX.1-2008 shall behave as if the contents of symbolic links can always be read, except that the value of the file mode bits returned in the st_mode field of the stat structure is unspecified.

Aqui, "não especificado" deixa espaço de interpretação para cada implementação. Detalhes:

  • No Linux (testado usando o ext4fs), stat() retorna st_mode=0777 , não importa qual seja o umask quando o symlink foi criado; Por isso, ls -l sempre exibe lrwxrwxrwx para links simbólicos.
  • No macOS (HFS) e FreeBSD (UFS e ZFS), um link simbólico tem sua própria permissão: O comando chmod -h mencionado acima pode alterar essa permissão de link (que usa internamente um sistema não POSIX lchown() chamada para conseguir isso), e a chamada do sistema stat() retorna este valor para st_mode .

Links simbólicos no Linux e no FreeBSD sempre podem ser seguidos, conforme especificado pelo POSIX. Em particular, no FreeBSD, isso significa que o modo de arquivo de um link simbólico não tem efeito algum no controle de acesso.

Por outro lado, o macOS interrompe ligeiramente o POSIX. Embora um link simbólico possa ser seguido, independentemente de sua permissão de leitura, readlink() falha com EACCES (Permissão negada) se o usuário não tiver permissão de leitura:

$ sudo ln -shf target symlink
$ sudo chmod -h 444 symlink
$ ls -l symlink
lr--r--r--  1 root  staff  1 Mar 14 13:05 symlink -> target
$ sudo chmod -h 000 symlink
$ ls -l symlink

ls: symlink: Permission denied
l---------  1 root  staff  1 Mar 14 13:05 symlink
$ echo kthxbye > target
$ cat symlink
kthxbye

(Observe que a parte -> target está ausente na saída do segundo comando ls -l e que cat symlink ainda teve êxito e imprimiu o conteúdo do arquivo target mesmo que o usuário não tivesse permissão de leitura em symlink .)

O NetBSD aparentemente oferece uma opção de montagem especial chamada symperm que, se configurada, faz com que permissões de leitura / execução de link simbólico controlem readlink() e passagem de link.

    
por 14.03.2017 / 21:32
-2
  1. descarta o arquivo de link (depois de garantir que ele não seja usado por nenhum processo)
  2. defina umask de tal forma que o 777-umask = permissões de arquivo necessárias
  3. crie novamente o arquivo de link
por 02.10.2015 / 07:48