Por que não posso criar hardlink para um arquivo que não possuo mesmo que eu possa movê-lo?

1

Exemplo de script:

#!/bin/sh -e 
sudo useradd -m user_a
sudo useradd -m user_b -g user_a
sudo chmod g+w /home/user_a

set +e
sudo su user_a <<EOF
cd
umask 027
>> file_a 
>> file_b
>> file_c
ls -l file_*
EOF

sudo su user_b <<EOF
cd
umask 000
rm -f file_*
ls -l ~user_a/
set -x
mv ~user_a/file_a .
cp ~user_a/file_b .
ln ~user_a/file_c .
set +x
ls -l ~/
EOF
sudo userdel  -r user_b
sudo userdel  -r user_a

Saída:

-rw-r----- 1 user_a user_a 0 Jul 11 12:26 file_a
-rw-r----- 1 user_a user_a 0 Jul 11 12:26 file_b
-rw-r----- 1 user_a user_a 0 Jul 11 12:26 file_c
total 0
-rw-r----- 1 user_a user_a 0 Jul 11 12:26 file_a
-rw-r----- 1 user_a user_a 0 Jul 11 12:26 file_b
-rw-r----- 1 user_a user_a 0 Jul 11 12:26 file_c
+ mv /home/user_a/file_a .
+ cp /home/user_a/file_b .
+ ln /home/user_a/file_c .
ln: failed to create hard link ‘./file_c’ => ‘/home/user_a/file_c’: Operation not permitted
+ set +x
total 0
-rw-r----- 1 user_a user_a 0 Jul 11 12:26 file_a
-rw-r----- 1 user_b user_a 0 Jul 11 12:26 file_b
userdel: user_b mail spool (/var/mail/user_b) not found
userdel: user_a mail spool (/var/mail/user_a) not found
    
por PSkocik 11.07.2017 / 12:27

3 respostas

5

Qual sistema você está executando? No Linux, esse comportamento é configurável, através de /proc/sys/fs/protected_hardlinks (ou sysctl fs.protected_hardlinks ).

O comportamento é descrito em proc(5) :

/proc/sys/fs/protected_hardlinks (since Linux 3.6)
When the value in this file is 0, no restrictions are placed on the creation of hard links (i.e., this is the historical behavior before Linux 3.6). When the value in this file is 1, a hard link can be created to a target file only if one of the following conditions is true:

  • The calling process has the CAP_FOWNER capability ...
  • The filesystem UID of the process creating the link matches the owner (UID) of the target file ...
  • All of the following conditions are true:
    • the target is a regular file;
    • the target file does not have its set-user-ID mode bit enabled;
    • the target file does not have both its set-group-ID and group-executable mode bits enabled; and
    • the caller has permission to read and write the target file (either via the file's permissions mask or because it has suitable capabilities).

E a justificativa para isso deve ficar clara:

The default value in this file is 0. Setting the value to 1 prevents a longstanding class of security issues caused by hard-link-based time-of-check, time-of-use races, most commonly seen in world-writable directories such as /tmp.

Nos sistemas Debian, protected_hardlinks e protected_symlinks padrão são iguais a um, então fazer um link sem acesso de gravação ao arquivo não funciona:

$ ls -ld . ./foo
drwxrwxr-x 2 root itvirta 4096 Jul 11 16:43 ./
-rw-r--r-- 1 root root       4 Jul 11 16:43 ./foo
$ mv foo bar
$ ln bar bar2
ln: failed to create hard link 'bar2' => 'bar': Operation not permitted

A definição de protected_hardlinks para zero elimina a restrição:

# echo 0 >  /proc/sys/fs/protected_hardlinks 
$ ln bar bar2
$ ls -l bar bar2
-rw-r--r-- 2 root root 4 Jul 11 16:43 bar
-rw-r--r-- 2 root root 4 Jul 11 16:43 bar2
    
por 11.07.2017 / 15:53
-1

Normalmente, cada arquivo tem uma entrada de diretório (há exceções, mas não há necessidade de entrar nisso).

A entrada de diretório é essencialmente um par nome + número ; o nome do arquivo e um número chamado i-number. Este é um índice em algo chamado i-list , que contém todos os detalhes reais sobre cada arquivo, em estruturas chamadas i-nodes .

O nó i contém, entre outras coisas, detalhes de quem possui o arquivo. É efetivamente 'propriedade' do proprietário do arquivo. Um dos campos nele é um contagem de uso , que normalmente é definido como 1.

Quando um link físico é criado, é apenas outro nome + par de números, indistinguível do primeiro. Nesse ponto, a contagem de uso é aumentada em 1; Quando o link físico (ou a entrada de diretório original, porque ambos têm status igual) é removido, a contagem de uso é diminuída por 1. Quando ele se torna zero, o arquivo desaparece. Você pode ver que fazer um link físico significaria ter que ser capaz de alterar o i-node quando você não era o dono dele.

Este foi um problema por alguns anos no UNIX, e foi uma das razões pelas quais o link simbólico (ou symlink , às vezes chamado de soft link ) foi introduzido . É um par name + name , basicamente fornecendo apenas um alias para o arquivo original. Nada é alterado no nó i; é apenas um redirecionamento. A desvantagem é que o arquivo original pode ser excluído sem que o symlink desapareça, e ele acaba apontando para um arquivo inexistente.

    
por 11.07.2017 / 13:11
-1

De man 2 link : "... ambos os nomes se referem ao mesmo arquivo (e assim ter as mesmas permissões e propriedade) "

Mesmo que você tenha permissão para ler / copiar / mover o arquivo, não é possível criar dois links para o mesmo arquivo com permissões diferentes ou propriedade, como o modo , uid e gid são armazenados no inode para o qual você está criando links de dois diretórios diferentes, não na própria entrada de diretório.

Considere:

$ touch file_a
$ touch file_b
$ ln file_a file_A
$ ls -iln
total 0
1310731 -rw-rw-r-- 2 1000 1000 0 Jul 11 08:45 file_a
1310731 -rw-rw-r-- 2 1000 1000 0 Jul 11 08:45 file_A
1320710 -rw-rw-r-- 1 1000 1000 0 Jul 11 08:45 file_b

======= ===================================== ======
^       ^                                     ^
|       |                                     \-- names, stored in directory
|       \-- file metadata, stored in inode
\-- inode number, stored in directory and pointing to inode

Neste exemplo, file_a e file_A têm o mesmo número de inode, então necessariamente tem todos os mesmos atributos armazenados em um inode.

    
por 11.07.2017 / 12:57