Como posso baixar todos os nomes de usuário?

1

Eu tenho acesso ao servidor Linux de uma universidade onde todos os alunos têm contas. Posso recuperar seu nome completo digitando finger username e seus departamentos digitando id username . Todos os nomes de usuários do aluno 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 nota lá algumas pastas www no Linux que tem todos os nomes de usuários.

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)
    
por ilhan 07.05.2014 / 10:30

5 respostas

6

Nos sistemas Linux, há o programa getent , que utiliza as funções get*ent(2) padrão ( getpwent() sendo o único a ser usado aqui). O que você deseja recuperar é o conteúdo do banco de dados passwd (tente man nsswitch.conf para 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 são roladas.

Se você não é um sistema Linux, pode facilitar isso escrevendo algo que elimina o banco de dados do usuário sozinho usando a função getpwent(2) . 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

Depois, você pode ligar para ./test e ver o que você recebe:

$ ./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 usar getwent() tem a grande vantagem de você não precisar fazer suposições sobre como o sistema de login está configurado ( /etc/passwd , LDAP, NIS,…?), mas permite que o sistema recupere o sistema. informações com sua configuração atual.

Editar: pode acontecer que o back-end de armazenamento da base de dados passwd , p. LDAP, não permite enumerar o banco de dados (e, portanto, getpwent() ), mas apenas entregar conjuntos de dados solicitados explicitamente pela chave (por exemplo, nome de login ou UID, portanto getpwuid() ou getpwnam() pode funcionar). Neste caso (e desde que seus nomes de usuários de destino são tão bem nomeados) você ainda pode "enumerar" manualmente com uma modificação do script @ masegaloeh:

#!/bin/bash

for i in {000000..999999}; do 
    getent passwd "e${i}" 2> /dev/null
done

Como fazer isso na ausência de getent com a API do sistema ( getpwnam() , getpwuid() ) é deixado como um exercício para o leitor.

    
por 07.05.2014 / 16:00
5

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 são armazenadas localmente em / etc / passwd, ou se elas estão em LDAP, AD, NIS, ou qualquer serviço que você tenha configurado no 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 que começam com 'e' e são seguidas apenas por dígitos.

Se eu precisasse fazer isso em um sistema Windows, eu instalaria o cygwin e faria como acima :). Na verdade, acabei de testar o getent no Windows / cygwin e ele funciona muito bem (de maneira surpreendente).

    
por 07.05.2014 / 16:43
3

Este script bash faz um loop para você

#!/bin/bash
for i in {205846..205850}; do
    finger e${i}
    id e${i}
done

Você apenas modifica 205846 e 205850 para obter um intervalo diferente

    
por 07.05.2014 / 10:54
1

/ etc / password output é a sua aposta mais segura, pois o dedo imprime duplicatas se alguma parte do nome corresponder.

O seguinte script bash deve fazer o truque, vai sair user $ output do usuário id

l=$(grep "^UID_MIN" /etc/login.defs)

# get max UID limit
#l1=$(grep "^UID_MAX" /etc/login.defs)

# if not set, set manually
l1=4999

# get all users and assign to users array
users=$(awk -F':' -v "min=${l##UID_MIN}" -v "max=${l1##UID_MAX}" '{ if ( $3 >= min && $3 <= max ) print $0}' /etc/passwd | awk 'BEGIN { FS = ":" } ; { print $1 }')

# print the needed info
for user in $users ; do echo -n $user && echo -n " " && id $user ; done

Se você alterar a última linha para

for user in $users ; do echo "INSERT INTO users(name,groups) VALUES('$user', ''id $user'');" ; done

Você receberá instruções de inserção de SQL, por exemplo

INSERT INTO users(name,groups) VALUES('priit', 'uid=1056(priit) gid=1056(priit) grupid=1056(priit)');
    
por 07.05.2014 / 10:55
-3

Você pode obter todas as informações do usuário em / etc / passwd

    
por 07.05.2014 / 10:52

Tags