From 3b1c9a13df1deda907ce744888e3d9e17290bfbd Mon Sep 17 00:00:00 2001 From: lucia-huang7 <226875132+lucia-huang7@users.noreply.github.com> Date: Tue, 13 Oct 2026 23:26:42 -0500 Subject: [PATCH] userdb: filter both keys in membership queries GetMemberships with both keys only filtered groupName and could return other members. Reproduce with a non-member and a group that has members: varlinkctl call --more SOCKET io.systemd.UserDatabase.GetMemberships '{"userName":"nonmember","groupName":"GROUP","service":"io.systemd.Multiplexer"}' (cherry picked from commit 2126abeb6d4905f95b963c7f5c5bc4bd92444ba5) --- src/userdb/userwork.c | 3 ++- test/units/TEST-74-AUX-UTILS.varlinkctl.sh | 18 +++++++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/userdb/userwork.c b/src/userdb/userwork.c index fa06a49b26..64e425e45a 100644 --- a/src/userdb/userwork.c +++ b/src/userdb/userwork.c @@ -430,7 +430,8 @@ static int vl_method_get_memberships(sd_varlink *link, sd_json_variant *paramete return r; /* If both group + user are specified do a-posteriori filtering */ - if (p.group_name && p.user_name && !streq(group_name, p.group_name)) + if (p.group_name && p.user_name && + (!streq(user_name, p.user_name) || !streq(group_name, p.group_name))) continue; r = sd_varlink_replybo( diff --git a/test/units/TEST-74-AUX-UTILS.varlinkctl.sh b/test/units/TEST-74-AUX-UTILS.varlinkctl.sh index ed2e0cb73b..9b807810ee 100755 --- a/test/units/TEST-74-AUX-UTILS.varlinkctl.sh +++ b/test/units/TEST-74-AUX-UTILS.varlinkctl.sh @@ -53,6 +53,22 @@ if command -v userdbctl >/dev/null; then varlinkctl call --oneway /run/systemd/userdb/io.systemd.Multiplexer io.systemd.UserDatabase.GetMemberships '{ "service" : "io.systemd.Multiplexer" }' (! varlinkctl call --oneway /run/systemd/userdb/io.systemd.Multiplexer io.systemd.UserDatabase.GetMemberships '{ "service" : "io.systemd.Multiplexer" }' | grep .) + mkdir -p /run/userdb + membership=/run/userdb/test-74-member:test-74-group.membership + touch "$membership" + trap 'rm -f "$membership"' EXIT + member_reply="$(varlinkctl call -j /run/systemd/userdb/io.systemd.Multiplexer \ + io.systemd.UserDatabase.GetMemberships \ + '{"userName":"test-74-member","groupName":"test-74-group","service":"io.systemd.Multiplexer"}')" + test "$(jq -r .userName <<<"$member_reply")" = test-74-member + test "$(jq -r .groupName <<<"$member_reply")" = test-74-group + nonmember_reply="$(varlinkctl call --graceful=io.systemd.UserDatabase.NoRecordFound -j \ + /run/systemd/userdb/io.systemd.Multiplexer \ + io.systemd.UserDatabase.GetMemberships \ + '{"userName":"test-74-nonmember","groupName":"test-74-group","service":"io.systemd.Multiplexer"}')" + test -z "$nonmember_reply" + rm "$membership" + if command -v openssl >/dev/null && command -v groupadd >/dev/null; then group=haldo salt=waldo @@ -103,7 +119,7 @@ rm_rf_sshbindir() { rm -rf "$SSHBINDIR" } -trap rm_rf_sshbindir EXIT +trap 'rm -f "${membership:-}"; rm_rf_sshbindir' EXIT # Create a fake "ssh" binary that validates everything works as expected if invoked for the "ssh-unix:" Varlink transport cat >"$SSHBINDIR"/ssh <<'EOF'