]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: do not provide non-dynamic user through DBus/Varlink
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sat, 3 Jan 2026 03:46:56 +0000 (12:46 +0900)
committerMike Yuan <me@yhndnzj.com>
Sat, 3 Jan 2026 18:57:44 +0000 (19:57 +0100)
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
src/core/varlink-dynamic-user.c
test/units/TEST-74-AUX-UTILS.userdbctl.sh

index f3d059e1beafc253c2b94a292d5d108e4c0f0506..9d7d96e4a37ac24aa9b05160d3ab9b209fc826d5 100644 (file)
@@ -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) {
index cdf5fa86933a70fadf8a48a404e10599f4c8db68..e200e16fcfc93d8b1cb2845bf7d9773ec849db58 100644 (file)
@@ -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;
 
index e166195ef7db5fca5607d41bb69c6368ba275b24..e31c6553d52501e82ce33b6bbe06133bd78cb4aa 100755 (executable)
@@ -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"