BASH: Registre em / etc / shadow se a senha do usuário estiver bloqueada

7

Objetivo: Verifique em /etc/shadow se a senha do usuário está bloqueada, ou seja, se o primeiro caractere no 2º campo em / etc / shadow, que contém a senha com hash do usuário, é um ponto de exclamação ( '!')

Saída desejada: uma variável chamada $disabled contendo 'Verdadeiro' ou 'Falso'

O nome de usuário está no $uname varable e eu faço algo assim:

disabled='cat /etc/shadow |grep $uname |awk -F\: '{print$2}''
# I now have the password and need one more pipe into the check for the character
# which is where I'm stuck. I would like to do like (in PHP syntax):
| VARIABLE=="!"?"True":"False"'

Este é um fragmento de um script que será executado pelo Cron com permissões de root, para que haja acesso a todas as informações desejadas.

    
por DavDav 01.11.2018 / 13:53

4 respostas

4

Por que não fazer tudo com o awk?

awk -F: '/<username>/ {if(substr($2,1,1) == "!"){print "True"} else {print "False"}}' /etc/shadow
    
por 01.11.2018 / 14:16
26

Não analise o arquivo shadow manualmente

A análise de tais arquivos é frágil se você não levar em conta todas as eventualidades (por exemplo, senhas desabilitadas geralmente são codificadas como um único * ; outras soluções lidam com isso?).

Além disso, a autenticação pode não acontecer através de shadow (mas sim através de NIS ou ldap ou quem sabe o quê). Existem ferramentas padrão que lidam com tudo isso para você. Nesse caso, passwd :

-S, --status Display account status information. The status information consists of 7 fields. The first field is the user's login name. The second field indicates if the user account has a locked password (L), has no password (NP), or has a usable password (P). The third field gives the date of the last password change. The next four fields are the minimum age, maximum age, warning period, and inactivity period for the password. These ages are expressed in days.

Portanto, passwd -S | cut -d ' ' -f 2 produzirá o que você precisa. Um simples se / então irá traduzi-lo para a sua variável desejada:

if [ "$(passwd -S "$USER" | cut -d ' ' -f 2)" = "P" ]
then
    disabled="False"
else
    disabled="True"
fi

O mesmo se aplica ao bloqueio da senha de um usuário; isso é feito preferencialmente através de usermod ( --lock option), não editando shadow manualmente.

    
por 01.11.2018 / 16:43
4
U=$user LC_ALL=C awk -F: < /etc/shadow '
  $1 "" == ENVIRON["U"] {
    user_found = 1
    if ($2 ~ /^!/) {
      print "True"
      exit 0
    } else {
      print "False"
      exit 1
    }
  }
  END {
    if (!user_found) {
      print "False"
      print "User "ENVIRON["U"]" not found" > "/dev/stderr"
      exit 2
    }
  }'

$1 "" == ENVIRON["U"] compara o primeiro campo com ENVIRON["U"] lexicamente. Sem o "" , os campos poderiam ser comparados numericamente se parecessem números (fazendo com que inf correspondesse a INF ou Infinity , por exemplo).

Sem LC_ALL=C , uma vez que algumas implementações de awk usam strcoll() para a comparação == lexical, pode acabar verificando entradas incorretas para nomes de usuários que ordenam o mesmo.

    
por 01.11.2018 / 14:34
0

Um usuário é bloqueado quando o campo passwd é a string *LK* , mas você não pode verificar isso porque /etc/shadow é legível apenas por root por motivos de segurança.

Se as permissões não forem um problema, tente o seguinte:

while IFS=: read USER PW REST; do 
    if [ "$USER" = "$uname" ]; then 
            if [ "$PW" = "*LK*" ]; then 
                    echo "$uname" Locked 
            fi 
    fi 
done < /etc/shadow 

Editar: movido IFS =: para tornar o código mais simples

    
por 01.11.2018 / 14:08