UTMP(5)

NOME
utmp, wtmp - registri dei login

SINTASSI
#include <utmp.h>

DESCRIZIONE
Il file utmp permette di scoprire informazioni su chi sta usando attualmente il sistema. Ci possono essere più utenti che stanno usando il sistema di quelli riportati, poiché non tutti i programmi usano registrazioni utmp.

Attenzione: utmp non deve essere scrivibile, poiché molti programmi di sistema dipendono (stupidamente) dalla sua integrità. Si rischia che vengano contraffatti i file di log del sistema e che il sistema sia modificato se si lascia utmp scrivibile a qualsiasi utente.

Il file è una sequenza di voci con la seguente struttura dichiarata nel file di include (si noti che questa è solo una delle numerose definizioni in giro; i dettagli dipendono dalla versione di libc:

#define UT_UNKNOWN      0
#define RUN_LVL         1
#define BOOT_TIME       2
#define NEW_TIME        3
#define OLD_TIME        4
#define INIT_PROCESS    5
#define LOGIN_PROCESS   6
#define USER_PROCESS    7
#define DEAD_PROCESS    8
#define ACCOUNTING      9
#define UT_LINESIZE     12
#define UT_NAMESIZE     32
#define UT_HOSTSIZE     256
struct exit_status {
  short int e_termination;    /* process termination status */
  short int e_exit;           /* process exit status */
};
struct utmp {
  short ut_type;              /* type of login */
  pid_t ut_pid;               /* PID of login process */
  char ut_line[UT_LINESIZE];  /* device name of tty - "/dev/" */
  char ut_id[4];              /* init id or abbrev. ttyname */
  char ut_user[UT_NAMESIZE];  /* user name */
  char ut_host[UT_HOSTSIZE];  /* hostname for remote login */
  struct exit_status ut_exit; /* The exit status of a process
                                 marked as DEAD_PROCESS */

  /* The ut_session and ut_tv fields must be the same size when
     compiled 32- and 64-bit.  This allows data files and shared
     memory to be shared between 32- and 64-bit applications */
#if __WORDSIZE == 64 && defined __WORDSIZE_COMPAT32
  int32_t ut_session;         /* Session ID, used for windowing */
  struct {
    int32_t tv_sec;           /* Seconds */
    int32_t tv_usec;          /* Microseconds */
  } ut_tv;                    /* Time entry was made */
#else
   long int ut_session;        /* Session ID, used for windowing */
   struct timeval ut_tv;       /* Time entry was made */
#endif
  int32_t ut_addr_v6[4];       /* IP address of remote host */
  char __unused[20];           /* Reserved for future use */
};
/* Backwards compatibility hacks.  */
#define ut_name ut_user
#ifndef _NO_UT_TIME
#define ut_time ut_tv.tv_sec
#endif
#define ut_xtime ut_tv.tv_sec
#define ut_addr ut_addr_v6[0]

Questa struttura dà il nome del file speciale associato con il terminale utente, il nome di login dell'utente, e l'ora di login nel formato di time(2). I campi stringa sono terminati con '\0' se sono più corti della dimensione del campo.

Le prime voci del file sono il risultato di init(8) quando processa inittab(5). Prima che una voce sia eseguita, però, init(8) pulisce il file utmp assegnando il valore di DEAD_PROCESS a ut_type, pulendo ut_user, ut_host e ut_time con byte nulli per ogni registrazione il cui ut_type non sia DEAD_PROCESS o RUN_LVL, e quelle per cui non esistono processi con PID ut_pid. Se non si trovano registrazioni vuote con la ut_id necessaria, init ne crea una nuova. Poi assegna ut_id dal file inittab, assegna i valori correnti a ut_pid e fIut_time e assegna INIT_PROCESS a ut_type.

getty(8) localizza le voci tramite il PID, cambia ut_type perché contenga LOGIN_PROCESS, aggiorna ut_time, assegna ut_line e aspetta che venga stabilita una connessione. login(8), dopo aver autenticato un utente, cambia ut_type perché valga USER_PROCESS, aggiorna ut_time e imposta ut_host e ut_addr. In base al comportamento di getty(8) e login(8), le registrazioni possono essere indirizzate da ut_line invece del metodo preferibile, ut_pid.

Quando init(8) scopre che un processo è terminato, ricerca la sua voce utmp tramite ut_pid, assegna il valore DEAD_PROCESS a ut_type e pulisce ut_user, ut_host e ut_time, assegnandogli dei byte nulli.

xterm(1) e altri emulatori terminale creano direttamente un record USER_PROCESS e generano il ut_id usando le ultime due lettere di /dev/ttyp%c o usando p%d per /dev/pts/%d. Se essi trovano un DEAD_PROCESS per questo ID, lo riciclano, altrimenti creano una nuova voce. Se possono, lo marcheranno come DEAD_PROCESS all'uscita e si consiglia che azzerino anche ut_line, ut_time, ut_user, e ut_host.

telnetd(8) imposta una voce LOGIN_PROCESS e lascia il resto a login(8) come al solito. Dopo che la sessione telnet termina telnetd(8) pulisce utmp nel modo descritto.

Il file wtmp registra tutti i login e logout. Il suo formato è esattamente come utmp tranne che un nome utente nullo indica un logout sul terminale associato. Inoltre il nome terminale ~ con nome utente shutdown o reboot indica uno spegnimento o riavvio del sistema e la coppia di nomi di terminale |/} fa il log della vecchia/nuova ora di sistema quando date(1) la cambia. wtmp è mantenuto da login(1), init(1), e da alcune versioni di getty(1). Il file non è creato da nessuno di questi programmi, quindi se esso viene rimosso la registrazione è disattivata.

