]> git.ipfire.org Git - thirdparty/systemd.git/blame_incremental - src/update-utmp/update-utmp.c
conf-files: include the expected suffix in the 'unexpected suffix' debug message.
[thirdparty/systemd.git] / src / update-utmp / update-utmp.c
... / ...
CommitLineData
1/* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3#include <sys/stat.h>
4
5#include "sd-bus.h"
6
7#include "bus-error.h"
8#include "bus-locator.h"
9#include "bus-util.h"
10#include "libaudit-util.h"
11#include "log.h"
12#include "main-func.h"
13#include "time-util.h"
14#include "utmp-wtmp.h"
15#include "verbs.h"
16
17typedef struct Context {
18 sd_bus *bus;
19 int audit_fd;
20} Context;
21
22static void context_clear(Context *c) {
23 assert(c);
24
25 c->bus = sd_bus_flush_close_unref(c->bus);
26 c->audit_fd = close_audit_fd(c->audit_fd);
27}
28
29static int get_startup_monotonic_time(Context *c, usec_t *ret) {
30 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
31 int r;
32
33 assert(c);
34 assert(ret);
35
36 if (!c->bus) {
37 r = bus_connect_system_systemd(&c->bus);
38 if (r < 0)
39 return log_warning_errno(r, "Failed to get D-Bus connection, ignoring: %m");
40 }
41
42 r = bus_get_property_trivial(
43 c->bus,
44 bus_systemd_mgr,
45 "UserspaceTimestampMonotonic",
46 &error,
47 't', ret);
48 if (r < 0)
49 return log_warning_errno(r, "Failed to get timestamp, ignoring: %s", bus_error_message(&error, r));
50
51 return 0;
52}
53
54static int on_reboot(int argc, char *argv[], void *userdata) {
55 Context *c = ASSERT_PTR(userdata);
56 usec_t t = 0, boottime;
57 int r, q = 0;
58
59 /* We finished start-up, so let's write the utmp record and send the audit msg. */
60
61#if HAVE_AUDIT
62 if (c->audit_fd >= 0)
63 if (sym_audit_log_user_comm_message(c->audit_fd, AUDIT_SYSTEM_BOOT, "", "systemd-update-utmp", NULL, NULL, NULL, 1) < 0 &&
64 errno != EPERM)
65 q = log_error_errno(errno, "Failed to send audit message: %m");
66#endif
67
68 /* If this call fails, then utmp_put_reboot() will fix to the current time. */
69 (void) get_startup_monotonic_time(c, &t);
70 boottime = map_clock_usec(t, CLOCK_MONOTONIC, CLOCK_REALTIME);
71 /* We query the recorded monotonic time here (instead of the system clock CLOCK_REALTIME), even
72 * though we actually want the system clock time. That's because there's a likely chance that the
73 * system clock wasn't set right during early boot. By manually converting the monotonic clock to the
74 * system clock here we can compensate for incorrectly set clocks during early boot. */
75
76 r = utmp_put_reboot(boottime);
77 if (r < 0)
78 return log_error_errno(r, "Failed to write utmp record: %m");
79
80 return q;
81}
82
83static int on_shutdown(int argc, char *argv[], void *userdata) {
84 int r, q = 0;
85
86 /* We started shut-down, so let's write the utmp record and send the audit msg. */
87
88#if HAVE_AUDIT
89 Context *c = ASSERT_PTR(userdata);
90
91 if (c->audit_fd >= 0)
92 if (sym_audit_log_user_comm_message(c->audit_fd, AUDIT_SYSTEM_SHUTDOWN, "", "systemd-update-utmp", NULL, NULL, NULL, 1) < 0 &&
93 errno != EPERM)
94 q = log_error_errno(errno, "Failed to send audit message: %m");
95#endif
96
97 r = utmp_put_shutdown();
98 if (r < 0)
99 return log_error_errno(r, "Failed to write utmp record: %m");
100
101 return q;
102}
103
104static int run(int argc, char *argv[]) {
105 static const Verb verbs[] = {
106 { "reboot", 1, 1, 0, on_reboot },
107 { "shutdown", 1, 1, 0, on_shutdown },
108 {}
109 };
110
111 _cleanup_(context_clear) Context c = {
112 .audit_fd = -EBADF,
113 };
114
115 log_setup();
116
117 umask(0022);
118
119 c.audit_fd = open_audit_fd_or_warn();
120
121 return dispatch_verb(argc, argv, verbs, &c);
122}
123
124DEFINE_MAIN_FUNCTION(run);