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");
// ...