diff options
Diffstat (limited to 'src/settings/nm-settings.c')
| -rw-r--r-- | src/settings/nm-settings.c | 769 |
1 files changed, 449 insertions, 320 deletions
diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index 8e3fc582..2c6b7101 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -62,10 +62,12 @@ #include "nm-utils.h" #include "nm-core-internal.h" +#include "nm-utils/nm-c-list.h" +#include "nm-dbus-object.h" #include "devices/nm-device-ethernet.h" #include "nm-settings-connection.h" #include "nm-settings-plugin.h" -#include "nm-bus-manager.h" +#include "nm-dbus-manager.h" #include "nm-auth-utils.h" #include "nm-auth-subject.h" #include "nm-session-monitor.h" @@ -77,8 +79,6 @@ #include "nm-dispatcher.h" #include "nm-hostname-manager.h" -#include "introspection/org.freedesktop.NetworkManager.Settings.h" - /*****************************************************************************/ #define EXPORT(sym) void * __export_##sym = &sym; @@ -107,7 +107,6 @@ enum { CONNECTION_UPDATED, CONNECTION_REMOVED, CONNECTION_FLAGS_CHANGED, - NEW_CONNECTION, /* exported, not used internally */ LAST_SIGNAL }; @@ -121,29 +120,33 @@ typedef struct { GSList *auths; GSList *plugins; - gboolean connections_loaded; - GHashTable *connections; + + CList connections_lst_head; + NMSettingsConnection **connections_cached_list; GSList *unmanaged_specs; GSList *unrecognized_specs; - gboolean started; - gboolean startup_complete; - NMHostnameManager *hostname_manager; + guint connections_len; + + bool started:1; + bool startup_complete:1; + bool connections_loaded:1; + } NMSettingsPrivate; struct _NMSettings { - NMExportedObject parent; + NMDBusObject parent; NMSettingsPrivate _priv; }; struct _NMSettingsClass { - NMExportedObjectClass parent; + NMDBusObjectClass parent; }; -G_DEFINE_TYPE (NMSettings, nm_settings, NM_TYPE_EXPORTED_OBJECT); +G_DEFINE_TYPE (NMSettings, nm_settings, NM_TYPE_DBUS_OBJECT); #define NM_SETTINGS_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMSettings, NM_IS_SETTINGS) @@ -154,6 +157,10 @@ G_DEFINE_TYPE (NMSettings, nm_settings, NM_TYPE_EXPORTED_OBJECT); /*****************************************************************************/ +static const NMDBusInterfaceInfoExtended interface_info_settings; +static const GDBusSignalInfo signal_info_new_connection; +static const GDBusSignalInfo signal_info_connection_removed; + static void claim_connection (NMSettings *self, NMSettingsConnection *connection); @@ -164,27 +171,29 @@ static void connection_ready_changed (NMSettingsConnection *conn, GParamSpec *pspec, gpointer user_data); +static void default_wired_clear_tag (NMSettings *self, + NMDevice *device, + NMSettingsConnection *connection, + gboolean add_to_no_auto_default); + /*****************************************************************************/ static void check_startup_complete (NMSettings *self) { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - GHashTableIter iter; NMSettingsConnection *conn; if (priv->startup_complete) return; - g_hash_table_iter_init (&iter, priv->connections); - while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &conn)) { + c_list_for_each_entry (conn, &priv->connections_lst_head, _connections_lst) { if (!nm_settings_connection_get_ready (conn)) return; } /* the connection_ready_changed signal handler is no longer needed. */ - g_hash_table_iter_init (&iter, priv->connections); - while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &conn)) + c_list_for_each_entry (conn, &priv->connections_lst_head, _connections_lst) g_signal_handlers_disconnect_by_func (conn, G_CALLBACK (connection_ready_changed), self); priv->startup_complete = TRUE; @@ -247,43 +256,25 @@ load_connections (NMSettings *self) unrecognized_specs_changed (NULL, self); } -void -nm_settings_for_each_connection (NMSettings *self, - NMSettingsForEachFunc for_each_func, - gpointer user_data) -{ - NMSettingsPrivate *priv; - GHashTableIter iter; - gpointer data; - - g_return_if_fail (NM_IS_SETTINGS (self)); - g_return_if_fail (for_each_func != NULL); - - priv = NM_SETTINGS_GET_PRIVATE (self); - - g_hash_table_iter_init (&iter, priv->connections); - while (g_hash_table_iter_next (&iter, NULL, &data)) - for_each_func (self, NM_SETTINGS_CONNECTION (data), user_data); -} - static void -impl_settings_list_connections (NMSettings *self, - GDBusMethodInvocation *context) +impl_settings_list_connections (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *dbus_connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) { + NMSettings *self = NM_SETTINGS (obj); 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); - g_hash_table_iter_init (&iter, priv->connections); - while (g_hash_table_iter_next (&iter, &key, NULL)) - 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); + gs_free const char **strv = NULL; + + strv = nm_dbus_utils_get_paths_for_clist (&priv->connections_lst_head, + priv->connections_len, + G_STRUCT_OFFSET (NMSettingsConnection, _connections_lst), + TRUE); + g_dbus_method_invocation_return_value (invocation, + g_variant_new ("(^ao)", strv)); } NMSettingsConnection * @@ -291,16 +282,14 @@ nm_settings_get_connection_by_uuid (NMSettings *self, const char *uuid) { NMSettingsPrivate *priv; NMSettingsConnection *candidate; - GHashTableIter iter; g_return_val_if_fail (NM_IS_SETTINGS (self), NULL); g_return_val_if_fail (uuid != NULL, NULL); priv = NM_SETTINGS_GET_PRIVATE (self); - g_hash_table_iter_init (&iter, priv->connections); - while (g_hash_table_iter_next (&iter, NULL, (gpointer) &candidate)) { - if (g_strcmp0 (uuid, nm_settings_connection_get_uuid (candidate)) == 0) + c_list_for_each_entry (candidate, &priv->connections_lst_head, _connections_lst) { + if (nm_streq (uuid, nm_settings_connection_get_uuid (candidate))) return candidate; } @@ -308,14 +297,21 @@ nm_settings_get_connection_by_uuid (NMSettings *self, const char *uuid) } static void -impl_settings_get_connection_by_uuid (NMSettings *self, - GDBusMethodInvocation *context, - const char *uuid) +impl_settings_get_connection_by_uuid (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *dbus_connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) { + NMSettings *self = NM_SETTINGS (obj); NMSettingsConnection *connection = NULL; - NMAuthSubject *subject = NULL; + gs_unref_object NMAuthSubject *subject = NULL; GError *error = NULL; - char *error_desc = NULL; + const char *uuid; + + g_variant_get (parameters, "(&s)", &uuid); connection = nm_settings_get_connection_by_uuid (self, uuid); if (!connection) { @@ -325,7 +321,7 @@ impl_settings_get_connection_by_uuid (NMSettings *self, goto error; } - subject = nm_auth_subject_new_unix_process_from_context (context); + subject = nm_auth_subject_new_unix_process_from_context (invocation); if (!subject) { error = g_error_new_literal (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_PERMISSION_DENIED, @@ -333,26 +329,40 @@ impl_settings_get_connection_by_uuid (NMSettings *self, goto error; } - if (!nm_auth_is_subject_in_acl (NM_CONNECTION (connection), - subject, - &error_desc)) { - error = g_error_new_literal (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_PERMISSION_DENIED, - error_desc); - g_free (error_desc); + if (!nm_auth_is_subject_in_acl_set_error (NM_CONNECTION (connection), + subject, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED, + &error)) goto error; - } - g_clear_object (&subject); - g_dbus_method_invocation_return_value ( - context, - g_variant_new ("(o)", nm_connection_get_path (NM_CONNECTION (connection)))); + g_dbus_method_invocation_return_value (invocation, + g_variant_new ("(o)", + nm_dbus_object_get_path (NM_DBUS_OBJECT (connection)))); return; error: - g_assert (error); - g_dbus_method_invocation_take_error (context, error); - g_clear_object (&subject); + g_dbus_method_invocation_take_error (invocation, error); +} + +static void +_clear_connections_cached_list (NMSettingsPrivate *priv) +{ + if (!priv->connections_cached_list) + return; + + nm_assert (priv->connections_len == NM_PTRARRAY_LEN (priv->connections_cached_list)); + +#if NM_MORE_ASSERTS + /* set the pointer to a bogus value. This makes it more apparent + * if somebody has a reference to the cached list and still uses + * it. That is a bug, this code just tries to make it blow up + * more eagerly. */ + memset (priv->connections_cached_list, + 0xdeaddead, + sizeof (NMSettingsConnection *) * (priv->connections_len + 1)); +#endif + nm_clear_g_free (&priv->connections_cached_list); } /** @@ -370,37 +380,33 @@ error: NMSettingsConnection *const* nm_settings_get_connections (NMSettings *self, guint *out_len) { - GHashTableIter iter; NMSettingsPrivate *priv; - guint l, i; NMSettingsConnection **v; NMSettingsConnection *con; + guint i; g_return_val_if_fail (NM_IS_SETTINGS (self), NULL); priv = NM_SETTINGS_GET_PRIVATE (self); - if (G_LIKELY (priv->connections_cached_list)) { - NM_SET_OUT (out_len, g_hash_table_size (priv->connections)); - return priv->connections_cached_list; - } + nm_assert (priv->connections_len == c_list_length (&priv->connections_lst_head)); - l = g_hash_table_size (priv->connections); + if (G_UNLIKELY (!priv->connections_cached_list)) { + v = g_new (NMSettingsConnection *, priv->connections_len + 1); - v = g_new (NMSettingsConnection *, (gsize) l + 1); + i = 0; + c_list_for_each_entry (con, &priv->connections_lst_head, _connections_lst) { + nm_assert (i < priv->connections_len); + v[i++] = con; + } + nm_assert (i == priv->connections_len); + v[i] = NULL; - i = 0; - g_hash_table_iter_init (&iter, priv->connections); - while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &con)) { - nm_assert (i < l); - v[i++] = con; + priv->connections_cached_list = v; } - nm_assert (i == l); - v[i] = NULL; - NM_SET_OUT (out_len, l); - priv->connections_cached_list = v; - return v; + NM_SET_OUT (out_len, priv->connections_len); + return priv->connections_cached_list; } /** @@ -467,28 +473,41 @@ NMSettingsConnection * nm_settings_get_connection_by_path (NMSettings *self, const char *path) { NMSettingsPrivate *priv; + NMSettingsConnection *connection; g_return_val_if_fail (NM_IS_SETTINGS (self), NULL); - g_return_val_if_fail (path != NULL, NULL); + g_return_val_if_fail (path, NULL); priv = NM_SETTINGS_GET_PRIVATE (self); - return (NMSettingsConnection *) g_hash_table_lookup (priv->connections, path); + connection = (NMSettingsConnection *) nm_dbus_manager_lookup_object (nm_dbus_object_get_manager (NM_DBUS_OBJECT (self)), + path); + if ( !connection + || !NM_IS_SETTINGS_CONNECTION (connection)) + return NULL; + + nm_assert (c_list_contains (&priv->connections_lst_head, &connection->_connections_lst)); + return connection; } gboolean nm_settings_has_connection (NMSettings *self, NMSettingsConnection *connection) { - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - GHashTableIter iter; - gpointer data; + NMSettingsConnection *candidate = NULL; + const char *path; - g_hash_table_iter_init (&iter, priv->connections); - while (g_hash_table_iter_next (&iter, NULL, &data)) - if (data == connection) - return TRUE; + g_return_val_if_fail (NM_IS_SETTINGS (self), FALSE); + g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (connection), FALSE); - return FALSE; + path = nm_dbus_object_get_path (NM_DBUS_OBJECT (connection)); + if (path) + candidate = nm_settings_get_connection_by_path (self, path); + + nm_assert (!candidate || candidate == connection); + nm_assert (!!candidate == nm_c_list_contains_entry (&NM_SETTINGS_GET_PRIVATE (self)->connections_lst_head, + connection, + _connections_lst)); + return !!candidate; } const GSList * @@ -500,7 +519,7 @@ nm_settings_get_unmanaged_specs (NMSettings *self) } static NMSettingsPlugin * -get_plugin (NMSettings *self, guint32 capability) +get_plugin (NMSettings *self, NMSettingsPluginCapabilities capability) { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); GSList *iter; @@ -677,8 +696,8 @@ load_plugins (NMSettings *self, const char **plugins, GError **error) continue; } - if (!strcmp (pname, "ifcfg-suse")) { - _LOGW ("skipping deprecated plugin ifcfg-suse"); + if (NM_IN_STRSET (pname, "ifcfg-suse", "ifnet")) { + _LOGW ("skipping deprecated plugin %s", pname); continue; } @@ -806,7 +825,6 @@ connection_updated (NMSettingsConnection *connection, gboolean by_user, gpointer static void connection_flags_changed (NMSettingsConnection *connection, - GParamSpec *pspec, gpointer user_data) { g_signal_emit (NM_SETTINGS (user_data), @@ -820,11 +838,20 @@ connection_removed (NMSettingsConnection *connection, gpointer user_data) { NMSettings *self = NM_SETTINGS (user_data); NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - const char *cpath = nm_connection_get_path (NM_CONNECTION (connection)); + NMDevice *device; - if (!g_hash_table_lookup (priv->connections, cpath)) - g_return_if_reached (); - g_object_ref (connection); + g_return_if_fail (NM_IS_SETTINGS_CONNECTION (connection)); + g_return_if_fail (!c_list_is_empty (&connection->_connections_lst)); + nm_assert (c_list_contains (&priv->connections_lst_head, &connection->_connections_lst)); + + /* When the default wired connection is removed (either deleted or saved to + * a new persistent connection by a plugin), write the MAC address of the + * wired device to the config file and don't create a new default wired + * connection for that device again. + */ + device = g_object_get_qdata (G_OBJECT (connection), _default_wired_device_quark ()); + if (device) + default_wired_clear_tag (self, device, connection, TRUE); /* Disconnect signal handlers, as plugins might still keep references * to the connection (and thus the signal handlers would still be live) @@ -836,23 +863,30 @@ connection_removed (NMSettingsConnection *connection, gpointer user_data) g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (connection_flags_changed), self); if (!priv->startup_complete) g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (connection_ready_changed), self); - g_object_unref (self); /* Forget about the connection internally */ - g_hash_table_remove (priv->connections, (gpointer) cpath); - g_clear_pointer (&priv->connections_cached_list, g_free); + _clear_connections_cached_list (priv); + priv->connections_len--; + c_list_unlink (&connection->_connections_lst); + + if (priv->connections_loaded) { + _notify (self, PROP_CONNECTIONS); - /* Notify D-Bus */ - g_signal_emit (self, signals[CONNECTION_REMOVED], 0, connection); + nm_dbus_object_emit_signal (NM_DBUS_OBJECT (self), + &interface_info_settings, + &signal_info_connection_removed, + "(o)", + nm_dbus_object_get_path (NM_DBUS_OBJECT (connection))); + } - /* Re-emit for listeners like NMPolicy */ - _notify (self, PROP_CONNECTIONS); - if (nm_exported_object_is_exported (NM_EXPORTED_OBJECT (connection))) - nm_exported_object_unexport (NM_EXPORTED_OBJECT (connection)); + nm_dbus_object_unexport (NM_DBUS_OBJECT (connection)); - check_startup_complete (self); + if (priv->connections_loaded) + g_signal_emit (self, signals[CONNECTION_REMOVED], 0, connection); g_object_unref (connection); + + check_startup_complete (self); } #define NM_DBUS_SERVICE_OPENCONNECT "org.freedesktop.NetworkManager.openconnect" @@ -900,19 +934,16 @@ claim_connection (NMSettings *self, NMSettingsConnection *connection) { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); GError *error = NULL; - GHashTableIter iter; - gpointer data; const char *path; NMSettingsConnection *existing; g_return_if_fail (NM_IS_SETTINGS_CONNECTION (connection)); - g_return_if_fail (nm_connection_get_path (NM_CONNECTION (connection)) == NULL); + g_return_if_fail (!nm_dbus_object_is_exported (NM_DBUS_OBJECT (connection))); - g_hash_table_iter_init (&iter, priv->connections); - while (g_hash_table_iter_next (&iter, NULL, &data)) { - /* prevent duplicates */ - if (data == connection) - return; + /* prevent duplicates */ + if (!c_list_is_empty (&connection->_connections_lst)) { + nm_assert (c_list_contains (&priv->connections_lst_head, &connection->_connections_lst)); + return; } if (!nm_connection_normalize (NM_CONNECTION (connection), NULL, NULL, &error)) { @@ -944,20 +975,19 @@ claim_connection (NMSettings *self, NMSettingsConnection *connection) /* Read seen-bssids from look-aside file and put it into the connection's data */ nm_settings_connection_read_and_fill_seen_bssids (connection); - /* Ensure it's initial visibility is up-to-date */ + /* Ensure its initial visibility is up-to-date */ nm_settings_connection_recheck_visibility (connection); /* Evil openconnect migration hack */ openconnect_migrate_hack (NM_CONNECTION (connection)); - g_object_ref (self); /* This one unexports the connection, it needs to run late to give the active * connection a chance to deal with its reference to this settings connection. */ g_signal_connect_after (connection, NM_SETTINGS_CONNECTION_REMOVED, G_CALLBACK (connection_removed), self); g_signal_connect (connection, NM_SETTINGS_CONNECTION_UPDATED_INTERNAL, G_CALLBACK (connection_updated), self); - g_signal_connect (connection, "notify::" NM_SETTINGS_CONNECTION_FLAGS, + g_signal_connect (connection, NM_SETTINGS_CONNECTION_FLAGS_CHANGED, G_CALLBACK (connection_flags_changed), self); if (!priv->startup_complete) { @@ -966,28 +996,29 @@ claim_connection (NMSettings *self, NMSettingsConnection *connection) self); } - /* Export the connection over D-Bus */ - g_warn_if_fail (nm_connection_get_path (NM_CONNECTION (connection)) == NULL); - path = nm_exported_object_export (NM_EXPORTED_OBJECT (connection)); - nm_connection_set_path (NM_CONNECTION (connection), path); + _clear_connections_cached_list (priv); - g_hash_table_insert (priv->connections, - (gpointer) nm_connection_get_path (NM_CONNECTION (connection)), - g_object_ref (connection)); - g_clear_pointer (&priv->connections_cached_list, g_free); + g_object_ref (connection); + priv->connections_len++; + c_list_link_tail (&priv->connections_lst_head, &connection->_connections_lst); + + path = nm_dbus_object_export (NM_DBUS_OBJECT (connection)); - nm_utils_log_connection_diff (NM_CONNECTION (connection), NULL, LOGL_DEBUG, LOGD_CORE, "new connection", "++ "); + nm_utils_log_connection_diff (NM_CONNECTION (connection), NULL, LOGL_DEBUG, LOGD_CORE, "new connection", "++ ", + path); /* Only emit the individual connection-added signal after connections * have been initially loaded. */ if (priv->connections_loaded) { - /* Internal added signal */ + nm_dbus_object_emit_signal (NM_DBUS_OBJECT (self), + &interface_info_settings, + &signal_info_new_connection, + "(o)", + nm_dbus_object_get_path (NM_DBUS_OBJECT (connection))); + g_signal_emit (self, signals[CONNECTION_ADDED], 0, connection); _notify (self, PROP_CONNECTIONS); - - /* Exported D-Bus signal */ - g_signal_emit (self, signals[NEW_CONNECTION], 0, connection); } nm_settings_connection_added (connection); @@ -1035,14 +1066,14 @@ nm_settings_add_connection (NMSettings *self, NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); GSList *iter; NMSettingsConnection *added = NULL; - GHashTableIter citer; - NMConnection *candidate = NULL; + NMSettingsConnection *candidate = NULL; + const char *uuid; + + uuid = nm_connection_get_uuid (connection); /* Make sure a connection with this UUID doesn't already exist */ - g_hash_table_iter_init (&citer, priv->connections); - while (g_hash_table_iter_next (&citer, NULL, (gpointer *) &candidate)) { - if (g_strcmp0 (nm_connection_get_uuid (connection), - nm_connection_get_uuid (candidate)) == 0) { + c_list_for_each_entry (candidate, &priv->connections_lst_head, _connections_lst) { + if (nm_streq0 (uuid, nm_connection_get_uuid (NM_CONNECTION (candidate)))) { g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_UUID_EXISTS, @@ -1099,7 +1130,7 @@ send_agent_owned_secrets (NMSettings *self, NMAuthSubject *subject) { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - NMConnection *for_agent; + gs_unref_object NMConnection *for_agent = NULL; /* Dupe the connection so we can clear out non-agent-owned secrets, * as agent-owned secrets are the only ones we send back to be saved. @@ -1110,10 +1141,9 @@ send_agent_owned_secrets (NMSettings *self, secrets_filter_cb, GUINT_TO_POINTER (NM_SETTING_SECRET_FLAG_AGENT_OWNED)); nm_agent_manager_save_secrets (priv->agent_mgr, - nm_connection_get_path (NM_CONNECTION (connection)), + nm_dbus_object_get_path (NM_DBUS_OBJECT (connection)), for_agent, subject); - g_object_unref (for_agent); } static void @@ -1170,7 +1200,7 @@ pk_add_cb (NMAuthChain *chain, send_agent_owned_secrets (self, added, subject); g_clear_error (&error); - nm_auth_chain_unref (chain); + nm_auth_chain_destroy (chain); } /* FIXME: remove if/when kernel supports adhoc wpa */ @@ -1218,7 +1248,6 @@ nm_settings_add_connection_dbus (NMSettings *self, NMAuthSubject *subject = NULL; NMAuthChain *chain; GError *error = NULL, *tmp_error = NULL; - char *error_desc = NULL; const char *perm; g_return_if_fail (connection != NULL); @@ -1261,18 +1290,12 @@ nm_settings_add_connection_dbus (NMSettings *self, goto done; } - /* 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 (connection, - subject, - &error_desc)) { - error = g_error_new_literal (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_PERMISSION_DENIED, - error_desc); - g_free (error_desc); + if (!nm_auth_is_subject_in_acl_set_error (connection, + subject, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED, + &error)) goto done; - } /* 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 @@ -1312,30 +1335,30 @@ done: } static void -impl_settings_add_connection_add_cb (NMSettings *self, - NMSettingsConnection *connection, - GError *error, - GDBusMethodInvocation *context, - NMAuthSubject *subject, - gpointer user_data) +settings_add_connection_add_cb (NMSettings *self, + NMSettingsConnection *connection, + GError *error, + GDBusMethodInvocation *context, + NMAuthSubject *subject, + gpointer user_data) { if (error) { g_dbus_method_invocation_return_gerror (context, error); nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD, NULL, FALSE, NULL, subject, error->message); } else { - g_dbus_method_invocation_return_value ( - context, - g_variant_new ("(o)", nm_connection_get_path (NM_CONNECTION (connection)))); + g_dbus_method_invocation_return_value (context, + g_variant_new ("(o)", + nm_dbus_object_get_path (NM_DBUS_OBJECT (connection)))); nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD, connection, TRUE, NULL, subject, NULL); } } static void -impl_settings_add_connection_helper (NMSettings *self, - GDBusMethodInvocation *context, - GVariant *settings, - gboolean save_to_disk) +settings_add_connection_helper (NMSettings *self, + GDBusMethodInvocation *context, + GVariant *settings, + gboolean save_to_disk) { gs_unref_object NMConnection *connection = NULL; GError *error = NULL; @@ -1355,77 +1378,111 @@ impl_settings_add_connection_helper (NMSettings *self, connection, save_to_disk, context, - impl_settings_add_connection_add_cb, + settings_add_connection_add_cb, NULL); } static void -impl_settings_add_connection (NMSettings *self, - GDBusMethodInvocation *context, - GVariant *settings) +impl_settings_add_connection (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) { - impl_settings_add_connection_helper (self, context, settings, TRUE); + NMSettings *self = NM_SETTINGS (obj); + gs_unref_variant GVariant *settings = NULL; + + g_variant_get (parameters, "(@a{sa{sv}})", &settings); + settings_add_connection_helper (self, invocation, settings, TRUE); } static void -impl_settings_add_connection_unsaved (NMSettings *self, - GDBusMethodInvocation *context, - GVariant *settings) +impl_settings_add_connection_unsaved (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) { - impl_settings_add_connection_helper (self, context, settings, FALSE); + NMSettings *self = NM_SETTINGS (obj); + gs_unref_variant GVariant *settings = NULL; + + g_variant_get (parameters, "(@a{sa{sv}})", &settings); + settings_add_connection_helper (self, invocation, settings, FALSE); } static void -impl_settings_load_connections (NMSettings *self, - GDBusMethodInvocation *context, - char **filenames) +impl_settings_load_connections (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) { + NMSettings *self = NM_SETTINGS (obj); NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - GPtrArray *failures; + gs_unref_ptrarray GPtrArray *failures = NULL; GSList *iter; - int i; + guint i; + gs_free const char **filenames = NULL; + + g_variant_get (parameters, "(^a&s)", &filenames); /* The permission is already enforced by the D-Bus daemon, but we ensure * that the caller is still alive so that clients are forced to wait and * we'll be able to switch to polkit without breaking behavior. */ - if (!nm_bus_manager_ensure_uid (nm_bus_manager_get (), - context, - G_MAXULONG, - NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_PERMISSION_DENIED)) + if (!nm_dbus_manager_ensure_uid (nm_dbus_object_get_manager (obj), + invocation, + G_MAXULONG, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED)) return; - failures = g_ptr_array_new (); - - for (i = 0; filenames[i]; i++) { - for (iter = priv->plugins; iter; iter = g_slist_next (iter)) { - NMSettingsPlugin *plugin = NM_SETTINGS_PLUGIN (iter->data); + if (filenames) { + for (i = 0; filenames[i]; i++) { + for (iter = priv->plugins; iter; iter = g_slist_next (iter)) { + NMSettingsPlugin *plugin = NM_SETTINGS_PLUGIN (iter->data); - if (nm_settings_plugin_load_connection (plugin, filenames[i])) - break; - } + if (nm_settings_plugin_load_connection (plugin, filenames[i])) + break; + } - if (!iter) { - if (!g_path_is_absolute (filenames[i])) - _LOGW ("connection filename '%s' is not an absolute path", filenames[i]); - g_ptr_array_add (failures, (char *) filenames[i]); + if (!iter) { + if (!g_path_is_absolute (filenames[i])) + _LOGW ("connection filename '%s' is not an absolute path", filenames[i]); + if (!failures) + failures = g_ptr_array_new (); + g_ptr_array_add (failures, (char *) filenames[i]); + } } } - g_ptr_array_add (failures, NULL); - g_dbus_method_invocation_return_value ( - context, - g_variant_new ("(b^as)", - failures->len == 1, - failures->pdata)); - g_ptr_array_unref (failures); + if (failures) + g_ptr_array_add (failures, NULL); + + g_dbus_method_invocation_return_value (invocation, + g_variant_new ("(b^as)", + (gboolean) (!!failures), + failures + ? (const char **) failures->pdata + : NM_PTRARRAY_EMPTY (const char *))); } static void -impl_settings_reload_connections (NMSettings *self, - GDBusMethodInvocation *context) +impl_settings_reload_connections (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) { + NMSettings *self = NM_SETTINGS (obj); NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); GSList *iter; @@ -1433,11 +1490,11 @@ impl_settings_reload_connections (NMSettings *self, * that the caller is still alive so that clients are forced to wait and * we'll be able to switch to polkit without breaking behavior. */ - if (!nm_bus_manager_ensure_uid (nm_bus_manager_get (), - context, - G_MAXULONG, - NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_PERMISSION_DENIED)) + if (!nm_dbus_manager_ensure_uid (nm_dbus_object_get_manager (obj), + invocation, + G_MAXULONG, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED)) return; for (iter = priv->plugins; iter; iter = g_slist_next (iter)) { @@ -1446,7 +1503,7 @@ impl_settings_reload_connections (NMSettings *self, nm_settings_plugin_reload_connections (plugin); } - g_dbus_method_invocation_return_value (context, g_variant_new ("(b)", TRUE)); + g_dbus_method_invocation_return_value (invocation, g_variant_new ("(b)", TRUE)); } /*****************************************************************************/ @@ -1494,41 +1551,46 @@ pk_hostname_cb (NMAuthChain *chain, else g_dbus_method_invocation_return_value (context, NULL); - nm_auth_chain_unref (chain); + nm_auth_chain_destroy (chain); } static void -impl_settings_save_hostname (NMSettings *self, - GDBusMethodInvocation *context, - const char *hostname) +impl_settings_save_hostname (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) { + NMSettings *self = NM_SETTINGS (obj); NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); NMAuthChain *chain; - GError *error = NULL; + const char *hostname; + + g_variant_get (parameters, "(&s)", &hostname); /* Minimal validation of the hostname */ if (!nm_hostname_manager_validate_hostname (hostname)) { - error = g_error_new_literal (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_INVALID_HOSTNAME, - "The hostname was too long or contained invalid characters."); - goto done; + g_dbus_method_invocation_return_error_literal (invocation, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_HOSTNAME, + "The hostname was too long or contained invalid characters."); + return; } - chain = nm_auth_chain_new_context (context, pk_hostname_cb, self); + chain = nm_auth_chain_new_context (invocation, pk_hostname_cb, self); if (!chain) { - error = g_error_new_literal (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_PERMISSION_DENIED, - "Unable to authenticate the request."); - goto done; + g_dbus_method_invocation_return_error_literal (invocation, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED, + "Unable to authenticate the request."); + return; } priv->auths = g_slist_append (priv->auths, chain); nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME, TRUE); nm_auth_chain_set_data (chain, "hostname", g_strdup (hostname), g_free); - -done: - if (error) - g_dbus_method_invocation_take_error (context, error); } /*****************************************************************************/ @@ -1537,27 +1599,24 @@ static gboolean have_connection_for_device (NMSettings *self, NMDevice *device) { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - GHashTableIter iter; - gpointer data; NMSettingConnection *s_con; NMSettingWired *s_wired; const char *setting_hwaddr; const char *perm_hw_addr; + NMSettingsConnection *connection; g_return_val_if_fail (NM_IS_SETTINGS (self), FALSE); perm_hw_addr = nm_device_get_permanent_hw_address (device); /* Find a wired connection locked to the given MAC address, if any */ - g_hash_table_iter_init (&iter, priv->connections); - while (g_hash_table_iter_next (&iter, NULL, &data)) { - NMConnection *connection = NM_CONNECTION (data); + c_list_for_each_entry (connection, &priv->connections_lst_head, _connections_lst) { const char *ctype, *iface; - if (!nm_device_check_connection_compatible (device, connection)) + if (!nm_device_check_connection_compatible (device, NM_CONNECTION (connection))) continue; - s_con = nm_connection_get_setting_connection (connection); + s_con = nm_connection_get_setting_connection (NM_CONNECTION (connection)); iface = nm_setting_connection_get_interface_name (s_con); if (iface && strcmp (iface, nm_device_get_iface (device)) != 0) @@ -1568,7 +1627,7 @@ have_connection_for_device (NMSettings *self, NMDevice *device) && strcmp (ctype, NM_SETTING_PPPOE_SETTING_NAME)) continue; - s_wired = nm_connection_get_setting_wired (connection); + s_wired = nm_connection_get_setting_wired (NM_CONNECTION (connection)); if (!s_wired && !strcmp (ctype, NM_SETTING_PPPOE_SETTING_NAME)) { /* No wired setting; therefore the PPPoE connection applies to any device */ @@ -1596,26 +1655,6 @@ have_connection_for_device (NMSettings *self, NMDevice *device) return FALSE; } -static void default_wired_clear_tag (NMSettings *self, - NMDevice *device, - NMSettingsConnection *connection, - gboolean add_to_no_auto_default); - -static void -default_wired_connection_removed_cb (NMSettingsConnection *connection, NMSettings *self) -{ - NMDevice *device; - - /* When the default wired connection is removed (either deleted or saved to - * a new persistent connection by a plugin), write the MAC address of the - * wired device to the config file and don't create a new default wired - * connection for that device again. - */ - device = g_object_get_qdata (G_OBJECT (connection), _default_wired_device_quark ()); - if (device) - default_wired_clear_tag (self, device, connection, TRUE); -} - static void default_wired_connection_updated_by_user_cb (NMSettingsConnection *connection, gboolean by_user, NMSettings *self) { @@ -1648,7 +1687,6 @@ default_wired_clear_tag (NMSettings *self, g_object_set_qdata (G_OBJECT (connection), _default_wired_device_quark (), NULL); g_object_set_qdata (G_OBJECT (device), _default_wired_connection_quark (), NULL); - g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (default_wired_connection_removed_cb), self); g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (default_wired_connection_updated_by_user_cb), self); if (add_to_no_auto_default) @@ -1700,8 +1738,6 @@ device_realized (NMDevice *device, GParamSpec *pspec, NMSettings *self) g_signal_connect (added, NM_SETTINGS_CONNECTION_UPDATED_INTERNAL, G_CALLBACK (default_wired_connection_updated_by_user_cb), self); - g_signal_connect (added, NM_SETTINGS_CONNECTION_REMOVED, - G_CALLBACK (default_wired_connection_removed_cb), self); _LOGI ("(%s): created default wired connection '%s'", nm_device_get_iface (device), @@ -1774,10 +1810,8 @@ nm_settings_start (NMSettings *self, GError **error) /* Load the plugins; fail if a plugin is not found. */ plugins = nm_config_data_get_plugins (nm_config_get_data_orig (priv->config), TRUE); - if (!load_plugins (self, (const char **) plugins, error)) { - g_object_unref (self); + if (!load_plugins (self, (const char **) plugins, error)) return FALSE; - } load_connections (self); check_startup_complete (self); @@ -1802,18 +1836,19 @@ get_property (GObject *object, guint prop_id, NMSettings *self = NM_SETTINGS (object); NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); const GSList *specs, *iter; - GHashTableIter citer; - GPtrArray *array; - const char *path; + guint i; + char **strvs; + const char **strv; 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)) - 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)); + strvs = g_new (char *, g_slist_length ((GSList *) specs) + 1); + i = 0; + for (iter = specs; iter; iter = iter->next) + strvs[i++] = g_strdup (iter->data); + strvs[i] = NULL; + g_value_take_boxed (value, strvs); break; case PROP_HOSTNAME: g_value_set_string (value, @@ -1825,12 +1860,14 @@ get_property (GObject *object, guint prop_id, g_value_set_boolean (value, !!get_plugin (self, NM_SETTINGS_PLUGIN_CAP_MODIFY_CONNECTIONS)); break; case PROP_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_ptr_array_add (array, NULL); - g_value_take_boxed (value, (char **) g_ptr_array_free (array, FALSE)); + if (priv->connections_loaded) { + strv = nm_dbus_utils_get_paths_for_clist (&priv->connections_lst_head, + priv->connections_len, + G_STRUCT_OFFSET (NMSettingsConnection, _connections_lst), + TRUE); + g_value_take_boxed (value, nm_utils_strv_make_deep_copied (strv)); + } else + g_value_set_boxed (value, NULL); break; case PROP_STARTUP_COMPLETE: g_value_set_boolean (value, nm_settings_get_startup_complete (self)); @@ -1848,7 +1885,7 @@ nm_settings_init (NMSettings *self) { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - priv->connections = g_hash_table_new_full (nm_str_hash, g_str_equal, NULL, g_object_unref); + c_list_init (&priv->connections_lst_head); priv->agent_mgr = g_object_ref (nm_agent_manager_get ()); priv->config = g_object_ref (nm_config_get ()); @@ -1866,11 +1903,9 @@ dispose (GObject *object) NMSettings *self = NM_SETTINGS (object); NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - g_slist_free_full (priv->auths, (GDestroyNotify) nm_auth_chain_unref); + g_slist_free_full (priv->auths, (GDestroyNotify) nm_auth_chain_destroy); priv->auths = NULL; - g_object_unref (priv->agent_mgr); - if (priv->hostname_manager) { g_signal_handlers_disconnect_by_func (priv->hostname_manager, G_CALLBACK (_hostname_changed_cb), @@ -1887,26 +1922,139 @@ finalize (GObject *object) NMSettings *self = NM_SETTINGS (object); NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - g_hash_table_destroy (priv->connections); - g_clear_pointer (&priv->connections_cached_list, g_free); + _clear_connections_cached_list (priv); + + nm_assert (c_list_is_empty (&priv->connections_lst_head)); g_slist_free_full (priv->unmanaged_specs, g_free); g_slist_free_full (priv->unrecognized_specs, g_free); g_slist_free_full (priv->plugins, g_object_unref); + g_clear_object (&priv->agent_mgr); + g_clear_object (&priv->config); G_OBJECT_CLASS (nm_settings_parent_class)->finalize (object); } +static const GDBusSignalInfo signal_info_new_connection = NM_DEFINE_GDBUS_SIGNAL_INFO_INIT ( + "NewConnection", + .args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("connection", "o"), + ), +); + +static const GDBusSignalInfo signal_info_connection_removed = NM_DEFINE_GDBUS_SIGNAL_INFO_INIT ( + "ConnectionRemoved", + .args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("connection", "o"), + ), +); + +static const NMDBusInterfaceInfoExtended interface_info_settings = { + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( + NM_DBUS_INTERFACE_SETTINGS, + .methods = NM_DEFINE_GDBUS_METHOD_INFOS ( + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "ListConnections", + .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("connections", "ao"), + ), + ), + .handle = impl_settings_list_connections, + ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "GetConnectionByUuid", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("uuid", "s"), + ), + .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("connection", "o"), + ), + ), + .handle = impl_settings_get_connection_by_uuid, + ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "AddConnection", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("connection", "a{sa{sv}}"), + ), + .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("path", "o"), + ), + ), + .handle = impl_settings_add_connection, + ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "AddConnectionUnsaved", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("connection", "a{sa{sv}}"), + ), + .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("path", "o"), + ), + ), + .handle = impl_settings_add_connection_unsaved, + ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "LoadConnections", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("filenames", "as"), + ), + .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("status", "b"), + NM_DEFINE_GDBUS_ARG_INFO ("failures", "as"), + ), + ), + .handle = impl_settings_load_connections, + ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "ReloadConnections", + .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("status", "b"), + ), + ), + .handle = impl_settings_reload_connections, + ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "SaveHostname", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("hostname", "s"), + ), + ), + .handle = impl_settings_save_hostname, + ), + ), + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( + &nm_signal_info_property_changed_legacy, + &signal_info_new_connection, + &signal_info_connection_removed, + ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Connections", "ao", NM_SETTINGS_CONNECTIONS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Hostname", "s", NM_SETTINGS_HOSTNAME), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("CanModify", "b", NM_SETTINGS_CAN_MODIFY), + ), + ), + .legacy_property_changed = TRUE, +}; + static void nm_settings_class_init (NMSettingsClass *class) { GObjectClass *object_class = G_OBJECT_CLASS (class); - NMExportedObjectClass *exported_object_class = NM_EXPORTED_OBJECT_CLASS (class); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (class); - exported_object_class->export_path = NM_DBUS_PATH_SETTINGS; + dbus_object_class->export_path = NM_DBUS_EXPORT_PATH_STATIC (NM_DBUS_PATH_SETTINGS); + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_settings); object_class->get_property = get_property; object_class->dispose = dispose; @@ -1975,23 +2123,4 @@ nm_settings_class_init (NMSettingsClass *class) 0, NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, NM_TYPE_SETTINGS_CONNECTION); - - signals[NEW_CONNECTION] = - g_signal_new ("new-connection", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, 0, NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, NM_TYPE_SETTINGS_CONNECTION); - - nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (class), - 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); } - |