N'analysez pas le shadow
déposer manuellement
L'analyse de ces fichiers est fragile si vous ne parvenez pas à tenir compte de toutes les éventualités (par exemple, les mots de passe désactivés sont souvent codés comme un seul *
; d'autres solutions traitent-elles cela ?).
De plus, l'authentification peut ne pas se faire via shadow
(mais plutôt via NIS ou ldap ou qui sait quoi). Il existe des outils standard qui s'occuperont de tout cela pour vous. Dans ce cas, passwd
:
-S, --status Afficher les informations sur l'état du compte. Les informations d'état se composent de 7 champs. Le premier champ est le nom de connexion de l'utilisateur. Le deuxième champ indique si le compte utilisateur a un mot de passe verrouillé (L), n'a pas de mot de passe (NP) ou a un mot de passe utilisable (P). Le troisième champ donne la date du dernier changement de mot de passe. Les quatre champs suivants sont l'âge minimum, l'âge maximum, la période d'avertissement et la période d'inactivité du mot de passe. Ces âges sont exprimés en jours.
Alors passwd -S | cut -d ' ' -f 2
donnera ce dont vous avez besoin. Un simple si/alors le traduira dans la variable souhaitée :
if [ "$(passwd -S "$USER" | cut -d ' ' -f 2)" = "P" ]
then
disabled="False"
else
disabled="True"
fi
Il en va de même pour le verrouillage du mot de passe d'un utilisateur ; cela se fait de préférence via usermod
(--lock
option), sans modifier shadow
manuellement.
Pourquoi ne pas tout faire avec 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"]
compare le premier champ avec ENVIRON["U"]
lexicalement. Sans le ""
, les champs pourraient finir par être comparés numériquement s'ils ressemblent à des nombres (causant inf
à comparer avec INF
ou Infinity
par exemple).
Sans LC_ALL=C
, puisque quelques awk
les implémentations utilisent strcoll()
pour le ==
comparaison lexicale, il pourrait finir par vérifier les mauvaises entrées pour les noms d'utilisateur qui trient de la même manière.