[systemd-devel] Some questions on userdbd and providing a compatible service
Lennart Poettering
lennart at poettering.net
Thu Nov 24 11:18:17 UTC 2022
On Do, 24.11.22 00:58, Dominik George (nik at naturalnet.de) wrote:
> Hi,
>
> for some time now, I have been investigating how to best make a
> desktop system talk to a web API (HTTP, REST) for user management, so
> NSS and PAM make HTTP requests to an API to verify authentication
> (using OIDC) and to retrieve NIS information (using REST endpoints).
>
> One of the approaches I am evaluating involves systemd-userdbd,
> because it seems to be designed with extensibility with modular
> service implementations in mind.
That would make a lot of sense to me.
> Right now, I have a few questions concerning its architecture and use:
>
> * Why was Varlink chosen over D-Bus, given that most other parts of
> systemd seem to talk D-Bus?
Three reasons:
1. We want this to work in early boot, i.e. before dbus-daemon is up
2. dbus-daemon policies involve user names, thus dbus-daemon must be
able to resolve them, and this deadlocks if dbus-daemon is used as
transport for the resolution requests dbus-daemon itself makes.
3. D-Bus is suitable for transmitting control data only. It puts
limits on queued messages, and thus is not suitable to transfer
bulk data. This means it's kinda unsuitable for doing things like a
dump of a user database, which might have millions of entries. If
we'd ignore that fact, then whenever the user would try to dump the
user databsae userdbd would be forcibly kicked off the bus, under
the assumption it tried to flood the bus.
Every single one of the three is a killer really. using varlink avoids
that mess, it requires no broker, is efficient for transferring bulk
data, and works from any context.
(There are other reasons: for example we want user records to be json
objects, and it's just a lot nicer if json is passed around over a
json-based IPC then nesting it inside of dbus marshalling. But hese
are "softer" reasons, so I'll spare you the rest)
> * How does protection of privileged fields work? In a different
> approach (using my own gRPC-based protocol), I used peer
> credentials on the UNIX socket for authorisation, but it seems this
> should break with userdbd when going through the
> multipelxer. However, I see "Warning: lacking rights to acquire
> privileged fields of user record of 'testnik', output incomplete."
> when I try to inspect another user as an unprivileged user. How
> does userdbd determine that?
See:
https://systemd.io/USER_RECORD/
Basically, a user record consist of multiple sections (i.e. json
fields contain subobjects), one is called "privileged": this contains
everything traditionally found in /etc/shadow basically, and
everything else pretty much that should only be visible to privileged
users and the user itself.
Any IPC service is supposed to strip "privileged" from user records it
sends or passes on, and report that in the "incomplete" boolean return
parameter – unless it can know for sure (via SO_PEERCRED or so) that
whoever it is talking to is the user itself or is privileged.
See this for details on the IPC API: https://systemd.io/USER_GROUP_API/
> * userdbd only helps for user information, i.e. for providing data to
> NSS through a decoupled interface. I would need to do the same for
> PAM, but intil now, I could not find an existing standard for
> verifying credentials. Was that just not done yet, or is there a
> design decision that userdbd should not offer methods for
> authentication? I see that systemd-homed implements its own API
> through D-Bus…
Yeah, you have to deal with PAM yourself (unless you add classic
hashed UNIX passwords in the "privileged" section of your use records
– in that case pam_unix will just use that).
One of these days people should revisit PAM and redesign it around
IPC, but today is not that day I fear.
> * Ultimately, I would like to retrieve and store an OAuth token on
> user login. It would somehow be a good fit for the "secret" section
> of the User Record, but the fields allowed in it seem to be
> static. Are there any ideas around here where such a token could be
> stored during the user session?
Kernel keyring for the user? It's where kerberos stuff is stored, and
is probably the best place. The API is a bit convoluted, but this has
been done before.
Lennart
--
Lennart Poettering, Berlin
More information about the systemd-devel
mailing list