Por que não fazer tudo com o awk?
awk -F: '/<username>/ {if(substr($2,1,1) == "!"){print "True"} else {print "False"}}' /etc/shadow
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.
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.
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.
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
Tags bash users linux regular-expression