Como o sudo decide se um comando é apenas executável por sudoers com TODOS os direitos?

0

Eu só queria saber por que em um sistema Debian com sudo instalado, um usuário padrão pode executar ls , mas não ifconfig , já que os binários têm os mesmos direitos:

-rwxr-xr-x 1 root root 114032 Jan 26  2013 /bin/ls
-rwxr-xr-x 1 root root 72296 Sep  7  2012 /sbin/ifconfig

Então eu suponho que deve haver algum tipo de banco de dados ou política que diga ao sistema quem tem permissão para executar um comando e quem não está, mas onde eu o encontro? Não pode ser /etc/sudoers , pois nesse arquivo só se define quem é sudoer root e quem não é assim:

%admin  ALL=(ALL)   ALL
john ALL=/usr/sbin/useradd, /usr/sbin/userdel, /usr/bin/passwd

Então john não seria capaz de executar /sbin/ifconfig , mas como o sistema sabe que ele não é permitido?

    
por JohnnyFromBF 04.09.2014 / 21:11

1 resposta

3

sudo não tem nada a ver com essa pequena diferença, a restrição está muito mais próxima do kernel. Você vê, mesmo que todos tenham o direito de executar o programa /sbin/ifconfig , isso não significa que este programa terá permissões suficientes para fazer seu trabalho com privilégios normais de usuário.

Basicamente, com o conjunto de permissões do UNIX, você tem o direito de criar um processo cujo código executável é /sbin/ifconfig 's . E, na verdade, não importa como ls e ifconfig se comportem, os processos são de fato gerados. No entanto, ifconfig sairá prematuramente porque os privilégios fornecidos por meio do usuário em execução não são suficientes. Citando o comentário de Frank Thomas:

[it cannot] grab the network card object

Observação: pode ser possível executar ifconfig --help sem privilégios. Como esta operação não requer o uso da placa de rede, ela não falhará nem exigirá privilégios de root.

Agora, se você quiser saber mais especificamente qual operação foi negada a ifconfig com poucos privilégios, convém dar uma tentativa a strace . Aqui está um exemplo com ls .

strace - trace system calls and signals

O código de erro para permissão negada é 13 ( EACCES ) . Usando strace , posso descobrir quais chamadas de sistema acionaram EACCES :

$ strace ls ~ 2>&1 | grep EACCES
# No output, I can read my home directory just fine.
$ strace ls /root 2>&1 | grep EACCES
openat(AT_FDCWD, "/root", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = -1 EACCES (Permission denied)

Lá, você pode ver que a chamada do sistema openat falhou. De fato, como meu usuário atual, não tenho o direito de ler o diretório /root , portanto o kernel grita em ls quando tenta obter informações sobre /root . Quando ls percebe que openat falhou e devolveu EACCES , apenas me informa:

ls: cannot open directory /root: Permission denied

Agora, cabe ao programa informar ao usuário quando uma chamada do sistema falhar. Por exemplo, em C:

if((rootdir = opendir("/root")) == NULL){
    perror("myprogram");
    exit(1);
}

Com baixos privilégios, isso resultará:

$ ./myprogram
myprogram: Permission denied

Agora, se você executar strace /sbin/ifconfig , poderá descobrir qual chamada de sistema foi negada a ifconfig quando executada como usuário. Aqui está um exemplo de mim tentando diminuir a interface sem fio:

$ strace ifconfig wlan0 down 2>&1 | grep EPERM
ioctl(4, SIOCSIFFLAGS, {ifr_name="wlan0", ???}) = -1 EPERM (Operation not permitted)

Como você pode ver, a chamada do sistema ioctl falhou. Nesse caso, a chamada de erro é EPERM ( 1: operação não permitida ). Os programas ifconfig avisam sobre isso em sua função setifflags :

// ...
if (ioctl(s, SIOCSIFFLAGS, &ifreq) == -1)
    err(EXIT_FAILURE, "SIOCSIFFLAGS");
// ...
    
por 05.09.2014 / 13:08