Bug#1030262: gnome-control-center: User deleted via "gnome-control-center user-accounts" can still login
Simon McVittie
smcv at debian.org
Wed Feb 1 22:32:40 GMT 2023
On Wed, 01 Feb 2023 at 21:07:09 +0000, Simon McVittie wrote:
> Looking briefly at the gnome-control-center code, I think this indicates
> that act_user_is_local_account() is returning false, so instead of deleting
> a local user, gnome-control-center is telling accountsservice to
> "uncache" a remotely-managed (enterprise) user? I don't know what practical
> effect that has, but it doesn't sound like a true "delete" operation?
This seems to be a side-effect of new user accounts accidentally being
created with nologin as their shell (#1030253). This indirectly makes
accountsservice, and therefore gnome-control-center, think that it's
a remotely-managed account (from LDAP or equivalent).
When accountsservice reads /etc/passwd and /etc/shadow, it ignores local
accounts that do not appear to belong to a "human" user (this includes
accounts with nologin as their shell, among others). (It also ignores
local human users above an arbitrary limit of 50, to avoid having a
ridiculously long list.)
However, there are several reasons why accountsservice might have a user
account in its in-memory list, and one of those reasons is that it recently
created the account itself. The accounts listed in its D-Bus API are the
union of everything it has found from multiple sources.
When accountsservice is deciding whether an account is local, it assumes
that the only accounts that are local are the ones in its list of accounts
from /etc/shadow, after filtering. Pseudocode:
local = empty set
interesting = empty set
for account in /etc/shadow:
if account appears human and number of accounts found so far < 50:
local.add(account)
interesting.add(account)
for account in other sources:
interesting.add(account)
for account in interesting:
account.LocalAccount = bool(account in local)
return interesting
I think this is a bug. It should look more like this pseudocode:
local = empty set
interesting = empty set
for account in /etc/shadow:
local.add(account)
if account appears human and number of accounts found so far < 50:
interesting.add(account)
for account in other sources:
interesting.add(account)
for account in interesting:
account.LocalAccount = bool(account in local)
return interesting
or maybe even:
interesting = empty set
for account in /etc/shadow:
if account appears human and number of accounts found so far < 50:
interesting.add(account)
for account in other sources:
interesting.add(account)
for account in interesting:
account.LocalAccount = (getspnam(account.UserName) != NULL)
return interesting
gnome-control-center is not exactly helping here, by not having a
particularly clear indication of whether it thinks an account is local
or remote, and using the same button for deleting a local account (which
literally does delete the account) and removing a remote account from the
cache (which just forgets about the account as being locally relevant,
but does not attempt to delete it from LDAP or whatever remote accounts
database it's using). This is not ideal, but I don't think it's RC
for gnome-control-center.
Meanwhile, gdm3 only lists accountsservice accounts (local or remote)
in its GUI, but lets other accounts log in via "Not listed?". Because
accountsservice wrongly thinks your account is remote, and you used
gnome-control-center to remove the "remote" account from the cache
of interesting accounts, gdm3 stopped listing it.
However, it's still possible to log in with that account, because gdm3
doesn't check whether users' shells are listed in /etc/shells or not.
(Should it? Other entry-point services don't, except indirectly by trying
to run the user's shell and having nologin fail as a result.)
smcv
More information about the pkg-gnome-maintainers
mailing list