Tenho acesso ao servidor Linux de uma universidade onde todos os alunos possuem contas. Posso recuperar o nome completo digitando finger username
, e os departamentos digitando id username
. Todos os nomes de usuário dos alunos são consecutivos. Por exemplo:
e205846
e205847
e205848
e205849
e205850
...
É possível escrever algum tipo de script e recuperar todas as informações para algum tipo de banco de dados? Ou já existe uma ferramenta disponível para isso? Além disso, como observação lateral, existem algumas pastas www no Linux que possuem todos os nomes de usuário.
Aqui está um exemplo
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)
Responder1
Em sistemas Linux existe o getent
programa, que utiliza as funções padrão get*ent(2)
( getpwent()
sendo a que usaremos aqui). O que você deseja recuperar é o conteúdo do passwd
banco de dados (tente man nsswitch.conf
entender melhor):
$ 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
...
Fica muito mais interessante depois que as contas padrão do sistema passam.
Se você não possui um sistema Linux, pode fazer isso com bastante facilidade escrevendo algo que despeja o banco de dados do usuário por conta própria usando a getpwent(2)
função. Um exemplo em C seria algo assim:
#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;
}
Coloque isso em um arquivo test.c
e construa-o com
$ gcc -o test test.c
Então você pode ligar ./test
e ver o que você ganha:
$ ./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 acima, ficará mais interessante mais tarde.
A abordagem de uso getwent()
tem a grande vantagem de que você não precisa fazer nenhuma suposição sobre como o sistema de login está configurado ( /etc/passwd
, LDAP, NIS, …?), mas apenas deixar o sistema recuperar as informações com sua configuração real.
Editar:Pode acontecer que o passwd
backend de armazenamento do banco de dados, por exemplo, LDAP, não permita enumerar o banco de dados (e, portanto getpwent()
), mas apenas distribuir conjuntos de dados explicitamente solicitados por chave (por exemplo, nome de login ou UID, então getpwuid()
ou getpwnam()
pode funcionar). Nesse caso (e como seus nomes de usuário alvo são nomeados de maneira tão organizada), você ainda pode "enumerar" manualmente com uma modificação do script de @masegaloeh:
#!/bin/bash
for i in {000000..999999}; do
getent passwd "e${i}" 2> /dev/null
done
Como fazer isso na ausência getent
da API do sistema ( getpwnam()
, getpwuid()
) fica como exercício para o leitor.
Responder2
getent é de fato o caminho certo para acessar qualquer banco de dados através da troca de nome em um sistema Unix/Linux, então não importa se as contas estão armazenadas localmente em /etc/passwd, ou se estão em LDAP, AD, NIS ou qualquer serviço que você configurou em nsswitch.conf.
Então eu faria:
getent passwd | awk -F: '$1 ~"^e[0-9]*$" {print $5}'
Isso imprimirá os nomes de usuário completos de todas as contas começando com 'e' e seguidos apenas por dígitos.
Se eu precisasse fazer isso em um sistema Windows, instalaria o cygwin e faria como acima :). Na verdade, acabei de testar o getent no Windows/cygwin e funciona muito bem (surpreendentemente).
Responder3
Este script bash fará loop para você
#!/bin/bash
for i in {205846..205850}; do
finger e${i}
id e${i}
done
Você acabou de modificar 205846 e 205850 para obter um intervalo diferente
Responder4
Você pode obter todas as informações do usuário em /etc/passwd