| utmp(5) | File Formats Manual | utmp(5) |
نام (NAME)
utmp, wtmp - رکوردهای ورود به سیستم
خلاصه دستور (SYNOPSIS)
#include <utmp.h>
توضیحات (DESCRIPTION)
پرونده utmp امکان آگاهی از اطلاعات مربوط به اینکه چه کسانی در حال حاضر از سیستم استفاده میکنند را فراهم میسازد. ممکن است کاربران بیشتری در حال حاضر از سیستم استفاده کنند، زیرا همه برنامهها از ثبت وقایع utmp استفاده نمیکنند.
هشدار: utmp نباید توسط دسته کاربری «دیگران» (other) قابل نوشتن باشد، زیرا بسیاری از برنامههای سیستم (از روی ناآگاهی) به سلامت و یکپارچگی آن وابسته هستند. اگر utmp را برای هر کاربری غیر از مالک و گروه مالک پرونده قابل نوشتن بگذارید، با خطر جعلی شدن پروندههای وقایع سیستم و تغییر غیرمجاز پروندههای سیستمی روبرو خواهید شد.
این پرونده دنبالهای از ساختارهای utmp است که به صورت زیر در <utmp.h> اعلام شدهاند (توجه داشته باشید که این تنها یکی از چندین تعریف موجود است؛ جزئیات به نسخه libc بستگی دارد):
/* مقادیر برای فیلد ut_type در زیر */
#define EMPTY 0 /* رکورد حاوی اطلاعات معتبر نیست
(پیشتر در لینوکس به عنوان UT_UNKNOWN شناخته میشد) */
#define RUN_LVL 1 /* تغییر در سطح اجرای سیستم (نگاه کنید به
init(1))
*/
#define BOOT_TIME 2 /* زمان راهاندازی سیستم (در ut_tv) */
#define NEW_TIME 3 /* زمان پس از تغییر ساعت سیستم
(در ut_tv) */
#define OLD_TIME 4 /* زمان پیش از تغییر ساعت سیستم
(در ut_tv) */
#define INIT_PROCESS 5 /* فرآیند ایجادشده توسط
init(1)
*/
#define LOGIN_PROCESS 6 /* فرآیند رهبر نشست برای ورود کاربر */
#define USER_PROCESS 7 /* فرآیند عادی */
#define DEAD_PROCESS 8 /* فرآیند خاتمهیافته */
#define ACCOUNTING 9 /* پیادهسازی نشده است */
#define UT_LINESIZE 32
#define UT_NAMESIZE 32
#define UT_HOSTSIZE 256
struct exit_status { /* نوع داده برای ut_exit در زیر */
short e_termination; /* وضعیت خاتمه فرآیند */
short e_exit; /* وضعیت خروج فرآیند */
};
struct utmp {
short ut_type; /* نوع رکورد */
pid_t ut_pid; /* شناسه PID فرآیند ورود */
char ut_line[UT_LINESIZE]; /* نام دستگاه tty - "/dev/" */
char ut_id[4]; /* پسوند نام ترمینال یا
شناسه inittab(5) */
char ut_user[UT_NAMESIZE]; /* نام کاربری */
char ut_host[UT_HOSTSIZE]; /* نام میزبان برای ورود از دور، یا
نسخه هسته برای پیامهای سطح
اجرا */
struct exit_status ut_exit; /* وضعیت خروج فرآیندی که به عنوان
DEAD_PROCESS علامتگذاری شده؛ توسط
init(1)
لینوکس استفاده نمیشود */
/* فیلدهای ut_session و ut_tv هنگام کامپایل ۳۲ و ۶۴ بیتی باید اندازه
یکسانی داشته باشند. این ویژگی اجازه میدهد پروندههای داده و حافظه اشتراکی
بین برنامههای ۳۲ بیتی و ۶۴ بیتی به اشتراک گذاشته شوند. */
#if __WORDSIZE == 64 && defined __WORDSIZE_COMPAT32
int32_t ut_session; /* شناسه نشست (
getsid(2))،
مورد استفاده برای پنجرهبندی */
struct {
int32_t tv_sec; /* ثانیه */
int32_t tv_usec; /* میکروثانیه */
} ut_tv; /* زمان ثبت مدخل */
#else
long ut_session; /* شناسه نشست */
struct timeval ut_tv; /* زمان ثبت مدخل */
#endif
int32_t ut_addr_v6[4]; /* نشانی اینترنتی میزبان دور؛
نشانی IPv4 تنها از
ut_addr_v6[0] استفاده میکند */
char __unused[20]; /* رزرو شده برای کاربردهای آینده */
};
/* ترفندهای سازگاری با گذشته */
#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) ارائه میدهد. فیلدهای رشتهای در صورتی که کوتاهتر از اندازه فیلد باشند، با یک بایت تهی ('\0') خاتمه مییابند.
نخستین مدخلهایی که تاکنون ایجاد شدهاند حاصل پردازش inittab(5) توسط init(1) هستند. با این حال، پیش از پردازش یک مدخل، init(1) با تنظیم ut_type روی DEAD_PROCESS، و پاک کردن ut_user، ut_host و ut_time با بایتهای تهی برای هر رکوردی که ut_type آن DEAD_PROCESS یا RUN_LVL نبوده و هیچ فرآیندی با شناسه ut_pid برای آن وجود ندارد، utmp را پاکسازی میکند. اگر هیچ رکورد خالی با ut_id مورد نیاز یافت نشود، init(1) یک رکورد جدید ایجاد میکند. این برنامه ut_id را از inittab، و 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_pid، بر اساس ut_line یافت شوند.
هنگامی که init(1) درمییابد فرآیندی خارج شده است، مدخل utmp آن را از طریق ut_pid پیدا میکند، ut_type را روی DEAD_PROCESS تنظیم مینماید، و ut_user، ut_host و ut_time را با بایتهای تهی پاک میکند.
xterm(1) و دیگر شبیهسازهای ترمینال، مستقیماً یک رکورد USER_PROCESS ایجاد کرده و ut_id را با استفاده از رشتهای که بخش پسوند نام ترمینال است (نویسههای پس از /dev/[pt]ty) تولید مینمایند. اگر آنها برای این شناسه یک DEAD_PROCESS پیدا کنند، آن را دوباره استفاده (بازیافت) میکنند، در غیر این صورت یک مدخل جدید میسازند. در صورت امکان، آنها هنگام خروج آن را به عنوان DEAD_PROCESS علامتگذاری میکنند و توصیه میشود که ut_line، ut_time، ut_user و ut_host را نیز با بایت تهی پاک کنند.
telnetd(8) یک مدخل LOGIN_PROCESS ایجاد کرده و باقی کار را مطابق معمول به login(1) میسپارد. پس از پایان نشست telnet، برنامه telnetd(8) پرونده utmp را به همان شیوه شرح داده شده پاکسازی میکند.
پرونده wtmp تمامی ورودها و خروجها را ثبت میکند. قالب آن دقیقاً همانند utmp است، به جز اینکه یک نام کاربری تهی نشاندهنده خروج از سیستم روی ترمینال مربوطه است. علاوه بر این، نام ترمینال ~ با نام کاربری shutdown یا reboot نشاندهنده خاموش شدن یا راهاندازی مجدد سیستم است و جفت نامهای ترمینال |/} زمان قدیم/جدید سیستم را هنگامی که date(1) آن را تغییر میدهد ثبت میکند. wtmp توسط login(1)، init(1) و برخی نسخههای getty(8) (مانند mingetty(8) یا agetty(8)) نگهداری میشود. هیچیک از این برنامهها پرونده را نمیسازند، بنابراین اگر این پرونده حذف شود، ثبت وقایع غیرفعال میگردد.
فایلها (FILES)
/var/run/utmp
/var/log/wtmp
نسخهها (VERSIONS)
استاندارد POSIX.1 ساختار utmp را مشخص نمیکند، بلکه ساختاری با نام utmpx (به عنوان بخشی از الحاقیه XSI) را تعریف میکند، با مشخصاتی برای فیلدهای ut_type، ut_pid، ut_line، ut_id، ut_user و ut_tv. استاندارد POSIX.1 طول فیلدهای ut_line و ut_user را مشخص نمیکند.
لینوکس ساختار utmpx را همانند ساختار utmp تعریف میکند.
استانداردها (STANDARDS)
لینوکس.
تاریخچه (HISTORY)
مدخلهای utmp در لینوکس نه کاملاً مطابق با v7/BSD هستند و نه System V؛ بلکه ترکیبی از این دو میباشند.
نسخه v7/BSD فیلدهای کمتری دارد؛ مهمتر از همه اینکه فاقد ut_type است، که باعث میشود برنامههای بومی شبه-v7/BSD (برای نمونه) مدخلهای مرده یا ورود را نمایش دهند. علاوه بر این، هیچ پرونده پیکربندیای وجود ندارد که شیارها (slots) را به نشستها اختصاص دهد. سیستم BSD این کار را انجام میدهد زیرا فاقد فیلدهای ut_id است.
در لینوکس (همانند System V)، مقدار فیلد ut_id یک رکورد پس از مقداردهی اولیه هرگز تغییر نخواهد کرد، که همین امر بدون نیاز به پرونده پیکربندی، آن شیار را رزرو نگه میدارد. پاک کردن ut_id ممکن است منجر به شرایط رقابتی (race conditions) شود که به آسیب دیدن رکوردهای utmp و رخنههای امنیتی بالقوه میانجامد. پاک کردن فیلدهای ذکرشده با پر کردن آنها با بایتهای تهی، بر اساس معناشناسی System V الزامی نیست، اما اجرای بسیاری از برنامههایی را ممکن میسازد که معناشناسی BSD را فرض کرده و utmp را تغییر نمیدهند. لینوکس از قواعد BSD برای محتوای خط استفاده میکند، همانگونه که در بالا مستند شده است.
سیستمعامل System V فاقد فیلدهای ut_host یا ut_addr_v6 است.
یادداشتها (NOTES)
برخلاف سیستمهای متعدد دیگر که در آنها ثبت وقایع utmp را میتوان با حذف پرونده غیرفعال کرد، utmp در لینوکس همواره باید وجود داشته باشد. اگر میخواهید who(1) را غیرفعال کنید، دسترسی خواندن همگانی utmp را بردارید (آن را برای همه قابل خواندن نکنید).
قالب پرونده وابسته به معماری ماشین است، بنابراین توصیه میشود که تنها بر روی همان معماری ماشینی که بر روی آن ساخته شده پردازش گردد.
توجه داشته باشید که در پلتفرمهای با معماری دوگانه (biarch)، یعنی سیستمهایی که میتوانند هر دو برنامههای ۳۲ بیتی و ۶۴ بیتی را اجرا کنند (x86-64، ppc64، s390x و غیره)، اندازه ut_tv در حالت ۳۲ بیتی همانند حالت ۶۴ بیتی است. همین موضوع برای ut_session و ut_time نیز در صورت وجود صادق است. این قابلیت امکان اشتراک پروندههای داده و حافظه اشتراکی را میان برنامههای ۳۲ بیتی و ۶۴ بیتی فراهم میکند. این امر با تغییر دادن نوع 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;
همچنین ببینید (SEE ALSO)
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)
| 2025-09-21 | Linux man-pages 6.19 |