UTMP - Linux手册页

时间:2019-08-20 18:01:51  来源:igfitidea点击:

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_lineut_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_typeut_pidut_lineut_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/