Tengo acceso al servidor Linux de una universidad donde todos los estudiantes tienen cuentas. Puedo recuperar su nombre completo escribiendo finger username
y sus departamentos escribiendo id username
. Todos los nombres de usuario de los estudiantes son consecutivos. Por ejemplo:
e205846
e205847
e205848
e205849
e205850
...
¿Es posible para mí escribir algún tipo de script y recuperar toda la información en algún tipo de base de datos? ¿O ya existe una herramienta disponible para eso? Además, como nota al margen, hay algunas carpetas www en Linux que tienen todos los nombres de usuario.
Aquí hay un ejemplo
e147290@beluga:~$ finger e204158
Login: e204158 Name: april oneil
Directory: /home705/e204158 Shell: /bin/bash
Never logged in.
No mail.
No Plan.
e147290@beluga:~$ id e204159
uid=53653(e204158) gid=5621(ce_bs) groups=5621(ce_bs)
Respuesta1
En los sistemas Linux existe el getent
programa que utiliza las get*ent(2)
funciones estándar ( getpwent()
siendo el que se utiliza aquí). Lo que desea recuperar es el contenido de la passwd
base de datos (intente man nsswitch.conf
comprenderlo mejor):
$ getent passwd
root:x:0:0:root:/root:/bin/bash
sashroot:x:0:0:root:/root:/bin/sash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:65004:65534:sync:/bin:/bin/sync
games:x:65005:65060:games:/usr/games:/bin/sh
man:x:65006:65012:man:/var/cache/man:/bin/sh
lp:x:65007:7:lp:/var/spool/lpd:/bin/sh
mail:x:65008:65008:mail:/var/mail:/bin/sh
...
Se vuelve mucho más interesante después de que pasan las cuentas estándar del sistema.
Si no tiene un sistema Linux, puede conseguirlo bastante fácilmente escribiendo algo que descargue la base de datos del usuario por sí solo mediante el uso de la getpwent(2)
función. Un ejemplo en C sería algo como esto:
#include <sys/types.h>
#include <pwd.h>
#include <stdio.h>
int
main(void)
{
struct passwd *pwd;
while ((pwd = getpwent()) != NULL) {
printf("user = `%s', uid = %d, gid = %d, name = `%s'\n",
pwd->pw_name, pwd->pw_uid, pwd->pw_gid, pwd->pw_gecos);
}
return 0;
}
Pon esto en un archivo test.c
y constrúyelo con
$ gcc -o test test.c
Entonces puedes llamar ./test
y ver lo que obtienes:
$ ./test
user = `root', uid = 0, gid = 0, name = `root'
user = `sashroot', uid = 0, gid = 0, name = `root'
user = `daemon', uid = 1, gid = 1, name = `daemon'
user = `bin', uid = 2, gid = 2, name = `bin'
user = `sys', uid = 3, gid = 3, name = `sys'
user = `sync', uid = 65004, gid = 65534, name = `sync'
user = `games', uid = 65005, gid = 65060, name = `games'
user = `man', uid = 65006, gid = 65012, name = `man'
user = `lp', uid = 65007, gid = 7, name = `lp'
user = `mail', uid = 65008, gid = 65008, name = `mail'
...
Como se indicó anteriormente, se volverá más interesante más adelante.
El enfoque de uso getwent()
tiene la gran ventaja de que no es necesario hacer suposiciones sobre cómo está configurado el sistema de inicio de sesión ( /etc/passwd
¿LDAP, NIS,…?), sino simplemente dejar que el sistema recupere la información con su configuración real.
Editar:Puede suceder que el passwd
backend de almacenamiento de la base de datos, por ejemplo, LDAP, no permita enumerar la base de datos (y por lo tanto getpwent()
), sino que solo le entregue conjuntos de datos solicitados explícitamente por clave (por ejemplo, nombre de inicio de sesión o UID, por lo que getpwuid()
podría getpwnam()
funcionar). En este caso (y dado que los nombres de usuario de destino tienen nombres tan claros), aún podrías "enumerar" manualmente con una modificación del script de @masegaloeh:
#!/bin/bash
for i in {000000..999999}; do
getent passwd "e${i}" 2> /dev/null
done
Cómo hacer esto en ausencia de getent
la API del sistema ( getpwnam()
, getpwuid()
) se deja como ejercicio para el lector.
Respuesta2
De hecho, getent es la forma correcta de acceder a cualquier base de datos a través del cambio de nombre en un sistema Unix/Linux, por lo que no importa si las cuentas están almacenadas localmente en /etc/passwd, o si están en LDAP, AD, NIS o cualquier servicio que haya configurado en nsswitch.conf.
Entonces yo haría:
getent passwd | awk -F: '$1 ~"^e[0-9]*$" {print $5}'
Esto imprimirá los nombres de usuario completos de todas las cuentas que comiencen con 'e' y seguidas solo de dígitos.
Si necesitara hacer esto en un sistema Windows, instalaría cygwin y luego lo haría como se indica arriba :). De hecho, acabo de probar getent en Windows/cygwin y funciona muy bien (algo sorprendente).
Respuesta3
Este script bash hará un bucle por ti
#!/bin/bash
for i in {205846..205850}; do
finger e${i}
id e${i}
done
Simplemente modifica 205846 y 205850 para obtener un rango diferente
Respuesta4
Puede obtener toda la información del usuario en /etc/passwd