[RFC] specification extension: ConnectClient()
@tomegun
Submitted by Tom Gundersen Assigned to D-Bus Maintainers
Link to original bug (#107245)
Description
This is a follow-up on the discussion in https://github.com/systemd/systemd/issues/9503.
I want to suggest adding a new call, ConnectClient() to the org.freedesktop.DBus interface. The intention behind this is to allow a (privileged) client to connect and claim names on behalf of another (unprivileged) one.
The discussion that precipitated this was the desire to allow PID1 to spawn dbus-clients running as a dynamic user, without having to update the DBus policy dynamically to allow these new users to connect and claim names on the bus.
The proposed API extension would allow PID1 to tell dbus daemon to connect the new client, acquire for it a set of given names, and pin in it its dynamic (unprivileged) credentials, but to use PID1's (privileged) credentials for the policy checks when deciding if the client is allowed to be connected and to acquire the names.
This would solve the immediate problem at hand of dynamic users, but it would also allow other features:
- Scheduling of well-known names
Currently, if a name is activatable, it is always activatable. There is no way of delaying the availability of a name, or making a name no longer activatable. Short of delaynig the start-up of the whole bus, or shutting the bus down.
- Socket activation of DBus clients
Allowing DBus clients to be socket-activated is both a simpler scheme than the current name activation, but it would also allow for proper exit-on-idle, which name activation does not allow (without potentially dropping messages).
- Simplification of XML policy
This is obviously up to the implementers, but this scheme would long-term allow systems without own/user/group directives. And as send_* recv_* directives are already not strictly speaking necessary (one could use polkit instead), this could in the future allow for greatly simplified policies in the common case.
Suggested API (based on suggestion by David Herrmann):
`org.freedesktop.DBus.ConnectClient(h socket, a{sv} args) -> (s unique_name);
This pre-connects, pre-authenticates, and prepares an AF_UNIX socket for use as a D-Bus connection. The socket is taken as input rather than output, to guarantee that the owning-uid/creds are correct. If the socket is not AF_UNIX+SOCK_STREAM+unconnected, the call simply fails.
The args parameter can be extended in the future to modify this call. Examples:
`RequestNames`: Takes a string array as argument; specifies which names are pre-acquired by the client.
`AllowUnixFds`: Set the ALLOW_UNIX_FDS flag for the new connection.
The message daemon makes this call available to everyone, but verifies the caller (not the passed in client socket) is allowed to connect and claim the names specified in RequestNames
.
Note that it isn't expected that existing clients connecting in the traditional way can necessarily be ported over to this new API without further notification. As pointed out by smcv in the above bug, care must be taken with the fact that names are claimed before the client has been initialized. In the common case this shouldn't make a difference, and in the case a client needs to make calls on the bus before processing incomming method calls on its names, it would either have to buffer messages, or use a separate connection to the bus for the initialization before starting to process the main connection (much could be said on that topic, I'm just mentioning it briefly here to note that it is on the radar).
If we agree that we want something like this and on a basic design, I'm happy to write it up as a patch to the spec.