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