Por que o sudo não lembra a senha quando executada em um script com fluxos redirecionados?

4

robot :

#!/bin/bash
sudo echo apple
sudo cat << EOF
banana
EOF

prompt de comando :

$ sudo true
[sudo] password for vb:
$ ./robot
apple
banana
$ ./robot > /dev/null
$ ./robot &> /dev/null
[sudo] password for vb:

Por que o sudo (1) pede senha quando o stdout e o stderr são redirecionados?

    
por vbarbarosh 25.04.2011 / 00:56

2 respostas

3

O Sudo lembra a sua senha (sua autenticação) por algum tempo, portanto você não precisa digitar a senha para vários comandos em uma sucessão rápida.

A duração é controlada pela instrução timestamp_timeout no arquivo /etc/sudoers . Leia man sudoers para mais informações.

Mais interessting é a questão como sua autenticação é lembrada. Toda vez que você usar o sudo, o sudo criará um arquivo no diretório /var/run/sudo/username (Ubuntu 10.04). O nome do arquivo é retirado do seu terminal atual (ou tty). Isso significa que o sudo se lembra da sua autenticação por terminal. Se você mudar para outro terminal, o sudo não se lembrará de que você acabou de usar o sudo no terminal anterior.

Demonstração:

Use o sudo:

$ sudo echo foo
[sudo] password for lesmana: 
foo

Veja o arquivo criado em /var/run/sudo/username :

$ sudo ls -l /var/run/sudo/lesmana
total 0
-rw------- 1 root lesmana  0 2011-04-25 16:56 1

Note que este sudo não pediu senha. O arquivo é chamado de 1 porque eu executei o comando sudo a partir de tty (ou pts) número 1. use o comando tty para ver seu nome tty.

$ tty
/dev/pts/1

Agora mude para outro terminal:

$ tty
/dev/pts/2

Use o sudo neste terminal.

$ sudo echo bar
[sudo] password for lesmana: 
bar

Observe que ele pede uma senha.

Veja o arquivo criado em /var/run/sudo/username :

$ sudo ls -l /var/run/sudo/lesmana
total 0
-rw------- 1 root lesmana 0 2011-04-25 16:56 1
-rw------- 1 root lesmana 0 2011-04-25 16:57 2 # <-- new

Agora mude para um console virtual.

$ tty
/dev/tty/1

Use o sudo:

$ sudo echo baz
[sudo] password for lesmana: 
baz

Veja o arquivo criado em /var/run/sudo/username :

$ sudo ls -l /var/run/sudo/lesmana
total 0
-rw------- 1 root lesmana 0 2011-04-25 16:56 1
-rw------- 1 root lesmana 0 2011-04-25 16:57 2
-rw------- 1 root lesmana 0 2011-04-25 16:58 tty1 # <-- new

Agora vamos tentar usar o seu script de shell. Eu usei o mesmo script robótico que no texto da pergunta.

$ ./robot
apple
banana

Nenhum prompt de senha porque eu usei o primeiro terminal no qual o sudo ainda se lembra da minha senha.

Veja o arquivo atualizado em /var/run/sudo/username :

$ sudo ls -l /var/run/sudo/lesmana
total 0
-rw------- 1 root lesmana 0 2011-04-25 17:01 1 # <-- timestamp update
-rw------- 1 root lesmana 0 2011-04-25 16:57 2
-rw------- 1 root lesmana 0 2011-04-25 16:58 tty1

Agora vamos tentar o script com redirecionamento:

$ ./robot > foo
[sudo] password for lesmana:

Observe que o sudo pediu senha.

Verifique /var/run/sudo/username :

$ sudo ls -l /var/run/sudo/lesmana
total 0
-rw------- 1 root lesmana 0 2011-04-25 17:01 1
-rw------- 1 root lesmana 0 2011-04-25 16:57 2
-rw------- 1 root lesmana 0 2011-04-25 16:58 tty1
-rw------- 1 root lesmana 0 2011-04-25 17:02 unknown # <-- new

Veja o arquivo unknown . Por alguma razão, o sudo não é mais capaz de determinar o terminal quando executado em um script com fluxos redirecionados. É por isso que o sudo pede sua senha.

Note que no seu sistema sudo pediu senha somente após redirecionar stdout e stderr. No meu sistema (Ubuntu 10.04) sudo pediu senha quando redirecionei stdout. Eu não tenho ideia de por que existe essa diferença.

Note também que você pode fazer o sudo esquecer sua autenticação imediatamente com o comando sudo -k . Isso só vai esquecer a autenticação do terminal onde o comando foi emitido.

    
por 25.04.2011 / 17:23
2

Ele lê e grava em /dev/tty , que sempre se conecta ao atual tty / pty.

    
por 25.04.2011 / 01:17

Tags