Bug#1118640: libnss-systemd: Not configured for shadow/gshadow when upgraded from Debian 11 or older
Simon McVittie
smcv at debian.org
Thu Oct 23 11:27:21 BST 2025
Package: libnss-systemd
Version: 251.3-2
Severity: important
This was previously discussed on gdm3 bug #1116563, but I'm reporting it
here to have a clear statement of the issue in libnss-systemd.
If libnss-systemd is installed on Debian 12 or newer, it handles four
nsswitch databases: passwd, group, shadow and gshadow. The bug is that
if libnss-systemd was originally installed on a Debian 11 or older
system, and subsequently upgraded to Debian 12 or newer, it will only
handle passwd and group. This breaks packages like gdm3 which want to be
able to look up their dynamically-created users in the shadow and gshadow
databases (#1116563).
Steps to reproduce
==================
Unfortunately this involves "going back in time" since it's a divergence
between upgraded systems and fresh installations.
I acknowledge that we don't directly support Debian 11 any more, but
many Debian systems will have been installed with Debian 11 or older and
subsequently upgraded in the supported way (11 -> 12 -> 13 -> ...) and
this issue will affect those systems.
$ autopkgtest-build-qemu bullseye ~/tmp/d11.qcow2
(or use some other small VM image or non-overlayfs-based container)
(run the VM and log in, it has a passwordless root shell on tty1)
# apt update
# apt install libnss-systemd
# sed -i -e 's/bullseye/bookworm/g' -e 's/archive.debian.org/deb.debian.org/g' /etc/apt/sources.list
# apt update
# apt dist-upgrade
# reboot
(log back in)
# sed -i -e 's/bookworm/trixie/g' -e 's/archive.debian.org/deb.debian.org/g' /etc/apt/sources.list
# apt update
# apt dist-upgrade
# reboot
(log back in)
(optionally upgrade again, from trixie to forky or sid)
# cat /etc/nsswitch.conf
# apt install atftpd # a convenient DynamicUser
# systemctl start atftpd
# grep atftpd /etc/passwd /etc/group /etc/shadow /etc/gshadow || echo not found
not found
# getent passwd atftpd
atftpd:(etc.)
# getent group atftpd
atftpd:(etc.)
# getent shadow atftpd
(should have a record, does not, this is the bug)
# getent gshadow atftpd
(should have a record, does not, this is the bug)
and to compare with a fresh system:
$ autopkgtest-build-qemu trixie ~/tmp/d13.qcow2
(or use some other small VM image or container)
(run the VM and log in, it has a passwordless root shell on tty1)
# apt update
# apt install libnss-systemd
# cat /etc/nsswitch.conf
# apt install atftpd # a convenient DynamicUser
# systemctl start atftpd
# grep atftpd /etc/passwd /etc/group /etc/shadow /etc/gshadow || echo not found
not found
# getent passwd atftpd
atftpd:(etc.)
# getent group atftpd
atftpd:(etc.)
# getent shadow atftpd
atftpd:(etc.)
# getent gshadow atftpd
atftpd:(etc.)
Expected result
===============
On both the fresh install and the upgraded system, "systemd" should
appear in the list of modules used to resolve all four of the
user-related databases: passwd, group, shadow and gshadow.
The atftpd dynamic user should appear when querying all four databases,
despite not being in any of the flat files.
Actual result
=============
On the fresh install, the four user-related databases are as expected:
passwd: files systemd
group: files systemd
shadow: files systemd
gshadow: files systemd
but on the upgraded system, libnss-systemd is missing from the shadow
and gshadow databases:
passwd: files systemd
group: files systemd
shadow: files
gshadow: files
As a result, "getent passwd atftpd" and "getent group atftpd" work as
expected, but "getent shadow atftpd" and "getent gshadow atftpd" fail.
Suggested solution
==================
https://bugs.debian.org/1113745 argues that this is a dh-nss bug, but
that bug has been marked wontfix, so unfortunately it will have to be up
to each NSS module to work around that limitation by doing its own
upgrade logic.
On upgrading to some threshold version - let's say $V - the maintainer
scripts for libnss-systemd should have logic like this pseudocode, to do
a one-time upgrade action:
if this is an upgrade, current version << $V:
if nsswitch.conf doesn't have /^shadow:.*\<systemd\>/:
add systemd to the shadow: line in an appropriate position
if nsswitch.conf doesn't have /^gshadow:.*\<systemd\>/:
add systemd to the shadow: line in an appropriate position
or perhaps what Ubuntu 25.10 has done:
if this is an upgrade, current version << $V:
completely remove systemd from nsswitch.conf
#DEBHELPER# # let dh-nss put it back, with the new config
Because we don't support skipping stable releases, this can be removed
after version $V or later has appeared in a stable release (ideally also
an Ubuntu LTS release).
In an ideal world, $V would have been the same version that added
systemd to the shadow and gshadow databases (251.3-2), but in the
absence of a time machine, we can no longer implement that.
The next best thing is for $V to be the first version uploaded to
unstable with that logic.
More generally, every time there is a future change to how an nss module
is registered in nsswitch.conf (not just libnss-systemd, but also
libnss-myhostname, etc.), if the change is functionally significant, it
should come with a one-time upgrade action in the maintainer scripts
that makes upgraded systems match the new configuration.
Impact
======
This is the root cause of #1116563 in gdm3, which is the last remaining
blocker for the GNOME 49 transition (#1116394). If there isn't a
straightforward solution in libnss-systemd, I'll investigate whether we
can work around it in gdm3.
It could also affect any other system service that creates dynamic users
and relies on being able to look up their shadow record (password hash,
password expiry, etc.), or creates dynamic groups and relies on being
able to look up their gshadow record.
Ordinary static system users and groups (sysusers.d or adduser) are
unaffected.
Out of scope
============
In https://salsa.debian.org/systemd-team/systemd/-/merge_requests/293,
Marco proposes that instead of systemd being ordered last, it should be
ordered immediately after 'files', possibly with
'files [SUCCESS=merge] systemd', to better match upstream's
recommendations. For example, this might make libnss-systemd
higher-precedence than LDAP or similar services, where it would
currently be lower-precedence.
Strictly speaking this is orthogonal to solving the bug described here.
However, if this bug is solved in systemd version $X, and then Marco's
suggestion is subsequently implemented in systemd version $Y (> $X),
then the reasoning above implies that the maintainer script will now
need to handle more scenarios:
- new installation, no configuration (dh-nss handles this)
- upgrading, current version << $X
- upgrading, $X <= current version << $Y
- upgrading, current version >= $Y (no action needed)
and leave nsswitch configured appropriately in each of those scenarios.
So if we are sure that what Marco proposes is the right thing to do, it
might be simpler to batch together the change Marco requested and the
fix for this bug into the same systemd upload.
smcv
More information about the Pkg-systemd-maintainers
mailing list