Non analizzare shadow
file manualmente
L'analisi di tali file è fragile se non si tiene conto di tutte le eventualità (ad esempio, le password disabilitate sono spesso codificate come un singolo *
; altre soluzioni si occupano di questo?).
Inoltre, l'autenticazione potrebbe non avvenire tramite shadow
(ma invece tramite NIS o ldap o chissà cosa). Ci sono strumenti standard che si occuperanno di tutto questo per te. In questo caso, passwd
:
-S, --status Visualizza le informazioni sullo stato dell'account. Le informazioni sullo stato sono composte da 7 campi. Il primo campo è il nome di accesso dell'utente. Il secondo campo indica se l'account utente ha una password bloccata (L), non ha password (NP) o ha una password utilizzabile (P). Il terzo campo fornisce la data dell'ultima modifica della password. I successivi quattro campi sono l'età minima, l'età massima, il periodo di avviso e il periodo di inattività per la password. Queste età sono espresse in giorni.
Quindi passwd -S | cut -d ' ' -f 2
produrrà ciò di cui hai bisogno. Un semplice if/then lo tradurrà nella variabile desiderata:
if [ "$(passwd -S "$USER" | cut -d ' ' -f 2)" = "P" ]
then
disabled="False"
else
disabled="True"
fi
Lo stesso vale per bloccare la password di un utente; questo è preferibilmente fatto attraverso usermod
(--lock
option), senza modificare shadow
manualmente.
Perché non fare tutto con awk?
awk -F: '/<username>/ {if(substr($2,1,1) == "!"){print "True"} else {print "False"}}' /etc/shadow
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"]
confronta il primo campo con ENVIRON["U"]
lessicalmente. Senza il ""
, i campi potrebbero finire per essere confrontati numericamente se sembrano numeri (causando inf
da confrontare con INF
o Infinity
per esempio).
Senza LC_ALL=C
, poiché alcuni awk
le implementazioni usano strcoll()
per il ==
confronto lessicale, potrebbe finire per controllare le voci errate per i nomi utente che ordinano lo stesso.