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)
This commit is contained in:
lucia-huang7
2026-10-16 17:24:51 +01:00
committed by Luca Boccassi
parent bc171ac92e
commit 3b1c9a13df
2 changed files with 19 additions and 2 deletions
+2 -1
View File
@@ -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(
+17 -1
View File
@@ -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'