settings: port to gdbus

This commit is contained in:
Dan Winship 2015-04-15 14:53:30 -04:00
parent 9f8de603e3
commit df6706813a
10 changed files with 427 additions and 550 deletions

View file

@ -8,8 +8,6 @@
Called by secret Agents to register their ability to provide and save
network secrets.
</tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_agent_manager_register"/>
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg name="identifier" type="s" direction="in">
<tp:docstring>
Identifies this agent; only one agent in each user session may use the
@ -27,8 +25,6 @@
<tp:docstring>
Like Register() but indicates agent capabilities to NetworkManager.
</tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_agent_manager_register_with_capabilities"/>
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg name="identifier" type="s" direction="in">
<tp:docstring>
See the Register() method's identifier argument.
@ -47,8 +43,6 @@
longer handle requests for network secrets. Agents are automatically
unregistered when they disconnect from D-Bus.
</tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_agent_manager_unregister"/>
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
</method>
</interface>

View file

@ -15,8 +15,6 @@
stored in persistent storage or sent to a Secret Agent for storage,
depending on the flags associated with each secret.
</tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_settings_connection_update"/>
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg name="properties" type="a{sa{sv}}" direction="in">
<tp:docstring>
New connection settings, properties, and (optionally) secrets.
@ -37,8 +35,6 @@
reloaded from disk (either automatically on file change or
due to an explicit ReloadConnections call).
</tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_settings_connection_update_unsaved"/>
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg name="properties" type="a{sa{sv}}" direction="in">
<tp:docstring>
New connection settings, properties, and (optionally) secrets.
@ -50,8 +46,6 @@
<tp:docstring>
Delete the connection.
</tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_settings_connection_delete"/>
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
</method>
<method name="GetSettings">
@ -61,8 +55,6 @@
to the network, as those are often protected. Secrets must
be requested separately using the GetSecrets() call.
</tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_settings_connection_get_settings"/>
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg name="settings" type="a{sa{sv}}" direction="out" tp:type="String_String_Variant_Map_Map">
<tp:docstring>
The nested settings maps describing this object.
@ -77,8 +69,6 @@
the requestor's session will be returned. The user will never
be prompted for secrets as a result of this request.
</tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_settings_connection_get_secrets"/>
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg name="setting_name" type="s" direction="in">
<tp:docstring>
Name of the setting to return secrets for. If empty, all
@ -97,8 +87,6 @@
<tp:docstring>
Clear the secrets belonging to this network connection profile.
</tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_settings_connection_clear_secrets"/>
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
</method>
<method name="Save">
@ -106,8 +94,6 @@
Saves a "dirty" connection (that had previously been
updated with UpdateUnsaved) to persistent storage.
</tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_settings_connection_save"/>
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
</method>
<signal name="Updated">

View file

@ -10,7 +10,6 @@
<tp:docstring>
List the saved network connections known to NetworkManager.
</tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_settings_list_connections"/>
<arg name="connections" type="ao" direction="out">
<tp:docstring>
List of connections.
@ -22,8 +21,6 @@
<tp:docstring>
Retrieve the object path of a connection, given that connection's UUID.
</tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_settings_get_connection_by_uuid"/>
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg name="uuid" type="s" direction="in">
<tp:docstring>
The UUID to find the connection object path for.
@ -43,8 +40,6 @@
the network described by the new connection, and (2) the connection
is allowed to be started automatically.
</tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_settings_add_connection"/>
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg name="connection" type="a{sa{sv}}" direction="in">
<tp:docstring>
Connection settings and properties.
@ -69,8 +64,6 @@
connection is reloaded from disk (either automatically on file
change or due to an explicit ReloadConnections call).
</tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_settings_add_connection_unsaved"/>
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg name="connection" type="a{sa{sv}}" direction="in">
<tp:docstring>
Connection settings and properties.
@ -93,8 +86,6 @@
harmless.) As with AddConnection(), this operation does not
necessarily start the network connection.
</tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_settings_load_connections"/>
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg name="filenames" type="as" direction="in">
<tp:docstring>
Array of paths to on-disk connection profiles in directories
@ -125,8 +116,6 @@
change, so you only need to use this command if you have set
"monitor-connection-files=false" in NetworkManager.conf.
</tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_settings_reload_connections"/>
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg name="status" type="b" direction="out">
<tp:docstring>
Success or failure.
@ -138,8 +127,6 @@
<tp:docstring>
Save the hostname to persistent configuration.
</tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_settings_save_hostname"/>
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg name="hostname" type="s" direction="in">
<tp:docstring>
The hostname to save to persistent configuration. If blank, the persistent hostname is cleared.

View file

