userdb: Add userdb.user.* and userdb.group.* credentials

Let's allow providing extra userdb users and groups via credentials.
Similarly to systemd-udev-load-credentials.service, we ship
systemd-userdb-load-credentials.service which transform the JSON
user/group records provided via the corresponding credentials to static
userdb dropins in /etc/userdb.

Replaces #33811
This commit is contained in:
Daan De Meyer
2025-03-18 22:46:10 +01:00
parent e5039d459e
commit fe0342edf4
11 changed files with 441 additions and 17 deletions
+12
View File
@@ -372,3 +372,15 @@ bool group_record_match(GroupRecord *h, const UserDBMatch *match) {
return true;
}
bool group_record_is_root(const GroupRecord *g) {
assert(g);
return g->gid == 0 || streq_ptr(g->group_name, "root");
}
bool group_record_is_nobody(const GroupRecord *g) {
assert(g);
return g->gid == GID_NOBODY || STRPTR_IN_SET(g->group_name, NOBODY_GROUP_NAME, "nobody");
}
+3
View File
@@ -49,3 +49,6 @@ const char* group_record_group_name_and_realm(GroupRecord *h);
UserDisposition group_record_disposition(GroupRecord *h);
bool group_record_matches_group_name(const GroupRecord *g, const char *groupname);
bool group_record_is_root(const GroupRecord *g);
bool group_record_is_nobody(const GroupRecord *g);
+2 -2
View File
@@ -2717,13 +2717,13 @@ int user_record_test_password_change_required(UserRecord *h) {
return change_permitted ? 0 : -EROFS;
}
int user_record_is_root(const UserRecord *u) {
bool user_record_is_root(const UserRecord *u) {
assert(u);
return u->uid == 0 || streq_ptr(u->user_name, "root");
}
int user_record_is_nobody(const UserRecord *u) {
bool user_record_is_nobody(const UserRecord *u) {
assert(u);
return u->uid == UID_NOBODY || STRPTR_IN_SET(u->user_name, NOBODY_USER_NAME, "nobody");
+14 -2
View File
@@ -132,6 +132,18 @@ typedef enum UserRecordLoadFlags {
USER_RECORD_STRIP_BINDING |
USER_RECORD_STRIP_STATUS,
USER_RECORD_LOAD_MASK_PRIVILEGED = USER_RECORD_REQUIRE_REGULAR|
USER_RECORD_STRIP_PRIVILEGED|
USER_RECORD_ALLOW_PER_MACHINE|
USER_RECORD_ALLOW_BINDING|
USER_RECORD_ALLOW_SIGNATURE,
USER_RECORD_EXTRACT_PRIVILEGED = USER_RECORD_STRIP_REGULAR|
USER_RECORD_ALLOW_PRIVILEGED|
USER_RECORD_STRIP_PER_MACHINE|
USER_RECORD_STRIP_BINDING|
USER_RECORD_STRIP_SIGNATURE,
/* Whether to log about loader errors beyond LOG_DEBUG */
USER_RECORD_LOG = 1U << 28,
@@ -477,8 +489,8 @@ int user_record_masked_equal(UserRecord *a, UserRecord *b, UserRecordMask mask);
int user_record_test_blocked(UserRecord *h);
int user_record_test_password_change_required(UserRecord *h);
int user_record_is_root(const UserRecord *u);
int user_record_is_nobody(const UserRecord *u);
bool user_record_is_root(const UserRecord *u);
bool user_record_is_nobody(const UserRecord *u);
/* The following six are user by group-record.c, that's why we export them here */
int json_dispatch_realm(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata);