1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2025-01-06 13:17:44 +03:00

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.
This commit is contained in:
Lennart Poettering 2021-11-12 18:50:44 +01:00
parent bb562024a5
commit b085d22406
16 changed files with 173 additions and 157 deletions

View File

@ -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 */

View File

@ -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 */

View File

@ -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"

View File

@ -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"

View File

@ -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

View File

@ -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"

View File

@ -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"

View File

@ -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) {

View File

@ -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

View File

@ -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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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 */

View File

@ -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"

View File

@ -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"

View File

@ -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>");