@ -23,16 +23,11 @@
#include <string.h>
#include <pwd.h>
#include <dbus/dbus-glib.h>
#include <dbus/dbus-glib-lowlevel.h>
#include "nm-default.h"
#include "nm-dbus-interface.h"
#include "nm-agent-manager.h"
#include "nm-secret-agent.h"
#include "nm-auth-utils.h"
#include "nm-dbus-glib-types.h"
#include "nm-auth-utils.h"
#include "nm-setting-vpn.h"
#include "nm-setting-connection.h"
#include "nm-enum-types.h"
@ -41,6 +36,9 @@
#include "nm-session-monitor.h"
#include "nm-simple-connection.h"
#include "NetworkManagerUtils.h"
#include "nm-core-internal.h"
#include "nmdbus-agent-manager.h"
G_DEFINE_TYPE (NMAgentManager, nm_agent_manager, NM_TYPE_EXPORTED_OBJECT)
@ -78,20 +76,6 @@ static void request_remove_agent (Request *req, NMSecretAgent *agent, GSList **p
static void request_next_agent (Request *req);
static void impl_agent_manager_register (NMAgentManager *self,
const char *identifier,
DBusGMethodInvocation *context);
static void impl_agent_manager_register_with_capabilities (NMAgentManager *self,
const char *identifier,
NMSecretAgentCapabilities capabilities,
DBusGMethodInvocation *context);
static void impl_agent_manager_unregister (NMAgentManager *self,
DBusGMethodInvocation *context);
#include "nm-agent-manager-glue.h"
/*************************************************************/
static gboolean
@ -130,6 +114,17 @@ remove_agent (NMAgentManager *self, const char *owner)
return TRUE;
}
/* Call this *after* calling request_next_agent() */
static void
maybe_remove_agent_on_error (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))
remove_agent (nm_agent_manager_get (), nm_secret_agent_get_dbus_owner (agent));
}
/*************************************************************/
static gboolean
@ -190,7 +185,7 @@ validate_identifier (const char *identifier, GError **error)
static void
agent_register_permissions_done (NMAuthChain *chain,
GError *error,
DBusGMethodInvocation *context,
GDBusMethodInvocation *context,
gpointer user_data)
{
NMAgentManager *self = NM_AGENT_MANAGER (user_data);
@ -211,8 +206,7 @@ agent_register_permissions_done (NMAuthChain *chain,
NM_AGENT_MANAGER_ERROR_PERMISSION_DENIED,
"Failed to request agent permissions: (%d) %s",
error->code, error->message);
dbus_g_method_return_error (context, local);
g_error_free (local);
g_dbus_method_invocation_take_error (context, local);
} else {
agent = nm_auth_chain_steal_data (chain, "agent");
g_assert (agent);
@ -229,7 +223,7 @@ agent_register_permissions_done (NMAuthChain *chain,
g_hash_table_insert (priv->agents, g_strdup (sender), agent);
nm_log_dbg (LOGD_AGENTS, "(%s) agent registered",
nm_secret_agent_get_description (agent));
dbus_g_method_return (context);
g_dbus_method_invocation_return_value (context, NULL);
/* Signal an agent was registered */
g_signal_emit (self, signals[AGENT_REGISTERED], 0, agent);
@ -271,9 +265,9 @@ agent_disconnected_cb (NMSecretAgent *agent, gpointer user_data)
static void
impl_agent_manager_register_with_capabilities (NMAgentManager *self,
GDBusMethodInvocation *context,
const char *identifier,
NMSecretAgentCapabilities capabilities,
DBusGMethodInvocation *context)
guint32 capabilities)
{
NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self);
NMAuthSubject *subject;
@ -334,22 +328,21 @@ impl_agent_manager_register_with_capabilities (NMAgentManager *self,
done:
if (error)
dbus_g_method_return_error (context, error);
g_clear_error (&error);
g_dbus_method_invocation_take_error (context, error);
g_clear_object (&subject);
}
static void
impl_agent_manager_register (NMAgentManager *self,
const char *identifier,
DBusGMethodInvocation *context)
GDBusMethodInvocation *context,
const char *identifier)
{
impl_agent_manager_register_with_capabilities (self, identifier, 0, context);
impl_agent_manager_register_with_capabilities (self, context, identifier, 0);
}
static void
impl_agent_manager_unregister (NMAgentManager *self,
DBusGMethodInvocation *context)
GDBusMethodInvocation *context)
{
GError *error = NULL;
char *sender = NULL;
@ -373,19 +366,18 @@ impl_agent_manager_unregister (NMAgentManager *self,
goto done;
}
dbus_g_method_return (context);
g_dbus_method_invocation_return_value (context, NULL);
done:
if (error)
dbus_g_method_return_error (context, error);
g_clear_error (&error);
g_dbus_method_invocation_take_error (context, error);
g_free (sender);
}
/*************************************************************/
typedef void (*RequestCompleteFunc) (Request *req,
GHashTable *secrets,
GVariant *secrets,
const char *agent_dbus_owner,
const char *agent_username,
GError *error,
@ -481,7 +473,7 @@ request_free (Request *req)
static void
req_complete_success (Request *req,
GHashTable *secrets,
GVariant *secrets,
const char *agent_dbus_owner,
const char *agent_uname)
{
@ -658,7 +650,7 @@ typedef struct {
char *setting_name;
char **hints;
GHashTable *existing_secrets;
GVariant *existing_secrets;
NMAgentSecretsResultFunc callback;
gpointer callback_data;
@ -682,7 +674,7 @@ connection_request_free (gpointer data)
g_free (req->setting_name);
g_strfreev (req->hints);
if (req->existing_secrets)
g_hash_table_unref (req->existing_secrets);
g_variant_unref (req->existing_secrets);
if (req->chain)
nm_auth_chain_unref (req->chain);
}
@ -710,7 +702,7 @@ connection_request_add_agent (Request *parent, NMSecretAgent *agent)
static ConnectionRequest *
connection_request_new_get (NMConnection *connection,
NMAuthSubject *subject,
GHashTable *existing_secrets,
GVariant *existing_secrets,
const char *setting_name,
const char *verb,
NMSecretAgentGetSecretsFlags flags,
@ -740,7 +732,7 @@ connection_request_new_get (NMConnection *connection,
req->connection = g_object_ref (connection);
if (existing_secrets)
req->existing_secrets = g_hash_table_ref (existing_secrets);
req->existing_secrets = g_variant_ref (existing_secrets);
req->setting_name = g_strdup (setting_name);
req->hints = g_strdupv ((char **) hints);
req->flags = flags;
@ -779,13 +771,13 @@ connection_request_new_other (NMConnection *connection,
static void
get_done_cb (NMSecretAgent *agent,
gconstpointer call_id,
GHashTable *secrets,
GVariant *secrets,
GError *error,
gpointer user_data)
{
Request *parent = user_data;
ConnectionRequest *req = user_data;
GHashTable *setting_secrets;
GVariant *setting_secrets;
const char *agent_dbus_owner;
struct passwd *pw;
char *agent_uname = NULL;
@ -799,7 +791,7 @@ get_done_cb (NMSecretAgent *agent,
error ? error->code : -1,
(error && error->message) ? error->message : "(unknown)");
if (dbus_g_error_has_name (error, NM_DBUS_INTERFACE_SECRET_AGENT ".UserCanceled")) {
if (_nm_dbus_error_has_name (error, NM_DBUS_INTERFACE_SECRET_AGENT ".UserCanceled")) {
error = g_error_new_literal (NM_AGENT_MANAGER_ERROR,
NM_AGENT_MANAGER_ERROR_USER_CANCELED,
"User canceled the secrets request.");
@ -808,13 +800,14 @@ get_done_cb (NMSecretAgent *agent,
} else {
/* Try the next agent */
request_next_agent (parent);
maybe_remove_agent_on_error (agent, error);
}
return;
}
/* Ensure the setting we wanted secrets for got returned and has something in it */
setting_secrets = g_hash_table_lookup (secrets, req->setting_name);
if (!setting_secrets || !g_hash_table_size (setting_secrets)) {
setting_secrets = g_variant_lookup_value (secrets, req->setting_name, NM_VARIANT_TYPE_SETTING);
if (!setting_secrets || !g_variant_n_children (setting_secrets)) {
nm_log_dbg (LOGD_AGENTS, "(%s) agent returned no secrets for request %p/%s/%s",
nm_secret_agent_get_description (agent),
req, parent->detail, req->setting_name);
@ -841,40 +834,40 @@ get_done_cb (NMSecretAgent *agent,
}
static void
set_secrets_not_required (NMConnection *connection, GHashTable *hash)
set_secrets_not_required (NMConnection *connection, GVariant *dict)
{
GHashTableIter iter, setting_iter;
GVariantIter iter, setting_iter;
const char *setting_name = NULL;
GHashTable *setting_hash = NULL;
GVariant *setting_dict = NULL;
/* Iterate through the settings hashes */
g_hash_table_iter_init (&iter, hash);
while (g_hash_table_iter_next (&iter,
(gpointer *) &setting_name,
(gpointer *) &setting_hash)) {
/* 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;
GValue *val;
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_hash_table_iter_init (&setting_iter, setting_hash);
while (g_hash_table_iter_next (&setting_iter, (gpointer *) &key_name, (gpointer *) &val)) {
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 hash table of secrets.
* "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) {
GHashTableIter vpn_secret_iter;
const char *secret_name;
&& 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_hash_table_iter_init (&vpn_secret_iter, g_value_get_boxed (val));
while (g_hash_table_iter_next (&vpn_secret_iter, (gpointer *) &secret_name, NULL))
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);
}
}
}
@ -889,13 +882,8 @@ get_agent_request_secrets (ConnectionRequest *req, gboolean include_system_secre
tmp = nm_simple_connection_new_clone (req->connection);
nm_connection_clear_secrets (tmp);
if (include_system_secrets) {
if (req->existing_secrets) {
GVariant *secrets_dict;
secrets_dict = nm_utils_connection_hash_to_dict (req->existing_secrets);
(void) nm_connection_update_secrets (tmp, req->setting_name, secrets_dict, NULL);
g_variant_unref (secrets_dict);
}
if (req->existing_secrets)
(void) nm_connection_update_secrets (tmp, req->setting_name, req->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,
@ -924,7 +912,7 @@ get_agent_request_secrets (ConnectionRequest *req, gboolean include_system_secre
static void
get_agent_modify_auth_cb (NMAuthChain *chain,
GError *error,
DBusGMethodInvocation *context,
GDBusMethodInvocation *context,
gpointer user_data)
{
Request *parent = user_data;
@ -1058,19 +1046,18 @@ get_start (gpointer user_data)
{
Request *parent = user_data;
ConnectionRequest *req = user_data;
GHashTable *setting_secrets = NULL;
GVariant *setting_secrets = NULL;
parent->idle_id = 0;
/* Check if there are any existing secrets */
if (req->existing_secrets)
setting_secrets = g_hash_table_lookup (req->existing_secrets, req->setting_name);
setting_secrets = g_variant_lookup_value (req->existing_secrets, req->setting_name, NM_VARIANT_TYPE_SETTING);
if (setting_secrets && g_hash_table_size (setting_secrets)) {
if (setting_secrets && g_variant_n_children (setting_secrets)) {
NMConnection *tmp;
GError *error = NULL;
gboolean new_secrets = (req->flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW);
GVariant *secrets_dict;
/* The connection already had secrets; check if any more are required.
* If no more are required, we're done. If secrets are still needed,
@ -1080,8 +1067,7 @@ get_start (gpointer user_data)
tmp = nm_simple_connection_new_clone (req->connection);
g_assert (tmp);
secrets_dict = nm_utils_connection_hash_to_dict (req->existing_secrets);
if (!nm_connection_update_secrets (tmp, req->setting_name, secrets_dict, &error)) {
if (!nm_connection_update_secrets (tmp, req->setting_name, req->existing_secrets, &error)) {
req_complete_error (parent, error);
g_clear_error (&error);
} else {
@ -1107,7 +1093,6 @@ get_start (gpointer user_data)
request_next_agent (parent);
}
}
g_variant_unref (secrets_dict);
g_object_unref (tmp);
} else {
/* Couldn't get secrets from system settings, so now we ask the
@ -1117,12 +1102,15 @@ get_start (gpointer user_data)
request_next_agent (parent);
}
if (setting_secrets)
g_variant_unref (setting_secrets);
return FALSE;
}
static void
get_complete_cb (Request *parent,
GHashTable *secrets,
GVariant *secrets,
const char *agent_dbus_owner,
const char *agent_username,
GError *error,
@ -1163,7 +1151,7 @@ guint32
nm_agent_manager_get_secrets (NMAgentManager *self,
NMConnection *connection,
NMAuthSubject *subject,
GHashTable *existing_secrets,
GVariant *existing_secrets,
const char *setting_name,
NMSecretAgentGetSecretsFlags flags,
const char **hints,
@ -1233,7 +1221,7 @@ nm_agent_manager_cancel_secrets (NMAgentManager *self,
static void
save_done_cb (NMSecretAgent *agent,
gconstpointer call_id,
GHashTable *secrets,
GVariant *secrets,
GError *error,
gpointer user_data)
{
@ -1251,6 +1239,7 @@ save_done_cb (NMSecretAgent *agent,
(error && error->message) ? error->message : "(unknown)");
/* Try the next agent */
request_next_agent (parent);
maybe_remove_agent_on_error (agent, error);
return;
}
@ -1280,7 +1269,7 @@ save_next_cb (Request *parent)
static void
save_complete_cb (Request *req,
GHashTable *secrets,
GVariant *secrets,
const char *agent_dbus_owner,
const char *agent_username,
GError *error,
@ -1327,7 +1316,7 @@ nm_agent_manager_save_secrets (NMAgentManager *self,
static void
delete_done_cb (NMSecretAgent *agent,
gconstpointer call_id,
GHashTable *secrets,
GVariant *secrets,
GError *error,
gpointer user_data)
{
@ -1347,6 +1336,8 @@ delete_done_cb (NMSecretAgent *agent,
/* Tell the next agent to delete secrets */
request_next_agent (req);
if (error)
maybe_remove_agent_on_error (agent, error);
}
static void
@ -1367,7 +1358,7 @@ delete_next_cb (Request *parent)
static void
delete_complete_cb (Request *req,
GHashTable *secrets,
GVariant *secrets,
const char *agent_dbus_owner,
const char *agent_username,
GError *error,
@ -1460,7 +1451,7 @@ nm_agent_manager_all_agents_have_capability (NMAgentManager *manager,
static void
agent_permissions_changed_done (NMAuthChain *chain,
GError *error,
DBusGMethodInvocation *context,
GDBusMethodInvocation *context,
gpointer user_data)
{
NMAgentManager *self = NM_AGENT_MANAGER (user_data);
@ -1609,9 +1600,9 @@ nm_agent_manager_class_init (NMAgentManagerClass *agent_manager_class)
G_TYPE_OBJECT);
nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (agent_manager_class),
&dbus_glib_nm_agent_manager_object_info);
dbus_g_error_domain_register (NM_AGENT_MANAGER_ERROR,
NM_DBUS_INTERFACE_AGENT_MANAGER,
NM_TYPE_AGENT_MANAGER_ERROR);
NMDBUS_TYPE_AGENT_MANAGER_SKELETON,
"Register", impl_agent_manager_register,
"RegisterWithCapabilities", impl_agent_manager_register_with_capabilities,
"Unregister", impl_agent_manager_unregister,
NULL);
}

View file

@ -56,7 +56,7 @@ typedef void (*NMAgentSecretsResultFunc) (NMAgentManager *manager,
gboolean agent_has_modify,
const char *setting_name,
NMSecretAgentGetSecretsFlags flags,
GHashTable *secrets,
GVariant *secrets,
GError *error,
gpointer user_data,
gpointer other_data2,
@ -65,7 +65,7 @@ typedef void (*NMAgentSecretsResultFunc) (NMAgentManager *manager,
guint32 nm_agent_manager_get_secrets (NMAgentManager *manager,
NMConnection *connection,
NMAuthSubject *subject,
GHashTable *existing_secrets,
GVariant *existing_secrets,
const char *setting_name,
NMSecretAgentGetSecretsFlags flags,
const char **hints,

View file

@ -23,17 +23,14 @@
#include <sys/types.h>
#include <pwd.h>
#include <dbus/dbus-glib.h>
#include <dbus/dbus-glib-lowlevel.h>
#include "nm-default.h"
#include "nm-dbus-interface.h"
#include "nm-secret-agent.h"
#include "nm-bus-manager.h"
#include "nm-dbus-glib-types.h"
#include "nm-auth-subject.h"
#include "nm-simple-connection.h"
#include "NetworkManagerUtils.h"
#include "nmdbus-secret-agent.h"
G_DEFINE_TYPE (NMSecretAgent, nm_secret_agent, G_TYPE_OBJECT)
@ -52,7 +49,7 @@ typedef struct {
GSList *permissions;
DBusGProxy *proxy;
NMDBusSecretAgent *proxy;
GHashTable *requests;
} NMSecretAgentPrivate;
@ -68,7 +65,7 @@ static guint signals[LAST_SIGNAL] = { 0 };
typedef struct {
NMSecretAgent *agent;
DBusGProxyCall *call;
GCancellable *cancellable;
char *path;
char *setting_name;
NMSecretAgentCallback callback;
@ -90,6 +87,7 @@ request_new (NMSecretAgent *agent,
r->setting_name = g_strdup (setting_name);
r->callback = callback;
r->callback_data = callback_data;
r->cancellable = g_cancellable_new ();
return r;
}
@ -98,6 +96,7 @@ request_free (Request *r)
{
g_free (r->path);
g_free (r->setting_name);
g_object_unref (r->cancellable);
g_slice_free (Request, r);
}
@ -258,25 +257,26 @@ nm_secret_agent_has_permission (NMSecretAgent *agent, const char *permission)
/*************************************************************/
static void
get_callback (DBusGProxy *proxy,
DBusGProxyCall *call,
void *user_data)
get_callback (GObject *proxy,
GAsyncResult *result,
gpointer user_data)
{
Request *r = user_data;
NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (r->agent);
GVariant *secrets = NULL;
GError *error = NULL;
GHashTable *secrets = NULL;
g_return_if_fail (call == r->call);
if (!g_cancellable_is_cancelled (r->cancellable)) {
nmdbus_secret_agent_call_get_secrets_finish (priv->proxy, &secrets, result, &error);
if (error)
g_dbus_error_strip_remote_error (error);
dbus_g_proxy_end_call (proxy, call, &error,
DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, &secrets,
G_TYPE_INVALID);
r->callback (r->agent, r->call, secrets, error, r->callback_data);
if (secrets)
g_hash_table_unref (secrets);
g_clear_error (&error);
g_hash_table_remove (priv->requests, call);
r->callback (r->agent, r, secrets, error, r->callback_data);
g_clear_pointer (&secrets, g_variant_unref);
g_clear_error (&error);
}
g_hash_table_remove (priv->requests, r);
}
gconstpointer
@ -289,8 +289,8 @@ nm_secret_agent_get_secrets (NMSecretAgent *self,
gpointer callback_data)
{
NMSecretAgentPrivate *priv;
static const char *no_hints[] = { NULL };
GVariant *dict;
GHashTable *hash;
Request *r;
g_return_val_if_fail (self != NULL, NULL);
@ -301,123 +301,81 @@ nm_secret_agent_get_secrets (NMSecretAgent *self,
g_return_val_if_fail (priv->proxy != NULL, NULL);
dict = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL);
hash = nm_utils_connection_dict_to_hash (dict);
g_variant_unref (dict);
/* Mask off the private flags if present */
flags &= ~NM_SECRET_AGENT_GET_SECRETS_FLAG_ONLY_SYSTEM;
flags &= ~NM_SECRET_AGENT_GET_SECRETS_FLAG_NO_ERRORS;
r = request_new (self, nm_connection_get_path (connection), setting_name, callback, callback_data);
r->call = dbus_g_proxy_begin_call_with_timeout (priv->proxy,
"GetSecrets",
get_callback,
r,
NULL,
120000, /* 120 seconds */
DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, hash,
DBUS_TYPE_G_OBJECT_PATH, nm_connection_get_path (connection),
G_TYPE_STRING, setting_name,
G_TYPE_STRV, hints,
G_TYPE_UINT, flags,
G_TYPE_INVALID);
g_hash_table_insert (priv->requests, r->call, r);
nmdbus_secret_agent_call_get_secrets (priv->proxy,
dict,
nm_connection_get_path (connection),
setting_name,
hints ? hints : no_hints,
flags,
r->cancellable,
get_callback, r);
g_hash_table_insert (priv->requests, r, r);
g_hash_table_destroy (hash);
return r->call;
return r;
}
static void
cancel_done (DBusGProxy *proxy, DBusGProxyCall *call_id, void *user_data)
cancel_done (GObject *proxy, GAsyncResult *result, gpointer user_data)
{
char *description = user_data;
GError *error = NULL;
if (!dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID)) {
nm_log_dbg (LOGD_AGENTS, "(%s): agent failed to cancel secrets: (%d) %s",
(const char *) user_data,
error ? error->code : -1,
error && error->message ? error->message : "(unknown)");
if (!nmdbus_secret_agent_call_cancel_get_secrets_finish (NMDBUS_SECRET_AGENT (proxy), result, &error)) {
g_dbus_error_strip_remote_error (error);
nm_log_dbg (LOGD_AGENTS, "(%s): agent failed to cancel secrets: %s",
description, error->message);
g_clear_error (&error);
}
g_free (description);
}
void
nm_secret_agent_cancel_secrets (NMSecretAgent *self, gconstpointer call)
{
NMSecretAgentPrivate *priv;
Request *r;
Request *r = (gpointer) call;
g_return_if_fail (self != NULL);
priv = NM_SECRET_AGENT_GET_PRIVATE (self);
g_return_if_fail (priv->proxy != NULL);
r = g_hash_table_lookup (priv->requests, call);
g_return_if_fail (r != NULL);
dbus_g_proxy_cancel_call (priv->proxy, (gpointer) call);
g_cancellable_cancel (r->cancellable);
dbus_g_proxy_begin_call (priv->proxy,
"CancelGetSecrets",
cancel_done,
g_strdup (nm_secret_agent_get_description (self)),
g_free,
DBUS_TYPE_G_OBJECT_PATH, r->path,
G_TYPE_STRING, r->setting_name,
G_TYPE_INVALID);
g_hash_table_remove (priv->requests, call);
nmdbus_secret_agent_call_cancel_get_secrets (priv->proxy,
r->path, r->setting_name,
NULL,
cancel_done,
g_strdup (nm_secret_agent_get_description (self)));
}
/*************************************************************/
static void
agent_save_delete_cb (DBusGProxy *proxy,
DBusGProxyCall *call,
void *user_data)
agent_save_cb (GObject *proxy,
GAsyncResult *result,
gpointer user_data)
{
Request *r = user_data;
NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (r->agent);
GError *error = NULL;
g_return_if_fail (call == r->call);
if (!g_cancellable_is_cancelled (r->cancellable)) {
nmdbus_secret_agent_call_save_secrets_finish (priv->proxy, result, &error);
if (error)
g_dbus_error_strip_remote_error (error);
r->callback (r->agent, r, NULL, error, r->callback_data);
g_clear_error (&error);
}
dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID);
r->callback (r->agent, r->call, NULL, error, r->callback_data);
g_clear_error (&error);
g_hash_table_remove (priv->requests, call);
}
static gpointer
agent_new_save_delete (NMSecretAgent *self,
NMConnection *connection,
NMConnectionSerializationFlags flags,
const char *method,
NMSecretAgentCallback callback,
gpointer callback_data)
{
NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self);
GVariant *dict;
GHashTable *hash;
Request *r;
const char *cpath = nm_connection_get_path (connection);
dict = nm_connection_to_dbus (connection, flags);
hash = nm_utils_connection_dict_to_hash (dict);
g_variant_unref (dict);
r = request_new (self, cpath, NULL, callback, callback_data);
r->call = dbus_g_proxy_begin_call_with_timeout (priv->proxy,
method,
agent_save_delete_cb,
r,
NULL,
10000, /* 10 seconds */
DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, hash,
DBUS_TYPE_G_OBJECT_PATH, cpath,
G_TYPE_INVALID);
g_hash_table_insert (priv->requests, r->call, r);
g_hash_table_destroy (hash);
return r->call;
g_hash_table_remove (priv->requests, r);
}
gconstpointer
@ -426,16 +384,46 @@ nm_secret_agent_save_secrets (NMSecretAgent *self,
NMSecretAgentCallback callback,
gpointer callback_data)
{
NMSecretAgentPrivate *priv;
GVariant *dict;
Request *r;
const char *cpath;
g_return_val_if_fail (self != NULL, NULL);
g_return_val_if_fail (connection != NULL, NULL);
priv = NM_SECRET_AGENT_GET_PRIVATE (self);
cpath = nm_connection_get_path (connection);
/* Caller should have ensured that only agent-owned secrets exist in 'connection' */
return agent_new_save_delete (self,
connection,
NM_CONNECTION_SERIALIZE_ALL,
"SaveSecrets",
callback,
callback_data);
dict = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL);
r = request_new (self, cpath, NULL, callback, callback_data);
nmdbus_secret_agent_call_save_secrets (priv->proxy,
dict, cpath,
NULL,
agent_save_cb, r);
g_hash_table_insert (priv->requests, r, r);
return r;
}
static void
agent_delete_cb (GObject *proxy,
GAsyncResult *result,
gpointer user_data)
{
Request *r = user_data;
NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (r->agent);
GError *error = NULL;
if (!g_cancellable_is_cancelled (r->cancellable)) {
nmdbus_secret_agent_call_delete_secrets_finish (priv->proxy, result, &error);
r->callback (r->agent, r, NULL, error, r->callback_data);
g_clear_error (&error);
}
g_hash_table_remove (priv->requests, r);
}
gconstpointer
@ -444,54 +432,54 @@ nm_secret_agent_delete_secrets (NMSecretAgent *self,
NMSecretAgentCallback callback,
gpointer callback_data)
{
NMSecretAgentPrivate *priv;
GVariant *dict;
Request *r;
const char *cpath;
g_return_val_if_fail (self != NULL, NULL);
g_return_val_if_fail (connection != NULL, NULL);
priv = NM_SECRET_AGENT_GET_PRIVATE (self);
cpath = nm_connection_get_path (connection);
/* No secrets sent; agents must be smart enough to track secrets using the UUID or something */
return agent_new_save_delete (self,
connection,
NM_CONNECTION_SERIALIZE_NO_SECRETS,
"DeleteSecrets",
callback,
callback_data);
dict = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_NO_SECRETS);
r = request_new (self, cpath, NULL, callback, callback_data);
nmdbus_secret_agent_call_delete_secrets (priv->proxy,
dict, cpath,
NULL,
agent_delete_cb, r);
g_hash_table_insert (priv->requests, r, r);
return r;
}
static void proxy_cleanup (NMSecretAgent *self);
static void
name_owner_changed_cb (NMBusManager *dbus_mgr,
const char *name,
const char *old_owner,
const char *new_owner,
name_owner_changed_cb (GObject *proxy,
GParamSpec *pspec,
gpointer user_data)
{
NMSecretAgent *self = NM_SECRET_AGENT (user_data);
NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self);
char *owner;
if (!new_owner && !g_strcmp0 (old_owner, priv->dbus_owner))
proxy_cleanup (self);
}
static void
proxy_cleanup (NMSecretAgent *self)
{
NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self);
if (priv->proxy) {
g_signal_handlers_disconnect_by_func (priv->proxy, proxy_cleanup, self);
owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY (proxy));
if (!owner) {
g_signal_handlers_disconnect_by_func (priv->proxy, name_owner_changed_cb, self);
g_clear_object (&priv->proxy);
g_signal_handlers_disconnect_by_func (nm_bus_manager_get (), name_owner_changed_cb, self);
g_signal_emit (self, signals[DISCONNECTED], 0);
g_clear_pointer (&priv->dbus_owner, g_free);
}
} else
g_free (owner);
}
/*************************************************************/
NMSecretAgent *
nm_secret_agent_new (DBusGMethodInvocation *context,
nm_secret_agent_new (GDBusMethodInvocation *context,
NMAuthSubject *subject,
const char *identifier,
NMSecretAgentCapabilities capabilities)
@ -500,6 +488,7 @@ nm_secret_agent_new (DBusGMethodInvocation *context,
NMSecretAgentPrivate *priv;
char *hash_str;
struct passwd *pw;
GDBusProxy *proxy;
g_return_val_if_fail (context != NULL, NULL);
g_return_val_if_fail (NM_IS_AUTH_SUBJECT (subject), NULL);
@ -523,18 +512,17 @@ nm_secret_agent_new (DBusGMethodInvocation *context,
priv->hash = g_str_hash (hash_str);
g_free (hash_str);
priv->proxy = nm_bus_manager_new_proxy (nm_bus_manager_get (),
context,
priv->dbus_owner,
NM_DBUS_PATH_SECRET_AGENT,
NM_DBUS_INTERFACE_SECRET_AGENT);
g_assert (priv->proxy);
g_signal_connect_swapped (priv->proxy, "destroy",
G_CALLBACK (proxy_cleanup), self);
g_signal_connect (nm_bus_manager_get (),
NM_BUS_MANAGER_NAME_OWNER_CHANGED,
proxy = nm_bus_manager_new_proxy (nm_bus_manager_get (),
context,
NMDBUS_TYPE_SECRET_AGENT_PROXY,
priv->dbus_owner,
NM_DBUS_PATH_SECRET_AGENT,
NM_DBUS_INTERFACE_SECRET_AGENT);
g_assert (proxy);
g_signal_connect (proxy, "notify::g-name-owner",
G_CALLBACK (name_owner_changed_cb),
self);
priv->proxy = NMDBUS_SECRET_AGENT (proxy);
return self;
}
@ -553,7 +541,7 @@ dispose (GObject *object)
{
NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (object);
proxy_cleanup (NM_SECRET_AGENT (object));
g_clear_object (&priv->proxy);
g_clear_object (&priv->subject);
G_OBJECT_CLASS (nm_secret_agent_parent_class)->dispose (object);

View file

@ -21,7 +21,6 @@
#ifndef __NETWORKMANAGER_SECRET_AGENT_H__
#define __NETWORKMANAGER_SECRET_AGENT_H__
#include <nm-connection.h>
#include "nm-default.h"
@ -46,7 +45,7 @@ typedef struct {
GType nm_secret_agent_get_type (void);
NMSecretAgent *nm_secret_agent_new (DBusGMethodInvocation *context,
NMSecretAgent *nm_secret_agent_new (GDBusMethodInvocation *context,
NMAuthSubject *subject,
const char *identifier,
NMSecretAgentCapabilities capabilities);
@ -78,7 +77,7 @@ gboolean nm_secret_agent_has_permission (NMSecretAgent *agent,
typedef void (*NMSecretAgentCallback) (NMSecretAgent *agent,
gconstpointer call,
GHashTable *new_secrets, /* NULL for save & delete */
GVariant *new_secrets, /* NULL for save & delete */
GError *error,
gpointer user_data);

View file

@ -24,12 +24,10 @@
#include <string.h>
#include <nm-dbus-interface.h>
#include <dbus/dbus-glib-lowlevel.h>
#include "nm-default.h"
#include "nm-settings-connection.h"
#include "nm-session-monitor.h"
#include "nm-dbus-glib-types.h"
#include "nm-auth-utils.h"
#include "nm-auth-subject.h"
#include "nm-agent-manager.h"
@ -37,10 +35,11 @@
#include "nm-core-internal.h"
#include "nm-audit-manager.h"
#include "nmdbus-settings-connection.h"
#define SETTINGS_TIMESTAMPS_FILE NMSTATEDIR "/timestamps"
#define SETTINGS_SEEN_BSSIDS_FILE NMSTATEDIR "/seen-bssids"
#define _LOG_DOMAIN LOGD_SETTINGS
#define _LOG_PREFIX_NAME "settings-connection"
@ -81,33 +80,6 @@
#define _LOGW(...) _LOG (LOGL_WARN , _LOG_DOMAIN, self, __VA_ARGS__)
#define _LOGE(...) _LOG (LOGL_ERR , _LOG_DOMAIN, self, __VA_ARGS__)
static void impl_settings_connection_get_settings (NMSettingsConnection *self,
DBusGMethodInvocation *context);
static void impl_settings_connection_update (NMSettingsConnection *self,
GHashTable *new_settings,
DBusGMethodInvocation *context);
static void impl_settings_connection_update_unsaved (NMSettingsConnection *self,
GHashTable *new_settings,
DBusGMethodInvocation *context);
static void impl_settings_connection_save (NMSettingsConnection *self,
DBusGMethodInvocation *context);
static void impl_settings_connection_delete (NMSettingsConnection *self,
DBusGMethodInvocation *context);
static void impl_settings_connection_get_secrets (NMSettingsConnection *self,
const gchar *setting_name,
DBusGMethodInvocation *context);
static void impl_settings_connection_clear_secrets (NMSettingsConnection *self,
DBusGMethodInvocation *context);
#include "nm-settings-connection-glue.h"
static void nm_settings_connection_connection_interface_init (NMConnectionInterface *iface);
G_DEFINE_TYPE_WITH_CODE (NMSettingsConnection, nm_settings_connection, NM_TYPE_EXPORTED_OBJECT,
@ -183,88 +155,93 @@ typedef struct {
typedef gboolean (*ForEachSecretFunc) (NMSettingSecretFlags flags,
gpointer user_data);
static void
static GVariant *
for_each_secret (NMConnection *self,
GHashTable *secrets,
GVariant *secrets,
gboolean remove_non_secrets,
ForEachSecretFunc callback,
gpointer callback_data)
{
GHashTableIter iter;
GVariantBuilder secrets_builder, setting_builder;
GVariantIter secrets_iter, *setting_iter;
const char *setting_name;
GHashTable *setting_hash;
/* This function, given a hash of hashes representing new secrets of
* an NMConnection, walks through each toplevel hash (which represents a
* NMSetting), and for each setting, walks through that setting hash's
/* This function, given a dict of dicts representing new secrets of
* an NMConnection, walks through each toplevel dict (which represents a
* NMSetting), and for each setting, walks through that setting dict's
* properties. For each property that's a secret, it will check that
* secret's flags in the backing NMConnection object, and call a supplied
* callback.
*
* The one complexity is that the VPN setting's 'secrets' property is
* *also* a hash table (since the key/value pairs are arbitrary and known
* *also* a dict (since the key/value pairs are arbitrary and known
* only to the VPN plugin itself). That means we have three levels of
* GHashTables that we potentially have to traverse here. When we hit the
* dicts that we potentially have to traverse here. When we hit the
* VPN setting's 'secrets' property, we special-case that and iterate over
* each item in that 'secrets' hash table, calling the supplied callback
* each item in that 'secrets' dict, calling the supplied callback
* each time.
*/
g_return_if_fail (callback);
g_return_val_if_fail (callback, NULL);
/* Walk through the list of setting hashes */
g_hash_table_iter_init (&iter, secrets);
while (g_hash_table_iter_next (&iter, (gpointer) &setting_name, (gpointer) &setting_hash)) {
g_variant_iter_init (&secrets_iter, secrets);
g_variant_builder_init (&secrets_builder, NM_VARIANT_TYPE_CONNECTION);
while (g_variant_iter_next (&secrets_iter, "{&sa{sv}}", &setting_name, &setting_iter)) {
NMSetting *setting;
GHashTableIter secret_iter;
const char *secret_name;
GValue *val;
GVariant *val;
if (g_hash_table_size (setting_hash) == 0)
continue;
/* Get the actual NMSetting from the connection so we can get secret flags
* from the connection data, since flags aren't secrets. What we're
* iterating here is just the secrets, not a whole connection.
*/
setting = nm_connection_get_setting_by_name (self, setting_name);
if (setting == NULL)
if (setting == NULL) {
g_variant_iter_free (setting_iter);
continue;
}
/* Walk through the list of keys in each setting hash */
g_hash_table_iter_init (&secret_iter, setting_hash);
while (g_hash_table_iter_next (&secret_iter, (gpointer) &secret_name, (gpointer) &val)) {
g_variant_builder_init (&setting_builder, NM_VARIANT_TYPE_SETTING);
while (g_variant_iter_next (setting_iter, "{sv}", &secret_name, &val)) {
NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE;
/* VPN secrets need slightly different treatment here since the
* "secrets" property is actually a hash table of secrets.
*/
if (NM_IS_SETTING_VPN (setting) && (g_strcmp0 (secret_name, NM_SETTING_VPN_SECRETS) == 0)) {
GHashTableIter vpn_secrets_iter;
if (NM_IS_SETTING_VPN (setting) && !g_strcmp0 (secret_name, NM_SETTING_VPN_SECRETS)) {
GVariantBuilder vpn_secrets_builder;
GVariantIter vpn_secrets_iter;
const char *vpn_secret_name, *secret;
/* Iterate through each secret from the VPN hash in the overall secrets hash */
g_hash_table_iter_init (&vpn_secrets_iter, g_value_get_boxed (val));
while (g_hash_table_iter_next (&vpn_secrets_iter, (gpointer) &secret_name, NULL)) {
secret_flags = NM_SETTING_SECRET_FLAG_NONE;
if (!nm_setting_get_secret_flags (setting, secret_name, &secret_flags, NULL)) {
if (remove_non_secrets)
g_hash_table_iter_remove (&vpn_secrets_iter);
/* Iterate through each secret from the VPN dict in the overall secrets dict */
g_variant_builder_init (&vpn_secrets_builder, G_VARIANT_TYPE ("a{ss}"));
g_variant_iter_init (&vpn_secrets_iter, val);
while (g_variant_iter_next (&vpn_secrets_iter, "{&s&s}", &vpn_secret_name, &secret)) {
if (!nm_setting_get_secret_flags (setting, vpn_secret_name, &secret_flags, NULL)) {
if (!remove_non_secrets)
g_variant_builder_add (&vpn_secrets_builder, "{ss}", vpn_secret_name, secret);
continue;
}
if (!callback (secret_flags, callback_data))
g_hash_table_iter_remove (&vpn_secrets_iter);
if (callback (secret_flags, callback_data))
g_variant_builder_add (&vpn_secrets_builder, "{ss}", vpn_secret_name, secret);
}
g_variant_builder_add (&setting_builder, "{sv}",
secret_name, g_variant_builder_end (&vpn_secrets_builder));
} else {
if (!nm_setting_get_secret_flags (setting, secret_name, &secret_flags, NULL)) {
if (remove_non_secrets)
g_hash_table_iter_remove (&secret_iter);
if (!remove_non_secrets)
g_variant_builder_add (&setting_builder, "{sv}", secret_name, val);
continue;
}
if (!callback (secret_flags, callback_data))
g_hash_table_iter_remove (&secret_iter);
if (callback (secret_flags, callback_data))
g_variant_builder_add (&setting_builder, "{sv}", secret_name, val);
}
g_variant_unref (val);
}
g_variant_iter_free (setting_iter);
g_variant_builder_add (&secrets_builder, "{sa{sv}}", setting_name, &setting_builder);
}
return g_variant_builder_end (&secrets_builder);
}
typedef gboolean (*FindSecretFunc) (NMSettingSecretFlags flags,
@ -284,22 +261,24 @@ find_secret_for_each_func (NMSettingSecretFlags flags,
if (!data->found)
data->found = data->find_func (flags, data->find_func_data);
return TRUE;
return FALSE;
}
static gboolean
find_secret (NMConnection *self,
GHashTable *secrets,
GVariant *secrets,
FindSecretFunc callback,
gpointer callback_data)
{
FindSecretData data;
GVariant *dummy;
data.find_func = callback;
data.find_func_data = callback_data;
data.found = FALSE;
for_each_secret (self, secrets, FALSE, find_secret_for_each_func, &data);
dummy = for_each_secret (self, secrets, FALSE, find_secret_for_each_func, &data);
g_variant_unref (dummy);
return data.found;
}
@ -836,7 +815,7 @@ agent_secrets_done_cb (NMAgentManager *manager,
gboolean agent_has_modify,
const char *setting_name,
NMSecretAgentGetSecretsFlags flags,
GHashTable *secrets,
GVariant *secrets,
GError *error,
gpointer user_data,
gpointer other_data2,
@ -925,21 +904,19 @@ agent_secrets_done_cb (NMAgentManager *manager,
| NM_SETTING_SECRET_FLAG_NOT_REQUIRED);
}
for_each_secret (NM_CONNECTION (self), secrets, TRUE, validate_secret_flags, &cmp_flags);
/* Update the connection with our existing secrets from backing storage */
nm_connection_clear_secrets (NM_CONNECTION (self));
dict = nm_connection_to_dbus (priv->system_secrets, NM_CONNECTION_SERIALIZE_ONLY_SECRETS);
if (!dict || nm_connection_update_secrets (NM_CONNECTION (self), setting_name, dict, &local)) {
GVariant *secrets_dict;
GVariant *filtered_secrets;
/* Update the connection with the agent's secrets; by this point if any
* system-owned secrets exist in 'secrets' the agent that provided them
* will have been authenticated, so those secrets can replace the existing
* system secrets.
*/
secrets_dict = nm_utils_connection_hash_to_dict (secrets);
if (nm_connection_update_secrets (NM_CONNECTION (self), setting_name, secrets_dict, &local)) {
filtered_secrets = for_each_secret (NM_CONNECTION (self), secrets, TRUE, validate_secret_flags, &cmp_flags);
if (nm_connection_update_secrets (NM_CONNECTION (self), setting_name, filtered_secrets, &local)) {
/* Now that all secrets are updated, copy and cache new secrets,
* then save them to backing storage.
*/
@ -962,6 +939,8 @@ agent_secrets_done_cb (NMAgentManager *manager,
setting_name,
call_id);
}
g_variant_unref (filtered_secrets);
} else {
_LOGD ("(%s:%u) failed to update with agent secrets: (%d) %s",
setting_name,
@ -969,7 +948,6 @@ agent_secrets_done_cb (NMAgentManager *manager,
local ? local->code : -1,
(local && local->message) ? local->message : "(unknown)");
}
g_variant_unref (secrets_dict);
} else {
_LOGD ("(%s:%u) failed to update with existing secrets: (%d) %s",
setting_name,
@ -1012,7 +990,6 @@ nm_settings_connection_get_secrets (NMSettingsConnection *self,
{
NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
GVariant *existing_secrets;
GHashTable *existing_secrets_hash;
guint32 call_id = 0;
gs_free char *joined_hints = NULL;
@ -1035,11 +1012,12 @@ nm_settings_connection_get_secrets (NMSettingsConnection *self,
}
existing_secrets = nm_connection_to_dbus (priv->system_secrets, NM_CONNECTION_SERIALIZE_ONLY_SECRETS);
existing_secrets_hash = nm_utils_connection_dict_to_hash (existing_secrets);
if (existing_secrets)
g_variant_ref_sink (existing_secrets);
call_id = nm_agent_manager_get_secrets (priv->agent_mgr,
NM_CONNECTION (self),
subject,
existing_secrets_hash,
existing_secrets,
setting_name,
flags,
hints,
@ -1047,8 +1025,6 @@ nm_settings_connection_get_secrets (NMSettingsConnection *self,
self,
callback,
callback_data);
if (existing_secrets_hash)
g_hash_table_unref (existing_secrets_hash);
if (existing_secrets)
g_variant_unref (existing_secrets);
@ -1077,7 +1053,7 @@ nm_settings_connection_cancel_secrets (NMSettingsConnection *self,
/**** User authorization **************************************/
typedef void (*AuthCallback) (NMSettingsConnection *self,
DBusGMethodInvocation *context,
GDBusMethodInvocation *context,
NMAuthSubject *subject,
GError *error,
gpointer data);
@ -1085,7 +1061,7 @@ typedef void (*AuthCallback) (NMSettingsConnection *self,
static void
pk_auth_cb (NMAuthChain *chain,
GError *chain_error,
DBusGMethodInvocation *context,
GDBusMethodInvocation *context,
gpointer user_data)
{
NMSettingsConnection *self = NM_SETTINGS_CONNECTION (user_data);
@ -1134,7 +1110,7 @@ pk_auth_cb (NMAuthChain *chain,
* Returns: the #NMAuthSubject on success, or %NULL on failure and sets @error
*/
static NMAuthSubject *
_new_auth_subject (DBusGMethodInvocation *context, GError **error)
_new_auth_subject (GDBusMethodInvocation *context, GError **error)
{
NMAuthSubject *subject;
@ -1151,7 +1127,7 @@ _new_auth_subject (DBusGMethodInvocation *context, GError **error)
static void
auth_start (NMSettingsConnection *self,
DBusGMethodInvocation *context,
GDBusMethodInvocation *context,
NMAuthSubject *subject,
const char *check_permission,
AuthCallback callback,
@ -1239,16 +1215,15 @@ check_writable (NMConnection *self, GError **error)
static void
get_settings_auth_cb (NMSettingsConnection *self,
DBusGMethodInvocation *context,
GDBusMethodInvocation *context,
NMAuthSubject *subject,
GError *error,
gpointer data)
{
if (error)
dbus_g_method_return_error (context, error);
g_dbus_method_invocation_return_gerror (context, error);
else {
GVariant *settings;
GHashTable *settings_hash;
NMConnection *dupl_con;
NMSettingConnection *s_con;
NMSettingWireless *s_wifi;
@ -1286,17 +1261,15 @@ get_settings_auth_cb (NMSettingsConnection *self,
*/
settings = nm_connection_to_dbus (NM_CONNECTION (dupl_con), NM_CONNECTION_SERIALIZE_NO_SECRETS);
g_assert (settings);
settings_hash = nm_utils_connection_dict_to_hash (settings);
dbus_g_method_return (context, settings_hash);
g_hash_table_destroy (settings_hash);
g_variant_unref (settings);
g_dbus_method_invocation_return_value (context,
g_variant_new ("(@a{sa{sv}})", settings));
g_object_unref (dupl_con);
}
}
static void
impl_settings_connection_get_settings (NMSettingsConnection *self,
DBusGMethodInvocation *context)
GDBusMethodInvocation *context)
{
NMAuthSubject *subject;
GError *error = NULL;
@ -1305,14 +1278,12 @@ impl_settings_connection_get_settings (NMSettingsConnection *self,
if (subject) {
auth_start (self, context, subject, NULL, get_settings_auth_cb, NULL);
g_object_unref (subject);
} else {
dbus_g_method_return_error (context, error);
g_error_free (error);
}
} else
g_dbus_method_invocation_take_error (context, error);
}
typedef struct {
DBusGMethodInvocation *context;
GDBusMethodInvocation *context;
NMAgentManager *agent_mgr;
NMAuthSubject *subject;
NMConnection *new_settings;
@ -1320,7 +1291,7 @@ typedef struct {
} UpdateInfo;
typedef struct {
DBusGMethodInvocation *context;
GDBusMethodInvocation *context;
NMAuthSubject *subject;
} CallbackInfo;
@ -1384,9 +1355,9 @@ update_complete (NMSettingsConnection *self,
GError *error)
{
if (error)
dbus_g_method_return_error (info->context, error);
g_dbus_method_invocation_return_gerror (info->context, error);
else
dbus_g_method_return (info->context);
g_dbus_method_invocation_return_value (info->context, NULL);
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_UPDATE, NM_CONNECTION (self), !error,
info->subject, error ? error->message : NULL);
@ -1424,7 +1395,7 @@ con_update_cb (NMSettingsConnection *self,
static void
update_auth_cb (NMSettingsConnection *self,
DBusGMethodInvocation *context,
GDBusMethodInvocation *context,
NMAuthSubject *subject,
GError *error,
gpointer data)
@ -1492,8 +1463,8 @@ get_update_modify_permission (NMConnection *old, NMConnection *new)
static void
impl_settings_connection_update_helper (NMSettingsConnection *self,
GHashTable *new_settings,
DBusGMethodInvocation *context,
GDBusMethodInvocation *context,
GVariant *new_settings,
gboolean save_to_disk)
{
NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
@ -1515,14 +1486,9 @@ impl_settings_connection_update_helper (NMSettingsConnection *self,
/* Check if the settings are valid first */
if (new_settings) {
GVariant *new_settings_dict = nm_utils_connection_hash_to_dict (new_settings);
tmp = nm_simple_connection_new_from_dbus (new_settings_dict, &error);
g_variant_unref (new_settings_dict);
if (!tmp) {
g_assert (error);
tmp = nm_simple_connection_new_from_dbus (new_settings, &error);
if (!tmp)
goto error;
}
}
subject = _new_auth_subject (context, &error);
@ -1562,37 +1528,34 @@ error:
g_clear_object (&tmp);
g_clear_object (&subject);
dbus_g_method_return_error (context, error);
g_clear_error (&error);
g_dbus_method_invocation_take_error (context, error);
}
static void
impl_settings_connection_update (NMSettingsConnection *self,
GHashTable *new_settings,
DBusGMethodInvocation *context)
GDBusMethodInvocation *context,
GVariant *new_settings)
{
g_assert (new_settings);
impl_settings_connection_update_helper (self, new_settings, context, TRUE);
impl_settings_connection_update_helper (self, context, new_settings, TRUE);
}
static void
impl_settings_connection_update_unsaved (NMSettingsConnection *self,
GHashTable *new_settings,
DBusGMethodInvocation *context)
GDBusMethodInvocation *context,
GVariant *new_settings)
{
g_assert (new_settings);
impl_settings_connection_update_helper (self, new_settings, context, FALSE);
impl_settings_connection_update_helper (self, context, new_settings, FALSE);
}
static void
impl_settings_connection_save (NMSettingsConnection *self,
DBusGMethodInvocation *context)
GDBusMethodInvocation *context)
{
/* Do nothing if the connection is already synced with disk */
if (nm_settings_connection_get_unsaved (self))
impl_settings_connection_update_helper (self, NULL, context, TRUE);
impl_settings_connection_update_helper (self, context, NULL, TRUE);
else
dbus_g_method_return (context);
g_dbus_method_invocation_return_value (context, NULL);
}
static void
@ -1603,9 +1566,9 @@ con_delete_cb (NMSettingsConnection *self,
CallbackInfo *info = user_data;
if (error)
dbus_g_method_return_error (info->context, error);
g_dbus_method_invocation_return_gerror (info->context, error);
else
dbus_g_method_return (info->context);
g_dbus_method_invocation_return_value (info->context, NULL);
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DELETE, NM_CONNECTION (self),
!error, info->subject, error ? error->message : NULL);
@ -1614,7 +1577,7 @@ con_delete_cb (NMSettingsConnection *self,
static void
delete_auth_cb (NMSettingsConnection *self,
DBusGMethodInvocation *context,
GDBusMethodInvocation *context,
NMAuthSubject *subject,
GError *error,
gpointer data)
@ -1624,7 +1587,7 @@ delete_auth_cb (NMSettingsConnection *self,
if (error) {
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DELETE, NM_CONNECTION (self), FALSE, subject,
error->message);
dbus_g_method_return_error (context, error);
g_dbus_method_invocation_return_gerror (context, error);
return;
}
@ -1654,7 +1617,7 @@ get_modify_permission_basic (NMSettingsConnection *self)
static void
impl_settings_connection_delete (NMSettingsConnection *self,
DBusGMethodInvocation *context)
GDBusMethodInvocation *context)
{
NMAuthSubject *subject = NULL;
GError *error = NULL;
@ -1671,9 +1634,8 @@ impl_settings_connection_delete (NMSettingsConnection *self,
return;
out_err:
dbus_g_method_return_error (context, error);
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DELETE, NM_CONNECTION (self), FALSE, subject, error->message);
g_error_free (error);
g_dbus_method_invocation_take_error (context, error);
}
/**************************************************************/
@ -1687,14 +1649,13 @@ dbus_get_agent_secrets_cb (NMSettingsConnection *self,
gpointer user_data)
{
NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
DBusGMethodInvocation *context = user_data;
GDBusMethodInvocation *context = user_data;
GVariant *dict;
GHashTable *hash;
priv->reqs = g_slist_remove (priv->reqs, GUINT_TO_POINTER (call_id));
if (error)
dbus_g_method_return_error (context, error);
g_dbus_method_invocation_return_gerror (context, error);
else {
/* Return secrets from agent and backing storage to the D-Bus caller;
* nm_settings_connection_get_secrets() will have updated itself with
@ -1702,20 +1663,15 @@ dbus_get_agent_secrets_cb (NMSettingsConnection *self,
* by the time we get here.
*/
dict = nm_connection_to_dbus (NM_CONNECTION (self), NM_CONNECTION_SERIALIZE_ONLY_SECRETS);
if (dict)
hash = nm_utils_connection_dict_to_hash (dict);
else
hash = g_hash_table_new (NULL, NULL);
dbus_g_method_return (context, hash);
g_hash_table_destroy (hash);
if (dict)
g_variant_unref (dict);
if (!dict)
dict = g_variant_new_array (G_VARIANT_TYPE ("{sa{sv}}"), NULL, 0);
g_dbus_method_invocation_return_value (context, g_variant_new ("(@a{s{a{sv}}})", dict));
}
}
static void
dbus_get_secrets_auth_cb (NMSettingsConnection *self,
DBusGMethodInvocation *context,
GDBusMethodInvocation *context,
NMAuthSubject *subject,
GError *error,
gpointer user_data)
@ -1742,7 +1698,7 @@ dbus_get_secrets_auth_cb (NMSettingsConnection *self,
}
if (error || local) {
dbus_g_method_return_error (context, error ? error : local);
g_dbus_method_invocation_return_gerror (context, error ? error : local);
g_clear_error (&local);
}
@ -1751,8 +1707,8 @@ dbus_get_secrets_auth_cb (NMSettingsConnection *self,
static void
impl_settings_connection_get_secrets (NMSettingsConnection *self,
const gchar *setting_name,
DBusGMethodInvocation *context)
GDBusMethodInvocation *context,
const gchar *setting_name)
{
NMAuthSubject *subject;
GError *error = NULL;
@ -1766,10 +1722,8 @@ impl_settings_connection_get_secrets (NMSettingsConnection *self,
dbus_get_secrets_auth_cb,
g_strdup (setting_name));
g_object_unref (subject);
} else {
dbus_g_method_return_error (context, error);
g_error_free (error);
}
} else
g_dbus_method_invocation_take_error (context, error);
}
static void
@ -1780,9 +1734,9 @@ clear_secrets_cb (NMSettingsConnection *self,
CallbackInfo *info = user_data;
if (error)
dbus_g_method_return_error (info->context, error);
g_dbus_method_invocation_return_gerror (info->context, error);
else
dbus_g_method_return (info->context);
g_dbus_method_invocation_return_value (info->context, NULL);
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_CLEAR_SECRETS, NM_CONNECTION (self),
!error, info->subject, error ? error->message : NULL);
@ -1791,7 +1745,7 @@ clear_secrets_cb (NMSettingsConnection *self,
static void
dbus_clear_secrets_auth_cb (NMSettingsConnection *self,
DBusGMethodInvocation *context,
GDBusMethodInvocation *context,
NMAuthSubject *subject,
GError *error,
gpointer user_data)
@ -1800,7 +1754,7 @@ dbus_clear_secrets_auth_cb (NMSettingsConnection *self,
CallbackInfo *info;
if (error) {
dbus_g_method_return_error (context, error);
g_dbus_method_invocation_return_gerror (context, error);
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_CLEAR_SECRETS, NM_CONNECTION (self),
FALSE, subject, error->message);
} else {
@ -1824,7 +1778,7 @@ dbus_clear_secrets_auth_cb (NMSettingsConnection *self,
static void
impl_settings_connection_clear_secrets (NMSettingsConnection *self,
DBusGMethodInvocation *context)
GDBusMethodInvocation *context)
{
NMAuthSubject *subject;
GError *error = NULL;
@ -1839,10 +1793,9 @@ impl_settings_connection_clear_secrets (NMSettingsConnection *self,
NULL);
g_object_unref (subject);
} else {
dbus_g_method_return_error (context, error);
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_CLEAR_SECRETS, NM_CONNECTION (self),
FALSE, NULL, error->message);
g_error_free (error);
g_dbus_method_invocation_take_error (context, error);
}
}
@ -2586,7 +2539,15 @@ nm_settings_connection_class_init (NMSettingsConnectionClass *class)
G_TYPE_NONE, 0);
nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (class),
&dbus_glib_nm_settings_connection_object_info);
NMDBUS_TYPE_SETTINGS_CONNECTION_SKELETON,
"Update", impl_settings_connection_update,
"UpdateUnsaved", impl_settings_connection_update_unsaved,
"Delete", impl_settings_connection_delete,
"GetSettings", impl_settings_connection_get_settings,
"GetSecrets", impl_settings_connection_get_secrets,
"ClearSecrets", impl_settings_connection_clear_secrets,
"Save", impl_settings_connection_save,
NULL);
}
static void

View file

@ -31,8 +31,6 @@
#include <string.h>
#include <gmodule.h>
#include <pwd.h>
#include <dbus/dbus.h>
#include <dbus/dbus-glib-lowlevel.h>
#if HAVE_SELINUX
#include <selinux/selinux.h>
@ -61,7 +59,6 @@
#include "nm-core-internal.h"
#include "nm-device-ethernet.h"
#include "nm-dbus-glib-types.h"
#include "nm-settings.h"
#include "nm-settings-connection.h"
#include "nm-system-config-interface.h"
@ -78,6 +75,8 @@
#include "NetworkManagerUtils.h"
#include "nm-dispatcher.h"
#include "nmdbus-settings.h"
#define LOG(level, ...) \
G_STMT_START { \
nm_log ((level), LOGD_CORE, \
@ -122,35 +121,6 @@ EXPORT(nm_settings_connection_replace_and_commit)
static void claim_connection (NMSettings *self,
NMSettingsConnection *connection);
static gboolean impl_settings_list_connections (NMSettings *self,
GPtrArray **connections,
GError **error);
static void impl_settings_get_connection_by_uuid (NMSettings *self,
const char *uuid,
DBusGMethodInvocation *context);
static void impl_settings_add_connection (NMSettings *self,
GHashTable *settings,
DBusGMethodInvocation *context);
static void impl_settings_add_connection_unsaved (NMSettings *self,
GHashTable *settings,
DBusGMethodInvocation *context);
static void impl_settings_load_connections (NMSettings *self,
char **filenames,
DBusGMethodInvocation *context);
static void impl_settings_reload_connections (NMSettings *self,
DBusGMethodInvocation *context);
static void impl_settings_save_hostname (NMSettings *self,
const char *hostname,
DBusGMethodInvocation *context);
#include "nm-settings-glue.h"
static void unmanaged_specs_changed (NMSystemConfigInterface *config, gpointer user_data);
static void unrecognized_specs_changed (NMSystemConfigInterface *config, gpointer user_data);
@ -161,8 +131,6 @@ G_DEFINE_TYPE_EXTENDED (NMSettings, nm_settings, NM_TYPE_EXPORTED_OBJECT, 0,
typedef struct {
NMBusManager *dbus_mgr;
NMAgentManager *agent_mgr;
NMConfig *config;
@ -310,20 +278,24 @@ nm_settings_for_each_connection (NMSettings *self,
for_each_func (self, NM_SETTINGS_CONNECTION (data), user_data);
}
static gboolean
static void
impl_settings_list_connections (NMSettings *self,
GPtrArray **connections,
GError **error)
GDBusMethodInvocation *context)
{
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
GPtrArray *connections;
GHashTableIter iter;
gpointer key;
*connections = g_ptr_array_sized_new (g_hash_table_size (priv->connections) + 1);
connections = g_ptr_array_sized_new (g_hash_table_size (priv->connections) + 1);
g_hash_table_iter_init (&iter, priv->connections);
while (g_hash_table_iter_next (&iter, &key, NULL))
g_ptr_array_add (*connections, g_strdup ((const char *) key));
return TRUE;
g_ptr_array_add (connections, key);
g_ptr_array_add (connections, NULL);
g_dbus_method_invocation_return_value (context,
g_variant_new ("(^ao)", connections->pdata));
g_ptr_array_unref (connections);
}
NMSettingsConnection *
@ -349,8 +321,8 @@ nm_settings_get_connection_by_uuid (NMSettings *self, const char *uuid)
static void
impl_settings_get_connection_by_uuid (NMSettings *self,
const char *uuid,
DBusGMethodInvocation *context)
GDBusMethodInvocation *context,
const char *uuid)
{
NMSettingsConnection *connection = NULL;
NMAuthSubject *subject = NULL;
@ -384,13 +356,14 @@ impl_settings_get_connection_by_uuid (NMSettings *self,
}
g_clear_object (&subject);
dbus_g_method_return (context, nm_connection_get_path (NM_CONNECTION (connection)));
g_dbus_method_invocation_return_value (
context,
g_variant_new ("(o)", nm_connection_get_path (NM_CONNECTION (connection))));
return;
error:
g_assert (error);
dbus_g_method_return_error (context, error);
g_error_free (error);
g_dbus_method_invocation_take_error (context, error);
g_clear_object (&subject);
}
@ -1189,7 +1162,7 @@ send_agent_owned_secrets (NMSettings *self,
static void
pk_add_cb (NMAuthChain *chain,
GError *chain_error,
DBusGMethodInvocation *context,
GDBusMethodInvocation *context,
gpointer user_data)
{
NMSettings *self = NM_SETTINGS (user_data);
@ -1277,11 +1250,11 @@ is_adhoc_wpa (NMConnection *connection)
void
nm_settings_add_connection_dbus (NMSettings *self,
NMConnection *connection,
gboolean save_to_disk,
DBusGMethodInvocation *context,
NMSettingsAddCallback callback,
gpointer user_data)
NMConnection *connection,
gboolean save_to_disk,
GDBusMethodInvocation *context,
NMSettingsAddCallback callback,
gpointer user_data)
{
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
NMSettingConnection *s_con;
@ -1385,15 +1358,17 @@ static void
impl_settings_add_connection_add_cb (NMSettings *self,
NMSettingsConnection *connection,
GError *error,
DBusGMethodInvocation *context,
GDBusMethodInvocation *context,
NMAuthSubject *subject,
gpointer user_data)
{
if (error) {
dbus_g_method_return_error (context, error);
g_dbus_method_invocation_return_gerror (context, error);
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD, NULL, FALSE, subject, error->message);
} else {
dbus_g_method_return (context, nm_connection_get_path (NM_CONNECTION (connection)));
g_dbus_method_invocation_return_value (
context,
g_variant_new ("(o)", nm_connection_get_path (NM_CONNECTION (connection))));
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD, NM_CONNECTION (connection), TRUE,
subject, NULL);
}
@ -1401,17 +1376,14 @@ impl_settings_add_connection_add_cb (NMSettings *self,
static void
impl_settings_add_connection_helper (NMSettings *self,
GHashTable *settings,
gboolean save_to_disk,
DBusGMethodInvocation *context)
GDBusMethodInvocation *context,
GVariant *settings,
gboolean save_to_disk)
{
NMConnection *connection;
GVariant *dict;
GError *error = NULL;
dict = nm_utils_connection_hash_to_dict (settings);
connection = nm_simple_connection_new_from_dbus (dict, &error);
g_variant_unref (dict);
connection = nm_simple_connection_new_from_dbus (settings, &error);
if (connection) {
nm_settings_add_connection_dbus (self,
connection,
@ -1422,30 +1394,29 @@ impl_settings_add_connection_helper (NMSettings *self,
g_object_unref (connection);
} else {
g_assert (error);
dbus_g_method_return_error (context, error);
g_error_free (error);
g_dbus_method_invocation_take_error (context, error);
}
}
static void
impl_settings_add_connection (NMSettings *self,
GHashTable *settings,
DBusGMethodInvocation *context)
GDBusMethodInvocation *context,
GVariant *settings)
{
impl_settings_add_connection_helper (self, settings, TRUE, context);
impl_settings_add_connection_helper (self, context, settings, TRUE);
}
static void
impl_settings_add_connection_unsaved (NMSettings *self,
GHashTable *settings,
DBusGMethodInvocation *context)
GDBusMethodInvocation *context,
GVariant *settings)
{
impl_settings_add_connection_helper (self, settings, FALSE, context);
impl_settings_add_connection_helper (self, context, settings, FALSE);
}
static gboolean
ensure_root (NMBusManager *dbus_mgr,
DBusGMethodInvocation *context)
GDBusMethodInvocation *context)
{
gulong caller_uid;
GError *error = NULL;
@ -1454,16 +1425,14 @@ ensure_root (NMBusManager *dbus_mgr,
error = g_error_new_literal (NM_SETTINGS_ERROR,
NM_SETTINGS_ERROR_PERMISSION_DENIED,
"Unable to determine request UID.");
dbus_g_method_return_error (context, error);
g_error_free (error);
g_dbus_method_invocation_take_error (context, error);
return FALSE;
}
if (caller_uid != 0) {
error = g_error_new_literal (NM_SETTINGS_ERROR,
NM_SETTINGS_ERROR_PERMISSION_DENIED,
"Permission denied");
dbus_g_method_return_error (context, error);
g_error_free (error);
g_dbus_method_invocation_take_error (context, error);
return FALSE;
}
@ -1472,15 +1441,15 @@ ensure_root (NMBusManager *dbus_mgr,
static void
impl_settings_load_connections (NMSettings *self,
char **filenames,
DBusGMethodInvocation *context)
GDBusMethodInvocation *context,
char **filenames)
{
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
GPtrArray *failures;
GSList *iter;
int i;
if (!ensure_root (priv->dbus_mgr, context))
if (!ensure_root (nm_bus_manager_get (), context))
return;
failures = g_ptr_array_new ();
@ -1501,18 +1470,22 @@ impl_settings_load_connections (NMSettings *self,
}
g_ptr_array_add (failures, NULL);
dbus_g_method_return (context, failures->len == 1, failures->pdata);
g_dbus_method_invocation_return_value (
context,
g_variant_new ("(b^as)",
failures->len == 1,
failures->pdata));
g_ptr_array_unref (failures);
}
static void
impl_settings_reload_connections (NMSettings *self,
DBusGMethodInvocation *context)
GDBusMethodInvocation *context)
{
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
GSList *iter;
if (!ensure_root (priv->dbus_mgr, context))
if (!ensure_root (nm_bus_manager_get (), context))
return;
for (iter = priv->plugins; iter; iter = g_slist_next (iter)) {
@ -1521,7 +1494,7 @@ impl_settings_reload_connections (NMSettings *self,
nm_system_config_interface_reload_connections (plugin);
}
dbus_g_method_return (context, TRUE);
g_dbus_method_invocation_return_value (context, g_variant_new ("(b)", TRUE));
}
static gboolean
@ -1594,7 +1567,7 @@ write_hostname (NMSettingsPrivate *priv, const char *hostname)
static void
pk_hostname_cb (NMAuthChain *chain,
GError *chain_error,
DBusGMethodInvocation *context,
GDBusMethodInvocation *context,
gpointer user_data)
{
NMSettings *self = NM_SETTINGS (user_data);
@ -1630,11 +1603,10 @@ pk_hostname_cb (NMAuthChain *chain,
}
if (error)
dbus_g_method_return_error (context, error);
g_dbus_method_invocation_take_error (context, error);
else
dbus_g_method_return (context);
g_dbus_method_invocation_return_value (context, NULL);
g_clear_error (&error);
nm_auth_chain_unref (chain);
}
@ -1667,8 +1639,8 @@ validate_hostname (const char *hostname)
static void
impl_settings_save_hostname (NMSettings *self,
const char *hostname,
DBusGMethodInvocation *context)
GDBusMethodInvocation *context,
const char *hostname)
{
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
NMAuthChain *chain;
@ -1696,8 +1668,7 @@ impl_settings_save_hostname (NMSettings *self,
done:
if (error)
dbus_g_method_return_error (context, error);
g_clear_error (&error);
g_dbus_method_invocation_take_error (context, error);
}
static void
@ -2108,7 +2079,6 @@ nm_settings_new (void)
priv = NM_SETTINGS_GET_PRIVATE (self);
priv->config = nm_config_get ();
priv->dbus_mgr = nm_bus_manager_get ();
nm_exported_object_export (NM_EXPORTED_OBJECT (self));
return self;
@ -2198,8 +2168,6 @@ dispose (GObject *object)
g_slist_free_full (priv->auths, (GDestroyNotify) nm_auth_chain_unref);
priv->auths = NULL;
priv->dbus_mgr = NULL;
g_object_unref (priv->agent_mgr);
if (priv->hostname.hostnamed_proxy) {
@ -2255,17 +2223,18 @@ get_property (GObject *object, guint prop_id,
NMSettings *self = NM_SETTINGS (object);
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
const GSList *specs, *iter;
GSList *copy = NULL;
GHashTableIter citer;
GPtrArray *array;
const char *path;
switch (prop_id) {
case PROP_UNMANAGED_SPECS:
array = g_ptr_array_new ();
specs = nm_settings_get_unmanaged_specs (self);
for (iter = specs; iter; iter = g_slist_next (iter))
copy = g_slist_append (copy, g_strdup (iter->data));
g_value_take_boxed (value, copy);
g_ptr_array_add (array, g_strdup (iter->data));
g_ptr_array_add (array, NULL);
g_value_take_boxed (value, (char **) g_ptr_array_free (array, FALSE));
break;
case PROP_HOSTNAME:
g_value_take_string (value, nm_settings_get_hostname (self));
@ -2278,11 +2247,12 @@ get_property (GObject *object, guint prop_id,
g_value_set_boolean (value, !!get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS));
break;
case PROP_CONNECTIONS:
array = g_ptr_array_sized_new (g_hash_table_size (priv->connections));
array = g_ptr_array_sized_new (g_hash_table_size (priv->connections) + 1);
g_hash_table_iter_init (&citer, priv->connections);
while (g_hash_table_iter_next (&citer, (gpointer) &path, NULL))
g_ptr_array_add (array, g_strdup (path));
g_value_take_boxed (value, array);
g_ptr_array_add (array, NULL);
g_value_take_boxed (value, (char **) g_ptr_array_free (array, FALSE));
break;
case PROP_STARTUP_COMPLETE:
g_value_set_boolean (value, nm_settings_get_startup_complete (self));
@ -2313,7 +2283,7 @@ nm_settings_class_init (NMSettingsClass *class)
g_object_class_install_property
(object_class, PROP_UNMANAGED_SPECS,
g_param_spec_boxed (NM_SETTINGS_UNMANAGED_SPECS, "", "",
DBUS_TYPE_G_LIST_OF_STRING,
G_TYPE_STRV,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
@ -2334,7 +2304,7 @@ nm_settings_class_init (NMSettingsClass *class)
g_object_class_install_property
(object_class, PROP_CONNECTIONS,
g_param_spec_boxed (NM_SETTINGS_CONNECTIONS, "", "",
DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH,
G_TYPE_STRV,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
@ -2346,7 +2316,7 @@ nm_settings_class_init (NMSettingsClass *class)
G_STRUCT_OFFSET (NMSettingsClass, connection_added),
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, G_TYPE_OBJECT);
G_TYPE_NONE, 1, NM_TYPE_SETTINGS_CONNECTION);
signals[CONNECTION_UPDATED] =
g_signal_new (NM_SETTINGS_SIGNAL_CONNECTION_UPDATED,
@ -2355,7 +2325,7 @@ nm_settings_class_init (NMSettingsClass *class)
G_STRUCT_OFFSET (NMSettingsClass, connection_updated),
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, G_TYPE_OBJECT);
G_TYPE_NONE, 1, NM_TYPE_SETTINGS_CONNECTION);
signals[CONNECTION_UPDATED_BY_USER] =
g_signal_new (NM_SETTINGS_SIGNAL_CONNECTION_UPDATED_BY_USER,
@ -2364,7 +2334,7 @@ nm_settings_class_init (NMSettingsClass *class)
0,
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, G_TYPE_OBJECT);
G_TYPE_NONE, 1, NM_TYPE_SETTINGS_CONNECTION);
signals[CONNECTION_REMOVED] =
g_signal_new (NM_SETTINGS_SIGNAL_CONNECTION_REMOVED,
@ -2373,7 +2343,7 @@ nm_settings_class_init (NMSettingsClass *class)
G_STRUCT_OFFSET (NMSettingsClass, connection_removed),
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, G_TYPE_OBJECT);
G_TYPE_NONE, 1, NM_TYPE_SETTINGS_CONNECTION);
signals[CONNECTION_VISIBILITY_CHANGED] =
g_signal_new (NM_SETTINGS_SIGNAL_CONNECTION_VISIBILITY_CHANGED,
@ -2382,7 +2352,7 @@ nm_settings_class_init (NMSettingsClass *class)
G_STRUCT_OFFSET (NMSettingsClass, connection_visibility_changed),
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, G_TYPE_OBJECT);
G_TYPE_NONE, 1, NM_TYPE_SETTINGS_CONNECTION);
signals[AGENT_REGISTERED] =
g_signal_new (NM_SETTINGS_SIGNAL_AGENT_REGISTERED,
@ -2391,7 +2361,7 @@ nm_settings_class_init (NMSettingsClass *class)
G_STRUCT_OFFSET (NMSettingsClass, agent_registered),
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, G_TYPE_OBJECT);
G_TYPE_NONE, 1, NM_TYPE_SECRET_AGENT);
signals[NEW_CONNECTION] =
@ -2399,16 +2369,17 @@ nm_settings_class_init (NMSettingsClass *class)
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);
G_TYPE_NONE, 1, NM_TYPE_SETTINGS_CONNECTION);
nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (class),
&dbus_glib_nm_settings_object_info);
dbus_g_error_domain_register (NM_SETTINGS_ERROR,
NM_DBUS_INTERFACE_SETTINGS,
NM_TYPE_SETTINGS_ERROR);
dbus_g_error_domain_register (NM_CONNECTION_ERROR,
NM_DBUS_INTERFACE_SETTINGS_CONNECTION,
NM_TYPE_CONNECTION_ERROR);
NMDBUS_TYPE_SETTINGS_SKELETON,
"ListConnections", impl_settings_list_connections,
"GetConnectionByUuid", impl_settings_get_connection_by_uuid,
"AddConnection", impl_settings_add_connection,
"AddConnectionUnsaved", impl_settings_add_connection_unsaved,
"LoadConnections", impl_settings_load_connections,
"ReloadConnections", impl_settings_reload_connections,
"SaveHostname", impl_settings_save_hostname,
NULL);
}

View file

@ -87,14 +87,14 @@ void nm_settings_for_each_connection (NMSettings *settings,
typedef void (*NMSettingsAddCallback) (NMSettings *settings,
NMSettingsConnection *connection,
GError *error,
DBusGMethodInvocation *context,
GDBusMethodInvocation *context,
NMAuthSubject *subject,
gpointer user_data);
void nm_settings_add_connection_dbus (NMSettings *self,
NMConnection *connection,
gboolean save_to_disk,
DBusGMethodInvocation *context,
GDBusMethodInvocation *context,
NMSettingsAddCallback callback,
gpointer user_data);