From cb39d66ec837dc36b4f6719f15e7573a6fc68ce6 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sat, 3 Jan 2026 12:46:56 +0900 Subject: [PATCH] core: do not provide non-dynamic user through DBus/Varlink With a service with DynamicUser= with static user or group, e.g., ``` $ systemd-run -p DynamicUser=yes -p Group=disk sleep infinity ``` previously the lookup by name and ID through DBus/Varlink are inconsistent: ``` $ busctl call org.freedesktop.systemd1 /org/freedesktop/systemd1 org.freedesktop.systemd1.Manager LookupDynamicUserByUID "u" 6 Call failed: Dynamic user ID 6 does not exist. $ busctl call org.freedesktop.systemd1 /org/freedesktop/systemd1 org.freedesktop.systemd1.Manager LookupDynamicUserByName "s" disk u 6 $ userdbctl group 6 Group name: disk Disposition: system GID: 6 Passwords: 1 Service: io.systemd.NameServiceSwitch $ userdbctl group disk Group name: disk Disposition: dynamic GID: 6 Description: Dynamic Group Service: io.systemd.DynamicUser ``` With this change, the results of these methods are consistent. Fixes #40228. --- src/core/dynamic-user.c | 13 +++++++++++-- src/core/varlink-dynamic-user.c | 7 +++++++ test/units/TEST-74-AUX-UTILS.userdbctl.sh | 10 ++++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/core/dynamic-user.c b/src/core/dynamic-user.c index f3d059e1be..9d7d96e4a3 100644 --- a/src/core/dynamic-user.c +++ b/src/core/dynamic-user.c @@ -695,11 +695,20 @@ int dynamic_user_lookup_name(Manager *m, const char *name, uid_t *ret) { if (!d) return -ESRCH; - r = dynamic_user_current(d, ret); + uid_t uid; + r = dynamic_user_current(d, &uid); if (r == -EAGAIN) /* not realized yet? */ return -ESRCH; + if (r < 0) + return r; - return r; + if (!uid_is_dynamic(uid)) + return -ESRCH; + + if (ret) + *ret = uid; + + return 0; } int dynamic_creds_make(Manager *m, const char *user, const char *group, DynamicCreds **ret) { diff --git a/src/core/varlink-dynamic-user.c b/src/core/varlink-dynamic-user.c index cdf5fa8693..e200e16fcf 100644 --- a/src/core/varlink-dynamic-user.c +++ b/src/core/varlink-dynamic-user.c @@ -7,6 +7,7 @@ #include "json-util.h" #include "manager.h" #include "string-util.h" +#include "uid-classification.h" #include "user-util.h" #include "varlink-dynamic-user.h" @@ -91,6 +92,9 @@ int vl_method_get_user_record(sd_varlink *link, sd_json_variant *parameters, sd_ if (r < 0) return r; + if (!uid_is_dynamic(uid)) + continue; + if (!user_match_lookup_parameters(&p, d->name, uid)) continue; @@ -199,6 +203,9 @@ int vl_method_get_group_record(sd_varlink *link, sd_json_variant *parameters, sd if (r < 0) return r; + if (!gid_is_dynamic((gid_t) uid)) + continue; + if (!group_match_lookup_parameters(&p, d->name, (gid_t) uid)) continue; diff --git a/test/units/TEST-74-AUX-UTILS.userdbctl.sh b/test/units/TEST-74-AUX-UTILS.userdbctl.sh index e166195ef7..e31c6553d5 100755 --- a/test/units/TEST-74-AUX-UTILS.userdbctl.sh +++ b/test/units/TEST-74-AUX-UTILS.userdbctl.sh @@ -59,3 +59,13 @@ if [[ ! -v ASAN_OPTIONS ]]; then assert_rc 2 systemd-run -q -t --property SystemCallFilter=~open_tree getent group definitelynotarealgroup systemctl start systemd-userdbd.socket systemd-userdbd.service fi + +# For issue 40228 +UNIT="sleep$RANDOM" +DISK_GID=$(userdbctl -j group disk | jq .gid) +systemd-run -p DynamicUser=yes -p Group=disk -u "$UNIT" sleep infinity +userdbctl group disk | grep -F 'io.systemd.NameServiceSwitch' >/dev/null +userdbctl group "$DISK_GID" | grep -F 'io.systemd.NameServiceSwitch' >/dev/null +(! busctl call org.freedesktop.systemd1 /org/freedesktop/systemd1 org.freedesktop.systemd1.Manager LookupDynamicUserByName "s" disk) +(! busctl call org.freedesktop.systemd1 /org/freedesktop/systemd1 org.freedesktop.systemd1.Manager LookupDynamicUserByUID "u" "$DISK_GID") +systemctl stop "$UNIT"