martes, 21 de junio de 2011

Como encontrar los uid duplicados en /etc/passwd

En cajas en las que continuamente se agregan y eliminan usuarios, no es raro encontrar algunos que ya sea a propósito o por accidente comparten el uid.(A veces son por completo entradas duplicadas)
A fin de poder tomar las decisiones necesarias (ya sea desde cambiar el uid de alguno de los usuarios, hasta la eliminación de aquellos duplicados) es buena práctica el examinar las líneas del archivo /etc/passwd.

A manera de ejemplo he creado dos usuarios con el mismo uid, en mi caja.
Ambos usuarios dummyuser y lameruser aunque con diferentes usernames comparten el mismo uid, por lo que a fines practicos se trata del mismo usuario.

Ahora, para llegar a encontrar las líneas duplicadas necesitamos:
a) Registrar cada uid diferente que se presente en el archivo /etc/passwd

b) En caso de que uid ya este registrado imprimirlo
c) Sería buena idea ordenar el listado por uid, para que las entradas con el mismo uid  se mantengan juntas
d) Agregar el nombre del equipo al listado

Interesante requerimiento ¿no es así? ¿Complicado? Para nada.
Para los puntos a-c usaremos la herramienta awk, que nos permite usar un archivo de entrada para su procesamiento usando su propio lenguaje de ordenes: AWK.
El archivo de usuarios y contraseñas /etc/passwd esta separado por el caracter (:) por lo que el primer parametro de nuestro comando awk sería: -F:
Para registrar cada uno de los uid creamos un arreglo, lo ideal es hacerlo antes de comenzar a leer cada linea del archivo /etc/passwd. Es decir al principio (BEGIN): BEGIN{a[NULL]=0;}
Luego, a fin de verificar que cada uid(el tercer campo por cierto) no se haya usado antes: if($3 in a )
Si el uid no se ha presentado antes será almacenado de lo contrario se imprimirá la línea.
Ahora para ordenarlo, con respecto al campo 3, evaluándolo de forma númerica y teniendo como delimitador el caracter: usamos el comando: sort -t: -k3 -n
Por ultimo agregamos el nombre del equipo a la salida con el comando sed.
¿Cómo queda todo junto?
¡En una sola línea, claro esta!
awk -F: 'BEGIN{a[NULL]=0;}{if($3 in a){print a[$3];print ;}else a[$3]=$0;} ' /etc/passwd | sort -t: -k3 -n | uniq | sed -e 's/^/'$(hostname)':/g'

Nuestro comando trabajando:

Como puede apreciarse.... funciona bastante bien.

0 comentarios:

Publicar un comentario