summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2021-11-13 08:13:44 +0100
committerGitHub <noreply@github.com>2021-11-13 08:13:44 +0100
commita4e27f051a0d8e47a9927421d8e6a5234fef924d (patch)
treeab863be28223efe583e991cace7498716d48728d
parentbb562024a57d2e183d85a2e62639f9fb63281969 (diff)
parentb4d4596ffbf7ebeb6719f590db21ef67eafa97c2 (diff)
downloadsystemd-a4e27f051a0d8e47a9927421d8e6a5234fef924d.tar.gz
Merge pull request #21337 from poettering/uid-alloc-range-split
split out UID allocation range stuff from user-record.c/h (i.e. login.defs parsing)
-rw-r--r--src/core/dynamic-user.c2
-rw-r--r--src/coredump/coredump.c2
-rw-r--r--src/home/homectl.c1
-rw-r--r--src/home/homed-home.c1
-rw-r--r--src/journal/journald-server.c2
-rw-r--r--src/login/logind-user.c1
-rw-r--r--src/shared/condition.c2
-rw-r--r--src/shared/group-record.c1
-rw-r--r--src/shared/meson.build2
-rw-r--r--src/shared/uid-alloc-range.c123
-rw-r--r--src/shared/uid-alloc-range.h34
-rw-r--r--src/shared/user-record.c121
-rw-r--r--src/shared/user-record.h29
-rw-r--r--src/sysusers/sysusers.c2
-rw-r--r--src/test/meson.build2
-rw-r--r--src/test/test-condition.c2
-rw-r--r--src/test/test-uid-alloc-range.c (renamed from src/test/test-user-record.c)4
17 files changed, 173 insertions, 158 deletions
diff --git a/src/core/dynamic-user.c b/src/core/dynamic-user.c
index 2672496724..04d8e7c5e3 100644
--- a/src/core/dynamic-user.c
+++ b/src/core/dynamic-user.c
@@ -19,7 +19,7 @@
#include "stdio-util.h"
#include "string-util.h"
#include "strv.h"
-#include "user-record.h"
+#include "uid-alloc-range.h"
#include "user-util.h"
/* Takes a value generated randomly or by hashing and turns it into a UID in the right range */
diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c
index a88f495571..62a622a6ca 100644
--- a/src/coredump/coredump.c
+++ b/src/coredump/coredump.c
@@ -50,7 +50,7 @@
#include "strv.h"
#include "sync-util.h"
#include "tmpfile-util.h"
-#include "user-record.h"
+#include "uid-alloc-range.h"
#include "user-util.h"
/* The maximum size up to which we process coredumps */
diff --git a/src/home/homectl.c b/src/home/homectl.c
index 21c12816c4..a4f3116544 100644
--- a/src/home/homectl.c
+++ b/src/home/homectl.c
@@ -36,6 +36,7 @@
#include "rlimit-util.h"
#include "spawn-polkit-agent.h"
#include "terminal-util.h"
+#include "uid-alloc-range.h"
#include "user-record-pwquality.h"
#include "user-record-show.h"
#include "user-record-util.h"
diff --git a/src/home/homed-home.c b/src/home/homed-home.c
index 2b4e5dde8f..a31e27d051 100644
--- a/src/home/homed-home.c
+++ b/src/home/homed-home.c
@@ -34,6 +34,7 @@
#include "stat-util.h"
#include "string-table.h"
#include "strv.h"
+#include "uid-alloc-range.h"
#include "user-record-pwquality.h"
#include "user-record-sign.h"
#include "user-record-util.h"
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
index fc7bdb8737..ed53d32005 100644
--- a/src/journal/journald-server.c
+++ b/src/journal/journald-server.c
@@ -55,7 +55,7 @@
#include "string-table.h"
#include "string-util.h"
#include "syslog-util.h"
-#include "user-record.h"
+#include "uid-alloc-range.h"
#include "user-util.h"
#define USER_JOURNALS_MAX 1024
diff --git a/src/login/logind-user.c b/src/login/logind-user.c
index 1c8d84329f..5266f55775 100644
--- a/src/login/logind-user.c
+++ b/src/login/logind-user.c
@@ -32,6 +32,7 @@
#include "string-table.h"
#include "strv.h"
#include "tmpfile-util.h"
+#include "uid-alloc-range.h"
#include "unit-name.h"
#include "user-util.h"
#include "util.h"
diff --git a/src/shared/condition.c b/src/shared/condition.c
index 3e6ae79553..6e769e9d59 100644
--- a/src/shared/condition.c
+++ b/src/shared/condition.c
@@ -47,7 +47,7 @@
#include "string-table.h"
#include "string-util.h"
#include "tomoyo-util.h"
-#include "user-record.h"
+#include "uid-alloc-range.h"
#include "user-util.h"
#include "util.h"
#include "virt.h"
diff --git a/src/shared/group-record.c b/src/shared/group-record.c
index a13c06fd88..2f12ac1c22 100644
--- a/src/shared/group-record.c
+++ b/src/shared/group-record.c
@@ -2,6 +2,7 @@
#include "group-record.h"
#include "strv.h"
+#include "uid-alloc-range.h"
#include "user-util.h"
GroupRecord* group_record_new(void) {
diff --git a/src/shared/meson.build b/src/shared/meson.build
index 229e58beba..1fd1d711b0 100644
--- a/src/shared/meson.build
+++ b/src/shared/meson.build
@@ -292,6 +292,8 @@ shared_sources = files('''
tpm2-util.h
udev-util.c
udev-util.h
+ uid-alloc-range.c
+ uid-alloc-range.h
uid-range.c
uid-range.h
user-record-nss.c
diff --git a/src/shared/uid-alloc-range.c b/src/shared/uid-alloc-range.c
new file mode 100644
index 0000000000..dcecdbe343
--- /dev/null
+++ b/src/shared/uid-alloc-range.c
@@ -0,0 +1,123 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "chase-symlinks.h"
+#include "fd-util.h"
+#include "fileio.h"
+#include "string-util.h"
+#include "uid-alloc-range.h"
+#include "user-util.h"
+
+static const UGIDAllocationRange default_ugid_allocation_range = {
+ .system_alloc_uid_min = SYSTEM_ALLOC_UID_MIN,
+ .system_uid_max = SYSTEM_UID_MAX,
+ .system_alloc_gid_min = SYSTEM_ALLOC_GID_MIN,
+ .system_gid_max = SYSTEM_GID_MAX,
+};
+
+#if ENABLE_COMPAT_MUTABLE_UID_BOUNDARIES
+static int parse_alloc_uid(const char *path, const char *name, const char *t, uid_t *ret_uid) {
+ uid_t uid;
+ int r;
+
+ r = parse_uid(t, &uid);
+ if (r < 0)
+ return log_debug_errno(r, "%s: failed to parse %s %s, ignoring: %m", path, name, t);
+ if (uid == 0)
+ uid = 1;
+
+ *ret_uid = uid;
+ return 0;
+}
+#endif
+
+int read_login_defs(UGIDAllocationRange *ret_defs, const char *path, const char *root) {
+#if ENABLE_COMPAT_MUTABLE_UID_BOUNDARIES
+ _cleanup_fclose_ FILE *f = NULL;
+ UGIDAllocationRange defs;
+ int r;
+
+ if (!path)
+ path = "/etc/login.defs";
+
+ r = chase_symlinks_and_fopen_unlocked(path, root, CHASE_PREFIX_ROOT, "re", NULL, &f);
+ if (r == -ENOENT)
+ goto defaults;
+ if (r < 0)
+ return log_debug_errno(r, "Failed to open %s: %m", path);
+
+ defs = default_ugid_allocation_range;
+
+ for (;;) {
+ _cleanup_free_ char *line = NULL;
+ char *t;
+
+ r = read_line(f, LINE_MAX, &line);
+ if (r < 0)
+ return log_debug_errno(r, "Failed to read %s: %m", path);
+ if (r == 0)
+ break;
+
+ if ((t = first_word(line, "SYS_UID_MIN")))
+ (void) parse_alloc_uid(path, "SYS_UID_MIN", t, &defs.system_alloc_uid_min);
+ else if ((t = first_word(line, "SYS_UID_MAX")))
+ (void) parse_alloc_uid(path, "SYS_UID_MAX", t, &defs.system_uid_max);
+ else if ((t = first_word(line, "SYS_GID_MIN")))
+ (void) parse_alloc_uid(path, "SYS_GID_MIN", t, &defs.system_alloc_gid_min);
+ else if ((t = first_word(line, "SYS_GID_MAX")))
+ (void) parse_alloc_uid(path, "SYS_GID_MAX", t, &defs.system_gid_max);
+ }
+
+ if (defs.system_alloc_uid_min > defs.system_uid_max) {
+ log_debug("%s: SYS_UID_MIN > SYS_UID_MAX, resetting.", path);
+ defs.system_alloc_uid_min = MIN(defs.system_uid_max - 1, (uid_t) SYSTEM_ALLOC_UID_MIN);
+ /* Look at sys_uid_max to make sure sys_uid_min..sys_uid_max remains a valid range. */
+ }
+ if (defs.system_alloc_gid_min > defs.system_gid_max) {
+ log_debug("%s: SYS_GID_MIN > SYS_GID_MAX, resetting.", path);
+ defs.system_alloc_gid_min = MIN(defs.system_gid_max - 1, (gid_t) SYSTEM_ALLOC_GID_MIN);
+ /* Look at sys_gid_max to make sure sys_gid_min..sys_gid_max remains a valid range. */
+ }
+
+ *ret_defs = defs;
+ return 1;
+defaults:
+#endif
+ *ret_defs = default_ugid_allocation_range;
+ return 0;
+}
+
+const UGIDAllocationRange *acquire_ugid_allocation_range(void) {
+#if ENABLE_COMPAT_MUTABLE_UID_BOUNDARIES
+ static thread_local UGIDAllocationRange defs;
+ static thread_local int initialized = 0; /* == 0 → not initialized yet
+ * < 0 → failure
+ * > 0 → success */
+
+ /* This function will ignore failure to read the file, so it should only be called from places where
+ * we don't crucially depend on the answer. In other words, it's appropriate for journald, but
+ * probably not for sysusers. */
+
+ if (initialized == 0)
+ initialized = read_login_defs(&defs, NULL, NULL) < 0 ? -1 : 1;
+ if (initialized < 0)
+ return &default_ugid_allocation_range;
+
+ return &defs;
+
+#endif
+ return &default_ugid_allocation_range;
+}
+
+bool uid_is_system(uid_t uid) {
+ const UGIDAllocationRange *defs;
+ assert_se(defs = acquire_ugid_allocation_range());
+
+ return uid <= defs->system_uid_max;
+}
+
+bool gid_is_system(gid_t gid) {
+ const UGIDAllocationRange *defs;
+ assert_se(defs = acquire_ugid_allocation_range());
+
+ return gid <= defs->system_gid_max;
+}
diff --git a/src/shared/uid-alloc-range.h b/src/shared/uid-alloc-range.h
new file mode 100644
index 0000000000..d3bf077045
--- /dev/null
+++ b/src/shared/uid-alloc-range.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+#include <stdbool.h>
+#include <sys/types.h>
+
+bool uid_is_system(uid_t uid);
+bool gid_is_system(gid_t gid);
+
+static inline bool uid_is_dynamic(uid_t uid) {
+ return DYNAMIC_UID_MIN <= uid && uid <= DYNAMIC_UID_MAX;
+}
+
+static inline bool gid_is_dynamic(gid_t gid) {
+ return uid_is_dynamic((uid_t) gid);
+}
+
+static inline bool uid_is_container(uid_t uid) {
+ return CONTAINER_UID_BASE_MIN <= uid && uid <= CONTAINER_UID_BASE_MAX;
+}
+
+static inline bool gid_is_container(gid_t gid) {
+ return uid_is_container((uid_t) gid);
+}
+
+typedef struct UGIDAllocationRange {
+ uid_t system_alloc_uid_min;
+ uid_t system_uid_max;
+ gid_t system_alloc_gid_min;
+ gid_t system_gid_max;
+} UGIDAllocationRange;
+
+int read_login_defs(UGIDAllocationRange *ret_defs, const char *path, const char *root);
+const UGIDAllocationRange *acquire_ugid_allocation_range(void);
diff --git a/src/shared/user-record.c b/src/shared/user-record.c
index 2fbe6ad5bd..b68b6a98d2 100644
--- a/src/shared/user-record.c
+++ b/src/shared/user-record.c
@@ -3,11 +3,8 @@
#include <sys/mount.h>
#include "cgroup-util.h"
-#include "chase-symlinks.h"
#include "dns-domain.h"
#include "env-util.h"
-#include "fd-util.h"
-#include "fileio.h"
#include "fs-util.h"
#include "hexdecoct.h"
#include "hostname-util.h"
@@ -15,131 +12,15 @@
#include "path-util.h"
#include "pkcs11-util.h"
#include "rlimit-util.h"
-#include "stat-util.h"
#include "string-table.h"
#include "strv.h"
+#include "uid-alloc-range.h"
#include "user-record.h"
#include "user-util.h"
#define DEFAULT_RATELIMIT_BURST 30
#define DEFAULT_RATELIMIT_INTERVAL_USEC (1*USEC_PER_MINUTE)
-#if ENABLE_COMPAT_MUTABLE_UID_BOUNDARIES
-static int parse_alloc_uid(const char *path, const char *name, const char *t, uid_t *ret_uid) {
- uid_t uid;
- int r;
-
- r = parse_uid(t, &uid);
- if (r < 0)
- return log_debug_errno(r, "%s: failed to parse %s %s, ignoring: %m", path, name, t);
- if (uid == 0)
- uid = 1;
-
- *ret_uid = uid;
- return 0;
-}
-#endif
-
-int read_login_defs(UGIDAllocationRange *ret_defs, const char *path, const char *root) {
- UGIDAllocationRange defs = {
- .system_alloc_uid_min = SYSTEM_ALLOC_UID_MIN,
- .system_uid_max = SYSTEM_UID_MAX,
- .system_alloc_gid_min = SYSTEM_ALLOC_GID_MIN,
- .system_gid_max = SYSTEM_GID_MAX,
- };
-
-#if ENABLE_COMPAT_MUTABLE_UID_BOUNDARIES
- _cleanup_fclose_ FILE *f = NULL;
- int r;
-
- if (!path)
- path = "/etc/login.defs";
-
- r = chase_symlinks_and_fopen_unlocked(path, root, CHASE_PREFIX_ROOT, "re", NULL, &f);
- if (r == -ENOENT)
- goto assign;
- if (r < 0)
- return log_debug_errno(r, "Failed to open %s: %m", path);
-
- for (;;) {
- _cleanup_free_ char *line = NULL;
- char *t;
-
- r = read_line(f, LINE_MAX, &line);
- if (r < 0)
- return log_debug_errno(r, "Failed to read %s: %m", path);
- if (r == 0)
- break;
-
- if ((t = first_word(line, "SYS_UID_MIN")))
- (void) parse_alloc_uid(path, "SYS_UID_MIN", t, &defs.system_alloc_uid_min);
- else if ((t = first_word(line, "SYS_UID_MAX")))
- (void) parse_alloc_uid(path, "SYS_UID_MAX", t, &defs.system_uid_max);
- else if ((t = first_word(line, "SYS_GID_MIN")))
- (void) parse_alloc_uid(path, "SYS_GID_MIN", t, &defs.system_alloc_gid_min);
- else if ((t = first_word(line, "SYS_GID_MAX")))
- (void) parse_alloc_uid(path, "SYS_GID_MAX", t, &defs.system_gid_max);
- }
-
- assign:
- if (defs.system_alloc_uid_min > defs.system_uid_max) {
- log_debug("%s: SYS_UID_MIN > SYS_UID_MAX, resetting.", path);
- defs.system_alloc_uid_min = MIN(defs.system_uid_max - 1, (uid_t) SYSTEM_ALLOC_UID_MIN);
- /* Look at sys_uid_max to make sure sys_uid_min..sys_uid_max remains a valid range. */
- }
- if (defs.system_alloc_gid_min > defs.system_gid_max) {
- log_debug("%s: SYS_GID_MIN > SYS_GID_MAX, resetting.", path);
- defs.system_alloc_gid_min = MIN(defs.system_gid_max - 1, (gid_t) SYSTEM_ALLOC_GID_MIN);
- /* Look at sys_gid_max to make sure sys_gid_min..sys_gid_max remains a valid range. */
- }
-#endif
-
- *ret_defs = defs;
- return 0;
-}
-
-const UGIDAllocationRange *acquire_ugid_allocation_range(void) {
-#if ENABLE_COMPAT_MUTABLE_UID_BOUNDARIES
- static thread_local UGIDAllocationRange defs = {
-#else
- static const UGIDAllocationRange defs = {
-#endif
- .system_alloc_uid_min = SYSTEM_ALLOC_UID_MIN,
- .system_uid_max = SYSTEM_UID_MAX,
- .system_alloc_gid_min = SYSTEM_ALLOC_GID_MIN,
- .system_gid_max = SYSTEM_GID_MAX,
- };
-
-#if ENABLE_COMPAT_MUTABLE_UID_BOUNDARIES
- /* This function will ignore failure to read the file, so it should only be called from places where
- * we don't crucially depend on the answer. In other words, it's appropriate for journald, but
- * probably not for sysusers. */
-
- static thread_local bool initialized = false;
-
- if (!initialized) {
- (void) read_login_defs(&defs, NULL, NULL);
- initialized = true;
- }
-#endif
-
- return &defs;
-}
-
-bool uid_is_system(uid_t uid) {
- const UGIDAllocationRange *defs;
- assert_se(defs = acquire_ugid_allocation_range());
-
- return uid <= defs->system_uid_max;
-}
-
-bool gid_is_system(gid_t gid) {
- const UGIDAllocationRange *defs;
- assert_se(defs = acquire_ugid_allocation_range());
-
- return gid <= defs->system_gid_max;
-}
-
UserRecord* user_record_new(void) {
UserRecord *h;
diff --git a/src/shared/user-record.h b/src/shared/user-record.h
index bc160a0a5e..c72bef4a72 100644
--- a/src/shared/user-record.h
+++ b/src/shared/user-record.h
@@ -17,35 +17,6 @@
/* The default disk size to use when nothing else is specified, relative to free disk space */
#define USER_DISK_SIZE_DEFAULT_PERCENT 85
-bool uid_is_system(uid_t uid);
-bool gid_is_system(gid_t gid);
-
-static inline bool uid_is_dynamic(uid_t uid) {
- return DYNAMIC_UID_MIN <= uid && uid <= DYNAMIC_UID_MAX;
-}
-
-static inline bool gid_is_dynamic(gid_t gid) {
- return uid_is_dynamic((uid_t) gid);
-}
-
-static inline bool uid_is_container(uid_t uid) {
- return CONTAINER_UID_BASE_MIN <= uid && uid <= CONTAINER_UID_BASE_MAX;
-}
-
-static inline bool gid_is_container(gid_t gid) {
- return uid_is_container((uid_t) gid);
-}
-
-typedef struct UGIDAllocationRange {
- uid_t system_alloc_uid_min;
- uid_t system_uid_max;
- gid_t system_alloc_gid_min;
- gid_t system_gid_max;
-} UGIDAllocationRange;
-
-int read_login_defs(UGIDAllocationRange *ret_defs, const char *path, const char *root);
-const UGIDAllocationRange *acquire_ugid_allocation_range(void);
-
typedef enum UserDisposition {
USER_INTRINSIC, /* root and nobody */
USER_SYSTEM, /* statically allocated users for system services */
diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c
index 106a602305..0e60f2c00f 100644
--- a/src/sysusers/sysusers.c
+++ b/src/sysusers/sysusers.c
@@ -31,8 +31,8 @@
#include "strv.h"
#include "sync-util.h"
#include "tmpfile-util-label.h"
+#include "uid-alloc-range.h"
#include "uid-range.h"
-#include "user-record.h"
#include "user-util.h"
#include "utf8.h"
#include "util.h"
diff --git a/src/test/meson.build b/src/test/meson.build
index 84811c038f..77fe462a6b 100644
--- a/src/test/meson.build
+++ b/src/test/meson.build
@@ -261,7 +261,7 @@ tests += [
[['src/test/test-import-util.c']],
- [['src/test/test-user-record.c']],
+ [['src/test/test-uid-alloc-range.c']],
[['src/test/test-user-util.c']],
diff --git a/src/test/test-condition.c b/src/test/test-condition.c
index d7cd63da81..f7fa4ef2b1 100644
--- a/src/test/test-condition.c
+++ b/src/test/test-condition.c
@@ -32,7 +32,7 @@
#include "strv.h"
#include "tests.h"
#include "tomoyo-util.h"
-#include "user-record.h"
+#include "uid-alloc-range.h"
#include "user-util.h"
#include "virt.h"
diff --git a/src/test/test-user-record.c b/src/test/test-uid-alloc-range.c
index c9182e382b..8fa0b165d4 100644
--- a/src/test/test-user-record.c
+++ b/src/test/test-uid-alloc-range.c
@@ -7,9 +7,9 @@
#include "fileio.h"
#include "format-util.h"
#include "fs-util.h"
-#include "tmpfile-util.h"
#include "tests.h"
-#include "user-record.h"
+#include "tmpfile-util.h"
+#include "uid-alloc-range.h"
static void test_read_login_defs(const char *path) {
log_info("/* %s(\"%s\") */", __func__, path ?: "<custom>");