Backport patch to emit audit events from systemd-sysusers
A second patch is backported to avoid conflict and also because it seems reasoanble to backport.
This commit is contained in:
parent
e54ec2f978
commit
d0973df863
3 changed files with 367 additions and 0 deletions
|
|
@ -0,0 +1,75 @@
|
|||
From 8ed12b37afea9ccc36789aad2cef0d60eb6c5073 Mon Sep 17 00:00:00 2001
|
||||
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||
Date: Wed, 18 Dec 2024 22:27:29 +0900
|
||||
Subject: [PATCH 1/2] update-utmp: do not give up if the first attempt at
|
||||
connecting bus failed
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Otherwise, the program exits with failure if the first attempt in run() failed:
|
||||
```
|
||||
Dec 18 20:27:37 systemd-update-utmp[254]: Bus n/a: changing state UNSET → OPENING
|
||||
Dec 18 20:27:37 systemd-update-utmp[254]: sd-bus: starting bus by connecting to /run/systemd/private...
|
||||
Dec 18 20:27:37 systemd-update-utmp[254]: Bus n/a: changing state OPENING → CLOSED
|
||||
Dec 18 20:27:37 systemd-update-utmp[254]: Failed to get D-Bus connection: Connection refused
|
||||
```
|
||||
|
||||
(cherry picked from commit 85d040dabd2cc67c89b7ed6157429b8f6f2240f4)
|
||||
---
|
||||
src/update-utmp/update-utmp.c | 15 ++++++++++-----
|
||||
1 file changed, 10 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/src/update-utmp/update-utmp.c b/src/update-utmp/update-utmp.c
|
||||
index e40843cf35..a10e6d478a 100644
|
||||
--- a/src/update-utmp/update-utmp.c
|
||||
+++ b/src/update-utmp/update-utmp.c
|
||||
@@ -53,6 +53,12 @@ static int get_startup_monotonic_time(Context *c, usec_t *ret) {
|
||||
assert(c);
|
||||
assert(ret);
|
||||
|
||||
+ if (!c->bus) {
|
||||
+ r = bus_connect_system_systemd(&c->bus);
|
||||
+ if (r < 0)
|
||||
+ return log_warning_errno(r, "Failed to get D-Bus connection, ignoring: %m");
|
||||
+ }
|
||||
+
|
||||
r = bus_get_property_trivial(
|
||||
c->bus,
|
||||
bus_systemd_mgr,
|
||||
@@ -94,10 +100,13 @@ static int get_current_runlevel(Context *c) {
|
||||
UINT64_C(100) * USEC_PER_MSEC +
|
||||
random_u64_range(UINT64_C(1900) * USEC_PER_MSEC * n_attempts / MAX_ATTEMPTS);
|
||||
(void) usleep_safe(usec);
|
||||
+ }
|
||||
|
||||
+ if (!c->bus) {
|
||||
r = bus_connect_system_systemd(&c->bus);
|
||||
if (r == -ECONNREFUSED && n_attempts < 64) {
|
||||
- log_debug_errno(r, "Failed to reconnect to system bus, retrying after a slight delay: %m");
|
||||
+ log_debug_errno(r, "Failed to %s to system bus, retrying after a slight delay: %m",
|
||||
+ n_attempts <= 1 ? "connect" : "reconnect");
|
||||
continue;
|
||||
}
|
||||
if (r < 0)
|
||||
@@ -251,7 +260,6 @@ static int run(int argc, char *argv[]) {
|
||||
.audit_fd = -EBADF,
|
||||
#endif
|
||||
};
|
||||
- int r;
|
||||
|
||||
log_setup();
|
||||
|
||||
@@ -264,9 +272,6 @@ static int run(int argc, char *argv[]) {
|
||||
log_full_errno(IN_SET(errno, EAFNOSUPPORT, EPROTONOSUPPORT) ? LOG_DEBUG : LOG_WARNING,
|
||||
errno, "Failed to connect to audit log, ignoring: %m");
|
||||
#endif
|
||||
- r = bus_connect_system_systemd(&c.bus);
|
||||
- if (r < 0)
|
||||
- return log_error_errno(r, "Failed to get D-Bus connection: %m");
|
||||
|
||||
return dispatch_verb(argc, argv, verbs, &c);
|
||||
}
|
||||
--
|
||||
2.47.1
|
||||
|
||||
287
0002-sysusers-emit-audit-events-for-user-and-group-creati.patch
Normal file
287
0002-sysusers-emit-audit-events-for-user-and-group-creati.patch
Normal file
|
|
@ -0,0 +1,287 @@
|
|||
From 398049208b4aae5f2a9f0d4914dee6ab6e101118 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||
Date: Fri, 10 Jan 2025 15:35:13 +0100
|
||||
Subject: [PATCH 2/2] sysusers: emit audit events for user and group creation
|
||||
|
||||
Background: Fedora/RHEL are switching to sysusers.d metadata for creation of
|
||||
users and groups for system users defined by packages
|
||||
(https://fedoraproject.org/wiki/Changes/RPMSuportForSystemdSysusers).
|
||||
Packages carry sysusers files. During package installation, rpm calls an
|
||||
program to execute on this config. This program may either be
|
||||
/usr/lib/rpm/sysusers.sh which calls useradd/groupadd, or
|
||||
/usr/bin/systemd-sysusers. To match the functionality provided by
|
||||
useradd/groupadd from the shadow-utils project, systemd-sysusers must emit
|
||||
audit events so that it provides a drop-in replacement.
|
||||
|
||||
systemd-sysuers will emit audit events AUDIT_ADD_USER/AUDIT_ADD_GROUP when
|
||||
adding users and groups. The operation "names" are copied from shadow-utils in
|
||||
Fedora (which has a patch to change them from the upstream version), so the
|
||||
format of the events that is generated on success should be identical.
|
||||
|
||||
The helper code is shared between sysusers and utmp-wtmp. I changed the
|
||||
audit_fd variable to be unconditional. This way we can avoid ugly iffdefery
|
||||
every time the variable would be used. The cost is that 4 bytes of unused
|
||||
storage might be present. This is negligible, and the compiler might even be
|
||||
able to optimize that away if it inlines things.
|
||||
---
|
||||
src/basic/audit-util.h | 33 +++++++++++++++++++++
|
||||
src/sysusers/meson.build | 2 ++
|
||||
src/sysusers/sysusers.c | 56 +++++++++++++++++++++++++++++++++++
|
||||
src/update-utmp/update-utmp.c | 23 ++------------
|
||||
4 files changed, 94 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/src/basic/audit-util.h b/src/basic/audit-util.h
|
||||
index 9a74e4f102..d8ecf14f69 100644
|
||||
--- a/src/basic/audit-util.h
|
||||
+++ b/src/basic/audit-util.h
|
||||
@@ -1,10 +1,16 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
+#if HAVE_AUDIT
|
||||
+# include <libaudit.h>
|
||||
+#endif
|
||||
+
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
+#include "errno-util.h"
|
||||
+#include "log.h"
|
||||
#include "pidref.h"
|
||||
|
||||
#define AUDIT_SESSION_INVALID UINT32_MAX
|
||||
@@ -17,3 +23,30 @@ bool use_audit(void);
|
||||
static inline bool audit_session_is_valid(uint32_t id) {
|
||||
return id > 0 && id != AUDIT_SESSION_INVALID;
|
||||
}
|
||||
+
|
||||
+/* The wrappers for audit_open() and audit_close() are inline functions so that we don't get a spurious
|
||||
+ * linkage to libaudit in libbasic, but we also don't need to create a separate source file for two very
|
||||
+ * short functions. */
|
||||
+
|
||||
+static inline int close_audit_fd(int fd) {
|
||||
+#if HAVE_AUDIT
|
||||
+ if (fd >= 0)
|
||||
+ audit_close(fd);
|
||||
+#else
|
||||
+ assert(fd < 0);
|
||||
+#endif
|
||||
+ return -EBADF;
|
||||
+}
|
||||
+
|
||||
+static inline int open_audit_fd_or_warn(void) {
|
||||
+ int fd = -EBADF;
|
||||
+
|
||||
+#if HAVE_AUDIT
|
||||
+ /* If the kernel lacks netlink or audit support, don't worry about it. */
|
||||
+ fd = audit_open();
|
||||
+ if (fd < 0)
|
||||
+ return log_full_errno(ERRNO_IS_NOT_SUPPORTED(errno) ? LOG_DEBUG : LOG_WARNING,
|
||||
+ errno, "Failed to connect to audit log, ignoring: %m");
|
||||
+#endif
|
||||
+ return fd;
|
||||
+}
|
||||
diff --git a/src/sysusers/meson.build b/src/sysusers/meson.build
|
||||
index 123ff41d3f..c968f55110 100644
|
||||
--- a/src/sysusers/meson.build
|
||||
+++ b/src/sysusers/meson.build
|
||||
@@ -9,6 +9,7 @@ executables += [
|
||||
'name' : 'systemd-sysusers',
|
||||
'public' : true,
|
||||
'sources' : files('sysusers.c'),
|
||||
+ 'dependencies' : libaudit,
|
||||
},
|
||||
executable_template + {
|
||||
'name' : 'systemd-sysusers.standalone',
|
||||
@@ -20,6 +21,7 @@ executables += [
|
||||
libshared_static,
|
||||
libsystemd_static,
|
||||
],
|
||||
+ 'dependencies' : libaudit,
|
||||
'build_by_default' : have_standalone_binaries,
|
||||
'install' : have_standalone_binaries,
|
||||
},
|
||||
diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c
|
||||
index 44253483db..84eb9fc0c3 100644
|
||||
--- a/src/sysusers/sysusers.c
|
||||
+++ b/src/sysusers/sysusers.c
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <getopt.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
+#include "audit-util.h"
|
||||
#include "build.h"
|
||||
#include "chase.h"
|
||||
#include "conf-files.h"
|
||||
@@ -106,6 +107,8 @@ STATIC_DESTRUCTOR_REGISTER(arg_image, freep);
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_image_policy, image_policy_freep);
|
||||
|
||||
typedef struct Context {
|
||||
+ int audit_fd;
|
||||
+
|
||||
OrderedHashmap *users, *groups;
|
||||
OrderedHashmap *todo_uids, *todo_gids;
|
||||
OrderedHashmap *members;
|
||||
@@ -126,6 +129,8 @@ typedef struct Context {
|
||||
static void context_done(Context *c) {
|
||||
assert(c);
|
||||
|
||||
+ c->audit_fd = close_audit_fd(c->audit_fd);
|
||||
+
|
||||
ordered_hashmap_free(c->groups);
|
||||
ordered_hashmap_free(c->users);
|
||||
ordered_hashmap_free(c->members);
|
||||
@@ -163,6 +168,48 @@ static void maybe_emit_login_defs_warning(Context *c) {
|
||||
c->login_defs_need_warning = false;
|
||||
}
|
||||
|
||||
+static void log_audit_accounts(Context *c, ItemType what) {
|
||||
+#if HAVE_AUDIT
|
||||
+ assert(c);
|
||||
+ assert(IN_SET(what, ADD_USER, ADD_GROUP));
|
||||
+
|
||||
+ if (arg_dry_run || c->audit_fd < 0)
|
||||
+ return;
|
||||
+
|
||||
+ Item *i;
|
||||
+ int type = what == ADD_USER ? AUDIT_ADD_USER : AUDIT_ADD_GROUP;
|
||||
+ const char *op = what == ADD_USER ? "adding-user" : "adding-group";
|
||||
+
|
||||
+ /* Notes:
|
||||
+ *
|
||||
+ * The op must not contain whitespace. The format with a dash matches what Fedora shadow-utils uses.
|
||||
+ *
|
||||
+ * We send id == -1, even though we know the number, in particular on success. This is because if we
|
||||
+ * send the id, the generated audit message will not contain the name. The name seems more useful
|
||||
+ * than the number, hence send just the name:
|
||||
+ *
|
||||
+ * type=ADD_USER msg=audit(01/10/2025 16:02:00.639:3854) :
|
||||
+ * pid=3846380 uid=root auid=zbyszek ses=2 msg='op=adding-user id=unknown(952) exe=systemd-sysusers ... res=success'
|
||||
+ * vs.
|
||||
+ * type=ADD_USER msg=audit(01/10/2025 16:03:15.457:3908) :
|
||||
+ * pid=3846607 uid=root auid=zbyszek ses=2 msg='op=adding-user acct=foo5 exe=systemd-sysusers ... res=success'
|
||||
+ */
|
||||
+
|
||||
+ ORDERED_HASHMAP_FOREACH(i, what == ADD_USER ? c->todo_uids : c->todo_gids)
|
||||
+ audit_log_acct_message(
|
||||
+ c->audit_fd,
|
||||
+ type,
|
||||
+ program_invocation_short_name,
|
||||
+ op,
|
||||
+ i->name,
|
||||
+ /* id= */ (unsigned) -1,
|
||||
+ /* host= */ NULL,
|
||||
+ /* addr= */ NULL,
|
||||
+ /* tty= */ NULL,
|
||||
+ /* success= */ 1);
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
static int load_user_database(Context *c) {
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
const char *passwd_path;
|
||||
@@ -971,6 +1018,8 @@ static int write_files(Context *c) {
|
||||
group_tmp, group_path);
|
||||
group_tmp = mfree(group_tmp);
|
||||
}
|
||||
+ /* OK, we have written the group entries successfully */
|
||||
+ log_audit_accounts(c, ADD_GROUP);
|
||||
if (gshadow) {
|
||||
r = rename_and_apply_smack_floor_label(gshadow_tmp, gshadow_path);
|
||||
if (r < 0)
|
||||
@@ -988,6 +1037,8 @@ static int write_files(Context *c) {
|
||||
|
||||
passwd_tmp = mfree(passwd_tmp);
|
||||
}
|
||||
+ /* OK, we have written the user entries successfully */
|
||||
+ log_audit_accounts(c, ADD_USER);
|
||||
if (shadow) {
|
||||
r = rename_and_apply_smack_floor_label(shadow_tmp, shadow_path);
|
||||
if (r < 0)
|
||||
@@ -2232,6 +2283,7 @@ static int run(int argc, char *argv[]) {
|
||||
#endif
|
||||
_cleanup_close_ int lock = -EBADF;
|
||||
_cleanup_(context_done) Context c = {
|
||||
+ .audit_fd = -EBADF,
|
||||
.search_uid = UID_INVALID,
|
||||
};
|
||||
|
||||
@@ -2281,6 +2333,10 @@ static int run(int argc, char *argv[]) {
|
||||
assert(!arg_image);
|
||||
#endif
|
||||
|
||||
+ /* Prepare to emit audit events, but only if we're operating on the host system. */
|
||||
+ if (!arg_root)
|
||||
+ c.audit_fd = open_audit_fd_or_warn();
|
||||
+
|
||||
/* If command line arguments are specified along with --replace, read all configuration files and
|
||||
* insert the positional arguments at the specified place. Otherwise, if command line arguments are
|
||||
* specified, execute just them, and finally, without --replace= or any positional arguments, just
|
||||
diff --git a/src/update-utmp/update-utmp.c b/src/update-utmp/update-utmp.c
|
||||
index a10e6d478a..6df9414063 100644
|
||||
--- a/src/update-utmp/update-utmp.c
|
||||
+++ b/src/update-utmp/update-utmp.c
|
||||
@@ -5,12 +5,9 @@
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
-#if HAVE_AUDIT
|
||||
-#include <libaudit.h>
|
||||
-#endif
|
||||
-
|
||||
#include "sd-bus.h"
|
||||
|
||||
+#include "audit-util.h"
|
||||
#include "alloc-util.h"
|
||||
#include "bus-error.h"
|
||||
#include "bus-locator.h"
|
||||
@@ -30,20 +27,14 @@
|
||||
|
||||
typedef struct Context {
|
||||
sd_bus *bus;
|
||||
-#if HAVE_AUDIT
|
||||
int audit_fd;
|
||||
-#endif
|
||||
} Context;
|
||||
|
||||
static void context_clear(Context *c) {
|
||||
assert(c);
|
||||
|
||||
c->bus = sd_bus_flush_close_unref(c->bus);
|
||||
-#if HAVE_AUDIT
|
||||
- if (c->audit_fd >= 0)
|
||||
- audit_close(c->audit_fd);
|
||||
- c->audit_fd = -EBADF;
|
||||
-#endif
|
||||
+ c->audit_fd = close_audit_fd(c->audit_fd);
|
||||
}
|
||||
|
||||
static int get_startup_monotonic_time(Context *c, usec_t *ret) {
|
||||
@@ -256,22 +247,14 @@ static int run(int argc, char *argv[]) {
|
||||
};
|
||||
|
||||
_cleanup_(context_clear) Context c = {
|
||||
-#if HAVE_AUDIT
|
||||
.audit_fd = -EBADF,
|
||||
-#endif
|
||||
};
|
||||
|
||||
log_setup();
|
||||
|
||||
umask(0022);
|
||||
|
||||
-#if HAVE_AUDIT
|
||||
- /* If the kernel lacks netlink or audit support, don't worry about it. */
|
||||
- c.audit_fd = audit_open();
|
||||
- if (c.audit_fd < 0)
|
||||
- log_full_errno(IN_SET(errno, EAFNOSUPPORT, EPROTONOSUPPORT) ? LOG_DEBUG : LOG_WARNING,
|
||||
- errno, "Failed to connect to audit log, ignoring: %m");
|
||||
-#endif
|
||||
+ c.audit_fd = open_audit_fd_or_warn();
|
||||
|
||||
return dispatch_verb(argc, argv, verbs, &c);
|
||||
}
|
||||
--
|
||||
2.47.1
|
||||
|
||||
|
|
@ -118,6 +118,11 @@ Patch: https://github.com/systemd/systemd/pull/26494.patch
|
|||
# https://github.com/coreos/fedora-coreos-tracker/issues/1857
|
||||
Patch: 0001-Revert-units-use-PrivateTmp-disconnected-instead-of-.patch
|
||||
|
||||
# Backport of sysusers audit support for
|
||||
# https://fedoraproject.org/wiki/Changes/RPMSuportForSystemdSysusers.
|
||||
Patch: 0001-update-utmp-do-not-give-up-if-the-first-attempt-at-c.patch
|
||||
Patch: 0002-sysusers-emit-audit-events-for-user-and-group-creati.patch
|
||||
|
||||
# Those are downstream-only patches, but we don't want them in packit builds:
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=2251843
|
||||
Patch: https://github.com/systemd/systemd/pull/30846.patch
|
||||
|
|
|
|||
Loading…
Reference in a new issue