No analizar el shadow
archivo manualmente
El análisis de dichos archivos es frágil si no tiene en cuenta todas las eventualidades (por ejemplo, las contraseñas deshabilitadas a menudo se codifican como un solo *
; ¿Hay otras soluciones que se ocupen de eso?).
Además, es posible que la autenticación no se realice a través de shadow
(pero en su lugar a través de NIS o ldap o quién sabe qué). Existen herramientas estándar que se encargarán de todo esto por usted. En este caso, passwd
:
-S, --status Muestra la información del estado de la cuenta. La información de estado consta de 7 campos. El primer campo es el nombre de inicio de sesión del usuario. El segundo campo indica si la cuenta de usuario tiene una contraseña bloqueada (L), no tiene contraseña (NP) o tiene una contraseña utilizable (P). El tercer campo da la fecha del último cambio de contraseña. Los siguientes cuatro campos son la edad mínima, la edad máxima, el período de advertencia y el período de inactividad de la contraseña. Estas edades se expresan en días.
Así que passwd -S | cut -d ' ' -f 2
producirá lo que necesita. Un simple si/entonces lo traducirá a la variable deseada:
if [ "$(passwd -S "$USER" | cut -d ' ' -f 2)" = "P" ]
then
disabled="False"
else
disabled="True"
fi
Lo mismo se aplica al bloqueo de la contraseña de un usuario; esto se hace preferiblemente a través de usermod
(--lock
opción), sin editar shadow
manualmente.
¿Por qué no hacerlo todo 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"]
compara el primer campo con ENVIRON["U"]
léxicamente. Sin el ""
, los campos podrían terminar comparándose numéricamente si se ven como números (provocando inf
para hacer coincidir con INF
o Infinity
por ejemplo).
Sin LC_ALL=C
, ya que algunos awk
las implementaciones usan strcoll()
para el ==
comparación léxica, podría terminar revisando entradas incorrectas para nombres de usuario que tienen el mismo tipo.