UTMP - Linux手册页
Linux程序员手册 第5部分
更新日期: 2020-08-13
名称
utmp,wtmp-登录记录
语法
#包括
说明
utmp文件允许发现有关谁当前正在使用该系统的信息。当前可能有更多用户在使用该系统,因为并非所有程序都使用utmp日志记录。
警告:utmp不能由"其他"用户类写入,因为许多系统程序(愚蠢地)依赖于它的完整性。如果让utmp对文件所有者和组所有者以外的任何用户可写,则可能会冒充伪造的系统日志文件和修改系统文件的风险。
该文件是utmp结构的序列,声明如下:(请注意,这只是周围的几种定义之一;详细信息取决于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 int e_termination; /* Process termination status */ short int 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]
此结构以time(2)的形式给出与用户终端关联的特殊文件的名称,用户的登录名以及登录时间。如果字符串字段短于字段的大小,则以空字节(aq \ 0aq)终止。
有史以来创建的第一个条目来自init(1)处理inittab(5)的结果。但是,在处理条目之前,init(1)通过将ut_type设置为DEAD_PROCESS来清除utmp,清除ut_user,ut_host和ut_time的空字节,以确保ut_type不是DEAD_PROCESS或RUN_LVL且没有使用PID ut_pid的进程的每个记录。如果找不到具有所需ut_id的空记录,则init(1)创建一个新记录。它将inittab中的ut_id,ut_pid和ut_time设置为当前值,并将ut_type设置为INIT_PROCESS。
mingetty(8)(或agetty(8))通过PID找到条目,将ut_type更改为LOGIN_PROCESS,更改ut_time,设置ut_line,然后等待建立连接。 login(1),在验证用户身份之后,将ut_type更改为USER_PROCESS,更改ut_time,并设置ut_host和ut_addr。根据mingetty(8)(或agetty(8))和login(1),记录可以通过ut_line定位,而不是首选的ut_pid。
当init(1)发现某个进程已退出时,它将通过ut_pid查找其utmp条目,将ut_type设置为DEAD_PROCESS,并使用空字节清除ut_user,ut_host和ut_time。
xterm(1)和其他终端仿真器通过使用在终端名称后缀部分的字符串(/ dev / [pt] ty之后的字符)直接创建USER_PROCESS记录并生成ut_id。如果他们找到此ID的DEAD_PROCESS,则将其回收,否则将创建一个新条目。如果可以的话,他们将在退出时将其标记为DEAD_PROCESS,并且建议将ut_line,ut_time,ut_user和ut_host也设置为null。
telnetd(8)设置LOGIN_PROCESS条目,其余部分照常保留给login(1)。 telnet会话结束后,telnetd(8)以上述方式清除utmp。
wtmp文件记录所有登录和注销。其格式与utmp完全相同,不同之处在于用户名为空表示在关联终端上注销。此外,带有用户名shutdown或reboot的终端名称ti表示系统已关闭或重启,并且一对终端名称| /}在date(1)更改时记录旧/新系统时间。 wtmp由login(1),init(1)和一些getty(8)版本维护(例如mingetty(8)或agetty(8))。这些程序都不创建该文件,因此,如果删除该文件,则将关闭记录保存。
文件
/ var / run / utmp
/ var / log / wtmp
遵循规范
POSIX.1没有指定utmp结构,而是指定了一个名为utmpx的结构,其中指定了ut_type,ut_pid,ut_line,ut_id,ut_user和ut_tv字段的规范。 POSIX.1没有指定ut_line和ut_user字段的长度。
Linux将utmpx结构定义为与utmp结构相同。
Comparison with historical systems
Linux utmp条目既不符合v7 / BSD也不符合System V;它们是两者的结合。
v7 / BSD的字段较少;最重要的是,它缺少ut_type,这会导致类似v7 / BSD的本机程序显示(例如)无效或登录条目。此外,没有配置文件为会话分配插槽。 BSD之所以这样做是因为它缺少ut_id字段。
在Linux中(如在System V中),记录的ut_id字段一旦设置就永远不会改变,它无需配置文件即可保留该插槽。清除ut_id可能会导致争用情况,从而导致utmp条目损坏和潜在的安全漏洞。 System V语义不需要通过将它们填充为空字节来清除上述字段,但是可以运行许多采用BSD语义并且不修改utmp的程序。如上所述,Linux将BSD约定用于行内容。
系统V没有ut_host或ut_addr_v6字段。
备注
与其他各种系统不同,在其他系统中,可以通过删除文件来禁用utmp日志记录,而utmp必须始终存在于Linux上。如果要禁用who(1),则不要使utmp世界可读。
该文件格式取决于计算机,因此建议仅在创建该文件的计算机体系结构上对其进行处理。
请注意,在biarch平台上,即可以同时运行32位和64位应用程序(x86-64,ppc64,s390x等)的系统,ut_tv在32位模式下的大小与在64位模式下的大小相同模式。如果存在,则ut_session和ut_time也是一样。这允许在32位和64位应用程序之间共享数据文件和共享内存。这是通过将ut_session的类型更改为int32_t,并将ut_tv的类型更改为具有两个int32_t字段tv_sec和tv_usec的结构来实现的。由于ut_tv可能与struct timeval不同,所以代替调用:
gettimeofday((struct timeval *) &ut.ut_tv, NULL);
建议使用以下方法设置此字段:
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)
出版信息
这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/。