about summary refs log tree commit diff
path: root/src/settings/nm-agent-manager.c
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2021-02-11 18:11:46 +0100
committerMichael Biebl <biebl@debian.org>2021-02-11 18:11:46 +0100
commit80ec1decc49c72efec2a8b87c06245c92c0ab807 (patch)
treee3b229aa94e8dcf0590f2317664176e7b8f7607b /src/settings/nm-agent-manager.c
parent65f86e8f56267192d42f2b629fc6b0c99fb9cd0c (diff)
New upstream version 1.29.90 upstream/1.29.90
Diffstat (limited to 'src/settings/nm-agent-manager.c')
-rw-r--r--src/settings/nm-agent-manager.c1618
1 files changed, 0 insertions, 1618 deletions
diff --git a/src/settings/nm-agent-manager.c b/src/settings/nm-agent-manager.c
deleted file mode 100644
index 07a3dafe..00000000
--- a/src/settings/nm-agent-manager.c
+++ /dev/null
@@ -1,1618 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Copyright (C) 2010 - 2013 Red Hat, Inc.
- */
-
-#include "nm-default.h"
-
-#include "nm-agent-manager.h"
-
-#include <pwd.h>
-
-#include "nm-libnm-core-intern/nm-common-macros.h"
-#include "nm-dbus-interface.h"
-#include "nm-secret-agent.h"
-#include "nm-auth-utils.h"
-#include "nm-setting-vpn.h"
-#include "nm-auth-manager.h"
-#include "nm-dbus-manager.h"
-#include "nm-session-monitor.h"
-#include "nm-simple-connection.h"
-#include "NetworkManagerUtils.h"
-#include "nm-core-internal.h"
-#include "c-list/src/c-list.h"
-
-/*****************************************************************************/
-
-enum {
-    AGENT_REGISTERED,
-    LAST_SIGNAL,
-};
-
-static guint signals[LAST_SIGNAL] = {0};
-
-typedef struct {
-    NMAuthManager *   auth_mgr;
-    NMSessionMonitor *session_monitor;
-
-    CList agent_lst_head;
-
-    CList request_lst_head;
-
-    guint64 agent_version_id;
-} NMAgentManagerPrivate;
-
-struct _NMAgentManager {
-    NMDBusObject          parent;
-    NMAgentManagerPrivate _priv;
-};
-
-struct _NMAgentManagerClass {
-    NMDBusObjectClass parent;
-};
-
-G_DEFINE_TYPE(NMAgentManager, nm_agent_manager, NM_TYPE_DBUS_OBJECT)
-
-#define NM_AGENT_MANAGER_GET_PRIVATE(self) \
-    _NM_GET_PRIVATE(self, NMAgentManager, NM_IS_AGENT_MANAGER)
-
-/*****************************************************************************/
-
-NM_DEFINE_SINGLETON_GETTER(NMAgentManager, nm_agent_manager_get, NM_TYPE_AGENT_MANAGER);
-
-/*****************************************************************************/
-
-#define _NMLOG_PREFIX_NAME "agent-manager"
-#define _NMLOG_DOMAIN      LOGD_AGENTS
-#define _NMLOG(level, agent, ...)                                            \
-    G_STMT_START                                                             \
-    {                                                                        \
-        if (nm_logging_enabled((level), (_NMLOG_DOMAIN))) {                  \
-            char           __prefix1[32];                                    \
-            char           __prefix2[128];                                   \
-            NMSecretAgent *__agent = (agent);                                \
-                                                                             \
-            if (!(self))                                                     \
-                g_snprintf(__prefix1,                                        \
-                           sizeof(__prefix1),                                \
-                           "%s%s",                                           \
-                           ""_NMLOG_PREFIX_NAME                              \
-                           "",                                               \
-                           "[]");                                            \
-            else if ((self) != singleton_instance)                           \
-                g_snprintf(__prefix1,                                        \
-                           sizeof(__prefix1),                                \
-                           "%s[" NM_HASH_OBFUSCATE_PTR_FMT "]",              \
-                           ""_NMLOG_PREFIX_NAME                              \
-                           "",                                               \
-                           NM_HASH_OBFUSCATE_PTR(self));                     \
-            else                                                             \
-                g_strlcpy(__prefix1, _NMLOG_PREFIX_NAME, sizeof(__prefix1)); \
-            if (__agent) {                                                   \
-                g_snprintf(__prefix2,                                        \
-                           sizeof(__prefix2),                                \
-                           ": agent[" NM_HASH_OBFUSCATE_PTR_FMT ",%s]",      \
-                           NM_HASH_OBFUSCATE_PTR(__agent),                   \
-                           nm_secret_agent_get_description(__agent));        \
-            } else                                                           \
-                __prefix2[0] = '\0';                                         \
-            _nm_log((level),                                                 \
-                    (_NMLOG_DOMAIN),                                         \
-                    0,                                                       \
-                    NULL,                                                    \
-                    NULL,                                                    \
-                    "%s%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__),             \
-                    __prefix1,                                               \
-                    __prefix2 _NM_UTILS_MACRO_REST(__VA_ARGS__));            \
-        }                                                                    \
-    }                                                                        \
-    G_STMT_END
-
-#define LOG_REQ_FMT "[" NM_HASH_OBFUSCATE_PTR_FMT "/%s%s%s%s%s%s]"
-#define LOG_REQ_ARG(req)                                                  \
-    NM_HASH_OBFUSCATE_PTR(req), NM_PRINT_FMT_QUOTE_STRING((req)->detail), \
-        NM_PRINT_FMT_QUOTED(((req)->request_type == REQUEST_TYPE_CON_GET) \
-                                && (req)->con.get.setting_name,           \
-                            "/\"",                                        \
-                            (req)->con.get.setting_name,                  \
-                            "\"",                                         \
-                            ((req)->request_type == REQUEST_TYPE_CON_GET  \
-                                 ? "/(none)"                              \
-                                 : _request_type_to_string((req)->request_type, FALSE)))
-
-/*****************************************************************************/
-
-typedef struct _NMAgentManagerCallId Request;
-
-static void request_add_agent(Request *req, NMSecretAgent *agent);
-
-static void request_remove_agent(Request *req, NMSecretAgent *agent);
-
-static void request_next_agent(Request *req);
-
-static void _con_get_request_start(Request *req);
-static void _con_save_request_start(Request *req);
-static void _con_del_request_start(Request *req);
-
-static gboolean _con_get_try_complete_early(Request *req);
-
-static void agent_disconnected_cb(NMSecretAgent *agent, gpointer user_data);
-
-/*****************************************************************************/
-
-guint64
-nm_agent_manager_get_agent_version_id(NMAgentManager *self)
-{
-    g_return_val_if_fail(NM_IS_AGENT_MANAGER(self), 0);
-
-    return NM_AGENT_MANAGER_GET_PRIVATE(self)->agent_version_id;
-}
-
-/*****************************************************************************/
-
-typedef enum {
-    REQUEST_TYPE_INVALID,
-    REQUEST_TYPE_CON_GET,
-    REQUEST_TYPE_CON_SAVE,
-    REQUEST_TYPE_CON_DEL,
-} RequestType;
-
-static const char *
-_request_type_to_string(RequestType request_type, gboolean verbose)
-{
-    switch (request_type) {
-    case REQUEST_TYPE_CON_GET:
-        return verbose ? "getting" : "get";
-    case REQUEST_TYPE_CON_SAVE:
-        return verbose ? "saving" : "sav";
-    case REQUEST_TYPE_CON_DEL:
-        return verbose ? "deleting" : "del";
-    default:
-        return "??";
-    }
-}
-
-/*****************************************************************************/
-
-struct _NMAgentManagerCallId {
-    CList request_lst;
-
-    NMAgentManager *self;
-
-    RequestType request_type;
-
-    char *detail;
-
-    NMAuthSubject *subject;
-
-    /* Current agent being asked for secrets */
-    NMSecretAgent *      current;
-    NMSecretAgentCallId *current_call_id;
-
-    /* Stores the sorted list of NMSecretAgents which will be asked for secrets */
-    GSList *pending;
-
-    guint idle_id;
-
-    union {
-        struct {
-            char *        path;
-            NMConnection *connection;
-
-            NMAuthChain *chain;
-
-            /* Whether the agent currently being asked for secrets
-             * has the system.modify privilege.
-             */
-            gboolean current_has_modify;
-
-            union {
-                struct {
-                    NMSecretAgentGetSecretsFlags flags;
-                    char *                       setting_name;
-                    char **                      hints;
-
-                    GVariant *existing_secrets;
-
-                    NMAgentSecretsResultFunc callback;
-                    gpointer                 callback_data;
-                } get;
-            };
-        } con;
-    };
-};
-
-/*****************************************************************************/
-
-static NMSecretAgent *
-_agent_find_by_owner(NMAgentManagerPrivate *priv, const char *owner)
-{
-    NMSecretAgent *agent;
-
-    c_list_for_each_entry (agent, &priv->agent_lst_head, agent_lst) {
-        if (nm_streq(nm_secret_agent_get_dbus_owner(agent), owner))
-            return agent;
-    }
-    return NULL;
-}
-
-static NMSecretAgent *
-_agent_find_by_identifier_and_uid(NMAgentManagerPrivate *priv,
-                                  const char *           identifier,
-                                  gulong                 sender_uid)
-{
-    NMSecretAgent *agent;
-
-    c_list_for_each_entry (agent, &priv->agent_lst_head, agent_lst) {
-        if (nm_streq0(nm_secret_agent_get_identifier(agent), identifier)
-            && sender_uid == nm_secret_agent_get_owner_uid(agent))
-            return agent;
-    }
-    return NULL;
-}
-
-/*****************************************************************************/
-
-static void
-_agent_remove(NMAgentManager *self, NMSecretAgent *agent)
-{
-    NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE(self);
-    CList *                iter, *safe;
-
-    nm_assert(NM_IS_SECRET_AGENT(agent));
-    nm_assert(c_list_contains(&priv->agent_lst_head, &agent->agent_lst));
-
-    _LOGD(agent, "agent unregistered or disappeared");
-
-    nm_clear_pointer(&agent->auth_chain, nm_auth_chain_destroy);
-
-    c_list_unlink(&agent->agent_lst);
-
-    g_signal_handlers_disconnect_by_func(agent, G_CALLBACK(agent_disconnected_cb), self);
-
-    /* Remove this agent from any in-progress secrets requests */
-    c_list_for_each_safe (iter, safe, &priv->request_lst_head)
-        request_remove_agent(c_list_entry(iter, Request, request_lst), agent);
-
-    g_object_unref(agent);
-}
-
-/* Call this *after* calling request_next_agent() */
-static void
-maybe_remove_agent_on_error(NMAgentManager *self, NMSecretAgent *agent, GError *error)
-{
-    if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CLOSED)
-        && !g_error_matches(error, G_DBUS_ERROR, G_DBUS_ERROR_DISCONNECTED)
-        && !g_error_matches(error, G_DBUS_ERROR, G_DBUS_ERROR_NAME_HAS_NO_OWNER))
-        return;
-
-    if (!c_list_is_empty(&agent->agent_lst))
-        _agent_remove(self, agent);
-}
-
-/*****************************************************************************/
-
-static gboolean
-validate_identifier(const char *identifier, GError **error)
-{
-    const char *p = identifier;
-    size_t      id_len;
-
-    if (!identifier) {
-        g_set_error_literal(error,
-                            NM_AGENT_MANAGER_ERROR,
-                            NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER,
-                            "No identifier was given");
-        return FALSE;
-    }
-
-    /* Length between 3 and 255 characters inclusive */
-    id_len = strlen(identifier);
-    if (id_len < 3 || id_len > 255) {
-        g_set_error_literal(error,
-                            NM_AGENT_MANAGER_ERROR,
-                            NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER,
-                            "Identifier length not between 3 and 255 characters (inclusive)");
-        return FALSE;
-    }
-
-    if ((identifier[0] == '.') || (identifier[id_len - 1] == '.')) {
-        g_set_error_literal(error,
-                            NM_AGENT_MANAGER_ERROR,
-                            NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER,
-                            "Identifier must not start or end with '.'");
-        return FALSE;
-    }
-
-    /* FIXME: do complete validation here */
-    while (p && *p) {
-        if (!g_ascii_isalnum(*p) && (*p != '_') && (*p != '-') && (*p != '.')) {
-            g_set_error(error,
-                        NM_AGENT_MANAGER_ERROR,
-                        NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER,
-                        "Identifier contains invalid character '%c'",
-                        *p);
-            return FALSE;
-        }
-
-        if ((*p == '.') && (*(p + 1) == '.')) {
-            g_set_error_literal(error,
-                                NM_AGENT_MANAGER_ERROR,
-                                NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER,
-                                "Identifier contains two '.' characters in sequence");
-            return FALSE;
-        }
-        p++;
-    }
-
-    return TRUE;
-}
-
-static void
-_agent_permissions_check_done(NMAuthChain *          chain,
-                              GDBusMethodInvocation *context,
-                              gpointer               user_data)
-{
-    NMAgentManager *       self = NM_AGENT_MANAGER(user_data);
-    NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE(self);
-    NMSecretAgent *        agent;
-    Request *              request;
-
-    nm_assert(!context || G_IS_DBUS_METHOD_INVOCATION(context));
-
-    agent = nm_auth_chain_steal_data(chain, "agent");
-
-    nm_assert(NM_IS_SECRET_AGENT(agent));
-    nm_assert(agent->auth_chain == chain);
-    nm_assert(agent->fully_registered == (!context));
-    nm_assert(c_list_contains(&priv->agent_lst_head, &agent->agent_lst));
-
-    agent->auth_chain = NULL;
-
-    nm_secret_agent_add_permission(
-        agent,
-        NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED,
-        (nm_auth_chain_get_result(chain, NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED)
-         == NM_AUTH_CALL_RESULT_YES));
-    nm_secret_agent_add_permission(
-        agent,
-        NM_AUTH_PERMISSION_WIFI_SHARE_OPEN,
-        (nm_auth_chain_get_result(chain, NM_AUTH_PERMISSION_WIFI_SHARE_OPEN)
-         == NM_AUTH_CALL_RESULT_YES));
-
-    if (agent->fully_registered) {
-        _LOGD(agent, "updated agent permissions");
-        return;
-    }
-
-    _LOGI(agent, "agent registered");
-
-    agent->fully_registered = TRUE;
-
-    priv->agent_version_id += 1;
-
-    g_dbus_method_invocation_return_value(context, NULL);
-
-    c_list_for_each_entry (request, &priv->request_lst_head, request_lst)
-        request_add_agent(request, agent);
-
-    g_signal_emit(self, signals[AGENT_REGISTERED], 0, agent);
-}
-
-static NMAuthChain *
-_agent_create_auth_chain(NMAgentManager *self, NMSecretAgent *agent, GDBusMethodInvocation *context)
-{
-    NMAuthChain *chain;
-
-    _LOGD(agent, "requesting permissions");
-
-    nm_assert(!agent->auth_chain
-              || (agent->fully_registered == (!nm_auth_chain_get_context(agent->auth_chain))));
-
-    if (agent->auth_chain && !context && !agent->fully_registered) {
-        /* we restart the authorization check (without a @context), but the currently
-         * pending auth-chain carries a context. We need to pass it on as we replace
-         * the auth-chain. */
-        context = nm_auth_chain_get_context(agent->auth_chain);
-        nm_assert(context);
-    }
-
-    chain = nm_auth_chain_new_subject(nm_secret_agent_get_subject(agent),
-                                      context,
-                                      _agent_permissions_check_done,
-                                      self);
-
-    nm_auth_chain_set_data(chain, "agent", agent, NULL);
-    nm_auth_chain_add_call(chain, NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED, FALSE);
-    nm_auth_chain_add_call(chain, NM_AUTH_PERMISSION_WIFI_SHARE_OPEN, FALSE);
-
-    nm_clear_pointer(&agent->auth_chain, nm_auth_chain_destroy);
-    agent->auth_chain = chain;
-    return chain;
-}
-
-static void
-agent_disconnected_cb(NMSecretAgent *agent, gpointer user_data)
-{
-    _agent_remove(NM_AGENT_MANAGER(user_data), agent);
-}
-
-static void
-agent_manager_register_with_capabilities(NMAgentManager *       self,
-                                         GDBusMethodInvocation *context,
-                                         const char *           identifier,
-                                         guint32                capabilities)
-{
-    NMAgentManagerPrivate *priv               = NM_AGENT_MANAGER_GET_PRIVATE(self);
-    gs_unref_object NMAuthSubject *subject    = NULL;
-    gulong                         sender_uid = G_MAXULONG;
-    GError *                       error      = NULL;
-    NMSecretAgent *                agent;
-
-    subject = nm_dbus_manager_new_auth_subject_from_context(context);
-    if (!subject) {
-        error = g_error_new_literal(NM_AGENT_MANAGER_ERROR,
-                                    NM_AGENT_MANAGER_ERROR_PERMISSION_DENIED,
-                                    NM_UTILS_ERROR_MSG_REQ_UID_UKNOWN);
-        g_dbus_method_invocation_take_error(context, error);
-        return;
-    }
-    sender_uid = nm_auth_subject_get_unix_process_uid(subject);
-
-    /* Validate the identifier */
-    if (!validate_identifier(identifier, &error)) {
-        g_dbus_method_invocation_take_error(context, error);
-        return;
-    }
-
-    /* Only one agent for each identifier is allowed per user */
-    if (_agent_find_by_identifier_and_uid(priv, identifier, sender_uid)) {
-        error = g_error_new_literal(NM_AGENT_MANAGER_ERROR,
-                                    NM_AGENT_MANAGER_ERROR_PERMISSION_DENIED,
-                                    "An agent with this ID is already registered for this user.");
-        g_dbus_method_invocation_take_error(context, error);
-        return;
-    }
-
-    agent = nm_secret_agent_new(context, subject, identifier, capabilities);
-
-    g_signal_connect(agent, NM_SECRET_AGENT_DISCONNECTED, G_CALLBACK(agent_disconnected_cb), self);
-
-    c_list_link_tail(&priv->agent_lst_head, &agent->agent_lst);
-
-    _agent_create_auth_chain(self, agent, context);
-}
-
-static void
-impl_agent_manager_register(NMDBusObject *                     obj,
-                            const NMDBusInterfaceInfoExtended *interface_info,
-                            const NMDBusMethodInfoExtended *   method_info,
-                            GDBusConnection *                  connection,
-                            const char *                       sender,
-                            GDBusMethodInvocation *            invocation,
-                            GVariant *                         parameters)
-{
-    const char *identifier;
-
-    g_variant_get(parameters, "(&s)", &identifier);
-    agent_manager_register_with_capabilities(NM_AGENT_MANAGER(obj), invocation, identifier, 0);
-}
-
-static void
-impl_agent_manager_register_with_capabilities(NMDBusObject *                     obj,
-                                              const NMDBusInterfaceInfoExtended *interface_info,
-                                              const NMDBusMethodInfoExtended *   method_info,
-                                              GDBusConnection *                  connection,
-                                              const char *                       sender,
-                                              GDBusMethodInvocation *            invocation,
-                                              GVariant *                         parameters)
-{
-    const char *identifier;
-    guint32     capabilities;
-
-    g_variant_get(parameters, "(&su)", &identifier, &capabilities);
-    agent_manager_register_with_capabilities(NM_AGENT_MANAGER(obj),
-                                             invocation,
-                                             identifier,
-                                             capabilities);
-}
-
-static void
-impl_agent_manager_unregister(NMDBusObject *                     obj,
-                              const NMDBusInterfaceInfoExtended *interface_info,
-                              const NMDBusMethodInfoExtended *   method_info,
-                              GDBusConnection *                  connection,
-                              const char *                       sender,
-                              GDBusMethodInvocation *            invocation,
-                              GVariant *                         parameters)
-{
-    NMAgentManager *       self = NM_AGENT_MANAGER(obj);
-    NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE(self);
-    NMSecretAgent *        agent;
-
-    agent = _agent_find_by_owner(priv, sender);
-    if (!agent) {
-        g_dbus_method_invocation_return_error_literal(invocation,
-                                                      NM_AGENT_MANAGER_ERROR,
-                                                      NM_AGENT_MANAGER_ERROR_NOT_REGISTERED,
-                                                      "Caller is not registered as an Agent");
-        return;
-    }
-
-    _agent_remove(self, agent);
-
-    g_dbus_method_invocation_return_value(invocation, NULL);
-}
-
-/*****************************************************************************/
-
-static Request *
-request_new(NMAgentManager *self,
-            RequestType     request_type,
-            const char *    detail,
-            NMAuthSubject * subject)
-{
-    Request *req;
-
-    req               = g_slice_new0(Request);
-    req->self         = g_object_ref(self);
-    req->request_type = request_type;
-    req->detail       = g_strdup(detail);
-    req->subject      = g_object_ref(subject);
-    c_list_link_tail(&NM_AGENT_MANAGER_GET_PRIVATE(self)->request_lst_head, &req->request_lst);
-    return req;
-}
-
-static void
-request_free(Request *req)
-{
-    switch (req->request_type) {
-    case REQUEST_TYPE_CON_GET:
-    case REQUEST_TYPE_CON_SAVE:
-    case REQUEST_TYPE_CON_DEL:
-        g_object_unref(req->con.connection);
-        g_free(req->con.path);
-        nm_clear_pointer(&req->con.chain, nm_auth_chain_destroy);
-        if (req->request_type == REQUEST_TYPE_CON_GET) {
-            g_free(req->con.get.setting_name);
-            g_strfreev(req->con.get.hints);
-            if (req->con.get.existing_secrets)
-                g_variant_unref(req->con.get.existing_secrets);
-        }
-        break;
-    default:
-        g_assert_not_reached();
-    }
-
-    if (req->idle_id)
-        g_source_remove(req->idle_id);
-
-    /* cancel-secrets invokes the done-callback synchronously -- in which case
-     * the handler just return.
-     * Hence, we can proceed to free @req... */
-    nm_secret_agent_cancel_call(req->current, req->current_call_id);
-
-    g_object_unref(req->subject);
-
-    g_free(req->detail);
-    g_slist_free_full(req->pending, g_object_unref);
-
-    g_object_unref(req->self);
-
-    if (req->current)
-        g_object_unref(req->current);
-
-    memset(req, 0, sizeof(Request));
-    g_slice_free(Request, req);
-}
-
-static void
-req_complete_release(Request *   req,
-                     GVariant *  secrets,
-                     const char *agent_dbus_owner,
-                     const char *agent_username,
-                     GError *    error)
-{
-    NMAgentManager *self = req->self;
-
-    switch (req->request_type) {
-    case REQUEST_TYPE_CON_GET:
-        req->con.get.callback(self,
-                              req,
-                              agent_dbus_owner,
-                              agent_username,
-                              req->con.current_has_modify,
-                              req->con.get.setting_name,
-                              req->con.get.flags,
-                              error ? NULL : secrets,
-                              error,
-                              req->con.get.callback_data);
-
-        break;
-    case REQUEST_TYPE_CON_SAVE:
-    case REQUEST_TYPE_CON_DEL:
-        break;
-    default:
-        g_return_if_reached();
-    }
-
-    request_free(req);
-}
-
-static void
-req_complete_cancel(Request *req, gboolean is_disposing)
-{
-    gs_free_error GError *error = NULL;
-
-    nm_assert(req && req->self);
-    nm_assert(!c_list_contains(&NM_AGENT_MANAGER_GET_PRIVATE(req->self)->request_lst_head,
-                               &req->request_lst));
-
-    nm_utils_error_set_cancelled(&error, is_disposing, "NMAgentManager");
-    req_complete_release(req, NULL, NULL, NULL, error);
-}
-
-static void
-req_complete(Request *   req,
-             GVariant *  secrets,
-             const char *agent_dbus_owner,
-             const char *agent_username,
-             GError *    error)
-{
-    NMAgentManager *self = req->self;
-
-    nm_assert(
-        c_list_contains(&NM_AGENT_MANAGER_GET_PRIVATE(self)->request_lst_head, &req->request_lst));
-
-    c_list_unlink(&req->request_lst);
-
-    req_complete_release(req, secrets, agent_dbus_owner, agent_username, error);
-}
-
-static void
-req_complete_error(Request *req, GError *error)
-{
-    req_complete(req, NULL, NULL, NULL, error);
-}
-
-static int
-agent_compare_func(gconstpointer aa, gconstpointer bb, gpointer user_data)
-{
-    NMSecretAgent *   a   = (NMSecretAgent *) aa;
-    NMSecretAgent *   b   = (NMSecretAgent *) bb;
-    Request *         req = user_data;
-    NMSessionMonitor *sm;
-    gboolean          a_active, b_active;
-    gulong            a_pid, b_pid, requester;
-    guint64           a_start, b_start;
-
-    a_pid = nm_secret_agent_get_pid(a);
-    b_pid = nm_secret_agent_get_pid(b);
-
-    /* Prefer agents in the process the request came from */
-    if (nm_auth_subject_get_subject_type(req->subject) == NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS) {
-        requester = nm_auth_subject_get_unix_process_pid(req->subject);
-
-        if (a_pid != b_pid) {
-            if (a_pid == requester)
-                return -1;
-            else if (b_pid == requester)
-                return 1;
-        }
-    }
-
-    /* Prefer agents in active sessions */
-    sm       = NM_AGENT_MANAGER_GET_PRIVATE(req->self)->session_monitor;
-    a_active = nm_session_monitor_session_exists(sm, nm_secret_agent_get_owner_uid(a), TRUE);
-    b_active = nm_session_monitor_session_exists(sm, nm_secret_agent_get_owner_uid(b), TRUE);
-    if (a_active && !b_active)
-        return -1;
-    else if (!a_active && b_active)
-        return 1;
-
-    /* Prefer agents launched later (this is essentially to ease agent debugging) */
-    a_start = nm_utils_get_start_time_for_pid(a_pid, NULL, NULL);
-    b_start = nm_utils_get_start_time_for_pid(b_pid, NULL, NULL);
-    if (a_start > b_start)
-        return -1;
-    else if (a_start < b_start)
-        return 1;
-
-    return 0;
-}
-
-static void
-request_add_agent(Request *req, NMSecretAgent *agent)
-{
-    NMAgentManager *self;
-
-    g_return_if_fail(req != NULL);
-    g_return_if_fail(agent != NULL);
-
-    self = req->self;
-
-    if (req->request_type == REQUEST_TYPE_CON_GET) {
-        NMAuthSubject *subject = nm_secret_agent_get_subject(agent);
-
-        /* Ensure the caller's username exists in the connection's permissions,
-         * or that the permissions is empty (ie, visible by everyone).
-         */
-        if (!nm_auth_is_subject_in_acl(req->con.connection, subject, NULL)) {
-            _LOGD(agent,
-                  "agent ignored for secrets request " LOG_REQ_FMT " (not in ACL)",
-                  LOG_REQ_ARG(req));
-            /* Connection not visible to this agent's user */
-            return;
-        }
-    }
-
-    /* If the request should filter agents by UID, do that now */
-    if (nm_auth_subject_get_subject_type(req->subject) == NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS) {
-        uid_t agent_uid, subject_uid;
-
-        agent_uid   = nm_secret_agent_get_owner_uid(agent);
-        subject_uid = nm_auth_subject_get_unix_process_uid(req->subject);
-        if (agent_uid != subject_uid) {
-            _LOGD(agent,
-                  "agent ignored for secrets request " LOG_REQ_FMT " "
-                  "(uid %ld not required %ld)",
-                  LOG_REQ_ARG(req),
-                  (long) agent_uid,
-                  (long) subject_uid);
-            return;
-        }
-    }
-
-    _LOGD(agent, "agent allowed for secrets request " LOG_REQ_FMT, LOG_REQ_ARG(req));
-
-    /* Add this agent to the list, sorted appropriately */
-    req->pending =
-        g_slist_insert_sorted_with_data(req->pending, g_object_ref(agent), agent_compare_func, req);
-}
-
-static void
-request_add_agents(NMAgentManager *self, Request *req)
-{
-    NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE(self);
-    NMSecretAgent *        agent;
-
-    c_list_for_each_entry (agent, &priv->agent_lst_head, agent_lst) {
-        if (agent->fully_registered)
-            request_add_agent(req, agent);
-    }
-}
-
-static void
-request_next_agent(Request *req)
-{
-    NMAgentManager *self;
-    GError *        error = NULL;
-
-    self = req->self;
-
-    nm_secret_agent_cancel_call(req->current, req->current_call_id);
-    nm_assert(!req->current_call_id);
-    g_clear_object(&req->current);
-
-    if (req->pending) {
-        /* Send the request to the next agent */
-        req->current = req->pending->data;
-        req->pending = g_slist_remove(req->pending, req->current);
-
-        _LOGD(req->current,
-              "agent %s secrets for request " LOG_REQ_FMT,
-              _request_type_to_string(req->request_type, TRUE),
-              LOG_REQ_ARG(req));
-
-        switch (req->request_type) {
-        case REQUEST_TYPE_CON_GET:
-            _con_get_request_start(req);
-            break;
-        case REQUEST_TYPE_CON_SAVE:
-            _con_save_request_start(req);
-            break;
-        case REQUEST_TYPE_CON_DEL:
-            _con_del_request_start(req);
-            break;
-        default:
-            g_assert_not_reached();
-        }
-    } else {
-        /* No more secret agents are available to fulfill this secrets request */
-        error = g_error_new_literal(NM_AGENT_MANAGER_ERROR,
-                                    NM_AGENT_MANAGER_ERROR_NO_SECRETS,
-                                    "No agents were available for this request.");
-        req_complete_error(req, error);
-        g_error_free(error);
-    }
-}
-
-static void
-request_remove_agent(Request *req, NMSecretAgent *agent)
-{
-    NMAgentManager *self;
-
-    g_return_if_fail(req != NULL);
-    g_return_if_fail(agent != NULL);
-
-    self = req->self;
-
-    if (agent == req->current) {
-        nm_assert(!g_slist_find(req->pending, agent));
-
-        _LOGD(agent, "current agent removed from secrets request " LOG_REQ_FMT, LOG_REQ_ARG(req));
-
-        switch (req->request_type) {
-        case REQUEST_TYPE_CON_GET:
-        case REQUEST_TYPE_CON_SAVE:
-        case REQUEST_TYPE_CON_DEL:
-            /* This cancels the pending authorization requests. */
-            nm_clear_pointer(&req->con.chain, nm_auth_chain_destroy);
-            break;
-        default:
-            g_assert_not_reached();
-        }
-
-        request_next_agent(req);
-    } else if (g_slist_find(req->pending, agent)) {
-        req->pending = g_slist_remove(req->pending, agent);
-
-        _LOGD(agent, "agent removed from secrets request " LOG_REQ_FMT, LOG_REQ_ARG(req));
-
-        g_object_unref(agent);
-    }
-}
-
-static gboolean
-request_start(gpointer user_data)
-{
-    Request *req = user_data;
-
-    req->idle_id = 0;
-
-    switch (req->request_type) {
-    case REQUEST_TYPE_CON_GET:
-        if (_con_get_try_complete_early(req))
-            goto out;
-        break;
-    default:
-        break;
-    }
-    request_next_agent(req);
-
-out:
-    return FALSE;
-}
-
-/*****************************************************************************/
-
-static void
-_con_get_request_done(NMSecretAgent *      agent,
-                      NMSecretAgentCallId *call_id,
-                      GVariant *           secrets,
-                      GError *             error,
-                      gpointer             user_data)
-{
-    NMAgentManager *self;
-    Request *       req = user_data;
-    GVariant *      setting_secrets;
-    const char *    agent_dbus_owner;
-    gs_free char *  agent_name = NULL;
-
-    g_return_if_fail(call_id == req->current_call_id);
-    g_return_if_fail(agent == req->current);
-    g_return_if_fail(req->request_type == REQUEST_TYPE_CON_GET);
-
-    self = req->self;
-
-    req->current_call_id = NULL;
-
-    if (error) {
-        if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
-            _LOGD(agent, "get secrets request cancelled: " LOG_REQ_FMT, LOG_REQ_ARG(req));
-            return;
-        }
-
-        _LOGD(agent,
-              "agent failed secrets request " LOG_REQ_FMT ": %s",
-              LOG_REQ_ARG(req),
-              error->message);
-
-        if (g_error_matches(error, NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_USER_CANCELED)) {
-            error = g_error_new_literal(NM_AGENT_MANAGER_ERROR,
-                                        NM_AGENT_MANAGER_ERROR_USER_CANCELED,
-                                        "User canceled the secrets request.");
-            req_complete_error(req, error);
-            g_error_free(error);
-        } else {
-            /* Tell the failed agent we're no longer interested. */
-            nm_secret_agent_cancel_call(req->current, req->current_call_id);
-
-            /* Try the next agent */
-            request_next_agent(req);
-            maybe_remove_agent_on_error(self, agent, error);
-        }
-        return;
-    }
-
-    /* Ensure the setting we wanted secrets for got returned and has something in it */
-    setting_secrets =
-        g_variant_lookup_value(secrets, req->con.get.setting_name, NM_VARIANT_TYPE_SETTING);
-    if (!setting_secrets || !g_variant_n_children(setting_secrets)) {
-        _LOGD(agent, "agent returned no secrets for request " LOG_REQ_FMT, LOG_REQ_ARG(req));
-        /* Try the next agent */
-        request_next_agent(req);
-        return;
-    }
-
-    _LOGD(agent, "agent returned secrets for request " LOG_REQ_FMT, LOG_REQ_ARG(req));
-
-    agent_name = nm_utils_uid_to_name(nm_secret_agent_get_owner_uid(agent));
-    if (agent_name && !g_utf8_validate(agent_name, -1, NULL)) {
-        /* Needs to be UTF-8 valid since it may be pushed through D-Bus */
-        nm_clear_g_free(&agent_name);
-    }
-
-    agent_dbus_owner = nm_secret_agent_get_dbus_owner(agent);
-
-    req_complete(req, secrets, agent_dbus_owner, agent_name, NULL);
-}
-
-static void
-set_secrets_not_required(NMConnection *connection, GVariant *dict)
-{
-    GVariantIter iter, setting_iter;
-    const char * setting_name = NULL;
-    GVariant *   setting_dict = NULL;
-
-    /* Iterate through the settings dicts */
-    g_variant_iter_init(&iter, dict);
-    while (g_variant_iter_next(&iter, "{&s@a{sv}}", &setting_name, &setting_dict)) {
-        const char *key_name = NULL;
-        NMSetting * setting;
-        GVariant *  val;
-
-        setting = nm_connection_get_setting_by_name(connection, setting_name);
-        if (setting) {
-            /* Now through each secret in the setting and mark it as not required */
-            g_variant_iter_init(&setting_iter, setting_dict);
-            while (g_variant_iter_next(&setting_iter, "{&sv}", &key_name, &val)) {
-                /* For each secret, set the flag that it's not required; VPN
-                 * secrets need slightly different treatment here since the
-                 * "secrets" property is actually a dictionary of secrets.
-                 */
-                if (strcmp(setting_name, NM_SETTING_VPN_SETTING_NAME) == 0
-                    && strcmp(key_name, NM_SETTING_VPN_SECRETS) == 0
-                    && g_variant_is_of_type(val, G_VARIANT_TYPE("a{ss}"))) {
-                    GVariantIter vpn_secret_iter;
-                    const char * secret_name, *secret;
-
-                    g_variant_iter_init(&vpn_secret_iter, val);
-                    while (g_variant_iter_next(&vpn_secret_iter, "{&s&s}", &secret_name, &secret))
-                        nm_setting_set_secret_flags(setting,
-                                                    secret_name,
-                                                    NM_SETTING_SECRET_FLAG_NOT_REQUIRED,
-                                                    NULL);
-                } else
-                    nm_setting_set_secret_flags(setting,
-                                                key_name,
-                                                NM_SETTING_SECRET_FLAG_NOT_REQUIRED,
-                                                NULL);
-                g_variant_unref(val);
-            }
-        }
-        g_variant_unref(setting_dict);
-    }
-}
-
-static void
-_con_get_request_start_proceed(Request *req, gboolean include_system_secrets)
-{
-    NMConnection *tmp;
-
-    g_return_if_fail(req->request_type == REQUEST_TYPE_CON_GET);
-
-    tmp = nm_simple_connection_new_clone(req->con.connection);
-    nm_connection_clear_secrets(tmp);
-    if (include_system_secrets) {
-        if (req->con.get.existing_secrets)
-            (void) nm_connection_update_secrets(tmp,
-                                                req->con.get.setting_name,
-                                                req->con.get.existing_secrets,
-                                                NULL);
-    } else {
-        /* Update secret flags in the temporary connection to indicate that
-         * the system secrets we're not sending to the agent aren't required,
-         * so the agent can properly validate UI controls and such.
-         */
-        if (req->con.get.existing_secrets)
-            set_secrets_not_required(tmp, req->con.get.existing_secrets);
-    }
-
-    req->current_call_id = nm_secret_agent_get_secrets(req->current,
-                                                       req->con.path,
-                                                       tmp,
-                                                       req->con.get.setting_name,
-                                                       (const char **) req->con.get.hints,
-                                                       req->con.get.flags,
-                                                       _con_get_request_done,
-                                                       req);
-    if (!req->current_call_id) {
-        g_warn_if_reached();
-        request_next_agent(req);
-    }
-
-    g_object_unref(tmp);
-}
-
-static void
-_con_get_request_start_validated(NMAuthChain *          chain,
-                                 GDBusMethodInvocation *context,
-                                 gpointer               user_data)
-{
-    NMAgentManager *self;
-    Request *       req = user_data;
-    const char *    perm;
-
-    g_return_if_fail(req->request_type == REQUEST_TYPE_CON_GET);
-
-    self = req->self;
-
-    req->con.chain = NULL;
-
-    /* If the agent obtained the 'modify' permission, we send all system secrets
-     * to it.  If it didn't, we still ask it for secrets, but we don't send
-     * any system secrets.
-     */
-    perm = nm_auth_chain_get_data(chain, "perm");
-    g_assert(perm);
-    if (nm_auth_chain_get_result(chain, perm) == NM_AUTH_CALL_RESULT_YES)
-        req->con.current_has_modify = TRUE;
-
-    _LOGD(req->current,
-          "agent " LOG_REQ_FMT " MODIFY check result %s",
-          LOG_REQ_ARG(req),
-          req->con.current_has_modify ? "YES" : "NO");
-
-    _con_get_request_start_proceed(req, req->con.current_has_modify);
-}
-
-static void
-_con_get_request_start(Request *req)
-{
-    NMAgentManager *     self;
-    NMSettingConnection *s_con;
-    const char *         agent_dbus_owner, *perm;
-
-    self = req->self;
-
-    req->con.current_has_modify = FALSE;
-
-    agent_dbus_owner = nm_secret_agent_get_dbus_owner(req->current);
-
-    /* If the request flags allow user interaction, and there are existing
-     * system secrets (or blank secrets that are supposed to be system-owned),
-     * check whether the agent has the 'modify' permission before sending those
-     * secrets to the agent.  We shouldn't leak system-owned secrets to
-     * unprivileged users.
-     */
-    if ((req->con.get.flags != NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE)
-        && (req->con.get.existing_secrets
-            || _nm_connection_aggregate(req->con.connection,
-                                        NM_CONNECTION_AGGREGATE_ANY_SYSTEM_SECRET_FLAGS,
-                                        NULL))) {
-        _LOGD(NULL,
-              "(" LOG_REQ_FMT ") request has system secrets; checking agent %s for MODIFY",
-              LOG_REQ_ARG(req),
-              agent_dbus_owner);
-
-        req->con.chain = nm_auth_chain_new_subject(nm_secret_agent_get_subject(req->current),
-                                                   NULL,
-                                                   _con_get_request_start_validated,
-                                                   req);
-        nm_assert(req->con.chain);
-
-        /* If the caller is the only user in the connection's permissions, then
-         * we use the 'modify.own' permission instead of 'modify.system'.  If the
-         * request affects more than just the caller, require 'modify.system'.
-         */
-        s_con = nm_connection_get_setting_connection(req->con.connection);
-        g_assert(s_con);
-        if (nm_setting_connection_get_num_permissions(s_con) == 1)
-            perm = NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN;
-        else
-            perm = NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM;
-        nm_auth_chain_set_data(req->con.chain, "perm", (gpointer) perm, NULL);
-
-        nm_auth_chain_add_call_unsafe(req->con.chain, perm, TRUE);
-    } else {
-        _LOGD(NULL,
-              "(" LOG_REQ_FMT ") requesting user-owned secrets from agent %s",
-              LOG_REQ_ARG(req),
-              agent_dbus_owner);
-
-        _con_get_request_start_proceed(req, FALSE);
-    }
-}
-
-static gboolean
-_con_get_try_complete_early(Request *req)
-{
-    NMAgentManager * self;
-    gs_unref_variant GVariant *setting_secrets = NULL;
-    gs_unref_object NMConnection *tmp          = NULL;
-    GError *                      error        = NULL;
-
-    self = req->self;
-
-    /* Check if there are any existing secrets */
-    if (req->con.get.existing_secrets)
-        setting_secrets = g_variant_lookup_value(req->con.get.existing_secrets,
-                                                 req->con.get.setting_name,
-                                                 NM_VARIANT_TYPE_SETTING);
-
-    if (!setting_secrets || !g_variant_n_children(setting_secrets))
-        return FALSE;
-
-    /* The connection already had secrets; check if any more are required.
-     * If no more are required, we're done.  If secrets are still needed,
-     * ask a secret agent for more.  This allows admins to provide generic
-     * secrets but allow additional user-specific ones as well.
-     */
-    tmp = nm_simple_connection_new_clone(req->con.connection);
-    g_assert(tmp);
-
-    if (!nm_connection_update_secrets(tmp,
-                                      req->con.get.setting_name,
-                                      req->con.get.existing_secrets,
-                                      &error)) {
-        req_complete_error(req, error);
-        g_clear_error(&error);
-        return TRUE;
-    }
-    /* Do we have everything we need? */
-    if (NM_FLAGS_HAS(req->con.get.flags, NM_SECRET_AGENT_GET_SECRETS_FLAG_ONLY_SYSTEM)
-        || ((nm_connection_need_secrets(tmp, NULL) == NULL)
-            && !NM_FLAGS_HAS(req->con.get.flags, NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW))) {
-        _LOGD(NULL, "(" LOG_REQ_FMT ") system settings secrets sufficient", LOG_REQ_ARG(req));
-
-        /* Got everything, we're done */
-        req_complete(req, req->con.get.existing_secrets, NULL, NULL, NULL);
-        return TRUE;
-    }
-
-    _LOGD(NULL,
-          "(" LOG_REQ_FMT ") system settings secrets insufficient, asking agents",
-          LOG_REQ_ARG(req));
-
-    /* We don't, so ask some agents for additional secrets */
-    if (req->con.get.flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_NO_ERRORS && !req->pending) {
-        /* The request initiated from GetSecrets() via DBus,
-         * don't error out if any secrets are missing. */
-        req_complete(req, req->con.get.existing_secrets, NULL, NULL, NULL);
-        return TRUE;
-    }
-
-    /* Couldn't get secrets from system settings, so now we ask the
-     * agents for secrets.  Let the Agent Manager handle which agents
-     * we'll ask and in which order.
-     */
-    return FALSE;
-}
-
-/**
- * nm_agent_manager_get_secrets:
- * @self:
- * @path:
- * @connection:
- * @subject:
- * @existing_secrets:
- * @flags:
- * @hints:
- * @callback:
- * @callback_data:
- *
- * Requests secrets for a connection.
- *
- * This function cannot fail. The callback will be invoked
- * asynchronously, but it will always be invoked exactly once.
- * Even for cancellation and disposing of @self. In those latter
- * cases, the callback is invoked synchronously during the cancellation/
- * disposal.
- *
- * Returns: a call-id to cancel the call.
- */
-NMAgentManagerCallId
-nm_agent_manager_get_secrets(NMAgentManager *             self,
-                             const char *                 path,
-                             NMConnection *               connection,
-                             NMAuthSubject *              subject,
-                             GVariant *                   existing_secrets,
-                             const char *                 setting_name,
-                             NMSecretAgentGetSecretsFlags flags,
-                             const char *const *          hints,
-                             NMAgentSecretsResultFunc     callback,
-                             gpointer                     callback_data)
-{
-    Request *req;
-
-    g_return_val_if_fail(self != NULL, NULL);
-    g_return_val_if_fail(path && *path, NULL);
-    g_return_val_if_fail(NM_IS_CONNECTION(connection), NULL);
-    g_return_val_if_fail(callback != NULL, NULL);
-
-    nm_log_dbg(LOGD_SETTINGS,
-               "Secrets requested for connection %s (%s/%s)",
-               path,
-               nm_connection_get_id(connection),
-               setting_name);
-
-    /* NOTE: a few things in the Request handling depend on existing_secrets
-     * being NULL if there aren't any system-owned secrets for this connection.
-     * This in turn depends on nm_connection_to_dbus() and nm_setting_to_hash()
-     * both returning NULL if they didn't hash anything.
-     */
-    req = request_new(self, REQUEST_TYPE_CON_GET, nm_connection_get_id(connection), subject);
-
-    req->con.path       = g_strdup(path);
-    req->con.connection = g_object_ref(connection);
-    if (existing_secrets)
-        req->con.get.existing_secrets = g_variant_ref(existing_secrets);
-    req->con.get.setting_name  = g_strdup(setting_name);
-    req->con.get.hints         = g_strdupv((char **) hints);
-    req->con.get.flags         = flags;
-    req->con.get.callback      = callback;
-    req->con.get.callback_data = callback_data;
-
-    if (!(req->con.get.flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_ONLY_SYSTEM))
-        request_add_agents(self, req);
-    req->idle_id = g_idle_add(request_start, req);
-    return req;
-}
-
-void
-nm_agent_manager_cancel_secrets(NMAgentManager *self, NMAgentManagerCallId request_id)
-{
-    g_return_if_fail(self != NULL);
-    g_return_if_fail(request_id);
-    g_return_if_fail(request_id->request_type == REQUEST_TYPE_CON_GET);
-
-    nm_assert(c_list_contains(&NM_AGENT_MANAGER_GET_PRIVATE(self)->request_lst_head,
-                              &request_id->request_lst));
-
-    c_list_unlink(&request_id->request_lst);
-
-    req_complete_cancel(request_id, FALSE);
-}
-
-/*****************************************************************************/
-
-static void
-_con_save_request_done(NMSecretAgent *      agent,
-                       NMSecretAgentCallId *call_id,
-                       GVariant *           secrets,
-                       GError *             error,
-                       gpointer             user_data)
-{
-    NMAgentManager *self;
-    Request *       req = user_data;
-    const char *    agent_dbus_owner;
-
-    g_return_if_fail(call_id == req->current_call_id);
-    g_return_if_fail(agent == req->current);
-    g_return_if_fail(req->request_type == REQUEST_TYPE_CON_SAVE);
-
-    self = req->self;
-
-    req->current_call_id = NULL;
-
-    if (error) {
-        if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
-            _LOGD(agent, "save secrets request cancelled: " LOG_REQ_FMT, LOG_REQ_ARG(req));
-            return;
-        }
-
-        _LOGD(agent,
-              "agent failed save secrets request " LOG_REQ_FMT ": %s",
-              LOG_REQ_ARG(req),
-              error->message);
-        /* Try the next agent */
-        request_next_agent(req);
-        maybe_remove_agent_on_error(self, agent, error);
-        return;
-    }
-
-    _LOGD(agent, "agent saved secrets for request " LOG_REQ_FMT, LOG_REQ_ARG(req));
-
-    agent_dbus_owner = nm_secret_agent_get_dbus_owner(agent);
-    req_complete(req, NULL, NULL, agent_dbus_owner, NULL);
-}
-
-static void
-_con_save_request_start(Request *req)
-{
-    req->current_call_id = nm_secret_agent_save_secrets(req->current,
-                                                        req->con.path,
-                                                        req->con.connection,
-                                                        _con_save_request_done,
-                                                        req);
-    if (!req->current_call_id) {
-        g_warn_if_reached();
-        request_next_agent(req);
-    }
-}
-
-void
-nm_agent_manager_save_secrets(NMAgentManager *self,
-                              const char *    path,
-                              NMConnection *  connection,
-                              NMAuthSubject * subject)
-{
-    Request *req;
-
-    g_return_if_fail(self);
-    g_return_if_fail(path && *path);
-    g_return_if_fail(NM_IS_CONNECTION(connection));
-
-    nm_log_dbg(LOGD_SETTINGS,
-               "Saving secrets for connection %s (%s)",
-               path,
-               nm_connection_get_id(connection));
-
-    req = request_new(self, REQUEST_TYPE_CON_SAVE, nm_connection_get_id(connection), subject);
-    req->con.path       = g_strdup(path);
-    req->con.connection = g_object_ref(connection);
-
-    request_add_agents(self, req);
-    req->idle_id = g_idle_add(request_start, req);
-}
-
-/*****************************************************************************/
-
-static void
-_con_del_request_done(NMSecretAgent *      agent,
-                      NMSecretAgentCallId *call_id,
-                      GVariant *           secrets,
-                      GError *             error,
-                      gpointer             user_data)
-{
-    NMAgentManager *self;
-    Request *       req = user_data;
-
-    g_return_if_fail(call_id == req->current_call_id);
-    g_return_if_fail(agent == req->current);
-    g_return_if_fail(req->request_type == REQUEST_TYPE_CON_DEL);
-
-    self = req->self;
-
-    req->current_call_id = NULL;
-
-    if (error) {
-        if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
-            _LOGD(agent, "delete secrets request cancelled: " LOG_REQ_FMT, LOG_REQ_ARG(req));
-            return;
-        }
-
-        _LOGD(agent,
-              "agent failed delete secrets request " LOG_REQ_FMT ": %s",
-              LOG_REQ_ARG(req),
-              error->message);
-    } else {
-        _LOGD(agent, "agent deleted secrets for request " LOG_REQ_FMT, LOG_REQ_ARG(req));
-    }
-
-    /* Tell the next agent to delete secrets */
-    request_next_agent(req);
-    if (error)
-        maybe_remove_agent_on_error(self, agent, error);
-}
-
-static void
-_con_del_request_start(Request *req)
-{
-    req->current_call_id = nm_secret_agent_delete_secrets(req->current,
-                                                          req->con.path,
-                                                          req->con.connection,
-                                                          _con_del_request_done,
-                                                          req);
-    if (!req->current_call_id) {
-        g_warn_if_reached();
-        request_next_agent(req);
-    }
-}
-
-void
-nm_agent_manager_delete_secrets(NMAgentManager *self, const char *path, NMConnection *connection)
-{
-    NMAuthSubject *subject;
-    Request *      req;
-
-    g_return_if_fail(self != NULL);
-    g_return_if_fail(path && *path);
-    g_return_if_fail(NM_IS_CONNECTION(connection));
-
-    nm_log_dbg(LOGD_SETTINGS,
-               "Deleting secrets for connection %s (%s)",
-               path,
-               nm_connection_get_id(connection));
-
-    subject = nm_auth_subject_new_internal();
-    req     = request_new(self, REQUEST_TYPE_CON_DEL, nm_connection_get_id(connection), subject);
-    req->con.path       = g_strdup(path);
-    req->con.connection = g_object_ref(connection);
-    g_object_unref(subject);
-
-    request_add_agents(self, req);
-    req->idle_id = g_idle_add(request_start, req);
-}
-
-/*****************************************************************************/
-
-gboolean
-nm_agent_manager_has_agent_with_permission(NMAgentManager *self,
-                                           const char *    username,
-                                           const char *    permission)
-{
-    NMAgentManagerPrivate *priv;
-    NMSecretAgent *        agent;
-
-    g_return_val_if_fail(NM_IS_AGENT_MANAGER(self), FALSE);
-    g_return_val_if_fail(username, FALSE);
-    g_return_val_if_fail(permission, FALSE);
-
-    priv = NM_AGENT_MANAGER_GET_PRIVATE(self);
-
-    c_list_for_each_entry (agent, &priv->agent_lst_head, agent_lst) {
-        if (!agent->fully_registered)
-            continue;
-        if (!nm_streq0(nm_secret_agent_get_owner_username(agent), username))
-            continue;
-        if (nm_secret_agent_has_permission(agent, permission))
-            return TRUE;
-    }
-
-    return FALSE;
-}
-
-/*****************************************************************************/
-
-gboolean
-nm_agent_manager_all_agents_have_capability(NMAgentManager *          manager,
-                                            NMAuthSubject *           subject,
-                                            NMSecretAgentCapabilities capability)
-{
-    NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE(manager);
-    NMSecretAgent *        agent;
-    gboolean               subject_is_unix_process =
-        (nm_auth_subject_get_subject_type(subject) == NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS);
-    gulong subject_uid =
-        subject_is_unix_process ? nm_auth_subject_get_unix_process_uid(subject) : 0u;
-
-    c_list_for_each_entry (agent, &priv->agent_lst_head, agent_lst) {
-        if (!agent->fully_registered)
-            continue;
-        if (subject_is_unix_process && nm_secret_agent_get_owner_uid(agent) != subject_uid)
-            continue;
-        if (!(nm_secret_agent_get_capabilities(agent) & capability))
-            return FALSE;
-    }
-
-    return TRUE;
-}
-
-/*****************************************************************************/
-
-static void
-authority_changed_cb(NMAuthManager *auth_manager, NMAgentManager *self)
-{
-    NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE(self);
-    NMSecretAgent *        agent;
-
-    c_list_for_each_entry (agent, &priv->agent_lst_head, agent_lst)
-        _agent_create_auth_chain(self, agent, NULL);
-}
-
-/*****************************************************************************/
-
-static void
-nm_agent_manager_init(NMAgentManager *self)
-{
-    NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE(self);
-
-    priv->agent_version_id = 1;
-    c_list_init(&priv->agent_lst_head);
-    c_list_init(&priv->request_lst_head);
-}
-
-static void
-constructed(GObject *object)
-{
-    NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE(object);
-
-    G_OBJECT_CLASS(nm_agent_manager_parent_class)->constructed(object);
-
-    priv->auth_mgr        = g_object_ref(nm_auth_manager_get());
-    priv->session_monitor = g_object_ref(nm_session_monitor_get());
-
-    nm_dbus_object_export(NM_DBUS_OBJECT(object));
-
-    g_signal_connect(priv->auth_mgr,
-                     NM_AUTH_MANAGER_SIGNAL_CHANGED,
-                     G_CALLBACK(authority_changed_cb),
-                     object);
-}
-
-static void
-dispose(GObject *object)
-{
-    NMAgentManager *       self = NM_AGENT_MANAGER(object);
-    NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE(self);
-    Request *              request;
-    NMSecretAgent *        agent;
-
-    while ((request = c_list_first_entry(&priv->request_lst_head, Request, request_lst))) {
-        c_list_unlink(&request->request_lst);
-        req_complete_cancel(request, TRUE);
-    }
-
-    while ((agent = c_list_first_entry(&priv->agent_lst_head, NMSecretAgent, agent_lst)))
-        _agent_remove(self, agent);
-
-    if (priv->auth_mgr) {
-        g_signal_handlers_disconnect_by_func(priv->auth_mgr,
-                                             G_CALLBACK(authority_changed_cb),
-                                             object);
-        g_clear_object(&priv->auth_mgr);
-    }
-
-    nm_dbus_object_unexport(NM_DBUS_OBJECT(object));
-
-    g_clear_object(&priv->session_monitor);
-
-    G_OBJECT_CLASS(nm_agent_manager_parent_class)->dispose(object);
-}
-
-static const NMDBusInterfaceInfoExtended interface_info_agent_manager = {
-    .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT(
-        NM_DBUS_INTERFACE_AGENT_MANAGER,
-        .methods = NM_DEFINE_GDBUS_METHOD_INFOS(
-            NM_DEFINE_DBUS_METHOD_INFO_EXTENDED(
-                NM_DEFINE_GDBUS_METHOD_INFO_INIT(
-                    "Register",
-                    .in_args =
-                        NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("identifier", "s"), ), ),
-                .handle = impl_agent_manager_register, ),
-            NM_DEFINE_DBUS_METHOD_INFO_EXTENDED(
-                NM_DEFINE_GDBUS_METHOD_INFO_INIT(
-                    "RegisterWithCapabilities",
-                    .in_args = NM_DEFINE_GDBUS_ARG_INFOS(
-                        NM_DEFINE_GDBUS_ARG_INFO("identifier", "s"),
-                        NM_DEFINE_GDBUS_ARG_INFO("capabilities", "u"), ), ),
-                .handle = impl_agent_manager_register_with_capabilities, ),
-            NM_DEFINE_DBUS_METHOD_INFO_EXTENDED(NM_DEFINE_GDBUS_METHOD_INFO_INIT("Unregister", ),
-                                                .handle = impl_agent_manager_unregister, ), ), ),
-};
-
-static void
-nm_agent_manager_class_init(NMAgentManagerClass *agent_manager_class)
-{
-    GObjectClass *     object_class      = G_OBJECT_CLASS(agent_manager_class);
-    NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(agent_manager_class);
-
-    dbus_object_class->export_path     = NM_DBUS_EXPORT_PATH_STATIC(NM_DBUS_PATH_AGENT_MANAGER);
-    dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS(&interface_info_agent_manager);
-
-    object_class->constructed = constructed;
-    object_class->dispose     = dispose;
-
-    signals[AGENT_REGISTERED] = g_signal_new(NM_AGENT_MANAGER_AGENT_REGISTERED,
-                                             G_OBJECT_CLASS_TYPE(object_class),
-                                             G_SIGNAL_RUN_FIRST,
-                                             0,
-                                             NULL,
-                                             NULL,
-                                             g_cclosure_marshal_VOID__OBJECT,
-                                             G_TYPE_NONE,
-                                             1,
-                                             G_TYPE_OBJECT);
-}