diff options
author | Lennart Poettering <lennart@poettering.net> | 2021-11-12 18:50:44 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2021-11-13 08:10:11 +0100 |
commit | b085d2240658bed3eb313777fe7b766797fff71d (patch) | |
tree | bb1fc9b7face6f1eae01e2f498f28141419dcc1e | |
parent | bb562024a57d2e183d85a2e62639f9fb63281969 (diff) | |
download | systemd-b085d2240658bed3eb313777fe7b766797fff71d.tar.gz |
shared: split out UID allocation range stuff from user-record.h
user-record.[ch] are about the UserRecord JSON stuff, and the UID
allocation range stuff (i.e. login.defs handling) is a very different
thing, and complex enough on its own, let's give it its own c/h files.
No code changes, just some splitting out of code.
-rw-r--r-- | src/core/dynamic-user.c | 2 | ||||
-rw-r--r-- | src/coredump/coredump.c | 2 | ||||
-rw-r--r-- | src/home/homectl.c | 1 | ||||
-rw-r--r-- | src/home/homed-home.c | 1 | ||||
-rw-r--r-- | src/journal/journald-server.c | 2 | ||||
-rw-r--r-- | src/login/logind-user.c | 1 | ||||
-rw-r--r-- | src/shared/condition.c | 2 | ||||
-rw-r--r-- | src/shared/group-record.c | 1 | ||||
-rw-r--r-- | src/shared/meson.build | 2 | ||||
-rw-r--r-- | src/shared/uid-alloc-range.c | 124 | ||||
-rw-r--r-- | src/shared/uid-alloc-range.h | 34 | ||||
-rw-r--r-- | src/shared/user-record.c | 121 | ||||
-rw-r--r-- | src/shared/user-record.h | 29 | ||||
-rw-r--r-- | src/sysusers/sysusers.c | 2 | ||||
-rw-r--r-- | src/test/test-condition.c | 2 | ||||
-rw-r--r-- | src/test/test-user-record.c | 4 |
16 files changed, 173 insertions, 157 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..9615183473 --- /dev/null +++ b/src/shared/uid-alloc-range.c @@ -0,0 +1,124 @@ +/* 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" + +#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; +} 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/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-user-record.c index c9182e382b..8fa0b165d4 100644 --- a/src/test/test-user-record.c +++ b/src/test/test-user-record.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>"); |