Cloud with rain
.:G
G:.
0 and 1 serie, black on white
pulled card
myjsp.feelinglinux.com
ver. 1.1.9-4
Hallo, welcome to my world.
Here you can find some stuff about computer science.
<<< Enjoy your visit! >>>
0 and 1 serie, white on black

Scoprire dati sugli utenti (come fa Finger)

        Scritto: Giansante Gabriele, 2001     

Un comando onnipresente sui sistemi Linux e Unix, e' "Finger" che si occupa di fornire dati sugli utenti collegati alla macchina su cui viene eseguito o collegati ad un host remoto.
Pubblicita'

Quel che si vuole spiegare e' come il finger reperisca i dati che visualizza, tralasciando il funzionamento nel caso di richieste remote.
Le fonti principali di informazione sono i file "/etc/passwd" e "/var/run/utmp". Se non si riuscisse a trovare il file utmp con il percorso indicato, si provi a guardare nel file "/usr/include/path.h" nella costante "_PATH_UTMP".
Il formato del file passwd e' semplice da comprendere, mentre quello di utmp no (dati memorizzati in forma binaria).
Comunque, per accedere alle informazioni che contengono, generalmente si includono i file "utmp.h" e "pwd.h" che contengono tutte le funzioni e strutture dati necessarie.

Prima di passare a vedere delle semplici routine che ci permettono di reperire informazioni, e' bene sapere che non tutte le informazioni possibili sono disponibili su tutti i sistemi unix. Ad esempio, il campo ut_addr_v6 (utmp), che dovrebbe contenere in Linux l'indirizzo IP dell'host remoto, non e' presente sui sistemi basati su unix SYS V.
Inoltre, non tutti gli elementi del file "/var/run/utmp" rappresentano degli utenti normali.

La routine seguente utilizza funzioni e strutture definite in utmp.h per cercare dati sugli utenti.

 #include <utmp.h>
 ...
 //Definisco una variabile per contenere i dati degli utenti
 struct utmp* Utente = NULL;
 //Conto gli utenti trovati: mi serve solo per scopi statistici
 int cont=0;
 //Inizializzo il file degli utenti alla prima posizione
 setutent();

 //Ciclo di ricerca degli utenti
 while ((Utente=getutent())!=NULL)
 {
     //Gli utenti sono contrassegnati dal valore 7 (USER_PROCESS). Se non ho un utente,
     //allora ricomincio il ciclo per andare avanti nella ricerca degli utenti
     //nel file UTMP_FILE, altrimenti stampo i dati trovati.
     if (Utente->ut_type!=USER_PROCESS) continue;

     //Se l'elemento rappresenta un utente, ne stampo i dati
     StampaDatiUtente(Utente);

     //Aumenta il numero degli utenti trovati
      cont++;
 }

Sono state usate due funzioni di utmp.h: "setutent()" e "getutent()".
La prima serve ad inizializzare il puntatore corrente nel file "/var/run/utmp" alla posizione del primo utente/processo. Ha come prototipo "void setutent(void)".
La seconda funzione usata e' getutent() con prototipo "struct utmp* getutent(void)". Il suo compito e' di restituire le informazioni presenti alla posizione attuale nel file utmp. Viene inoltre aumentata di uno la posizione del puntatore cosi' da poter avere l'utente successivo nella prossima chiamata alla funzione. Il risultato e' nullo in caso di errore o fine file.
Alla fine del ciclo, cont conterra' il numero complessivo di utenti validi trovati e, per mezzo della procedura "StampaDatiUtente", si avranno tutte le informazioni desiderate.
Non e' mia intenzione scendere nei particolari della realizzazione della funzione "StampaDatiUtente", comunque segue una descrizione dei campi della "struttura utmp" ed un metodo per convertire l'orario in tale struttura da un formato numerico ad uno con testo comprensibile.


Campi Descrizione
short ut_type Contiene il tipo di login (ad es. USER_PROCESS; DEAD_PROCESS;ecc.)
char ut_line[UT_LINESIZE] Indica il nome del dispositivo (sotto "/dev") assegnato all'utente
char ut_user[UT_NAMESIZE] Qui e' presente il nome dell'utente
char ut_host[UT_HOSTSIZE] Nome dell'host per login remoti
struct timeval ut_tv Contiene l'ora ed il giorno in cui l'utente si e' collegato
int32_t ut_addr_v6[4] Indirizzo IP dell'host remoto
Esistono anche altri campi.  

L'orario di collegamento, come si puo' vedere dalla tabella, e' espresso sotto forma di struttura. Un campo di tale struttura e' il tempo misurato in secondi: e' necessario convertire il valore numerico in una stringa leggibile.
Il campo in questione e' "ut_tv.tv_sec". La routine seguente si occupa della conversione voluta.

  #include <time.h>
  ...
  char* ConvertiTempo(time_t t)
  {
     return ctime(&t);
  }
  ...
  printf("%s",ConvertiTempo(Utente->ut_tv.tv_sec));
  ...

La funzione ctime, definita in time.h, e' quella che si occupa effettivamente della conversione.

Rimane da analizzare l'utilizzo di "passwd.h". Si dia uno sguardo alla seguente routine.

  #include <pwd.h>
  ...
  //Variabile contenente le informazioni tratte da /etc/passwd
  struct passwd* PwUtente = NULL;
  //Inizializzazione per la scansione del file /etc/passwd
  setpwent();
  //Cerco, se esiste, l'utente trovato con le funzioni di utmp (potrei 
  //usare anche un'altra variabile char* qualsiasi)
  if ((PwUtente=getpwnam(Utente->ut_user))!=NULL)
  {
    //Stampa di: nome reale; home directory; shell
    printf("%s;%s;%s",PwUtente->pw_gecos,PwUtente->pw_dir,PwUtente->pw_shell
  }
  endpwent();
  ...

I campi pw_gecos, pw_dir e pw_shel, contengono rispettivamente informazioni sul nome reale dell'utente, sulla home directory, sulla shell che viene avviata a seguito del login.
Questa porzione di codice e' stata studiata per essere integrata con quella relativa all'estrapolazione delle informazioni dal file "/var/run/utmp". Per ogni utente trovato nel file utmp, cerco ulteriori dati nel modo mostrato. La funzione getpwnam, con prototipo "struct passwd* getpwnam(char*)", ricerca, all'interno del file /etc/passwd, le informazioni relative all'utente indicato.
Se l'utente non esiste, il risultato e' un puntetore nullo.

Per ulteriori informazioni ed approfondimenti sulle altre funzioni disponibili, consiglio di guardare direttamente i file "utmp.h" e "pwd.h".


Hai trovato utile questo articolo?
Aiutami a condividerlo o metti un "mi piace".
Grazie mille!


Gli strumenti di condivisione (Google+, Facebook) sono visibili in alto a destra solo dopo aver accettato la policy di utilizzo dei cookie per questo sito.
FAQ - Come faccio a cambiare la mia scelta?

 

Strumenti (myjsp.feelinglinux.com)
Gioco: allenamento con la tastiera Strumenti di codifica/decodifica URI (%-encoding) e Base64 Strumenti di calcolo online per IP e Reti
QUIZ GAME
Quiz game

Cerca @myjsp.feelinglinux.com

Pubblicita'