From: Yu Watanabe Date: Sat, 3 Jan 2026 03:46:56 +0000 (+0900) Subject: core: do not provide non-dynamic user through DBus/Varlink X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cb39d66ec837dc36b4f6719f15e7573a6fc68ce6;p=thirdparty%2Fsystemd.git 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. --- diff --git a/src/core/dynamic-user.c b/src/core/dynamic-user.c index f3d059e1bea..9d7d96e4a37 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; + + if (!uid_is_dynamic(uid)) + return -ESRCH; - return r; + 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 cdf5fa86933..e200e16fcfc 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 e166195ef7d..e31c6553d52 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"