sudo: introduce nm-sudo D-Bus service
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
2021-07-18 08:53:43 +02:00
|
|
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
|
|
|
|
|
|
|
|
|
#include "libnm-glib-aux/nm-default-glib-i18n-prog.h"
|
|
|
|
|
|
2021-07-21 16:31:48 +02:00
|
|
|
#include <gio/gunixfdlist.h>
|
|
|
|
|
|
sudo: introduce nm-sudo D-Bus service
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
2021-07-18 08:53:43 +02:00
|
|
|
#include "c-list/src/c-list.h"
|
2021-08-04 11:53:30 +02:00
|
|
|
#include "libnm-base/nm-sudo-utils.h"
|
2021-08-02 22:30:47 +02:00
|
|
|
#include "libnm-glib-aux/nm-dbus-aux.h"
|
|
|
|
|
#include "libnm-glib-aux/nm-io-utils.h"
|
sudo: introduce nm-sudo D-Bus service
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
2021-07-18 08:53:43 +02:00
|
|
|
#include "libnm-glib-aux/nm-logging-base.h"
|
|
|
|
|
#include "libnm-glib-aux/nm-shared-utils.h"
|
|
|
|
|
#include "libnm-glib-aux/nm-time-utils.h"
|
|
|
|
|
|
|
|
|
|
/* nm-sudo doesn't link with libnm-core nor libnm-base, but these headers
|
|
|
|
|
* can be used independently. */
|
|
|
|
|
#include "libnm-core-public/nm-dbus-interface.h"
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
#define IDLE_TIMEOUT_MSEC 2000
|
|
|
|
|
#define IDLE_TIMEOUT_INFINITY G_MAXINT32
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
/* Serves only the purpose to mark environment variables that are honored by
|
|
|
|
|
* the application. You can search for this macro, and find what options are supported. */
|
|
|
|
|
#define _ENV(var) ("" var "")
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
typedef struct _GlobalData GlobalData;
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
|
CList pending_jobs_lst;
|
|
|
|
|
GlobalData *gl;
|
|
|
|
|
} PendingJobData;
|
|
|
|
|
|
|
|
|
|
struct _GlobalData {
|
|
|
|
|
GDBusConnection *dbus_connection;
|
2021-08-04 11:53:30 +02:00
|
|
|
GCancellable * quit_cancellable;
|
|
|
|
|
|
|
|
|
|
GSource *source_sigterm;
|
sudo: introduce nm-sudo D-Bus service
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
2021-07-18 08:53:43 +02:00
|
|
|
|
|
|
|
|
CList pending_jobs_lst_head;
|
|
|
|
|
|
|
|
|
|
GSource *source_idle_timeout;
|
2021-08-04 11:53:30 +02:00
|
|
|
|
|
|
|
|
char *name_owner;
|
|
|
|
|
|
|
|
|
|
gint64 start_timestamp_msec;
|
|
|
|
|
|
|
|
|
|
guint name_owner_changed_id;
|
|
|
|
|
guint service_regist_id;
|
|
|
|
|
|
|
|
|
|
guint32 timeout_msec;
|
|
|
|
|
|
|
|
|
|
bool name_owner_initialized;
|
sudo: introduce nm-sudo D-Bus service
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
2021-07-18 08:53:43 +02:00
|
|
|
|
|
|
|
|
/* This is controlled by $NM_SUDO_NO_AUTH_FOR_TESTING. It disables authentication
|
|
|
|
|
* of the request, so it is ONLY for testing. */
|
|
|
|
|
bool no_auth_for_testing;
|
|
|
|
|
|
2021-08-04 11:53:30 +02:00
|
|
|
bool name_requested;
|
nm-sudo: reject new request once we have no well-known-name
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).
2021-08-04 10:50:37 +02:00
|
|
|
bool reject_new_requests;
|
|
|
|
|
|
2021-08-04 11:53:30 +02:00
|
|
|
bool shutdown_quitting;
|
|
|
|
|
bool shutdown_timeout;
|
sudo: introduce nm-sudo D-Bus service
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
2021-07-18 08:53:43 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
static void _pending_job_register_object(GlobalData *gl, GObject *obj);
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2021-08-03 09:43:31 +02:00
|
|
|
#define _nm_log(level, ...) _nm_log_simple_printf((level), __VA_ARGS__)
|
sudo: introduce nm-sudo D-Bus service
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
2021-07-18 08:53:43 +02:00
|
|
|
|
|
|
|
|
#define _NMLOG(level, ...) \
|
|
|
|
|
G_STMT_START \
|
|
|
|
|
{ \
|
|
|
|
|
const NMLogLevel _level = (level); \
|
|
|
|
|
\
|
|
|
|
|
if (_nm_logging_enabled(_level)) { \
|
|
|
|
|
_nm_log(_level, __VA_ARGS__); \
|
|
|
|
|
} \
|
|
|
|
|
} \
|
|
|
|
|
G_STMT_END
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
_handle_ping(GlobalData *gl, GDBusMethodInvocation *invocation, const char *arg)
|
|
|
|
|
{
|
|
|
|
|
gs_free char *msg = NULL;
|
|
|
|
|
gint64 running_msec;
|
|
|
|
|
|
|
|
|
|
running_msec = nm_utils_clock_gettime_msec(CLOCK_BOOTTIME) - gl->start_timestamp_msec;
|
|
|
|
|
|
2021-07-26 18:08:24 +02:00
|
|
|
msg = g_strdup_printf("pid=%lu, unique-name=%s, nm-name-owner=%s, since=%" G_GINT64_FORMAT
|
|
|
|
|
".%03d%s, pong=%s",
|
sudo: introduce nm-sudo D-Bus service
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
2021-07-18 08:53:43 +02:00
|
|
|
(unsigned long) getpid(),
|
|
|
|
|
g_dbus_connection_get_unique_name(gl->dbus_connection),
|
|
|
|
|
gl->name_owner ?: "(none)",
|
2021-07-26 18:08:24 +02:00
|
|
|
(gint64) (running_msec / 1000),
|
sudo: introduce nm-sudo D-Bus service
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
2021-07-18 08:53:43 +02:00
|
|
|
(int) (running_msec % 1000),
|
|
|
|
|
gl->no_auth_for_testing ? ", no-auth-for-testing" : "",
|
|
|
|
|
arg);
|
|
|
|
|
g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", msg));
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-21 16:31:48 +02:00
|
|
|
static void
|
|
|
|
|
_handle_get_fd(GlobalData *gl, GDBusMethodInvocation *invocation, guint32 fd_type)
|
|
|
|
|
{
|
|
|
|
|
nm_auto_close int fd = -1;
|
|
|
|
|
gs_unref_object GUnixFDList *fd_list = NULL;
|
|
|
|
|
gs_free_error GError *error = NULL;
|
|
|
|
|
|
|
|
|
|
if (fd_type != (NMSudoGetFDType) fd_type)
|
|
|
|
|
fd_type = NM_SUDO_GET_FD_TYPE_NONE;
|
|
|
|
|
|
|
|
|
|
fd = nm_sudo_utils_open_fd(fd_type, &error);
|
|
|
|
|
if (fd < 0) {
|
|
|
|
|
g_dbus_method_invocation_take_error(invocation, g_steal_pointer(&error));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fd_list = g_unix_fd_list_new_from_array(&fd, 1);
|
|
|
|
|
nm_steal_fd(&fd);
|
|
|
|
|
|
|
|
|
|
g_dbus_method_invocation_return_value_with_unix_fd_list(invocation, NULL, fd_list);
|
|
|
|
|
}
|
|
|
|
|
|
sudo: introduce nm-sudo D-Bus service
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
2021-07-18 08:53:43 +02:00
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
_signal_callback_term(gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
GlobalData *gl = user_data;
|
|
|
|
|
|
|
|
|
|
_LOGD("sigterm received (%s)",
|
|
|
|
|
c_list_is_empty(&gl->pending_jobs_lst_head) ? "quit mainloop" : "cancel operations");
|
|
|
|
|
|
2021-08-04 11:53:30 +02:00
|
|
|
gl->shutdown_quitting = TRUE;
|
sudo: introduce nm-sudo D-Bus service
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
2021-07-18 08:53:43 +02:00
|
|
|
g_cancellable_cancel(gl->quit_cancellable);
|
|
|
|
|
return G_SOURCE_CONTINUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
static GDBusConnection *
|
|
|
|
|
_bus_get(GCancellable *cancellable, int *out_exit_code)
|
|
|
|
|
{
|
|
|
|
|
gs_free_error GError *error = NULL;
|
|
|
|
|
gs_unref_object GDBusConnection *dbus_connection = NULL;
|
|
|
|
|
|
2021-08-03 10:08:30 +02:00
|
|
|
dbus_connection = nm_g_bus_get_blocking(cancellable, &error);
|
sudo: introduce nm-sudo D-Bus service
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
2021-07-18 08:53:43 +02:00
|
|
|
|
|
|
|
|
if (!dbus_connection) {
|
|
|
|
|
gboolean was_cancelled = nm_utils_error_is_cancelled(error);
|
|
|
|
|
|
|
|
|
|
NM_SET_OUT(out_exit_code, was_cancelled ? EXIT_SUCCESS : EXIT_FAILURE);
|
|
|
|
|
if (!was_cancelled)
|
|
|
|
|
_LOGE("dbus: failure to get D-Bus connection: %s", error->message);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* On bus-disconnect, GDBus will raise(SIGTERM), which we handle like a
|
|
|
|
|
* regular request to quit. */
|
|
|
|
|
g_dbus_connection_set_exit_on_close(dbus_connection, TRUE);
|
|
|
|
|
|
|
|
|
|
_LOGD("dbus: unique name: %s", g_dbus_connection_get_unique_name(dbus_connection));
|
|
|
|
|
|
|
|
|
|
return g_steal_pointer(&dbus_connection);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
_name_owner_changed_cb(GDBusConnection *connection,
|
|
|
|
|
const char * sender_name,
|
|
|
|
|
const char * object_path,
|
|
|
|
|
const char * interface_name,
|
|
|
|
|
const char * signal_name,
|
|
|
|
|
GVariant * parameters,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
GlobalData *gl = user_data;
|
|
|
|
|
const char *new_owner;
|
|
|
|
|
|
|
|
|
|
if (!gl->name_owner_initialized)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (!g_variant_is_of_type(parameters, G_VARIANT_TYPE("(sss)")))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
g_variant_get(parameters, "(&s&s&s)", NULL, NULL, &new_owner);
|
|
|
|
|
new_owner = nm_str_not_empty(new_owner);
|
|
|
|
|
|
|
|
|
|
_LOGD("%s name-owner changed: %s -> %s",
|
|
|
|
|
NM_DBUS_SERVICE,
|
|
|
|
|
gl->name_owner ?: "(null)",
|
|
|
|
|
new_owner ?: "(null)");
|
|
|
|
|
|
2021-07-30 09:04:53 +02:00
|
|
|
nm_strdup_reset(&gl->name_owner, new_owner);
|
sudo: introduce nm-sudo D-Bus service
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
2021-07-18 08:53:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
|
GlobalData *gl;
|
|
|
|
|
char ** p_name_owner;
|
|
|
|
|
gboolean is_cancelled;
|
|
|
|
|
} BusFindNMNameOwnerData;
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
_bus_find_nm_nameowner_cb(const char *name_owner, GError *error, gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
BusFindNMNameOwnerData *data = user_data;
|
|
|
|
|
|
|
|
|
|
*data->p_name_owner = nm_strdup_not_empty(name_owner);
|
|
|
|
|
data->is_cancelled = nm_utils_error_is_cancelled(error);
|
|
|
|
|
data->gl->name_owner_initialized = TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
_bus_find_nm_nameowner(GlobalData *gl)
|
|
|
|
|
{
|
|
|
|
|
BusFindNMNameOwnerData data;
|
|
|
|
|
guint name_owner_changed_id;
|
|
|
|
|
gs_free char * name_owner = NULL;
|
|
|
|
|
|
|
|
|
|
name_owner_changed_id =
|
|
|
|
|
nm_dbus_connection_signal_subscribe_name_owner_changed(gl->dbus_connection,
|
|
|
|
|
NM_DBUS_SERVICE,
|
|
|
|
|
_name_owner_changed_cb,
|
|
|
|
|
gl,
|
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
|
|
data = (BusFindNMNameOwnerData){
|
|
|
|
|
.gl = gl,
|
|
|
|
|
.is_cancelled = FALSE,
|
|
|
|
|
.p_name_owner = &name_owner,
|
|
|
|
|
};
|
|
|
|
|
nm_dbus_connection_call_get_name_owner(gl->dbus_connection,
|
|
|
|
|
NM_DBUS_SERVICE,
|
|
|
|
|
10000,
|
|
|
|
|
gl->quit_cancellable,
|
|
|
|
|
_bus_find_nm_nameowner_cb,
|
|
|
|
|
&data);
|
|
|
|
|
while (!gl->name_owner_initialized)
|
|
|
|
|
g_main_context_iteration(NULL, TRUE);
|
|
|
|
|
|
|
|
|
|
if (data.is_cancelled) {
|
|
|
|
|
g_dbus_connection_signal_unsubscribe(gl->dbus_connection, name_owner_changed_id);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gl->name_owner_changed_id = name_owner_changed_id;
|
|
|
|
|
gl->name_owner = g_steal_pointer(&name_owner);
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
_bus_method_call(GDBusConnection * connection,
|
|
|
|
|
const char * sender,
|
|
|
|
|
const char * object_path,
|
|
|
|
|
const char * interface_name,
|
|
|
|
|
const char * method_name,
|
|
|
|
|
GVariant * parameters,
|
|
|
|
|
GDBusMethodInvocation *invocation,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
GlobalData *gl = user_data;
|
|
|
|
|
const char *arg_s;
|
2021-07-21 16:31:48 +02:00
|
|
|
guint32 arg_u;
|
sudo: introduce nm-sudo D-Bus service
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
2021-07-18 08:53:43 +02:00
|
|
|
|
|
|
|
|
nm_assert(nm_streq(object_path, NM_SUDO_DBUS_OBJECT_PATH));
|
|
|
|
|
nm_assert(nm_streq(interface_name, NM_SUDO_DBUS_IFACE_NAME));
|
|
|
|
|
|
|
|
|
|
if (!gl->no_auth_for_testing && !nm_streq0(sender, gl->name_owner)) {
|
|
|
|
|
_LOGT("dbus: request sender=%s, %s%s, ACCESS DENIED",
|
|
|
|
|
sender,
|
|
|
|
|
method_name,
|
|
|
|
|
g_variant_get_type_string(parameters));
|
|
|
|
|
g_dbus_method_invocation_return_error(invocation,
|
|
|
|
|
G_DBUS_ERROR,
|
|
|
|
|
G_DBUS_ERROR_ACCESS_DENIED,
|
|
|
|
|
"Access denied");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
nm-sudo: reject new request once we have no well-known-name
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).
2021-08-04 10:50:37 +02:00
|
|
|
if (gl->reject_new_requests) {
|
|
|
|
|
/* after the name was released, we must not accept new requests. This new
|
|
|
|
|
* request was probably targeted against the unique-name. But we already
|
|
|
|
|
* gave up the well-known name. If we'd accept new request now, they would
|
|
|
|
|
* keep the service running indefinitely (and thus preventing the service
|
|
|
|
|
* to restart and serve the well-known name. */
|
|
|
|
|
_LOGT("dbus: request sender=%s, %s%s, SERVER SHUTTING DOWN",
|
|
|
|
|
sender,
|
|
|
|
|
method_name,
|
|
|
|
|
g_variant_get_type_string(parameters));
|
|
|
|
|
g_dbus_method_invocation_return_error(invocation,
|
|
|
|
|
G_DBUS_ERROR,
|
|
|
|
|
G_DBUS_ERROR_NO_SERVER,
|
|
|
|
|
"Server is exiting");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
sudo: introduce nm-sudo D-Bus service
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
2021-07-18 08:53:43 +02:00
|
|
|
_LOGT("dbus: request sender=%s, %s%s",
|
|
|
|
|
sender,
|
|
|
|
|
method_name,
|
|
|
|
|
g_variant_get_type_string(parameters));
|
|
|
|
|
|
2021-08-03 18:07:50 +02:00
|
|
|
if (!nm_streq(interface_name, NM_SUDO_DBUS_IFACE_NAME))
|
|
|
|
|
goto out_unknown_method;
|
|
|
|
|
|
|
|
|
|
if (nm_streq(method_name, "GetFD")) {
|
|
|
|
|
g_variant_get(parameters, "(u)", &arg_u);
|
|
|
|
|
_handle_get_fd(gl, invocation, arg_u);
|
|
|
|
|
return;
|
|
|
|
|
}
|
sudo: introduce nm-sudo D-Bus service
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
2021-07-18 08:53:43 +02:00
|
|
|
if (nm_streq(method_name, "Ping")) {
|
|
|
|
|
g_variant_get(parameters, "(&s)", &arg_s);
|
|
|
|
|
_handle_ping(gl, invocation, arg_s);
|
2021-08-03 18:07:50 +02:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
out_unknown_method:
|
|
|
|
|
g_dbus_method_invocation_return_error(invocation,
|
|
|
|
|
G_DBUS_ERROR,
|
|
|
|
|
G_DBUS_ERROR_UNKNOWN_METHOD,
|
|
|
|
|
"Unknown method %s",
|
|
|
|
|
method_name);
|
sudo: introduce nm-sudo D-Bus service
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
2021-07-18 08:53:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static GDBusInterfaceInfo *const interface_info = NM_DEFINE_GDBUS_INTERFACE_INFO(
|
|
|
|
|
NM_SUDO_DBUS_IFACE_NAME,
|
|
|
|
|
.methods = NM_DEFINE_GDBUS_METHOD_INFOS(
|
|
|
|
|
NM_DEFINE_GDBUS_METHOD_INFO(
|
|
|
|
|
"Ping",
|
|
|
|
|
.in_args = NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("arg", "s"), ),
|
2021-07-21 16:31:48 +02:00
|
|
|
.out_args = NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("arg", "s"), ), ),
|
|
|
|
|
NM_DEFINE_GDBUS_METHOD_INFO("GetFD",
|
|
|
|
|
.in_args = NM_DEFINE_GDBUS_ARG_INFOS(
|
|
|
|
|
NM_DEFINE_GDBUS_ARG_INFO("fd_type", "u"), ), ), ), );
|
sudo: introduce nm-sudo D-Bus service
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
2021-07-18 08:53:43 +02:00
|
|
|
|
2021-08-03 13:37:09 +02:00
|
|
|
static gboolean
|
sudo: introduce nm-sudo D-Bus service
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
2021-07-18 08:53:43 +02:00
|
|
|
_bus_register_service(GlobalData *gl)
|
|
|
|
|
{
|
|
|
|
|
static const GDBusInterfaceVTable interface_vtable = {
|
|
|
|
|
.method_call = _bus_method_call,
|
|
|
|
|
};
|
2021-08-03 13:32:10 +02:00
|
|
|
gs_free_error GError * error = NULL;
|
|
|
|
|
NMDBusConnectionCallBlockingData data = {
|
|
|
|
|
.result = NULL,
|
|
|
|
|
};
|
|
|
|
|
gs_unref_variant GVariant *ret = NULL;
|
|
|
|
|
guint32 ret_val;
|
sudo: introduce nm-sudo D-Bus service
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
2021-07-18 08:53:43 +02:00
|
|
|
|
|
|
|
|
gl->service_regist_id =
|
|
|
|
|
g_dbus_connection_register_object(gl->dbus_connection,
|
|
|
|
|
NM_SUDO_DBUS_OBJECT_PATH,
|
|
|
|
|
interface_info,
|
|
|
|
|
NM_UNCONST_PTR(GDBusInterfaceVTable, &interface_vtable),
|
|
|
|
|
gl,
|
|
|
|
|
NULL,
|
|
|
|
|
&error);
|
|
|
|
|
if (gl->service_regist_id == 0) {
|
|
|
|
|
_LOGE("dbus: error registering object %s: %s", NM_SUDO_DBUS_OBJECT_PATH, error->message);
|
2021-08-03 13:37:09 +02:00
|
|
|
return FALSE;
|
sudo: introduce nm-sudo D-Bus service
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
2021-07-18 08:53:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_LOGD("dbus: object %s registered", NM_SUDO_DBUS_OBJECT_PATH);
|
|
|
|
|
|
2021-08-02 22:30:47 +02:00
|
|
|
/* regardless whether the request is successful, after we start calling
|
|
|
|
|
* RequestName, we remember that we need to ReleaseName it. */
|
|
|
|
|
gl->name_requested = TRUE;
|
|
|
|
|
|
2021-08-03 13:32:10 +02:00
|
|
|
nm_dbus_connection_call_request_name(gl->dbus_connection,
|
|
|
|
|
NM_SUDO_DBUS_BUS_NAME,
|
|
|
|
|
DBUS_NAME_FLAG_ALLOW_REPLACEMENT
|
|
|
|
|
| DBUS_NAME_FLAG_REPLACE_EXISTING,
|
|
|
|
|
10000,
|
|
|
|
|
gl->quit_cancellable,
|
|
|
|
|
nm_dbus_connection_call_blocking_callback,
|
|
|
|
|
&data);
|
sudo: introduce nm-sudo D-Bus service
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
2021-07-18 08:53:43 +02:00
|
|
|
|
|
|
|
|
/* Note that with D-Bus activation, the first request will already hit us before RequestName
|
2021-08-03 13:32:10 +02:00
|
|
|
* completes. So when we start iterating the main context, the first request may already come
|
|
|
|
|
* in. */
|
sudo: introduce nm-sudo D-Bus service
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
2021-07-18 08:53:43 +02:00
|
|
|
|
2021-08-03 13:32:10 +02:00
|
|
|
ret = nm_dbus_connection_call_blocking(&data, &error);
|
|
|
|
|
|
|
|
|
|
if (nm_utils_error_is_cancelled(error))
|
2021-08-03 13:37:09 +02:00
|
|
|
return FALSE;
|
2021-08-03 13:32:10 +02:00
|
|
|
|
|
|
|
|
if (error) {
|
|
|
|
|
_LOGE("d-bus: failed to request name %s: %s", NM_SUDO_DBUS_BUS_NAME, error->message);
|
2021-08-03 13:37:09 +02:00
|
|
|
return FALSE;
|
2021-08-03 13:32:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_variant_get(ret, "(u)", &ret_val);
|
|
|
|
|
|
|
|
|
|
if (ret_val != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
|
|
|
|
|
_LOGW("dbus: request name for %s failed to take name (response %u)",
|
|
|
|
|
NM_SUDO_DBUS_BUS_NAME,
|
|
|
|
|
ret_val);
|
2021-08-03 13:37:09 +02:00
|
|
|
return FALSE;
|
2021-08-03 13:32:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_LOGD("dbus: request name for %s succeeded", NM_SUDO_DBUS_BUS_NAME);
|
2021-08-03 13:37:09 +02:00
|
|
|
return TRUE;
|
sudo: introduce nm-sudo D-Bus service
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
2021-07-18 08:53:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
_idle_timeout_cb(gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
GlobalData *gl = user_data;
|
|
|
|
|
|
|
|
|
|
_LOGT("idle-timeout: expired");
|
2021-08-04 16:08:40 +02:00
|
|
|
nm_clear_g_source_inst(&gl->source_idle_timeout);
|
2021-08-04 11:53:30 +02:00
|
|
|
gl->shutdown_timeout = TRUE;
|
sudo: introduce nm-sudo D-Bus service
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
2021-07-18 08:53:43 +02:00
|
|
|
return G_SOURCE_CONTINUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
_idle_timeout_restart(GlobalData *gl)
|
|
|
|
|
{
|
|
|
|
|
nm_clear_g_source_inst(&gl->source_idle_timeout);
|
|
|
|
|
|
2021-08-04 11:53:30 +02:00
|
|
|
if (gl->shutdown_quitting)
|
sudo: introduce nm-sudo D-Bus service
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
2021-07-18 08:53:43 +02:00
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (!c_list_is_empty(&gl->pending_jobs_lst_head))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (gl->timeout_msec == IDLE_TIMEOUT_INFINITY)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
nm_assert(gl->timeout_msec < G_MAXINT32);
|
|
|
|
|
G_STATIC_ASSERT_EXPR(G_MAXINT32 < G_MAXUINT);
|
|
|
|
|
|
|
|
|
|
_LOGT("idle-timeout: start (%u msec)", gl->timeout_msec);
|
|
|
|
|
gl->source_idle_timeout = nm_g_timeout_add_source(gl->timeout_msec, _idle_timeout_cb, gl);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
_pending_job_register_object_release_on_idle_cb(gpointer data)
|
|
|
|
|
{
|
|
|
|
|
PendingJobData *idle_data = data;
|
|
|
|
|
GlobalData * gl = idle_data->gl;
|
|
|
|
|
|
|
|
|
|
c_list_unlink_stale(&idle_data->pending_jobs_lst);
|
|
|
|
|
nm_g_slice_free(idle_data);
|
|
|
|
|
|
|
|
|
|
_idle_timeout_restart(gl);
|
|
|
|
|
return G_SOURCE_REMOVE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
_pending_job_register_object_weak_cb(gpointer data, GObject *where_the_object_was)
|
|
|
|
|
{
|
|
|
|
|
/* The object might be destroyed on another thread. We need
|
|
|
|
|
* to sync with the main GMainContext by scheduling an idle action
|
|
|
|
|
* there. */
|
|
|
|
|
nm_g_idle_add(_pending_job_register_object_release_on_idle_cb, data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
_pending_job_register_object(GlobalData *gl, GObject *obj)
|
|
|
|
|
{
|
|
|
|
|
PendingJobData *idle_data;
|
|
|
|
|
|
|
|
|
|
/* if we just hit the timeout, we can ignore it. */
|
2021-08-04 11:53:30 +02:00
|
|
|
gl->shutdown_timeout = FALSE;
|
sudo: introduce nm-sudo D-Bus service
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
2021-07-18 08:53:43 +02:00
|
|
|
|
|
|
|
|
if (nm_clear_g_source_inst(&gl->source_idle_timeout))
|
|
|
|
|
_LOGT("idle-timeout: suspend timeout for pending request");
|
|
|
|
|
|
|
|
|
|
idle_data = g_slice_new(PendingJobData);
|
|
|
|
|
|
|
|
|
|
idle_data->gl = gl;
|
|
|
|
|
c_list_link_tail(&gl->pending_jobs_lst_head, &idle_data->pending_jobs_lst);
|
|
|
|
|
|
|
|
|
|
g_object_weak_ref(obj, _pending_job_register_object_weak_cb, idle_data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2021-08-02 22:30:47 +02:00
|
|
|
static void
|
|
|
|
|
_bus_release_name_cb(GObject *source, GAsyncResult *result, gpointer user_data)
|
|
|
|
|
{
|
nm-sudo: reject new request once we have no well-known-name
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).
2021-08-04 10:50:37 +02:00
|
|
|
_nm_unused gs_unref_object GObject *keep_alive_object = NULL;
|
|
|
|
|
GlobalData * gl;
|
2021-08-02 22:30:47 +02:00
|
|
|
|
nm-sudo: reject new request once we have no well-known-name
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).
2021-08-04 10:50:37 +02:00
|
|
|
nm_utils_user_data_unpack(user_data, &gl, &keep_alive_object);
|
|
|
|
|
|
|
|
|
|
gl->reject_new_requests = TRUE;
|
2021-08-02 22:30:47 +02:00
|
|
|
g_main_context_wakeup(NULL);
|
|
|
|
|
}
|
|
|
|
|
|
nm-sudo: reject new request once we have no well-known-name
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).
2021-08-04 10:50:37 +02:00
|
|
|
static gboolean
|
|
|
|
|
_bus_release_name(GlobalData *gl)
|
|
|
|
|
{
|
|
|
|
|
gs_unref_object GObject *keep_alive_object = NULL;
|
|
|
|
|
int r;
|
|
|
|
|
|
|
|
|
|
/* We already requested a name. To exit-on-idle without race, we need to dance.
|
|
|
|
|
* See https://lists.freedesktop.org/archives/dbus/2015-May/016671.html . */
|
|
|
|
|
|
|
|
|
|
if (!gl->name_requested)
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
2021-08-04 11:53:30 +02:00
|
|
|
gl->name_requested = FALSE;
|
|
|
|
|
gl->shutdown_quitting = TRUE;
|
nm-sudo: reject new request once we have no well-known-name
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).
2021-08-04 10:50:37 +02:00
|
|
|
|
|
|
|
|
_LOGT("shutdown: release-name");
|
|
|
|
|
|
|
|
|
|
keep_alive_object = g_object_new(G_TYPE_OBJECT, NULL);
|
|
|
|
|
|
|
|
|
|
/* we use the _pending_job_register_object() mechanism to make the loop busy during
|
|
|
|
|
* shutdown. */
|
|
|
|
|
_pending_job_register_object(gl, keep_alive_object);
|
|
|
|
|
|
|
|
|
|
r = nm_sd_notify("STOPPING=1");
|
|
|
|
|
if (r < 0)
|
|
|
|
|
_LOGW("shutdown: sd_notifiy(STOPPING=1) failed: %s", nm_strerror_native(-r));
|
|
|
|
|
else
|
|
|
|
|
_LOGT("shutdown: sd_notifiy(STOPPING=1) succeeded");
|
|
|
|
|
|
|
|
|
|
g_dbus_connection_call(gl->dbus_connection,
|
|
|
|
|
DBUS_SERVICE_DBUS,
|
|
|
|
|
DBUS_PATH_DBUS,
|
|
|
|
|
DBUS_INTERFACE_DBUS,
|
|
|
|
|
"ReleaseName",
|
|
|
|
|
g_variant_new("(s)", NM_SUDO_DBUS_BUS_NAME),
|
|
|
|
|
G_VARIANT_TYPE("(u)"),
|
|
|
|
|
G_DBUS_CALL_FLAGS_NONE,
|
|
|
|
|
10000,
|
|
|
|
|
NULL,
|
|
|
|
|
_bus_release_name_cb,
|
|
|
|
|
nm_utils_user_data_pack(gl, g_steal_pointer(&keep_alive_object)));
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-02 22:30:47 +02:00
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
sudo: introduce nm-sudo D-Bus service
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
2021-07-18 08:53:43 +02:00
|
|
|
static void
|
|
|
|
|
_initial_setup(GlobalData *gl)
|
|
|
|
|
{
|
|
|
|
|
gl->no_auth_for_testing =
|
|
|
|
|
_nm_utils_ascii_str_to_int64(g_getenv(_ENV("NM_SUDO_NO_AUTH_FOR_TESTING")), 0, 0, 1, 0);
|
|
|
|
|
gl->timeout_msec = _nm_utils_ascii_str_to_int64(g_getenv(_ENV("NM_SUDO_IDLE_TIMEOUT_MSEC")),
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
G_MAXINT32,
|
|
|
|
|
IDLE_TIMEOUT_MSEC);
|
|
|
|
|
|
|
|
|
|
gl->quit_cancellable = g_cancellable_new();
|
|
|
|
|
|
|
|
|
|
signal(SIGPIPE, SIG_IGN);
|
|
|
|
|
gl->source_sigterm = nm_g_unix_signal_add_source(SIGTERM, _signal_callback_term, gl);
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-04 11:53:30 +02:00
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
sudo: introduce nm-sudo D-Bus service
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
2021-07-18 08:53:43 +02:00
|
|
|
int
|
|
|
|
|
main(int argc, char **argv)
|
|
|
|
|
{
|
|
|
|
|
GlobalData _gl = {
|
|
|
|
|
.quit_cancellable = NULL,
|
|
|
|
|
.pending_jobs_lst_head = C_LIST_INIT(_gl.pending_jobs_lst_head),
|
|
|
|
|
};
|
|
|
|
|
GlobalData *const gl = &_gl;
|
|
|
|
|
int exit_code;
|
|
|
|
|
int r = 0;
|
|
|
|
|
|
|
|
|
|
_nm_logging_enabled_init(g_getenv(_ENV("NM_SUDO_LOG")));
|
|
|
|
|
|
|
|
|
|
gl->start_timestamp_msec = nm_utils_clock_gettime_msec(CLOCK_BOOTTIME);
|
|
|
|
|
|
|
|
|
|
_LOGD("starting nm-sudo (%s)", NM_DIST_VERSION);
|
|
|
|
|
|
|
|
|
|
_initial_setup(gl);
|
|
|
|
|
|
|
|
|
|
if (gl->no_auth_for_testing) {
|
|
|
|
|
_LOGW("WARNING: running in debug mode without authentication "
|
|
|
|
|
"(NM_SUDO_NO_AUTH_FOR_TESTING). ");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (gl->timeout_msec != IDLE_TIMEOUT_INFINITY)
|
|
|
|
|
_LOGT("idle-timeout: %u msec", gl->timeout_msec);
|
|
|
|
|
else
|
|
|
|
|
_LOGT("idle-timeout: disabled");
|
|
|
|
|
|
|
|
|
|
gl->dbus_connection = _bus_get(gl->quit_cancellable, &r);
|
|
|
|
|
if (!gl->dbus_connection) {
|
|
|
|
|
exit_code = r;
|
|
|
|
|
goto done;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!_bus_find_nm_nameowner(gl)) {
|
|
|
|
|
/* abort due to cancellation. That is success. */
|
|
|
|
|
exit_code = EXIT_SUCCESS;
|
|
|
|
|
goto done;
|
|
|
|
|
}
|
|
|
|
|
_LOGD("%s name-owner: %s", NM_DBUS_SERVICE, gl->name_owner ?: "(null)");
|
|
|
|
|
|
|
|
|
|
_idle_timeout_restart(gl);
|
|
|
|
|
|
|
|
|
|
exit_code = EXIT_SUCCESS;
|
|
|
|
|
|
2021-08-03 13:37:09 +02:00
|
|
|
if (!_bus_register_service(gl)) {
|
sudo: introduce nm-sudo D-Bus service
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
2021-07-18 08:53:43 +02:00
|
|
|
/* We failed to RequestName, but due to D-Bus activation we
|
|
|
|
|
* might have a pending request still (on the unique name).
|
|
|
|
|
* Process it below.
|
|
|
|
|
*
|
|
|
|
|
* Let's fake a shutdown signal, and still process the request below. */
|
2021-08-03 13:37:09 +02:00
|
|
|
if (!g_cancellable_is_cancelled(gl->quit_cancellable))
|
|
|
|
|
exit_code = EXIT_FAILURE;
|
2021-08-04 11:53:30 +02:00
|
|
|
gl->shutdown_quitting = TRUE;
|
nm-sudo: reject new request once we have no well-known-name
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).
2021-08-04 10:50:37 +02:00
|
|
|
|
|
|
|
|
if (gl->name_requested) {
|
|
|
|
|
/* We requested a name, but something went wrong. Below we will release
|
|
|
|
|
* the name right away. */
|
|
|
|
|
} else {
|
|
|
|
|
/* In case we didn't even went as far to request the name. New requests
|
|
|
|
|
* can only come via the unique name, and as we are shutting down, they
|
|
|
|
|
* are rejected. */
|
|
|
|
|
gl->reject_new_requests = TRUE;
|
|
|
|
|
}
|
sudo: introduce nm-sudo D-Bus service
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
2021-07-18 08:53:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (TRUE) {
|
2021-08-04 11:53:30 +02:00
|
|
|
if (gl->shutdown_quitting)
|
nm-sudo: reject new request once we have no well-known-name
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).
2021-08-04 10:50:37 +02:00
|
|
|
_bus_release_name(gl);
|
2021-08-04 11:53:30 +02:00
|
|
|
|
sudo: introduce nm-sudo D-Bus service
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
2021-07-18 08:53:43 +02:00
|
|
|
if (!c_list_is_empty(&gl->pending_jobs_lst_head)) {
|
|
|
|
|
/* we must first reply to all requests. No matter what. */
|
2021-08-04 11:53:30 +02:00
|
|
|
} else if (gl->shutdown_quitting || gl->shutdown_timeout) {
|
2021-08-02 22:30:47 +02:00
|
|
|
/* we either hit the idle timeout or received SIGTERM. Note that
|
|
|
|
|
* if we received an idle-timeout and the very moment afterwards
|
2021-08-04 11:53:30 +02:00
|
|
|
* a new request, then _bus_method_call() will clear gl->shutdown_timeout
|
2021-08-02 22:30:47 +02:00
|
|
|
* (via _pending_job_register_object()). */
|
nm-sudo: reject new request once we have no well-known-name
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).
2021-08-04 10:50:37 +02:00
|
|
|
if (!_bus_release_name(gl))
|
|
|
|
|
break;
|
sudo: introduce nm-sudo D-Bus service
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
2021-07-18 08:53:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_main_context_iteration(NULL, TRUE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
done:
|
2021-08-02 22:30:47 +02:00
|
|
|
_LOGD("shutdown: cleanup");
|
sudo: introduce nm-sudo D-Bus service
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
2021-07-18 08:53:43 +02:00
|
|
|
|
2021-08-04 11:53:30 +02:00
|
|
|
gl->shutdown_quitting = TRUE;
|
2021-08-03 11:29:07 +02:00
|
|
|
g_cancellable_cancel(gl->quit_cancellable);
|
|
|
|
|
|
sudo: introduce nm-sudo D-Bus service
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
2021-07-18 08:53:43 +02:00
|
|
|
nm_assert(c_list_is_empty(&gl->pending_jobs_lst_head));
|
|
|
|
|
|
|
|
|
|
if (gl->service_regist_id != 0) {
|
|
|
|
|
g_dbus_connection_unregister_object(gl->dbus_connection,
|
|
|
|
|
nm_steal_int(&gl->service_regist_id));
|
|
|
|
|
}
|
|
|
|
|
if (gl->name_owner_changed_id != 0) {
|
|
|
|
|
g_dbus_connection_signal_unsubscribe(gl->dbus_connection,
|
|
|
|
|
nm_steal_int(&gl->name_owner_changed_id));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (gl->dbus_connection) {
|
|
|
|
|
g_dbus_connection_flush_sync(gl->dbus_connection, NULL, NULL);
|
|
|
|
|
g_clear_object(&gl->dbus_connection);
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-04 11:53:30 +02:00
|
|
|
nm_g_main_context_iterate_ready(NULL);
|
|
|
|
|
|
|
|
|
|
nm_clear_g_free(&gl->name_owner);
|
|
|
|
|
|
|
|
|
|
nm_clear_g_source_inst(&gl->source_sigterm);
|
|
|
|
|
nm_clear_g_source_inst(&gl->source_idle_timeout);
|
|
|
|
|
g_clear_object(&gl->quit_cancellable);
|
2021-08-03 11:29:07 +02:00
|
|
|
|
sudo: introduce nm-sudo D-Bus service
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
2021-07-18 08:53:43 +02:00
|
|
|
_LOGD("exit (%d)", exit_code);
|
|
|
|
|
return exit_code;
|
|
|
|
|
}
|