nm-sudo and nm-dispatcher are very similar from a high level. Both are D-Bus activated
services that exit on idle and all they do, is to provide a simple D-Bus API with no
objects or properties.
Hence it's not surprising that they follow the same structure.
Rename the code to make them look more similar.
Currently we only implmement two operations (Ping() and GetFD()). Both
complete right away. There is no need to register a pending job, if
the job does not get processed asynchronously.
In the future, we may have methods that need asynchronous processing
and where we need to register them as pending job.
If we fail to acquire the well-known name or if we already released it,
we must not accept anymore new requests.
Otherwise, requests directly targeted to the unique name will keep the
process alive, and prevent it from restarting (and serving the
well-known name). Clients really should not talk to the unique name of a
service that exits on idle. If they do, and the service is about to shut
down, then the request will be rejected. After we released the name,
there is now turning back and we should quit fast (only processing the
requests we already have).
Also, if we receive a SIGTERM, then we are requested to quit and should
do so in a timely manner. That means, we will start with releasing the
name. As the service is D-Bus activated, new requests can be served by
the next instance (or if the service is about to be disabled altogether,
they will start failing).
GDBus will invoke the method_call callback also for the Get/Set
functions. Thus, we need to check the interface_name and handle
them (actually, there is nothing to handle, no properties exist).
Also, "Ping" method only exists for testing. It is usually not called
in production, so check for "GetFD" first.
To talk to ovsdb, we use the unix socket at
/var/run/openvswitch/db.sock. But that socket is owned by another user
and NetworkManager would need dac_override capability to open it.
We want to drop dac_override, but we still need to talk to ovsdb. Add a
GetFD() method to nm-sudo.
We still first try to open the socket directly. Maybe it just works.
Note that SELinux may block passing file descriptors from nm-sudo. If it
doesn't work for you, test with SELinux permissive mode and wait for an
SELinux update.
NetworkManager runs as root and has lots of capabilities.
We want to reduce the attach surface by dropping capabilities,
but there is a genuine need to do certain things.
For example, we currently require dac_override capability, to open
the unix socket of ovsdb. Most users wouldn't use OVS, so we should
find a way to not require that dac_override capability. The solution
is to have a separate, D-Bus activate service (nm-sudo), which
has the capability to open and provide the file descriptor.
For authentication, we only rely on D-Bus. We watch the name owner
of NetworkManager, and only accept requests from that service. We trust
D-Bus to get it right a request from that name owner is really coming
from NetworkManager. If we couldn't trust that, how could PolicyKit
or any authentication via D-Bus work? For testing, the user can set
NM_SUDO_NO_AUTH_FOR_TESTING=1.
https://bugzilla.redhat.com/show_bug.cgi?id=1921826