utmp(5) File Formats Manual utmp(5)

utmp, wtmp - registro de sesiones

#include <utmp.h>

El archivo utmp nos permite obtener información acerca de qué usuarios están usando el sistema actualmente. No todas las aplicaciones usan el registro de utmp por lo que puede haber usuarios que no figuren.

Atención: utmp no debe ser modificable ya que muchos programas del sistema dependen (tontamente) de su integridad. Corre el riesgo de tener registros del sistema ("logs" en inglés) incorrectos e incluso modificaciones indeseadas de archivos del sistema si deja que cualquiera pueda escribir en utmp.

El archivo es una secuencia de estructuras de utmp, declaradas a continuación en el archivo <utmp.h> (esto es sólo una posible definición ya que los detalles dependen de la versión de libc):


/* Values for ut_type field, below */
#define EMPTY         0 /* Record does not contain valid info

(formerly known as UT_UNKNOWN on Linux) */ #define RUN_LVL 1 /* Change in system run-level (see
init(1)) */ #define BOOT_TIME 2 /* Time of system boot (in ut_tv) */ #define NEW_TIME 3 /* Time after system clock change
(in ut_tv) */ #define OLD_TIME 4 /* Time before system clock change
(in ut_tv) */ #define INIT_PROCESS 5 /* Process spawned by init(1) */ #define LOGIN_PROCESS 6 /* Session leader process for user login */ #define USER_PROCESS 7 /* Normal process */ #define DEAD_PROCESS 8 /* Terminated process */ #define ACCOUNTING 9 /* Not implemented */ #define UT_LINESIZE 32 #define UT_NAMESIZE 32 #define UT_HOSTSIZE 256 struct exit_status { /* Type for ut_exit, below */
short e_termination; /* Process termination status */
short e_exit; /* Process exit status */ }; struct utmp {
short ut_type; /* Type of record */
pid_t ut_pid; /* PID of login process */
char ut_line[UT_LINESIZE]; /* Device name of tty - "/dev/" */
char ut_id[4]; /* Terminal name suffix,
or inittab(5) ID */
char ut_user[UT_NAMESIZE]; /* Username */
char ut_host[UT_HOSTSIZE]; /* Hostname for remote login, or
kernel version for run-level
messages */
struct exit_status ut_exit; /* Exit status of a process
marked as DEAD_PROCESS; not
used by Linux init(1) */
/* 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 (getsid(2)),
used for windowing */
struct {
int32_t tv_sec; /* Seconds */
int32_t tv_usec; /* Microseconds */
} ut_tv; /* Time entry was made */ #else
long ut_session; /* Session ID */
struct timeval ut_tv; /* Time entry was made */ #endif
int32_t ut_addr_v6[4]; /* Internet address of remote
host; IPv4 address uses
just ut_addr_v6[0] */
char __unused[20]; /* Reserved for future use */ }; /* Backward 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]

Esta estructura nos da el nombre del fichero especial asociado con el terminal del usuario, el nombre del usuario y el momento de inicio de sesión en el formato definido en time(2). Los campos del tipo cadena terminan con bytes nulos ( ('\0') si no completan la totalidad del campo.

Las primeras entradas que se crean siempre proceden del procesamiento de inittab(5) por parte de init(1). Sin embargo, antes de que se procese una entrada, init(1) limpia utmp asignando a ut_type el valor DEAD_PROCESS, limpiando los campos ut_user, ut_host y ut_time con caracteres nulos para cada registro cuyo campo ut_type no sea DEAD_PROCESS ni RUN_LVL y donde no exista ningún proceso con PID ut_pid. Si no se puede encontrar ningún registro vacío con el ut_id que se necesita, init(1) crea uno nuevo. Asigna un valor a ut_id a partir del inittab, a ut_pid y a ut_time a partir de los valores actuales y asigna a ut_type el valor INIT_PROCESS.

mingetty(8) (o agetty(8)) busca la entrada por el PID, cambia el valor de ut_type a LOGIN_PROCESS, cambia ut_time, asigna un valor a ut_line y espera a que se establezca la conexión. Una vez que se produjo la autentifiación del usuario, login(1), cambia el valor de ut_type a USER_PROCESS, cambia ut_time y asigna un valor a ut_host y a ut_addr. Dependiendo de mingetty(8) (o agetty(8)) y login(8), los registros se pueden buscar por ut_line en lugar de por ut_pid, como sería preferible.

Cuando init(1) detecta que un proceso ha terminado, busca su entrada utmp mediante ut_pid, asigna a ut_type el valor DEAD_PROCESS y limpia ut_user, ut_host y ut_time con bytes nulos.

xterm(1) y otros emuladores de terminal crean directamente un registro USER_PROCESS y generan ut_id con los caracteres siguientes de la cadena /dev/[pt]ty. Si encuentran un DEAD_PROCESS para este ID, lo reutilizan; en caso contrario, crean una nueva entrada. Si pueden, las marcarán como DEAD_PROCESS al terminar y se aconseja que también rellenen con bytes nulos los campos ut_line, ut_time, ut_user y ut_host.

telnetd(8) establece una entrada LOGIN_PROCESS y deja el resto a login(1), como es habitual. Después de que termine la sesión de telnet, telnetd(8) limpia utmp de la forma descrita.

El archivo wtmp registra todos los inicios y finales de sesión. Su formato es como el de utmp salvo que un nombre nulo de usuario indica el fin de sesión en la terminal asociada. Además, el nombre de terminal ~ con nombre de usuario shutdown o reboot indica un cierre (shutdown) o reinicio del sistema y el par de nombres de terminal |/} registra la fecha antigua/nueva del sistema cuando la cambia date(1). wtmp se gestiona a través de login(1), init(1) y algunas versiones de getty(8) (por ejemplo: mingetty(8) o agetty(8)) Ninguno de estos programas crea el archivo, por lo que si se borra se desactiva el mantenimiento de los registros.

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

POSIX.1 no define la estructura de utmp, en cambio la define para utmpx (como parte de la extensión XSI) detallando especificaciones para los campos ut_type, ut_pid, ut_line, ut_id, ut_user y ut_tv. Tampoco define la longitud de los campos ut_line y ut_user.

Linux define que la estructura de utmpx debe ser idéntica a la de utmp.

Linux.

Las entradas de utmp no son conformes nia v7/BSD ni a System V sino que son una mezcla de ambos.

v7/BSD tiene un menor número de campo; principalmente no tiene ut_type lo que provoca que las aplicaciones nativas de este sistema muestren (entre otras cosas) algunas sesiones muertas. Es más, no dispone de un archivos para configurar la reserva de entradas para sesiones al no disponer de campos ut_id.

En Linux (igual que en System V), el campo ut_id de un registro nunca cambiará una vez que se le haya asignado un valor, lo que reserva esa entrada sin necesidad de un fichero de configuración. Limpiar el campo ut_id puede producir condiciones de carrera que den lugar a entradas utmp corruptas y a potenciales problemas de seguridad. La semántica de System V no necesita la limpieza de los campos mencionados anteriormente rellenándolos con bytes nulos, pero esto permite ejecutar muchos programas que suponen una semántica BSD y que no modifican utmp. Linux usa las convenciones de BSD para los contenidos de las líneas, tal y como se ha descrito anteriormente.

System V no tiene los campos ut_host ni ut_addr_v6.

A diferencia de otros sistemas, donde el registro de información en utmp se puede deshabilitar borrando el fichero, en Linux este fichero siempre debe existir. Si quiere deshabilitar who(1) elimine el permiso de lectura de utmp de los permisos correspondientes a "otros".

El formato del fichero depende de la arquitectura de la máquina, por lo que se recomienda que sea procesado únicamente en la arquitectura en que fue creado.

Tenga en cuenta que en plataformas biarch (aquellas que pueden ejecutar aplicaciones de 32 y de 64 bits tales como x86-64,ppc64,s390x,etc...), ut_tv tiene el mismo tamaño en el mode de 32-bits y en el de 64-bits. Lo mismo ocurre con ut_session y ut_time si existen. Esto permite que se comparta memoria y datos entre aplicaciones de distinto tipo. Este se consigue al modificar el tipo de ut_session a int32_t y el de ut_tv a una estructura con dos campos int32_t: tv_sec y tv_usec. Como ut_tv puede no ser igual que struct timeval en lugar de la llamada:


gettimeofday((struct timeval *) &ut.ut_tv, NULL);

se recomienda definir este campo con el siguiente método:


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;

ac(1), date(1), init(1), last(1), login(1), logname(1), lslogins(1), users(1), utmpdump(1), who(1), getutent(3), getutmp(3), login(3), logout(3), logwtmp(3), updwtmp(3)

La traducción al español de esta página del manual fue creada por Juan Piernas <piernas@ditec.um.es>, Miguel Pérez Ibars <mpi79470@alu.um.es> y Marcos Fouces <marcos@debian.org>

Esta traducción es documentación libre; lea la GNU General Public License Version 3 o posterior con respecto a las condiciones de copyright. No existe NINGUNA RESPONSABILIDAD.

Si encuentra algún error en la traducción de esta página del manual, envíe un correo electrónico a debian-l10n-spanish@lists.debian.org.

3 Mayo 2023 Páginas de manual de Linux 6.05.01