]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/update-utmp/update-utmp.c
ci: fix workaround about bpftool for codeql
[thirdparty/systemd.git] / src / update-utmp / update-utmp.c
CommitLineData
db9ecf05 1/* SPDX-License-Identifier: LGPL-2.1-or-later */
4927fcae 2
ca78ad1d 3#include <sys/stat.h>
4927fcae 4
89456fce
TG
5#include "sd-bus.h"
6
b5efdb8a 7#include "bus-error.h"
b7147168 8#include "bus-locator.h"
b5efdb8a 9#include "bus-util.h"
c992250c 10#include "libaudit-util.h"
4927fcae 11#include "log.h"
72682957 12#include "main-func.h"
8857aa74 13#include "time-util.h"
b5efdb8a 14#include "utmp-wtmp.h"
230f663e 15#include "verbs.h"
4927fcae
LP
16
17typedef struct Context {
89456fce 18 sd_bus *bus;
4927fcae 19 int audit_fd;
4927fcae
LP
20} Context;
21
3664cbab
YW
22static void context_clear(Context *c) {
23 assert(c);
24
25 c->bus = sd_bus_flush_close_unref(c->bus);
9c6afab6 26 c->audit_fd = close_audit_fd(c->audit_fd);
3664cbab
YW
27}
28
3950d8f6 29static int get_startup_monotonic_time(Context *c, usec_t *ret) {
4afd3348 30 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
89456fce 31 int r;
4927fcae 32
4927fcae 33 assert(c);
3950d8f6 34 assert(ret);
4927fcae 35
85d040da
YW
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
3950d8f6
YW
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));
4927fcae 50
3950d8f6 51 return 0;
4927fcae
LP
52}
53
230f663e
YW
54static int on_reboot(int argc, char *argv[], void *userdata) {
55 Context *c = ASSERT_PTR(userdata);
3950d8f6 56 usec_t t = 0, boottime;
4c40ab20 57 int r, q = 0;
4927fcae 58
309491e4 59 /* We finished start-up, so let's write the utmp record and send the audit msg. */
4927fcae 60
349cc4a5 61#if HAVE_AUDIT
4927fcae 62 if (c->audit_fd >= 0)
4d8c5c65 63 if (sym_audit_log_user_comm_message(c->audit_fd, AUDIT_SYSTEM_BOOT, "", "systemd-update-utmp", NULL, NULL, NULL, 1) < 0 &&
38cd55b0 64 errno != EPERM)
4c40ab20 65 q = log_error_errno(errno, "Failed to send audit message: %m");
4927fcae
LP
66#endif
67
3950d8f6
YW
68 /* If this call fails, then utmp_put_reboot() will fix to the current time. */
69 (void) get_startup_monotonic_time(c, &t);
f813b623 70 boottime = map_clock_usec(t, CLOCK_MONOTONIC, CLOCK_REALTIME);
309491e4
YW
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. */
f813b623 75
4c40ab20
YW
76 r = utmp_put_reboot(boottime);
77 if (r < 0)
78 return log_error_errno(r, "Failed to write utmp record: %m");
4927fcae 79
4c40ab20 80 return q;
4927fcae
LP
81}
82
230f663e 83static int on_shutdown(int argc, char *argv[], void *userdata) {
4c40ab20 84 int r, q = 0;
4927fcae 85
309491e4 86 /* We started shut-down, so let's write the utmp record and send the audit msg. */
4927fcae 87
349cc4a5 88#if HAVE_AUDIT
230f663e
YW
89 Context *c = ASSERT_PTR(userdata);
90
4927fcae 91 if (c->audit_fd >= 0)
4d8c5c65 92 if (sym_audit_log_user_comm_message(c->audit_fd, AUDIT_SYSTEM_SHUTDOWN, "", "systemd-update-utmp", NULL, NULL, NULL, 1) < 0 &&
38cd55b0 93 errno != EPERM)
4c40ab20 94 q = log_error_errno(errno, "Failed to send audit message: %m");
4927fcae
LP
95#endif
96
4c40ab20
YW
97 r = utmp_put_shutdown();
98 if (r < 0)
99 return log_error_errno(r, "Failed to write utmp record: %m");
4927fcae 100
4c40ab20 101 return q;
4927fcae
LP
102}
103
72682957 104static int run(int argc, char *argv[]) {
230f663e
YW
105 static const Verb verbs[] = {
106 { "reboot", 1, 1, 0, on_reboot },
107 { "shutdown", 1, 1, 0, on_shutdown },
230f663e
YW
108 {}
109 };
110
3664cbab 111 _cleanup_(context_clear) Context c = {
254d1313 112 .audit_fd = -EBADF,
1cea22a5 113 };
4927fcae 114
d2acb93d 115 log_setup();
4927fcae 116
4c12626c
LP
117 umask(0022);
118
9c6afab6 119 c.audit_fd = open_audit_fd_or_warn();
4927fcae 120
230f663e 121 return dispatch_verb(argc, argv, verbs, &c);
4927fcae 122}
72682957
ZJS
123
124DEFINE_MAIN_FUNCTION(run);