Notare che su piattaforme biarch, come sistemi che possono far girare sia applicazioni 32-bit che 64-bit (x86-64, ppc64, s390x, etc.), ut_tv è della stessa dimensione in modo 32-bit e in modo 64-bit. Lo stesso vale per ut_session e ut_time se essi sono presenti. Ciò permette a file dati e memoria condivisa di essere condivisi tra applicazioni 32-bit e applicazioni 64-bit. Poiché ut_tv potrebbe non essere lo stesso di struct timeval, allora, invece della chiamata:

    gettimeofday((struct timeval *) &ut.ut_tv, NULL);
si raccomanda il seguente metodo di impostare il campo:

    struct utmp ut;
    struct timeval tv;
    gettimeofday(&tv, NULL);
    ut.ut_tv.tv_sec = tv.tv_sec;
    ut.ut_tv.tv_usec = tv.tv_usec;

FILE
/var/run/utmp
/var/log/wtmp

CONFORME A
Le voci Linux utmp non sono conformi nè a v7/BSD nè a SYSV; esse sono un mix delle due. v7/BSD ha meno campi; più importante, esso non ha ut_type, e ciò fa sì che programmi nativi v7/BSD visualizzino (per esempio) voci morte e login. Inoltre, non c'è alcun file di configurazione che alloca slot alle sessioni. BSD fa questo perché non ha campi ut_id. In Linux (come in SYSV), il campo ut_id di un record non cambierà mai una volta che è stato impostato, e ciò riserva questo spazio senza bisogno di un file di configurazione. Cancellare ut_id può dar luogo a delle race condition che portano a voci utmp corrotte e a potenziali buchi di sicurezza. Cancellare i campi menzionati sopra riempiendoli con byte nulli non è richiesto dalla semantica SYSV, ma permette di eseguire molti programmi che assumono la semantica BSD e che non modificano utmp. Linux usa le convenzioni BSD per i contenuti di linea, come documentato in precedenza.

System V usa solo il campo ``typè' per marcare le righe e registra messaggi informativi come, per esempio, "new time" nel campo line. UT_UNKNOWN sembra essere una invenzione di Linux. System V non ha campi ut_host o ut_addr.

A differenza di vari altri sistemi, dove la registrazione in utmp può essere disabilitata cancellando il file, utmp deve sempre esistere in Linux. Se si vuole disabilitare who(1) basta togliere il permesso di lettura globale al file utmp.

Si noti che lo struct di utmp è cambiato tra libc5 e libc6. Di conseguenza, un programma che usi il vecchio struct di libc5 altera /var/run/utmp e/o /var/log/wtmp.

NOTE
Il formato del file dipende dalla macchina, perciò si raccomanda di modificarlo solo macchine della stessa architettura di quella su cui il file è stato creato.

Si noti che su piattaforme che possono eseguire applicazioni sia a 32-bit che a 64-bit (x86-64, ppc64, s390x, etc.), le dimensioni dei campi di una struttura utmp devono essere le stesse in modalità 32-bit e in modalità 64-bit. Ciò è raggiunto cambiando il tipo di ut_session in int32_t, e quello di ut_tv in una struttura con due campi int32_t tv_sec e tv_usec. (Quindi, per riempirlo, mettere l'ora in una reale struct timeval, quindi copiare i due campi in ut_tv.)

BACHI
Questa pagina di manuale si basa su quella di libc5, ora le cose potrebbero funzionare diversamente.

VEDERE ANCHE
ac(1), date(1), last(1), login(1), who(1), getutent(3), updwtmp(3), init(8)