From c9067d8fedf6f6f2d530fd68bbfca7ce68638d38 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 11 Jun 2009 00:39:12 -0400 Subject: everything: use libgudev instead of HAL; merge NM and nm-system-settings The only thing that doesn't work yet is the system-settings service's "auto eth" connections for ethernet devices that don't have an existing connection. Might also have issues with unmanaged devices that can't provide a MAC address until they are brought up, but we'll see. --- configure.ac | 6 +- introspection/nm-device.xml | 4 +- introspection/nm-settings-system.xml | 6 - marshallers/nm-marshal.list | 4 +- src/Makefile.am | 10 +- src/NetworkManager.c | 72 +- src/NetworkManager.conf | 10 + src/NetworkManagerPolicy.c | 2 +- src/NetworkManagerUtils.c | 29 +- src/NetworkManagerUtils.h | 2 + src/modem-manager/nm-modem-gsm.c | 24 +- src/nm-activation-request.c | 252 +-- src/nm-activation-request.h | 40 +- src/nm-dbus-manager.c | 18 + src/nm-device-ethernet.c | 74 +- src/nm-device-ethernet.h | 9 +- src/nm-device-interface.c | 15 +- src/nm-device-interface.h | 21 +- src/nm-device-wifi.c | 79 +- src/nm-device-wifi.h | 17 +- src/nm-device.c | 69 +- src/nm-device.h | 5 + src/nm-hal-manager.c | 600 ------ src/nm-hal-manager.h | 67 - src/nm-manager.c | 2171 ++++++++++---------- src/nm-manager.h | 7 +- src/nm-secrets-provider-interface.c | 224 ++ src/nm-secrets-provider-interface.h | 91 + src/nm-udev-manager.c | 224 +- src/nm-udev-manager.h | 17 + src/ppp-manager/nm-ppp-manager.c | 12 +- src/system-settings/Makefile.am | 60 + src/system-settings/nm-default-wired-connection.c | 355 ++++ src/system-settings/nm-default-wired-connection.h | 57 + src/system-settings/nm-inotify-helper.c | 211 ++ src/system-settings/nm-inotify-helper.h | 54 + src/system-settings/nm-polkit-helpers.c | 148 ++ src/system-settings/nm-polkit-helpers.h | 37 + src/system-settings/nm-sysconfig-connection.c | 346 ++++ src/system-settings/nm-sysconfig-connection.h | 54 + src/system-settings/nm-sysconfig-settings.c | 848 ++++++++ src/system-settings/nm-sysconfig-settings.h | 94 + src/system-settings/nm-system-config-error.c | 59 + src/system-settings/nm-system-config-error.h | 45 + src/system-settings/nm-system-config-interface.c | 163 ++ src/system-settings/nm-system-config-interface.h | 138 ++ src/vpn-manager/nm-vpn-connection.c | 221 +- src/vpn-manager/nm-vpn-connection.h | 3 +- src/vpn-manager/nm-vpn-manager.c | 8 +- src/vpn-manager/nm-vpn-manager.h | 10 +- src/vpn-manager/nm-vpn-service.c | 1 + system-settings/Makefile.am | 2 +- system-settings/plugins/ifcfg-rh/Makefile.am | 14 +- .../plugins/ifcfg-rh/nm-ifcfg-connection.c | 194 +- .../plugins/ifcfg-rh/nm-ifcfg-connection.h | 7 +- system-settings/plugins/ifcfg-rh/plugin.c | 122 +- system-settings/plugins/ifcfg-rh/reader.c | 64 +- system-settings/plugins/ifcfg-rh/reader.h | 2 +- .../plugins/ifcfg-rh/tests/test-ifcfg-rh.c | 71 +- system-settings/plugins/ifcfg-suse/Makefile.am | 4 +- system-settings/plugins/ifcfg-suse/plugin.c | 217 +- system-settings/plugins/ifupdown/Makefile.am | 23 +- .../plugins/ifupdown/interface_parser.c | 1 - system-settings/plugins/ifupdown/plugin.c | 455 ++-- system-settings/plugins/keyfile/Makefile.am | 2 +- system-settings/plugins/keyfile/plugin.c | 10 +- system-settings/src/Makefile.am | 84 - system-settings/src/dbus-settings.c | 671 ------ system-settings/src/dbus-settings.h | 95 - system-settings/src/main.c | 900 -------- system-settings/src/nm-default-wired-connection.c | 355 ---- system-settings/src/nm-default-wired-connection.h | 57 - system-settings/src/nm-inotify-helper.c | 211 -- system-settings/src/nm-inotify-helper.h | 54 - system-settings/src/nm-polkit-helpers.c | 148 -- system-settings/src/nm-polkit-helpers.h | 37 - system-settings/src/nm-sysconfig-connection.c | 344 ---- system-settings/src/nm-sysconfig-connection.h | 47 - system-settings/src/nm-system-config-error.c | 59 - system-settings/src/nm-system-config-error.h | 45 - system-settings/src/nm-system-config-hal-manager.c | 388 ---- system-settings/src/nm-system-config-hal-manager.h | 58 - system-settings/src/nm-system-config-interface.c | 163 -- system-settings/src/nm-system-config-interface.h | 133 -- system-settings/src/nm-system-settings.conf | 22 - ...desktop.NetworkManagerSystemSettings.service.in | 5 - 86 files changed, 5323 insertions(+), 6834 deletions(-) delete mode 100644 src/nm-hal-manager.c delete mode 100644 src/nm-hal-manager.h create mode 100644 src/nm-secrets-provider-interface.c create mode 100644 src/nm-secrets-provider-interface.h create mode 100644 src/system-settings/Makefile.am create mode 100644 src/system-settings/nm-default-wired-connection.c create mode 100644 src/system-settings/nm-default-wired-connection.h create mode 100644 src/system-settings/nm-inotify-helper.c create mode 100644 src/system-settings/nm-inotify-helper.h create mode 100644 src/system-settings/nm-polkit-helpers.c create mode 100644 src/system-settings/nm-polkit-helpers.h create mode 100644 src/system-settings/nm-sysconfig-connection.c create mode 100644 src/system-settings/nm-sysconfig-connection.h create mode 100644 src/system-settings/nm-sysconfig-settings.c create mode 100644 src/system-settings/nm-sysconfig-settings.h create mode 100644 src/system-settings/nm-system-config-error.c create mode 100644 src/system-settings/nm-system-config-error.h create mode 100644 src/system-settings/nm-system-config-interface.c create mode 100644 src/system-settings/nm-system-config-interface.h delete mode 100644 system-settings/src/Makefile.am delete mode 100644 system-settings/src/dbus-settings.c delete mode 100644 system-settings/src/dbus-settings.h delete mode 100644 system-settings/src/main.c delete mode 100644 system-settings/src/nm-default-wired-connection.c delete mode 100644 system-settings/src/nm-default-wired-connection.h delete mode 100644 system-settings/src/nm-inotify-helper.c delete mode 100644 system-settings/src/nm-inotify-helper.h delete mode 100644 system-settings/src/nm-polkit-helpers.c delete mode 100644 system-settings/src/nm-polkit-helpers.h delete mode 100644 system-settings/src/nm-sysconfig-connection.c delete mode 100644 system-settings/src/nm-sysconfig-connection.h delete mode 100644 system-settings/src/nm-system-config-error.c delete mode 100644 system-settings/src/nm-system-config-error.h delete mode 100644 system-settings/src/nm-system-config-hal-manager.c delete mode 100644 system-settings/src/nm-system-config-hal-manager.h delete mode 100644 system-settings/src/nm-system-config-interface.c delete mode 100644 system-settings/src/nm-system-config-interface.h delete mode 100644 system-settings/src/nm-system-settings.conf delete mode 100644 system-settings/src/org.freedesktop.NetworkManagerSystemSettings.service.in diff --git a/configure.ac b/configure.ac index a83ac28c91..adaf2e040f 100644 --- a/configure.ac +++ b/configure.ac @@ -204,10 +204,6 @@ else fi AM_CONDITIONAL(NO_GIO, test x"$have_gio" == "xno") -PKG_CHECK_MODULES(HAL, hal >= 0.5.0) -AC_SUBST(HAL_CFLAGS) -AC_SUBST(HAL_LIBS) - PKG_CHECK_MODULES(LIBNL, libnl-1 >= 1.0-pre8) AC_SUBST(LIBNL_CFLAGS) AC_SUBST(LIBNL_LIBS) @@ -447,6 +443,7 @@ src/ppp-manager/Makefile src/dnsmasq-manager/Makefile src/modem-manager/Makefile src/bluez-manager/Makefile +src/system-settings/Makefile src/backends/Makefile libnm-util/libnm-util.pc libnm-util/Makefile @@ -459,7 +456,6 @@ gfilemonitor/Makefile callouts/Makefile tools/Makefile system-settings/Makefile -system-settings/src/Makefile system-settings/plugins/Makefile system-settings/plugins/ifupdown/Makefile system-settings/plugins/ifcfg-rh/Makefile diff --git a/introspection/nm-device.xml b/introspection/nm-device.xml index 376c0ebb3c..b866e04c0a 100644 --- a/introspection/nm-device.xml +++ b/introspection/nm-device.xml @@ -2,9 +2,9 @@ - + - HAL UDI for the device. + Udev path of the device in sysfs. diff --git a/introspection/nm-settings-system.xml b/introspection/nm-settings-system.xml index 08225ad4e6..0e13b7a8d6 100644 --- a/introspection/nm-settings-system.xml +++ b/introspection/nm-settings-system.xml @@ -44,12 +44,6 @@ - - - The list of HAL UDIs of devices that should not be managed by NetworkManager. - - - diff --git a/marshallers/nm-marshal.list b/marshallers/nm-marshal.list index 62c9ed08ef..970fe24f00 100644 --- a/marshallers/nm-marshal.list +++ b/marshallers/nm-marshal.list @@ -11,7 +11,7 @@ VOID:UINT,UINT,UINT VOID:STRING,STRING VOID:STRING,UCHAR VOID:STRING,OBJECT -VOID:STRING,STRING,POINTER,POINTER +VOID:POINTER,POINTER VOID:STRING,STRING,STRING,UINT VOID:OBJECT,UINT,UINT VOID:STRING,INT @@ -20,3 +20,5 @@ VOID:OBJECT,OBJECT,ENUM VOID:POINTER,STRING POINTER:POINTER VOID:STRING,BOXED +BOOLEAN:POINTER,STRING,BOOLEAN,UINT,STRING,STRING + diff --git a/src/Makefile.am b/src/Makefile.am index 2f218bd7df..79c2a2e64b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -8,6 +8,7 @@ SUBDIRS= \ dnsmasq-manager \ modem-manager \ bluez-manager \ + system-settings \ . \ tests @@ -21,7 +22,9 @@ INCLUDES = -I${top_srcdir} \ -I${top_srcdir}/src/dnsmasq-manager \ -I${top_srcdir}/src/modem-manager \ -I$(top_srcdir)/src/bluez-manager \ + -I$(top_srcdir)/src/system-settings \ -I${top_srcdir}/libnm-util \ + -I${top_srcdir}/libnm-glib \ -I${top_srcdir}/callouts ########################################### @@ -71,14 +74,14 @@ NetworkManager_SOURCES = \ NetworkManagerAP.h \ nm-dbus-manager.h \ nm-dbus-manager.c \ - nm-hal-manager.c \ - nm-hal-manager.h \ nm-udev-manager.c \ nm-udev-manager.h \ nm-hostname-provider.c \ nm-hostname-provider.h \ nm-ip4-config.c \ nm-ip4-config.h \ + nm-secrets-provider-interface.c \ + nm-secrets-provider-interface.h \ nm-active-connection.h \ nm-active-connection.c \ NetworkManager.c \ @@ -150,6 +153,7 @@ NetworkManager_CPPFLAGS = \ $(GUDEV_CFLAGS) \ $(OPENSSL_CFLAGS) \ $(LIBNL_CFLAGS) \ + $(GMODULE_CFLAGS) \ -DG_DISABLE_DEPRECATED \ -DBINDIR=\"$(bindir)\" \ -DSBINDIR=\"$(sbindir)\" \ @@ -167,6 +171,7 @@ NetworkManager_LDADD = \ $(HAL_LIBS) \ $(GUDEV_LIBS) \ $(LIBNL_LIBS) \ + $(GMODULE_LIBS) \ $(top_builddir)/marshallers/libmarshallers.la \ ./named-manager/libnamed-manager.la \ ./vpn-manager/libvpn-manager.la \ @@ -176,6 +181,7 @@ NetworkManager_LDADD = \ ./ppp-manager/libppp-manager.la \ ./modem-manager/libmodem-manager.la \ ./bluez-manager/libbluez-manager.la \ + ./system-settings/libsystem-settings.la \ ./backends/libnmbackend.la \ $(top_builddir)/libnm-util/libnm-util.la diff --git a/src/NetworkManager.c b/src/NetworkManager.c index c6b04d299f..6c2834fd81 100644 --- a/src/NetworkManager.c +++ b/src/NetworkManager.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include "NetworkManager.h" @@ -243,6 +244,30 @@ write_pidfile (const char *pidfile) nm_warning ("Closing %s failed: %s", pidfile, strerror (errno)); } +static gboolean +parse_config_file (const char *filename, char **plugins, GError **error) +{ + GKeyFile *config; + + config = g_key_file_new (); + if (!config) { + g_set_error (error, 0, 0, + "Not enough memory to load config file."); + return FALSE; + } + + g_key_file_set_list_separator (config, ','); + if (!g_key_file_load_from_file (config, filename, G_KEY_FILE_NONE, error)) + return FALSE; + + *plugins = g_key_file_get_value (config, "main", "plugins", error); + if (*error) + return FALSE; + + g_key_file_free (config); + return TRUE; +} + /* * main * @@ -251,10 +276,10 @@ int main (int argc, char *argv[]) { GOptionContext *opt_ctx = NULL; - gboolean become_daemon = FALSE; - gboolean g_fatal_warnings = FALSE; - char * pidfile = NULL; - char * user_pidfile = NULL; + gboolean become_daemon = FALSE; + gboolean g_fatal_warnings = FALSE; + char *pidfile = NULL, *user_pidfile = NULL; + char *config = NULL, *plugins = NULL; gboolean success; NMPolicy *policy = NULL; NMVPNManager *vpn_manager = NULL; @@ -262,11 +287,14 @@ main (int argc, char *argv[]) NMDBusManager *dbus_mgr = NULL; NMSupplicantManager *sup_mgr = NULL; NMDHCPManager *dhcp_mgr = NULL; + GError *error = NULL; GOptionEntry options[] = { - {"no-daemon", 0, 0, G_OPTION_ARG_NONE, &become_daemon, "Don't become a daemon", NULL}, + { "no-daemon", 0, 0, G_OPTION_ARG_NONE, &become_daemon, "Don't become a daemon", NULL }, { "g-fatal-warnings", 0, 0, G_OPTION_ARG_NONE, &g_fatal_warnings, "Make all warnings fatal", NULL }, - {"pid-file", 0, 0, G_OPTION_ARG_FILENAME, &user_pidfile, "Specify the location of a PID file", "filename"}, + { "pid-file", 0, 0, G_OPTION_ARG_FILENAME, &user_pidfile, "Specify the location of a PID file", "filename" }, + { "config", 0, 0, G_OPTION_ARG_FILENAME, &config, "Config file location", "/path/to/config.file" }, + { "plugins", 0, 0, G_OPTION_ARG_STRING, &plugins, "List of plugins separated by ,", "plugin1,plugin2" }, {NULL} }; @@ -275,6 +303,11 @@ main (int argc, char *argv[]) exit (1); } + if (!g_module_supported ()) { + g_printerr ("GModules are not supported on your platform!"); + exit (1); + } + bindtextdomain (GETTEXT_PACKAGE, NMLOCALEDIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); @@ -297,6 +330,14 @@ main (int argc, char *argv[]) exit (1); } + /* Parse the config file */ + if (config) { + if (!parse_config_file (config, &plugins, &error)) { + g_warning ("Config file %s invalid: %s.", config, error->message); + exit (1); + } + } + pidfile = g_strdup (user_pidfile ? user_pidfile : NM_DEFAULT_PID_FILE); /* Tricky: become_daemon is FALSE by default, so unless it's TRUE because @@ -358,9 +399,16 @@ main (int argc, char *argv[]) goto done; } - manager = nm_manager_get (); + named_mgr = nm_named_manager_get (); + if (!named_mgr) { + nm_warning ("Failed to start the named manager."); + goto done; + } + + manager = nm_manager_get (plugins, &error); if (manager == NULL) { - nm_error ("Failed to initialize the network manager."); + nm_error ("Failed to initialize the network manager: %s", + error && error->message ? error->message : "(unknown)"); goto done; } @@ -377,12 +425,6 @@ main (int argc, char *argv[]) goto done; } - named_mgr = nm_named_manager_get (); - if (!named_mgr) { - nm_warning ("Failed to start the named manager."); - goto done; - } - dhcp_mgr = nm_dhcp_manager_get (); if (!dhcp_mgr) { nm_warning ("Failed to start the DHCP manager."); @@ -397,6 +439,8 @@ main (int argc, char *argv[]) goto done; } + nm_manager_start (manager); + /* Bring up the loopback interface. */ nm_system_enable_loopback (); diff --git a/src/NetworkManager.conf b/src/NetworkManager.conf index c3d7b84f5b..a5eee46e88 100644 --- a/src/NetworkManager.conf +++ b/src/NetworkManager.conf @@ -4,7 +4,10 @@ + + + @@ -56,7 +59,14 @@ + + + + + 512 diff --git a/src/NetworkManagerPolicy.c b/src/NetworkManagerPolicy.c index 9d400251d2..b1b485c4d4 100644 --- a/src/NetworkManagerPolicy.c +++ b/src/NetworkManagerPolicy.c @@ -648,7 +648,7 @@ auto_activate_device (gpointer user_data) GError *error = NULL; const char *device_path; - device_path = nm_device_get_udi (data->device); + device_path = nm_device_get_path (data->device); if (!nm_manager_activate_connection (policy->manager, best_connection, specific_object, diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c index ae498d8c10..8243b5e2b7 100644 --- a/src/NetworkManagerUtils.c +++ b/src/NetworkManagerUtils.c @@ -366,7 +366,7 @@ nm_utils_call_dispatcher (const char *action, /* state */ value_hash_add_uint (device_props, NMD_DEVICE_PROPS_STATE, nm_device_get_state (device)); - value_hash_add_object_path (device_props, NMD_DEVICE_PROPS_PATH, nm_device_get_udi (device)); + value_hash_add_object_path (device_props, NMD_DEVICE_PROPS_PATH, nm_device_get_path (device)); } dbus_g_proxy_call_no_reply (proxy, "Action", @@ -383,6 +383,32 @@ nm_utils_call_dispatcher (const char *action, g_object_unref (dbus_mgr); } +gboolean +nm_match_spec_hwaddr (const GSList *specs, const char *hwaddr) +{ + const GSList *iter; + char *hwaddr_match, *p; + + g_return_val_if_fail (hwaddr != NULL, FALSE); + + p = hwaddr_match = g_strdup_printf ("mac:%s", hwaddr); + + while (*p) { + *p = g_ascii_tolower (*p); + p++; + } + + for (iter = specs; iter; iter = g_slist_next (iter)) { + if (!strcmp ((const char *) iter->data, hwaddr_match)) { + g_free (hwaddr_match); + return TRUE; + } + } + + g_free (hwaddr_match); + return FALSE; +} + /*********************************/ static void @@ -449,3 +475,4 @@ value_hash_add_uint (GHashTable *hash, value_hash_add (hash, key, value); } + diff --git a/src/NetworkManagerUtils.h b/src/NetworkManagerUtils.h index cb0e178c24..7293581bde 100644 --- a/src/NetworkManagerUtils.h +++ b/src/NetworkManagerUtils.h @@ -46,6 +46,8 @@ void nm_utils_call_dispatcher (const char *action, NMDevice *device, const char *vpn_iface); +gboolean nm_match_spec_hwaddr (const GSList *specs, const char *hwaddr); + GHashTable *value_hash_create (void); void value_hash_add (GHashTable *hash, diff --git a/src/modem-manager/nm-modem-gsm.c b/src/modem-manager/nm-modem-gsm.c index fdb5c1c3d0..0cafaa9af8 100644 --- a/src/modem-manager/nm-modem-gsm.c +++ b/src/modem-manager/nm-modem-gsm.c @@ -129,12 +129,12 @@ stage1_prepare_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_d if (required_secret) { nm_device_state_changed (device, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE); - nm_act_request_request_connection_secrets (nm_device_get_act_request (device), - NM_SETTING_GSM_SETTING_NAME, - retry_secret, - SECRETS_CALLER_GSM, - required_secret, - NULL); + nm_act_request_get_secrets (nm_device_get_act_request (device), + NM_SETTING_GSM_SETTING_NAME, + retry_secret, + SECRETS_CALLER_GSM, + required_secret, + NULL); } else nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, translate_mm_error (error)); @@ -237,12 +237,12 @@ real_act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason) nm_device_state_changed (device, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE); tries = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (connection), GSM_SECRETS_TRIES)); - nm_act_request_request_connection_secrets (req, - setting_name, - tries ? TRUE : FALSE, - SECRETS_CALLER_GSM, - hint1, - hint2); + nm_act_request_get_secrets (req, + setting_name, + tries ? TRUE : FALSE, + SECRETS_CALLER_GSM, + hint1, + hint2); g_object_set_data (G_OBJECT (connection), GSM_SECRETS_TRIES, GUINT_TO_POINTER (++tries)); if (hints) diff --git a/src/nm-activation-request.c b/src/nm-activation-request.c index 9775041db6..c919c5e710 100644 --- a/src/nm-activation-request.c +++ b/src/nm-activation-request.c @@ -36,9 +36,12 @@ #include "nm-active-connection.h" #include "nm-dbus-glib-types.h" -#include "nm-manager.h" /* FIXME! */ -G_DEFINE_TYPE (NMActRequest, nm_act_request, G_TYPE_OBJECT) +static void secrets_provider_interface_init (NMSecretsProviderInterface *sp_interface_class); + +G_DEFINE_TYPE_EXTENDED (NMActRequest, nm_act_request, G_TYPE_OBJECT, 0, + G_IMPLEMENT_INTERFACE (NM_TYPE_SECRETS_PROVIDER_INTERFACE, + secrets_provider_interface_init)) #define NM_ACT_REQUEST_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_ACT_REQUEST, NMActRequestPrivate)) @@ -61,7 +64,7 @@ typedef struct { gboolean disposed; NMConnection *connection; - DBusGProxyCall *secrets_call; + guint32 secrets_call_id; char *specific_object; NMDevice *device; @@ -177,24 +180,6 @@ nm_act_request_init (NMActRequest *req) g_object_unref (dbus_mgr); } -static void -cleanup_secrets_dbus_call (NMActRequest *self) -{ - NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (self); - DBusGProxy *proxy; - - g_return_if_fail (priv->connection != NULL); - g_return_if_fail (NM_IS_CONNECTION (priv->connection)); - - proxy = g_object_get_data (G_OBJECT (priv->connection), NM_MANAGER_CONNECTION_SECRETS_PROXY_TAG); - g_assert (proxy); - - if (priv->secrets_call) { - dbus_g_proxy_cancel_call (proxy, priv->secrets_call); - priv->secrets_call = NULL; - } -} - static void dispose (GObject *object) { @@ -212,8 +197,6 @@ dispose (GObject *object) G_CALLBACK (device_state_changed), NM_ACT_REQUEST (object)); - cleanup_secrets_dbus_call (NM_ACT_REQUEST (object)); - /* Clear any share rules */ nm_act_request_set_shared (NM_ACT_REQUEST (object), FALSE); @@ -275,7 +258,7 @@ get_property (GObject *object, guint prop_id, break; case PROP_DEVICES: devices = g_ptr_array_sized_new (1); - g_ptr_array_add (devices, g_strdup (nm_device_get_udi (priv->device))); + g_ptr_array_add (devices, g_strdup (nm_device_get_path (priv->device))); g_value_take_boxed (value, devices); break; case PROP_STATE: @@ -363,7 +346,7 @@ nm_act_request_class_init (NMActRequestClass *req_class) g_signal_new ("connection-secrets-updated", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMActRequestClass, connection_secrets_updated), + G_STRUCT_OFFSET (NMActRequestClass, secrets_updated), NULL, NULL, _nm_marshal_VOID__OBJECT_POINTER_UINT, G_TYPE_NONE, 3, @@ -373,7 +356,7 @@ nm_act_request_class_init (NMActRequestClass *req_class) g_signal_new ("connection-secrets-failed", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMActRequestClass, connection_secrets_failed), + G_STRUCT_OFFSET (NMActRequestClass, secrets_failed), NULL, NULL, _nm_marshal_VOID__OBJECT_STRING_UINT, G_TYPE_NONE, 3, @@ -386,30 +369,17 @@ nm_act_request_class_init (NMActRequestClass *req_class) nm_active_connection_install_type_info (object_class); } -typedef struct GetSecretsInfo { - NMActRequest *req; - char *setting_name; - RequestSecretsCaller caller; -} GetSecretsInfo; - -static void -free_get_secrets_info (gpointer data) -{ - GetSecretsInfo *info = (GetSecretsInfo *) data; - - g_free (info->setting_name); - g_free (info); -} - -static void -update_one_setting (const char* setting_name, - GHashTable *setting_hash, - NMConnection *connection, - GSList **updated) +static gboolean +secrets_update_setting (NMSecretsProviderInterface *interface, + const char *setting_name, + GHashTable *new) { - GType type; + NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (interface); NMSetting *setting = NULL; GError *error = NULL; + GType type; + + g_return_val_if_fail (priv->connection != NULL, FALSE); /* Check whether a complete & valid NMSetting object was returned. If * yes, replace the setting object in the connection. If not, just try @@ -417,9 +387,9 @@ update_one_setting (const char* setting_name, */ type = nm_connection_lookup_setting_type (setting_name); if (type == 0) - return; + return FALSE; - setting = nm_setting_new_from_hash (type, setting_hash); + setting = nm_setting_new_from_hash (type, new); if (setting) { NMSetting *s_8021x = NULL; GSList *all_settings = NULL; @@ -427,7 +397,7 @@ update_one_setting (const char* setting_name, /* The wireless-security setting might need the 802.1x setting in * the all_settings argument of the verify function. Ugh. */ - s_8021x = nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X); + s_8021x = nm_connection_get_setting (priv->connection, NM_TYPE_SETTING_802_1X); if (s_8021x) all_settings = g_slist_append (all_settings, s_8021x); @@ -441,9 +411,9 @@ update_one_setting (const char* setting_name, } if (setting) - nm_connection_add_setting (connection, setting); + nm_connection_add_setting (priv->connection, setting); else { - if (!nm_connection_update_secrets (connection, setting_name, setting_hash, &error)) { + if (!nm_connection_update_secrets (priv->connection, setting_name, new, &error)) { nm_warning ("Failed to update connection secrets: %d %s", error ? error->code : -1, error && error->message ? error->message : "(none)"); @@ -451,166 +421,56 @@ update_one_setting (const char* setting_name, } } - *updated = g_slist_append (*updated, (gpointer) setting_name); + return TRUE; } static void -add_one_key_to_list (gpointer key, gpointer data, gpointer user_data) +secrets_result (NMSecretsProviderInterface *interface, + const char *setting_name, + RequestSecretsCaller caller, + const GSList *updated, + GError *error) { - GSList **list = (GSList **) user_data; - - *list = g_slist_append (*list, key); -} - -static gint -settings_order_func (gconstpointer a, gconstpointer b) -{ - /* Just ensure the 802.1x setting gets processed _before_ the - * wireless-security one. - */ - - if ( !strcmp (a, NM_SETTING_802_1X_SETTING_NAME) - && !strcmp (b, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME)) - return -1; + NMActRequest *self = NM_ACT_REQUEST (interface); + NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (self); - if ( !strcmp (a, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) - && !strcmp (b, NM_SETTING_802_1X_SETTING_NAME)) - return 1; + g_return_if_fail (priv->connection != NULL); - return 0; + if (error) { + g_signal_emit (self, signals[CONNECTION_SECRETS_FAILED], 0, + priv->connection, setting_name, caller); + } else { + g_signal_emit (self, signals[CONNECTION_SECRETS_UPDATED], 0, + priv->connection, updated, caller); + } } static void -get_secrets_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data) +secrets_provider_interface_init (NMSecretsProviderInterface *sp_interface_class) { - GetSecretsInfo *info = (GetSecretsInfo *) user_data; - GError *err = NULL; - GHashTable *settings = NULL; - NMActRequestPrivate *priv = NULL; - GSList *keys = NULL, *iter; - GSList *updated = NULL; - - g_return_if_fail (info != NULL); - g_return_if_fail (info->req); - g_return_if_fail (info->setting_name); - - priv = NM_ACT_REQUEST_GET_PRIVATE (info->req); - - g_return_if_fail (call == priv->secrets_call); - priv->secrets_call = NULL; - - if (!dbus_g_proxy_end_call (proxy, call, &err, - DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, &settings, - G_TYPE_INVALID)) { - nm_warning ("Couldn't get connection secrets: %s.", err->message); - g_error_free (err); - g_signal_emit (info->req, - signals[CONNECTION_SECRETS_FAILED], - 0, - priv->connection, - info->setting_name, - info->caller); - return; - } - - if (g_hash_table_size (settings) == 0) { - // FIXME: some better way to handle invalid message? - nm_warning ("GetSecrets call returned but no secrets were found."); - goto out; - } - - g_hash_table_foreach (settings, add_one_key_to_list, &keys); - keys = g_slist_sort (keys, settings_order_func); - for (iter = keys; iter; iter = g_slist_next (iter)) { - GHashTable *setting_hash; - - setting_hash = g_hash_table_lookup (settings, iter->data); - if (setting_hash) { - update_one_setting ((const char *) iter->data, - setting_hash, - priv->connection, - &updated); - } else - nm_warning ("Couldn't get setting secrets for '%s'", (const char *) iter->data); - } - g_slist_free (keys); - - if (g_slist_length (updated)) { - g_signal_emit (info->req, - signals[CONNECTION_SECRETS_UPDATED], - 0, - priv->connection, - updated, - info->caller); - } else { - nm_warning ("No secrets updated because not valid settings were received!"); - } - -out: - g_slist_free (updated); - g_hash_table_destroy (settings); + /* interface implementation */ + sp_interface_class->update_setting = secrets_update_setting; + sp_interface_class->result = secrets_result; } gboolean -nm_act_request_request_connection_secrets (NMActRequest *self, - const char *setting_name, - gboolean request_new, - RequestSecretsCaller caller, - const char *hint1, - const char *hint2) +nm_act_request_get_secrets (NMActRequest *self, + const char *setting_name, + gboolean request_new, + RequestSecretsCaller caller, + const char *hint1, + const char *hint2) { - DBusGProxy *secrets_proxy; - GetSecretsInfo *info = NULL; - NMActRequestPrivate *priv = NULL; - GPtrArray *hints = NULL; - + g_return_val_if_fail (self, FALSE); g_return_val_if_fail (NM_IS_ACT_REQUEST (self), FALSE); - g_return_val_if_fail (setting_name != NULL, FALSE); - - priv = NM_ACT_REQUEST_GET_PRIVATE (self); - - cleanup_secrets_dbus_call (self); - - info = g_malloc0 (sizeof (GetSecretsInfo)); - g_return_val_if_fail (info != NULL, FALSE); - - info->req = self; - info->caller = caller; - info->setting_name = g_strdup (setting_name); - - /* Empty for now */ - hints = g_ptr_array_sized_new (2); - - if (hint1) - g_ptr_array_add (hints, g_strdup (hint1)); - if (hint2) - g_ptr_array_add (hints, g_strdup (hint2)); - - secrets_proxy = g_object_get_data (G_OBJECT (priv->connection), NM_MANAGER_CONNECTION_SECRETS_PROXY_TAG); - g_assert (secrets_proxy); - - priv->secrets_call = dbus_g_proxy_begin_call_with_timeout (secrets_proxy, "GetSecrets", - get_secrets_cb, - info, - free_get_secrets_info, - G_MAXINT32, - G_TYPE_STRING, setting_name, - DBUS_TYPE_G_ARRAY_OF_STRING, hints, - G_TYPE_BOOLEAN, request_new, - G_TYPE_INVALID); - g_ptr_array_free (hints, TRUE); - if (!priv->secrets_call) { - nm_warning ("Could not call get secrets"); - goto error; - } - - return TRUE; -error: - if (info) - free_get_secrets_info (info); - cleanup_secrets_dbus_call (self); - return FALSE; + return nm_secrets_provider_interface_get_secrets (NM_SECRETS_PROVIDER_INTERFACE (self), + nm_act_request_get_connection (self), + setting_name, + request_new, + caller, + hint1, + hint2); } NMConnection * diff --git a/src/nm-activation-request.h b/src/nm-activation-request.h index 6ddd0373b1..18760925f2 100644 --- a/src/nm-activation-request.h +++ b/src/nm-activation-request.h @@ -25,6 +25,7 @@ #include #include "nm-connection.h" #include "nm-active-connection.h" +#include "nm-secrets-provider-interface.h" #define NM_TYPE_ACT_REQUEST (nm_act_request_get_type ()) #define NM_ACT_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_ACT_REQUEST, NMActRequest)) @@ -37,27 +38,18 @@ typedef struct { GObject parent; } NMActRequest; -typedef enum { - SECRETS_CALLER_NONE = 0, - SECRETS_CALLER_ETHERNET, - SECRETS_CALLER_WIFI, - SECRETS_CALLER_GSM, - SECRETS_CALLER_CDMA, - SECRETS_CALLER_PPP -} RequestSecretsCaller; - typedef struct { GObjectClass parent; /* Signals */ - void (*connection_secrets_updated) (NMActRequest *req, - NMConnection *connection, - GSList *updated_settings, - RequestSecretsCaller caller); - void (*connection_secrets_failed) (NMActRequest *req, - NMConnection *connection, - const char *setting, - RequestSecretsCaller caller); + void (*secrets_updated) (NMActRequest *req, + NMConnection *connection, + GSList *updated_settings, + RequestSecretsCaller caller); + void (*secrets_failed) (NMActRequest *req, + NMConnection *connection, + const char *setting, + RequestSecretsCaller caller); void (*properties_changed) (NMActRequest *req, GHashTable *properties); } NMActRequestClass; @@ -70,12 +62,6 @@ NMActRequest *nm_act_request_new (NMConnection *connection, gpointer *device); /* An NMDevice */ NMConnection *nm_act_request_get_connection (NMActRequest *req); -gboolean nm_act_request_request_connection_secrets (NMActRequest *req, - const char *setting_name, - gboolean request_new, - RequestSecretsCaller caller, - const char *hint1, - const char *hint2); const char * nm_act_request_get_specific_object (NMActRequest *req); void nm_act_request_set_specific_object (NMActRequest *req, @@ -99,4 +85,12 @@ void nm_act_request_add_share_rule (NMActRequest *req, GObject * nm_act_request_get_device (NMActRequest *req); +gboolean nm_act_request_get_secrets (NMActRequest *req, + const char *setting_name, + gboolean request_new, + RequestSecretsCaller caller, + const char *hint1, + const char *hint2); + #endif /* NM_ACTIVATION_REQUEST_H */ + diff --git a/src/nm-dbus-manager.c b/src/nm-dbus-manager.c index bb52457a75..37039f1872 100644 --- a/src/nm-dbus-manager.c +++ b/src/nm-dbus-manager.c @@ -339,6 +339,24 @@ nm_dbus_manager_start_service (NMDBusManager *self) return FALSE; } + if (!dbus_g_proxy_call (priv->proxy, "RequestName", &err, + G_TYPE_STRING, NM_DBUS_SERVICE_SYSTEM_SETTINGS, + G_TYPE_UINT, DBUS_NAME_FLAG_DO_NOT_QUEUE, + G_TYPE_INVALID, + G_TYPE_UINT, &result, + G_TYPE_INVALID)) { + g_warning ("Could not acquire the NetworkManagerSystemSettings service.\n" + " Message: '%s'", err->message); + g_error_free (err); + return FALSE; + } + + if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { + g_warning ("Could not acquire the NetworkManagerSystemSettings service " + "as it is already taken."); + return FALSE; + } + priv->started = TRUE; return priv->started; } diff --git a/src/nm-device-ethernet.c b/src/nm-device-ethernet.c index 393390315c..b8a8590319 100644 --- a/src/nm-device-ethernet.c +++ b/src/nm-device-ethernet.c @@ -104,6 +104,7 @@ typedef struct { struct ether_addr hw_addr; gboolean carrier; + guint32 ifindex; guint state_to_disconnected_id; char * carrier_file_path; @@ -131,6 +132,7 @@ enum { PROP_HW_ADDRESS, PROP_SPEED, PROP_CARRIER, + PROP_IFINDEX, LAST_PROP }; @@ -386,7 +388,7 @@ NMDeviceEthernet * nm_device_ethernet_new (const char *udi, const char *iface, const char *driver, - gboolean managed) + guint32 ifindex) { g_return_val_if_fail (udi != NULL, NULL); g_return_val_if_fail (iface != NULL, NULL); @@ -396,7 +398,7 @@ nm_device_ethernet_new (const char *udi, NM_DEVICE_INTERFACE_UDI, udi, NM_DEVICE_INTERFACE_IFACE, iface, NM_DEVICE_INTERFACE_DRIVER, driver, - NM_DEVICE_INTERFACE_MANAGED, managed, + NM_DEVICE_ETHERNET_IFINDEX, ifindex, NULL); } @@ -427,6 +429,14 @@ nm_device_ethernet_get_carrier (NMDeviceEthernet *self) return NM_DEVICE_ETHERNET_GET_PRIVATE (self)->carrier; } +guint32 +nm_device_ethernet_get_ifindex (NMDeviceEthernet *self) +{ + g_return_val_if_fail (self != NULL, FALSE); + + return NM_DEVICE_ETHERNET_GET_PRIVATE (self)->ifindex; +} + /* Returns speed in Mb/s */ static guint32 nm_device_ethernet_get_speed (NMDeviceEthernet *self) @@ -801,8 +811,12 @@ link_timeout_cb (gpointer user_data) supplicant_interface_release (self); nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT); - nm_act_request_request_connection_secrets (req, setting_name, TRUE, - SECRETS_CALLER_ETHERNET, NULL, NULL); + nm_act_request_get_secrets (req, + setting_name, + TRUE, + SECRETS_CALLER_ETHERNET, + NULL, + NULL); return FALSE; @@ -1078,8 +1092,12 @@ handle_auth_or_fail (NMDeviceEthernet *self, * only ask for new secrets after the first failure. */ get_new = new_secrets ? TRUE : (tries ? TRUE : FALSE); - nm_act_request_request_connection_secrets (req, setting_name, get_new, - SECRETS_CALLER_ETHERNET, NULL, NULL); + nm_act_request_get_secrets (req, + setting_name, + get_new, + SECRETS_CALLER_ETHERNET, + NULL, + NULL); g_object_set_data (G_OBJECT (connection), WIRED_SECRETS_TRIES, GUINT_TO_POINTER (++tries)); } else @@ -1445,6 +1463,21 @@ real_check_connection_compatible (NMDevice *device, return TRUE; } +static gboolean +spec_match_list (NMDevice *device, const GSList *specs) +{ + struct ether_addr ether; + char *hwaddr; + gboolean matched; + + nm_device_ethernet_get_address (NM_DEVICE_ETHERNET (device), ðer); + hwaddr = nm_ether_ntop (ðer); + matched = nm_match_spec_hwaddr (specs, hwaddr); + g_free (hwaddr); + + return matched; +} + static void nm_device_ethernet_dispose (GObject *object) { @@ -1512,12 +1545,31 @@ get_property (GObject *object, guint prop_id, case PROP_CARRIER: g_value_set_boolean (value, nm_device_ethernet_get_carrier (device)); break; + case PROP_IFINDEX: + g_value_set_uint (value, nm_device_ethernet_get_ifindex (device)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_IFINDEX: + /* construct-only */ + priv->ifindex = g_value_get_uint (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} static void nm_device_ethernet_class_init (NMDeviceEthernetClass *klass) @@ -1531,6 +1583,7 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *klass) object_class->constructor = constructor; object_class->dispose = nm_device_ethernet_dispose; object_class->get_property = get_property; + object_class->set_property = set_property; object_class->finalize = nm_device_ethernet_finalize; parent_class->get_generic_capabilities = real_get_generic_capabilities; @@ -1550,6 +1603,7 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *klass) parent_class->act_stage2_config = real_act_stage2_config; parent_class->act_stage4_get_ip4_config = real_act_stage4_get_ip4_config; parent_class->deactivate_quickly = real_deactivate_quickly; + parent_class->spec_match_list = spec_match_list; /* properties */ g_object_class_install_property @@ -1576,6 +1630,14 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *klass) FALSE, G_PARAM_READABLE)); + g_object_class_install_property + (object_class, PROP_IFINDEX, + g_param_spec_uint (NM_DEVICE_ETHERNET_IFINDEX, + "Ifindex", + "Interface index", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + /* Signals */ signals[PROPERTIES_CHANGED] = nm_properties_changed_signal_new (object_class, diff --git a/src/nm-device-ethernet.h b/src/nm-device-ethernet.h index 608224ddc4..4ab851ce36 100644 --- a/src/nm-device-ethernet.h +++ b/src/nm-device-ethernet.h @@ -39,6 +39,7 @@ G_BEGIN_DECLS #define NM_DEVICE_ETHERNET_HW_ADDRESS "hw-address" #define NM_DEVICE_ETHERNET_SPEED "speed" #define NM_DEVICE_ETHERNET_CARRIER "carrier" +#define NM_DEVICE_ETHERNET_IFINDEX "ifindex" typedef struct { NMDevice parent; @@ -56,15 +57,17 @@ GType nm_device_ethernet_get_type (void); NMDeviceEthernet *nm_device_ethernet_new (const char *udi, - const char *iface, - const char *driver, - gboolean managed); + const char *iface, + const char *driver, + guint32 ifindex); void nm_device_ethernet_get_address (NMDeviceEthernet *dev, struct ether_addr *addr); gboolean nm_device_ethernet_get_carrier (NMDeviceEthernet *dev); +guint32 nm_device_ethernet_get_ifindex (NMDeviceEthernet *dev); + G_END_DECLS #endif /* NM_DEVICE_ETHERNET_H */ diff --git a/src/nm-device-interface.c b/src/nm-device-interface.c index 6d45ca9052..0a2ccf120e 100644 --- a/src/nm-device-interface.c +++ b/src/nm-device-interface.c @@ -70,8 +70,8 @@ nm_device_interface_init (gpointer g_iface) g_object_interface_install_property (g_iface, g_param_spec_string (NM_DEVICE_INTERFACE_UDI, - "Udi", - "HAL Udi", + "UDI", + "Unique Device Identifier", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); @@ -143,7 +143,7 @@ nm_device_interface_init (gpointer g_iface) (g_iface, g_param_spec_boolean (NM_DEVICE_INTERFACE_MANAGED, "Managed", "Managed", - TRUE, + FALSE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); /* Signals */ @@ -270,3 +270,12 @@ nm_device_interface_get_state (NMDeviceInterface *device) return state; } +gboolean +nm_device_interface_spec_match_list (NMDeviceInterface *device, + const GSList *specs) +{ + if (NM_DEVICE_INTERFACE_GET_INTERFACE (device)->spec_match_list) + return NM_DEVICE_INTERFACE_GET_INTERFACE (device)->spec_match_list (device, specs); + return FALSE; +} + diff --git a/src/nm-device-interface.h b/src/nm-device-interface.h index b1f56db215..14d1a38f88 100644 --- a/src/nm-device-interface.h +++ b/src/nm-device-interface.h @@ -41,16 +41,16 @@ typedef enum #define NM_DEVICE_INTERFACE_ERROR (nm_device_interface_error_quark ()) #define NM_TYPE_DEVICE_INTERFACE_ERROR (nm_device_interface_error_get_type ()) -#define NM_DEVICE_INTERFACE_UDI "udi" -#define NM_DEVICE_INTERFACE_IFACE "interface" -#define NM_DEVICE_INTERFACE_DRIVER "driver" +#define NM_DEVICE_INTERFACE_UDI "udi" +#define NM_DEVICE_INTERFACE_IFACE "interface" +#define NM_DEVICE_INTERFACE_DRIVER "driver" #define NM_DEVICE_INTERFACE_CAPABILITIES "capabilities" -#define NM_DEVICE_INTERFACE_IP4_ADDRESS "ip4-address" -#define NM_DEVICE_INTERFACE_IP4_CONFIG "ip4-config" +#define NM_DEVICE_INTERFACE_IP4_ADDRESS "ip4-address" +#define NM_DEVICE_INTERFACE_IP4_CONFIG "ip4-config" #define NM_DEVICE_INTERFACE_DHCP4_CONFIG "dhcp4-config" -#define NM_DEVICE_INTERFACE_STATE "state" -#define NM_DEVICE_INTERFACE_DEVICE_TYPE "device-type" /* ugh */ -#define NM_DEVICE_INTERFACE_MANAGED "managed" +#define NM_DEVICE_INTERFACE_STATE "state" +#define NM_DEVICE_INTERFACE_DEVICE_TYPE "device-type" /* ugh */ +#define NM_DEVICE_INTERFACE_MANAGED "managed" typedef enum { NM_DEVICE_INTERFACE_PROP_FIRST = 0x1000, @@ -84,6 +84,8 @@ struct _NMDeviceInterface { void (*deactivate) (NMDeviceInterface *device, NMDeviceStateReason reason); + gboolean (*spec_match_list) (NMDeviceInterface *device, const GSList *specs); + /* Signals */ void (*state_changed) (NMDeviceInterface *device, NMDeviceState new_state, @@ -108,4 +110,7 @@ void nm_device_interface_deactivate (NMDeviceInterface *device, NMDeviceStateRea NMDeviceState nm_device_interface_get_state (NMDeviceInterface *device); +gboolean nm_device_interface_spec_match_list (NMDeviceInterface *device, + const GSList *specs); + #endif /* NM_DEVICE_INTERFACE_H */ diff --git a/src/nm-device-wifi.c b/src/nm-device-wifi.c index 2b62b8bc8c..3664c1b83d 100644 --- a/src/nm-device-wifi.c +++ b/src/nm-device-wifi.c @@ -81,6 +81,7 @@ enum { PROP_BITRATE, PROP_ACTIVE_ACCESS_POINT, PROP_CAPABILITIES, + PROP_IFINDEX, LAST_PROP }; @@ -138,6 +139,7 @@ struct _NMDeviceWifiPrivate { gboolean dispose_has_run; struct ether_addr hw_addr; + guint32 ifindex; GByteArray * ssid; gint8 invalid_strength_counter; @@ -2136,8 +2138,12 @@ link_timeout_cb (gpointer user_data) " asking for new key.", nm_device_get_iface (dev)); cleanup_association_attempt (self, TRUE); nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT); - nm_act_request_request_connection_secrets (req, setting_name, TRUE, - SECRETS_CALLER_WIFI, NULL, NULL); + nm_act_request_get_secrets (req, + setting_name, + TRUE, + SECRETS_CALLER_WIFI, + NULL, + NULL); return FALSE; } @@ -2495,8 +2501,12 @@ handle_auth_or_fail (NMDeviceWifi *self, * only ask for new secrets after the first failure. */ get_new = new_secrets ? TRUE : (tries ? TRUE : FALSE); - nm_act_request_request_connection_secrets (req, setting_name, get_new, - SECRETS_CALLER_WIFI, NULL, NULL); + nm_act_request_get_secrets (req, + setting_name, + get_new, + SECRETS_CALLER_WIFI, + NULL, + NULL); g_object_set_data (G_OBJECT (connection), WIRELESS_SECRETS_TRIES, GUINT_TO_POINTER (++tries)); } else { @@ -2671,10 +2681,10 @@ build_supplicant_config (NMDeviceWifi *self, s_wireless_sec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY); if (s_wireless_sec) { - DBusGProxy *proxy = g_object_get_data (G_OBJECT (connection), NM_MANAGER_CONNECTION_PROXY_TAG); - const char *con_path = dbus_g_proxy_get_path (proxy); NMSetting8021x *s_8021x; + const char *con_path = nm_connection_get_path (connection); + g_assert (con_path); s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X); if (!nm_supplicant_config_add_setting_wireless_security (config, s_wireless_sec, @@ -3209,6 +3219,21 @@ nm_device_wifi_dispose (GObject *object) G_OBJECT_CLASS (nm_device_wifi_parent_class)->dispose (object); } +static gboolean +spec_match_list (NMDevice *device, const GSList *specs) +{ + struct ether_addr ether; + char *hwaddr; + gboolean matched; + + nm_device_wifi_get_address (NM_DEVICE_WIFI (device), ðer); + hwaddr = nm_ether_ntop (ðer); + matched = nm_match_spec_hwaddr (specs, hwaddr); + g_free (hwaddr); + + return matched; +} + static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) @@ -3237,12 +3262,33 @@ get_property (GObject *object, guint prop_id, else g_value_set_boxed (value, "/"); break; + case PROP_IFINDEX: + g_value_set_uint (value, nm_device_wifi_get_ifindex (device)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_IFINDEX: + /* construct-only */ + priv->ifindex = g_value_get_uint (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } + static void nm_device_wifi_class_init (NMDeviceWifiClass *klass) { @@ -3253,6 +3299,7 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass) object_class->constructor = constructor; object_class->get_property = get_property; + object_class->set_property = set_property; object_class->dispose = nm_device_wifi_dispose; parent_class->get_type_capabilities = real_get_type_capabilities; @@ -3276,6 +3323,7 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass) parent_class->deactivate = real_deactivate; parent_class->deactivate_quickly = real_deactivate_quickly; parent_class->can_interrupt_activation = real_can_interrupt_activation; + parent_class->spec_match_list = spec_match_list; /* Properties */ g_object_class_install_property (object_class, PROP_HW_ADDRESS, @@ -3315,6 +3363,13 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass) 0, G_MAXUINT32, NM_WIFI_DEVICE_CAP_NONE, G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_IFINDEX, + g_param_spec_uint (NM_DEVICE_WIFI_IFINDEX, + "Ifindex", + "Interface index", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + /* Signals */ signals[ACCESS_POINT_ADDED] = g_signal_new ("access-point-added", @@ -3435,7 +3490,7 @@ NMDeviceWifi * nm_device_wifi_new (const char *udi, const char *iface, const char *driver, - gboolean managed) + guint32 ifindex) { GObject *obj; @@ -3447,7 +3502,7 @@ nm_device_wifi_new (const char *udi, NM_DEVICE_INTERFACE_UDI, udi, NM_DEVICE_INTERFACE_IFACE, iface, NM_DEVICE_INTERFACE_DRIVER, driver, - NM_DEVICE_INTERFACE_MANAGED, managed, + NM_DEVICE_WIFI_IFINDEX, ifindex, NULL); if (obj == NULL) return NULL; @@ -3457,6 +3512,14 @@ nm_device_wifi_new (const char *udi, return NM_DEVICE_WIFI (obj); } +guint32 +nm_device_wifi_get_ifindex (NMDeviceWifi *self) +{ + g_return_val_if_fail (self != NULL, FALSE); + + return NM_DEVICE_WIFI_GET_PRIVATE (self)->ifindex; +} + NMAccessPoint * nm_device_wifi_get_activation_ap (NMDeviceWifi *self) { diff --git a/src/nm-device-wifi.h b/src/nm-device-wifi.h index 1e885cb036..4fe6dd5836 100644 --- a/src/nm-device-wifi.h +++ b/src/nm-device-wifi.h @@ -42,11 +42,12 @@ G_BEGIN_DECLS #define NM_DEVICE_WIFI_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_WIFI, NMDeviceWifiClass)) -#define NM_DEVICE_WIFI_HW_ADDRESS "hw-address" -#define NM_DEVICE_WIFI_MODE "mode" -#define NM_DEVICE_WIFI_BITRATE "bitrate" +#define NM_DEVICE_WIFI_HW_ADDRESS "hw-address" +#define NM_DEVICE_WIFI_MODE "mode" +#define NM_DEVICE_WIFI_BITRATE "bitrate" #define NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT "active-access-point" -#define NM_DEVICE_WIFI_CAPABILITIES "wireless-capabilities" +#define NM_DEVICE_WIFI_CAPABILITIES "wireless-capabilities" +#define NM_DEVICE_WIFI_IFINDEX "ifindex" #ifndef NM_DEVICE_WIFI_DEFINED #define NM_DEVICE_WIFI_DEFINED @@ -79,9 +80,9 @@ struct _NMDeviceWifiClass GType nm_device_wifi_get_type (void); NMDeviceWifi *nm_device_wifi_new (const char *udi, - const char *iface, - const char *driver, - gboolean managed); + const char *iface, + const char *driver, + guint32 ifindex); void nm_device_wifi_get_address (NMDeviceWifi *dev, struct ether_addr *addr); @@ -100,6 +101,8 @@ NMAccessPoint * nm_device_wifi_get_activation_ap (NMDeviceWifi *self); void nm_device_wifi_set_enabled (NMDeviceWifi *self, gboolean enabled); +guint32 nm_device_wifi_get_ifindex (NMDeviceWifi *self); + G_END_DECLS #endif /* NM_DEVICE_WIFI_H */ diff --git a/src/nm-device.c b/src/nm-device.c index 1506b96ba6..5769a0177f 100644 --- a/src/nm-device.c +++ b/src/nm-device.c @@ -66,12 +66,12 @@ struct _NMDevicePrivate { gboolean dispose_has_run; gboolean initialized; - guint start_timer; NMDeviceState state; guint failed_to_disconnected_id; char * udi; + char * path; char * iface; /* may change, could be renamed by user */ char * ip_iface; NMDeviceType type; @@ -109,13 +109,13 @@ struct _NMDevicePrivate static gboolean check_connection_compatible (NMDeviceInterface *device, NMConnection *connection, GError **error); - static gboolean nm_device_activate (NMDeviceInterface *device, NMActRequest *req, GError **error); +static void nm_device_deactivate (NMDeviceInterface *device, NMDeviceStateReason reason); +static gboolean nm_device_spec_match_list (NMDeviceInterface *device, const GSList *specs); static void nm_device_activate_schedule_stage5_ip_config_commit (NMDevice *self); -static void nm_device_deactivate (NMDeviceInterface *device, NMDeviceStateReason reason); static void nm_device_take_down (NMDevice *dev, gboolean wait, NMDeviceStateReason reason); @@ -131,6 +131,7 @@ device_interface_init (NMDeviceInterface *device_interface_class) device_interface_class->check_connection_compatible = check_connection_compatible; device_interface_class->activate = nm_device_activate; device_interface_class->deactivate = nm_device_deactivate; + device_interface_class->spec_match_list = nm_device_spec_match_list; } @@ -144,19 +145,6 @@ nm_device_init (NMDevice * self) self->priv->state = NM_DEVICE_STATE_UNMANAGED; } -static gboolean -device_start (gpointer user_data) -{ - NMDevice *self = NM_DEVICE (user_data); - - self->priv->start_timer = 0; - if (self->priv->managed) - nm_device_state_changed (self, NM_DEVICE_STATE_UNAVAILABLE, NM_DEVICE_STATE_REASON_NOW_MANAGED); - else - nm_info ("(%s): now unmanaged", nm_device_get_iface (self)); - return FALSE; -} - static GObject* constructor (GType type, guint n_construct_params, @@ -191,13 +179,10 @@ constructor (GType type, goto error; } - nm_print_device_capabilities (dev); + if (NM_DEVICE_GET_CLASS (dev)->update_hw_address) + NM_DEVICE_GET_CLASS (dev)->update_hw_address (dev); - /* Delay transition from UNMANAGED to UNAVAILABLE until we've given the - * system settings service a chance to figure out whether the device is - * managed or not. - */ - priv->start_timer = g_timeout_add_seconds (4, device_start, dev); + nm_print_device_capabilities (dev); priv->initialized = TRUE; return object; @@ -224,6 +209,22 @@ real_get_generic_capabilities (NMDevice *dev) return 0; } +void +nm_device_set_path (NMDevice *self, const char *path) +{ + g_return_if_fail (self != NULL); + g_return_if_fail (self->priv->path == NULL); + + self->priv->path = g_strdup (path); +} + +const char * +nm_device_get_path (NMDevice *self) +{ + g_return_val_if_fail (self != NULL, NULL); + + return self->priv->path; +} const char * nm_device_get_udi (NMDevice *self) @@ -2161,11 +2162,6 @@ nm_device_dispose (GObject *object) self->priv->dispose_has_run = TRUE; - if (self->priv->start_timer) { - g_source_remove (self->priv->start_timer); - self->priv->start_timer = 0; - } - if (self->priv->failed_to_disconnected_id) { g_source_remove (self->priv->failed_to_disconnected_id); self->priv->failed_to_disconnected_id = 0; @@ -2497,11 +2493,6 @@ nm_device_set_managed (NMDevice *device, priv->managed = managed; nm_info ("(%s): now %s", nm_device_get_iface (device), managed ? "managed" : "unmanaged"); - if (priv->start_timer) { - g_source_remove (priv->start_timer); - priv->start_timer = 0; - } - g_object_notify (G_OBJECT (device), NM_DEVICE_INTERFACE_MANAGED); /* If now managed, jump to unavailable */ @@ -2511,3 +2502,17 @@ nm_device_set_managed (NMDevice *device, nm_device_state_changed (device, NM_DEVICE_STATE_UNMANAGED, reason); } +static gboolean +nm_device_spec_match_list (NMDeviceInterface *device, const GSList *specs) +{ + NMDevice *self; + + g_return_val_if_fail (device != NULL, FALSE); + + self = NM_DEVICE (device); + if (NM_DEVICE_GET_CLASS (self)->spec_match_list) + return NM_DEVICE_GET_CLASS (self)->spec_match_list (self, specs); + + return FALSE; +} + diff --git a/src/nm-device.h b/src/nm-device.h index f78e1e8e94..c8e86254a4 100644 --- a/src/nm-device.h +++ b/src/nm-device.h @@ -113,11 +113,16 @@ struct _NMDeviceClass void (* deactivate_quickly) (NMDevice *self); gboolean (* can_interrupt_activation) (NMDevice *self); + + gboolean (* spec_match_list) (NMDevice *self, const GSList *specs); }; GType nm_device_get_type (void); +const char * nm_device_get_path (NMDevice *dev); +void nm_device_set_path (NMDevice *dev, const char *path); + const char * nm_device_get_udi (NMDevice *dev); const char * nm_device_get_iface (NMDevice *dev); const char * nm_device_get_ip_iface (NMDevice *dev); diff --git a/src/nm-hal-manager.c b/src/nm-hal-manager.c deleted file mode 100644 index 8b211e125e..0000000000 --- a/src/nm-hal-manager.c +++ /dev/null @@ -1,600 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager -- Network link manager - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2007 - 2008 Red Hat, Inc. - */ - -#include -#include -#include -#include -#include -#include - -#include "nm-glib-compat.h" -#include "nm-hal-manager.h" -#include "nm-marshal.h" -#include "nm-dbus-manager.h" -#include "nm-utils.h" -#include "nm-device-wifi.h" -#include "nm-device-ethernet.h" - -#define HAL_DBUS_SERVICE "org.freedesktop.Hal" - -typedef struct { - LibHalContext *hal_ctx; - NMDBusManager *dbus_mgr; - GSList *device_creators; - - gboolean disposed; -} NMHalManagerPrivate; - -#define NM_HAL_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_HAL_MANAGER, NMHalManagerPrivate)) - -G_DEFINE_TYPE (NMHalManager, nm_hal_manager, G_TYPE_OBJECT) - -enum { - UDI_ADDED, - UDI_REMOVED, - HAL_REAPPEARED, - - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0 }; - - -/* Device creators */ - -typedef struct { - GType device_type; - char *capability_str; - char *category; - gboolean (*is_device_fn) (NMHalManager *self, const char *udi); - NMDeviceCreatorFn creator_fn; -} DeviceCreator; - -static DeviceCreator * -get_creator (NMHalManager *self, const char *udi) -{ - NMHalManagerPrivate *priv = NM_HAL_MANAGER_GET_PRIVATE (self); - DeviceCreator *creator; - GSList *iter; - - for (iter = priv->device_creators; iter; iter = g_slist_next (iter)) { - creator = (DeviceCreator *) iter->data; - - if (libhal_device_query_capability (priv->hal_ctx, udi, creator->capability_str, NULL) && - creator->is_device_fn (self, udi)) - return creator; - } - - return NULL; -} - -/* end of device creators */ - -/* Common helpers for built-in device creators */ - -static char * -hal_get_subsystem (LibHalContext *ctx, const char *udi) -{ - char *subsys; - - subsys = libhal_device_get_property_string (ctx, udi, "info.subsystem", NULL); - if (!subsys) { - /* info.bus is deprecated */ - subsys = libhal_device_get_property_string (ctx, udi, "info.bus", NULL); - } - return subsys; -} - -static char * -nm_get_device_driver_name (LibHalContext *ctx, const char *origdev_udi) -{ - char *driver_name = NULL, *subsystem, *drv, *od_parent = NULL; - - if (!origdev_udi) - return NULL; - - /* s390 driver name is on the grandparent of the net device */ - subsystem = hal_get_subsystem (ctx, origdev_udi); - if (subsystem && !strcmp (subsystem, "ibmebus")) { - od_parent = libhal_device_get_property_string (ctx, origdev_udi, "info.parent", NULL); - origdev_udi = (const char *) od_parent; - } - - drv = libhal_device_get_property_string (ctx, origdev_udi, "info.linux.driver", NULL); - if (drv) - driver_name = g_strdup (drv); - - libhal_free_string (drv); - libhal_free_string (od_parent); - libhal_free_string (subsystem); - return driver_name; -} - -/* Wired device creator */ - -static gboolean -is_wired_device (NMHalManager *self, const char *udi) -{ - NMHalManagerPrivate *priv = NM_HAL_MANAGER_GET_PRIVATE (self); - char *category; - gboolean is_wired = FALSE; - - if (libhal_device_property_exists (priv->hal_ctx, udi, "net.linux.ifindex", NULL) && - libhal_device_property_exists (priv->hal_ctx, udi, "info.category", NULL)) { - - category = libhal_device_get_property_string (priv->hal_ctx, udi, "info.category", NULL); - if (category) { - is_wired = strcmp (category, "net.80203") == 0; - libhal_free_string (category); - } - } - - return is_wired; -} - -static GObject * -wired_device_creator (NMHalManager *self, - const char *udi, - const char *origdev_udi, - gboolean managed) -{ - NMHalManagerPrivate *priv = NM_HAL_MANAGER_GET_PRIVATE (self); - GObject *device; - char *iface; - char *driver; - - iface = libhal_device_get_property_string (priv->hal_ctx, udi, "net.interface", NULL); - if (!iface) { - nm_warning ("Couldn't get interface for %s, ignoring.", udi); - return NULL; - } - - driver = nm_get_device_driver_name (priv->hal_ctx, origdev_udi); - device = (GObject *) nm_device_ethernet_new (udi, iface, driver, managed); - - libhal_free_string (iface); - g_free (driver); - - return device; -} - -/* Wireless device creator */ - -static gboolean -is_wireless_device (NMHalManager *self, const char *udi) -{ - NMHalManagerPrivate *priv = NM_HAL_MANAGER_GET_PRIVATE (self); - char *category; - gboolean is_wireless = FALSE; - - if (libhal_device_property_exists (priv->hal_ctx, udi, "net.linux.ifindex", NULL) && - libhal_device_property_exists (priv->hal_ctx, udi, "info.category", NULL)) { - - category = libhal_device_get_property_string (priv->hal_ctx, udi, "info.category", NULL); - if (category) { - is_wireless = strcmp (category, "net.80211") == 0; - libhal_free_string (category); - } - } - - return is_wireless; -} - -static GObject * -wireless_device_creator (NMHalManager *self, - const char *udi, - const char *origdev_udi, - gboolean managed) -{ - NMHalManagerPrivate *priv = NM_HAL_MANAGER_GET_PRIVATE (self); - GObject *device; - char *iface; - char *driver; - - iface = libhal_device_get_property_string (priv->hal_ctx, udi, "net.interface", NULL); - if (!iface) { - nm_warning ("Couldn't get interface for %s, ignoring.", udi); - return NULL; - } - - driver = nm_get_device_driver_name (priv->hal_ctx, origdev_udi); - device = (GObject *) nm_device_wifi_new (udi, iface, driver, managed); - - libhal_free_string (iface); - g_free (driver); - - return device; -} - -static void -register_built_in_creators (NMHalManager *self) -{ - NMHalManagerPrivate *priv = NM_HAL_MANAGER_GET_PRIVATE (self); - DeviceCreator *creator; - - /* Wired device */ - creator = g_slice_new0 (DeviceCreator); - creator->device_type = NM_TYPE_DEVICE_ETHERNET; - creator->capability_str = g_strdup ("net.80203"); - creator->category = g_strdup ("net"); - creator->is_device_fn = is_wired_device; - creator->creator_fn = wired_device_creator; - priv->device_creators = g_slist_append (priv->device_creators, creator); - - /* Wireless device */ - creator = g_slice_new0 (DeviceCreator); - creator->device_type = NM_TYPE_DEVICE_WIFI; - creator->capability_str = g_strdup ("net.80211"); - creator->category = g_strdup ("net"); - creator->is_device_fn = is_wireless_device; - creator->creator_fn = wireless_device_creator; - priv->device_creators = g_slist_append (priv->device_creators, creator); -} - -static void -emit_udi_added (NMHalManager *self, const char *udi, DeviceCreator *creator) -{ - NMHalManagerPrivate *priv = NM_HAL_MANAGER_GET_PRIVATE (self); - char *od, *tmp; - - g_return_if_fail (self != NULL); - g_return_if_fail (udi != NULL); - g_return_if_fail (creator != NULL); - - tmp = g_strdup_printf ("%s.originating_device", creator->category); - od = libhal_device_get_property_string (priv->hal_ctx, udi, tmp, NULL); - g_free (tmp); - - if (!od) { - /* Older HAL uses 'physical_device' */ - tmp = g_strdup_printf ("%s.physical_device", creator->category); - od = libhal_device_get_property_string (priv->hal_ctx, udi, tmp, NULL); - g_free (tmp); - } - - g_signal_emit (self, signals[UDI_ADDED], 0, - udi, - od, - GSIZE_TO_POINTER (creator->device_type), - creator->creator_fn); - - libhal_free_string (od); -} - -static void -device_added (LibHalContext *ctx, const char *udi) -{ - NMHalManager *self = NM_HAL_MANAGER (libhal_ctx_get_user_data (ctx)); - DeviceCreator *creator; - - /* If not all the device's properties are set up yet (like net.interface), - * the device will actually get added later when HAL signals new device - * capabilties. - */ - creator = get_creator (self, udi); - if (creator) - emit_udi_added (self, udi, creator); -} - -static void -device_removed (LibHalContext *ctx, const char *udi) -{ - NMHalManager *self = NM_HAL_MANAGER (libhal_ctx_get_user_data (ctx)); - - g_signal_emit (self, signals[UDI_REMOVED], 0, udi); -} - -static void -device_new_capability (LibHalContext *ctx, const char *udi, const char *capability) -{ - NMHalManager *self = NM_HAL_MANAGER (libhal_ctx_get_user_data (ctx)); - DeviceCreator *creator; - - creator = get_creator (self, udi); - if (creator) - emit_udi_added (self, udi, creator); -} - -static void -add_initial_devices (NMHalManager *self) -{ - NMHalManagerPrivate *priv = NM_HAL_MANAGER_GET_PRIVATE (self); - DeviceCreator *creator; - GSList *iter; - char **devices; - int num_devices; - int i; - DBusError err; - - for (iter = priv->device_creators; iter; iter = g_slist_next (iter)) { - creator = (DeviceCreator *) iter->data; - - dbus_error_init (&err); - devices = libhal_find_device_by_capability (priv->hal_ctx, - creator->capability_str, - &num_devices, - &err); - if (dbus_error_is_set (&err)) { - nm_warning ("could not find existing devices: %s", err.message); - dbus_error_free (&err); - continue; - } - if (!devices) - continue; - - for (i = 0; i < num_devices; i++) { - if (creator->is_device_fn (self, devices[i])) - emit_udi_added (self, devices[i], creator); - } - - libhal_free_string_array (devices); - } -} - -static gboolean -hal_init (NMHalManager *self) -{ - NMHalManagerPrivate *priv = NM_HAL_MANAGER_GET_PRIVATE (self); - DBusError error; - DBusGConnection *connection; - - priv->hal_ctx = libhal_ctx_new (); - if (!priv->hal_ctx) { - nm_warning ("Could not get connection to the HAL service."); - return FALSE; - } - - connection = nm_dbus_manager_get_connection (priv->dbus_mgr); - libhal_ctx_set_dbus_connection (priv->hal_ctx, - dbus_g_connection_get_connection (connection)); - - dbus_error_init (&error); - if (!libhal_ctx_init (priv->hal_ctx, &error)) { - nm_warning ("libhal_ctx_init() failed: %s\n" - "Make sure the hal daemon is running?", - error.message); - goto error; - } - - libhal_ctx_set_user_data (priv->hal_ctx, self); - libhal_ctx_set_device_added (priv->hal_ctx, device_added); - libhal_ctx_set_device_removed (priv->hal_ctx, device_removed); - libhal_ctx_set_device_new_capability (priv->hal_ctx, device_new_capability); - - libhal_device_property_watch_all (priv->hal_ctx, &error); - if (dbus_error_is_set (&error)) { - nm_error ("libhal_device_property_watch_all(): %s", error.message); - libhal_ctx_shutdown (priv->hal_ctx, NULL); - goto error; - } - - return TRUE; - -error: - if (dbus_error_is_set (&error)) - dbus_error_free (&error); - if (priv->hal_ctx) { - libhal_ctx_free (priv->hal_ctx); - priv->hal_ctx = NULL; - } - return FALSE; -} - -static void -hal_deinit (NMHalManager *self) -{ - NMHalManagerPrivate *priv = NM_HAL_MANAGER_GET_PRIVATE (self); - DBusError error; - - if (!priv->hal_ctx) - return; - - dbus_error_init (&error); - libhal_ctx_shutdown (priv->hal_ctx, &error); - if (dbus_error_is_set (&error)) { - nm_warning ("libhal shutdown failed - %s", error.message); - dbus_error_free (&error); - } - - libhal_ctx_free (priv->hal_ctx); - priv->hal_ctx = NULL; -} - -static void -name_owner_changed (NMDBusManager *dbus_mgr, - const char *name, - const char *old, - const char *new, - gpointer user_data) -{ - NMHalManager *self = NM_HAL_MANAGER (user_data); - gboolean old_owner_good = (old && (strlen (old) > 0)); - gboolean new_owner_good = (new && (strlen (new) > 0)); - - /* Only care about signals from HAL */ - if (strcmp (name, HAL_DBUS_SERVICE)) - return; - - if (!old_owner_good && new_owner_good) { - nm_info ("HAL re-appeared"); - /* HAL just appeared */ - if (!hal_init (self)) - nm_warning ("Could not re-connect to HAL!!"); - else - g_signal_emit (self, signals[HAL_REAPPEARED], 0); - } else if (old_owner_good && !new_owner_good) { - /* HAL went away. Bad HAL. */ - nm_info ("HAL disappeared"); - hal_deinit (self); - } -} - -static void -connection_changed (NMDBusManager *dbus_mgr, - DBusGConnection *connection, - gpointer user_data) -{ - NMHalManager *self = NM_HAL_MANAGER (user_data); - - if (!connection) { - hal_deinit (self); - return; - } - - if (nm_dbus_manager_name_has_owner (dbus_mgr, HAL_DBUS_SERVICE)) { - if (!hal_init (self)) - nm_warning ("Could not re-connect to HAL!!"); - } -} - -void -nm_hal_manager_query_devices (NMHalManager *self) -{ - NMHalManagerPrivate *priv = NM_HAL_MANAGER_GET_PRIVATE (self); - - /* Find hardware we care about */ - if (priv->hal_ctx) - add_initial_devices (self); -} - -gboolean -nm_hal_manager_udi_exists (NMHalManager *self, const char *udi) -{ - NMHalManagerPrivate *priv = NM_HAL_MANAGER_GET_PRIVATE (self); - - return libhal_device_property_exists (priv->hal_ctx, udi, "info.udi", NULL); -} - -NMHalManager * -nm_hal_manager_new (void) -{ - NMHalManager *self; - NMHalManagerPrivate *priv; - - self = NM_HAL_MANAGER (g_object_new (NM_TYPE_HAL_MANAGER, NULL)); - - priv = NM_HAL_MANAGER_GET_PRIVATE (self); - if (!nm_dbus_manager_name_has_owner (priv->dbus_mgr, HAL_DBUS_SERVICE)) { - nm_info ("Waiting for HAL to start..."); - return self; - } - - if (!hal_init (self)) { - g_object_unref (self); - self = NULL; - } - - return self; -} - -static void -nm_hal_manager_init (NMHalManager *self) -{ - NMHalManagerPrivate *priv = NM_HAL_MANAGER_GET_PRIVATE (self); - - priv->dbus_mgr = nm_dbus_manager_get (); - - register_built_in_creators (self); - - g_signal_connect (priv->dbus_mgr, - "name-owner-changed", - G_CALLBACK (name_owner_changed), - self); - g_signal_connect (priv->dbus_mgr, - "dbus-connection-changed", - G_CALLBACK (connection_changed), - self); -} - -static void -destroy_creator (gpointer data, gpointer user_data) -{ - DeviceCreator *creator = (DeviceCreator *) data; - - g_free (creator->capability_str); - g_free (creator->category); - g_slice_free (DeviceCreator, data); -} - -static void -dispose (GObject *object) -{ - NMHalManager *self = NM_HAL_MANAGER (object); - NMHalManagerPrivate *priv = NM_HAL_MANAGER_GET_PRIVATE (self); - - if (priv->disposed) { - G_OBJECT_CLASS (nm_hal_manager_parent_class)->dispose (object); - return; - } - priv->disposed = TRUE; - - g_object_unref (priv->dbus_mgr); - - g_slist_foreach (priv->device_creators, destroy_creator, NULL); - g_slist_free (priv->device_creators); - - hal_deinit (self); - - G_OBJECT_CLASS (nm_hal_manager_parent_class)->dispose (object); -} - -static void -nm_hal_manager_class_init (NMHalManagerClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (NMHalManagerPrivate)); - - /* virtual methods */ - object_class->dispose = dispose; - - /* Signals */ - signals[UDI_ADDED] = - g_signal_new ("udi-added", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMHalManagerClass, udi_added), - NULL, NULL, - _nm_marshal_VOID__STRING_STRING_POINTER_POINTER, - G_TYPE_NONE, 4, - G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_POINTER); - - signals[UDI_REMOVED] = - g_signal_new ("udi-removed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMHalManagerClass, udi_removed), - NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, - G_TYPE_STRING); - - signals[HAL_REAPPEARED] = - g_signal_new ("hal-reappeared", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMHalManagerClass, hal_reappeared), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); -} - diff --git a/src/nm-hal-manager.h b/src/nm-hal-manager.h deleted file mode 100644 index 9c32cdcde9..0000000000 --- a/src/nm-hal-manager.h +++ /dev/null @@ -1,67 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager -- Network link manager - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2007 - 2008 Red Hat, Inc. - */ - -#ifndef NM_HAL_MANAGER_H -#define NM_HAL_MANAGER_H - -#include -#include - -G_BEGIN_DECLS - -#define NM_TYPE_HAL_MANAGER (nm_hal_manager_get_type ()) -#define NM_HAL_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_HAL_MANAGER, NMHalManager)) -#define NM_HAL_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_HAL_MANAGER, NMHalManagerClass)) -#define NM_IS_HAL_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_HAL_MANAGER)) -#define NM_IS_HAL_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_HAL_MANAGER)) -#define NM_HAL_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_HAL_MANAGER, NMHalManagerClass)) - -typedef struct { - GObject parent; -} NMHalManager; - -typedef GObject *(*NMDeviceCreatorFn) (NMHalManager *manager, - const char *udi, - const char *origdev_udi, - gboolean managed); - -typedef struct { - GObjectClass parent; - - /* Virtual functions */ - void (*udi_added) (NMHalManager *manager, - const char *udi, - const char *originating_device, - gpointer general_device_type, - NMDeviceCreatorFn creator_fn); - - void (*udi_removed) (NMHalManager *manager, const char *udi); - - void (*hal_reappeared) (NMHalManager *manager); -} NMHalManagerClass; - -GType nm_hal_manager_get_type (void); - -NMHalManager *nm_hal_manager_new (void); -void nm_hal_manager_query_devices (NMHalManager *manager); -gboolean nm_hal_manager_udi_exists (NMHalManager *manager, const char *udi); - -#endif /* NM_HAL_MANAGER_H */ diff --git a/src/nm-manager.c b/src/nm-manager.c index 95c388c743..708a5bc3b2 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -43,11 +43,12 @@ #include "nm-setting-vpn.h" #include "nm-marshal.h" #include "nm-dbus-glib-types.h" -#include "nm-hal-manager.h" #include "nm-udev-manager.h" #include "nm-hostname-provider.h" #include "nm-bluez-manager.h" #include "nm-bluez-common.h" +#include "nm-sysconfig-settings.h" +#include "nm-secrets-provider-interface.h" #define NM_AUTOIP_DBUS_SERVICE "org.freedesktop.nm_avahi_autoipd" #define NM_AUTOIP_DBUS_IFACE "org.freedesktop.nm_avahi_autoipd" @@ -66,8 +67,6 @@ static gboolean impl_manager_deactivate_connection (NMManager *manager, static gboolean impl_manager_sleep (NMManager *manager, gboolean sleep, GError **err); -static gboolean poke_system_settings_daemon_cb (gpointer user_data); - /* Legacy 0.6 compatibility interface */ static gboolean impl_manager_legacy_sleep (NMManager *manager, GError **err); @@ -76,31 +75,26 @@ static gboolean impl_manager_legacy_state (NMManager *manager, guint32 *state, G #include "nm-manager-glue.h" -static void nm_manager_connections_destroy (NMManager *manager, NMConnectionScope scope); +static void user_destroy_connections (NMManager *manager); static void manager_set_wireless_enabled (NMManager *manager, gboolean enabled); static void connection_added_default_handler (NMManager *manager, NMConnection *connection, NMConnectionScope scope); -static void hal_manager_udi_added_cb (NMHalManager *hal_mgr, - const char *udi, - const char *originating_device, - gpointer general_type_ptr, - NMDeviceCreatorFn creator_fn, - gpointer user_data); +static void udev_device_added_cb (NMUdevManager *udev_mgr, + GUdevDevice *device, + NMDeviceCreatorFn creator_fn, + gpointer user_data); -static void hal_manager_udi_removed_cb (NMHalManager *hal_mgr, - const char *udi, - gpointer user_data); +static void udev_device_removed_cb (NMUdevManager *udev_mgr, + GUdevDevice *device, + gpointer user_data); -static void udev_manager_rfkill_changed_cb (NMHalManager *hal_mgr, +static void udev_manager_rfkill_changed_cb (NMUdevManager *udev_mgr, RfKillState state, gpointer user_data); -static void hal_manager_hal_reappeared_cb (NMHalManager *hal_mgr, - gpointer user_data); - static void bluez_manager_bdaddr_added_cb (NMBluezManager *bluez_mgr, const char *bdaddr, const char *name, @@ -115,10 +109,6 @@ static void bluez_manager_bdaddr_removed_cb (NMBluezManager *bluez_mgr, static void bluez_manager_resync_devices (NMManager *self); -static void system_settings_properties_changed_cb (DBusGProxy *proxy, - GHashTable *properties, - gpointer user_data); - static void add_device (NMManager *self, NMDevice *device); static void hostname_provider_init (NMHostnameProvider *provider_class); @@ -140,7 +130,6 @@ typedef struct { NMState state; NMDBusManager *dbus_mgr; - NMHalManager *hal_mgr; NMUdevManager *udev_mgr; NMBluezManager *bluez_mgr; @@ -148,19 +137,16 @@ typedef struct { DBusGProxy *user_proxy; GHashTable *system_connections; - DBusGProxy *system_proxy; - DBusGProxy *system_props_proxy; - GSList *unmanaged_udis; + NMSysconfigSettings *sys_settings; char *hostname; + GSList *secrets_calls; + PendingConnectionInfo *pending_connection_info; gboolean wireless_enabled; gboolean wireless_hw_enabled; gboolean sleeping; - guint poke_id; - guint sync_devices_id; - NMVPNManager *vpn_manager; guint vpn_manager_id; @@ -435,84 +421,6 @@ hostname_provider_init (NMHostnameProvider *provider_class) provider_class->get_hostname = hostname_provider_get_hostname; } -static void -nm_manager_init (NMManager *manager) -{ - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); - DBusGConnection *g_connection; - guint id; - - priv->wireless_enabled = TRUE; - priv->wireless_hw_enabled = TRUE; - priv->sleeping = FALSE; - priv->state = NM_STATE_DISCONNECTED; - - priv->dbus_mgr = nm_dbus_manager_get (); - - priv->user_connections = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - g_object_unref); - - priv->system_connections = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - g_object_unref); - - priv->modem_manager = nm_modem_manager_get (); - priv->modem_added_id = g_signal_connect (priv->modem_manager, "device-added", - G_CALLBACK (modem_added), manager); - priv->modem_removed_id = g_signal_connect (priv->modem_manager, "device-removed", - G_CALLBACK (modem_removed), manager); - - priv->vpn_manager = nm_vpn_manager_get (); - id = g_signal_connect (G_OBJECT (priv->vpn_manager), "connection-deactivated", - G_CALLBACK (vpn_manager_connection_deactivated_cb), manager); - priv->vpn_manager_id = id; - - g_connection = nm_dbus_manager_get_connection (priv->dbus_mgr); - - /* avahi-autoipd stuff */ - priv->aipd_proxy = dbus_g_proxy_new_for_name (g_connection, - NM_AUTOIP_DBUS_SERVICE, - "/", - NM_AUTOIP_DBUS_IFACE); - if (priv->aipd_proxy) { - dbus_g_object_register_marshaller (_nm_marshal_VOID__STRING_STRING_STRING, - G_TYPE_NONE, - G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, - G_TYPE_INVALID); - - dbus_g_proxy_add_signal (priv->aipd_proxy, - "Event", - G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, - G_TYPE_INVALID); - - dbus_g_proxy_connect_signal (priv->aipd_proxy, "Event", - G_CALLBACK (aipd_handle_event), - manager, - NULL); - } else - nm_warning ("%s: could not initialize avahi-autoipd D-Bus proxy", __func__); - - /* System settings stuff */ - priv->system_props_proxy = dbus_g_proxy_new_for_name (g_connection, - NM_DBUS_SERVICE_SYSTEM_SETTINGS, - NM_DBUS_PATH_SETTINGS, - "org.freedesktop.NetworkManagerSettings.System"); - if (priv->system_props_proxy) { - dbus_g_object_register_marshaller (g_cclosure_marshal_VOID__BOXED, - G_TYPE_NONE, G_TYPE_VALUE, G_TYPE_INVALID); - dbus_g_proxy_add_signal (priv->system_props_proxy, "PropertiesChanged", - DBUS_TYPE_G_MAP_OF_VARIANT, G_TYPE_INVALID); - dbus_g_proxy_connect_signal (priv->system_props_proxy, "PropertiesChanged", - G_CALLBACK (system_settings_properties_changed_cb), - manager, - NULL); - } else - nm_warning ("%s: could not initialize system settings properties D-Bus proxy", __func__); -} - NMState nm_manager_get_state (NMManager *manager) { @@ -521,6 +429,17 @@ nm_manager_get_state (NMManager *manager) return NM_MANAGER_GET_PRIVATE (manager)->state; } +static void +emit_removed (gpointer key, gpointer value, gpointer user_data) +{ + NMManager *manager = NM_MANAGER (user_data); + NMConnection *connection = NM_CONNECTION (value); + + g_signal_emit (manager, signals[CONNECTION_REMOVED], 0, + connection, + nm_connection_get_scope (connection)); +} + static void pending_connection_info_destroy (PendingConnectionInfo *info) { @@ -537,91 +456,6 @@ pending_connection_info_destroy (PendingConnectionInfo *info) g_slice_free (PendingConnectionInfo, info); } -static void -dispose (GObject *object) -{ - NMManager *manager = NM_MANAGER (object); - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); - - if (priv->disposed) { - G_OBJECT_CLASS (nm_manager_parent_class)->dispose (object); - return; - } - priv->disposed = TRUE; - - pending_connection_info_destroy (priv->pending_connection_info); - priv->pending_connection_info = NULL; - - if (priv->sync_devices_id) { - g_source_remove (priv->sync_devices_id); - priv->sync_devices_id = 0; - } - - while (g_slist_length (priv->devices)) { - NMDevice *device = NM_DEVICE (priv->devices->data); - - priv->devices = remove_one_device (manager, priv->devices, device); - } - - nm_manager_connections_destroy (manager, NM_CONNECTION_SCOPE_USER); - g_hash_table_destroy (priv->user_connections); - priv->user_connections = NULL; - - nm_manager_connections_destroy (manager, NM_CONNECTION_SCOPE_SYSTEM); - g_hash_table_destroy (priv->system_connections); - priv->system_connections = NULL; - - g_free (priv->hostname); - - if (priv->system_props_proxy) { - g_object_unref (priv->system_props_proxy); - priv->system_props_proxy = NULL; - } - g_slist_foreach (priv->unmanaged_udis, (GFunc) g_free, NULL); - g_slist_free (priv->unmanaged_udis); - - if (priv->poke_id) { - g_source_remove (priv->poke_id); - priv->poke_id = 0; - } - - if (priv->vpn_manager_id) { - g_source_remove (priv->vpn_manager_id); - priv->vpn_manager_id = 0; - } - g_object_unref (priv->vpn_manager); - - if (priv->modem_added_id) { - g_source_remove (priv->modem_added_id); - priv->modem_added_id = 0; - } - if (priv->modem_removed_id) { - g_source_remove (priv->modem_removed_id); - priv->modem_removed_id = 0; - } - g_object_unref (priv->modem_manager); - - g_object_unref (priv->dbus_mgr); - g_object_unref (priv->hal_mgr); - g_object_unref (priv->bluez_mgr); - - G_OBJECT_CLASS (nm_manager_parent_class)->dispose (object); -} - -static void -set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) -{ - switch (prop_id) { - case PROP_WIRELESS_ENABLED: - manager_set_wireless_enabled (NM_MANAGER (object), g_value_get_boolean (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - static GPtrArray * get_active_connections (NMManager *manager, NMConnection *filter) { @@ -656,194 +490,42 @@ get_active_connections (NMManager *manager, NMConnection *filter) } static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) +remove_connection (NMManager *manager, + NMConnection *connection, + GHashTable *hash) { - NMManager *self = NM_MANAGER (object); - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + /* Destroys the connection, then associated DBusGProxy due to the + * weak reference notify function placed on the connection when it + * was created. + */ + g_object_ref (connection); + g_hash_table_remove (hash, nm_connection_get_path (connection)); + g_signal_emit (manager, signals[CONNECTION_REMOVED], 0, + connection, + nm_connection_get_scope (connection)); + g_object_unref (connection); - switch (prop_id) { - case PROP_STATE: - nm_manager_update_state (self); - g_value_set_uint (value, priv->state); - break; - case PROP_WIRELESS_ENABLED: - g_value_set_boolean (value, priv->wireless_enabled); - break; - case PROP_WIRELESS_HARDWARE_ENABLED: - g_value_set_boolean (value, priv->wireless_hw_enabled); - break; - case PROP_ACTIVE_CONNECTIONS: - g_value_take_boxed (value, get_active_connections (self, NULL)); - break; - case PROP_HOSTNAME: - g_value_set_string (value, priv->hostname); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + bluez_manager_resync_devices (manager); } -static void -nm_manager_class_init (NMManagerClass *manager_class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (manager_class); - - g_type_class_add_private (manager_class, sizeof (NMManagerPrivate)); - - /* virtual methods */ - manager_class->connection_added = connection_added_default_handler; - - object_class->set_property = set_property; - object_class->get_property = get_property; - object_class->dispose = dispose; - - /* properties */ - g_object_class_install_property - (object_class, PROP_STATE, - g_param_spec_uint (NM_MANAGER_STATE, - "State", - "Current state", - 0, 5, 0, /* FIXME */ - G_PARAM_READABLE)); - - g_object_class_install_property - (object_class, PROP_WIRELESS_ENABLED, - g_param_spec_boolean (NM_MANAGER_WIRELESS_ENABLED, - "WirelessEnabled", - "Is wireless enabled", - TRUE, - G_PARAM_READWRITE)); - - g_object_class_install_property - (object_class, PROP_WIRELESS_HARDWARE_ENABLED, - g_param_spec_boolean (NM_MANAGER_WIRELESS_HARDWARE_ENABLED, - "WirelessHardwareEnabled", - "RF kill state", - TRUE, - G_PARAM_READABLE)); - - g_object_class_install_property - (object_class, PROP_ACTIVE_CONNECTIONS, - g_param_spec_boxed (NM_MANAGER_ACTIVE_CONNECTIONS, - "Active connections", - "Active connections", - DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, - G_PARAM_READABLE)); - - /* Hostname is not exported over D-Bus */ - g_object_class_install_property - (object_class, PROP_HOSTNAME, - g_param_spec_string (NM_MANAGER_HOSTNAME, - "Hostname", - "Hostname", - NULL, - G_PARAM_READABLE | NM_PROPERTY_PARAM_NO_EXPORT)); - - /* signals */ - signals[DEVICE_ADDED] = - g_signal_new ("device-added", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMManagerClass, device_added), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, - G_TYPE_OBJECT); - - signals[DEVICE_REMOVED] = - g_signal_new ("device-removed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMManagerClass, device_removed), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, - G_TYPE_OBJECT); +/*******************************************************************/ +/* User settings stuff via D-Bus */ +/*******************************************************************/ - signals[STATE_CHANGED] = - g_signal_new ("state-changed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMManagerClass, state_changed), - NULL, NULL, - g_cclosure_marshal_VOID__UINT, - G_TYPE_NONE, 1, - G_TYPE_UINT); - - signals[PROPERTIES_CHANGED] = - nm_properties_changed_signal_new (object_class, - G_STRUCT_OFFSET (NMManagerClass, properties_changed)); - - signals[CONNECTIONS_ADDED] = - g_signal_new ("connections-added", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMManagerClass, connections_added), - NULL, NULL, - g_cclosure_marshal_VOID__UINT, - G_TYPE_NONE, 1, - G_TYPE_UINT); - - signals[CONNECTION_ADDED] = - g_signal_new ("connection-added", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMManagerClass, connection_added), - NULL, NULL, - _nm_marshal_VOID__OBJECT_UINT, - G_TYPE_NONE, 2, - G_TYPE_OBJECT, G_TYPE_UINT); - - signals[CONNECTION_UPDATED] = - g_signal_new ("connection-updated", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMManagerClass, connection_updated), - NULL, NULL, - _nm_marshal_VOID__OBJECT_UINT, - G_TYPE_NONE, 2, - G_TYPE_OBJECT, G_TYPE_UINT); - - signals[CONNECTION_REMOVED] = - g_signal_new ("connection-removed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMManagerClass, connection_removed), - NULL, NULL, - _nm_marshal_VOID__OBJECT_UINT, - G_TYPE_NONE, 2, - G_TYPE_OBJECT, G_TYPE_UINT); - - /* StateChange is DEPRECATED */ - signals[STATE_CHANGE] = - g_signal_new ("state-change", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, - g_cclosure_marshal_VOID__UINT, - G_TYPE_NONE, 1, - G_TYPE_UINT); - - - dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (manager_class), - &dbus_glib_nm_manager_object_info); - - dbus_g_error_domain_register (NM_MANAGER_ERROR, NULL, NM_TYPE_MANAGER_ERROR); -} - -static NMConnectionScope -get_scope_for_proxy (DBusGProxy *proxy) +static void +user_destroy_connections (NMManager *manager) { - const char *bus_name = dbus_g_proxy_get_bus_name (proxy); + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); - if (strcmp (bus_name, NM_DBUS_SERVICE_USER_SETTINGS) == 0) - return NM_CONNECTION_SCOPE_USER; - else if (strcmp (bus_name, NM_DBUS_SERVICE_SYSTEM_SETTINGS) == 0) - return NM_CONNECTION_SCOPE_SYSTEM; + if (priv->user_connections) { + g_hash_table_foreach (priv->user_connections, emit_removed, manager); + g_hash_table_remove_all (priv->user_connections); + } - return NM_CONNECTION_SCOPE_UNKNOWN; + if (priv->user_proxy) { + g_object_unref (priv->user_proxy); + priv->user_proxy = NULL; + } } typedef struct GetSettingsInfo { @@ -851,9 +533,7 @@ typedef struct GetSettingsInfo { NMConnection *connection; DBusGProxy *proxy; DBusGProxyCall *call; - DBusGProxy *secrets_proxy; GSList **calls; - NMConnectionScope scope; } GetSettingsInfo; static void @@ -869,7 +549,7 @@ free_get_settings_info (gpointer data) if (g_slist_length (*(info->calls)) == 0) { g_slist_free (*(info->calls)); g_slice_free (GSList, (gpointer) info->calls); - g_signal_emit (info->manager, signals[CONNECTIONS_ADDED], 0, info->scope); + g_signal_emit (info->manager, signals[CONNECTIONS_ADDED], 0, NM_CONNECTION_SCOPE_USER); /* Update the Bluetooth connections for all the new connections */ bluez_manager_resync_devices (info->manager); @@ -884,20 +564,23 @@ free_get_settings_info (gpointer data) g_object_unref (info->connection); info->connection = NULL; } + if (info->proxy) { + g_object_unref (info->proxy); + info->proxy = NULL; + } g_slice_free (GetSettingsInfo, data); } static void -connection_get_settings_cb (DBusGProxy *proxy, - DBusGProxyCall *call_id, - gpointer user_data) +user_connection_get_settings_cb (DBusGProxy *proxy, + DBusGProxyCall *call_id, + gpointer user_data) { GetSettingsInfo *info = (GetSettingsInfo *) user_data; GError *err = NULL; GHashTable *settings = NULL; NMConnection *connection; - NMConnectionScope scope; NMManager *manager; g_return_if_fail (info != NULL); @@ -928,60 +611,29 @@ connection_get_settings_cb (DBusGProxy *proxy, goto out; } - scope = get_scope_for_proxy (proxy); - nm_connection_set_path (connection, path); - nm_connection_set_scope (connection, scope); - - g_object_set_data_full (G_OBJECT (connection), - NM_MANAGER_CONNECTION_PROXY_TAG, - proxy, - (GDestroyNotify) g_object_unref); - - g_object_set_data_full (G_OBJECT (connection), - NM_MANAGER_CONNECTION_SECRETS_PROXY_TAG, - info->secrets_proxy, - (GDestroyNotify) g_object_unref); + nm_connection_set_scope (connection, NM_CONNECTION_SCOPE_USER); /* Add the new connection to the internal hashes only if the same * connection isn't already there. */ priv = NM_MANAGER_GET_PRIVATE (manager); - switch (scope) { - case NM_CONNECTION_SCOPE_USER: - existing = g_hash_table_lookup (priv->user_connections, path); - if (!existing || !nm_connection_compare (existing, connection, NM_SETTING_COMPARE_FLAG_EXACT)) { - g_hash_table_insert (priv->user_connections, - g_strdup (path), - connection); - existing = NULL; - } else { - g_object_unref (connection); - } - break; - case NM_CONNECTION_SCOPE_SYSTEM: - existing = g_hash_table_lookup (priv->system_connections, path); - if (!existing || !nm_connection_compare (existing, connection, NM_SETTING_COMPARE_FLAG_EXACT)) { - g_hash_table_insert (priv->system_connections, - g_strdup (path), - connection); - existing = NULL; - } else { - g_object_unref (connection); - } - break; - default: - nm_warning ("Connection wasn't a user connection or a system connection."); - g_assert_not_reached (); - break; - } + + existing = g_hash_table_lookup (priv->user_connections, path); + if (!existing || !nm_connection_compare (existing, connection, NM_SETTING_COMPARE_FLAG_EXACT)) { + g_hash_table_insert (priv->user_connections, + g_strdup (path), + connection); + existing = NULL; + } else + g_object_unref (connection); /* If the connection-added signal is supposed to be batched, don't * emit the single connection-added here. Also, don't emit the signal * if the connection wasn't actually added to the system or user hashes. */ if (!info->calls && !existing) { - g_signal_emit (manager, signals[CONNECTION_ADDED], 0, connection, scope); + g_signal_emit (manager, signals[CONNECTION_ADDED], 0, connection, NM_CONNECTION_SCOPE_USER); /* Update the Bluetooth connections for that single new connection */ bluez_manager_resync_devices (manager); } @@ -997,74 +649,39 @@ out: return; } -static NMConnection * -get_connection_for_proxy (NMManager *manager, - DBusGProxy *proxy, - GHashTable **out_hash) +static void +user_connection_removed_cb (DBusGProxy *proxy, gpointer user_data) { + NMManager *manager = NM_MANAGER (user_data); NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); NMConnection *connection = NULL; - const char *path = dbus_g_proxy_get_path (proxy); + const char *path; - switch (get_scope_for_proxy (proxy)) { - case NM_CONNECTION_SCOPE_USER: - *out_hash = priv->user_connections; - connection = g_hash_table_lookup (priv->user_connections, path); - break; - case NM_CONNECTION_SCOPE_SYSTEM: - *out_hash = priv->system_connections; - connection = g_hash_table_lookup (priv->system_connections, path); - break; - default: - nm_warning ("Connection wasn't a user connection or a system connection."); - g_assert_not_reached (); - break; + path = dbus_g_proxy_get_path (proxy); + if (path) { + connection = g_hash_table_lookup (priv->user_connections, path); + if (connection) + remove_connection (manager, connection, priv->user_connections); } - return connection; -} - -static void -remove_connection (NMManager *manager, - NMConnection *connection, - GHashTable *hash) -{ - /* Destroys the connection, then associated DBusGProxy due to the - * weak reference notify function placed on the connection when it - * was created. - */ - g_object_ref (connection); - g_hash_table_remove (hash, nm_connection_get_path (connection)); - g_signal_emit (manager, signals[CONNECTION_REMOVED], 0, - connection, - nm_connection_get_scope (connection)); - g_object_unref (connection); - - bluez_manager_resync_devices (manager); -} - -static void -connection_removed_cb (DBusGProxy *proxy, gpointer user_data) -{ - NMManager * manager = NM_MANAGER (user_data); - NMConnection *connection = NULL; - GHashTable *hash = NULL; - - connection = get_connection_for_proxy (manager, proxy, &hash); - if (connection) - remove_connection (manager, connection, hash); } static void -connection_updated_cb (DBusGProxy *proxy, GHashTable *settings, gpointer user_data) +user_connection_updated_cb (DBusGProxy *proxy, + GHashTable *settings, + gpointer user_data) { NMManager *manager = NM_MANAGER (user_data); + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); NMConnection *new_connection; - NMConnection *old_connection; - GHashTable *hash; + NMConnection *old_connection = NULL; gboolean valid = FALSE; GError *error = NULL; + const char *path; + + path = dbus_g_proxy_get_path (proxy); + if (path) + old_connection = g_hash_table_lookup (priv->user_connections, path); - old_connection = get_connection_for_proxy (manager, proxy, &hash); g_return_if_fail (old_connection != NULL); new_connection = nm_connection_new_from_hash (settings, &error); @@ -1075,7 +692,7 @@ connection_updated_cb (DBusGProxy *proxy, GHashTable *settings, gpointer user_da g_type_name (nm_connection_lookup_setting_type_by_quark (error->domain)), error->message, error->code); g_error_free (error); - remove_connection (manager, old_connection, hash); + remove_connection (manager, old_connection, priv->user_connections); return; } g_object_unref (new_connection); @@ -1088,21 +705,20 @@ connection_updated_cb (DBusGProxy *proxy, GHashTable *settings, gpointer user_da bluez_manager_resync_devices (manager); } else { - remove_connection (manager, old_connection, hash); + remove_connection (manager, old_connection, priv->user_connections); } } static void -internal_new_connection_cb (DBusGProxy *proxy, - const char *path, - NMManager *manager, - GSList **calls) +user_internal_new_connection_cb (DBusGProxy *proxy, + const char *path, + NMManager *manager, + GSList **calls) { struct GetSettingsInfo *info; DBusGProxy *con_proxy; - DBusGConnection * g_connection; + DBusGConnection *g_connection; DBusGProxyCall *call; - DBusGProxy *secrets_proxy; NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); g_connection = nm_dbus_manager_get_connection (priv->dbus_mgr); @@ -1115,50 +731,38 @@ internal_new_connection_cb (DBusGProxy *proxy, return; } - secrets_proxy = dbus_g_proxy_new_for_name (g_connection, - dbus_g_proxy_get_bus_name (proxy), - path, - NM_DBUS_IFACE_SETTINGS_CONNECTION_SECRETS); - if (!secrets_proxy) { - nm_warning ("Error: could not init user connection secrets proxy"); - g_object_unref (con_proxy); - return; - } - dbus_g_proxy_add_signal (con_proxy, "Updated", DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, G_TYPE_INVALID); dbus_g_proxy_connect_signal (con_proxy, "Updated", - G_CALLBACK (connection_updated_cb), + G_CALLBACK (user_connection_updated_cb), manager, NULL); dbus_g_proxy_add_signal (con_proxy, "Removed", G_TYPE_INVALID, G_TYPE_INVALID); dbus_g_proxy_connect_signal (con_proxy, "Removed", - G_CALLBACK (connection_removed_cb), + G_CALLBACK (user_connection_removed_cb), manager, NULL); info = g_slice_new0 (GetSettingsInfo); info->manager = g_object_ref (manager); info->calls = calls; - info->scope = get_scope_for_proxy (con_proxy); call = dbus_g_proxy_begin_call (con_proxy, "GetSettings", - connection_get_settings_cb, + user_connection_get_settings_cb, info, free_get_settings_info, G_TYPE_INVALID); info->call = call; info->proxy = con_proxy; - info->secrets_proxy = secrets_proxy; if (info->calls) *(info->calls) = g_slist_prepend (*(info->calls), call); } static void -list_connections_cb (DBusGProxy *proxy, - DBusGProxyCall *call_id, - gpointer user_data) +user_list_connections_cb (DBusGProxy *proxy, + DBusGProxyCall *call_id, + gpointer user_data) { NMManager *manager = NM_MANAGER (user_data); GError *err = NULL; @@ -1182,7 +786,7 @@ list_connections_cb (DBusGProxy *proxy, for (i = 0; i < ops->len; i++) { char *op = g_ptr_array_index (ops, i); - internal_new_connection_cb (proxy, op, manager, calls); + user_internal_new_connection_cb (proxy, op, manager, calls); g_free (op); } @@ -1193,235 +797,223 @@ out: } static void -new_connection_cb (DBusGProxy *proxy, const char *path, gpointer user_data) +user_new_connection_cb (DBusGProxy *proxy, const char *path, gpointer user_data) { - internal_new_connection_cb (proxy, path, NM_MANAGER (user_data), NULL); + user_internal_new_connection_cb (proxy, path, NM_MANAGER (user_data), NULL); } static void -query_connections (NMManager *manager, - NMConnectionScope scope) +user_query_connections (NMManager *manager) { NMManagerPrivate *priv; DBusGProxyCall *call; - DBusGProxy ** proxy; - const char * service; + DBusGConnection *g_connection; g_return_if_fail (NM_IS_MANAGER (manager)); priv = NM_MANAGER_GET_PRIVATE (manager); - if (scope == NM_CONNECTION_SCOPE_USER) { - proxy = &priv->user_proxy; - service = NM_DBUS_SERVICE_USER_SETTINGS; - } else if (scope == NM_CONNECTION_SCOPE_SYSTEM) { - proxy = &priv->system_proxy; - service = NM_DBUS_SERVICE_SYSTEM_SETTINGS; - } else { - nm_warning ("Unknown NMConnectionScope %d", scope); - return; - } - - if (!*proxy) { - DBusGConnection * g_connection; - + if (!priv->user_proxy) { g_connection = nm_dbus_manager_get_connection (priv->dbus_mgr); - *proxy = dbus_g_proxy_new_for_name (g_connection, - service, - NM_DBUS_PATH_SETTINGS, - NM_DBUS_IFACE_SETTINGS); - if (!*proxy) { + priv->user_proxy = dbus_g_proxy_new_for_name (g_connection, + NM_DBUS_SERVICE_USER_SETTINGS, + NM_DBUS_PATH_SETTINGS, + NM_DBUS_IFACE_SETTINGS); + if (!priv->user_proxy) { nm_warning ("Error: could not init settings proxy"); return; } - dbus_g_proxy_add_signal (*proxy, + dbus_g_proxy_add_signal (priv->user_proxy, "NewConnection", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID); - dbus_g_proxy_connect_signal (*proxy, "NewConnection", - G_CALLBACK (new_connection_cb), + dbus_g_proxy_connect_signal (priv->user_proxy, "NewConnection", + G_CALLBACK (user_new_connection_cb), manager, NULL); } /* grab connections */ - call = dbus_g_proxy_begin_call (*proxy, "ListConnections", - list_connections_cb, + call = dbus_g_proxy_begin_call (priv->user_proxy, "ListConnections", + user_list_connections_cb, manager, NULL, G_TYPE_INVALID); } -static NMDevice * -nm_manager_get_device_by_udi (NMManager *manager, const char *udi) +/*******************************************************************/ +/* System settings stuff via NMSysconfigSettings */ +/*******************************************************************/ + +static void +system_connection_updated_cb (NMExportedConnection *exported, + gpointer unused, + NMManager *manager) { - GSList *iter; + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); + const char *path; + NMConnection *existing; + NMConnection *connection; + GError *error = NULL; - for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) { - if (!strcmp (nm_device_get_udi (NM_DEVICE (iter->data)), udi)) - return NM_DEVICE (iter->data); - } - return NULL; -} + connection = nm_exported_connection_get_connection (exported); + path = nm_connection_get_path (connection); -static gboolean -nm_manager_udi_is_managed (NMManager *self, const char *udi) -{ - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - GSList *iter; + existing = g_hash_table_lookup (priv->system_connections, path); + if (!existing) + return; + if (existing != connection) { + g_warning ("%s: existing connection didn't matched updated.", __func__); + return; + } - for (iter = priv->unmanaged_udis; iter; iter = iter->next) { - if (!strcmp (udi, iter->data)) - return FALSE; + if (!nm_connection_verify (existing, &error)) { + /* Updated connection invalid, remove existing connection */ + nm_warning ("%s: Invalid connection: '%s' / '%s' invalid: %d", + __func__, + g_type_name (nm_connection_lookup_setting_type_by_quark (error->domain)), + error->message, error->code); + g_error_free (error); + remove_connection (manager, existing, priv->system_connections); + return; } - return TRUE; + g_signal_emit (manager, signals[CONNECTION_UPDATED], 0, + existing, NM_CONNECTION_SCOPE_SYSTEM); + + bluez_manager_resync_devices (manager); } static void -handle_unmanaged_devices (NMManager *manager, GPtrArray *ops) +system_connection_removed_cb (NMExportedConnection *exported, + NMManager *manager) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); - int i; - GSList *unmanaged = NULL, *iter; - - g_slist_foreach (priv->unmanaged_udis, (GFunc) g_free, NULL); - g_slist_free (priv->unmanaged_udis); - priv->unmanaged_udis = NULL; - - /* Mark unmanaged devices */ - for (i = 0; ops && (i < ops->len); i++) { - NMDevice *device; - const char *udi = g_ptr_array_index (ops, i); - - priv->unmanaged_udis = g_slist_prepend (priv->unmanaged_udis, g_strdup (udi)); - - device = nm_manager_get_device_by_udi (manager, udi); - if (device) { - unmanaged = g_slist_prepend (unmanaged, device); - nm_device_set_managed (device, FALSE, NM_DEVICE_STATE_REASON_NOW_UNMANAGED); - } - } - - /* Mark managed devices */ - for (iter = priv->devices; iter; iter = g_slist_next (iter)) { - NMDevice *device = NM_DEVICE (iter->data); + const char *path; + NMConnection *connection; - if (!g_slist_find (unmanaged, device)) - nm_device_set_managed (device, TRUE, NM_DEVICE_STATE_REASON_NOW_MANAGED); - } + connection = nm_exported_connection_get_connection (exported); + path = nm_connection_get_path (connection); - g_slist_free (unmanaged); + connection = g_hash_table_lookup (priv->system_connections, path); + if (connection) + remove_connection (manager, connection, priv->system_connections); } static void -handle_hostname (NMManager *manager, const char *hostname) +system_internal_new_connection (NMManager *manager, + NMExportedConnection *exported) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); + NMConnection *connection; + const char *path; - if (!hostname && !priv->hostname) - return; + g_return_if_fail (exported != NULL); - if (hostname && priv->hostname && !strcmp (hostname, priv->hostname)) - return; + g_signal_connect (exported, "updated", + G_CALLBACK (system_connection_updated_cb), manager); + g_signal_connect (exported, "removed", + G_CALLBACK (system_connection_removed_cb), manager); - g_free (priv->hostname); - priv->hostname = (hostname && strlen (hostname)) ? g_strdup (hostname) : NULL; - g_object_notify (G_OBJECT (manager), NM_MANAGER_HOSTNAME); + connection = nm_exported_connection_get_connection (exported); + path = nm_connection_get_path (NM_CONNECTION (connection)); + g_hash_table_insert (priv->system_connections, g_strdup (path), + g_object_ref (connection)); } static void -system_settings_properties_changed_cb (DBusGProxy *proxy, - GHashTable *properties, - gpointer user_data) +system_new_connection_cb (NMSysconfigSettings *settings, + NMExportedConnection *exported, + NMManager *manager) { - NMManager *manager = NM_MANAGER (user_data); - GValue *value; + system_internal_new_connection (manager, exported); +} - value = g_hash_table_lookup (properties, "UnmanagedDevices"); - if (value && G_VALUE_HOLDS (value, DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH)) - handle_unmanaged_devices (manager, g_value_get_boxed (value)); +static void +system_query_connections (NMManager *manager) +{ + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); + GSList *system_connections, *iter; - value = g_hash_table_lookup (properties, "Hostname"); - if (value && G_VALUE_HOLDS (value, G_TYPE_STRING)) - handle_hostname (manager, g_value_get_string (value)); + system_connections = nm_sysconfig_settings_list_connections (priv->sys_settings); + for (iter = system_connections; iter; iter = g_slist_next (iter)) + system_internal_new_connection (manager, NM_EXPORTED_CONNECTION (iter->data)); + g_slist_free (system_connections); } static void -system_settings_get_unmanaged_devices_cb (DBusGProxy *proxy, - DBusGProxyCall *call_id, - gpointer user_data) +system_unmanaged_devices_changed_cb (NMSysconfigSettings *sys_settings, + GParamSpec *pspec, + gpointer user_data) { NMManager *manager = NM_MANAGER (user_data); - GError *error = NULL; - GValue value = { 0, }; - - if (!dbus_g_proxy_end_call (proxy, call_id, &error, - G_TYPE_VALUE, &value, - G_TYPE_INVALID)) { - nm_warning ("%s: Error getting unmanaged devices from the system " - "settings service: (%d) %s", - __func__, error->code, error->message); - g_error_free (error); - g_object_unref (proxy); - return; - } + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); + const GSList *unmanaged_specs, *iter; - if (G_VALUE_HOLDS (&value, DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH)) - handle_unmanaged_devices (manager, g_value_get_boxed (&value)); + unmanaged_specs = nm_sysconfig_settings_get_unmanaged_specs (sys_settings); + for (iter = priv->devices; iter; iter = g_slist_next (iter)) { + NMDevice *device = NM_DEVICE (iter->data); + gboolean managed; - g_value_unset (&value); - g_object_unref (proxy); + managed = !nm_device_interface_spec_match_list (NM_DEVICE_INTERFACE (device), unmanaged_specs); + nm_device_set_managed (device, + managed, + managed ? NM_DEVICE_STATE_REASON_NOW_MANAGED : + NM_DEVICE_STATE_REASON_NOW_UNMANAGED); + } } static void -system_settings_get_hostname_cb (DBusGProxy *proxy, - DBusGProxyCall *call_id, - gpointer user_data) +system_hostname_changed_cb (NMSysconfigSettings *sys_settings, + GParamSpec *pspec, + gpointer user_data) { NMManager *manager = NM_MANAGER (user_data); - GError *error = NULL; - GValue value = { 0, }; + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); + char *hostname; - if (!dbus_g_proxy_end_call (proxy, call_id, &error, - G_TYPE_VALUE, &value, - G_TYPE_INVALID)) { - nm_warning ("%s: Error getting hostname from the system settings service: (%d) %s", - __func__, error->code, error->message); - g_error_free (error); - g_object_unref (proxy); + hostname = nm_sysconfig_settings_get_hostname (sys_settings); + + if (!hostname && !priv->hostname) + return; + + if (hostname && priv->hostname && !strcmp (hostname, priv->hostname)) return; - } - if (G_VALUE_HOLDS (&value, G_TYPE_STRING)) - handle_hostname (manager, g_value_get_string (&value)); + g_free (priv->hostname); + priv->hostname = (hostname && strlen (hostname)) ? g_strdup (hostname) : NULL; + g_object_notify (G_OBJECT (manager), NM_MANAGER_HOSTNAME); - g_value_unset (&value); - g_object_unref (proxy); + g_free (hostname); } -static void -query_system_settings_property (NMManager *manager, - const char *property, - DBusGProxyCallNotify callback) +/*******************************************************************/ +/* General NMManager stuff */ +/*******************************************************************/ + +static NMDevice * +nm_manager_get_device_by_udi (NMManager *manager, const char *udi) { - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); - DBusGConnection *g_connection; - DBusGProxy *get_proxy; + GSList *iter; - g_connection = nm_dbus_manager_get_connection (priv->dbus_mgr); + for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) { + if (!strcmp (nm_device_get_udi (NM_DEVICE (iter->data)), udi)) + return NM_DEVICE (iter->data); + } + return NULL; +} - /* Get unmanaged devices */ - get_proxy = dbus_g_proxy_new_for_name (g_connection, - NM_DBUS_SERVICE_SYSTEM_SETTINGS, - NM_DBUS_PATH_SETTINGS, - "org.freedesktop.DBus.Properties"); +static NMDevice * +nm_manager_get_device_by_path (NMManager *manager, const char *path) +{ + GSList *iter; - dbus_g_proxy_begin_call (get_proxy, "Get", callback, manager, NULL, - G_TYPE_STRING, NM_DBUS_IFACE_SETTINGS_SYSTEM, - G_TYPE_STRING, property, - G_TYPE_INVALID); + for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) { + if (!strcmp (nm_device_get_path (NM_DEVICE (iter->data)), path)) + return NM_DEVICE (iter->data); + } + return NULL; } static void @@ -1432,335 +1024,79 @@ nm_manager_name_owner_changed (NMDBusManager *mgr, gpointer user_data) { NMManager *manager = NM_MANAGER (user_data); - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); gboolean old_owner_good = (old && (strlen (old) > 0)); gboolean new_owner_good = (new && (strlen (new) > 0)); if (strcmp (name, NM_DBUS_SERVICE_USER_SETTINGS) == 0) { if (!old_owner_good && new_owner_good) { /* User Settings service appeared, update stuff */ - query_connections (manager, NM_CONNECTION_SCOPE_USER); + user_query_connections (manager); } else { /* User Settings service disappeared, throw them away (?) */ - nm_manager_connections_destroy (manager, NM_CONNECTION_SCOPE_USER); - bluez_manager_resync_devices (manager); - } - } else if (strcmp (name, NM_DBUS_SERVICE_SYSTEM_SETTINGS) == 0) { - if (!old_owner_good && new_owner_good) { - if (priv->poke_id) { - g_source_remove (priv->poke_id); - priv->poke_id = 0; - } - - /* System Settings service appeared, update stuff */ - query_system_settings_property (manager, "UnmanagedDevices", system_settings_get_unmanaged_devices_cb); - query_system_settings_property (manager, "Hostname", system_settings_get_hostname_cb); - query_connections (manager, NM_CONNECTION_SCOPE_SYSTEM); - } else { - /* System Settings service disappeared, throw them away (?) */ - nm_manager_connections_destroy (manager, NM_CONNECTION_SCOPE_SYSTEM); + user_destroy_connections (manager); bluez_manager_resync_devices (manager); - - if (priv->system_props_proxy) { - g_object_unref (priv->system_props_proxy); - priv->system_props_proxy = NULL; - } - - if (priv->poke_id) - g_source_remove (priv->poke_id); - - /* Poke the system settings daemon so that it gets activated by dbus - * system bus activation. - */ - priv->poke_id = g_idle_add (poke_system_settings_daemon_cb, (gpointer) manager); } } } -static gboolean -poke_system_settings_daemon_cb (gpointer user_data) +static void +manager_set_wireless_enabled (NMManager *manager, gboolean enabled) { - NMManager *manager = NM_MANAGER (user_data); NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); - DBusGConnection *g_connection; - DBusGProxy *proxy; + GSList *iter; - g_connection = nm_dbus_manager_get_connection (priv->dbus_mgr); - proxy = dbus_g_proxy_new_for_name (g_connection, - NM_DBUS_SERVICE_SYSTEM_SETTINGS, - NM_DBUS_PATH_SETTINGS, - NM_DBUS_IFACE_SETTINGS); - if (!proxy) { - nm_warning ("Error: could not init system settings daemon proxy"); - goto out; - } + if (priv->wireless_enabled == enabled) + return; - nm_info ("Trying to start the system settings daemon..."); - dbus_g_proxy_call_no_reply (proxy, "ListConnections", G_TYPE_INVALID); - g_object_unref (proxy); + /* Can't set wireless enabled if it's disabled in hardware */ + if (!priv->wireless_hw_enabled && enabled) + return; -out: - /* Reschedule the poke */ - priv->poke_id = g_timeout_add_seconds (SSD_POKE_INTERVAL, poke_system_settings_daemon_cb, (gpointer) manager); + priv->wireless_enabled = enabled; - return FALSE; -} + g_object_notify (G_OBJECT (manager), NM_MANAGER_WIRELESS_ENABLED); -static gboolean -initial_get_connections (gpointer user_data) -{ - NMManager *manager = NM_MANAGER (user_data); - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); + /* Don't touch devices if asleep/networking disabled */ + if (priv->sleeping) + return; - if (nm_dbus_manager_name_has_owner (priv->dbus_mgr, - NM_DBUS_SERVICE_SYSTEM_SETTINGS)) { - query_system_settings_property (manager, "UnmanagedDevices", system_settings_get_unmanaged_devices_cb); - query_system_settings_property (manager, "Hostname", system_settings_get_hostname_cb); - query_connections (manager, NM_CONNECTION_SCOPE_SYSTEM); - } else { - /* Try to activate the system settings daemon */ - priv->poke_id = g_idle_add (poke_system_settings_daemon_cb, (gpointer) manager); + /* enable/disable wireless devices as required */ + for (iter = priv->devices; iter; iter = iter->next) { + if (NM_IS_DEVICE_WIFI (iter->data)) + nm_device_wifi_set_enabled (NM_DEVICE_WIFI (iter->data), enabled); } - - if (nm_dbus_manager_name_has_owner (priv->dbus_mgr, - NM_DBUS_SERVICE_USER_SETTINGS)) - query_connections (manager, NM_CONNECTION_SCOPE_USER); - - return FALSE; } static void -sync_devices (NMManager *self) +manager_hidden_ap_found (NMDeviceInterface *device, + NMAccessPoint *ap, + gpointer user_data) { - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - GSList *keep = NULL, *gone = NULL, *iter; + NMManager *manager = NM_MANAGER (user_data); + const struct ether_addr *ap_addr; + const GByteArray *ap_ssid; + GSList *iter; + GSList *connections; + gboolean done = FALSE; - /* Keep devices still known to HAL; get rid of ones HAL no longer knows about */ - for (iter = priv->devices; iter; iter = iter->next) { - NMDevice *device = NM_DEVICE (iter->data); - const char *udi = nm_device_get_udi (device); + ap_ssid = nm_ap_get_ssid (ap); + if (ap_ssid && ap_ssid->len) + return; - if (nm_hal_manager_udi_exists (priv->hal_mgr, udi)) { - if (nm_manager_udi_is_managed (self, udi)) - nm_device_set_managed (device, TRUE, NM_DEVICE_STATE_REASON_NOW_MANAGED); - else - nm_device_set_managed (device, FALSE, NM_DEVICE_STATE_REASON_NOW_UNMANAGED); - keep = g_slist_append (keep, device); - } else - gone = g_slist_append (gone, device); - } - g_slist_free (priv->devices); - priv->devices = keep; + ap_addr = nm_ap_get_address (ap); + g_assert (ap_addr); - /* Dispose of devices no longer present */ - while (g_slist_length (gone)) - gone = remove_one_device (self, gone, NM_DEVICE (gone->data)); + /* Look for this AP's BSSID in the seen-bssids list of a connection, + * and if a match is found, copy over the SSID */ + connections = nm_manager_get_connections (manager, NM_CONNECTION_SCOPE_SYSTEM); + connections = g_slist_concat (connections, nm_manager_get_connections (manager, NM_CONNECTION_SCOPE_USER)); - /* Ask HAL for new devices */ - nm_hal_manager_query_devices (priv->hal_mgr); - - /* Ask for new bluetooth devices */ - bluez_manager_resync_devices (self); -} - -static gboolean -deferred_sync_devices (gpointer user_data) -{ - NMManager *self = NM_MANAGER (user_data); - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - - priv->sync_devices_id = 0; - sync_devices (self); - - return FALSE; -} - -NMManager * -nm_manager_get (void) -{ - static NMManager *singleton = NULL; - NMManagerPrivate *priv; - gboolean enabled; - - if (singleton) - return g_object_ref (singleton); - - singleton = (NMManager *) g_object_new (NM_TYPE_MANAGER, NULL); - g_assert (singleton); - - priv = NM_MANAGER_GET_PRIVATE (singleton); - - dbus_g_connection_register_g_object (nm_dbus_manager_get_connection (priv->dbus_mgr), - NM_DBUS_PATH, - G_OBJECT (singleton)); - - g_signal_connect (priv->dbus_mgr, - "name-owner-changed", - G_CALLBACK (nm_manager_name_owner_changed), - singleton); - - g_idle_add ((GSourceFunc) initial_get_connections, singleton); - - priv->hal_mgr = nm_hal_manager_new (); - priv->sync_devices_id = g_idle_add (deferred_sync_devices, singleton); - - g_signal_connect (priv->hal_mgr, - "udi-added", - G_CALLBACK (hal_manager_udi_added_cb), - singleton); - - g_signal_connect (priv->hal_mgr, - "udi-removed", - G_CALLBACK (hal_manager_udi_removed_cb), - singleton); - - g_signal_connect (priv->hal_mgr, - "hal-reappeared", - G_CALLBACK (hal_manager_hal_reappeared_cb), - singleton); - - priv->udev_mgr = nm_udev_manager_new (); - g_signal_connect (priv->udev_mgr, - "rfkill-changed", - G_CALLBACK (udev_manager_rfkill_changed_cb), - singleton); - - switch (nm_udev_manager_get_rfkill_state (priv->udev_mgr)) { - case RFKILL_UNBLOCKED: - priv->wireless_enabled = TRUE; - priv->wireless_hw_enabled = TRUE; - break; - case RFKILL_SOFT_BLOCKED: - priv->wireless_enabled = FALSE; - priv->wireless_hw_enabled = TRUE; - break; - case RFKILL_HARD_BLOCKED: - priv->wireless_enabled = FALSE; - priv->wireless_hw_enabled = FALSE; - break; - default: - break; - } - - enabled = (priv->wireless_enabled && priv->wireless_hw_enabled); - nm_info ("Wireless now %s by radio killswitch", enabled ? "enabled" : "disabled"); - manager_set_wireless_enabled (singleton, enabled); - - priv->bluez_mgr = nm_bluez_manager_get (); - - g_signal_connect (priv->bluez_mgr, - "bdaddr-added", - G_CALLBACK (bluez_manager_bdaddr_added_cb), - singleton); - - g_signal_connect (priv->bluez_mgr, - "bdaddr-removed", - G_CALLBACK (bluez_manager_bdaddr_removed_cb), - singleton); - - return singleton; -} - -static void -emit_removed (gpointer key, gpointer value, gpointer user_data) -{ - NMManager *manager = NM_MANAGER (user_data); - NMConnection *connection = NM_CONNECTION (value); - - g_signal_emit (manager, signals[CONNECTION_REMOVED], 0, - connection, - nm_connection_get_scope (connection)); -} - -static void -nm_manager_connections_destroy (NMManager *manager, - NMConnectionScope scope) -{ - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); - - if (scope == NM_CONNECTION_SCOPE_USER) { - if (priv->user_connections) { - g_hash_table_foreach (priv->user_connections, emit_removed, manager); - g_hash_table_remove_all (priv->user_connections); - } - - if (priv->user_proxy) { - g_object_unref (priv->user_proxy); - priv->user_proxy = NULL; - } - } else if (scope == NM_CONNECTION_SCOPE_SYSTEM) { - if (priv->system_connections) { - g_hash_table_foreach (priv->system_connections, emit_removed, manager); - g_hash_table_remove_all (priv->system_connections); - } - - if (priv->system_proxy) { - g_object_unref (priv->system_proxy); - priv->system_proxy = NULL; - } - } else { - nm_warning ("Unknown NMConnectionScope %d", scope); - } -} - -static void -manager_set_wireless_enabled (NMManager *manager, gboolean enabled) -{ - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); - GSList *iter; - - if (priv->wireless_enabled == enabled) - return; - - /* Can't set wireless enabled if it's disabled in hardware */ - if (!priv->wireless_hw_enabled && enabled) - return; - - priv->wireless_enabled = enabled; - - g_object_notify (G_OBJECT (manager), NM_MANAGER_WIRELESS_ENABLED); - - /* Don't touch devices if asleep/networking disabled */ - if (priv->sleeping) - return; - - /* enable/disable wireless devices as required */ - for (iter = priv->devices; iter; iter = iter->next) { - if (NM_IS_DEVICE_WIFI (iter->data)) - nm_device_wifi_set_enabled (NM_DEVICE_WIFI (iter->data), enabled); - } -} - -static void -manager_hidden_ap_found (NMDeviceInterface *device, - NMAccessPoint *ap, - gpointer user_data) -{ - NMManager *manager = NM_MANAGER (user_data); - const struct ether_addr *ap_addr; - const GByteArray *ap_ssid; - GSList *iter; - GSList *connections; - gboolean done = FALSE; - - ap_ssid = nm_ap_get_ssid (ap); - if (ap_ssid && ap_ssid->len) - return; - - ap_addr = nm_ap_get_address (ap); - g_assert (ap_addr); - - /* Look for this AP's BSSID in the seen-bssids list of a connection, - * and if a match is found, copy over the SSID */ - connections = nm_manager_get_connections (manager, NM_CONNECTION_SCOPE_SYSTEM); - connections = g_slist_concat (connections, nm_manager_get_connections (manager, NM_CONNECTION_SCOPE_USER)); - - for (iter = connections; iter && !done; iter = g_slist_next (iter)) { - NMConnection *connection = NM_CONNECTION (iter->data); - NMSettingWireless *s_wireless; - const GByteArray *ssid; - guint32 num_bssids; - guint32 i; + for (iter = connections; iter && !done; iter = g_slist_next (iter)) { + NMConnection *connection = NM_CONNECTION (iter->data); + NMSettingWireless *s_wireless; + const GByteArray *ssid; + guint32 num_bssids; + guint32 i; s_wireless = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS); if (!s_wireless) @@ -1799,6 +1135,9 @@ add_device (NMManager *self, NMDevice *device) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); const char *iface, *driver; + char *path; + static guint32 devcount = 0; + const GSList *unmanaged_specs; priv->devices = g_slist_append (priv->devices, device); @@ -1836,10 +1175,18 @@ add_device (NMManager *self, NMDevice *device) else g_assert_not_reached (); + path = g_strdup_printf ("/org/freedesktop/NetworkManager/Devices/%d", devcount++); + nm_device_set_path (device, path); dbus_g_connection_register_g_object (nm_dbus_manager_get_connection (priv->dbus_mgr), - nm_device_get_udi (NM_DEVICE (device)), - G_OBJECT (device)); - nm_info ("(%s): exported as %s", iface, nm_device_get_udi (device)); + path, + G_OBJECT (device)); + nm_info ("(%s): exported as %s", iface, path); + g_free (path); + + /* Start the device if it's supposed to be managed */ + unmanaged_specs = nm_sysconfig_settings_get_unmanaged_specs (priv->sys_settings); + if (!priv->sleeping && !nm_device_interface_spec_match_list (NM_DEVICE_INTERFACE (device), unmanaged_specs)) + nm_device_set_managed (device, TRUE, NM_DEVICE_STATE_REASON_NOW_MANAGED); g_signal_emit (self, signals[DEVICE_ADDED], 0, device); } @@ -1953,11 +1300,11 @@ bluez_manager_resync_devices (NMManager *self) static void bluez_manager_bdaddr_added_cb (NMBluezManager *bluez_mgr, - const char *bdaddr, - const char *name, - const char *object_path, - guint32 capabilities, - NMManager *manager) + const char *bdaddr, + const char *name, + const char *object_path, + guint32 capabilities, + NMManager *manager) { NMDeviceBt *device; gboolean has_dun = (capabilities & NM_BT_CAPABILITY_DUN); @@ -2017,55 +1364,67 @@ bluez_manager_bdaddr_removed_cb (NMBluezManager *bluez_mgr, } } +static NMDevice * +find_device_by_ifindex (NMManager *self, guint32 ifindex) +{ + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + GSList *iter; + + for (iter = priv->devices; iter; iter = g_slist_next (iter)) { + NMDevice *device = NM_DEVICE (iter->data); + gint candidate_idx = 0; + + if (NM_IS_DEVICE_ETHERNET (device)) + candidate_idx = nm_device_ethernet_get_ifindex (NM_DEVICE_ETHERNET (device)); + else if (NM_IS_DEVICE_WIFI (device)) + candidate_idx = nm_device_wifi_get_ifindex (NM_DEVICE_WIFI (device)); + + if (candidate_idx == ifindex) + return device; + } + + return NULL; +} + static void -hal_manager_udi_added_cb (NMHalManager *hal_mgr, - const char *udi, - const char *originating_device, - gpointer general_type_ptr, - NMDeviceCreatorFn creator_fn, - gpointer user_data) +udev_device_added_cb (NMUdevManager *udev_mgr, + GUdevDevice *udev_device, + NMDeviceCreatorFn creator_fn, + gpointer user_data) { NMManager *self = NM_MANAGER (user_data); NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); GObject *device; + guint32 ifindex; - if (priv->sleeping) - return; - - /* Make sure the device is not already in the device list */ - if (nm_manager_get_device_by_udi (self, udi)) - return; - - device = creator_fn (hal_mgr, udi, originating_device, nm_manager_udi_is_managed (self, udi)); - if (!device) + ifindex = g_udev_device_get_property_as_int (udev_device, "IFINDEX"); + if (find_device_by_ifindex (self, ifindex)) return; - add_device (self, NM_DEVICE (device)); + device = creator_fn (udev_mgr, udev_device, priv->sleeping); + if (device) + add_device (self, NM_DEVICE (device)); } static void -hal_manager_udi_removed_cb (NMHalManager *manager, - const char *udi, - gpointer user_data) +udev_device_removed_cb (NMUdevManager *manager, + GUdevDevice *udev_device, + gpointer user_data) { NMManager *self = NM_MANAGER (user_data); NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - GSList *iter; + NMDevice *device; + guint32 ifindex; - g_return_if_fail (udi != NULL); - - for (iter = priv->devices; iter; iter = iter->next) { - NMDevice *device = NM_DEVICE (iter->data); + ifindex = g_udev_device_get_property_as_int (udev_device, "IFINDEX"); + device = find_device_by_ifindex (self, ifindex); + if (device) + priv->devices = remove_one_device (self, priv->devices, device); - if (!strcmp (nm_device_get_udi (device), udi)) { - priv->devices = remove_one_device (self, priv->devices, device); - break; - } - } } static void -udev_manager_rfkill_changed_cb (NMHalManager *hal_mgr, +udev_manager_rfkill_changed_cb (NMUdevManager *udev_mgr, RfKillState state, gpointer user_data) { @@ -2099,13 +1458,6 @@ udev_manager_rfkill_changed_cb (NMHalManager *hal_mgr, manager_set_wireless_enabled (self, new_we); } -static void -hal_manager_hal_reappeared_cb (NMHalManager *hal_mgr, - gpointer user_data) -{ - sync_devices (NM_MANAGER (user_data)); -} - GSList * nm_manager_get_devices (NMManager *manager) { @@ -2123,7 +1475,7 @@ impl_manager_get_devices (NMManager *manager, GPtrArray **devices, GError **err) *devices = g_ptr_array_sized_new (g_slist_length (priv->devices)); for (iter = priv->devices; iter; iter = iter->next) - g_ptr_array_add (*devices, g_strdup (nm_device_get_udi (NM_DEVICE (iter->data)))); + g_ptr_array_add (*devices, g_strdup (nm_device_get_path (NM_DEVICE (iter->data)))); return TRUE; } @@ -2159,56 +1511,328 @@ nm_manager_get_act_request_by_path (NMManager *manager, return NULL; } -static const char * -internal_activate_device (NMManager *manager, - NMDevice *device, - NMConnection *connection, - const char *specific_object, - gboolean user_requested, - GError **error) -{ - NMActRequest *req; - NMDeviceInterface *dev_iface; - gboolean success; +typedef struct GetSecretsInfo { + NMManager *manager; + NMSecretsProviderInterface *provider; - g_return_val_if_fail (NM_IS_MANAGER (manager), NULL); - g_return_val_if_fail (NM_IS_DEVICE (device), NULL); - g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + char *setting_name; + RequestSecretsCaller caller; + gboolean request_new; - dev_iface = NM_DEVICE_INTERFACE (device); + /* User connection bits */ + DBusGProxy *proxy; + DBusGProxyCall *call; - /* Ensure the requested connection is compatible with the device */ - if (!nm_device_interface_check_connection_compatible (dev_iface, connection, error)) - return NULL; + /* System connection bits */ + guint32 idle_id; + char *hint1; + char *hint2; + char *connection_path; +} GetSecretsInfo; - /* Tear down any existing connection */ - if (nm_device_get_act_request (device)) { - nm_device_state_changed (device, - NM_DEVICE_STATE_DISCONNECTED, - NM_DEVICE_STATE_REASON_NONE); +static void +free_get_secrets_info (gpointer data) +{ + GetSecretsInfo *info = data; + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (info->manager); + + g_object_weak_unref (G_OBJECT (info->provider), (GWeakNotify) free_get_secrets_info, info); + + priv->secrets_calls = g_slist_remove (priv->secrets_calls, info); + + if (info->proxy) { + if (info->call) + dbus_g_proxy_cancel_call (info->proxy, info->call); + g_object_unref (info->proxy); } - req = nm_act_request_new (connection, specific_object, user_requested, (gpointer) device); - success = nm_device_interface_activate (dev_iface, req, error); - g_object_unref (req); + if (info->idle_id) + g_source_remove (info->idle_id); - return success ? nm_act_request_get_active_connection_path (req) : NULL; + g_free (info->hint1); + g_free (info->hint2); + g_free (info->setting_name); + g_free (info->connection_path); + memset (info, 0, sizeof (GetSecretsInfo)); + g_free (info); } -static gboolean -wait_for_connection_expired (gpointer data) +static void +provider_cancel_secrets (NMSecretsProviderInterface *provider, gpointer user_data) { - NMManager *manager = NM_MANAGER (data); - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); - PendingConnectionInfo *info = priv->pending_connection_info; - GError *error = NULL; + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (user_data); + GSList *iter; - g_return_val_if_fail (info != NULL, FALSE); + for (iter = priv->secrets_calls; iter; iter = g_slist_next (iter)) { + GetSecretsInfo *candidate = iter->data; - g_set_error (&error, - NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_CONNECTION, - "%s", "Connection was not provided by any settings service"); - nm_warning ("Connection (%d) %s failed to activate (timeout): (%d) %s", + if (candidate->provider == provider) { + free_get_secrets_info (candidate); + break; + } + } +} + +static void +user_get_secrets_cb (DBusGProxy *proxy, + DBusGProxyCall *call, + gpointer user_data) +{ + GetSecretsInfo *info = (GetSecretsInfo *) user_data; + NMManagerPrivate *priv; + GHashTable *settings = NULL; + GError *error = NULL; + + g_return_if_fail (info != NULL); + g_return_if_fail (info->provider); + g_return_if_fail (info->setting_name); + + priv = NM_MANAGER_GET_PRIVATE (info->manager); + + if (dbus_g_proxy_end_call (proxy, call, &error, + DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, &settings, + G_TYPE_INVALID)) { + nm_secrets_provider_interface_get_secrets_result (info->provider, + info->setting_name, + info->caller, + settings, + NULL); + g_hash_table_destroy (settings); + } else { + nm_secrets_provider_interface_get_secrets_result (info->provider, + info->setting_name, + info->caller, + NULL, + error); + g_clear_error (&error); + } + + info->call = NULL; + free_get_secrets_info (info); +} + +static GetSecretsInfo * +user_get_secrets (NMManager *self, + NMSecretsProviderInterface *provider, + NMConnection *connection, + const char *setting_name, + gboolean request_new, + RequestSecretsCaller caller_id, + const char *hint1, + const char *hint2) +{ + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + DBusGConnection *g_connection; + GetSecretsInfo *info = NULL; + GPtrArray *hints = NULL; + + info = g_malloc0 (sizeof (GetSecretsInfo)); + + g_connection = nm_dbus_manager_get_connection (priv->dbus_mgr); + info->proxy = dbus_g_proxy_new_for_name (g_connection, + NM_DBUS_SERVICE_USER_SETTINGS, + nm_connection_get_path (connection), + NM_DBUS_IFACE_SETTINGS_CONNECTION_SECRETS); + if (!info->proxy) { + nm_warning ("%s: could not create user connection secrets proxy", __func__); + g_free (info); + return NULL; + } + + info->manager = self; + info->provider = provider; + info->caller = caller_id; + info->setting_name = g_strdup (setting_name); + + g_object_weak_ref (G_OBJECT (provider), (GWeakNotify) free_get_secrets_info, info); + + hints = g_ptr_array_sized_new (2); + if (hint1) + g_ptr_array_add (hints, (char *) hint1); + if (hint2) + g_ptr_array_add (hints, (char *) hint2); + + info->call = dbus_g_proxy_begin_call_with_timeout (info->proxy, "GetSecrets", + user_get_secrets_cb, + info, + NULL, + G_MAXINT32, + G_TYPE_STRING, setting_name, + DBUS_TYPE_G_ARRAY_OF_STRING, hints, + G_TYPE_BOOLEAN, request_new, + G_TYPE_INVALID); + g_ptr_array_free (hints, TRUE); + return info; +} + +static gboolean +system_get_secrets_cb (gpointer user_data) +{ + GetSecretsInfo *info = user_data; + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (info->manager); + GHashTable *settings; + NMSysconfigConnection *exported; + GError *error = NULL; + const char *hints[3] = { NULL, NULL, NULL }; + + exported = nm_sysconfig_settings_get_connection_by_path (priv->sys_settings, + info->connection_path); + if (!exported) { + g_set_error (&error, 0, 0, "%s", "unknown connection (not exported by " + "system settings)"); + nm_secrets_provider_interface_get_secrets_result (info->provider, + info->setting_name, + info->caller, + NULL, + error); + g_clear_error (&error); + return FALSE; + } + + hints[0] = info->hint1; + hints[1] = info->hint2; + settings = nm_sysconfig_connection_get_secrets (exported, + info->setting_name, + hints, + info->request_new, + &error); + nm_secrets_provider_interface_get_secrets_result (info->provider, + info->setting_name, + info->caller, + settings, + NULL); + g_hash_table_destroy (settings); + return FALSE; +} + +static GetSecretsInfo * +system_get_secrets (NMManager *self, + NMSecretsProviderInterface *provider, + NMConnection *connection, + const char *setting_name, + gboolean request_new, + RequestSecretsCaller caller_id, + const char *hint1, + const char *hint2) +{ + GetSecretsInfo *info; + + info = g_malloc0 (sizeof (GetSecretsInfo)); + info->manager = self; + info->provider = provider; + info->caller = caller_id; + info->setting_name = g_strdup (setting_name); + info->hint1 = hint1 ? g_strdup (hint1) : NULL; + info->hint2 = hint2 ? g_strdup (hint2) : NULL; + info->connection_path = g_strdup (nm_connection_get_path (connection)); + info->request_new = request_new; + + g_object_weak_ref (G_OBJECT (provider), (GWeakNotify) free_get_secrets_info, info); + + info->idle_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, + system_get_secrets_cb, + info, + free_get_secrets_info); + return info; +} + +static gboolean +provider_get_secrets (NMSecretsProviderInterface *provider, + NMConnection *connection, + const char *setting_name, + gboolean request_new, + RequestSecretsCaller caller_id, + const char *hint1, + const char *hint2, + gpointer user_data) +{ + NMManager *self = NM_MANAGER (user_data); + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + GetSecretsInfo *info = NULL; + NMConnectionScope scope; + GSList *iter; + + g_return_val_if_fail (connection != NULL, FALSE); + g_return_val_if_fail (setting_name != NULL, FALSE); + + /* Tear down any pending secrets requests for this secrets provider */ + for (iter = priv->secrets_calls; iter; iter = g_slist_next (iter)) { + GetSecretsInfo *candidate = iter->data; + + if (provider == candidate->provider) { + free_get_secrets_info (candidate); + break; + } + } + + /* Build up the new secrets request */ + scope = nm_connection_get_scope (connection); + if (scope == NM_CONNECTION_SCOPE_SYSTEM) { + info = system_get_secrets (self, provider, connection, setting_name, + request_new, caller_id, hint1, hint2); + } else if (scope == NM_CONNECTION_SCOPE_USER) { + info = user_get_secrets (self, provider, connection, setting_name, + request_new, caller_id, hint1, hint2); + } + + if (info) + priv->secrets_calls = g_slist_append (priv->secrets_calls, info); + + return !!info; +} + +static const char * +internal_activate_device (NMManager *manager, + NMDevice *device, + NMConnection *connection, + const char *specific_object, + gboolean user_requested, + GError **error) +{ + NMActRequest *req; + NMDeviceInterface *dev_iface; + gboolean success; + + g_return_val_if_fail (NM_IS_MANAGER (manager), NULL); + g_return_val_if_fail (NM_IS_DEVICE (device), NULL); + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + dev_iface = NM_DEVICE_INTERFACE (device); + + /* Ensure the requested connection is compatible with the device */ + if (!nm_device_interface_check_connection_compatible (dev_iface, connection, error)) + return NULL; + + /* Tear down any existing connection */ + if (nm_device_get_act_request (device)) { + nm_device_state_changed (device, + NM_DEVICE_STATE_DISCONNECTED, + NM_DEVICE_STATE_REASON_NONE); + } + + req = nm_act_request_new (connection, specific_object, user_requested, (gpointer) device); + g_signal_connect (req, "manager-get-secrets", G_CALLBACK (provider_get_secrets), manager); + g_signal_connect (req, "manager-cancel-secrets", G_CALLBACK (provider_cancel_secrets), manager); + success = nm_device_interface_activate (dev_iface, req, error); + g_object_unref (req); + + return success ? nm_act_request_get_active_connection_path (req) : NULL; +} + +static gboolean +wait_for_connection_expired (gpointer data) +{ + NMManager *manager = NM_MANAGER (data); + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); + PendingConnectionInfo *info = priv->pending_connection_info; + GError *error = NULL; + + g_return_val_if_fail (info != NULL, FALSE); + + g_set_error (&error, + NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_CONNECTION, + "%s", "Connection was not provided by any settings service"); + nm_warning ("Connection (%d) %s failed to activate (timeout): (%d) %s", info->scope, info->connection_path, error->code, error->message); dbus_g_method_return_error (info->context, error); g_error_free (error); @@ -2229,8 +1853,9 @@ nm_manager_activate_connection (NMManager *manager, GError **error) { NMDevice *device = NULL; - char *path = NULL; NMSettingConnection *s_con; + NMVPNConnection *vpn_connection; + const char *path; g_return_val_if_fail (manager != NULL, NULL); g_return_val_if_fail (connection != NULL, NULL); @@ -2261,17 +1886,22 @@ nm_manager_activate_connection (NMManager *manager, } vpn_manager = nm_vpn_manager_get (); - path = (char *) nm_vpn_manager_activate_connection (vpn_manager, - connection, - req, - device, - error); + vpn_connection = nm_vpn_manager_activate_connection (vpn_manager, + connection, + req, + device, + error); + g_signal_connect (vpn_connection, "manager-get-secrets", + G_CALLBACK (provider_get_secrets), manager); + g_signal_connect (vpn_connection, "manager-cancel-secrets", + G_CALLBACK (provider_cancel_secrets), manager); + path = nm_vpn_connection_get_active_connection_path (vpn_connection); g_object_unref (vpn_manager); } else { NMDeviceState state; /* Device-based connection */ - device = nm_manager_get_device_by_udi (manager, device_path); + device = nm_manager_get_device_by_path (manager, device_path); if (!device) { g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE, @@ -2287,12 +1917,12 @@ nm_manager_activate_connection (NMManager *manager, return NULL; } - path = (char *) internal_activate_device (manager, - device, - connection, - specific_object, - user_requested, - error); + path = internal_activate_device (manager, + device, + connection, + specific_object, + user_requested, + error); } return path; @@ -2583,13 +2213,14 @@ impl_manager_deactivate_connection (NMManager *manager, } static gboolean -impl_manager_sleep (NMManager *manager, gboolean sleep, GError **error) +impl_manager_sleep (NMManager *self, gboolean sleep, GError **error) { NMManagerPrivate *priv; + GSList *iter; - g_return_val_if_fail (NM_IS_MANAGER (manager), FALSE); + g_return_val_if_fail (NM_IS_MANAGER (self), FALSE); - priv = NM_MANAGER_GET_PRIVATE (manager); + priv = NM_MANAGER_GET_PRIVATE (self); if (priv->sleeping == sleep) { g_set_error (error, @@ -2601,8 +2232,6 @@ impl_manager_sleep (NMManager *manager, gboolean sleep, GError **error) priv->sleeping = sleep; if (sleep) { - GSList *iter; - nm_info ("Sleeping..."); /* Just deactivate and down all devices from the device list, @@ -2611,16 +2240,27 @@ impl_manager_sleep (NMManager *manager, gboolean sleep, GError **error) for (iter = priv->devices; iter; iter = iter->next) nm_device_set_managed (NM_DEVICE (iter->data), FALSE, NM_DEVICE_STATE_REASON_SLEEPING); } else { + const GSList *unmanaged_specs; + nm_info ("Waking up..."); - sync_devices (manager); - if (priv->sync_devices_id) { - g_source_remove (priv->sync_devices_id); - priv->sync_devices_id = 0; + unmanaged_specs = nm_sysconfig_settings_get_unmanaged_specs (priv->sys_settings); + + /* Re-manage managed devices */ + for (iter = priv->devices; iter; iter = iter->next) { + NMDevice *device = NM_DEVICE (iter->data); + + if (nm_device_interface_spec_match_list (NM_DEVICE_INTERFACE (device), unmanaged_specs)) + nm_device_set_managed (device, FALSE, NM_DEVICE_STATE_REASON_NOW_UNMANAGED); + else + nm_device_set_managed (device, TRUE, NM_DEVICE_STATE_REASON_NOW_MANAGED); } + + /* Ask for new bluetooth devices */ + bluez_manager_resync_devices (self); } - nm_manager_update_state (manager); + nm_manager_update_state (self); return TRUE; } @@ -2735,3 +2375,420 @@ nm_manager_get_active_connections_by_connection (NMManager *manager, return get_active_connections (manager, connection); } +void +nm_manager_start (NMManager *self) +{ + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + gboolean enabled; + + switch (nm_udev_manager_get_rfkill_state (priv->udev_mgr)) { + case RFKILL_UNBLOCKED: + priv->wireless_enabled = TRUE; + priv->wireless_hw_enabled = TRUE; + break; + case RFKILL_SOFT_BLOCKED: + priv->wireless_enabled = FALSE; + priv->wireless_hw_enabled = TRUE; + break; + case RFKILL_HARD_BLOCKED: + priv->wireless_enabled = FALSE; + priv->wireless_hw_enabled = FALSE; + break; + default: + break; + } + + enabled = (priv->wireless_enabled && priv->wireless_hw_enabled); + nm_info ("Wireless now %s by radio killswitch", enabled ? "enabled" : "disabled"); + manager_set_wireless_enabled (self, enabled); + + system_unmanaged_devices_changed_cb (priv->sys_settings, NULL, self); + system_hostname_changed_cb (priv->sys_settings, NULL, self); + system_query_connections (self); + + /* Get user connections if the user settings service is around, otherwise + * they will be queried when the user settings service shows up on the + * bus in nm_manager_name_owner_changed(). + */ + if (nm_dbus_manager_name_has_owner (priv->dbus_mgr, NM_DBUS_SERVICE_USER_SETTINGS)) + user_query_connections (self); + + nm_udev_manager_query_devices (priv->udev_mgr); + bluez_manager_resync_devices (self); +} + +NMManager * +nm_manager_get (const char *plugins, GError **error) +{ + static NMManager *singleton = NULL; + NMManagerPrivate *priv; + + if (singleton) + return g_object_ref (singleton); + + singleton = (NMManager *) g_object_new (NM_TYPE_MANAGER, NULL); + g_assert (singleton); + + priv = NM_MANAGER_GET_PRIVATE (singleton); + + priv->sys_settings = nm_sysconfig_settings_new (plugins, error); + if (!priv->sys_settings) { + g_object_unref (singleton); + return NULL; + } + + g_signal_connect (priv->sys_settings, "notify::" NM_SYSCONFIG_SETTINGS_UNMANAGED_SPECS, + G_CALLBACK (system_unmanaged_devices_changed_cb), singleton); + g_signal_connect (priv->sys_settings, "notify::" NM_SYSCONFIG_SETTINGS_HOSTNAME, + G_CALLBACK (system_hostname_changed_cb), singleton); + g_signal_connect (priv->sys_settings, "new-connection", + G_CALLBACK (system_new_connection_cb), singleton); + + dbus_g_connection_register_g_object (nm_dbus_manager_get_connection (priv->dbus_mgr), + NM_DBUS_PATH, + G_OBJECT (singleton)); + + g_signal_connect (priv->dbus_mgr, + "name-owner-changed", + G_CALLBACK (nm_manager_name_owner_changed), + singleton); + + priv->udev_mgr = nm_udev_manager_new (); + g_signal_connect (priv->udev_mgr, + "device-added", + G_CALLBACK (udev_device_added_cb), + singleton); + g_signal_connect (priv->udev_mgr, + "device-removed", + G_CALLBACK (udev_device_removed_cb), + singleton); + g_signal_connect (priv->udev_mgr, + "rfkill-changed", + G_CALLBACK (udev_manager_rfkill_changed_cb), + singleton); + + priv->bluez_mgr = nm_bluez_manager_get (); + + g_signal_connect (priv->bluez_mgr, + "bdaddr-added", + G_CALLBACK (bluez_manager_bdaddr_added_cb), + singleton); + + g_signal_connect (priv->bluez_mgr, + "bdaddr-removed", + G_CALLBACK (bluez_manager_bdaddr_removed_cb), + singleton); + + return singleton; +} + +static void +dispose (GObject *object) +{ + NMManager *manager = NM_MANAGER (object); + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); + + if (priv->disposed) { + G_OBJECT_CLASS (nm_manager_parent_class)->dispose (object); + return; + } + priv->disposed = TRUE; + + pending_connection_info_destroy (priv->pending_connection_info); + priv->pending_connection_info = NULL; + + while (g_slist_length (priv->secrets_calls)) { + GetSecretsInfo *info = priv->secrets_calls->data; + + free_get_secrets_info (info); + } + + while (g_slist_length (priv->devices)) { + NMDevice *device = NM_DEVICE (priv->devices->data); + + priv->devices = remove_one_device (manager, priv->devices, device); + } + + user_destroy_connections (manager); + g_hash_table_destroy (priv->user_connections); + priv->user_connections = NULL; + + g_hash_table_foreach (priv->system_connections, emit_removed, manager); + g_hash_table_remove_all (priv->system_connections); + g_hash_table_destroy (priv->system_connections); + priv->system_connections = NULL; + + g_free (priv->hostname); + + if (priv->sys_settings) { + g_object_unref (priv->sys_settings); + priv->sys_settings = NULL; + } + + if (priv->vpn_manager_id) { + g_source_remove (priv->vpn_manager_id); + priv->vpn_manager_id = 0; + } + g_object_unref (priv->vpn_manager); + + if (priv->modem_added_id) { + g_source_remove (priv->modem_added_id); + priv->modem_added_id = 0; + } + if (priv->modem_removed_id) { + g_source_remove (priv->modem_removed_id); + priv->modem_removed_id = 0; + } + g_object_unref (priv->modem_manager); + + g_object_unref (priv->dbus_mgr); + if (priv->bluez_mgr) + g_object_unref (priv->bluez_mgr); + + G_OBJECT_CLASS (nm_manager_parent_class)->dispose (object); +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + switch (prop_id) { + case PROP_WIRELESS_ENABLED: + manager_set_wireless_enabled (NM_MANAGER (object), g_value_get_boolean (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + NMManager *self = NM_MANAGER (object); + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + + switch (prop_id) { + case PROP_STATE: + nm_manager_update_state (self); + g_value_set_uint (value, priv->state); + break; + case PROP_WIRELESS_ENABLED: + g_value_set_boolean (value, priv->wireless_enabled); + break; + case PROP_WIRELESS_HARDWARE_ENABLED: + g_value_set_boolean (value, priv->wireless_hw_enabled); + break; + case PROP_ACTIVE_CONNECTIONS: + g_value_take_boxed (value, get_active_connections (self, NULL)); + break; + case PROP_HOSTNAME: + g_value_set_string (value, priv->hostname); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_manager_init (NMManager *manager) +{ + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); + DBusGConnection *g_connection; + guint id; + + priv->wireless_enabled = TRUE; + priv->wireless_hw_enabled = TRUE; + priv->sleeping = FALSE; + priv->state = NM_STATE_DISCONNECTED; + + priv->dbus_mgr = nm_dbus_manager_get (); + + priv->user_connections = g_hash_table_new_full (g_str_hash, + g_str_equal, + g_free, + g_object_unref); + + priv->system_connections = g_hash_table_new_full (g_str_hash, + g_str_equal, + g_free, + g_object_unref); + + priv->modem_manager = nm_modem_manager_get (); + priv->modem_added_id = g_signal_connect (priv->modem_manager, "device-added", + G_CALLBACK (modem_added), manager); + priv->modem_removed_id = g_signal_connect (priv->modem_manager, "device-removed", + G_CALLBACK (modem_removed), manager); + + priv->vpn_manager = nm_vpn_manager_get (); + id = g_signal_connect (G_OBJECT (priv->vpn_manager), "connection-deactivated", + G_CALLBACK (vpn_manager_connection_deactivated_cb), manager); + priv->vpn_manager_id = id; + + g_connection = nm_dbus_manager_get_connection (priv->dbus_mgr); + + /* avahi-autoipd stuff */ + priv->aipd_proxy = dbus_g_proxy_new_for_name (g_connection, + NM_AUTOIP_DBUS_SERVICE, + "/", + NM_AUTOIP_DBUS_IFACE); + if (priv->aipd_proxy) { + dbus_g_object_register_marshaller (_nm_marshal_VOID__STRING_STRING_STRING, + G_TYPE_NONE, + G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_INVALID); + + dbus_g_proxy_add_signal (priv->aipd_proxy, + "Event", + G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_INVALID); + + dbus_g_proxy_connect_signal (priv->aipd_proxy, "Event", + G_CALLBACK (aipd_handle_event), + manager, + NULL); + } else + nm_warning ("%s: could not initialize avahi-autoipd D-Bus proxy", __func__); +} + +static void +nm_manager_class_init (NMManagerClass *manager_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (manager_class); + + g_type_class_add_private (manager_class, sizeof (NMManagerPrivate)); + + /* virtual methods */ + manager_class->connection_added = connection_added_default_handler; + + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->dispose = dispose; + + /* properties */ + g_object_class_install_property + (object_class, PROP_STATE, + g_param_spec_uint (NM_MANAGER_STATE, + "State", + "Current state", + 0, NM_STATE_DISCONNECTED, 0, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_WIRELESS_ENABLED, + g_param_spec_boolean (NM_MANAGER_WIRELESS_ENABLED, + "WirelessEnabled", + "Is wireless enabled", + TRUE, + G_PARAM_READWRITE)); + + g_object_class_install_property + (object_class, PROP_WIRELESS_HARDWARE_ENABLED, + g_param_spec_boolean (NM_MANAGER_WIRELESS_HARDWARE_ENABLED, + "WirelessHardwareEnabled", + "RF kill state", + TRUE, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_ACTIVE_CONNECTIONS, + g_param_spec_boxed (NM_MANAGER_ACTIVE_CONNECTIONS, + "Active connections", + "Active connections", + DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, + G_PARAM_READABLE)); + + /* Hostname is not exported over D-Bus */ + g_object_class_install_property + (object_class, PROP_HOSTNAME, + g_param_spec_string (NM_MANAGER_HOSTNAME, + "Hostname", + "Hostname", + NULL, + G_PARAM_READABLE | NM_PROPERTY_PARAM_NO_EXPORT)); + + /* signals */ + signals[DEVICE_ADDED] = + g_signal_new ("device-added", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMManagerClass, device_added), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, G_TYPE_OBJECT); + + signals[DEVICE_REMOVED] = + g_signal_new ("device-removed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMManagerClass, device_removed), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, G_TYPE_OBJECT); + + signals[STATE_CHANGED] = + g_signal_new ("state-changed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMManagerClass, state_changed), + NULL, NULL, + g_cclosure_marshal_VOID__UINT, + G_TYPE_NONE, 1, G_TYPE_UINT); + + signals[PROPERTIES_CHANGED] = + nm_properties_changed_signal_new (object_class, + G_STRUCT_OFFSET (NMManagerClass, properties_changed)); + + signals[CONNECTIONS_ADDED] = + g_signal_new ("connections-added", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMManagerClass, connections_added), + NULL, NULL, + g_cclosure_marshal_VOID__UINT, + G_TYPE_NONE, 1, G_TYPE_UINT); + + signals[CONNECTION_ADDED] = + g_signal_new ("connection-added", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMManagerClass, connection_added), + NULL, NULL, + _nm_marshal_VOID__OBJECT_UINT, + G_TYPE_NONE, 2, G_TYPE_OBJECT, G_TYPE_UINT); + + signals[CONNECTION_UPDATED] = + g_signal_new ("connection-updated", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMManagerClass, connection_updated), + NULL, NULL, + _nm_marshal_VOID__OBJECT_UINT, + G_TYPE_NONE, 2, G_TYPE_OBJECT, G_TYPE_UINT); + + signals[CONNECTION_REMOVED] = + g_signal_new ("connection-removed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMManagerClass, connection_removed), + NULL, NULL, + _nm_marshal_VOID__OBJECT_UINT, + G_TYPE_NONE, 2, G_TYPE_OBJECT, G_TYPE_UINT); + + /* StateChange is DEPRECATED */ + signals[STATE_CHANGE] = + g_signal_new ("state-change", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + 0, NULL, NULL, + g_cclosure_marshal_VOID__UINT, + G_TYPE_NONE, 1, G_TYPE_UINT); + + dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (manager_class), + &dbus_glib_nm_manager_object_info); + + dbus_g_error_domain_register (NM_MANAGER_ERROR, NULL, NM_TYPE_MANAGER_ERROR); +} + diff --git a/src/nm-manager.h b/src/nm-manager.h index 486dd15d20..a364f8eb9c 100644 --- a/src/nm-manager.h +++ b/src/nm-manager.h @@ -43,9 +43,6 @@ /* Not exported */ #define NM_MANAGER_HOSTNAME "hostname" -#define NM_MANAGER_CONNECTION_PROXY_TAG "dbus-proxy" -#define NM_MANAGER_CONNECTION_SECRETS_PROXY_TAG "dbus-secrets-proxy" - typedef struct { GObject parent; } NMManager; @@ -76,7 +73,9 @@ typedef struct { GType nm_manager_get_type (void); -NMManager *nm_manager_get (void); +NMManager *nm_manager_get (const char *plugins, GError **error); + +void nm_manager_start (NMManager *manager); /* Device handling */ diff --git a/src/nm-secrets-provider-interface.c b/src/nm-secrets-provider-interface.c new file mode 100644 index 0000000000..9bbde7a394 --- /dev/null +++ b/src/nm-secrets-provider-interface.c @@ -0,0 +1,224 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2009 Red Hat, Inc. + */ + +#include + +#include "nm-marshal.h" +#include "nm-secrets-provider-interface.h" + +#include +#include +#include "nm-utils.h" + +static void +nm_secrets_provider_interface_init (gpointer g_iface) +{ + GType iface_type = G_TYPE_FROM_INTERFACE (g_iface); + static gboolean initialized = FALSE; + + if (initialized) + return; + initialized = TRUE; + + /* Signals */ + g_signal_new ("manager-get-secrets", + iface_type, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (NMSecretsProviderInterface, manager_get_secrets), + NULL, NULL, + _nm_marshal_BOOLEAN__POINTER_STRING_BOOLEAN_UINT_STRING_STRING, + G_TYPE_BOOLEAN, 6, + G_TYPE_POINTER, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING); + + g_signal_new ("manager-cancel-secrets", + iface_type, + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMSecretsProviderInterface, manager_cancel_secrets), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); +} + + +GType +nm_secrets_provider_interface_get_type (void) +{ + static GType interface_type = 0; + + if (!interface_type) { + const GTypeInfo interface_info = { + sizeof (NMSecretsProviderInterface), /* class_size */ + nm_secrets_provider_interface_init, /* base_init */ + NULL, /* base_finalize */ + NULL, + NULL, /* class_finalize */ + NULL, /* class_data */ + 0, + 0, /* n_preallocs */ + NULL + }; + + interface_type = g_type_register_static (G_TYPE_INTERFACE, + "NMSecretsProviderInterface", + &interface_info, 0); + + g_type_interface_add_prerequisite (interface_type, G_TYPE_OBJECT); + } + + return interface_type; +} + +gboolean +nm_secrets_provider_interface_get_secrets (NMSecretsProviderInterface *self, + NMConnection *connection, + const char *setting_name, + gboolean request_new, + RequestSecretsCaller caller, + const char *hint1, + const char *hint2) +{ + guint success = FALSE; + + g_return_val_if_fail (self != NULL, FALSE); + g_return_val_if_fail (NM_IS_SECRETS_PROVIDER_INTERFACE (self), FALSE); + g_return_val_if_fail (connection != NULL, FALSE); + g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); + g_return_val_if_fail (setting_name != NULL, FALSE); + + nm_secrets_provider_interface_cancel_get_secrets (self); + + g_signal_emit_by_name (self, "manager-get-secrets", + connection, setting_name, request_new, caller, hint1, hint2, + &success); + if (!success) { + nm_warning ("failed to get connection secrets."); + return FALSE; + } + + return TRUE; +} + +void +nm_secrets_provider_interface_cancel_get_secrets (NMSecretsProviderInterface *self) +{ + g_return_if_fail (self != NULL); + g_return_if_fail (NM_IS_SECRETS_PROVIDER_INTERFACE (self)); + + g_signal_emit_by_name (self, "manager-cancel-secrets"); +} + + +static void +add_one_key_to_list (gpointer key, gpointer data, gpointer user_data) +{ + GSList **list = (GSList **) user_data; + + *list = g_slist_append (*list, key); +} + +static gint +settings_order_func (gconstpointer a, gconstpointer b) +{ + /* Just ensure the 802.1x setting gets processed _before_ the + * wireless-security one. + */ + + if ( !strcmp (a, NM_SETTING_802_1X_SETTING_NAME) + && !strcmp (b, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME)) + return -1; + + if ( !strcmp (a, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) + && !strcmp (b, NM_SETTING_802_1X_SETTING_NAME)) + return 1; + + return 0; +} + +void +nm_secrets_provider_interface_get_secrets_result (NMSecretsProviderInterface *self, + const char *setting_name, + RequestSecretsCaller caller, + GHashTable *settings, + GError *error) +{ + GSList *keys = NULL, *iter; + GSList *updated = NULL; + GError *tmp_error = NULL; + + g_return_if_fail (self != NULL); + g_return_if_fail (NM_IS_SECRETS_PROVIDER_INTERFACE (self)); + + if (error) { + NM_SECRETS_PROVIDER_INTERFACE_GET_INTERFACE (self)->result (self, + setting_name, + caller, + NULL, + error); + return; + } + + if (g_hash_table_size (settings) == 0) { + g_set_error (&tmp_error, 0, 0, "%s", "no secrets were received!"); + NM_SECRETS_PROVIDER_INTERFACE_GET_INTERFACE (self)->result (self, + setting_name, + caller, + NULL, + tmp_error); + g_clear_error (&tmp_error); + return; + } + + g_hash_table_foreach (settings, add_one_key_to_list, &keys); + keys = g_slist_sort (keys, settings_order_func); + for (iter = keys; iter; iter = g_slist_next (iter)) { + GHashTable *hash; + const char *name = (const char *) iter->data; + + hash = g_hash_table_lookup (settings, name); + if (!hash) { + nm_warning ("couldn't get setting secrets for '%s'", name); + continue; + } + + if (NM_SECRETS_PROVIDER_INTERFACE_GET_INTERFACE (self)->update_setting (self, name, hash)) + updated = g_slist_append (updated, (gpointer) setting_name); + } + g_slist_free (keys); + + if (g_slist_length (updated)) { + NM_SECRETS_PROVIDER_INTERFACE_GET_INTERFACE (self)->result (self, + setting_name, + caller, + updated, + NULL); + } else { + g_set_error (&tmp_error, 0, 0, "%s", "no secrets updated because no valid " + "settings were received!"); + NM_SECRETS_PROVIDER_INTERFACE_GET_INTERFACE (self)->result (self, + setting_name, + caller, + NULL, + tmp_error); + g_clear_error (&tmp_error); + } + + g_slist_free (updated); +} + diff --git a/src/nm-secrets-provider-interface.h b/src/nm-secrets-provider-interface.h new file mode 100644 index 0000000000..299e8c2dc8 --- /dev/null +++ b/src/nm-secrets-provider-interface.h @@ -0,0 +1,91 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2009 Red Hat, Inc. + */ + +#ifndef NM_SECRETS_PROVIDER_INTERFACE_H +#define NM_SECRETS_PROVIDER_INTERFACE_H + +#include +#include + +typedef enum { + SECRETS_CALLER_NONE = 0, + SECRETS_CALLER_ETHERNET, + SECRETS_CALLER_WIFI, + SECRETS_CALLER_GSM, + SECRETS_CALLER_CDMA, + SECRETS_CALLER_PPP, + SECRETS_CALLER_VPN +} RequestSecretsCaller; + +#define NM_TYPE_SECRETS_PROVIDER_INTERFACE (nm_secrets_provider_interface_get_type ()) +#define NM_SECRETS_PROVIDER_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SECRETS_PROVIDER_INTERFACE, NMSecretsProviderInterface)) +#define NM_IS_SECRETS_PROVIDER_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SECRETS_PROVIDER_INTERFACE)) +#define NM_SECRETS_PROVIDER_INTERFACE_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), NM_TYPE_SECRETS_PROVIDER_INTERFACE, NMSecretsProviderInterface)) + +typedef struct _NMSecretsProviderInterface NMSecretsProviderInterface; + +struct _NMSecretsProviderInterface { + GTypeInterface g_iface; + + /* Methods */ + void (*result) (NMSecretsProviderInterface *self, + const char *setting_name, + RequestSecretsCaller caller, + const GSList *updated, + GError *error); + + gboolean (*update_setting) (NMSecretsProviderInterface *self, + const char *setting_name, + GHashTable *new); + + /* Signals */ + void (*manager_get_secrets) (NMSecretsProviderInterface *self, + NMConnection *connection, + const char *setting_name, + gboolean request_new, + RequestSecretsCaller caller, + const char *hint1, + const char *hint2); + + void (*manager_cancel_secrets) (NMSecretsProviderInterface *self); +}; + +GType nm_secrets_provider_interface_get_type (void); + +/* For callers */ +gboolean nm_secrets_provider_interface_get_secrets (NMSecretsProviderInterface *self, + NMConnection *connection, + const char *setting_name, + gboolean request_new, + RequestSecretsCaller caller, + const char *hint1, + const char *hint2); + +void nm_secrets_provider_interface_cancel_get_secrets (NMSecretsProviderInterface *self); + +/* For NMManager */ +void nm_secrets_provider_interface_get_secrets_result (NMSecretsProviderInterface *self, + const char *setting_name, + RequestSecretsCaller caller, + GHashTable *settings, + GError *error); + +#endif /* NM_SECRETS_PROVIDER_INTERFACE_H */ + diff --git a/src/nm-udev-manager.c b/src/nm-udev-manager.c index feafa11c14..7732de37be 100644 --- a/src/nm-udev-manager.c +++ b/src/nm-udev-manager.c @@ -21,6 +21,12 @@ #include #include #include +#include +#include +#include +#include + +#include "wireless-helper.h" #define G_UDEV_API_IS_SUBJECT_TO_CHANGE #include @@ -28,12 +34,14 @@ #include "nm-udev-manager.h" #include "nm-marshal.h" #include "nm-utils.h" +#include "NetworkManagerUtils.h" +#include "nm-device-wifi.h" +#include "nm-device-ethernet.h" typedef struct { GUdevClient *client; - /* Authoritative rfkill state (RFKILL_* enum) - */ + /* Authoritative rfkill state (RFKILL_* enum) */ RfKillState rfkill_state; GSList *killswitches; @@ -45,6 +53,8 @@ typedef struct { G_DEFINE_TYPE (NMUdevManager, nm_udev_manager, G_TYPE_OBJECT) enum { + DEVICE_ADDED, + DEVICE_REMOVED, RFKILL_CHANGED, LAST_SIGNAL @@ -197,6 +207,161 @@ add_one_killswitch (NMUdevManager *self, GUdevDevice *device) ks->driver ? ks->driver : ""); } +static void +rfkill_add (NMUdevManager *self, GUdevDevice *device) +{ + const char *name; + + g_return_if_fail (device != NULL); + name = g_udev_device_get_name (device); + g_return_if_fail (name != NULL); + + if (!killswitch_find_by_name (self, name)) + add_one_killswitch (self, device); +} + +static void +rfkill_remove (NMUdevManager *self, + GUdevDevice *device) +{ + NMUdevManagerPrivate *priv = NM_UDEV_MANAGER_GET_PRIVATE (self); + GSList *iter; + const char *name; + + g_return_if_fail (device != NULL); + name = g_udev_device_get_name (device); + g_return_if_fail (name != NULL); + + for (iter = priv->killswitches; iter; iter = g_slist_next (iter)) { + Killswitch *ks = iter->data; + + if (!strcmp (ks->name, name)) { + nm_info ("Radio killswitch %s disappeared", ks->path); + priv->killswitches = g_slist_remove (priv->killswitches, iter); + killswitch_destroy (iter->data); + g_slist_free (iter); + break; + } + } +} + +static gboolean +is_wireless (GUdevDevice *device) +{ + char phy80211_path[255]; + struct stat s; + int fd; + struct iwreq iwr; + const char *ifname, *path; + gboolean is_wifi = FALSE; + + ifname = g_udev_device_get_name (device); + g_assert (ifname); + + fd = socket (PF_INET, SOCK_DGRAM, 0); + strncpy (iwr.ifr_ifrn.ifrn_name, ifname, IFNAMSIZ); + + path = g_udev_device_get_sysfs_path (device); + snprintf (phy80211_path, sizeof (phy80211_path), "%s/phy80211", path); + + if ( (ioctl (fd, SIOCGIWNAME, &iwr) == 0) + || (stat (phy80211_path, &s) == 0 && (s.st_mode & S_IFDIR))) + is_wifi = TRUE; + + close (fd); + return is_wifi; +} + +static GObject * +device_creator (NMUdevManager *manager, + GUdevDevice *udev_device, + gboolean sleeping) +{ + GObject *device = NULL; + const char *ifname, *driver, *path; + GUdevDevice *parent; + gint ifindex; + + ifname = g_udev_device_get_name (udev_device); + g_assert (ifname); + + path = g_udev_device_get_sysfs_path (udev_device); + if (!path) { + nm_warning ("couldn't determine device path; ignoring..."); + return NULL; + } + + driver = g_udev_device_get_driver (udev_device); + if (!driver) { + /* Try the parent */ + parent = g_udev_device_get_parent (udev_device); + if (parent) { + driver = g_udev_device_get_driver (parent); + g_object_unref (parent); + } + } + + if (!driver) { + nm_warning ("%s: couldn't determine device driver; ignoring...", path); + return NULL; + } + + ifindex = g_udev_device_get_sysfs_attr_as_int (udev_device, "ifindex"); + if (ifindex <= 0) { + nm_warning ("%s: device had invalid ifindex %d; ignoring...", path, (guint32) ifindex); + return NULL; + } + + if (is_wireless (udev_device)) + device = (GObject *) nm_device_wifi_new (path, ifname, driver, ifindex); + else + device = (GObject *) nm_device_ethernet_new (path, ifname, driver, ifindex); + + return device; +} + +static void +net_add (NMUdevManager *self, GUdevDevice *device) +{ + gint devtype; + const char *iface; + + g_return_if_fail (device != NULL); + + devtype = g_udev_device_get_sysfs_attr_as_int (device, "type"); + if (devtype != 1) + return; /* Not using ethernet encapsulation, don't care */ + + iface = g_udev_device_get_name (device); + if (!iface) + return; + + g_signal_emit (self, signals[DEVICE_ADDED], 0, device, device_creator); +} + +static void +net_remove (NMUdevManager *self, GUdevDevice *device) +{ + g_signal_emit (self, signals[DEVICE_REMOVED], 0, device); +} + +void +nm_udev_manager_query_devices (NMUdevManager *self) +{ + NMUdevManagerPrivate *priv = NM_UDEV_MANAGER_GET_PRIVATE (self); + GList *devices, *iter; + + g_return_if_fail (self != NULL); + g_return_if_fail (NM_IS_UDEV_MANAGER (self)); + + devices = g_udev_client_query_by_subsystem (priv->client, "net"); + for (iter = devices; iter; iter = g_list_next (iter)) { + net_add (self, G_UDEV_DEVICE (iter->data)); + g_object_unref (G_UDEV_DEVICE (iter->data)); + } + g_list_free (devices); +} + static void handle_uevent (GUdevClient *client, const char *action, @@ -204,39 +369,28 @@ handle_uevent (GUdevClient *client, gpointer user_data) { NMUdevManager *self = NM_UDEV_MANAGER (user_data); - NMUdevManagerPrivate *priv = NM_UDEV_MANAGER_GET_PRIVATE (self); - const char *name, *subsys; + const char *subsys; g_return_if_fail (action != NULL); - name = g_udev_device_get_name (device); - g_return_if_fail (name != NULL); - /* A bit paranoid */ subsys = g_udev_device_get_subsystem (device); - g_return_if_fail (subsys && !strcmp (subsys, "rfkill")); + g_return_if_fail (subsys != NULL); + + g_return_if_fail (!strcmp (subsys, "rfkill") || !strcmp (subsys, "net")); if (!strcmp (action, "add")) { - if (!killswitch_find_by_name (self, name)) - add_one_killswitch (self, device); + if (!strcmp (subsys, "rfkill")) + rfkill_add (self, device); + else if (!strcmp (subsys, "net")) + net_add (self, device); } else if (!strcmp (action, "remove")) { - GSList *iter; - - for (iter = priv->killswitches; iter; iter = g_slist_next (iter)) { - Killswitch *ks = iter->data; - - if (!strcmp (ks->name, name)) { - nm_info ("Radio killswitch %s disappeared", ks->path); - priv->killswitches = g_slist_remove (priv->killswitches, iter); - killswitch_destroy (iter->data); - g_slist_free (iter); - break; - } - } + if (!strcmp (subsys, "rfkill")) + rfkill_remove (self, device); + else if (!strcmp (subsys, "net")) + net_remove (self, device); } - // FIXME: check sequence #s to ensure events don't arrive out of order - recheck_killswitches (self); } @@ -244,7 +398,7 @@ static void nm_udev_manager_init (NMUdevManager *self) { NMUdevManagerPrivate *priv = NM_UDEV_MANAGER_GET_PRIVATE (self); - const char *subsys[2] = { "rfkill", NULL }; + const char *subsys[3] = { "rfkill", "net", NULL }; GList *switches, *iter; priv->rfkill_state = RFKILL_UNBLOCKED; @@ -292,6 +446,24 @@ nm_udev_manager_class_init (NMUdevManagerClass *klass) object_class->dispose = dispose; /* Signals */ + signals[DEVICE_ADDED] = + g_signal_new ("device-added", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMUdevManagerClass, device_added), + NULL, NULL, + _nm_marshal_VOID__POINTER_POINTER, + G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_POINTER); + + signals[DEVICE_REMOVED] = + g_signal_new ("device-removed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMUdevManagerClass, device_removed), + NULL, NULL, + g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, 1, G_TYPE_POINTER); + signals[RFKILL_CHANGED] = g_signal_new ("rfkill-changed", G_OBJECT_CLASS_TYPE (object_class), diff --git a/src/nm-udev-manager.h b/src/nm-udev-manager.h index dd4dbf1591..4afcf3b6c7 100644 --- a/src/nm-udev-manager.h +++ b/src/nm-udev-manager.h @@ -25,6 +25,9 @@ #include #include +#define G_UDEV_API_IS_SUBJECT_TO_CHANGE +#include + typedef enum { RFKILL_UNBLOCKED = 0, RFKILL_SOFT_BLOCKED = 1, @@ -44,16 +47,30 @@ typedef struct { GObject parent; } NMUdevManager; +typedef GObject *(*NMDeviceCreatorFn) (NMUdevManager *manager, + GUdevDevice *device, + gboolean sleeping); + typedef struct { GObjectClass parent; /* Virtual functions */ + void (*device_added) (NMUdevManager *manager, + GUdevDevice *device, + NMDeviceCreatorFn creator_fn); + + void (*device_removed) (NMUdevManager *manager, GUdevDevice *device); + void (*rfkill_changed) (NMUdevManager *manager, RfKillState state); } NMUdevManagerClass; GType nm_udev_manager_get_type (void); NMUdevManager *nm_udev_manager_new (void); + +void nm_udev_manager_query_devices (NMUdevManager *manager); + RfKillState nm_udev_manager_get_rfkill_state (NMUdevManager *manager); #endif /* NM_UDEV_MANAGER_H */ + diff --git a/src/ppp-manager/nm-ppp-manager.c b/src/ppp-manager/nm-ppp-manager.c index 73fd1ed880..7fdf2ea808 100644 --- a/src/ppp-manager/nm-ppp-manager.c +++ b/src/ppp-manager/nm-ppp-manager.c @@ -408,12 +408,12 @@ impl_ppp_manager_need_secrets (NMPPPManager *manager, * servers (T-Mobile USA) appear to ask a few times when they actually don't * even care what you pass back. */ - nm_act_request_request_connection_secrets (priv->act_req, - setting_name, - tries > 1 ? TRUE : FALSE, - SECRETS_CALLER_PPP, - hint1, - hint2); + nm_act_request_get_secrets (priv->act_req, + setting_name, + tries > 1 ? TRUE : FALSE, + SECRETS_CALLER_PPP, + hint1, + hint2); g_object_set_data (G_OBJECT (connection), PPP_MANAGER_SECRET_TRIES, GUINT_TO_POINTER (++tries)); priv->pending_secrets_context = context; diff --git a/src/system-settings/Makefile.am b/src/system-settings/Makefile.am new file mode 100644 index 0000000000..e5c9313f6e --- /dev/null +++ b/src/system-settings/Makefile.am @@ -0,0 +1,60 @@ +INCLUDES = -I${top_srcdir} \ + -I${top_srcdir}/include \ + -I${top_srcdir}/libnm-util \ + -I${top_srcdir}/libnm-glib \ + -I${top_srcdir}/src \ + -I${top_builddir}/marshallers + +noinst_LTLIBRARIES = libsystem-settings.la + +BUILT_SOURCES = \ + nm-settings-system-glue.h + +libsystem_settings_la_SOURCES = \ + nm-sysconfig-settings.c \ + nm-sysconfig-settings.h \ + nm-inotify-helper.c \ + nm-inotify-helper.h \ + nm-polkit-helpers.c \ + nm-polkit-helpers.h \ + nm-system-config-error.c \ + nm-system-config-error.h \ + nm-system-config-interface.c \ + nm-system-config-interface.h \ + nm-sysconfig-connection.c \ + nm-sysconfig-connection.h \ + nm-default-wired-connection.c \ + nm-default-wired-connection.h + +libsystem_settings_la_CPPFLAGS = \ + $(DBUS_CFLAGS) \ + $(GLIB_CFLAGS) \ + $(GMODULE_CFLAGS) \ + $(POLKIT_CFLAGS) \ + -DG_DISABLE_DEPRECATED \ + -DBINDIR=\"$(bindir)\" \ + -DSBINDIR=\"$(sbindir)\" \ + -DLIBEXECDIR=\"$(libexecdir)\" \ + -DDATADIR=\"$(datadir)\" \ + -DSYSCONFDIR=\"$(sysconfdir)\" \ + -DLOCALSTATEDIR=\"$(localstatedir)\" \ + -DGNOMELOCALEDIR=\"$(datadir)/locale\" \ + -DPLUGINDIR=\"$(pkglibdir)\" + +libsystem_settings_la_LIBADD = \ + $(DBUS_LIBS) \ + $(GLIB_LIBS) \ + $(GMODULE_LIBS) \ + $(POLKIT_LIBS) \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(top_builddir)/libnm-glib/libnm_glib.la \ + $(top_builddir)/marshallers/libmarshallers.la + +libsystem_settings_la_LDFLAGS = -rdynamic + +nm-settings-system-glue.h: $(top_srcdir)/introspection/nm-settings-system.xml + dbus-binding-tool --prefix=nm_settings_system --mode=glib-server --output=$@ $< + +CLEANFILES = \ + $(BUILT_SOURCES) + diff --git a/src/system-settings/nm-default-wired-connection.c b/src/system-settings/nm-default-wired-connection.c new file mode 100644 index 0000000000..c8a6daab72 --- /dev/null +++ b/src/system-settings/nm-default-wired-connection.c @@ -0,0 +1,355 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2008 Novell, Inc. + * (C) Copyright 2009 Red Hat, Inc. + */ + +#include + +#include + +#include +#include +#include +#include +#include + +#include "nm-dbus-glib-types.h" +#include "nm-marshal.h" +#include "nm-default-wired-connection.h" + +G_DEFINE_TYPE (NMDefaultWiredConnection, nm_default_wired_connection, NM_TYPE_SYSCONFIG_CONNECTION) + +#define NM_DEFAULT_WIRED_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEFAULT_WIRED_CONNECTION, NMDefaultWiredConnectionPrivate)) + +typedef struct { + char *iface; + GByteArray *mac; + gboolean read_only; +} NMDefaultWiredConnectionPrivate; + +enum { + PROP_0, + PROP_MAC, + PROP_IFACE, + PROP_READ_ONLY, + LAST_PROP +}; + +enum { + TRY_UPDATE, + DELETED, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + + +NMDefaultWiredConnection * +nm_default_wired_connection_new (const GByteArray *mac, + const char *iface, + gboolean read_only) +{ + + g_return_val_if_fail (mac != NULL, NULL); + g_return_val_if_fail (mac->len == ETH_ALEN, NULL); + g_return_val_if_fail (iface != NULL, NULL); + + return g_object_new (NM_TYPE_DEFAULT_WIRED_CONNECTION, + NM_DEFAULT_WIRED_CONNECTION_MAC, mac, + NM_DEFAULT_WIRED_CONNECTION_IFACE, iface, + NM_DEFAULT_WIRED_CONNECTION_READ_ONLY, read_only, + NULL); +} + +static GByteArray * +dup_wired_mac (NMExportedConnection *exported) +{ + NMConnection *wrapped; + NMSettingWired *s_wired; + const GByteArray *mac; + GByteArray *dup; + + wrapped = nm_exported_connection_get_connection (exported); + if (!wrapped) + return NULL; + + s_wired = (NMSettingWired *) nm_connection_get_setting (wrapped, NM_TYPE_SETTING_WIRED); + if (!s_wired) + return NULL; + + mac = nm_setting_wired_get_mac_address (s_wired); + if (!mac || (mac->len != ETH_ALEN)) + return NULL; + + dup = g_byte_array_sized_new (ETH_ALEN); + g_byte_array_append (dup, mac->data, ETH_ALEN); + return dup; +} + +static gboolean +update (NMExportedConnection *exported, + GHashTable *new_settings, + GError **error) +{ + NMDefaultWiredConnection *connection = NM_DEFAULT_WIRED_CONNECTION (exported); + gboolean success; + GByteArray *mac; + + /* Ensure object stays alive across signal emission */ + g_object_ref (exported); + + /* Save a copy of the current MAC address just in case the user + * changed it when updating the connection. + */ + mac = dup_wired_mac (exported); + + /* Let NMSysconfigConnection check permissions */ + success = NM_EXPORTED_CONNECTION_CLASS (nm_default_wired_connection_parent_class)->update (exported, new_settings, error); + if (success) { + g_signal_emit_by_name (connection, "try-update", new_settings, error); + success = *error ? FALSE : TRUE; + + if (success) + g_signal_emit (connection, signals[DELETED], 0, mac); + } + + g_byte_array_free (mac, TRUE); + g_object_unref (exported); + return success; +} + +static gboolean +do_delete (NMExportedConnection *exported, GError **error) +{ + gboolean success; + GByteArray *mac; + + g_object_ref (exported); + mac = dup_wired_mac (exported); + + success = NM_EXPORTED_CONNECTION_CLASS (nm_default_wired_connection_parent_class)->do_delete (exported, error); + if (success) + g_signal_emit (exported, signals[DELETED], 0, mac); + + g_byte_array_free (mac, TRUE); + g_object_unref (exported); + return success; +} + +static void +nm_default_wired_connection_init (NMDefaultWiredConnection *self) +{ +} + +static GObject * +constructor (GType type, + guint n_construct_params, + GObjectConstructParam *construct_params) +{ + GObject *object; + NMDefaultWiredConnectionPrivate *priv; + NMConnection *wrapped; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + char *id, *uuid; + + object = G_OBJECT_CLASS (nm_default_wired_connection_parent_class)->constructor (type, n_construct_params, construct_params); + if (!object) + return NULL; + + priv = NM_DEFAULT_WIRED_CONNECTION_GET_PRIVATE (object); + + wrapped = nm_connection_new (); + + s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); + + id = g_strdup_printf (_("Auto %s"), priv->iface); + uuid = nm_utils_uuid_generate (); + + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, id, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_READ_ONLY, priv->read_only, + NULL); + + g_free (id); + g_free (uuid); + + nm_connection_add_setting (wrapped, NM_SETTING (s_con)); + + /* Lock the connection to the specific device */ + s_wired = NM_SETTING_WIRED (nm_setting_wired_new ()); + g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, priv->mac, NULL); + nm_connection_add_setting (wrapped, NM_SETTING (s_wired)); + + g_object_set (object, NM_EXPORTED_CONNECTION_CONNECTION, wrapped, NULL); + g_object_unref (wrapped); + + return object; +} + +static void +finalize (GObject *object) +{ + NMDefaultWiredConnectionPrivate *priv = NM_DEFAULT_WIRED_CONNECTION_GET_PRIVATE (object); + + g_free (priv->iface); + g_byte_array_free (priv->mac, TRUE); + + G_OBJECT_CLASS (nm_default_wired_connection_parent_class)->finalize (object); +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + NMDefaultWiredConnectionPrivate *priv = NM_DEFAULT_WIRED_CONNECTION_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_MAC: + g_value_set_pointer (value, priv->mac); + break; + case PROP_IFACE: + g_value_set_string (value, priv->iface); + break; + case PROP_READ_ONLY: + g_value_set_boolean (value, priv->read_only); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMDefaultWiredConnectionPrivate *priv = NM_DEFAULT_WIRED_CONNECTION_GET_PRIVATE (object); + GByteArray *array; + + switch (prop_id) { + case PROP_MAC: + /* Construct only */ + array = g_value_get_pointer (value); + if (priv->mac) { + g_byte_array_free (priv->mac, TRUE); + priv->mac = NULL; + } + if (array) { + g_return_if_fail (array->len == ETH_ALEN); + priv->mac = g_byte_array_sized_new (array->len); + g_byte_array_append (priv->mac, array->data, ETH_ALEN); + } + break; + case PROP_IFACE: + g_free (priv->iface); + priv->iface = g_value_dup_string (value); + break; + case PROP_READ_ONLY: + priv->read_only = g_value_get_boolean (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static gboolean +try_update_signal_accumulator (GSignalInvocationHint *ihint, + GValue *return_accu, + const GValue *handler_return, + gpointer data) +{ + gpointer new_ptr = g_value_get_pointer (handler_return); + + g_value_set_pointer (return_accu, new_ptr); + + /* Continue if no error was returned from the handler */ + return new_ptr ? FALSE : TRUE; +} + +static void +nm_default_wired_connection_class_init (NMDefaultWiredConnectionClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMExportedConnectionClass *exported_class = NM_EXPORTED_CONNECTION_CLASS (klass); + + g_type_class_add_private (klass, sizeof (NMDefaultWiredConnectionPrivate)); + + /* Virtual methods */ + object_class->constructor = constructor; + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->finalize = finalize; + + exported_class->update = update; + exported_class->do_delete = do_delete; + + /* Properties */ + g_object_class_install_property + (object_class, PROP_MAC, + g_param_spec_pointer (NM_DEFAULT_WIRED_CONNECTION_MAC, + "MAC", + "MAC Address", + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property + (object_class, PROP_IFACE, + g_param_spec_string (NM_DEFAULT_WIRED_CONNECTION_IFACE, + "Iface", + "Interface", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property + (object_class, PROP_READ_ONLY, + g_param_spec_boolean (NM_DEFAULT_WIRED_CONNECTION_READ_ONLY, + "ReadOnly", + "Read Only", + FALSE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + /* Signals */ + signals[TRY_UPDATE] = + g_signal_new ("try-update", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + 0, try_update_signal_accumulator, NULL, + _nm_marshal_POINTER__POINTER, + G_TYPE_POINTER, 1, + DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT); + + /* The 'deleted' signal is used to signal intentional deletions (like + * updating or user-requested deletion) rather than using the + * NMExportedConnection superclass' 'removed' signal, since that signal + * doesn't have the semantics we want; it gets emitted as a side-effect + * of various operations and is meant more for D-Bus clients instead + * of in-service uses. + */ + signals[DELETED] = + g_signal_new ("deleted", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, + g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, 1, G_TYPE_POINTER); +} diff --git a/src/system-settings/nm-default-wired-connection.h b/src/system-settings/nm-default-wired-connection.h new file mode 100644 index 0000000000..50c8b182e1 --- /dev/null +++ b/src/system-settings/nm-default-wired-connection.h @@ -0,0 +1,57 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2008 Novell, Inc. + * (C) Copyright 2009 Red Hat, Inc. + */ + +#ifndef NM_DEFAULT_WIRED_CONNECTION_H +#define NM_DEFAULT_WIRED_CONNECTION_H + +#include +#include "nm-sysconfig-connection.h" + +G_BEGIN_DECLS + +#define NM_TYPE_DEFAULT_WIRED_CONNECTION (nm_default_wired_connection_get_type ()) +#define NM_DEFAULT_WIRED_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEFAULT_WIRED_CONNECTION, NMDefaultWiredConnection)) +#define NM_DEFAULT_WIRED_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEFAULT_WIRED_CONNECTION, NMDefaultWiredConnectionClass)) +#define NM_IS_DEFAULT_WIRED_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEFAULT_WIRED_CONNECTION)) +#define NM_IS_DEFAULT_WIRED_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_DEFAULT_WIRED_CONNECTION)) +#define NM_DEFAULT_WIRED_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEFAULT_WIRED_CONNECTION, NMDefaultWiredConnectionClass)) + +#define NM_DEFAULT_WIRED_CONNECTION_MAC "mac" +#define NM_DEFAULT_WIRED_CONNECTION_IFACE "iface" +#define NM_DEFAULT_WIRED_CONNECTION_READ_ONLY "read-only" + +typedef struct { + NMSysconfigConnection parent; +} NMDefaultWiredConnection; + +typedef struct { + NMSysconfigConnectionClass parent; +} NMDefaultWiredConnectionClass; + +GType nm_default_wired_connection_get_type (void); + +NMDefaultWiredConnection *nm_default_wired_connection_new (const GByteArray *mac, + const char *iface, + gboolean read_only); + +G_END_DECLS + +#endif /* NM_DEFAULT_WIRED_CONNECTION_H */ diff --git a/src/system-settings/nm-inotify-helper.c b/src/system-settings/nm-inotify-helper.c new file mode 100644 index 0000000000..589dbd6917 --- /dev/null +++ b/src/system-settings/nm-inotify-helper.c @@ -0,0 +1,211 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2008 Red Hat, Inc. + */ + +#include +#include +#include +#include + +#include "nm-marshal.h" +#include "nm-inotify-helper.h" + +G_DEFINE_TYPE (NMInotifyHelper, nm_inotify_helper, G_TYPE_OBJECT) + +#define NM_INOTIFY_HELPER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_INOTIFY_HELPER, NMInotifyHelperPrivate)) + +typedef struct { + int ifd; + + GHashTable *wd_refs; +} NMInotifyHelperPrivate; + +/* Signals */ +enum { + EVENT, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +int +nm_inotify_helper_add_watch (NMInotifyHelper *self, const char *path) +{ + NMInotifyHelperPrivate *priv = NM_INOTIFY_HELPER_GET_PRIVATE (self); + int wd; + guint32 refcount; + + g_return_val_if_fail (priv->ifd >= 0, -1); + + /* We only care about modifications since we're just trying to get change + * notifications on hardlinks. + */ + + wd = inotify_add_watch (priv->ifd, path, IN_CLOSE_WRITE); + if (wd < 0) + return -1; + + refcount = GPOINTER_TO_UINT (g_hash_table_lookup (priv->wd_refs, GINT_TO_POINTER (wd))); + refcount++; + g_hash_table_replace (priv->wd_refs, GINT_TO_POINTER (wd), GUINT_TO_POINTER (refcount)); + + return wd; +} + +void +nm_inotify_helper_remove_watch (NMInotifyHelper *self, int wd) +{ + NMInotifyHelperPrivate *priv = NM_INOTIFY_HELPER_GET_PRIVATE (self); + guint32 refcount; + + g_return_if_fail (priv->ifd >= 0); + + refcount = GPOINTER_TO_UINT (g_hash_table_lookup (priv->wd_refs, GINT_TO_POINTER (wd))); + if (!refcount) + return; + + refcount--; + if (!refcount) { + g_hash_table_remove (priv->wd_refs, GINT_TO_POINTER (wd)); + inotify_rm_watch (priv->ifd, wd); + } else + g_hash_table_replace (priv->wd_refs, GINT_TO_POINTER (wd), GUINT_TO_POINTER (refcount)); +} + +static gboolean +inotify_event_handler (GIOChannel *channel, GIOCondition cond, gpointer user_data) +{ + NMInotifyHelper *self = NM_INOTIFY_HELPER (user_data); + struct inotify_event evt; + + /* read the notifications from the watch descriptor */ + while (g_io_channel_read_chars (channel, (gchar *) &evt, sizeof (struct inotify_event), NULL, NULL) == G_IO_STATUS_NORMAL) { + gchar filename[PATH_MAX + 1]; + + filename[0] = '\0'; + if (evt.len > 0) { + g_io_channel_read_chars (channel, + filename, + evt.len > PATH_MAX ? PATH_MAX : evt.len, + NULL, NULL); + } + + if (!(evt.mask & IN_IGNORED)) + g_signal_emit (self, signals[EVENT], 0, &evt, &filename[0]); + } + + return TRUE; +} + +static gboolean +init_inotify (NMInotifyHelper *self) +{ + NMInotifyHelperPrivate *priv = NM_INOTIFY_HELPER_GET_PRIVATE (self); + GIOChannel *channel; + guint source_id; + + priv->ifd = inotify_init (); + if (priv->ifd == -1) { + g_warning ("%s: couldn't initialize inotify", __func__); + return FALSE; + } + + /* Watch the inotify descriptor for file/directory change events */ + channel = g_io_channel_unix_new (priv->ifd); + if (!channel) { + g_warning ("%s: couldn't create new GIOChannel", __func__); + close (priv->ifd); + priv->ifd = -1; + return FALSE; + } + + g_io_channel_set_flags (channel, G_IO_FLAG_NONBLOCK, NULL); + g_io_channel_set_encoding (channel, NULL, NULL); + + source_id = g_io_add_watch (channel, + G_IO_IN | G_IO_ERR, + (GIOFunc) inotify_event_handler, + (gpointer) self); + g_io_channel_unref (channel); + return TRUE; +} + +NMInotifyHelper * +nm_inotify_helper_get (void) +{ + static NMInotifyHelper *singleton = NULL; + + if (!singleton) { + singleton = (NMInotifyHelper *) g_object_new (NM_TYPE_INOTIFY_HELPER, NULL); + if (!singleton) + return NULL; + + if (!init_inotify (singleton)) { + g_object_unref (singleton); + return NULL; + } + } else + g_object_ref (singleton); + + g_assert (singleton); + return singleton; +} + +static void +nm_inotify_helper_init (NMInotifyHelper *self) +{ + NMInotifyHelperPrivate *priv = NM_INOTIFY_HELPER_GET_PRIVATE (self); + + priv->wd_refs = g_hash_table_new (g_direct_hash, g_direct_equal); +} + +static void +finalize (GObject *object) +{ + NMInotifyHelperPrivate *priv = NM_INOTIFY_HELPER_GET_PRIVATE (object); + + if (priv->ifd >= 0) + close (priv->ifd); + + g_hash_table_destroy (priv->wd_refs); + + G_OBJECT_CLASS (nm_inotify_helper_parent_class)->finalize (object); +} + +static void +nm_inotify_helper_class_init (NMInotifyHelperClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (NMInotifyHelperPrivate)); + + /* Virtual methods */ + object_class->finalize = finalize; + + /* Signals */ + signals[EVENT] = + g_signal_new ("event", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (NMInotifyHelperClass, event), + NULL, NULL, + _nm_marshal_VOID__POINTER_STRING, + G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_STRING); +} + diff --git a/src/system-settings/nm-inotify-helper.h b/src/system-settings/nm-inotify-helper.h new file mode 100644 index 0000000000..10d43ac99f --- /dev/null +++ b/src/system-settings/nm-inotify-helper.h @@ -0,0 +1,54 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2008 Red Hat, Inc. + */ + +#ifndef __INOTIFY_HELPER_H__ +#define __INOTIFY_HELPER_H__ + +#include +#include +#include + +#define NM_TYPE_INOTIFY_HELPER (nm_inotify_helper_get_type ()) +#define NM_INOTIFY_HELPER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_INOTIFY_HELPER, NMInotifyHelper)) +#define NM_INOTIFY_HELPER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_INOTIFY_HELPER, NMInotifyHelperClass)) +#define NM_IS_INOTIFY_HELPER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_INOTIFY_HELPER)) +#define NM_IS_INOTIFY_HELPER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_INOTIFY_HELPER)) +#define NM_INOTIFY_HELPER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_INOTIFY_HELPER, NMInotifyHelperClass)) + +typedef struct { + GObject parent; +} NMInotifyHelper; + +typedef struct { + GObjectClass parent; + + /* signals */ + void (* event) (NMInotifyHelper *helper, struct inotify_event *evt, const char *filename); +} NMInotifyHelperClass; + +GType nm_inotify_helper_get_type (void); + +NMInotifyHelper * nm_inotify_helper_get (void); + +int nm_inotify_helper_add_watch (NMInotifyHelper *helper, const char *path); + +void nm_inotify_helper_remove_watch (NMInotifyHelper *helper, int wd); + +#endif /* __INOTIFY_HELPER_H__ */ diff --git a/src/system-settings/nm-polkit-helpers.c b/src/system-settings/nm-polkit-helpers.c new file mode 100644 index 0000000000..496a6f7ed1 --- /dev/null +++ b/src/system-settings/nm-polkit-helpers.c @@ -0,0 +1,148 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2008 Novell, Inc. + * (C) Copyright 2008 Red Hat, Inc. + */ + +#include +#include "nm-polkit-helpers.h" +#include "nm-system-config-error.h" + +static gboolean +pk_io_watch_have_data (GIOChannel *channel, GIOCondition condition, gpointer user_data) +{ + int fd; + PolKitContext *pk_context = (PolKitContext *) user_data; + + fd = g_io_channel_unix_get_fd (channel); + polkit_context_io_func (pk_context, fd); + + return TRUE; +} + +static int +pk_io_add_watch (PolKitContext *pk_context, int fd) +{ + guint id = 0; + GIOChannel *channel; + + channel = g_io_channel_unix_new (fd); + if (channel == NULL) + goto out; + id = g_io_add_watch (channel, G_IO_IN, pk_io_watch_have_data, pk_context); + if (id == 0) { + g_io_channel_unref (channel); + goto out; + } + g_io_channel_unref (channel); + + out: + return id; +} + +static void +pk_io_remove_watch (PolKitContext *pk_context, int watch_id) +{ + g_source_remove (watch_id); +} + +PolKitContext * +create_polkit_context (GError **error) +{ + static PolKitContext *global_context = NULL; + PolKitError *pk_err = NULL; + + if (G_LIKELY (global_context)) + return polkit_context_ref (global_context); + + global_context = polkit_context_new (); + polkit_context_set_io_watch_functions (global_context, pk_io_add_watch, pk_io_remove_watch); + if (!polkit_context_init (global_context, &pk_err)) { + g_set_error (error, NM_SYSCONFIG_SETTINGS_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR_GENERAL, + "%s (%d): %s", + pk_err ? polkit_error_get_error_name (pk_err) : "(unknown)", + pk_err ? polkit_error_get_error_code (pk_err) : -1, + pk_err ? polkit_error_get_error_message (pk_err) : "(unknown)"); + if (pk_err) + polkit_error_free (pk_err); + + /* PK 0.6's polkit_context_init() unrefs the global_context on failure */ +#if (POLKIT_VERSION_MAJOR == 0) && (POLKIT_VERSION_MINOR >= 7) + polkit_context_unref (global_context); +#endif + global_context = NULL; + } + + return global_context; +} + +gboolean +check_polkit_privileges (DBusGConnection *dbus_connection, + PolKitContext *pol_ctx, + DBusGMethodInvocation *context, + GError **err) +{ + DBusError dbus_error; + char *sender; + PolKitCaller *pk_caller; + PolKitAction *pk_action; + PolKitResult pk_result; + + dbus_error_init (&dbus_error); + sender = dbus_g_method_get_sender (context); + pk_caller = polkit_caller_new_from_dbus_name (dbus_g_connection_get_connection (dbus_connection), + sender, + &dbus_error); + g_free (sender); + + if (dbus_error_is_set (&dbus_error)) { + *err = g_error_new (NM_SYSCONFIG_SETTINGS_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR_NOT_PRIVILEGED, + "Error getting information about caller: %s: %s", + dbus_error.name, dbus_error.message); + dbus_error_free (&dbus_error); + + if (pk_caller) + polkit_caller_unref (pk_caller); + + return FALSE; + } + + pk_action = polkit_action_new (); + polkit_action_set_action_id (pk_action, NM_SYSCONFIG_POLICY_ACTION); + +#if (POLKIT_VERSION_MAJOR == 0) && (POLKIT_VERSION_MINOR < 7) + pk_result = polkit_context_can_caller_do_action (pol_ctx, pk_action, pk_caller); +#else + pk_result = polkit_context_is_caller_authorized (pol_ctx, pk_action, pk_caller, TRUE, NULL); +#endif + polkit_caller_unref (pk_caller); + polkit_action_unref (pk_action); + + if (pk_result != POLKIT_RESULT_YES) { + *err = g_error_new (NM_SYSCONFIG_SETTINGS_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR_NOT_PRIVILEGED, + "%s %s", + NM_SYSCONFIG_POLICY_ACTION, + polkit_result_to_string_representation (pk_result)); + return FALSE; + } + + return TRUE; +} diff --git a/src/system-settings/nm-polkit-helpers.h b/src/system-settings/nm-polkit-helpers.h new file mode 100644 index 0000000000..1382648c13 --- /dev/null +++ b/src/system-settings/nm-polkit-helpers.h @@ -0,0 +1,37 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2008 Novell, Inc. + * (C) Copyright 2008 Red Hat, Inc. + */ + +#ifndef NM_POLKIT_HELPERS_H +#define NM_POLKIT_HELPERS_H + +#include +#include +#include + +#define NM_SYSCONFIG_POLICY_ACTION "org.freedesktop.network-manager-settings.system.modify" + +PolKitContext *create_polkit_context (GError **error); +gboolean check_polkit_privileges (DBusGConnection *dbus_connection, + PolKitContext *pol_ctx, + DBusGMethodInvocation *context, + GError **err); + +#endif /* NM_POLKIT_HELPERS_H */ diff --git a/src/system-settings/nm-sysconfig-connection.c b/src/system-settings/nm-sysconfig-connection.c new file mode 100644 index 0000000000..3ed0eda8f1 --- /dev/null +++ b/src/system-settings/nm-sysconfig-connection.c @@ -0,0 +1,346 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2008 Novell, Inc. + */ + +#include +#include "nm-sysconfig-connection.h" +#include "nm-system-config-error.h" +#include "nm-polkit-helpers.h" +#include "nm-dbus-glib-types.h" + +G_DEFINE_ABSTRACT_TYPE (NMSysconfigConnection, nm_sysconfig_connection, NM_TYPE_EXPORTED_CONNECTION) + +#define NM_SYSCONFIG_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \ + NM_TYPE_SYSCONFIG_CONNECTION, \ + NMSysconfigConnectionPrivate)) + +typedef struct { + DBusGConnection *dbus_connection; + PolKitContext *pol_ctx; + + DBusGProxy *proxy; +} NMSysconfigConnectionPrivate; + +static gboolean +update (NMExportedConnection *exported, + GHashTable *new_settings, + GError **err) +{ + NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (exported); + DBusGMethodInvocation *context; + + context = g_object_get_data (G_OBJECT (exported), NM_EXPORTED_CONNECTION_DBUS_METHOD_INVOCATION); + g_return_val_if_fail (context != NULL, FALSE); + + return check_polkit_privileges (priv->dbus_connection, priv->pol_ctx, context, err); +} + +static gboolean +do_delete (NMExportedConnection *exported, GError **err) +{ + NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (exported); + DBusGMethodInvocation *context; + + context = g_object_get_data (G_OBJECT (exported), NM_EXPORTED_CONNECTION_DBUS_METHOD_INVOCATION); + g_return_val_if_fail (context != NULL, FALSE); + + return check_polkit_privileges (priv->dbus_connection, priv->pol_ctx, context, err); +} + +static GValue * +string_to_gvalue (const char *str) +{ + GValue *val = g_slice_new0 (GValue); + + g_value_init (val, G_TYPE_STRING); + g_value_set_string (val, str); + return val; +} + +static void +copy_one_secret (gpointer key, gpointer value, gpointer user_data) +{ + const char *value_str = (const char *) value; + + if (value_str) { + g_hash_table_insert ((GHashTable *) user_data, + g_strdup ((char *) key), + string_to_gvalue (value_str)); + } +} + +static void +add_secrets (NMSetting *setting, + const char *key, + const GValue *value, + GParamFlags flags, + gpointer user_data) +{ + GHashTable *secrets = user_data; + + if (!(flags & NM_SETTING_PARAM_SECRET)) + return; + + if (G_VALUE_HOLDS_STRING (value)) { + const char *tmp; + + tmp = g_value_get_string (value); + if (tmp) + g_hash_table_insert (secrets, g_strdup (key), string_to_gvalue (tmp)); + } else if (G_VALUE_HOLDS (value, DBUS_TYPE_G_MAP_OF_STRING)) { + /* Flatten the string hash by pulling its keys/values out */ + g_hash_table_foreach (g_value_get_boxed (value), copy_one_secret, secrets); + } +} + +static void +destroy_gvalue (gpointer data) +{ + GValue *value = (GValue *) data; + + g_value_unset (value); + g_slice_free (GValue, value); +} + +GHashTable * +nm_sysconfig_connection_get_secrets (NMSysconfigConnection *self, + const gchar *setting_name, + const gchar **hints, + gboolean request_new, + GError **error) +{ + NMConnection *connection; + GHashTable *settings = NULL; + GHashTable *secrets = NULL; + NMSetting *setting; + + connection = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (self)); + setting = nm_connection_get_setting_by_name (connection, setting_name); + if (!setting) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "%s.%d - Connection didn't have requested setting '%s'.", + __FILE__, __LINE__, setting_name); + return NULL; + } + + /* Returned secrets are a{sa{sv}}; this is the outer a{s...} hash that + * will contain all the individual settings hashes. + */ + settings = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, (GDestroyNotify) g_hash_table_destroy); + + /* Add the secrets from this setting to the inner secrets hash for this setting */ + secrets = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, destroy_gvalue); + nm_setting_enumerate_values (setting, add_secrets, secrets); + + g_hash_table_insert (settings, g_strdup (setting_name), secrets); + return settings; +} + +typedef struct { + NMSysconfigConnection *self; + char *setting_name; + DBusGMethodInvocation *context; +} GetUnixUserInfo; + +static GetUnixUserInfo * +get_unix_user_info_new (NMSysconfigConnection *self, + const char *setting_name, + DBusGMethodInvocation *context) +{ + GetUnixUserInfo *info; + + g_return_val_if_fail (self != NULL, NULL); + g_return_val_if_fail (setting_name != NULL, NULL); + g_return_val_if_fail (context != NULL, NULL); + + info = g_malloc0 (sizeof (GetUnixUserInfo)); + info->self = self; + info->setting_name = g_strdup (setting_name); + info->context = context; + return info; +} + +static void +get_unix_user_info_free (gpointer user_data) +{ + GetUnixUserInfo *info = user_data; + + g_free (info->setting_name); + g_free (info); +} + +static void +get_unix_user_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data) +{ + GetUnixUserInfo *info = user_data; + NMSysconfigConnection *self; + NMSysconfigConnectionPrivate *priv; + GError *error = NULL; + guint32 requestor_uid = G_MAXUINT32; + GHashTable *secrets; + + g_return_if_fail (info != NULL); + + self = info->self; + priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self); + + if (!dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_UINT, &requestor_uid, G_TYPE_INVALID)) + goto error; + + /* Non-root users need PolicyKit authorization */ + if (requestor_uid != 0) { + if (!check_polkit_privileges (priv->dbus_connection, priv->pol_ctx, info->context, &error)) + goto error; + } + + secrets = nm_sysconfig_connection_get_secrets (self, info->setting_name, NULL, FALSE, &error); + if (secrets) { + /* success; return secrets to caller */ + dbus_g_method_return (info->context, secrets); + g_hash_table_destroy (secrets); + return; + } + + if (!error) { + /* Shouldn't happen, but... */ + g_set_error (&error, NM_SYSCONFIG_SETTINGS_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR_GENERAL, + "%s", "Could not get secrets from connection (unknown error ocurred)"); + } + +error: + dbus_g_method_return_error (info->context, error); + g_clear_error (&error); +} + +static void +service_get_secrets (NMExportedConnection *exported, + const gchar *setting_name, + const gchar **hints, + gboolean request_new, + DBusGMethodInvocation *context) +{ + NMSysconfigConnection *self = NM_SYSCONFIG_CONNECTION (exported); + NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self); + GetUnixUserInfo *info; + GError *error = NULL; + char *sender = NULL; + + sender = dbus_g_method_get_sender (context); + if (!sender) { + g_set_error (&error, NM_SYSCONFIG_SETTINGS_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR_GENERAL, + "%s", "Could not determine D-Bus requestor to authorize GetSecrets request"); + goto out; + } + + if (priv->proxy) + g_object_unref (priv->proxy); + + priv->proxy = dbus_g_proxy_new_for_name (priv->dbus_connection, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS); + if (!priv->proxy) { + g_set_error (&error, NM_SYSCONFIG_SETTINGS_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR_GENERAL, + "%s", "Could not connect to D-Bus to authorize GetSecrets request"); + goto out; + } + + info = get_unix_user_info_new (self, setting_name, context); + if (!info) { + g_set_error (&error, NM_SYSCONFIG_SETTINGS_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR_GENERAL, + "%s", "Not enough memory to authorize GetSecrets request"); + goto out; + } + + dbus_g_proxy_begin_call_with_timeout (priv->proxy, "GetConnectionUnixUser", + get_unix_user_cb, + info, + get_unix_user_info_free, + 5000, + G_TYPE_STRING, sender, + G_TYPE_INVALID); + +out: + if (error) { + dbus_g_method_return_error (context, error); + g_error_free (error); + } +} + +/* GObject */ + +static void +nm_sysconfig_connection_init (NMSysconfigConnection *self) +{ + NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self); + GError *err = NULL; + + priv->dbus_connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &err); + if (err) { + g_warning ("%s: error getting D-Bus connection: %s", + __func__, + (err && err->message) ? err->message : "(unknown)"); + g_error_free (err); + } + + priv->pol_ctx = create_polkit_context (&err); + if (!priv->pol_ctx) { + g_warning ("%s: error creating PolicyKit context: %s", + __func__, + (err && err->message) ? err->message : "(unknown)"); + } +} + +static void +dispose (GObject *object) +{ + NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (object); + + if (priv->proxy) + g_object_unref (priv->proxy); + + if (priv->pol_ctx) + polkit_context_unref (priv->pol_ctx); + + if (priv->dbus_connection) + dbus_g_connection_unref (priv->dbus_connection); + + G_OBJECT_CLASS (nm_sysconfig_connection_parent_class)->dispose (object); +} + +static void +nm_sysconfig_connection_class_init (NMSysconfigConnectionClass *sysconfig_connection_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (sysconfig_connection_class); + NMExportedConnectionClass *connection_class = NM_EXPORTED_CONNECTION_CLASS (sysconfig_connection_class); + + g_type_class_add_private (sysconfig_connection_class, sizeof (NMSysconfigConnectionPrivate)); + + /* Virtual methods */ + object_class->dispose = dispose; + + connection_class->update = update; + connection_class->do_delete = do_delete; + connection_class->service_get_secrets = service_get_secrets; +} diff --git a/src/system-settings/nm-sysconfig-connection.h b/src/system-settings/nm-sysconfig-connection.h new file mode 100644 index 0000000000..694cc58e14 --- /dev/null +++ b/src/system-settings/nm-sysconfig-connection.h @@ -0,0 +1,54 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2008 Novell, Inc. + */ + +#ifndef NM_SYSCONFIG_CONNECTION_H +#define NM_SYSCONFIG_CONNECTION_H + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_SYSCONFIG_CONNECTION (nm_sysconfig_connection_get_type ()) +#define NM_SYSCONFIG_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SYSCONFIG_CONNECTION, NMSysconfigConnection)) +#define NM_SYSCONFIG_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SYSCONFIG_CONNECTION, NMSysconfigConnectionClass)) +#define NM_IS_SYSCONFIG_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SYSCONFIG_CONNECTION)) +#define NM_IS_SYSCONFIG_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_SYSCONFIG_CONNECTION)) +#define NM_SYSCONFIG_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SYSCONFIG_CONNECTION, NMSysconfigConnectionClass)) + +typedef struct { + NMExportedConnection parent; +} NMSysconfigConnection; + +typedef struct { + NMExportedConnectionClass parent; +} NMSysconfigConnectionClass; + +GType nm_sysconfig_connection_get_type (void); + +/* Only for internal NM usage */ +GHashTable *nm_sysconfig_connection_get_secrets (NMSysconfigConnection *self, + const gchar *setting_name, + const gchar **hints, + gboolean request_new, + GError **error); + +G_END_DECLS + +#endif /* NM_SYSCONFIG_CONNECTION_H */ diff --git a/src/system-settings/nm-sysconfig-settings.c b/src/system-settings/nm-sysconfig-settings.c new file mode 100644 index 0000000000..7d139e6e14 --- /dev/null +++ b/src/system-settings/nm-sysconfig-settings.c @@ -0,0 +1,848 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * Søren Sandmann + * Dan Williams + * Tambet Ingo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2007 - 2008 Red Hat, Inc. + * (C) Copyright 2008 Novell, Inc. + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include "nm-dbus-glib-types.h" +#include "nm-sysconfig-settings.h" +#include "nm-sysconfig-connection.h" +#include "nm-dbus-manager.h" +#include "nm-polkit-helpers.h" +#include "nm-system-config-error.h" +#include "nm-utils.h" + + +/* LINKER CRACKROCK */ +#define EXPORT(sym) void * __export_##sym = &sym; + +#include "nm-inotify-helper.h" +EXPORT(nm_inotify_helper_get_type) +EXPORT(nm_inotify_helper_get) +EXPORT(nm_inotify_helper_add_watch) +EXPORT(nm_inotify_helper_remove_watch) + +EXPORT(nm_sysconfig_connection_get_type) +/* END LINKER CRACKROCK */ + + +static gboolean +impl_settings_add_connection (NMSysconfigSettings *self, GHashTable *hash, DBusGMethodInvocation *context); + +static gboolean +impl_settings_save_hostname (NMSysconfigSettings *self, const char *hostname, DBusGMethodInvocation *context); + +#include "nm-settings-system-glue.h" + +static void unmanaged_devices_changed (NMSystemConfigInterface *config, gpointer user_data); + +typedef struct { + NMDBusManager *dbus_mgr; + PolKitContext *pol_ctx; + + GSList *plugins; + gboolean connections_loaded; + GHashTable *connections; + GSList *unmanaged_specs; + char *orig_hostname; +} NMSysconfigSettingsPrivate; + +G_DEFINE_TYPE (NMSysconfigSettings, nm_sysconfig_settings, NM_TYPE_SETTINGS); + +#define NM_SYSCONFIG_SETTINGS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SYSCONFIG_SETTINGS, NMSysconfigSettingsPrivate)) + +enum { + PROPERTIES_CHANGED, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +enum { + PROP_0, + PROP_UNMANAGED_SPECS, + PROP_HOSTNAME, + PROP_CAN_MODIFY, + + LAST_PROP +}; + +static void +load_connections (NMSysconfigSettings *self) +{ + NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + GSList *iter; + + if (priv->connections_loaded) + return; + + for (iter = priv->plugins; iter; iter = g_slist_next (iter)) { + NMSystemConfigInterface *plugin = NM_SYSTEM_CONFIG_INTERFACE (iter->data); + GSList *plugin_connections; + GSList *elt; + + plugin_connections = nm_system_config_interface_get_connections (plugin); + + // FIXME: ensure connections from plugins loaded with a lower priority + // get rejected when they conflict with connections from a higher + // priority plugin. + + for (elt = plugin_connections; elt; elt = g_slist_next (elt)) + nm_sysconfig_settings_add_connection (self, NM_EXPORTED_CONNECTION (elt->data), TRUE); + + g_slist_free (plugin_connections); + } + + priv->connections_loaded = TRUE; + + /* FIXME: Bad hack */ + unmanaged_devices_changed (NULL, self); +} + +static void +hash_keys_to_slist (gpointer key, gpointer val, gpointer user_data) +{ + GSList **list = (GSList **) user_data; + + *list = g_slist_prepend (*list, key); +} + +GSList * +nm_sysconfig_settings_list_connections (NMSysconfigSettings *self) +{ + NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + GSList *list = NULL; + + load_connections (self); + + g_hash_table_foreach (priv->connections, hash_keys_to_slist, &list); + + return list; +} + +static GSList * +list_connections (NMSettings *settings) +{ + return nm_sysconfig_settings_list_connections (NM_SYSCONFIG_SETTINGS (settings)); +} + +typedef struct { + const char *path; + NMSysconfigConnection *found; +} FindConnectionInfo; + +static void +find_by_path (gpointer key, gpointer data, gpointer user_data) +{ + FindConnectionInfo *info = user_data; + NMSysconfigConnection *exported = NM_SYSCONFIG_CONNECTION (data); + const char *path; + + if (!info->found) { + NMConnection *connection; + + connection = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (exported)); + g_assert (connection); + path = nm_connection_get_path (connection); + g_assert (path); + if (!strcmp (path, info->path)) + info->found = exported; + } +} + +NMSysconfigConnection * +nm_sysconfig_settings_get_connection_by_path (NMSysconfigSettings *self, + const char *path) +{ + NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + FindConnectionInfo info; + + info.path = path; + info.found = NULL; + g_hash_table_foreach (priv->connections, find_by_path, &info); + return info.found; +} + +static void +clear_unmanaged_specs (NMSysconfigSettings *self) +{ + NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + + g_slist_foreach (priv->unmanaged_specs, (GFunc) g_free, NULL); + g_slist_free (priv->unmanaged_specs); + priv->unmanaged_specs = NULL; +} + +static void +finalize (GObject *object) +{ + NMSysconfigSettings *self = NM_SYSCONFIG_SETTINGS (object); + NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + + g_hash_table_destroy (priv->connections); + + clear_unmanaged_specs (self); + + g_slist_foreach (priv->plugins, (GFunc) g_object_unref, NULL); + g_slist_free (priv->plugins); + + if (priv->pol_ctx) + polkit_context_unref (priv->pol_ctx); + + g_object_unref (priv->dbus_mgr); + + g_free (priv->orig_hostname); + + G_OBJECT_CLASS (nm_sysconfig_settings_parent_class)->finalize (object); +} + +static char* +uscore_to_wincaps (const char *uscore) +{ + const char *p; + GString *str; + gboolean last_was_uscore; + + last_was_uscore = TRUE; + + str = g_string_new (NULL); + p = uscore; + while (p && *p) { + if (*p == '-' || *p == '_') + last_was_uscore = TRUE; + else { + if (last_was_uscore) { + g_string_append_c (str, g_ascii_toupper (*p)); + last_was_uscore = FALSE; + } else + g_string_append_c (str, *p); + } + ++p; + } + + return g_string_free (str, FALSE); +} + +static void +notify (GObject *object, GParamSpec *pspec) +{ + GValue *value; + GHashTable *hash; + + value = g_slice_new0 (GValue); + hash = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, NULL); + + g_value_init (value, pspec->value_type); + g_object_get_property (object, pspec->name, value); + g_hash_table_insert (hash, uscore_to_wincaps (pspec->name), value); + g_signal_emit (object, signals[PROPERTIES_CHANGED], 0, hash); + g_hash_table_destroy (hash); + g_value_unset (value); + g_slice_free (GValue, value); +} + +const GSList * +nm_sysconfig_settings_get_unmanaged_specs (NMSysconfigSettings *self) +{ + NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + + load_connections (self); + return priv->unmanaged_specs; +} + +NMSystemConfigInterface * +nm_sysconfig_settings_get_plugin (NMSysconfigSettings *self, + guint32 capability) +{ + NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + GSList *iter; + + g_return_val_if_fail (self != NULL, NULL); + + /* Do any of the plugins support setting the hostname? */ + for (iter = priv->plugins; iter; iter = iter->next) { + NMSystemConfigInterfaceCapabilities caps = NM_SYSTEM_CONFIG_INTERFACE_CAP_NONE; + + g_object_get (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES, &caps, NULL); + if (caps & capability) + return NM_SYSTEM_CONFIG_INTERFACE (iter->data); + } + + return NULL; +} + +char * +nm_sysconfig_settings_get_hostname (NMSysconfigSettings *self) +{ + NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + GSList *iter; + char *hostname = NULL; + + /* Hostname returned is the hostname returned from the first plugin + * that provides one. + */ + for (iter = priv->plugins; iter; iter = iter->next) { + NMSystemConfigInterfaceCapabilities caps = NM_SYSTEM_CONFIG_INTERFACE_CAP_NONE; + + g_object_get (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES, &caps, NULL); + if (caps & NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME) { + g_object_get (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME, &hostname, NULL); + if (hostname && strlen (hostname)) + return hostname; + g_free (hostname); + } + } + + /* If no plugin provided a hostname, try the original hostname of the machine */ + if (priv->orig_hostname) + hostname = g_strdup (priv->orig_hostname); + + return hostname; +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + NMSysconfigSettings *self = NM_SYSCONFIG_SETTINGS (object); + const GSList *specs, *iter; + GSList *copy = NULL; + + switch (prop_id) { + case PROP_UNMANAGED_SPECS: + specs = nm_sysconfig_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); + break; + case PROP_HOSTNAME: + g_value_take_string (value, nm_sysconfig_settings_get_hostname (self)); + + /* Don't ever pass NULL through D-Bus */ + if (!g_value_get_string (value)) + g_value_set_static_string (value, ""); + break; + case PROP_CAN_MODIFY: + g_value_set_boolean (value, !!nm_sysconfig_settings_get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_sysconfig_settings_class_init (NMSysconfigSettingsClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + NMSettingsClass *settings_class = NM_SETTINGS_CLASS (class); + + g_type_class_add_private (class, sizeof (NMSysconfigSettingsPrivate)); + + /* virtual methods */ + object_class->notify = notify; + object_class->get_property = get_property; + object_class->finalize = finalize; + settings_class->list_connections = list_connections; + + /* properties */ + g_object_class_install_property + (object_class, PROP_UNMANAGED_SPECS, + g_param_spec_boxed (NM_SYSCONFIG_SETTINGS_UNMANAGED_SPECS, + "Unamanged device specs", + "Unmanaged device specs", + DBUS_TYPE_G_LIST_OF_STRING, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_HOSTNAME, + g_param_spec_string (NM_SYSCONFIG_SETTINGS_HOSTNAME, + "Hostname", + "Hostname", + NULL, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_CAN_MODIFY, + g_param_spec_boolean (NM_SYSCONFIG_SETTINGS_CAN_MODIFY, + "CanModify", + "Can modify", + FALSE, + G_PARAM_READABLE)); + + /* signals */ + signals[PROPERTIES_CHANGED] = + g_signal_new ("properties-changed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMSysconfigSettingsClass, properties_changed), + NULL, NULL, + g_cclosure_marshal_VOID__BOXED, + G_TYPE_NONE, 1, DBUS_TYPE_G_MAP_OF_VARIANT); + + dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (settings_class), + &dbus_glib_nm_settings_system_object_info); + + dbus_g_error_domain_register (NM_SYSCONFIG_SETTINGS_ERROR, + NM_DBUS_IFACE_SETTINGS_SYSTEM, + NM_TYPE_SYSCONFIG_SETTINGS_ERROR); +} + +static void +nm_sysconfig_settings_init (NMSysconfigSettings *self) +{ + NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + char hostname[HOST_NAME_MAX + 2]; + GError *error = NULL; + + priv->connections = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, NULL); + + priv->pol_ctx = create_polkit_context (&error); + if (!priv->pol_ctx) { + g_warning ("%s: failed to create PolicyKit context: %s", + __func__, + (error && error->message) ? error->message : "(unknown)"); + } + + /* Grab hostname on startup and use that if no plugins provide one */ + memset (hostname, 0, sizeof (hostname)); + if (gethostname (&hostname[0], HOST_NAME_MAX) == 0) { + /* only cache it if it's a valid hostname */ + if (strlen (hostname) && strcmp (hostname, "localhost") && strcmp (hostname, "localhost.localdomain")) + priv->orig_hostname = g_strdup (hostname); + } +} + +static void +plugin_connection_added (NMSystemConfigInterface *config, + NMExportedConnection *connection, + gpointer user_data) +{ + nm_sysconfig_settings_add_connection (NM_SYSCONFIG_SETTINGS (user_data), connection, TRUE); +} + +static gboolean +find_unmanaged_device (NMSysconfigSettings *self, const char *needle) +{ + NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + GSList *iter; + + for (iter = priv->unmanaged_specs; iter; iter = g_slist_next (iter)) { + if (!strcmp ((const char *) iter->data, needle)) + return TRUE; + } + return FALSE; +} + +static void +unmanaged_devices_changed (NMSystemConfigInterface *config, + gpointer user_data) +{ + NMSysconfigSettings *self = NM_SYSCONFIG_SETTINGS (user_data); + NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + GSList *iter; + + clear_unmanaged_specs (self); + + /* Ask all the plugins for their unmanaged devices */ + for (iter = priv->plugins; iter; iter = g_slist_next (iter)) { + GSList *specs, *specs_iter; + + specs = nm_system_config_interface_get_unmanaged_specs (NM_SYSTEM_CONFIG_INTERFACE (iter->data)); + for (specs_iter = specs; specs_iter; specs_iter = specs_iter->next) { + if (!find_unmanaged_device (self, (const char *) specs_iter->data)) { + priv->unmanaged_specs = g_slist_prepend (priv->unmanaged_specs, specs_iter->data); + } else + g_free (specs_iter->data); + } + + g_slist_free (specs); + } + + g_object_notify (G_OBJECT (self), NM_SYSCONFIG_SETTINGS_UNMANAGED_SPECS); +} + +static void +hostname_changed (NMSystemConfigInterface *config, + GParamSpec *pspec, + gpointer user_data) +{ + g_object_notify (G_OBJECT (user_data), NM_SYSCONFIG_SETTINGS_HOSTNAME); +} + +static void +add_plugin (NMSysconfigSettings *self, NMSystemConfigInterface *plugin) +{ + NMSysconfigSettingsPrivate *priv; + char *pname = NULL; + char *pinfo = NULL; + + g_return_if_fail (NM_IS_SYSCONFIG_SETTINGS (self)); + g_return_if_fail (NM_IS_SYSTEM_CONFIG_INTERFACE (plugin)); + + priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + + priv->plugins = g_slist_append (priv->plugins, g_object_ref (plugin)); + + g_signal_connect (plugin, "connection-added", G_CALLBACK (plugin_connection_added), self); + g_signal_connect (plugin, "unmanaged-devices-changed", G_CALLBACK (unmanaged_devices_changed), self); + g_signal_connect (plugin, "notify::hostname", G_CALLBACK (hostname_changed), self); + + nm_system_config_interface_init (plugin, NULL); + + g_object_get (G_OBJECT (plugin), + NM_SYSTEM_CONFIG_INTERFACE_NAME, &pname, + NM_SYSTEM_CONFIG_INTERFACE_INFO, &pinfo, + NULL); + + g_message ("Loaded plugin %s: %s", pname, pinfo); + g_free (pname); + g_free (pinfo); +} + +static GObject * +find_plugin (GSList *list, const char *pname) +{ + GSList *iter; + GObject *obj = NULL; + + g_return_val_if_fail (pname != NULL, FALSE); + + for (iter = list; iter && !obj; iter = g_slist_next (iter)) { + NMSystemConfigInterface *plugin = NM_SYSTEM_CONFIG_INTERFACE (iter->data); + char *list_pname = NULL; + + g_object_get (G_OBJECT (plugin), + NM_SYSTEM_CONFIG_INTERFACE_NAME, + &list_pname, + NULL); + if (list_pname && !strcmp (pname, list_pname)) + obj = G_OBJECT (plugin); + + g_free (list_pname); + } + + return obj; +} + +static gboolean +load_plugins (NMSysconfigSettings *self, const char *plugins, GError **error) +{ + GSList *list = NULL; + char **plist; + char **iter; + gboolean success = TRUE; + + plist = g_strsplit (plugins, ",", 0); + if (!plist) + return FALSE; + + for (iter = plist; *iter; iter++) { + GModule *plugin; + char *full_name, *path; + const char *pname = *iter; + GObject *obj; + GObject * (*factory_func) (void); + + /* ifcfg-fedora was renamed ifcfg-rh; handle old configs here */ + if (!strcmp (pname, "ifcfg-fedora")) + pname = "ifcfg-rh"; + + obj = find_plugin (list, pname); + if (obj) + continue; + + full_name = g_strdup_printf ("nm-settings-plugin-%s", pname); + path = g_module_build_path (PLUGINDIR, full_name); + + plugin = g_module_open (path, G_MODULE_BIND_LOCAL); + if (!plugin) { + g_set_error (error, 0, 0, + "Could not load plugin '%s': %s", + pname, g_module_error ()); + g_free (full_name); + g_free (path); + success = FALSE; + break; + } + + g_free (full_name); + g_free (path); + + if (!g_module_symbol (plugin, "nm_system_config_factory", (gpointer) (&factory_func))) { + g_set_error (error, 0, 0, + "Could not find plugin '%s' factory function.", + pname); + success = FALSE; + break; + } + + obj = (*factory_func) (); + if (!obj || !NM_IS_SYSTEM_CONFIG_INTERFACE (obj)) { + g_set_error (error, 0, 0, + "Plugin '%s' returned invalid system config object.", + pname); + success = FALSE; + break; + } + + g_module_make_resident (plugin); + g_object_weak_ref (obj, (GWeakNotify) g_module_close, plugin); + add_plugin (self, NM_SYSTEM_CONFIG_INTERFACE (obj)); + list = g_slist_append (list, obj); + } + + g_strfreev (plist); + + g_slist_foreach (list, (GFunc) g_object_unref, NULL); + g_slist_free (list); + + return success; +} + +static void +connection_removed (NMExportedConnection *connection, + gpointer user_data) +{ + NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (user_data); + + g_hash_table_remove (priv->connections, connection); +} + +void +nm_sysconfig_settings_add_connection (NMSysconfigSettings *self, + NMExportedConnection *connection, + gboolean do_export) +{ + NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + + g_return_if_fail (NM_IS_SYSCONFIG_SETTINGS (self)); + g_return_if_fail (NM_IS_EXPORTED_CONNECTION (connection)); + + if (g_hash_table_lookup (priv->connections, connection)) + /* A plugin is lying to us. */ + return; + + g_hash_table_insert (priv->connections, g_object_ref (connection), GINT_TO_POINTER (1)); + g_signal_connect (connection, "removed", G_CALLBACK (connection_removed), self); + + if (do_export) { + DBusGConnection *g_connection; + + g_connection = nm_dbus_manager_get_connection (priv->dbus_mgr); + nm_exported_connection_register_object (connection, NM_CONNECTION_SCOPE_SYSTEM, g_connection); + nm_settings_signal_new_connection (NM_SETTINGS (self), connection); + } +} + +void +nm_sysconfig_settings_remove_connection (NMSysconfigSettings *self, + NMExportedConnection *connection, + gboolean do_signal) +{ + NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + + g_return_if_fail (NM_IS_SYSCONFIG_SETTINGS (self)); + g_return_if_fail (NM_IS_EXPORTED_CONNECTION (connection)); + + if (g_hash_table_lookup (priv->connections, connection)) { + nm_exported_connection_signal_removed (connection); + g_hash_table_remove (priv->connections, connection); + } +} + +gboolean +nm_sysconfig_settings_add_new_connection (NMSysconfigSettings *self, + GHashTable *hash, + GError **error) +{ + NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + NMConnection *connection; + GError *tmp_error = NULL, *last_error = NULL; + GSList *iter; + gboolean success = FALSE; + + connection = nm_connection_new_from_hash (hash, &tmp_error); + if (!connection) { + /* Invalid connection hash */ + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid connection: '%s' / '%s' invalid: %d", + tmp_error ? g_type_name (nm_connection_lookup_setting_type_by_quark (tmp_error->domain)) : "(unknown)", + tmp_error ? tmp_error->message : "(unknown)", tmp_error ? tmp_error->code : -1); + g_clear_error (&tmp_error); + return FALSE; + } + + /* Here's how it works: + 1) plugin writes a connection. + 2) plugin notices that a new connection is available for reading. + 3) plugin reads the new connection (the one it wrote in 1) and emits 'connection-added' signal. + 4) NMSysconfigSettings receives the signal and adds it to it's connection list. + */ + + for (iter = priv->plugins; iter && !success; iter = iter->next) { + success = nm_system_config_interface_add_connection (NM_SYSTEM_CONFIG_INTERFACE (iter->data), + connection, &tmp_error); + g_clear_error (&last_error); + if (!success) + last_error = tmp_error; + } + + g_object_unref (connection); + + if (!success) { + g_set_error (error, NM_SYSCONFIG_SETTINGS_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR_ADD_FAILED, + "Saving connection failed: (%d) %s", + last_error ? last_error->code : -1, + last_error && last_error->message ? last_error->message : "(unknown)"); + g_clear_error (&last_error); + } + + return success; +} + +static gboolean +impl_settings_add_connection (NMSysconfigSettings *self, + GHashTable *hash, + DBusGMethodInvocation *context) +{ + NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + DBusGConnection *g_connection; + GError *err = NULL; + + /* Do any of the plugins support adding? */ + if (!nm_sysconfig_settings_get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS)) { + err = g_error_new (NM_SYSCONFIG_SETTINGS_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR_ADD_NOT_SUPPORTED, + "%s", "None of the registered plugins support add."); + goto out; + } + + g_connection = nm_dbus_manager_get_connection (priv->dbus_mgr); + if (!check_polkit_privileges (g_connection, priv->pol_ctx, context, &err)) + goto out; + + nm_sysconfig_settings_add_new_connection (self, hash, &err); + + out: + if (err) { + dbus_g_method_return_error (context, err); + g_error_free (err); + return FALSE; + } else { + dbus_g_method_return (context); + return TRUE; + } +} + +static gboolean +impl_settings_save_hostname (NMSysconfigSettings *self, + const char *hostname, + DBusGMethodInvocation *context) +{ + NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + GError *err = NULL; + GSList *iter; + gboolean success = FALSE; + DBusGConnection *g_connection; + + /* Do any of the plugins support setting the hostname? */ + if (!nm_sysconfig_settings_get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME)) { + err = g_error_new (NM_SYSCONFIG_SETTINGS_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR_SAVE_HOSTNAME_NOT_SUPPORTED, + "%s", "None of the registered plugins support setting the hostname."); + goto out; + } + + g_connection = nm_dbus_manager_get_connection (priv->dbus_mgr); + if (!check_polkit_privileges (g_connection, priv->pol_ctx, context, &err)) + goto out; + + /* Set the hostname in all plugins */ + for (iter = priv->plugins; iter; iter = iter->next) { + NMSystemConfigInterfaceCapabilities caps = NM_SYSTEM_CONFIG_INTERFACE_CAP_NONE; + + g_object_get (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES, &caps, NULL); + if (caps & NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME) { + g_object_set (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME, hostname, NULL); + success = TRUE; + } + } + + if (!success) { + err = g_error_new (NM_SYSCONFIG_SETTINGS_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR_SAVE_HOSTNAME_FAILED, + "%s", "Saving the hostname failed."); + } + + out: + if (err) { + dbus_g_method_return_error (context, err); + g_error_free (err); + return FALSE; + } else { + dbus_g_method_return (context); + return TRUE; + } +} + +NMSysconfigSettings * +nm_sysconfig_settings_new (const char *plugins, GError **error) +{ + NMSysconfigSettings *self; + NMSysconfigSettingsPrivate *priv; + DBusGConnection *g_connection; + + self = g_object_new (NM_TYPE_SYSCONFIG_SETTINGS, NULL); + if (!self) + return NULL; + + priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + + priv->dbus_mgr = nm_dbus_manager_get (); + g_assert (priv->dbus_mgr); + + g_connection = nm_dbus_manager_get_connection (priv->dbus_mgr); + dbus_g_connection_register_g_object (g_connection, NM_DBUS_PATH_SETTINGS, G_OBJECT (self)); + + if (plugins) { + /* Load the plugins; fail if a plugin is not found. */ + if (!load_plugins (self, plugins, error)) { + g_object_unref (self); + return NULL; + } + } + + return self; +} + diff --git a/src/system-settings/nm-sysconfig-settings.h b/src/system-settings/nm-sysconfig-settings.h new file mode 100644 index 0000000000..f3b0a458d1 --- /dev/null +++ b/src/system-settings/nm-sysconfig-settings.h @@ -0,0 +1,94 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * Søren Sandmann + * Dan Williams + * Tambet Ingo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2007 - 2009 Red Hat, Inc. + * (C) Copyright 2008 Novell, Inc. + */ + +#ifndef __NM_SYSCONFIG_SETTINGS_H__ +#define __NM_SYSCONFIG_SETTINGS_H__ + +#include +#include + +#include "nm-sysconfig-connection.h" +#include "nm-system-config-interface.h" + +typedef struct _NMSysconfigSettings NMSysconfigSettings; +typedef struct _NMSysconfigSettingsClass NMSysconfigSettingsClass; + +#define NM_TYPE_SYSCONFIG_SETTINGS (nm_sysconfig_settings_get_type ()) +#define NM_SYSCONFIG_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SYSCONFIG_SETTINGS, NMSysconfigSettings)) +#define NM_SYSCONFIG_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SYSCONFIG_SETTINGS, NMSysconfigSettingsClass)) +#define NM_IS_SYSCONFIG_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SYSCONFIG_SETTINGS)) +#define NM_IS_SYSCONFIG_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SYSCONFIG_SETTINGS)) +#define NM_SYSCONFIG_SETTINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SYSCONFIG_SETTINGS, NMSysconfigSettingsClass)) + +#define NM_SYSCONFIG_SETTINGS_UNMANAGED_SPECS "unmanaged-specs" +#define NM_SYSCONFIG_SETTINGS_HOSTNAME "hostname" +#define NM_SYSCONFIG_SETTINGS_CAN_MODIFY "can-modify" + +struct _NMSysconfigSettings +{ + NMSettings parent_instance; +}; + +struct _NMSysconfigSettingsClass +{ + NMSettingsClass parent_class; + + /* Signals */ + void (*properties_changed) (NMSysconfigSettings *settings, GHashTable *properties); +}; + +GType nm_sysconfig_settings_get_type (void); + +NMSysconfigSettings *nm_sysconfig_settings_new (const char *plugins, GError **error); + +/* Registers an exising connection with the settings service */ +void nm_sysconfig_settings_add_connection (NMSysconfigSettings *settings, + NMExportedConnection *connection, + gboolean do_export); + +void nm_sysconfig_settings_remove_connection (NMSysconfigSettings *settings, + NMExportedConnection *connection, + gboolean do_signal); + +NMSystemConfigInterface *nm_sysconfig_settings_get_plugin (NMSysconfigSettings *self, + guint32 capability); + +/* Adds a new connection from a hash of that connection's settings, + * potentially saving the new connection to persistent storage. + */ +gboolean nm_sysconfig_settings_add_new_connection (NMSysconfigSettings *self, + GHashTable *hash, + GError **error); + +const GSList *nm_sysconfig_settings_get_unmanaged_specs (NMSysconfigSettings *self); + +char *nm_sysconfig_settings_get_hostname (NMSysconfigSettings *self); + +GSList *nm_sysconfig_settings_list_connections (NMSysconfigSettings *self); + +NMSysconfigConnection *nm_sysconfig_settings_get_connection_by_path (NMSysconfigSettings *self, + const char *path); + +#endif /* __NM_SYSCONFIG_SETTINGS_H__ */ diff --git a/src/system-settings/nm-system-config-error.c b/src/system-settings/nm-system-config-error.c new file mode 100644 index 0000000000..13d47462f9 --- /dev/null +++ b/src/system-settings/nm-system-config-error.c @@ -0,0 +1,59 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2008 Novell, Inc. + * Copyright (C) 2008 Red Hat, Inc. + */ + +#include "nm-system-config-error.h" + +GQuark +nm_sysconfig_settings_error_quark (void) +{ + static GQuark ret = 0; + + if (ret == 0) + ret = g_quark_from_static_string ("nm_sysconfig_settings_error"); + + return ret; +} + +#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } + +GType +nm_sysconfig_settings_error_get_type (void) +{ + static GType etype = 0; + + if (etype == 0) { + static const GEnumValue values[] = { + ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_GENERAL, "GeneralError"), + ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_NOT_PRIVILEGED, "NotPrivileged"), + ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_ADD_NOT_SUPPORTED, "AddNotSupported"), + ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_UPDATE_NOT_SUPPORTED, "UpdateNotSupported"), + ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_DELETE_NOT_SUPPORTED, "DeleteNotSupported"), + ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_ADD_FAILED, "AddFailed"), + ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_SAVE_HOSTNAME_NOT_SUPPORTED, "SaveHostnameNotSupported"), + ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_SAVE_HOSTNAME_FAILED, "SaveHostnameFailed"), + { 0, 0, 0 } + }; + + etype = g_enum_register_static ("NMSysconfigSettingsError", values); + } + + return etype; +} diff --git a/src/system-settings/nm-system-config-error.h b/src/system-settings/nm-system-config-error.h new file mode 100644 index 0000000000..63896fcd09 --- /dev/null +++ b/src/system-settings/nm-system-config-error.h @@ -0,0 +1,45 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2008 Novell, Inc. + * Copyright (C) 2008 Red Hat, Inc. + */ + +#ifndef NM_SYSTEM_CONFIG_ERROR_H +#define NM_SYSTEM_CONFIG_ERROR_H + +#include +#include + +enum { + NM_SYSCONFIG_SETTINGS_ERROR_GENERAL = 0, + NM_SYSCONFIG_SETTINGS_ERROR_NOT_PRIVILEGED, + NM_SYSCONFIG_SETTINGS_ERROR_ADD_NOT_SUPPORTED, + NM_SYSCONFIG_SETTINGS_ERROR_UPDATE_NOT_SUPPORTED, + NM_SYSCONFIG_SETTINGS_ERROR_DELETE_NOT_SUPPORTED, + NM_SYSCONFIG_SETTINGS_ERROR_ADD_FAILED, + NM_SYSCONFIG_SETTINGS_ERROR_SAVE_HOSTNAME_NOT_SUPPORTED, + NM_SYSCONFIG_SETTINGS_ERROR_SAVE_HOSTNAME_FAILED, +}; + +#define NM_SYSCONFIG_SETTINGS_ERROR (nm_sysconfig_settings_error_quark ()) +#define NM_TYPE_SYSCONFIG_SETTINGS_ERROR (nm_sysconfig_settings_error_get_type ()) + +GQuark nm_sysconfig_settings_error_quark (void); +GType nm_sysconfig_settings_error_get_type (void); + +#endif /* NM_SYSTEM_CONFIG_ERROR_H */ diff --git a/src/system-settings/nm-system-config-interface.c b/src/system-settings/nm-system-config-interface.c new file mode 100644 index 0000000000..2f33e59069 --- /dev/null +++ b/src/system-settings/nm-system-config-interface.c @@ -0,0 +1,163 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2007 - 2008 Red Hat, Inc. + * Copyright (C) 2008 Novell, Inc. + */ + +#include "nm-system-config-interface.h" + +static void +interface_init (gpointer g_iface) +{ + GType iface_type = G_TYPE_FROM_INTERFACE (g_iface); + static gboolean initialized = FALSE; + + if (initialized) + return; + + /* Properties */ + g_object_interface_install_property + (g_iface, + g_param_spec_string (NM_SYSTEM_CONFIG_INTERFACE_NAME, + "Name", + "Plugin name", + NULL, + G_PARAM_READABLE)); + + g_object_interface_install_property + (g_iface, + g_param_spec_string (NM_SYSTEM_CONFIG_INTERFACE_INFO, + "Info", + "Plugin information", + NULL, + G_PARAM_READABLE)); + + g_object_interface_install_property + (g_iface, + g_param_spec_uint (NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES, + "Capabilities", + "Plugin capabilties", + NM_SYSTEM_CONFIG_INTERFACE_CAP_NONE, + NM_SYSTEM_CONFIG_INTERFACE_CAP_LAST - 1, + NM_SYSTEM_CONFIG_INTERFACE_CAP_NONE, + G_PARAM_READABLE)); + + g_object_interface_install_property + (g_iface, + g_param_spec_string (NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME, + "Hostname", + "Configured hostname", + NULL, + G_PARAM_READWRITE)); + + /* Signals */ + g_signal_new ("connection-added", + iface_type, + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMSystemConfigInterface, connection_added), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, + NM_TYPE_EXPORTED_CONNECTION); + + g_signal_new ("unmanaged-devices-changed", + iface_type, + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMSystemConfigInterface, unmanaged_devices_changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + initialized = TRUE; +} + + +GType +nm_system_config_interface_get_type (void) +{ + static GType system_config_interface_type = 0; + + if (!system_config_interface_type) { + const GTypeInfo system_config_interface_info = { + sizeof (NMSystemConfigInterface), /* class_size */ + interface_init, /* base_init */ + NULL, /* base_finalize */ + NULL, + NULL, /* class_finalize */ + NULL, /* class_data */ + 0, + 0, /* n_preallocs */ + NULL + }; + + system_config_interface_type = g_type_register_static (G_TYPE_INTERFACE, + "NMSystemConfigInterface", + &system_config_interface_info, + 0); + + g_type_interface_add_prerequisite (system_config_interface_type, G_TYPE_OBJECT); + } + + return system_config_interface_type; +} + +void +nm_system_config_interface_init (NMSystemConfigInterface *config, + gpointer unused) +{ + g_return_if_fail (config != NULL); + + if (NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->init) + NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->init (config); +} + +GSList * +nm_system_config_interface_get_connections (NMSystemConfigInterface *config) +{ + g_return_val_if_fail (config != NULL, NULL); + + if (NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->get_connections) + return NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->get_connections (config); + return NULL; +} + +GSList * +nm_system_config_interface_get_unmanaged_specs (NMSystemConfigInterface *config) +{ + g_return_val_if_fail (config != NULL, NULL); + + if (NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->get_unmanaged_specs) + return NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->get_unmanaged_specs (config); + return NULL; +} + +gboolean +nm_system_config_interface_add_connection (NMSystemConfigInterface *config, + NMConnection *connection, + GError **error) +{ + gboolean success = FALSE; + + g_return_val_if_fail (config != NULL, FALSE); + g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); + + if (NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->add_connection) + success = NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->add_connection (config, connection, error); + + return success; +} diff --git a/src/system-settings/nm-system-config-interface.h b/src/system-settings/nm-system-config-interface.h new file mode 100644 index 0000000000..1be49a7ee0 --- /dev/null +++ b/src/system-settings/nm-system-config-interface.h @@ -0,0 +1,138 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2007 - 2008 Red Hat, Inc. + * Copyright (C) 2008 Novell, Inc. + */ + +#ifndef NM_SYSTEM_CONFIG_INTERFACE_H +#define NM_SYSTEM_CONFIG_INTERFACE_H + +#include +#include +#include +#include + +G_BEGIN_DECLS + +#define PLUGIN_PRINT(pname, fmt, args...) \ + { g_message (" " pname ": " fmt, ##args); } + +#define PLUGIN_WARN(pname, fmt, args...) \ + { g_warning (" " pname ": " fmt, ##args); } + + +/* Plugin's factory function that returns a GObject that implements + * NMSystemConfigInterface. + */ +GObject * nm_system_config_factory (void); + +/* NOTE: + * When passing NMConnection objects to NetworkManager, any properties + * of that NMConnection's NMSetting objects that are secrets must be set as + * GObject data items on the NMSetting object, _not_ inside the NMSetting + * object itself. This is to ensure that the secrets are only given to + * NetworkManager itself and not exposed to clients like nm-applet that need + * connection details, but not secrets. + */ + +#define NM_TYPE_SYSTEM_CONFIG_INTERFACE (nm_system_config_interface_get_type ()) +#define NM_SYSTEM_CONFIG_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SYSTEM_CONFIG_INTERFACE, NMSystemConfigInterface)) +#define NM_IS_SYSTEM_CONFIG_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SYSTEM_CONFIG_INTERFACE)) +#define NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), NM_TYPE_SYSTEM_CONFIG_INTERFACE, NMSystemConfigInterface)) + + +#define NM_SYSTEM_CONFIG_INTERFACE_NAME "name" +#define NM_SYSTEM_CONFIG_INTERFACE_INFO "info" +#define NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES "capabilities" +#define NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME "hostname" + +typedef enum { + NM_SYSTEM_CONFIG_INTERFACE_CAP_NONE = 0x00000000, + NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS = 0x00000001, + NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME = 0x00000002, + + NM_SYSTEM_CONFIG_INTERFACE_CAP_LAST = NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME +} NMSystemConfigInterfaceCapabilities; + +typedef enum { + NM_SYSTEM_CONFIG_INTERFACE_PROP_FIRST = 0x1000, + + NM_SYSTEM_CONFIG_INTERFACE_PROP_NAME = NM_SYSTEM_CONFIG_INTERFACE_PROP_FIRST, + NM_SYSTEM_CONFIG_INTERFACE_PROP_INFO, + NM_SYSTEM_CONFIG_INTERFACE_PROP_CAPABILITIES, + NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME, +} NMSystemConfigInterfaceProp; + + +typedef struct _NMSystemConfigInterface NMSystemConfigInterface; + +struct _NMSystemConfigInterface { + GTypeInterface g_iface; + + /* Called when the plugin is loaded to initialize it */ + void (*init) (NMSystemConfigInterface *config); + + /* Returns the plugins currently known list of connections. The returned + * list is freed by the system settings service. + */ + GSList * (*get_connections) (NMSystemConfigInterface *config); + + /* + * Return a string list of specifications of devices which NetworkManager + * should not manage. Returned list will be freed by the system settings + * service, and each element must be allocated using g_malloc() or its + * variants (g_strdup, g_strdup_printf, etc). + * + * Each string in the list must follow the format :, where + * the method and data are one of the following: + * + * Method: mac Data: device MAC address formatted with leading zeros and + * lowercase letters, like 00:0a:0b:0c:0d:0e + */ + GSList * (*get_unmanaged_specs) (NMSystemConfigInterface *config); + + /* + * Add a new connection. + */ + gboolean (*add_connection) (NMSystemConfigInterface *config, NMConnection *connection, GError **error); + + /* Signals */ + + /* Emitted when a new connection has been found by the plugin */ + void (*connection_added) (NMSystemConfigInterface *config, NMExportedConnection *connection); + + /* Emitted when the list of unmanaged devices changes */ + void (*unmanaged_devices_changed) (NMSystemConfigInterface *config); +}; + +GType nm_system_config_interface_get_type (void); + +void nm_system_config_interface_init (NMSystemConfigInterface *config, + gpointer unused); + +GSList *nm_system_config_interface_get_connections (NMSystemConfigInterface *config); + +GSList *nm_system_config_interface_get_unmanaged_specs (NMSystemConfigInterface *config); + +gboolean nm_system_config_interface_add_connection (NMSystemConfigInterface *config, + NMConnection *connection, + GError **error); + +G_END_DECLS + +#endif /* NM_SYSTEM_CONFIG_INTERFACE_H */ diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c index b89587fb17..6657aa7870 100644 --- a/src/vpn-manager/nm-vpn-connection.c +++ b/src/vpn-manager/nm-vpn-connection.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2005 - 2008 Red Hat, Inc. + * Copyright (C) 2005 - 2009 Red Hat, Inc. * Copyright (C) 2006 - 2008 Novell, Inc. */ @@ -49,13 +49,16 @@ #include "nm-vpn-connection-glue.h" -G_DEFINE_TYPE (NMVPNConnection, nm_vpn_connection, G_TYPE_OBJECT) +static void secrets_provider_interface_init (NMSecretsProviderInterface *sp_interface_class); + +G_DEFINE_TYPE_EXTENDED (NMVPNConnection, nm_vpn_connection, G_TYPE_OBJECT, 0, + G_IMPLEMENT_INTERFACE (NM_TYPE_SECRETS_PROVIDER_INTERFACE, + secrets_provider_interface_init)) typedef struct { gboolean disposed; NMConnection *connection; - DBusGProxyCall *secrets_call; NMActRequest *act_request; char *ac_path; @@ -221,31 +224,31 @@ nm_vpn_connection_new (NMConnection *connection, NMActRequest *act_request, NMDevice *parent_device) { - NMVPNConnection *vpn_connection; + NMVPNConnection *self; NMVPNConnectionPrivate *priv; g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); g_return_val_if_fail (NM_IS_ACT_REQUEST (act_request), NULL); g_return_val_if_fail (NM_IS_DEVICE (parent_device), NULL); - vpn_connection = (NMVPNConnection *) g_object_new (NM_TYPE_VPN_CONNECTION, NULL); - if (!vpn_connection) + self = (NMVPNConnection *) g_object_new (NM_TYPE_VPN_CONNECTION, NULL); + if (!self) return NULL; - priv = NM_VPN_CONNECTION_GET_PRIVATE (vpn_connection); + priv = NM_VPN_CONNECTION_GET_PRIVATE (self); priv->connection = g_object_ref (connection); - priv->act_request = g_object_ref (act_request); priv->parent_dev = g_object_ref (parent_device); + priv->act_request = g_object_ref (act_request); priv->device_monitor = g_signal_connect (parent_device, "state-changed", G_CALLBACK (device_state_changed), - vpn_connection); + self); priv->device_ip4 = g_signal_connect (parent_device, "notify::" NM_DEVICE_INTERFACE_IP4_CONFIG, G_CALLBACK (device_ip4_config_changed), - vpn_connection); - return vpn_connection; + self); + return self; } static const char * @@ -741,147 +744,55 @@ nm_vpn_connection_disconnect (NMVPNConnection *connection, /******************************************************************************/ -static void -cleanup_secrets_dbus_call (NMVPNConnection *self) +static gboolean +secrets_update_setting (NMSecretsProviderInterface *interface, + const char *setting_name, + GHashTable *new) { + NMVPNConnection *self = NM_VPN_CONNECTION (interface); NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); - DBusGProxy *proxy; - - g_return_if_fail (priv->connection != NULL); - g_return_if_fail (NM_IS_CONNECTION (priv->connection)); - - proxy = g_object_get_data (G_OBJECT (priv->connection), NM_MANAGER_CONNECTION_SECRETS_PROXY_TAG); - g_assert (proxy); - - if (priv->secrets_call) { - dbus_g_proxy_cancel_call (proxy, priv->secrets_call); - priv->secrets_call = NULL; - } -} - -typedef struct GetSecretsInfo { - NMVPNConnection *vpn_connection; - char *setting_name; -} GetSecretsInfo; - -static void -free_get_secrets_info (gpointer data) -{ - GetSecretsInfo * info = (GetSecretsInfo *) data; - - g_free (info->setting_name); - if (info->vpn_connection) - g_object_unref (info->vpn_connection); - g_slice_free (GetSecretsInfo, info); -} - -static void -update_vpn_properties_secrets (gpointer key, gpointer data, gpointer user_data) -{ - NMConnection *connection = NM_CONNECTION (user_data); - GHashTable *secrets = (GHashTable *) data; GError *error = NULL; - if (strcmp (key, NM_SETTING_VPN_SETTING_NAME)) - return; + g_return_val_if_fail (priv->connection != NULL, FALSE); - if (!nm_connection_update_secrets (connection, NM_SETTING_VPN_SETTING_NAME, secrets, &error)) { + if (strcmp (setting_name, NM_SETTING_VPN_SETTING_NAME)) + return FALSE; + + if (!nm_connection_update_secrets (priv->connection, NM_SETTING_VPN_SETTING_NAME, new, &error)) { nm_warning ("Failed to update VPN secrets: %d %s", error ? error->code : -1, error && error->message ? error->message : "(none)"); g_clear_error (&error); + return FALSE; } + return TRUE; } static void -get_secrets_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data) +secrets_result (NMSecretsProviderInterface *interface, + const char *setting_name, + RequestSecretsCaller caller, + const GSList *updated, + GError *error) { - GetSecretsInfo *info = (GetSecretsInfo *) user_data; - NMVPNConnectionPrivate *priv; - GError *err = NULL; - GHashTable *settings = NULL; - - if (!info || !info->vpn_connection || !info->setting_name) - goto error; - - priv = NM_VPN_CONNECTION_GET_PRIVATE (info->vpn_connection); - - priv->secrets_call = NULL; - - if (!dbus_g_proxy_end_call (proxy, call, &err, - DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, &settings, - G_TYPE_INVALID)) { - nm_warning ("Couldn't get connection secrets: %s.", err->message); - g_error_free (err); - goto error; - } - - if (g_hash_table_size (settings) == 0) { - // FIXME: some better way to handle invalid message? - nm_warning ("GetSecrets call returned but no secrets were found."); - goto error; - } + NMVPNConnection *self = NM_VPN_CONNECTION (interface); + NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); - g_hash_table_foreach (settings, update_vpn_properties_secrets, priv->connection); - g_hash_table_destroy (settings); - really_activate (info->vpn_connection); - return; + g_return_if_fail (priv->connection != NULL); + g_return_if_fail (caller == SECRETS_CALLER_VPN); -error: - nm_vpn_connection_fail (info->vpn_connection, NM_VPN_CONNECTION_STATE_REASON_NO_SECRETS); + if (error) + nm_vpn_connection_fail (self, NM_VPN_CONNECTION_STATE_REASON_NO_SECRETS); + else + really_activate (self); } -static gboolean -get_connection_secrets (NMVPNConnection *vpn_connection, - const char *setting_name, - gboolean request_new) +static void +secrets_provider_interface_init (NMSecretsProviderInterface *sp_interface_class) { - NMVPNConnectionPrivate *priv; - DBusGProxy *secrets_proxy; - GetSecretsInfo *info = NULL; - GPtrArray *hints; - - g_return_val_if_fail (vpn_connection != NULL, FALSE); - g_return_val_if_fail (NM_IS_VPN_CONNECTION (vpn_connection), FALSE); - g_return_val_if_fail (setting_name != NULL, FALSE); - - priv = NM_VPN_CONNECTION_GET_PRIVATE (vpn_connection); - g_assert (priv->connection); - - secrets_proxy = g_object_get_data (G_OBJECT (priv->connection), NM_MANAGER_CONNECTION_SECRETS_PROXY_TAG); - g_assert (secrets_proxy); - - info = g_slice_new0 (GetSecretsInfo); - g_return_val_if_fail (info != NULL, FALSE); - - info->setting_name = g_strdup (setting_name); - info->vpn_connection = g_object_ref (vpn_connection); - - /* Empty for now... */ - hints = g_ptr_array_new (); - - /* use ..._with_timeout to give the user time to enter secrets */ - priv->secrets_call = dbus_g_proxy_begin_call_with_timeout (secrets_proxy, "GetSecrets", - get_secrets_cb, - info, - free_get_secrets_info, - G_MAXINT32, - G_TYPE_STRING, setting_name, - DBUS_TYPE_G_ARRAY_OF_STRING, hints, - G_TYPE_BOOLEAN, request_new, - G_TYPE_INVALID); - g_ptr_array_free (hints, TRUE); - if (!priv->secrets_call) { - nm_warning ("Could not call GetSecrets"); - goto error; - } - return TRUE; - -error: - if (info) - free_get_secrets_info (info); - cleanup_secrets_dbus_call (vpn_connection); - return FALSE; + /* interface implementation */ + sp_interface_class->update_setting = secrets_update_setting; + sp_interface_class->result = secrets_result; } static void @@ -890,25 +801,32 @@ connection_need_secrets_cb (DBusGProxy *proxy, GError *error, gpointer user_data) { - NMVPNConnection *vpn_connection = NM_VPN_CONNECTION (user_data); - - cleanup_secrets_dbus_call (vpn_connection); + NMVPNConnection *self = NM_VPN_CONNECTION (user_data); + NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); if (error) { g_warning ("%s.%d: NeedSecrets failed: %s %s", __FILE__, __LINE__, g_quark_to_string (error->domain), error->message); - nm_vpn_connection_fail (vpn_connection, NM_VPN_CONNECTION_STATE_REASON_NO_SECRETS); + nm_vpn_connection_fail (self, NM_VPN_CONNECTION_STATE_REASON_NO_SECRETS); return; } - if (setting_name && strlen (setting_name)) { - if (!get_connection_secrets (vpn_connection, setting_name, FALSE)) - nm_vpn_connection_fail (vpn_connection, NM_VPN_CONNECTION_STATE_REASON_NO_SECRETS); - } else { - /* No secrets needed */ - really_activate (vpn_connection); + if (!setting_name || !strlen (setting_name)) { + /* No secrets required */ + really_activate (self); + return; } + + /* Get the secrets the VPN plugin wants */ + if (!nm_secrets_provider_interface_get_secrets (NM_SECRETS_PROVIDER_INTERFACE (self), + priv->connection, + setting_name, + FALSE, + SECRETS_CALLER_VPN, + NULL, + NULL)) + nm_vpn_connection_fail (self, NM_VPN_CONNECTION_STATE_REASON_NO_SECRETS); } static void @@ -985,7 +903,7 @@ connection_state_changed (NMVPNConnection *connection, { NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection); - cleanup_secrets_dbus_call (connection); + nm_secrets_provider_interface_cancel_get_secrets (NM_SECRETS_PROVIDER_INTERFACE (priv->act_request)); switch (state) { case NM_VPN_CONNECTION_STATE_NEED_AUTH: @@ -1040,20 +958,16 @@ dispose (GObject *object) } priv->disposed = TRUE; - cleanup_secrets_dbus_call (NM_VPN_CONNECTION (object)); - if (priv->gw_route) rtnl_route_put (priv->gw_route); - if (priv->parent_dev) { - if (priv->device_ip4) - g_signal_handler_disconnect (priv->parent_dev, priv->device_ip4); + if (priv->device_ip4) + g_signal_handler_disconnect (priv->parent_dev, priv->device_ip4); - if (priv->device_monitor) - g_signal_handler_disconnect (priv->parent_dev, priv->device_monitor); + if (priv->device_monitor) + g_signal_handler_disconnect (priv->parent_dev, priv->device_monitor); - g_object_unref (priv->parent_dev); - } + g_object_unref (priv->parent_dev); if (priv->ip4_config) g_object_unref (priv->ip4_config); @@ -1064,6 +978,7 @@ dispose (GObject *object) if (priv->proxy) g_object_unref (priv->proxy); + g_object_unref (priv->act_request); g_object_unref (priv->connection); G_OBJECT_CLASS (nm_vpn_connection_parent_class)->dispose (object); diff --git a/src/vpn-manager/nm-vpn-connection.h b/src/vpn-manager/nm-vpn-connection.h index 31a2618cb2..d69674db9e 100644 --- a/src/vpn-manager/nm-vpn-connection.h +++ b/src/vpn-manager/nm-vpn-connection.h @@ -27,6 +27,7 @@ #include "NetworkManagerVPN.h" #include "nm-device.h" #include "nm-activation-request.h" +#include "nm-secrets-provider-interface.h" #define NM_TYPE_VPN_CONNECTION (nm_vpn_connection_get_type ()) #define NM_VPN_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VPN_CONNECTION, NMVPNConnection)) @@ -72,6 +73,6 @@ void nm_vpn_connection_disconnect (NMVPNConnection *connect NMIP4Config * nm_vpn_connection_get_ip4_config (NMVPNConnection *connection); const char * nm_vpn_connection_get_ip_iface (NMVPNConnection *connection); NMDevice * nm_vpn_connection_get_parent_device (NMVPNConnection *connection); -guint32 nm_vpn_connection_get_ip4_internal_gateway (NMVPNConnection *connection); +guint32 nm_vpn_connection_get_ip4_internal_gateway (NMVPNConnection *connection); #endif /* NM_VPN_CONNECTION_H */ diff --git a/src/vpn-manager/nm-vpn-manager.c b/src/vpn-manager/nm-vpn-manager.c index 3ed424d6ee..e8fa24c8db 100644 --- a/src/vpn-manager/nm-vpn-manager.c +++ b/src/vpn-manager/nm-vpn-manager.c @@ -160,7 +160,7 @@ connection_vpn_state_changed (NMVPNConnection *connection, } } -const char * +NMVPNConnection * nm_vpn_manager_activate_connection (NMVPNManager *manager, NMConnection *connection, NMActRequest *act_request, @@ -169,8 +169,7 @@ nm_vpn_manager_activate_connection (NMVPNManager *manager, { NMSettingVPN *vpn_setting; NMVPNService *service; - char *path = NULL; - NMVPNConnection *vpn; + NMVPNConnection *vpn = NULL; const char *service_type; g_return_val_if_fail (NM_IS_VPN_MANAGER (manager), NULL); @@ -212,7 +211,6 @@ nm_vpn_manager_activate_connection (NMVPNManager *manager, if (service) { vpn = nm_vpn_service_activate (service, connection, act_request, device, error); if (vpn) { - path = (char *) nm_vpn_connection_get_active_connection_path (vpn); g_signal_connect (vpn, "vpn-state-changed", G_CALLBACK (connection_vpn_state_changed), manager); @@ -223,7 +221,7 @@ nm_vpn_manager_activate_connection (NMVPNManager *manager, "%s", "The VPN service was invalid."); } - return path; + return vpn; } gboolean diff --git a/src/vpn-manager/nm-vpn-manager.h b/src/vpn-manager/nm-vpn-manager.h index 3500c6d494..d07aa25099 100644 --- a/src/vpn-manager/nm-vpn-manager.h +++ b/src/vpn-manager/nm-vpn-manager.h @@ -67,11 +67,11 @@ GType nm_vpn_manager_get_type (void); NMVPNManager *nm_vpn_manager_get (void); -const char *nm_vpn_manager_activate_connection (NMVPNManager *manager, - NMConnection *connection, - NMActRequest *act_request, - NMDevice *device, - GError **error); +NMVPNConnection *nm_vpn_manager_activate_connection (NMVPNManager *manager, + NMConnection *connection, + NMActRequest *act_request, + NMDevice *device, + GError **error); gboolean nm_vpn_manager_deactivate_connection (NMVPNManager *manager, const char *path, diff --git a/src/vpn-manager/nm-vpn-service.c b/src/vpn-manager/nm-vpn-service.c index 15aa56db5e..e99aa4f062 100644 --- a/src/vpn-manager/nm-vpn-service.c +++ b/src/vpn-manager/nm-vpn-service.c @@ -323,6 +323,7 @@ nm_vpn_service_activate (NMVPNService *service, priv = NM_VPN_SERVICE_GET_PRIVATE (service); +g_message ("%s: new VPNConnection for %s", __func__, nm_connection_get_path (connection)); vpn = nm_vpn_connection_new (connection, act_request, device); g_signal_connect (vpn, "vpn-state-changed", G_CALLBACK (connection_vpn_state_changed), diff --git a/system-settings/Makefile.am b/system-settings/Makefile.am index 128b058a00..67cf8702eb 100644 --- a/system-settings/Makefile.am +++ b/system-settings/Makefile.am @@ -1,2 +1,2 @@ -SUBDIRS=src plugins +SUBDIRS=plugins diff --git a/system-settings/plugins/ifcfg-rh/Makefile.am b/system-settings/plugins/ifcfg-rh/Makefile.am index f804ef172a..1635e39484 100644 --- a/system-settings/plugins/ifcfg-rh/Makefile.am +++ b/system-settings/plugins/ifcfg-rh/Makefile.am @@ -20,13 +20,18 @@ libifcfg_rh_io_la_SOURCES = \ crypto.c \ crypto.h +INCLUDES = \ + -I$(top_srcdir)/src/system-settings \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/libnm-glib \ + -I$(top_srcdir)/libnm-util \ + -I$(top_builddir)/marshallers + libifcfg_rh_io_la_CPPFLAGS = \ $(GLIB_CFLAGS) \ $(DBUS_CFLAGS) \ $(NSS_CFLAGS) \ -DG_DISABLE_DEPRECATED \ - -I$(top_srcdir)/include \ - -I$(top_srcdir)/libnm-util \ -DSYSCONFDIR=\"$(sysconfdir)\" libifcfg_rh_io_la_LIBADD = $(GLIB_LIBS) $(NSS_LIBS) @@ -42,11 +47,6 @@ libnm_settings_plugin_ifcfg_rh_la_CPPFLAGS = \ $(GMODULE_CFLAGS) \ $(DBUS_CFLAGS) \ -DG_DISABLE_DEPRECATED \ - -I$(top_srcdir)/system-settings/src \ - -I$(top_srcdir)/include \ - -I$(top_srcdir)/libnm-glib \ - -I$(top_srcdir)/libnm-util \ - -I$(top_builddir)/marshallers \ -DSYSCONFDIR=\"$(sysconfdir)\" libnm_settings_plugin_ifcfg_rh_la_LDFLAGS = -module -avoid-version diff --git a/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.c b/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.c index bfc36af6fd..4767b5183c 100644 --- a/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.c +++ b/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.c @@ -36,7 +36,6 @@ #include "common.h" #include "nm-ifcfg-connection.h" -#include "nm-system-config-hal-manager.h" #include "reader.h" #include "writer.h" #include "nm-inotify-helper.h" @@ -55,11 +54,7 @@ typedef struct { int keyfile_wd; char *udi; - gboolean unmanaged; - - NMSystemConfigHalManager *hal_mgr; - DBusGConnection *g_connection; - gulong daid; + char *unmanaged; } NMIfcfgConnectionPrivate; enum { @@ -79,150 +74,6 @@ enum { static guint signals[LAST_SIGNAL] = { 0 }; -static char * -get_ether_device_udi (DBusGConnection *g_connection, const GByteArray *mac, GSList *devices) -{ - GError *error = NULL; - GSList *iter; - char *udi = NULL; - - if (!g_connection || !mac) - return NULL; - - for (iter = devices; !udi && iter; iter = g_slist_next (iter)) { - DBusGProxy *dev_proxy; - char *address = NULL; - - dev_proxy = dbus_g_proxy_new_for_name (g_connection, - "org.freedesktop.Hal", - iter->data, - "org.freedesktop.Hal.Device"); - if (!dev_proxy) - continue; - - if (dbus_g_proxy_call_with_timeout (dev_proxy, - "GetPropertyString", 10000, &error, - G_TYPE_STRING, "net.address", G_TYPE_INVALID, - G_TYPE_STRING, &address, G_TYPE_INVALID)) { - struct ether_addr *dev_mac; - - if (address && strlen (address)) { - dev_mac = ether_aton (address); - if (!memcmp (dev_mac->ether_addr_octet, mac->data, ETH_ALEN)) - udi = g_strdup (iter->data); - } - } else { - g_error_free (error); - error = NULL; - } - g_free (address); - g_object_unref (dev_proxy); - } - - return udi; -} - -static NMDeviceType -get_device_type_for_connection (NMConnection *connection) -{ - NMDeviceType devtype = NM_DEVICE_TYPE_UNKNOWN; - NMSettingConnection *s_con; - const char *ctype; - - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); - if (!s_con) - return NM_DEVICE_TYPE_UNKNOWN; - - ctype = nm_setting_connection_get_connection_type (s_con); - - if ( !strcmp (ctype, NM_SETTING_WIRED_SETTING_NAME) - || !strcmp (ctype, NM_SETTING_PPPOE_SETTING_NAME)) { - if (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED)) - devtype = NM_DEVICE_TYPE_ETHERNET; - } else if (!strcmp (ctype, NM_SETTING_WIRELESS_SETTING_NAME)) { - if (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)) - devtype = NM_DEVICE_TYPE_WIFI; - } else if (!strcmp (ctype, NM_SETTING_GSM_SETTING_NAME)) { - if (nm_connection_get_setting (connection, NM_TYPE_SETTING_GSM)) - devtype = NM_DEVICE_TYPE_GSM; - } else if (!strcmp (ctype, NM_SETTING_CDMA_SETTING_NAME)) { - if (nm_connection_get_setting (connection, NM_TYPE_SETTING_CDMA)) - devtype = NM_DEVICE_TYPE_CDMA; - } - - return devtype; -} - -static char * -get_udi_for_connection (NMConnection *connection, - DBusGConnection *g_connection, - NMSystemConfigHalManager *hal_mgr, - NMDeviceType devtype) -{ - NMSettingWired *s_wired; - NMSettingWireless *s_wireless; - char *udi = NULL; - GSList *devices = NULL; - - if (devtype == NM_DEVICE_TYPE_UNKNOWN) - devtype = get_device_type_for_connection (connection); - - switch (devtype) { - case NM_DEVICE_TYPE_ETHERNET: - s_wired = (NMSettingWired *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED); - if (s_wired) { - devices = nm_system_config_hal_manager_get_devices_of_type (hal_mgr, NM_DEVICE_TYPE_ETHERNET); - udi = get_ether_device_udi (g_connection, nm_setting_wired_get_mac_address (s_wired), devices); - } - break; - - case NM_DEVICE_TYPE_WIFI: - s_wireless = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS); - if (s_wireless) { - devices = nm_system_config_hal_manager_get_devices_of_type (hal_mgr, NM_DEVICE_TYPE_WIFI); - udi = get_ether_device_udi (g_connection, nm_setting_wireless_get_mac_address (s_wireless), devices); - } - break; - - default: - break; - } - - g_slist_foreach (devices, (GFunc) g_free, NULL); - g_slist_free (devices); - - return udi; -} - -static void -device_added_cb (NMSystemConfigHalManager *hal_mgr, - const char *udi, - NMDeviceType devtype, - gpointer user_data) -{ - NMIfcfgConnection *connection = NM_IFCFG_CONNECTION (user_data); - NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (connection); - NMConnection *wrapped; - - /* Should only be called when udi is NULL */ - g_return_if_fail (priv->udi == NULL); - - wrapped = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (connection)); - if (devtype != get_device_type_for_connection (wrapped)) - return; - - priv->udi = get_udi_for_connection (wrapped, priv->g_connection, priv->hal_mgr, devtype); - if (!priv->udi) - return; - - /* If the connection is unmanaged we have to tell the plugin */ - if (priv->unmanaged) - g_object_notify (G_OBJECT (connection), NM_IFCFG_CONNECTION_UNMANAGED); - - g_signal_handler_disconnect (G_OBJECT (hal_mgr), priv->daid); - priv->daid = 0; -} - static void files_changed_cb (NMInotifyHelper *ih, struct inotify_event *evt, @@ -241,16 +92,13 @@ files_changed_cb (NMInotifyHelper *ih, NMIfcfgConnection * nm_ifcfg_connection_new (const char *filename, - DBusGConnection *g_connection, - NMSystemConfigHalManager *hal_mgr, GError **error, gboolean *ignore_error) { GObject *object; NMIfcfgConnectionPrivate *priv; NMConnection *wrapped; - gboolean unmanaged = FALSE; - char *udi; + char *unmanaged = NULL; char *keyfile = NULL; NMInotifyHelper *ih; @@ -260,12 +108,9 @@ nm_ifcfg_connection_new (const char *filename, if (!wrapped) return NULL; - udi = get_udi_for_connection (wrapped, g_connection, hal_mgr, NM_DEVICE_TYPE_UNKNOWN); - object = (GObject *) g_object_new (NM_TYPE_IFCFG_CONNECTION, NM_IFCFG_CONNECTION_FILENAME, filename, NM_IFCFG_CONNECTION_UNMANAGED, unmanaged, - NM_IFCFG_CONNECTION_UDI, udi, NM_EXPORTED_CONNECTION_CONNECTION, wrapped, NULL); if (!object) @@ -273,12 +118,6 @@ nm_ifcfg_connection_new (const char *filename, priv = NM_IFCFG_CONNECTION_GET_PRIVATE (object); - if (!udi) { - priv->hal_mgr = g_object_ref (hal_mgr); - priv->g_connection = dbus_g_connection_ref (g_connection); - priv->daid = g_signal_connect (priv->hal_mgr, "device-added", G_CALLBACK (device_added_cb), object); - } - ih = nm_inotify_helper_get (); priv->ih_event_id = g_signal_connect (ih, "event", G_CALLBACK (files_changed_cb), object); @@ -289,7 +128,6 @@ nm_ifcfg_connection_new (const char *filename, out: g_object_unref (wrapped); - g_free (udi); return (NMIfcfgConnection *) object; } @@ -302,15 +140,7 @@ nm_ifcfg_connection_get_filename (NMIfcfgConnection *self) } const char * -nm_ifcfg_connection_get_udi (NMIfcfgConnection *self) -{ - g_return_val_if_fail (NM_IS_IFCFG_CONNECTION (self), NULL); - - return NM_IFCFG_CONNECTION_GET_PRIVATE (self)->udi; -} - -gboolean -nm_ifcfg_connection_get_unmanaged (NMIfcfgConnection *self) +nm_ifcfg_connection_get_unmanaged_spec (NMIfcfgConnection *self) { g_return_val_if_fail (NM_IS_IFCFG_CONNECTION (self), FALSE); @@ -384,16 +214,6 @@ finalize (GObject *object) if (priv->keyfile_wd >= 0) nm_inotify_helper_remove_watch (ih, priv->keyfile_wd); - if (priv->hal_mgr) { - if (priv->daid) - g_signal_handler_disconnect (G_OBJECT (priv->hal_mgr), priv->daid); - - g_object_unref (priv->hal_mgr); - } - - if (priv->g_connection) - dbus_g_connection_unref (priv->g_connection); - G_OBJECT_CLASS (nm_ifcfg_connection_parent_class)->finalize (object); } @@ -409,7 +229,7 @@ set_property (GObject *object, guint prop_id, priv->filename = g_value_dup_string (value); break; case PROP_UNMANAGED: - priv->unmanaged = g_value_get_boolean (value); + priv->unmanaged = g_value_dup_string (value); break; case PROP_UDI: /* Construct only */ @@ -432,7 +252,7 @@ get_property (GObject *object, guint prop_id, g_value_set_string (value, priv->filename); break; case PROP_UNMANAGED: - g_value_set_boolean (value, priv->unmanaged); + g_value_set_string (value, priv->unmanaged); break; case PROP_UDI: g_value_set_string (value, priv->udi); @@ -470,10 +290,10 @@ nm_ifcfg_connection_class_init (NMIfcfgConnectionClass *ifcfg_connection_class) g_object_class_install_property (object_class, PROP_UNMANAGED, - g_param_spec_boolean (NM_IFCFG_CONNECTION_UNMANAGED, + g_param_spec_string (NM_IFCFG_CONNECTION_UNMANAGED, "Unmanaged", "Unmanaged", - FALSE, + NULL, G_PARAM_READWRITE)); g_object_class_install_property diff --git a/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.h b/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.h index dc13aa6c11..5cac5d9c8a 100644 --- a/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.h +++ b/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.h @@ -25,7 +25,6 @@ G_BEGIN_DECLS #include #include -#include "nm-system-config-hal-manager.h" #define NM_TYPE_IFCFG_CONNECTION (nm_ifcfg_connection_get_type ()) #define NM_IFCFG_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_IFCFG_CONNECTION, NMIfcfgConnection)) @@ -49,16 +48,12 @@ typedef struct { GType nm_ifcfg_connection_get_type (void); NMIfcfgConnection *nm_ifcfg_connection_new (const char *filename, - DBusGConnection *g_connection, - NMSystemConfigHalManager *hal_mgr, GError **error, gboolean *ignore_error); const char *nm_ifcfg_connection_get_filename (NMIfcfgConnection *self); -const char *nm_ifcfg_connection_get_udi (NMIfcfgConnection *self); - -gboolean nm_ifcfg_connection_get_unmanaged (NMIfcfgConnection *self); +const char *nm_ifcfg_connection_get_unmanaged_spec (NMIfcfgConnection *self); gboolean nm_ifcfg_connection_update (NMIfcfgConnection *self, GHashTable *new_settings, diff --git a/system-settings/plugins/ifcfg-rh/plugin.c b/system-settings/plugins/ifcfg-rh/plugin.c index 121aa80362..361a858005 100644 --- a/system-settings/plugins/ifcfg-rh/plugin.c +++ b/system-settings/plugins/ifcfg-rh/plugin.c @@ -72,9 +72,6 @@ G_DEFINE_TYPE_EXTENDED (SCPluginIfcfg, sc_plugin_ifcfg, G_TYPE_OBJECT, 0, typedef struct { - DBusGConnection *g_connection; - NMSystemConfigHalManager *hal_mgr; - GHashTable *connections; gulong ih_event_id; @@ -86,40 +83,6 @@ typedef struct { } SCPluginIfcfgPrivate; -static void -check_unmanaged (gpointer key, gpointer data, gpointer user_data) -{ - GSList **list = (GSList **) user_data; - NMIfcfgConnection *connection = NM_IFCFG_CONNECTION (data); - const char *udi; - GSList *iter; - - if (!nm_ifcfg_connection_get_unmanaged (connection)) - return; - - udi = nm_ifcfg_connection_get_udi (connection); - if (!udi) - return; - - /* Just return if the UDI is already in the list */ - for (iter = *list; iter; iter = g_slist_next (iter)) { - if (!strcmp ((char *) iter->data, udi)) - return; - } - - *list = g_slist_prepend (*list, g_strdup (udi)); -} - -static GSList * -get_unmanaged_devices (NMSystemConfigInterface *config) -{ - SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (config); - GSList *list = NULL; - - g_hash_table_foreach (priv->connections, check_unmanaged, &list); - return list; -} - static void connection_unmanaged_changed (NMIfcfgConnection *connection, GParamSpec *pspec, @@ -152,7 +115,7 @@ read_one_connection (SCPluginIfcfg *plugin, const char *filename) PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "parsing %s ... ", filename); - connection = nm_ifcfg_connection_new (filename, priv->g_connection, priv->hal_mgr, &error, &ignore_error); + connection = nm_ifcfg_connection_new (filename, &error, &ignore_error); if (connection) { NMConnection *wrapped; NMSettingConnection *s_con; @@ -171,7 +134,7 @@ read_one_connection (SCPluginIfcfg *plugin, const char *filename) g_object_ref (connection)); PLUGIN_PRINT (IFCFG_PLUGIN_NAME, " read connection '%s'", cid); - if (nm_ifcfg_connection_get_unmanaged (connection)) { + if (nm_ifcfg_connection_get_unmanaged_spec (connection)) { PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "Ignoring connection '%s' and its " "device because NM_CONTROLLED was false.", cid); g_signal_emit_by_name (plugin, "unmanaged-devices-changed"); @@ -271,11 +234,11 @@ connection_changed_handler (SCPluginIfcfg *plugin, gboolean *do_remove, gboolean *do_new) { - SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin); NMIfcfgConnection *tmp; GError *error = NULL; GHashTable *settings; - gboolean new_unmanaged, old_unmanaged, ignore_error = FALSE; + gboolean ignore_error = FALSE; + const char *new_unmanaged = NULL, *old_unmanaged = NULL; g_return_if_fail (plugin != NULL); g_return_if_fail (path != NULL); @@ -285,10 +248,7 @@ connection_changed_handler (SCPluginIfcfg *plugin, PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "updating %s", path); - tmp = (NMIfcfgConnection *) nm_ifcfg_connection_new (path, priv->g_connection, - priv->hal_mgr, - &error, - &ignore_error); + tmp = (NMIfcfgConnection *) nm_ifcfg_connection_new (path, &error, &ignore_error); if (!tmp) { /* errors reading connection; remove it */ if (!ignore_error) { @@ -304,8 +264,8 @@ connection_changed_handler (SCPluginIfcfg *plugin, /* Successfully read connection changes */ - old_unmanaged = nm_ifcfg_connection_get_unmanaged (NM_IFCFG_CONNECTION (connection)); - new_unmanaged = nm_ifcfg_connection_get_unmanaged (NM_IFCFG_CONNECTION (tmp)); + old_unmanaged = nm_ifcfg_connection_get_unmanaged_spec (NM_IFCFG_CONNECTION (connection)); + new_unmanaged = nm_ifcfg_connection_get_unmanaged_spec (NM_IFCFG_CONNECTION (tmp)); if (new_unmanaged) { if (!old_unmanaged) { @@ -318,7 +278,7 @@ connection_changed_handler (SCPluginIfcfg *plugin, new_wrapped = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (tmp)); old_wrapped = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (connection)); - if (old_unmanaged) { /* no longer unmanaged */ + if (old_unmanaged) { /* now managed */ NMSettingConnection *s_con; const char *cid; @@ -364,11 +324,11 @@ handle_connection_remove_or_new (SCPluginIfcfg *plugin, g_return_if_fail (path != NULL); if (do_remove) { - gboolean unmanaged; + const char *unmanaged; g_return_if_fail (connection != NULL); - unmanaged = nm_ifcfg_connection_get_unmanaged (connection); + unmanaged = nm_ifcfg_connection_get_unmanaged_spec (connection); g_hash_table_remove (priv->connections, path); nm_exported_connection_signal_removed (NM_EXPORTED_CONNECTION (connection)); @@ -380,7 +340,7 @@ handle_connection_remove_or_new (SCPluginIfcfg *plugin, if (do_new) { connection = read_one_connection (plugin, path); if (connection) { - if (!nm_ifcfg_connection_get_unmanaged (NM_IFCFG_CONNECTION (connection))) + if (!nm_ifcfg_connection_get_unmanaged_spec (NM_IFCFG_CONNECTION (connection))) g_signal_emit_by_name (plugin, "connection-added", connection); } } @@ -454,7 +414,7 @@ hash_to_slist (gpointer key, gpointer value, gpointer user_data) NMIfcfgConnection *exported = NM_IFCFG_CONNECTION (value); GSList **list = (GSList **) user_data; - if (!nm_ifcfg_connection_get_unmanaged (exported)) + if (!nm_ifcfg_connection_get_unmanaged_spec (exported)) *list = g_slist_prepend (*list, value); } @@ -475,6 +435,43 @@ get_connections (NMSystemConfigInterface *config) return list; } +static void +check_unmanaged (gpointer key, gpointer data, gpointer user_data) +{ + GSList **list = (GSList **) user_data; + NMIfcfgConnection *connection = NM_IFCFG_CONNECTION (data); + const char *unmanaged_spec; + GSList *iter; + + unmanaged_spec = nm_ifcfg_connection_get_unmanaged_spec (connection); + if (!unmanaged_spec) + return; + + /* Just return if the unmanaged spec is already in the list */ + for (iter = *list; iter; iter = g_slist_next (iter)) { + if (!strcmp ((char *) iter->data, unmanaged_spec)) + return; + } + + *list = g_slist_prepend (*list, g_strdup (unmanaged_spec)); +} + +static GSList * +get_unmanaged_specs (NMSystemConfigInterface *config) +{ + SCPluginIfcfg *plugin = SC_PLUGIN_IFCFG (config); + SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (config); + GSList *list = NULL; + + if (!priv->connections) { + setup_ifcfg_monitoring (plugin); + read_connections (plugin); + } + + g_hash_table_foreach (priv->connections, check_unmanaged, &list); + return list; +} + static gboolean add_connection (NMSystemConfigInterface *config, NMConnection *connection, @@ -560,28 +557,16 @@ sc_network_changed_cb (NMInotifyHelper *ih, } static void -init (NMSystemConfigInterface *config, NMSystemConfigHalManager *hal_manager) +init (NMSystemConfigInterface *config) { - SCPluginIfcfg *plugin = SC_PLUGIN_IFCFG (config); - SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin); - - priv->hal_mgr = g_object_ref (hal_manager); } static void sc_plugin_ifcfg_init (SCPluginIfcfg *plugin) { SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin); - GError *error = NULL; NMInotifyHelper *ih; - priv->g_connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); - if (!priv->g_connection) { - PLUGIN_PRINT (IFCFG_PLUGIN_NAME, " dbus-glib error: %s", - error->message ? error->message : "(unknown)"); - g_error_free (error); - } - ih = nm_inotify_helper_get (); priv->ih_event_id = g_signal_connect (ih, "event", G_CALLBACK (sc_network_changed_cb), plugin); priv->sc_network_wd = nm_inotify_helper_add_watch (ih, SC_NETWORK_FILE); @@ -596,8 +581,6 @@ dispose (GObject *object) SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin); NMInotifyHelper *ih; - g_object_unref (priv->hal_mgr); - ih = nm_inotify_helper_get (); g_signal_handler_disconnect (ih, priv->ih_event_id); @@ -607,9 +590,6 @@ dispose (GObject *object) g_free (priv->hostname); - if (priv->g_connection) - dbus_g_connection_unref (priv->g_connection); - if (priv->connections) g_hash_table_destroy (priv->connections); @@ -709,7 +689,7 @@ system_config_interface_init (NMSystemConfigInterface *system_config_interface_c /* interface implementation */ system_config_interface_class->get_connections = get_connections; system_config_interface_class->add_connection = add_connection; - system_config_interface_class->get_unmanaged_devices = get_unmanaged_devices; + system_config_interface_class->get_unmanaged_specs = get_unmanaged_specs; system_config_interface_class->init = init; } diff --git a/system-settings/plugins/ifcfg-rh/reader.c b/system-settings/plugins/ifcfg-rh/reader.c index a8119ac299..e41de7d563 100644 --- a/system-settings/plugins/ifcfg-rh/reader.c +++ b/system-settings/plugins/ifcfg-rh/reader.c @@ -1366,7 +1366,7 @@ fill_8021x (shvarFile *ifcfg, char *lower = NULL; lower = g_ascii_strdown (*iter, -1); - while (*eap->method && !found) { + while (eap->method && !found) { if (strcmp (eap->method, lower)) goto next; @@ -1602,7 +1602,8 @@ make_wireless_security_setting (shvarFile *ifcfg, static NMSetting * make_wireless_setting (shvarFile *ifcfg, - gboolean unmanaged, + gboolean nm_controlled, + char **unmanaged, GError **error) { NMSettingWireless *s_wireless; @@ -1614,6 +1615,14 @@ make_wireless_setting (shvarFile *ifcfg, if (read_mac_address (ifcfg, &array, error)) { if (array) { g_object_set (s_wireless, NM_SETTING_WIRELESS_MAC_ADDRESS, array, NULL); + + /* A connection can only be unmanaged if we know the MAC address */ + if (!nm_controlled) { + *unmanaged = g_strdup_printf ("mac:%02x:%02x:%02x:%02x:%02x:%02x", + array->data[0], array->data[1], array->data[2], + array->data[3], array->data[4], array->data[5]); + } + g_byte_array_free (array, TRUE); } } else { @@ -1681,13 +1690,13 @@ make_wireless_setting (shvarFile *ifcfg, g_free (value); } else { /* Only fail on lack of SSID if device is managed */ - if (!unmanaged) { + if (nm_controlled) { g_set_error (error, ifcfg_plugin_error_quark (), 0, "Missing SSID"); goto error; } } - if (unmanaged) + if (!nm_controlled) goto done; value = svGetValue (ifcfg, "MODE", FALSE); @@ -1778,7 +1787,8 @@ error: static NMConnection * wireless_connection_from_ifcfg (const char *file, shvarFile *ifcfg, - gboolean unmanaged, + gboolean nm_controlled, + char **unmanaged, GError **error) { NMConnection *connection = NULL; @@ -1804,7 +1814,7 @@ wireless_connection_from_ifcfg (const char *file, } /* Wireless */ - wireless_setting = make_wireless_setting (ifcfg, unmanaged, error); + wireless_setting = make_wireless_setting (ifcfg, nm_controlled, unmanaged, error); if (!wireless_setting) { g_object_unref (connection); return NULL; @@ -1817,7 +1827,7 @@ wireless_connection_from_ifcfg (const char *file, else printable_ssid = g_strdup_printf ("unmanaged"); - if (!unmanaged) { + if (nm_controlled) { mode = nm_setting_wireless_get_mode (NM_SETTING_WIRELESS (wireless_setting)); if (mode && !strcmp (mode, "adhoc")) adhoc = TRUE; @@ -1852,7 +1862,7 @@ wireless_connection_from_ifcfg (const char *file, nm_connection_add_setting (connection, con_setting); /* Don't verify if unmanaged since we may not have an SSID or whatever */ - if (!unmanaged) { + if (nm_controlled) { if (!nm_connection_verify (connection, error)) { g_object_unref (connection); return NULL; @@ -1865,7 +1875,8 @@ wireless_connection_from_ifcfg (const char *file, static NMSetting * make_wired_setting (shvarFile *ifcfg, const char *file, - gboolean unmanaged, + gboolean nm_controlled, + char **unmanaged, NMSetting8021x **s_8021x, GError **error) { @@ -1891,6 +1902,14 @@ make_wired_setting (shvarFile *ifcfg, if (read_mac_address (ifcfg, &mac, error)) { if (mac) { g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, mac, NULL); + + /* A connection can only be unmanaged if we know the MAC address */ + if (!nm_controlled) { + *unmanaged = g_strdup_printf ("mac:%02x:%02x:%02x:%02x:%02x:%02x", + mac->data[0], mac->data[1], mac->data[2], + mac->data[3], mac->data[4], mac->data[5]); + } + g_byte_array_free (mac, TRUE); } } else { @@ -1923,7 +1942,8 @@ error: static NMConnection * wired_connection_from_ifcfg (const char *file, shvarFile *ifcfg, - gboolean unmanaged, + gboolean nm_controlled, + char **unmanaged, GError **error) { NMConnection *connection = NULL; @@ -1950,7 +1970,7 @@ wired_connection_from_ifcfg (const char *file, } nm_connection_add_setting (connection, con_setting); - wired_setting = make_wired_setting (ifcfg, file, unmanaged, &s_8021x, error); + wired_setting = make_wired_setting (ifcfg, file, nm_controlled, unmanaged, &s_8021x, error); if (!wired_setting) { g_object_unref (connection); return NULL; @@ -2013,20 +2033,21 @@ NMConnection * connection_from_file (const char *filename, const char *network_file, const char *test_type, /* for unit tests only */ - gboolean *ignored, + char **unmanaged, char **keyfile, GError **error, gboolean *ignore_error) { NMConnection *connection = NULL; shvarFile *parsed; - char *type; - char *nmc = NULL; + char *type, *nmc = NULL; NMSetting *s_ip4; char *ifcfg_name = NULL; + gboolean nm_controlled = TRUE; g_return_val_if_fail (filename != NULL, NULL); - g_return_val_if_fail (ignored != NULL, NULL); + g_return_val_if_fail (unmanaged != NULL, NULL); + g_return_val_if_fail (*unmanaged == NULL, NULL); g_return_val_if_fail (keyfile != NULL, NULL); g_return_val_if_fail (*keyfile == NULL, NULL); @@ -2096,23 +2117,28 @@ connection_from_file (const char *filename, g_free (nmc); if (!strcmp (lower, "no") || !strcmp (lower, "n") || !strcmp (lower, "false")) - *ignored = TRUE; + nm_controlled = FALSE; g_free (lower); } if (!strcasecmp (type, TYPE_ETHERNET)) - connection = wired_connection_from_ifcfg (filename, parsed, *ignored, error); + connection = wired_connection_from_ifcfg (filename, parsed, nm_controlled, unmanaged, error); else if (!strcasecmp (type, TYPE_WIRELESS)) - connection = wireless_connection_from_ifcfg (filename, parsed, *ignored, error); + connection = wireless_connection_from_ifcfg (filename, parsed, nm_controlled, unmanaged, error); else { g_set_error (error, ifcfg_plugin_error_quark (), 0, "Unknown connection type '%s'", type); } + if (nm_controlled) { + g_free (*unmanaged); + *unmanaged = NULL; + } + g_free (type); /* Don't bother reading the connection fully if it's unmanaged */ - if (!connection || *ignored) + if (!connection || *unmanaged) goto done; s_ip4 = make_ip4_setting (parsed, network_file, error); diff --git a/system-settings/plugins/ifcfg-rh/reader.h b/system-settings/plugins/ifcfg-rh/reader.h index 1fce39b565..458223fce8 100644 --- a/system-settings/plugins/ifcfg-rh/reader.h +++ b/system-settings/plugins/ifcfg-rh/reader.h @@ -29,7 +29,7 @@ NMConnection *connection_from_file (const char *filename, const char *network_file, const char *test_type, - gboolean *ignored, + char **unmanaged, char **keyfile, GError **error, gboolean *ignore_error); diff --git a/system-settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c b/system-settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c index 8cf1e8f225..213aeab148 100644 --- a/system-settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c +++ b/system-settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c @@ -163,7 +163,7 @@ test_read_minimal (void) NMSettingConnection *s_con; NMSettingWired *s_wired; NMSettingIP4Config *s_ip4; - gboolean unmanaged = FALSE; + char *unmanaged = NULL; char *keyfile = NULL; gboolean ignore_error = FALSE; GError *error = NULL; @@ -286,7 +286,7 @@ test_read_unmanaged (void) NMSettingConnection *s_con; NMSettingWired *s_wired; NMSettingIP4Config *s_ip4; - gboolean unmanaged = FALSE; + char *unmanaged = NULL; char *keyfile = NULL; gboolean ignore_error = FALSE; GError *error = NULL; @@ -309,7 +309,10 @@ test_read_unmanaged (void) ASSERT (nm_connection_verify (connection, &error), "unmanaged-verify", "failed to verify %s: %s", TEST_IFCFG_UNMANAGED, error->message); - ASSERT (unmanaged == TRUE, + ASSERT (unmanaged != NULL, + "unmanaged-verify", "failed to verify %s: expected unmanaged", TEST_IFCFG_UNMANAGED); + + ASSERT (strcmp (unmanaged, "mac:00:11:22:33:f8:9f") == 0, "unmanaged-verify", "failed to verify %s: expected unmanaged", TEST_IFCFG_UNMANAGED); /* ===== CONNECTION SETTING ===== */ @@ -396,7 +399,7 @@ test_read_wired_static (void) NMSettingConnection *s_con; NMSettingWired *s_wired; NMSettingIP4Config *s_ip4; - gboolean unmanaged = FALSE; + char *unmanaged = FALSE; char *keyfile = NULL; gboolean ignore_error = FALSE; GError *error = NULL; @@ -593,7 +596,7 @@ test_read_wired_dhcp (void) NMSettingConnection *s_con; NMSettingWired *s_wired; NMSettingIP4Config *s_ip4; - gboolean unmanaged = FALSE; + char *unmanaged = NULL; char *keyfile = NULL; gboolean ignore_error = FALSE; GError *error = NULL; @@ -760,7 +763,7 @@ test_read_wired_global_gateway (void) NMSettingConnection *s_con; NMSettingWired *s_wired; NMSettingIP4Config *s_ip4; - gboolean unmanaged = FALSE; + char *unmanaged = NULL; char *keyfile = NULL; gboolean ignore_error = FALSE; GError *error = NULL; @@ -881,7 +884,7 @@ test_read_wired_never_default (void) NMSettingConnection *s_con; NMSettingWired *s_wired; NMSettingIP4Config *s_ip4; - gboolean unmanaged = FALSE; + char *unmanaged = NULL; char *keyfile = NULL; gboolean ignore_error = FALSE; GError *error = NULL; @@ -972,7 +975,7 @@ test_read_onboot_no (void) { NMConnection *connection; NMSettingConnection *s_con; - gboolean unmanaged = FALSE; + char *unmanaged = NULL; char *keyfile = NULL; gboolean ignore_error = FALSE; GError *error = NULL; @@ -1022,7 +1025,7 @@ test_read_wired_8021x_peap_mschapv2 (void) NMSettingIP4Config *s_ip4; NMSetting8021x *s_8021x; NMSetting8021x *tmp_8021x; - gboolean unmanaged = FALSE; + char *unmanaged = NULL; char *keyfile = NULL; gboolean ignore_error = FALSE; GError *error = NULL; @@ -1207,7 +1210,7 @@ test_read_wifi_open (void) NMSettingConnection *s_con; NMSettingWireless *s_wireless; NMSettingIP4Config *s_ip4; - gboolean unmanaged = FALSE; + char *unmanaged = NULL; char *keyfile = NULL; gboolean ignore_error = FALSE; GError *error = NULL; @@ -1379,7 +1382,7 @@ test_read_wifi_open_ssid_hex (void) NMConnection *connection; NMSettingConnection *s_con; NMSettingWireless *s_wireless; - gboolean unmanaged = FALSE; + char *unmanaged = NULL; char *keyfile = NULL; gboolean ignore_error = FALSE; GError *error = NULL; @@ -1455,7 +1458,7 @@ static void test_read_wifi_open_ssid_bad (const char *file, const char *test) { NMConnection *connection; - gboolean unmanaged = FALSE; + char *unmanaged = NULL; char *keyfile = NULL; gboolean ignore_error = FALSE; GError *error = NULL; @@ -1473,7 +1476,7 @@ test_read_wifi_open_ssid_quoted (void) NMConnection *connection; NMSettingConnection *s_con; NMSettingWireless *s_wireless; - gboolean unmanaged = FALSE; + char *unmanaged = NULL; char *keyfile = NULL; gboolean ignore_error = FALSE; GError *error = NULL; @@ -1555,7 +1558,7 @@ test_read_wifi_wep (void) NMSettingWireless *s_wireless; NMSettingWirelessSecurity *s_wsec; NMSettingIP4Config *s_ip4; - gboolean unmanaged = FALSE; + char *unmanaged = NULL; char *keyfile = NULL; gboolean ignore_error = FALSE; GError *error = NULL; @@ -1815,7 +1818,7 @@ test_read_wifi_wep_adhoc (void) NMSettingWireless *s_wireless; NMSettingWirelessSecurity *s_wsec; NMSettingIP4Config *s_ip4; - gboolean unmanaged = FALSE; + char *unmanaged = NULL; char *keyfile = NULL; gboolean ignore_error = FALSE; GError *error = NULL; @@ -2073,7 +2076,7 @@ test_read_wifi_leap (void) NMSettingConnection *s_con; NMSettingWireless *s_wireless; NMSettingWirelessSecurity *s_wsec; - gboolean unmanaged = FALSE; + char *unmanaged = NULL; char *keyfile = NULL; gboolean ignore_error = FALSE; GError *error = NULL; @@ -2205,7 +2208,7 @@ test_read_wifi_wpa_psk (void) NMSettingWireless *s_wireless; NMSettingWirelessSecurity *s_wsec; NMSettingIP4Config *s_ip4; - gboolean unmanaged = FALSE; + char *unmanaged = NULL; char *keyfile = NULL; gboolean ignore_error = FALSE; GError *error = NULL; @@ -2515,7 +2518,7 @@ test_read_wifi_wpa_psk_adhoc (void) NMSettingWireless *s_wireless; NMSettingWirelessSecurity *s_wsec; NMSettingIP4Config *s_ip4; - gboolean unmanaged = FALSE; + char *unmanaged = NULL; char *keyfile = NULL; gboolean ignore_error = FALSE; GError *error = NULL; @@ -2698,7 +2701,7 @@ test_read_wifi_wpa_psk_hex (void) NMSettingWireless *s_wireless; NMSettingWirelessSecurity *s_wsec; NMSettingIP4Config *s_ip4; - gboolean unmanaged = FALSE; + char *unmanaged = NULL; char *keyfile = NULL; gboolean ignore_error = FALSE; GError *error = NULL; @@ -2847,7 +2850,7 @@ test_read_wifi_wpa_eap_tls (void) NMSettingWireless *s_wireless; NMSettingIP4Config *s_ip4; NMSetting8021x *s_8021x; - gboolean unmanaged = FALSE; + char *unmanaged = NULL; char *keyfile = NULL; gboolean ignore_error = FALSE; GError *error = NULL; @@ -2981,7 +2984,7 @@ test_read_wifi_wpa_eap_ttls_tls (void) NMSettingWireless *s_wireless; NMSettingIP4Config *s_ip4; NMSetting8021x *s_8021x; - gboolean unmanaged = FALSE; + char *unmanaged = NULL; char *keyfile = NULL; gboolean ignore_error = FALSE; GError *error = NULL; @@ -3137,7 +3140,7 @@ test_read_wifi_wep_eap_ttls_chap (void) NMSettingWirelessSecurity *s_wsec; NMSettingIP4Config *s_ip4; NMSetting8021x *s_8021x; - gboolean unmanaged = FALSE; + char *unmanaged = NULL; char *keyfile = NULL; gboolean ignore_error = FALSE; GError *error = NULL; @@ -3307,7 +3310,7 @@ test_write_wired_static (void) gboolean success; GError *error = NULL; char *testfile = NULL; - gboolean unmanaged = FALSE; + char *unmanaged = NULL; char *keyfile = NULL; gboolean ignore_error = FALSE; @@ -3431,7 +3434,7 @@ test_write_wired_dhcp (void) gboolean success; GError *error = NULL; char *testfile = NULL; - gboolean unmanaged = FALSE; + char *unmanaged = NULL; char *keyfile = NULL; gboolean ignore_error = FALSE; @@ -3530,7 +3533,7 @@ test_write_wired_dhcp_8021x_peap_mschapv2 (void) gboolean success; GError *error = NULL; char *testfile = NULL; - gboolean unmanaged = FALSE; + char *unmanaged = NULL; char *keyfile = NULL; gboolean ignore_error = FALSE; @@ -3651,7 +3654,7 @@ test_write_wifi_open (void) gboolean success; GError *error = NULL; char *testfile = NULL; - gboolean unmanaged = FALSE; + char *unmanaged = NULL; char *keyfile = NULL; gboolean ignore_error = FALSE; GByteArray *ssid; @@ -3771,7 +3774,7 @@ test_write_wifi_open_hex_ssid (void) gboolean success; GError *error = NULL; char *testfile = NULL; - gboolean unmanaged = FALSE; + char *unmanaged = NULL; char *keyfile = NULL; gboolean ignore_error = FALSE; GByteArray *ssid; @@ -3876,7 +3879,7 @@ test_write_wifi_wep (void) gboolean success; GError *error = NULL; char *testfile = NULL; - gboolean unmanaged = FALSE; + char *unmanaged = NULL; char *keyfile = NULL; gboolean ignore_error = FALSE; GByteArray *ssid; @@ -4012,7 +4015,7 @@ test_write_wifi_wep_adhoc (void) gboolean success; GError *error = NULL; char *testfile = NULL; - gboolean unmanaged = FALSE; + char *unmanaged = NULL; char *keyfile = NULL; gboolean ignore_error = FALSE; GByteArray *ssid; @@ -4160,7 +4163,7 @@ test_write_wifi_wpa_psk (const char *name, gboolean success; GError *error = NULL; char *testfile = NULL; - gboolean unmanaged = FALSE; + char *unmanaged = NULL; char *keyfile = NULL; gboolean ignore_error = FALSE; GByteArray *ssid; @@ -4299,7 +4302,7 @@ test_write_wifi_wpa_psk_adhoc (void) gboolean success; GError *error = NULL; char *testfile = NULL; - gboolean unmanaged = FALSE; + char *unmanaged = NULL; char *keyfile = NULL; gboolean ignore_error = FALSE; GByteArray *ssid; @@ -4442,7 +4445,7 @@ test_write_wifi_wpa_eap_tls (void) gboolean success; GError *error = NULL; char *testfile = NULL; - gboolean unmanaged = FALSE; + char *unmanaged = NULL; char *keyfile = NULL; gboolean ignore_error = FALSE; GByteArray *ssid; @@ -4601,7 +4604,7 @@ test_write_wifi_wpa_eap_ttls_tls (void) gboolean success; GError *error = NULL; char *testfile = NULL; - gboolean unmanaged = FALSE; + char *unmanaged = NULL; char *keyfile = NULL; gboolean ignore_error = FALSE; GByteArray *ssid; @@ -4777,7 +4780,7 @@ test_write_wifi_wpa_eap_ttls_mschapv2 (void) gboolean success; GError *error = NULL; char *testfile = NULL; - gboolean unmanaged = FALSE; + char *unmanaged = NULL; char *keyfile = NULL; gboolean ignore_error = FALSE; GByteArray *ssid; diff --git a/system-settings/plugins/ifcfg-suse/Makefile.am b/system-settings/plugins/ifcfg-suse/Makefile.am index 7f1043f64a..b83a35abc0 100644 --- a/system-settings/plugins/ifcfg-suse/Makefile.am +++ b/system-settings/plugins/ifcfg-suse/Makefile.am @@ -16,8 +16,9 @@ libnm_settings_plugin_ifcfg_suse_la_CPPFLAGS = \ $(GMODULE_CFLAGS) \ $(DBUS_CFLAGS) \ $(POLKIT_CFLAGS) \ + $(GUDEV_CFLAGS) \ -DG_DISABLE_DEPRECATED \ - -I${top_srcdir}/system-settings/src \ + -I${top_srcdir}/src/system-settings \ -I$(top_srcdir)/include \ -I$(top_srcdir)/libnm-util \ -I$(top_srcdir)/libnm-glib \ @@ -28,6 +29,7 @@ libnm_settings_plugin_ifcfg_suse_la_LIBADD = \ $(GLIB_LIBS) \ $(GMODULE_LIBS) \ $(POLKIT_LIBS) \ + $(GUDEV_LIBS) \ $(top_builddir)/libnm-util/libnm-util.la \ $(top_builddir)/libnm-glib/libnm_glib.la diff --git a/system-settings/plugins/ifcfg-suse/plugin.c b/system-settings/plugins/ifcfg-suse/plugin.c index 812cdf3d20..c07ff2df60 100644 --- a/system-settings/plugins/ifcfg-suse/plugin.c +++ b/system-settings/plugins/ifcfg-suse/plugin.c @@ -18,7 +18,8 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 Red Hat, Inc. + * (C) Copyright 2007 - 2009 Red Hat, Inc. + * (C) Copyright 2007 - 2008 Novell, Inc. */ #include @@ -28,6 +29,9 @@ #include #include #include +#include +#include +#include #ifndef NO_GIO #include @@ -38,10 +42,14 @@ #include #include +#define G_UDEV_API_IS_SUBJECT_TO_CHANGE +#include + #include "plugin.h" #include "parser.h" #include "nm-suse-connection.h" #include "nm-system-config-interface.h" +#include "wireless-helper.h" #define IFCFG_PLUGIN_NAME "ifcfg-suse" #define IFCFG_PLUGIN_INFO "(C) 2008 Novell, Inc. To report bugs please use the NetworkManager mailing list." @@ -50,8 +58,8 @@ static void system_config_interface_init (NMSystemConfigInterface *system_config_interface_class); G_DEFINE_TYPE_EXTENDED (SCPluginIfcfg, sc_plugin_ifcfg, G_TYPE_OBJECT, 0, - G_IMPLEMENT_INTERFACE (NM_TYPE_SYSTEM_CONFIG_INTERFACE, - system_config_interface_init)) + G_IMPLEMENT_INTERFACE (NM_TYPE_SYSTEM_CONFIG_INTERFACE, + system_config_interface_init)) #define SC_PLUGIN_IFCFG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SC_TYPE_PLUGIN_IFCFG, SCPluginIfcfgPrivate)) @@ -59,12 +67,11 @@ G_DEFINE_TYPE_EXTENDED (SCPluginIfcfg, sc_plugin_ifcfg, G_TYPE_OBJECT, 0, #define IFCFG_FILE_PATH_TAG "ifcfg-file-path" typedef struct { - DBusGConnection *dbus_connection; - NMSystemConfigHalManager *hal_manager; + GUdevClient *client; gboolean initialized; GHashTable *connections; - GHashTable *unmanaged_devices; + GHashTable *unmanaged_specs; guint32 default_gw; GFileMonitor *default_gw_monitor; @@ -163,114 +170,140 @@ monitor_routes (SCPluginIfcfg *self, const char *filename) } } -static char * -get_iface_by_udi (SCPluginIfcfg *self, const char *udi) +static void +read_connection (SCPluginIfcfg *self, GUdevDevice *device, NMDeviceType dev_type) { SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self); - DBusGProxy *proxy; - char *iface = NULL; + const char *iface, *address; + guint32 ifindex; - proxy = dbus_g_proxy_new_for_name (priv->dbus_connection, - "org.freedesktop.Hal", - udi, - "org.freedesktop.Hal.Device"); - - dbus_g_proxy_call_with_timeout (proxy, "GetPropertyString", 10000, NULL, - G_TYPE_STRING, "net.interface", G_TYPE_INVALID, - G_TYPE_STRING, &iface, G_TYPE_INVALID); - g_object_unref (proxy); + iface = g_udev_device_get_name (device); + if (!iface) + return; - return iface; -} + ifindex = (guint32) g_udev_device_get_property_as_uint64 (device, "IFINDEX"); -static void -read_connection (SCPluginIfcfg *self, const char *udi, NMDeviceType dev_type) -{ - SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self); - char *iface; + if (parser_ignore_device (iface)) { + char *spec; - iface = get_iface_by_udi (self, udi); - if (iface) { - if (parser_ignore_device (iface)) { - g_hash_table_insert (priv->unmanaged_devices, g_strdup (udi), GINT_TO_POINTER (1)); + address = g_udev_device_get_sysfs_attr (device, "address"); + if (address && (strlen (address) == 17)) { + spec = g_strdup_printf ("mac:%s", address); + g_hash_table_insert (priv->unmanaged_specs, GUINT_TO_POINTER (ifindex), spec); g_signal_emit_by_name (self, "unmanaged-devices-changed"); - } else { - NMSuseConnection *connection; - - connection = nm_suse_connection_new (iface, dev_type); - if (connection) { - g_hash_table_insert (priv->connections, g_strdup (udi), connection); - g_signal_emit_by_name (self, "connection-added", connection); - } + } else + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " (%s) error getting hardware address", iface); + } else { + NMSuseConnection *connection; + + connection = nm_suse_connection_new (iface, dev_type); + if (connection) { + g_hash_table_insert (priv->connections, + GUINT_TO_POINTER (ifindex), + connection); + g_signal_emit_by_name (self, "connection-added", connection); } } - - g_free (iface); } static void read_connections_by_type (SCPluginIfcfg *self, NMDeviceType dev_type) { SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self); - GSList *list; - GSList *iter; + GList *devices, *iter; - list = nm_system_config_hal_manager_get_devices_of_type (priv->hal_manager, dev_type); - for (iter = list; iter; iter = iter->next) { - read_connection (self, (char *) iter->data, dev_type); - g_free (iter->data); - } + if ( (dev_type != NM_DEVICE_TYPE_ETHERNET) + && (dev_type != NM_DEVICE_TYPE_WIFI)) + return; - g_slist_free (list); + devices = g_udev_client_query_by_subsystem (priv->client, "net"); + for (iter = devices; iter; iter = g_list_next (iter)) { + read_connection (self, G_UDEV_DEVICE (iter->data), dev_type); + g_object_unref (G_UDEV_DEVICE (iter->data)); + } + g_list_free (devices); } -static void -device_added_cb (NMSystemConfigHalManager *hal_mgr, - const char *udi, - NMDeviceType dev_type, - gpointer user_data) +static gboolean +is_wireless (GUdevDevice *device) { - SCPluginIfcfg *self = SC_PLUGIN_IFCFG (user_data); + char phy80211_path[255]; + struct stat s; + int fd; + struct iwreq iwr; + const char *ifname, *path; + gboolean is_wifi = FALSE; - if (dev_type != NM_DEVICE_TYPE_ETHERNET && dev_type != NM_DEVICE_TYPE_WIFI) - return; + ifname = g_udev_device_get_name (device); + g_assert (ifname); + + fd = socket (PF_INET, SOCK_DGRAM, 0); + strncpy (iwr.ifr_ifrn.ifrn_name, ifname, IFNAMSIZ); - read_connection (self, udi, dev_type); + path = g_udev_device_get_sysfs_path (device); + snprintf (phy80211_path, sizeof (phy80211_path), "%s/phy80211", path); + + if ( (ioctl (fd, SIOCGIWNAME, &iwr) == 0) + || (stat (phy80211_path, &s) == 0 && (s.st_mode & S_IFDIR))) + is_wifi = TRUE; + + close (fd); + return is_wifi; } static void -device_removed_cb (NMSystemConfigHalManager *hal_mgr, - const char *udi, - NMDeviceType dev_type, - gpointer user_data) +handle_uevent (GUdevClient *client, + const char *action, + GUdevDevice *device, + gpointer user_data) { SCPluginIfcfg *self = SC_PLUGIN_IFCFG (user_data); SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self); - NMExportedConnection *exported; + const char *subsys; + gboolean wifi; - if (dev_type != NM_DEVICE_TYPE_ETHERNET && dev_type != NM_DEVICE_TYPE_WIFI) - return; + g_return_if_fail (action != NULL); + + /* A bit paranoid */ + subsys = g_udev_device_get_subsystem (device); + g_return_if_fail (subsys != NULL); + g_return_if_fail (strcmp (subsys, "net") == 0); - if (g_hash_table_remove (priv->unmanaged_devices, udi)) - g_signal_emit_by_name (self, "unmanaged-devices-changed"); + wifi = is_wireless (device); - exported = (NMExportedConnection *) g_hash_table_lookup (priv->connections, udi); - if (exported) { - nm_exported_connection_signal_removed (exported); - g_hash_table_remove (priv->connections, udi); + if (!strcmp (action, "add")) { + read_connection (self, + device, + wifi ? NM_DEVICE_TYPE_WIFI : NM_DEVICE_TYPE_ETHERNET); + } else if (!strcmp (action, "remove")) { + NMExportedConnection *exported; + guint32 ifindex; + + ifindex = (guint32) g_udev_device_get_property_as_uint64 (device, "IFINDEX"); + if (g_hash_table_remove (priv->unmanaged_specs, GUINT_TO_POINTER (ifindex))) + g_signal_emit_by_name (self, "unmanaged-devices-changed"); + + exported = (NMExportedConnection *) g_hash_table_lookup (priv->connections, + GUINT_TO_POINTER (ifindex)); + if (exported) { + nm_exported_connection_signal_removed (exported); + g_hash_table_remove (priv->connections, GUINT_TO_POINTER (ifindex)); + } } } static void -init (NMSystemConfigInterface *config, NMSystemConfigHalManager *hal_manager) +init (NMSystemConfigInterface *config) { SCPluginIfcfg *self = SC_PLUGIN_IFCFG (config); SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self); + const char *subsys[2] = { "net", NULL }; - priv->hal_manager = g_object_ref (hal_manager); - - g_signal_connect (priv->hal_manager, "device-added", G_CALLBACK (device_added_cb), self); - g_signal_connect (priv->hal_manager, "device-removed", G_CALLBACK (device_removed_cb), self); + priv->client = g_udev_client_new (subsys); + if (!priv->client) { + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " error initializing libgudev"); + } else + g_signal_connect (priv->client, "uevent", G_CALLBACK (handle_uevent), self); } static void @@ -309,21 +342,21 @@ get_connections (NMSystemConfigInterface *config) } static void -get_unamanged_devices_cb (gpointer key, gpointer val, gpointer user_data) +add_one_unmanaged_spec (gpointer key, gpointer val, gpointer user_data) { GSList **list = (GSList **) key; - *list = g_slist_prepend (*list, g_strdup ((char *) key)); + *list = g_slist_prepend (*list, g_strdup ((const char *) val)); } static GSList * -get_unmanaged_devices (NMSystemConfigInterface *config) +get_unmanaged_specs (NMSystemConfigInterface *config) { + SCPluginIfcfg *self = SC_PLUGIN_IFCFG (config); + SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self); GSList *list = NULL; - g_hash_table_foreach (SC_PLUGIN_IFCFG_GET_PRIVATE (config)->unmanaged_devices, - get_unamanged_devices_cb, &list); - + g_hash_table_foreach (priv->unmanaged_specs, add_one_unmanaged_spec, &list); return list; } @@ -331,17 +364,9 @@ static void sc_plugin_ifcfg_init (SCPluginIfcfg *self) { SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self); - GError *err = NULL; - priv->connections = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); - priv->unmanaged_devices = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); - - priv->dbus_connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &err); - if (!priv->dbus_connection) { - PLUGIN_PRINT (IFCFG_PLUGIN_NAME, " dbus-glib error: %s", - err->message ? err->message : "(unknown)"); - g_error_free (err); - } + priv->connections = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_object_unref); + priv->unmanaged_specs = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free); } static void @@ -350,7 +375,7 @@ dispose (GObject *object) SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (object); g_hash_table_destroy (priv->connections); - g_hash_table_destroy (priv->unmanaged_devices); + g_hash_table_destroy (priv->unmanaged_specs); if (priv->default_gw_monitor) { if (priv->default_gw_monitor_id) @@ -360,10 +385,8 @@ dispose (GObject *object) g_object_unref (priv->default_gw_monitor); } - if (priv->hal_manager) - g_object_unref (priv->hal_manager); - - dbus_g_connection_unref (priv->dbus_connection); + if (priv->client) + g_object_unref (priv->client); G_OBJECT_CLASS (sc_plugin_ifcfg_parent_class)->dispose (object); } @@ -423,7 +446,7 @@ system_config_interface_init (NMSystemConfigInterface *system_config_interface_c { /* interface implementation */ system_config_interface_class->get_connections = get_connections; - system_config_interface_class->get_unmanaged_devices = get_unmanaged_devices; + system_config_interface_class->get_unmanaged_specs = get_unmanaged_specs; system_config_interface_class->init = init; } diff --git a/system-settings/plugins/ifupdown/Makefile.am b/system-settings/plugins/ifupdown/Makefile.am index 0c7ab2461c..eca264be5a 100644 --- a/system-settings/plugins/ifupdown/Makefile.am +++ b/system-settings/plugins/ifupdown/Makefile.am @@ -1,29 +1,34 @@ INCLUDES = \ - -I${top_srcdir}/src + -I$(top_srcdir)/src/system-settings \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/libnm-glib \ + -I$(top_srcdir)/libnm-util pkglib_LTLIBRARIES = libnm-settings-plugin-ifupdown.la libnm_settings_plugin_ifupdown_la_SOURCES = \ - interface_parser.c interface_parser.h \ - nm-ifupdown-connection.c nm-ifupdown-connection.h \ - parser.c parser.h \ - plugin.c plugin.h + interface_parser.c \ + interface_parser.h \ + nm-ifupdown-connection.c \ + nm-ifupdown-connection.h \ + parser.c \ + parser.h \ + plugin.c \ + plugin.h libnm_settings_plugin_ifupdown_la_CPPFLAGS = \ $(GLIB_CFLAGS) \ $(GMODULE_CFLAGS) \ $(DBUS_CFLAGS) \ + $(GUDEV_CFLAGS) \ -DG_DISABLE_DEPRECATED \ - -I${top_srcdir}/system-settings/src \ - -I$(top_srcdir)/include \ - -I$(top_srcdir)/libnm-glib \ - -I$(top_srcdir)/libnm-util \ -DSYSCONFDIR=\"$(sysconfdir)\" libnm_settings_plugin_ifupdown_la_LDFLAGS = -module -avoid-version libnm_settings_plugin_ifupdown_la_LIBADD = \ $(GLIB_LIBS) \ $(GMODULE_LIBS) \ + $(GUDEV_LIBS) \ $(top_builddir)/libnm-util/libnm-util.la diff --git a/system-settings/plugins/ifupdown/interface_parser.c b/system-settings/plugins/ifupdown/interface_parser.c index dd0ba61455..f28cf7cab1 100644 --- a/system-settings/plugins/ifupdown/interface_parser.c +++ b/system-settings/plugins/ifupdown/interface_parser.c @@ -22,7 +22,6 @@ #include "interface_parser.h" -#include "NetworkManagerUtils.h" #include #include #include diff --git a/system-settings/plugins/ifupdown/plugin.c b/system-settings/plugins/ifupdown/plugin.c index c33f9d10f1..63fdd832cd 100644 --- a/system-settings/plugins/ifupdown/plugin.c +++ b/system-settings/plugins/ifupdown/plugin.c @@ -1,4 +1,4 @@ -/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager system settings service (ifupdown) * @@ -19,6 +19,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * (C) Copyright 2007,2008 Canonical Ltd. + * (C) Copyright 2009 Red Hat, Inc. */ #include @@ -35,6 +36,7 @@ #include "interface_parser.h" +#include "NetworkManager.h" #include "nm-system-config-interface.h" #include "nm-setting-ip4-config.h" #include "nm-setting-wireless.h" @@ -50,6 +52,9 @@ #include +#define G_UDEV_API_IS_SUBJECT_TO_CHANGE +#include + #define IFUPDOWN_PLUGIN_NAME "ifupdown" #define IFUPDOWN_PLUGIN_INFO "(C) 2008 Canonical Ltd. To report bugs please use the NetworkManager mailing list." #define IFUPDOWN_SYSTEM_HOSTNAME_FILE "/etc/hostname" @@ -65,14 +70,12 @@ #endif typedef struct { - - DBusGConnection *g_connection; - NMSystemConfigHalManager *hal_mgr; + GUdevClient *client; GHashTable *iface_connections; gchar* hostname; - GHashTable *well_known_udis; + GHashTable *well_known_ifaces; gboolean unmanage_well_known; gulong inotify_event_id; @@ -92,8 +95,7 @@ static void sc_plugin_ifupdown_class_init (SCPluginIfupdownClass *req_class); static void -SCPluginIfupdown_init (NMSystemConfigInterface *config, - NMSystemConfigHalManager *hal_manager); +SCPluginIfupdown_init (NMSystemConfigInterface *config); /* Returns the plugins currently known list of connections. The returned * list is freed by the system settings service. @@ -102,12 +104,12 @@ static GSList* SCPluginIfupdown_get_connections (NMSystemConfigInterface *config); /* - * Return a list of HAL UDIs of devices which NetworkManager should not + * Return a list of device specifications which NetworkManager should not * manage. Returned list will be freed by the system settings service, and * each element must be allocated using g_malloc() or its variants. */ static GSList* -SCPluginIfupdown_get_unmanaged_devices (NMSystemConfigInterface *config); +SCPluginIfupdown_get_unmanaged_specs (NMSystemConfigInterface *config); /* GObject */ @@ -142,7 +144,7 @@ system_config_interface_init (NMSystemConfigInterface *system_config_interface_c { system_config_interface_class->init = SCPluginIfupdown_init; system_config_interface_class->get_connections = SCPluginIfupdown_get_connections; - system_config_interface_class->get_unmanaged_devices = SCPluginIfupdown_get_unmanaged_devices; + system_config_interface_class->get_unmanaged_specs = SCPluginIfupdown_get_unmanaged_specs; } static void @@ -174,329 +176,251 @@ sc_plugin_ifupdown_class_init (SCPluginIfupdownClass *req_class) NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME); } -static GByteArray* -get_net_address_for_udi (DBusGConnection *g_connection, - const gchar* udi, - GError **error) -{ - DBusGProxy *dev_proxy; - char *address = NULL; - GByteArray *mac_address = NULL; - dev_proxy = dbus_g_proxy_new_for_name (g_connection, - "org.freedesktop.Hal", - udi, - "org.freedesktop.Hal.Device"); - if (!dev_proxy) - return NULL; - - if (!dbus_g_proxy_call_with_timeout (dev_proxy, - "GetPropertyString", 10000, error, - G_TYPE_STRING, "net.address", G_TYPE_INVALID, - G_TYPE_STRING, &address, G_TYPE_INVALID)) { - goto out; - } - - if (address && strlen (address)) { - struct ether_addr *dev_mac; - mac_address = g_byte_array_new(); - dev_mac = ether_aton (address); - g_byte_array_append (mac_address, dev_mac->ether_addr_octet, ETH_ALEN); - } - - out: - g_free(address); - g_object_unref (dev_proxy); - return mac_address; -} - -static gchar* -get_iface_for_udi (DBusGConnection *g_connection, - const gchar* udi, - GError **error) -{ - DBusGProxy *dev_proxy; - char *iface = NULL; - dev_proxy = dbus_g_proxy_new_for_name (g_connection, - "org.freedesktop.Hal", - udi, - "org.freedesktop.Hal.Device"); - if (!dev_proxy) - return NULL; - - if (dbus_g_proxy_call_with_timeout (dev_proxy, - "GetPropertyString", 10000, error, - G_TYPE_STRING, "net.interface", G_TYPE_INVALID, - G_TYPE_STRING, &iface, G_TYPE_INVALID)) { - g_object_unref (dev_proxy); - return iface; - } - g_object_unref (dev_proxy); - return NULL; -} - static void -bind_device_to_connection (NMSystemConfigInterface *config, - DBusGConnection *g_connection, - const gchar* udi, - NMExportedConnection *exported_iface_connection) +bind_device_to_connection (SCPluginIfupdown *self, + GUdevDevice *device, + NMExportedConnection *exported) { GByteArray *mac_address; - GError *error = NULL; - NMConnection *iface_connection; - NMSetting *wired_setting = NULL; - NMSetting *wireless_setting = NULL; + NMConnection *connection; + NMSetting *s_wired = NULL; + NMSetting *s_wifi = NULL; + const char *iface, *address; + struct ether_addr *tmp_mac; + + iface = g_udev_device_get_name (device); + if (!iface) { + PLUGIN_WARN ("SCPluginIfupdown", "failed to get ifname for device."); + return; + } - iface_connection = nm_exported_connection_get_connection (exported_iface_connection); - if (!iface_connection) { - nm_warning ("no device locking possible. NMExportedConnection doesnt have a real connection."); + connection = nm_exported_connection_get_connection (exported); + if (!connection) { + PLUGIN_WARN ("SCPluginIfupdown", "no device locking possible. " + "NMExportedConnection doesnt have a real connection."); return; } - mac_address = get_net_address_for_udi (g_connection, udi, &error); + address = g_udev_device_get_sysfs_attr (device, "address"); + if (!address || !strlen (address)) { + PLUGIN_WARN ("SCPluginIfupdown", "failed to get MAC address for %s", iface); + return; + } - if(error) { - PLUGIN_PRINT ("SCPluginIfupdown", "getting mac address for managed device" - "failed: %s (%d)", error->message, error->code); + tmp_mac = ether_aton (address); + if (!tmp_mac) { + PLUGIN_WARN ("SCPluginIfupdown", "failed to parse MAC address '%s' for %s", + address, iface); return; } - wired_setting = nm_connection_get_setting (iface_connection, - NM_TYPE_SETTING_WIRED); - wireless_setting = nm_connection_get_setting (iface_connection, - NM_TYPE_SETTING_WIRELESS); - if (wired_setting) { + mac_address = g_byte_array_sized_new (ETH_ALEN); + g_byte_array_append (mac_address, &(tmp_mac->ether_addr_octet[0]), ETH_ALEN); + + s_wired = nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED); + s_wifi = nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS); + if (s_wifi) { PLUGIN_PRINT ("SCPluginIfupdown", "locking wired connection setting"); - g_object_set (wired_setting, NM_SETTING_WIRED_MAC_ADDRESS, mac_address, NULL); - } else if (wireless_setting) { + g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, mac_address, NULL); + } else if (s_wifi) { PLUGIN_PRINT ("SCPluginIfupdown", "locking wireless connection setting"); - g_object_set (wireless_setting, NM_SETTING_WIRELESS_MAC_ADDRESS, mac_address, NULL); + g_object_set (s_wifi, NM_SETTING_WIRELESS_MAC_ADDRESS, mac_address, NULL); } - if(mac_address) - g_byte_array_free (mac_address, TRUE); + g_byte_array_free (mac_address, TRUE); } static void -hal_device_added_cb (NMSystemConfigHalManager *hal_mgr, - const gchar* udi, - NMDeviceType devtype, - NMSystemConfigInterface *config) +udev_device_added (SCPluginIfupdown *self, GUdevDevice *device) { - SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (config); - gchar *iface = NULL; - GError *error = NULL; - gpointer exported_iface_connection; - NMConnection *iface_connection = NULL; + SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (self); + const char *iface, *path; + NMExportedConnection *exported; - iface = get_iface_for_udi (priv->g_connection, - udi, - &error); - - PLUGIN_PRINT("SCPlugin-Ifupdown", - "devices added (udi: %s, iface: %s)", udi, iface); - - if(!iface) + iface = g_udev_device_get_name (device); + path = g_udev_device_get_sysfs_path (device); + if (!iface || !path) return; - exported_iface_connection = - NM_EXPORTED_CONNECTION (g_hash_table_lookup (priv->iface_connections, iface)); + PLUGIN_PRINT("SCPlugin-Ifupdown", + "devices added (path: %s, iface: %s)", path, iface); /* if we have a configured connection for this particular iface * we want to either unmanage the device or lock it */ - if(!exported_iface_connection) - goto out; - - iface_connection = nm_exported_connection_get_connection (exported_iface_connection); - - if(!iface_connection) - goto out; + exported = (NMExportedConnection *) g_hash_table_lookup (priv->iface_connections, iface); + if (!exported) + return; - g_hash_table_insert (priv->well_known_udis, (gpointer)udi, "nothing"); + g_hash_table_insert (priv->well_known_ifaces, g_strdup (iface), g_object_ref (device)); if (ALWAYS_UNMANAGE || priv->unmanage_well_known) - g_signal_emit_by_name (G_OBJECT(config), "unmanaged-devices-changed"); + g_signal_emit_by_name (G_OBJECT (self), "unmanaged-devices-changed"); else - bind_device_to_connection (config, priv->g_connection, udi, exported_iface_connection); - - out: - g_free (iface); + bind_device_to_connection (self, device, exported); } static void -hal_device_removed_cb (NMSystemConfigHalManager *hal_mgr, - const gchar* udi, - NMDeviceType devtype, - NMSystemConfigInterface *config) +udev_device_removed (SCPluginIfupdown *self, GUdevDevice *device) { - SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (config); + SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (self); + const char *iface, *path; + + iface = g_udev_device_get_name (device); + path = g_udev_device_get_sysfs_path (device); + if (!iface || !path) + return; PLUGIN_PRINT("SCPlugin-Ifupdown", - "devices removed (udi: %s)", udi); + "devices removed (path: %s, iface: %s)", path, iface); - if(!g_hash_table_remove (priv->well_known_udis, udi)) + if (!g_hash_table_remove (priv->well_known_ifaces, iface)) return; if (ALWAYS_UNMANAGE || priv->unmanage_well_known) - g_signal_emit_by_name (G_OBJECT(config), "unmanaged-devices-changed"); + g_signal_emit_by_name (G_OBJECT (self), "unmanaged-devices-changed"); } static void -hal_device_added_cb2 (gpointer data, - gpointer user_data) +handle_uevent (GUdevClient *client, + const char *action, + GUdevDevice *device, + gpointer user_data) { - NMSystemConfigHalManager *hal_mgr = ((gpointer*)user_data)[0]; - NMSystemConfigInterface *config = ((gpointer*)user_data)[1]; - NMDeviceType devtype = GPOINTER_TO_INT(((gpointer*)user_data)[2]); - const gchar *udi = data; - - hal_device_added_cb (hal_mgr, - udi, - devtype, - config); + SCPluginIfupdown *self = SC_PLUGIN_IFUPDOWN (user_data); + const char *subsys; + + g_return_if_fail (action != NULL); + + /* A bit paranoid */ + subsys = g_udev_device_get_subsystem (device); + g_return_if_fail (subsys != NULL); + g_return_if_fail (strcmp (subsys, "net") == 0); + + if (!strcmp (action, "add")) + udev_device_added (self, device); + else if (!strcmp (action, "remove")) + udev_device_removed (self, device); } static void -SCPluginIfupdown_init (NMSystemConfigInterface *config, - NMSystemConfigHalManager *hal_manager) +SCPluginIfupdown_init (NMSystemConfigInterface *config) { - SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (config); - GHashTable *auto_ifaces = g_hash_table_new (g_str_hash, g_str_equal); + SCPluginIfupdown *self = SC_PLUGIN_IFUPDOWN (config); + SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (self); + GHashTable *auto_ifaces; if_block *block = NULL; NMInotifyHelper *inotify_helper; GKeyFile* keyfile; GError *error = NULL; + GList *keys, *iter; + const char *subsys[2] = { "net", NULL }; + + auto_ifaces = g_hash_table_new (g_str_hash, g_str_equal); if(!priv->iface_connections) priv->iface_connections = g_hash_table_new (g_str_hash, g_str_equal); - if(!priv->well_known_udis) - priv->well_known_udis = g_hash_table_new (g_str_hash, g_str_equal); + if(!priv->well_known_ifaces) + priv->well_known_ifaces = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); PLUGIN_PRINT("SCPlugin-Ifupdown", "init!"); - priv->hal_mgr = g_object_ref (hal_manager); - g_signal_connect (G_OBJECT(hal_manager), - "device-added", - G_CALLBACK(hal_device_added_cb), - config); + priv->client = g_udev_client_new (subsys); + if (!priv->client) { + PLUGIN_WARN ("SCPlugin-Ifupdown", " error initializing libgudev"); + } else + g_signal_connect (priv->client, "uevent", G_CALLBACK (handle_uevent), self); - g_signal_connect (G_OBJECT(hal_manager), - "device-removed", - G_CALLBACK(hal_device_removed_cb), - config); + priv->unmanage_well_known = IFUPDOWN_UNMANAGE_WELL_KNOWN_DEFAULT; inotify_helper = nm_inotify_helper_get (); priv->inotify_event_id = g_signal_connect (inotify_helper, - "event", - G_CALLBACK (update_system_hostname), - config); + "event", + G_CALLBACK (update_system_hostname), + config); priv->inotify_system_hostname_wd = nm_inotify_helper_add_watch (inotify_helper, IFUPDOWN_SYSTEM_HOSTNAME_FILE); - update_system_hostname(inotify_helper, NULL, NULL, config); + update_system_hostname (inotify_helper, NULL, NULL, config); - ifparser_init(); - block = ifparser_getfirst(); + /* Read in all the interfaces */ + ifparser_init (); + block = ifparser_getfirst (); + while (block) { + if(!strcmp ("auto", block->type)) + g_hash_table_insert (auto_ifaces, block->name, GUINT_TO_POINTER (1)); + else if (!strcmp ("iface", block->type) && strcmp ("lo", block->name)) { + NMExportedConnection *exported; - while(block) { - if(!strcmp("auto", block->type)) { - g_hash_table_insert (auto_ifaces, block->name, "auto"); - } else if (!strcmp ("iface", block->type) && strcmp ("lo", block->name)) { - NMExportedConnection *connection = g_hash_table_lookup(priv->iface_connections, block->name); g_hash_table_remove (priv->iface_connections, block->name); - connection = NM_EXPORTED_CONNECTION(nm_ifupdown_connection_new(block)); - ifupdown_update_connection_from_if_block (nm_exported_connection_get_connection(connection), - block); - - g_hash_table_insert (priv->iface_connections, block->name, connection); + exported = NM_EXPORTED_CONNECTION (nm_ifupdown_connection_new (block)); + ifupdown_update_connection_from_if_block (nm_exported_connection_get_connection (exported), + block); + g_hash_table_insert (priv->iface_connections, block->name, exported); } - block = block -> next; + block = block->next; } - { - GList *keys = g_hash_table_get_keys (priv->iface_connections); - GList *key_it = keys; - while(key_it) { - gpointer val = g_hash_table_lookup(auto_ifaces, key_it->data); - if(val) { - NMExportedConnection *connection = - g_hash_table_lookup(priv->iface_connections, key_it->data); - NMConnection *wrapped = NULL; - NMSetting *setting; - g_object_get(connection, - NM_EXPORTED_CONNECTION_CONNECTION, &wrapped, NULL); - setting = NM_SETTING(nm_connection_get_setting - (wrapped, NM_TYPE_SETTING_CONNECTION)); - g_object_set (setting, - "autoconnect", TRUE, - NULL); - PLUGIN_PRINT("SCPlugin-Ifupdown", "autoconnect"); - } - key_it = key_it -> next; - } + /* Make 'auto' interfaces autoconnect=TRUE */ + keys = g_hash_table_get_keys (priv->iface_connections); + for (iter = keys; iter; iter = g_list_next (iter)) { + NMExportedConnection *exported; + NMConnection *wrapped; + NMSetting *setting; + + if (!g_hash_table_lookup (auto_ifaces, iter->data)) + continue; + + exported = g_hash_table_lookup (priv->iface_connections, iter->data); + wrapped = nm_exported_connection_get_connection (exported); + setting = NM_SETTING (nm_connection_get_setting (wrapped, NM_TYPE_SETTING_CONNECTION)); + g_object_set (setting, NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NULL); + PLUGIN_PRINT("SCPlugin-Ifupdown", "autoconnect"); } + g_list_free (keys); + g_hash_table_destroy (auto_ifaces); - priv->unmanage_well_known = IFUPDOWN_UNMANAGE_WELL_KNOWN_DEFAULT; keyfile = g_key_file_new (); if (!g_key_file_load_from_file (keyfile, - IFUPDOWN_SYSTEM_SETTINGS_KEY_FILE, - G_KEY_FILE_NONE, - &error)) { - nm_info ("loading system config file (%s) caused error: %s (%d)", - IFUPDOWN_SYSTEM_SETTINGS_KEY_FILE, - error->message, - error->code); + IFUPDOWN_SYSTEM_SETTINGS_KEY_FILE, + G_KEY_FILE_NONE, + &error)) { + nm_info ("loading system config file (%s) caused error: (%d) %s", + IFUPDOWN_SYSTEM_SETTINGS_KEY_FILE, + error ? error->code : -1, + error && error->message ? error->message : "(unknown)"); } else { gboolean manage_well_known; error = NULL; manage_well_known = g_key_file_get_boolean (keyfile, - IFUPDOWN_KEY_FILE_GROUP, - IFUPDOWN_KEY_FILE_KEY_MANAGED, - &error); + IFUPDOWN_KEY_FILE_GROUP, + IFUPDOWN_KEY_FILE_KEY_MANAGED, + &error); if (error) { - nm_info ("getting keyfile key '%s' in group '%s' failed: %s (%d)", - IFUPDOWN_KEY_FILE_GROUP, - IFUPDOWN_KEY_FILE_KEY_MANAGED, - error->message, - error->code); - } else { + nm_info ("getting keyfile key '%s' in group '%s' failed: (%d) %s", + IFUPDOWN_KEY_FILE_GROUP, + IFUPDOWN_KEY_FILE_KEY_MANAGED, + error ? error->code : -1, + error && error->message ? error->message : "(unknown)"); + } else priv->unmanage_well_known = !manage_well_known; - } } PLUGIN_PRINT ("SCPluginIfupdown", "management mode: %s", priv->unmanage_well_known ? "unmanaged" : "managed"); if (keyfile) g_key_file_free (keyfile); - { - /* init well_known_udis */ - GSList *wired_devices = nm_system_config_hal_manager_get_devices_of_type (hal_manager, NM_DEVICE_TYPE_ETHERNET); - GSList *wifi_devices = nm_system_config_hal_manager_get_devices_of_type (hal_manager, NM_DEVICE_TYPE_WIFI); - gpointer *user_data; - - /* 3g in /etc/network/interfaces? no clue if thats mappable - - GSList *gsm_devices = nm_system_config_hal_manager_get_devices_of_type (hal_manager, NM_DEVICE_TYPE_GSM); - GSList *cdma_devices = nm_system_config_hal_manager_get_devices_of_type (hal_manager, NM_DEVICE_TYPE_CDMA); - */ - - user_data = g_new0 (gpointer, 3); - user_data[0] = hal_manager; - user_data[1] = config; - user_data[2] = GINT_TO_POINTER (NM_DEVICE_TYPE_ETHERNET); - - g_slist_foreach (wired_devices, hal_device_added_cb2, user_data); - - user_data[0] = hal_manager; - user_data[1] = config; - user_data[2] = GINT_TO_POINTER (NM_DEVICE_TYPE_ETHERNET); - g_slist_foreach (wifi_devices, hal_device_added_cb2, user_data); - } + /* Add well-known interfaces */ + keys = g_udev_client_query_by_subsystem (priv->client, "net"); + for (iter = keys; iter; iter = g_list_next (iter)) { + udev_device_added (self, G_UDEV_DEVICE (iter->data)); + g_object_unref (G_UDEV_DEVICE (iter->data)); + } + g_list_free (keys); - g_hash_table_unref(auto_ifaces); PLUGIN_PRINT("SCPlugin-Ifupdown", "end _init."); } @@ -523,27 +447,37 @@ SCPluginIfupdown_get_connections (NMSystemConfigInterface *config) } /* - * Return a list of HAL UDIs of devices which NetworkManager should not + * Return a list of device specifications which NetworkManager should not * manage. Returned list will be freed by the system settings service, and * each element must be allocated using g_malloc() or its variants. */ static GSList* -SCPluginIfupdown_get_unmanaged_devices (NMSystemConfigInterface *config) +SCPluginIfupdown_get_unmanaged_specs (NMSystemConfigInterface *config) { SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (config); - GList *keys; - GSList *udis = NULL; + GList *keys, *iter; + GSList *specs = NULL; if (!ALWAYS_UNMANAGE && !priv->unmanage_well_known) return NULL; - keys = g_hash_table_get_keys (priv->well_known_udis); - PLUGIN_PRINT("Ifupdown", "get unmanaged devices count: %d", g_list_length(keys)); - while(keys) { - udis = g_slist_append(udis, g_strdup(keys->data)); - keys = g_list_next(keys); + keys = g_hash_table_get_keys (priv->well_known_ifaces); + PLUGIN_PRINT("Ifupdown", "get unmanaged devices count: %d", g_list_length (keys)); + + for (iter = keys; iter; iter = g_list_next (iter)) { + GUdevDevice *device = G_UDEV_DEVICE (iter->data); + const char *address; + char *spec; + + address = g_udev_device_get_sysfs_attr (device, "address"); + if (!address) + continue; + + spec = g_strdup_printf ("mac:%s", address); + specs = g_slist_append (specs, spec); } - return udis; + g_list_free (keys); + return specs; } @@ -615,15 +549,6 @@ write_system_hostname(NMSystemConfigInterface *config, static void sc_plugin_ifupdown_init (SCPluginIfupdown *plugin) { - SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (plugin); - GError *error = NULL; - - priv->g_connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); - if (!priv->g_connection) { - PLUGIN_PRINT ("SCPlugin-Ifupdown", " dbus-glib error: %s", - error->message ? error->message : "(unknown)"); - g_error_free (error); - } } static void @@ -685,10 +610,12 @@ GObject__dispose (GObject *object) if (priv->inotify_system_hostname_wd >= 0) nm_inotify_helper_remove_watch (inotify_helper, priv->inotify_system_hostname_wd); - if (priv->well_known_udis) - g_hash_table_destroy(priv->well_known_udis); + if (priv->well_known_ifaces) + g_hash_table_destroy(priv->well_known_ifaces); + + if (priv->client) + g_object_unref (priv->client); - g_object_unref (priv->hal_mgr); G_OBJECT_CLASS (sc_plugin_ifupdown_parent_class)->dispose (object); } diff --git a/system-settings/plugins/keyfile/Makefile.am b/system-settings/plugins/keyfile/Makefile.am index e904577aba..dccc9d617f 100644 --- a/system-settings/plugins/keyfile/Makefile.am +++ b/system-settings/plugins/keyfile/Makefile.am @@ -1,7 +1,7 @@ SUBDIRS=io tests INCLUDES = \ - -I$(top_srcdir)/system-settings/src \ + -I$(top_srcdir)/src/system-settings \ -I$(top_srcdir)/include \ -I$(top_srcdir)/libnm-util \ -I$(top_srcdir)/libnm-glib \ diff --git a/system-settings/plugins/keyfile/plugin.c b/system-settings/plugins/keyfile/plugin.c index 3a3f6ff7f2..f981f34e37 100644 --- a/system-settings/plugins/keyfile/plugin.c +++ b/system-settings/plugins/keyfile/plugin.c @@ -354,10 +354,10 @@ add_connection (NMSystemConfigInterface *config, } static GSList * -get_unmanaged_devices (NMSystemConfigInterface *config) +get_unmanaged_specs (NMSystemConfigInterface *config) { GKeyFile *key_file; - GSList *unmanaged_devices = NULL; + GSList *specs = NULL; GError *error = NULL; key_file = g_key_file_new (); @@ -373,7 +373,7 @@ get_unmanaged_devices (NMSystemConfigInterface *config) g_free (str); for (i = 0; udis[i] != NULL; i++) - unmanaged_devices = g_slist_append (unmanaged_devices, udis[i]); + specs = g_slist_append (specs, udis[i]); g_free (udis); /* Yes, g_free, not g_strfreev because we need the strings in the list */ } @@ -384,7 +384,7 @@ get_unmanaged_devices (NMSystemConfigInterface *config) g_key_file_free (key_file); - return unmanaged_devices; + return specs; } static char * @@ -567,7 +567,7 @@ system_config_interface_init (NMSystemConfigInterface *system_config_interface_c /* interface implementation */ system_config_interface_class->get_connections = get_connections; system_config_interface_class->add_connection = add_connection; - system_config_interface_class->get_unmanaged_devices = get_unmanaged_devices; + system_config_interface_class->get_unmanaged_specs = get_unmanaged_specs; } G_MODULE_EXPORT GObject * diff --git a/system-settings/src/Makefile.am b/system-settings/src/Makefile.am deleted file mode 100644 index c314e25dc4..0000000000 --- a/system-settings/src/Makefile.am +++ /dev/null @@ -1,84 +0,0 @@ -INCLUDES = -I${top_srcdir} \ - -I${top_srcdir}/include \ - -I${top_srcdir}/libnm-util \ - -I${top_srcdir}/libnm-glib \ - -I${top_builddir}/marshallers - -sbin_PROGRAMS = nm-system-settings - -BUILT_SOURCES = \ - nm-settings-system-glue.h - -nm_system_settings_SOURCES = \ - dbus-settings.c \ - dbus-settings.h \ - main.c \ - nm-inotify-helper.c \ - nm-inotify-helper.h \ - nm-polkit-helpers.c \ - nm-polkit-helpers.h \ - nm-system-config-error.c \ - nm-system-config-error.h \ - nm-system-config-interface.c \ - nm-system-config-interface.h \ - nm-system-config-hal-manager.c \ - nm-system-config-hal-manager.h \ - nm-sysconfig-connection.c \ - nm-sysconfig-connection.h \ - nm-default-wired-connection.c \ - nm-default-wired-connection.h - -nm_system_settings_CPPFLAGS = \ - $(DBUS_CFLAGS) \ - $(GLIB_CFLAGS) \ - $(GMODULE_CFLAGS) \ - $(POLKIT_CFLAGS) \ - -DG_DISABLE_DEPRECATED \ - -DBINDIR=\"$(bindir)\" \ - -DSBINDIR=\"$(sbindir)\" \ - -DLIBEXECDIR=\"$(libexecdir)\" \ - -DDATADIR=\"$(datadir)\" \ - -DSYSCONFDIR=\"$(sysconfdir)\" \ - -DLOCALSTATEDIR=\"$(localstatedir)\" \ - -DGNOMELOCALEDIR=\"$(datadir)/locale\" \ - -DPLUGINDIR=\"$(pkglibdir)\" - -nm_system_settings_LDADD = \ - $(DBUS_LIBS) \ - $(GLIB_LIBS) \ - $(GMODULE_LIBS) \ - $(POLKIT_LIBS) \ - $(top_builddir)/libnm-util/libnm-util.la \ - $(top_builddir)/libnm-glib/libnm_glib.la \ - $(top_builddir)/marshallers/libmarshallers.la - -nm_system_settings_LDFLAGS = -rdynamic - -nm-settings-system-glue.h: $(top_srcdir)/introspection/nm-settings-system.xml - dbus-binding-tool --prefix=nm_settings_system --mode=glib-server --output=$@ $< - - -dbusservicedir = $(DBUS_SYS_DIR) -dbusservice_DATA = nm-system-settings.conf - -dbusactivationdir = $(datadir)/dbus-1/system-services -dbusactivation_in_files = org.freedesktop.NetworkManagerSystemSettings.service.in -dbusactivation_DATA = $(dbusactivation_in_files:.service.in=.service) - -%service: %service.in - $(edit) $< >$@ - -edit = @sed \ - -e 's|@sbindir[@]|$(sbindir)|g' \ - -e 's|@sysconfdir[@]|$(sysconfdir)|g' \ - -e 's|@localstatedir[@]|$(localstatedir)|g' \ - -e 's|@libexecdir[@]|$(libexecdir)|g' - -EXTRA_DIST = \ - $(dbusservice_DATA) \ - $(dbusactivation_in_files) - -CLEANFILES = \ - $(BUILT_SOURCES) \ - $(dbusactivation_DATA) - diff --git a/system-settings/src/dbus-settings.c b/system-settings/src/dbus-settings.c deleted file mode 100644 index 8119f38e16..0000000000 --- a/system-settings/src/dbus-settings.c +++ /dev/null @@ -1,671 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager system settings service - * - * Søren Sandmann - * Dan Williams - * Tambet Ingo - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * (C) Copyright 2007 - 2008 Red Hat, Inc. - * (C) Copyright 2008 Novell, Inc. - */ - -#include -#include - -#include -#include -#include -#include - -#include "nm-dbus-glib-types.h" -#include "dbus-settings.h" -#include "nm-polkit-helpers.h" -#include "nm-system-config-error.h" -#include "nm-utils.h" - -static gboolean -impl_settings_add_connection (NMSysconfigSettings *self, GHashTable *hash, DBusGMethodInvocation *context); - -static gboolean -impl_settings_save_hostname (NMSysconfigSettings *self, const char *hostname, DBusGMethodInvocation *context); - -#include "nm-settings-system-glue.h" - -static void unmanaged_devices_changed (NMSystemConfigInterface *config, gpointer user_data); - -typedef struct { - DBusGConnection *g_connection; - PolKitContext *pol_ctx; - NMSystemConfigHalManager *hal_mgr; - - GSList *plugins; - gboolean connections_loaded; - GHashTable *connections; - GHashTable *unmanaged_devices; - char *orig_hostname; -} NMSysconfigSettingsPrivate; - -G_DEFINE_TYPE (NMSysconfigSettings, nm_sysconfig_settings, NM_TYPE_SETTINGS); - -#define NM_SYSCONFIG_SETTINGS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SYSCONFIG_SETTINGS, NMSysconfigSettingsPrivate)) - -enum { - PROPERTIES_CHANGED, - - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0 }; - -enum { - PROP_0, - PROP_UNMANAGED_DEVICES, - PROP_HOSTNAME, - PROP_CAN_MODIFY, - - LAST_PROP -}; - -static void -load_connections (NMSysconfigSettings *self) -{ - NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); - GSList *iter; - - if (priv->connections_loaded) - return; - - for (iter = priv->plugins; iter; iter = g_slist_next (iter)) { - NMSystemConfigInterface *plugin = NM_SYSTEM_CONFIG_INTERFACE (iter->data); - GSList *plugin_connections; - GSList *elt; - - plugin_connections = nm_system_config_interface_get_connections (plugin); - - // FIXME: ensure connections from plugins loaded with a lower priority - // get rejected when they conflict with connections from a higher - // priority plugin. - - for (elt = plugin_connections; elt; elt = g_slist_next (elt)) - nm_sysconfig_settings_add_connection (self, NM_EXPORTED_CONNECTION (elt->data), TRUE); - - g_slist_free (plugin_connections); - } - - priv->connections_loaded = TRUE; - - /* FIXME: Bad hack */ - unmanaged_devices_changed (NULL, self); -} - -static void -hash_keys_to_slist (gpointer key, gpointer val, gpointer user_data) -{ - GSList **list = (GSList **) user_data; - - *list = g_slist_prepend (*list, key); -} - -static GSList * -list_connections (NMSettings *settings) -{ - NMSysconfigSettings *self = NM_SYSCONFIG_SETTINGS (settings); - NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); - GSList *list = NULL; - - load_connections (self); - - g_hash_table_foreach (priv->connections, hash_keys_to_slist, &list); - - return list; -} - -static void -settings_finalize (GObject *object) -{ - NMSysconfigSettings *self = NM_SYSCONFIG_SETTINGS (object); - NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); - - g_hash_table_destroy (priv->connections); - g_hash_table_destroy (priv->unmanaged_devices); - - g_slist_foreach (priv->plugins, (GFunc) g_object_unref, NULL); - g_slist_free (priv->plugins); - - if (priv->pol_ctx) - polkit_context_unref (priv->pol_ctx); - - g_object_unref (priv->hal_mgr); - dbus_g_connection_unref (priv->g_connection); - - g_free (priv->orig_hostname); - - G_OBJECT_CLASS (nm_sysconfig_settings_parent_class)->finalize (object); -} - -static void -add_one_unmanaged_device (gpointer key, gpointer data, gpointer user_data) -{ - GPtrArray *devices = (GPtrArray *) user_data; - - g_ptr_array_add (devices, g_strdup (key)); -} - -static char* -uscore_to_wincaps (const char *uscore) -{ - const char *p; - GString *str; - gboolean last_was_uscore; - - last_was_uscore = TRUE; - - str = g_string_new (NULL); - p = uscore; - while (p && *p) { - if (*p == '-' || *p == '_') - last_was_uscore = TRUE; - else { - if (last_was_uscore) { - g_string_append_c (str, g_ascii_toupper (*p)); - last_was_uscore = FALSE; - } else - g_string_append_c (str, *p); - } - ++p; - } - - return g_string_free (str, FALSE); -} - -static void -notify (GObject *object, GParamSpec *pspec) -{ - GValue *value; - GHashTable *hash; - - value = g_slice_new0 (GValue); - hash = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, NULL); - - g_value_init (value, pspec->value_type); - g_object_get_property (object, pspec->name, value); - g_hash_table_insert (hash, uscore_to_wincaps (pspec->name), value); - g_signal_emit (object, signals[PROPERTIES_CHANGED], 0, hash); - g_hash_table_destroy (hash); - g_value_unset (value); - g_slice_free (GValue, value); -} - -static GPtrArray * -get_unmanaged_devices (NMSysconfigSettings *self) -{ - NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); - GPtrArray *devices; - - load_connections (self); - - devices = g_ptr_array_sized_new (3); - g_hash_table_foreach (priv->unmanaged_devices, (GHFunc) add_one_unmanaged_device, devices); - return devices; -} - -NMSystemConfigInterface * -nm_sysconfig_settings_get_plugin (NMSysconfigSettings *self, - guint32 capability) -{ - NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); - GSList *iter; - - g_return_val_if_fail (self != NULL, NULL); - - /* Do any of the plugins support setting the hostname? */ - for (iter = priv->plugins; iter; iter = iter->next) { - NMSystemConfigInterfaceCapabilities caps = NM_SYSTEM_CONFIG_INTERFACE_CAP_NONE; - - g_object_get (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES, &caps, NULL); - if (caps & capability) - return NM_SYSTEM_CONFIG_INTERFACE (iter->data); - } - - return NULL; -} - -static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) -{ - NMSysconfigSettings *self = NM_SYSCONFIG_SETTINGS (object); - NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); - GSList *iter; - - - switch (prop_id) { - case PROP_UNMANAGED_DEVICES: - g_value_take_boxed (value, get_unmanaged_devices (self)); - break; - case PROP_HOSTNAME: - /* Hostname returned is the hostname returned from the first plugin - * that provides one. - */ - for (iter = priv->plugins; iter; iter = iter->next) { - NMSystemConfigInterfaceCapabilities caps = NM_SYSTEM_CONFIG_INTERFACE_CAP_NONE; - - g_object_get (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES, &caps, NULL); - if (caps & NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME) { - char *hostname = NULL; - - g_object_get (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME, &hostname, NULL); - if (hostname && strlen (hostname)) { - g_value_take_string (value, hostname); - break; - } - } - } - - /* If no plugin provided a hostname, try the original hostname of the machine */ - if (!g_value_get_string (value) && priv->orig_hostname) - g_value_set_string (value, priv->orig_hostname); - - /* Don't ever pass NULL through D-Bus */ - if (!g_value_get_string (value)) - g_value_set_static_string (value, ""); - break; - case PROP_CAN_MODIFY: - g_value_set_boolean (value, !!nm_sysconfig_settings_get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -nm_sysconfig_settings_class_init (NMSysconfigSettingsClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - NMSettingsClass *settings_class = NM_SETTINGS_CLASS (class); - - g_type_class_add_private (class, sizeof (NMSysconfigSettingsPrivate)); - - /* virtual methods */ - object_class->notify = notify; - object_class->get_property = get_property; - object_class->finalize = settings_finalize; - settings_class->list_connections = list_connections; - - /* properties */ - g_object_class_install_property - (object_class, PROP_UNMANAGED_DEVICES, - g_param_spec_boxed (NM_SYSCONFIG_SETTINGS_UNMANAGED_DEVICES, - "Unamanged devices", - "Unmanaged devices", - DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, - G_PARAM_READABLE)); - - g_object_class_install_property - (object_class, PROP_HOSTNAME, - g_param_spec_string (NM_SYSCONFIG_SETTINGS_HOSTNAME, - "Hostname", - "Hostname", - NULL, - G_PARAM_READABLE)); - - g_object_class_install_property - (object_class, PROP_CAN_MODIFY, - g_param_spec_boolean (NM_SYSCONFIG_SETTINGS_CAN_MODIFY, - "CanModify", - "Can modify", - FALSE, - G_PARAM_READABLE)); - - /* signals */ - signals[PROPERTIES_CHANGED] = - g_signal_new ("properties-changed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMSysconfigSettingsClass, properties_changed), - NULL, NULL, - g_cclosure_marshal_VOID__BOXED, - G_TYPE_NONE, 1, DBUS_TYPE_G_MAP_OF_VARIANT); - - dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (settings_class), - &dbus_glib_nm_settings_system_object_info); - - dbus_g_error_domain_register (NM_SYSCONFIG_SETTINGS_ERROR, - NM_DBUS_IFACE_SETTINGS_SYSTEM, - NM_TYPE_SYSCONFIG_SETTINGS_ERROR); -} - -static void -nm_sysconfig_settings_init (NMSysconfigSettings *self) -{ - NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); - char hostname[HOST_NAME_MAX + 2]; - GError *error = NULL; - - priv->connections = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, NULL); - priv->unmanaged_devices = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); - - priv->pol_ctx = create_polkit_context (&error); - if (!priv->pol_ctx) { - g_warning ("%s: failed to create PolicyKit context: %s", - __func__, - (error && error->message) ? error->message : "(unknown)"); - } - - /* Grab hostname on startup and use that if no plugins provide one */ - memset (hostname, 0, sizeof (hostname)); - if (gethostname (&hostname[0], HOST_NAME_MAX) == 0) { - /* only cache it if it's a valid hostname */ - if (strlen (hostname) && strcmp (hostname, "localhost") && strcmp (hostname, "localhost.localdomain")) - priv->orig_hostname = g_strdup (hostname); - } -} - -NMSysconfigSettings * -nm_sysconfig_settings_new (DBusGConnection *g_conn, NMSystemConfigHalManager *hal_mgr) -{ - NMSysconfigSettings *settings; - NMSysconfigSettingsPrivate *priv; - - g_return_val_if_fail (g_conn != NULL, NULL); - g_return_val_if_fail (hal_mgr != NULL, NULL); - - settings = g_object_new (NM_TYPE_SYSCONFIG_SETTINGS, NULL); - dbus_g_connection_register_g_object (g_conn, NM_DBUS_PATH_SETTINGS, G_OBJECT (settings)); - - priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (settings); - priv->g_connection = dbus_g_connection_ref (g_conn); - priv->hal_mgr = g_object_ref (hal_mgr); - - return settings; -} - -static void -plugin_connection_added (NMSystemConfigInterface *config, - NMExportedConnection *connection, - gpointer user_data) -{ - nm_sysconfig_settings_add_connection (NM_SYSCONFIG_SETTINGS (user_data), connection, TRUE); -} - -static void -unmanaged_devices_changed (NMSystemConfigInterface *config, - gpointer user_data) -{ - NMSysconfigSettings *self = NM_SYSCONFIG_SETTINGS (user_data); - NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); - GSList *iter; - - g_hash_table_remove_all (priv->unmanaged_devices); - - /* Ask all the plugins for their unmanaged devices */ - for (iter = priv->plugins; iter; iter = g_slist_next (iter)) { - GSList *udis = nm_system_config_interface_get_unmanaged_devices (NM_SYSTEM_CONFIG_INTERFACE (iter->data)); - GSList *udi_iter; - - for (udi_iter = udis; udi_iter; udi_iter = udi_iter->next) { - if (!g_hash_table_lookup (priv->unmanaged_devices, udi_iter->data)) { - g_hash_table_insert (priv->unmanaged_devices, - udi_iter->data, - GUINT_TO_POINTER (1)); - } else - g_free (udi_iter->data); - } - - g_slist_free (udis); - } - - g_object_notify (G_OBJECT (self), NM_SYSCONFIG_SETTINGS_UNMANAGED_DEVICES); -} - -static void -hostname_changed (NMSystemConfigInterface *config, - GParamSpec *pspec, - gpointer user_data) -{ - g_object_notify (G_OBJECT (user_data), NM_SYSCONFIG_SETTINGS_HOSTNAME); -} - -void -nm_sysconfig_settings_add_plugin (NMSysconfigSettings *self, - NMSystemConfigInterface *plugin) -{ - NMSysconfigSettingsPrivate *priv; - char *pname = NULL; - char *pinfo = NULL; - - g_return_if_fail (NM_IS_SYSCONFIG_SETTINGS (self)); - g_return_if_fail (NM_IS_SYSTEM_CONFIG_INTERFACE (plugin)); - - priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); - - priv->plugins = g_slist_append (priv->plugins, g_object_ref (plugin)); - - g_signal_connect (plugin, "connection-added", G_CALLBACK (plugin_connection_added), self); - g_signal_connect (plugin, "unmanaged-devices-changed", G_CALLBACK (unmanaged_devices_changed), self); - g_signal_connect (plugin, "notify::hostname", G_CALLBACK (hostname_changed), self); - - nm_system_config_interface_init (plugin, priv->hal_mgr); - - g_object_get (G_OBJECT (plugin), - NM_SYSTEM_CONFIG_INTERFACE_NAME, &pname, - NM_SYSTEM_CONFIG_INTERFACE_INFO, &pinfo, - NULL); - - g_message ("Loaded plugin %s: %s", pname, pinfo); - g_free (pname); - g_free (pinfo); -} - -static void -connection_removed (NMExportedConnection *connection, - gpointer user_data) -{ - NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (user_data); - - g_hash_table_remove (priv->connections, connection); -} - -void -nm_sysconfig_settings_add_connection (NMSysconfigSettings *self, - NMExportedConnection *connection, - gboolean do_export) -{ - NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); - - g_return_if_fail (NM_IS_SYSCONFIG_SETTINGS (self)); - g_return_if_fail (NM_IS_EXPORTED_CONNECTION (connection)); - - if (g_hash_table_lookup (priv->connections, connection)) - /* A plugin is lying to us. */ - return; - - g_hash_table_insert (priv->connections, g_object_ref (connection), GINT_TO_POINTER (1)); - g_signal_connect (connection, "removed", G_CALLBACK (connection_removed), self); - - if (do_export) { - nm_exported_connection_register_object (connection, NM_CONNECTION_SCOPE_SYSTEM, priv->g_connection); - nm_settings_signal_new_connection (NM_SETTINGS (self), connection); - } -} - -void -nm_sysconfig_settings_remove_connection (NMSysconfigSettings *self, - NMExportedConnection *connection, - gboolean do_signal) -{ - NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); - - g_return_if_fail (NM_IS_SYSCONFIG_SETTINGS (self)); - g_return_if_fail (NM_IS_EXPORTED_CONNECTION (connection)); - - if (g_hash_table_lookup (priv->connections, connection)) { - nm_exported_connection_signal_removed (connection); - g_hash_table_remove (priv->connections, connection); - } -} - -gboolean -nm_sysconfig_settings_is_device_managed (NMSysconfigSettings *self, - const char *udi) -{ - NMSysconfigSettingsPrivate *priv; - - g_return_val_if_fail (NM_IS_SYSCONFIG_SETTINGS (self), FALSE); - - priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); - - load_connections (self); - - if (g_hash_table_lookup (priv->unmanaged_devices, udi)) - return FALSE; - return TRUE; -} - -gboolean -nm_sysconfig_settings_add_new_connection (NMSysconfigSettings *self, - GHashTable *hash, - GError **error) -{ - NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); - NMConnection *connection; - GError *tmp_error = NULL, *last_error = NULL; - GSList *iter; - gboolean success = FALSE; - - connection = nm_connection_new_from_hash (hash, &tmp_error); - if (!connection) { - /* Invalid connection hash */ - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Invalid connection: '%s' / '%s' invalid: %d", - tmp_error ? g_type_name (nm_connection_lookup_setting_type_by_quark (tmp_error->domain)) : "(unknown)", - tmp_error ? tmp_error->message : "(unknown)", tmp_error ? tmp_error->code : -1); - g_clear_error (&tmp_error); - return FALSE; - } - - /* Here's how it works: - 1) plugin writes a connection. - 2) plugin notices that a new connection is available for reading. - 3) plugin reads the new connection (the one it wrote in 1) and emits 'connection-added' signal. - 4) NMSysconfigSettings receives the signal and adds it to it's connection list. - */ - - for (iter = priv->plugins; iter && !success; iter = iter->next) { - success = nm_system_config_interface_add_connection (NM_SYSTEM_CONFIG_INTERFACE (iter->data), - connection, &tmp_error); - g_clear_error (&last_error); - if (!success) - last_error = tmp_error; - } - - g_object_unref (connection); - - if (!success) { - g_set_error (error, NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_ADD_FAILED, - "Saving connection failed: (%d) %s", - last_error ? last_error->code : -1, - last_error && last_error->message ? last_error->message : "(unknown)"); - g_clear_error (&last_error); - } - - return success; -} - -static gboolean -impl_settings_add_connection (NMSysconfigSettings *self, - GHashTable *hash, - DBusGMethodInvocation *context) -{ - NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); - GError *err = NULL; - - /* Do any of the plugins support adding? */ - if (!nm_sysconfig_settings_get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS)) { - err = g_error_new (NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_ADD_NOT_SUPPORTED, - "%s", "None of the registered plugins support add."); - goto out; - } - - if (!check_polkit_privileges (priv->g_connection, priv->pol_ctx, context, &err)) - goto out; - - nm_sysconfig_settings_add_new_connection (self, hash, &err); - - out: - if (err) { - dbus_g_method_return_error (context, err); - g_error_free (err); - return FALSE; - } else { - dbus_g_method_return (context); - return TRUE; - } -} - -static gboolean -impl_settings_save_hostname (NMSysconfigSettings *self, - const char *hostname, - DBusGMethodInvocation *context) -{ - NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); - GError *err = NULL; - GSList *iter; - gboolean success = FALSE; - - /* Do any of the plugins support setting the hostname? */ - if (!nm_sysconfig_settings_get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME)) { - err = g_error_new (NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_SAVE_HOSTNAME_NOT_SUPPORTED, - "%s", "None of the registered plugins support setting the hostname."); - goto out; - } - - if (!check_polkit_privileges (priv->g_connection, priv->pol_ctx, context, &err)) - goto out; - - /* Set the hostname in all plugins */ - for (iter = priv->plugins; iter; iter = iter->next) { - NMSystemConfigInterfaceCapabilities caps = NM_SYSTEM_CONFIG_INTERFACE_CAP_NONE; - - g_object_get (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES, &caps, NULL); - if (caps & NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME) { - g_object_set (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME, hostname, NULL); - success = TRUE; - } - } - - if (!success) { - err = g_error_new (NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_SAVE_HOSTNAME_FAILED, - "%s", "Saving the hostname failed."); - } - - out: - if (err) { - dbus_g_method_return_error (context, err); - g_error_free (err); - return FALSE; - } else { - dbus_g_method_return (context); - return TRUE; - } -} - diff --git a/system-settings/src/dbus-settings.h b/system-settings/src/dbus-settings.h deleted file mode 100644 index 2e253ab80f..0000000000 --- a/system-settings/src/dbus-settings.h +++ /dev/null @@ -1,95 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager system settings service - * - * Søren Sandmann - * Dan Williams - * Tambet Ingo - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * (C) Copyright 2007 - 2008 Red Hat, Inc. - * (C) Copyright 2008 Novell, Inc. - */ - -#ifndef __DBUS_SETTINGS_H__ -#define __DBUS_SETTINGS_H__ - -#include -#include - -#include "nm-system-config-interface.h" -#include "nm-system-config-hal-manager.h" - -typedef struct _NMSysconfigSettings NMSysconfigSettings; -typedef struct _NMSysconfigSettingsClass NMSysconfigSettingsClass; - -#define NM_TYPE_SYSCONFIG_SETTINGS (nm_sysconfig_settings_get_type ()) -#define NM_SYSCONFIG_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SYSCONFIG_SETTINGS, NMSysconfigSettings)) -#define NM_SYSCONFIG_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SYSCONFIG_SETTINGS, NMSysconfigSettingsClass)) -#define NM_IS_SYSCONFIG_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SYSCONFIG_SETTINGS)) -#define NM_IS_SYSCONFIG_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SYSCONFIG_SETTINGS)) -#define NM_SYSCONFIG_SETTINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SYSCONFIG_SETTINGS, NMSysconfigSettingsClass)) - -#define NM_SYSCONFIG_SETTINGS_UNMANAGED_DEVICES "unmanaged-devices" -#define NM_SYSCONFIG_SETTINGS_HOSTNAME "hostname" -#define NM_SYSCONFIG_SETTINGS_CAN_MODIFY "can-modify" - -struct _NMSysconfigSettings -{ - NMSettings parent_instance; -}; - -struct _NMSysconfigSettingsClass -{ - NMSettingsClass parent_class; - - /* Signals */ - void (*properties_changed) (NMSysconfigSettings *settings, GHashTable *properties); -}; - -GType nm_sysconfig_settings_get_type (void); - -NMSysconfigSettings *nm_sysconfig_settings_new (DBusGConnection *g_conn, - NMSystemConfigHalManager *hal_mgr); - -void nm_sysconfig_settings_add_plugin (NMSysconfigSettings *settings, - NMSystemConfigInterface *plugin); - -/* Registers an exising connection with the settings service */ -void nm_sysconfig_settings_add_connection (NMSysconfigSettings *settings, - NMExportedConnection *connection, - gboolean do_export); - -void nm_sysconfig_settings_remove_connection (NMSysconfigSettings *settings, - NMExportedConnection *connection, - gboolean do_signal); - -void nm_sysconfig_settings_update_unamanged_devices (NMSysconfigSettings *settings, - GSList *new_list); - -gboolean nm_sysconfig_settings_is_device_managed (NMSysconfigSettings *settings, - const char *udi); - -NMSystemConfigInterface *nm_sysconfig_settings_get_plugin (NMSysconfigSettings *self, - guint32 capability); - -/* Adds a new connection from a hash of that connection's settings, - * potentially saving the new connection to persistent storage. - */ -gboolean nm_sysconfig_settings_add_new_connection (NMSysconfigSettings *self, - GHashTable *hash, - GError **error); - -#endif /* __DBUS_SETTINGS_H__ */ diff --git a/system-settings/src/main.c b/system-settings/src/main.c deleted file mode 100644 index 2c4734d8cd..0000000000 --- a/system-settings/src/main.c +++ /dev/null @@ -1,900 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager system settings service - * - * Søren Sandmann - * Dan Williams - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * (C) Copyright 2007 - 2008 Red Hat, Inc. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include "nm-glib-compat.h" - -#include "dbus-settings.h" -#include "nm-system-config-hal-manager.h" -#include "nm-system-config-interface.h" -#include "nm-default-wired-connection.h" - -#define CONFIG_KEY_NO_AUTO_DEFAULT "no-auto-default" - -static GMainLoop *loop = NULL; -static gboolean debug = FALSE; - -typedef struct { - DBusConnection *connection; - DBusGConnection *g_connection; - - DBusGProxy *bus_proxy; - NMSystemConfigHalManager *hal_mgr; - - NMSysconfigSettings *settings; - - GHashTable *wired_devices; - - const char *config; -} Application; - - -NMSystemConfigHalManager *nm_system_config_hal_manager_get (DBusGConnection *g_connection); -void nm_system_config_hal_manager_shutdown (NMSystemConfigHalManager *self); - -static gboolean dbus_init (Application *app); -static gboolean start_dbus_service (Application *app); -static void destroy_cb (DBusGProxy *proxy, gpointer user_data); -static void device_added_cb (DBusGProxy *proxy, const char *udi, NMDeviceType devtype, gpointer user_data); - - -static GQuark -plugins_error_quark (void) -{ - static GQuark error_quark = 0; - - if (G_UNLIKELY (error_quark == 0)) - error_quark = g_quark_from_static_string ("plugins-error-quark"); - - return error_quark; -} - -static GObject * -find_plugin (GSList *list, const char *pname) -{ - GSList *iter; - GObject *obj = NULL; - - g_return_val_if_fail (pname != NULL, FALSE); - - for (iter = list; iter && !obj; iter = g_slist_next (iter)) { - NMSystemConfigInterface *plugin = NM_SYSTEM_CONFIG_INTERFACE (iter->data); - char *list_pname = NULL; - - g_object_get (G_OBJECT (plugin), - NM_SYSTEM_CONFIG_INTERFACE_NAME, - &list_pname, - NULL); - if (list_pname && !strcmp (pname, list_pname)) - obj = G_OBJECT (plugin); - - g_free (list_pname); - } - - return obj; -} - -static gboolean -load_plugins (Application *app, const char *plugins, GError **error) -{ - GSList *list = NULL; - char **plist; - char **iter; - - plist = g_strsplit (plugins, ",", 0); - if (!plist) - return FALSE; - - for (iter = plist; *iter; iter++) { - GModule *plugin; - char *full_name, *path; - const char *pname = *iter; - GObject *obj; - GObject * (*factory_func) (void); - - /* ifcfg-fedora was renamed ifcfg-rh; handle old configs here */ - if (!strcmp (pname, "ifcfg-fedora")) - pname = "ifcfg-rh"; - - obj = find_plugin (list, pname); - if (obj) - continue; - - full_name = g_strdup_printf ("nm-settings-plugin-%s", pname); - path = g_module_build_path (PLUGINDIR, full_name); - - plugin = g_module_open (path, G_MODULE_BIND_LOCAL); - if (!plugin) { - g_set_error (error, plugins_error_quark (), 0, - "Could not load plugin '%s': %s", - pname, g_module_error ()); - g_free (full_name); - g_free (path); - break; - } - - g_free (full_name); - g_free (path); - - if (!g_module_symbol (plugin, "nm_system_config_factory", (gpointer) (&factory_func))) { - g_set_error (error, plugins_error_quark (), 0, - "Could not find plugin '%s' factory function.", - pname); - break; - } - - obj = (*factory_func) (); - if (!obj || !NM_IS_SYSTEM_CONFIG_INTERFACE (obj)) { - g_set_error (error, plugins_error_quark (), 0, - "Plugin '%s' returned invalid system config object.", - pname); - break; - } - - g_module_make_resident (plugin); - g_object_weak_ref (obj, (GWeakNotify) g_module_close, plugin); - nm_sysconfig_settings_add_plugin (app->settings, NM_SYSTEM_CONFIG_INTERFACE (obj)); - list = g_slist_append (list, obj); - } - - g_strfreev (plist); - - g_slist_foreach (list, (GFunc) g_object_unref, NULL); - g_slist_free (list); - - return TRUE; -} - -static gboolean -load_stuff (gpointer user_data) -{ - Application *app = (Application *) user_data; - GSList *devs, *iter; - - /* Grab wired devices to make default DHCP connections for them if needed */ - devs = nm_system_config_hal_manager_get_devices_of_type (app->hal_mgr, NM_DEVICE_TYPE_ETHERNET); - for (iter = devs; iter; iter = g_slist_next (iter)) { - device_added_cb (NULL, (const char *) iter->data, NM_DEVICE_TYPE_ETHERNET, app); - g_free (iter->data); - } - - g_slist_free (devs); - - if (!start_dbus_service (app)) { - g_main_loop_quit (loop); - return FALSE; - } - - return FALSE; -} - -typedef struct { - Application *app; - NMDefaultWiredConnection *connection; - guint add_id; - guint updated_id; - guint deleted_id; - char *udi; -} WiredDeviceInfo; - -static void -wired_device_info_destroy (gpointer user_data) -{ - WiredDeviceInfo *info = (WiredDeviceInfo *) user_data; - - if (info->add_id) - g_source_remove (info->add_id); - if (info->updated_id) - g_source_remove (info->updated_id); - if (info->deleted_id) - g_source_remove (info->deleted_id); - if (info->connection) { - nm_sysconfig_settings_remove_connection (info->app->settings, - NM_EXPORTED_CONNECTION (info->connection), - TRUE); - g_object_unref (info->connection); - } - g_free (info); -} - -static char * -get_details_for_udi (Application *app, const char *udi, struct ether_addr *mac) -{ - DBusGProxy *dev_proxy = NULL; - char *address = NULL; - char *iface = NULL; - struct ether_addr *temp; - GError *error = NULL; - - g_return_val_if_fail (app != NULL, FALSE); - g_return_val_if_fail (udi != NULL, FALSE); - g_return_val_if_fail (mac != NULL, FALSE); - - dev_proxy = dbus_g_proxy_new_for_name (app->g_connection, - "org.freedesktop.Hal", - udi, - "org.freedesktop.Hal.Device"); - if (!dev_proxy) - goto out; - - if (!dbus_g_proxy_call_with_timeout (dev_proxy, - "GetPropertyString", 5000, &error, - G_TYPE_STRING, "net.address", G_TYPE_INVALID, - G_TYPE_STRING, &address, G_TYPE_INVALID)) { - g_message ("Error getting hardware address for %s: (%d) %s", - udi, error->code, error->message); - g_error_free (error); - goto out; - } - - if (!address && !strlen (address)) - goto out; - - temp = ether_aton (address); - if (!temp) - goto out; - memcpy (mac, temp, sizeof (struct ether_addr)); - - if (!dbus_g_proxy_call_with_timeout (dev_proxy, - "GetPropertyString", 5000, &error, - G_TYPE_STRING, "net.interface", G_TYPE_INVALID, - G_TYPE_STRING, &iface, G_TYPE_INVALID)) { - g_message ("Error getting interface name for %s: (%d) %s", - udi, error->code, error->message); - g_error_free (error); - } - -out: - g_free (address); - if (dev_proxy) - g_object_unref (dev_proxy); - return iface; -} - -static gboolean -have_connection_for_device (Application *app, GByteArray *mac) -{ - GSList *list, *iter; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - const GByteArray *setting_mac; - gboolean ret = FALSE; - - g_return_val_if_fail (app != NULL, FALSE); - g_return_val_if_fail (mac != NULL, FALSE); - - /* Find a wired connection locked to the given MAC address, if any */ - list = nm_settings_list_connections (NM_SETTINGS (app->settings)); - for (iter = list; iter; iter = g_slist_next (iter)) { - NMExportedConnection *exported = NM_EXPORTED_CONNECTION (iter->data); - NMConnection *connection; - const char *connection_type; - - connection = nm_exported_connection_get_connection (exported); - if (!connection) - continue; - - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); - connection_type = nm_setting_connection_get_connection_type (s_con); - - if ( strcmp (connection_type, NM_SETTING_WIRED_SETTING_NAME) - && strcmp (connection_type, NM_SETTING_PPPOE_SETTING_NAME)) - continue; - - s_wired = (NMSettingWired *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED); - - /* No wired setting; therefore the PPPoE connection applies to any device */ - if (!s_wired && !strcmp (connection_type, NM_SETTING_PPPOE_SETTING_NAME)) { - ret = TRUE; - break; - } - - setting_mac = nm_setting_wired_get_mac_address (s_wired); - if (setting_mac) { - /* A connection mac-locked to this device */ - if (!memcmp (setting_mac->data, mac->data, ETH_ALEN)) { - ret = TRUE; - break; - } - - } else { - /* A connection that applies to any wired device */ - ret = TRUE; - break; - } - } - - g_slist_free (list); - - return ret; -} - -/* Search through the list of blacklisted MAC addresses in the config file. */ -static gboolean -is_mac_auto_wired_blacklisted (const GByteArray *mac, const char *filename) -{ - GKeyFile *config; - char **list, **iter; - gboolean found = FALSE; - - g_return_val_if_fail (mac != NULL, FALSE); - g_return_val_if_fail (filename != NULL, FALSE); - - config = g_key_file_new (); - if (!config) { - g_warning ("%s: not enough memory to load config file.", __func__); - return FALSE; - } - - g_key_file_set_list_separator (config, ','); - if (!g_key_file_load_from_file (config, filename, G_KEY_FILE_NONE, NULL)) - goto out; - - list = g_key_file_get_string_list (config, "main", CONFIG_KEY_NO_AUTO_DEFAULT, NULL, NULL); - for (iter = list; iter && *iter; iter++) { - struct ether_addr *candidate; - - candidate = ether_aton (*iter); - if (candidate && !memcmp (mac->data, candidate->ether_addr_octet, ETH_ALEN)) { - found = TRUE; - break; - } - } - - if (list) - g_strfreev (list); - -out: - g_key_file_free (config); - return found; -} - -static void -default_wired_deleted (NMDefaultWiredConnection *wired, - const GByteArray *mac, - WiredDeviceInfo *info) -{ - NMConnection *wrapped; - NMSettingConnection *s_con; - char *tmp; - GKeyFile *config; - char **list, **iter, **updated; - gboolean found = FALSE; - gsize len = 0; - char *data; - - /* If there was no config file specified, there's nothing to do */ - if (!info->app->config) - goto cleanup; - - /* 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. - */ - - wrapped = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (wired)); - g_assert (wrapped); - s_con = (NMSettingConnection *) nm_connection_get_setting (wrapped, NM_TYPE_SETTING_CONNECTION); - g_assert (s_con); - - /* Ignore removals of read-only connections, since they couldn't have - * been removed by the user. - */ - if (nm_setting_connection_get_read_only (s_con)) - goto cleanup; - - config = g_key_file_new (); - if (!config) - goto cleanup; - - g_key_file_set_list_separator (config, ','); - g_key_file_load_from_file (config, info->app->config, G_KEY_FILE_KEEP_COMMENTS, NULL); - - list = g_key_file_get_string_list (config, "main", CONFIG_KEY_NO_AUTO_DEFAULT, &len, NULL); - /* Traverse entire list to get count of # items */ - for (iter = list; iter && *iter; iter++) { - struct ether_addr *candidate; - - candidate = ether_aton (*iter); - if (candidate && !memcmp (mac->data, candidate->ether_addr_octet, ETH_ALEN)) - found = TRUE; - } - - /* Add this device's MAC to the list */ - if (!found) { - tmp = g_strdup_printf ("%02x:%02x:%02x:%02x:%02x:%02x", - mac->data[0], mac->data[1], mac->data[2], - mac->data[3], mac->data[4], mac->data[5]); - - updated = g_malloc0 (sizeof (char*) * (len + 2)); - if (list && len) - memcpy (updated, list, len); - updated[len] = tmp; - - g_key_file_set_string_list (config, - "main", CONFIG_KEY_NO_AUTO_DEFAULT, - (const char **) updated, - len + 1); - /* g_free() not g_strfreev() since 'updated' isn't a deep-copy */ - g_free (updated); - g_free (tmp); - - data = g_key_file_to_data (config, &len, NULL); - if (data) { - g_file_set_contents (info->app->config, data, len, NULL); - g_free (data); - } - } - - if (list) - g_strfreev (list); - g_key_file_free (config); - -cleanup: - /* Clear the connection first so that a 'removed' signal doesn't get emitted - * during wired_device_info_destroy(), becuase this connection removal - * is expected and already handled. - */ - g_object_unref (wired); - info->connection = NULL; - - g_hash_table_remove (info->app->wired_devices, info->udi); -} - -static GError * -default_wired_try_update (NMDefaultWiredConnection *wired, - GHashTable *new_settings, - WiredDeviceInfo *info) -{ - GError *error = NULL; - NMConnection *wrapped; - NMSettingConnection *s_con; - const char *id; - - /* Try to move this default wired conneciton to a plugin so that it has - * persistent storage. - */ - - wrapped = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (wired)); - g_assert (wrapped); - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (wrapped, NM_TYPE_SETTING_CONNECTION)); - g_assert (s_con); - id = nm_setting_connection_get_id (s_con); - g_assert (id); - - nm_sysconfig_settings_remove_connection (info->app->settings, NM_EXPORTED_CONNECTION (wired), FALSE); - if (nm_sysconfig_settings_add_new_connection (info->app->settings, new_settings, &error)) { - g_message ("Saved default wired connection '%s' to persistent storage", id); - return NULL; - } - - g_warning ("%s: couldn't save default wired connection '%s': %d / %s", - __func__, id, error ? error->code : -1, - (error && error->message) ? error->message : "(unknown)"); - - /* If there was an error, don't destroy the default wired connection, - * but add it back to the system settings service. Connection is already - * exported on the bus, don't export it again, thus do_export == FALSE. - */ - nm_sysconfig_settings_add_connection (info->app->settings, NM_EXPORTED_CONNECTION (wired), FALSE); - - return error; -} - -static gboolean -add_default_wired_connection (gpointer user_data) -{ - WiredDeviceInfo *info = (WiredDeviceInfo *) user_data; - GByteArray *mac = NULL; - struct ether_addr tmp; - char *iface = NULL; - NMSettingConnection *s_con; - NMConnection *wrapped; - gboolean read_only = TRUE; - const char *id; - - info->add_id = 0; - g_assert (info->connection == NULL); - - /* If the device isn't managed, ignore it */ - if (!nm_sysconfig_settings_is_device_managed (info->app->settings, info->udi)) - goto ignore; - - iface = get_details_for_udi (info->app, info->udi, &tmp); - if (!iface) - goto ignore; - - mac = g_byte_array_sized_new (ETH_ALEN); - g_byte_array_append (mac, tmp.ether_addr_octet, ETH_ALEN); - - if (have_connection_for_device (info->app, mac)) - goto ignore; - - if (info->app->config && is_mac_auto_wired_blacklisted (mac, info->app->config)) - goto ignore; - - if (nm_sysconfig_settings_get_plugin (info->app->settings, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS)) - read_only = FALSE; - - info->connection = nm_default_wired_connection_new (mac, iface, read_only); - if (!info->connection) - goto ignore; - - wrapped = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (info->connection)); - g_assert (wrapped); - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (wrapped, NM_TYPE_SETTING_CONNECTION)); - g_assert (s_con); - id = nm_setting_connection_get_id (s_con); - g_assert (id); - - g_message ("Added default wired connection '%s' for %s", id, info->udi); - - info->updated_id = g_signal_connect (info->connection, "try-update", - (GCallback) default_wired_try_update, info); - info->deleted_id = g_signal_connect (info->connection, "deleted", - (GCallback) default_wired_deleted, info); - nm_sysconfig_settings_add_connection (info->app->settings, - NM_EXPORTED_CONNECTION (info->connection), - TRUE); - return FALSE; - -ignore: - if (mac) - g_byte_array_free (mac, TRUE); - g_free (iface); - g_hash_table_remove (info->app->wired_devices, info->udi); - return FALSE; -} - -static void -device_added_cb (DBusGProxy *proxy, const char *udi, NMDeviceType devtype, gpointer user_data) -{ - Application *app = (Application *) user_data; - WiredDeviceInfo *info; - - if (devtype != NM_DEVICE_TYPE_ETHERNET) - return; - - /* Wait for a plugin to figure out if the device should be managed or not */ - info = g_malloc0 (sizeof (WiredDeviceInfo)); - info->app = app; - info->add_id = g_timeout_add_seconds (4, add_default_wired_connection, info); - info->udi = g_strdup (udi); - g_hash_table_insert (app->wired_devices, info->udi, info); -} - -static void -device_removed_cb (DBusGProxy *proxy, const char *udi, NMDeviceType devtype, gpointer user_data) -{ - Application *app = (Application *) user_data; - - g_hash_table_remove (app->wired_devices, udi); -} - -/******************************************************************/ - -static void -dbus_cleanup (Application *app) -{ - if (app->g_connection) { - dbus_g_connection_unref (app->g_connection); - app->g_connection = NULL; - app->connection = NULL; - } - - if (app->bus_proxy) { - g_signal_handlers_disconnect_by_func (app->bus_proxy, destroy_cb, app); - g_object_unref (app->bus_proxy); - app->bus_proxy = NULL; - } -} - -static void -destroy_cb (DBusGProxy *proxy, gpointer user_data) -{ - /* Clean up existing connection */ - g_warning ("disconnected from the system bus, exiting."); - g_main_loop_quit (loop); -} - -static gboolean -start_dbus_service (Application *app) -{ - int request_name_result; - GError *err = NULL; - - if (!dbus_g_proxy_call (app->bus_proxy, "RequestName", &err, - G_TYPE_STRING, NM_DBUS_SERVICE_SYSTEM_SETTINGS, - G_TYPE_UINT, DBUS_NAME_FLAG_DO_NOT_QUEUE, - G_TYPE_INVALID, - G_TYPE_UINT, &request_name_result, - G_TYPE_INVALID)) { - g_warning ("Could not acquire the NetworkManagerSystemSettings service.\n" - " Message: '%s'", err->message); - g_error_free (err); - return FALSE; - } - - if (request_name_result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { - g_warning ("Could not acquire the NetworkManagerSystemSettings service " - "as it is already taken. Return: %d", - request_name_result); - return FALSE; - } - - return TRUE; -} - -static gboolean -dbus_init (Application *app) -{ - GError *err = NULL; - - dbus_connection_set_change_sigpipe (TRUE); - - app->g_connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &err); - if (!app->g_connection) { - g_warning ("Could not get the system bus. Make sure " - "the message bus daemon is running! Message: %s", - err->message); - g_error_free (err); - return FALSE; - } - - app->connection = dbus_g_connection_get_connection (app->g_connection); - dbus_connection_set_exit_on_disconnect (app->connection, FALSE); - - app->bus_proxy = dbus_g_proxy_new_for_name (app->g_connection, - "org.freedesktop.DBus", - "/org/freedesktop/DBus", - "org.freedesktop.DBus"); - if (!app->bus_proxy) { - g_warning ("Could not get the DBus object!"); - return FALSE; - } - - g_signal_connect (app->bus_proxy, "destroy", G_CALLBACK (destroy_cb), app); - - return TRUE; -} - -static gboolean -parse_config_file (const char *filename, char **plugins, GError **error) -{ - GKeyFile *config; - - config = g_key_file_new (); - if (!config) { - g_set_error (error, plugins_error_quark (), 0, - "Not enough memory to load config file."); - return FALSE; - } - - g_key_file_set_list_separator (config, ','); - if (!g_key_file_load_from_file (config, filename, G_KEY_FILE_NONE, error)) - return FALSE; - - *plugins = g_key_file_get_value (config, "main", "plugins", error); - if (*error) - return FALSE; - - g_key_file_free (config); - return TRUE; -} - -static void -log_handler (const gchar *log_domain, - GLogLevelFlags log_level, - const gchar *message, - gpointer ignored) -{ - int syslog_priority; - - switch (log_level) { - case G_LOG_LEVEL_ERROR: - syslog_priority = LOG_CRIT; - break; - - case G_LOG_LEVEL_CRITICAL: - syslog_priority = LOG_ERR; - break; - - case G_LOG_LEVEL_WARNING: - syslog_priority = LOG_WARNING; - break; - - case G_LOG_LEVEL_MESSAGE: - syslog_priority = LOG_NOTICE; - break; - - case G_LOG_LEVEL_DEBUG: - syslog_priority = LOG_DEBUG; - break; - - case G_LOG_LEVEL_INFO: - default: - syslog_priority = LOG_INFO; - break; - } - - syslog (syslog_priority, "%s", message); -} - - -static void -logging_setup (void) -{ - openlog (G_LOG_DOMAIN, LOG_CONS, LOG_DAEMON); - g_log_set_handler (G_LOG_DOMAIN, - G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, - log_handler, - NULL); -} - -static void -logging_shutdown (void) -{ - closelog (); -} - -static void -signal_handler (int signo) -{ - if (signo == SIGINT || signo == SIGTERM) { - if (debug) - g_message ("Caught signal %d, shutting down...", signo); - g_main_loop_quit (loop); - } -} - -static void -setup_signals (void) -{ - struct sigaction action; - sigset_t mask; - - sigemptyset (&mask); - action.sa_handler = signal_handler; - action.sa_mask = mask; - action.sa_flags = 0; - sigaction (SIGTERM, &action, NULL); - sigaction (SIGINT, &action, NULL); -} - -int -main (int argc, char **argv) -{ - Application *app = g_new0 (Application, 1); - GOptionContext *opt_ctx; - GError *error = NULL; - char *plugins = NULL; - char *config = NULL; - - GOptionEntry entries[] = { - { "config", 0, 0, G_OPTION_ARG_FILENAME, &config, "Config file location", "/path/to/config.file" }, - { "plugins", 0, 0, G_OPTION_ARG_STRING, &plugins, "List of plugins separated by ,", "plugin1,plugin2" }, - { "debug", 0, 0, G_OPTION_ARG_NONE, &debug, "Output to console rather than syslog", NULL }, - { NULL } - }; - - opt_ctx = g_option_context_new (NULL); - g_option_context_set_summary (opt_ctx, "Provides system network settings to NetworkManager."); - g_option_context_add_main_entries (opt_ctx, entries, NULL); - - if (!g_option_context_parse (opt_ctx, &argc, &argv, &error)) { - g_warning ("%s\n", error->message); - g_error_free (error); - return 1; - } - - g_option_context_free (opt_ctx); - - if (config) { - app->config = config; - if (!parse_config_file (app->config, &plugins, &error)) { - g_warning ("Invalid config file: %s.", error->message); - return 1; - } - } - - if (!plugins) { - g_warning ("No plugins were specified."); - return 1; - } - - g_type_init (); - - if (!g_module_supported ()) { - g_warning ("GModules are not supported on your platform!"); - return 1; - } - - loop = g_main_loop_new (NULL, FALSE); - - if (!debug) - logging_setup (); - - if (!dbus_init (app)) - return -1; - - app->hal_mgr = nm_system_config_hal_manager_get (app->g_connection); - app->settings = nm_sysconfig_settings_new (app->g_connection, app->hal_mgr); - - app->wired_devices = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, wired_device_info_destroy); - g_signal_connect (G_OBJECT (app->hal_mgr), "device-added", - G_CALLBACK (device_added_cb), app); - g_signal_connect (G_OBJECT (app->hal_mgr), "device-removed", - G_CALLBACK (device_removed_cb), app); - - /* Load the plugins; fail if a plugin is not found. */ - load_plugins (app, plugins, &error); - if (error) { - g_warning ("Error: %d - %s", error->code, error->message); - return -1; - } - g_free (plugins); - - setup_signals (); - - g_idle_add (load_stuff, app); - - g_main_loop_run (loop); - - nm_system_config_hal_manager_shutdown (app->hal_mgr); - g_object_unref (app->hal_mgr); - - g_hash_table_destroy (app->wired_devices); - - g_object_unref (app->settings); - dbus_cleanup (app); - - if (!debug) - logging_shutdown (); - - return 0; -} - diff --git a/system-settings/src/nm-default-wired-connection.c b/system-settings/src/nm-default-wired-connection.c deleted file mode 100644 index c8a6daab72..0000000000 --- a/system-settings/src/nm-default-wired-connection.c +++ /dev/null @@ -1,355 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager system settings service - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * (C) Copyright 2008 Novell, Inc. - * (C) Copyright 2009 Red Hat, Inc. - */ - -#include - -#include - -#include -#include -#include -#include -#include - -#include "nm-dbus-glib-types.h" -#include "nm-marshal.h" -#include "nm-default-wired-connection.h" - -G_DEFINE_TYPE (NMDefaultWiredConnection, nm_default_wired_connection, NM_TYPE_SYSCONFIG_CONNECTION) - -#define NM_DEFAULT_WIRED_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEFAULT_WIRED_CONNECTION, NMDefaultWiredConnectionPrivate)) - -typedef struct { - char *iface; - GByteArray *mac; - gboolean read_only; -} NMDefaultWiredConnectionPrivate; - -enum { - PROP_0, - PROP_MAC, - PROP_IFACE, - PROP_READ_ONLY, - LAST_PROP -}; - -enum { - TRY_UPDATE, - DELETED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0 }; - - -NMDefaultWiredConnection * -nm_default_wired_connection_new (const GByteArray *mac, - const char *iface, - gboolean read_only) -{ - - g_return_val_if_fail (mac != NULL, NULL); - g_return_val_if_fail (mac->len == ETH_ALEN, NULL); - g_return_val_if_fail (iface != NULL, NULL); - - return g_object_new (NM_TYPE_DEFAULT_WIRED_CONNECTION, - NM_DEFAULT_WIRED_CONNECTION_MAC, mac, - NM_DEFAULT_WIRED_CONNECTION_IFACE, iface, - NM_DEFAULT_WIRED_CONNECTION_READ_ONLY, read_only, - NULL); -} - -static GByteArray * -dup_wired_mac (NMExportedConnection *exported) -{ - NMConnection *wrapped; - NMSettingWired *s_wired; - const GByteArray *mac; - GByteArray *dup; - - wrapped = nm_exported_connection_get_connection (exported); - if (!wrapped) - return NULL; - - s_wired = (NMSettingWired *) nm_connection_get_setting (wrapped, NM_TYPE_SETTING_WIRED); - if (!s_wired) - return NULL; - - mac = nm_setting_wired_get_mac_address (s_wired); - if (!mac || (mac->len != ETH_ALEN)) - return NULL; - - dup = g_byte_array_sized_new (ETH_ALEN); - g_byte_array_append (dup, mac->data, ETH_ALEN); - return dup; -} - -static gboolean -update (NMExportedConnection *exported, - GHashTable *new_settings, - GError **error) -{ - NMDefaultWiredConnection *connection = NM_DEFAULT_WIRED_CONNECTION (exported); - gboolean success; - GByteArray *mac; - - /* Ensure object stays alive across signal emission */ - g_object_ref (exported); - - /* Save a copy of the current MAC address just in case the user - * changed it when updating the connection. - */ - mac = dup_wired_mac (exported); - - /* Let NMSysconfigConnection check permissions */ - success = NM_EXPORTED_CONNECTION_CLASS (nm_default_wired_connection_parent_class)->update (exported, new_settings, error); - if (success) { - g_signal_emit_by_name (connection, "try-update", new_settings, error); - success = *error ? FALSE : TRUE; - - if (success) - g_signal_emit (connection, signals[DELETED], 0, mac); - } - - g_byte_array_free (mac, TRUE); - g_object_unref (exported); - return success; -} - -static gboolean -do_delete (NMExportedConnection *exported, GError **error) -{ - gboolean success; - GByteArray *mac; - - g_object_ref (exported); - mac = dup_wired_mac (exported); - - success = NM_EXPORTED_CONNECTION_CLASS (nm_default_wired_connection_parent_class)->do_delete (exported, error); - if (success) - g_signal_emit (exported, signals[DELETED], 0, mac); - - g_byte_array_free (mac, TRUE); - g_object_unref (exported); - return success; -} - -static void -nm_default_wired_connection_init (NMDefaultWiredConnection *self) -{ -} - -static GObject * -constructor (GType type, - guint n_construct_params, - GObjectConstructParam *construct_params) -{ - GObject *object; - NMDefaultWiredConnectionPrivate *priv; - NMConnection *wrapped; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - char *id, *uuid; - - object = G_OBJECT_CLASS (nm_default_wired_connection_parent_class)->constructor (type, n_construct_params, construct_params); - if (!object) - return NULL; - - priv = NM_DEFAULT_WIRED_CONNECTION_GET_PRIVATE (object); - - wrapped = nm_connection_new (); - - s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); - - id = g_strdup_printf (_("Auto %s"), priv->iface); - uuid = nm_utils_uuid_generate (); - - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, id, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, - NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, - NM_SETTING_CONNECTION_UUID, uuid, - NM_SETTING_CONNECTION_READ_ONLY, priv->read_only, - NULL); - - g_free (id); - g_free (uuid); - - nm_connection_add_setting (wrapped, NM_SETTING (s_con)); - - /* Lock the connection to the specific device */ - s_wired = NM_SETTING_WIRED (nm_setting_wired_new ()); - g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, priv->mac, NULL); - nm_connection_add_setting (wrapped, NM_SETTING (s_wired)); - - g_object_set (object, NM_EXPORTED_CONNECTION_CONNECTION, wrapped, NULL); - g_object_unref (wrapped); - - return object; -} - -static void -finalize (GObject *object) -{ - NMDefaultWiredConnectionPrivate *priv = NM_DEFAULT_WIRED_CONNECTION_GET_PRIVATE (object); - - g_free (priv->iface); - g_byte_array_free (priv->mac, TRUE); - - G_OBJECT_CLASS (nm_default_wired_connection_parent_class)->finalize (object); -} - -static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) -{ - NMDefaultWiredConnectionPrivate *priv = NM_DEFAULT_WIRED_CONNECTION_GET_PRIVATE (object); - - switch (prop_id) { - case PROP_MAC: - g_value_set_pointer (value, priv->mac); - break; - case PROP_IFACE: - g_value_set_string (value, priv->iface); - break; - case PROP_READ_ONLY: - g_value_set_boolean (value, priv->read_only); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) -{ - NMDefaultWiredConnectionPrivate *priv = NM_DEFAULT_WIRED_CONNECTION_GET_PRIVATE (object); - GByteArray *array; - - switch (prop_id) { - case PROP_MAC: - /* Construct only */ - array = g_value_get_pointer (value); - if (priv->mac) { - g_byte_array_free (priv->mac, TRUE); - priv->mac = NULL; - } - if (array) { - g_return_if_fail (array->len == ETH_ALEN); - priv->mac = g_byte_array_sized_new (array->len); - g_byte_array_append (priv->mac, array->data, ETH_ALEN); - } - break; - case PROP_IFACE: - g_free (priv->iface); - priv->iface = g_value_dup_string (value); - break; - case PROP_READ_ONLY: - priv->read_only = g_value_get_boolean (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static gboolean -try_update_signal_accumulator (GSignalInvocationHint *ihint, - GValue *return_accu, - const GValue *handler_return, - gpointer data) -{ - gpointer new_ptr = g_value_get_pointer (handler_return); - - g_value_set_pointer (return_accu, new_ptr); - - /* Continue if no error was returned from the handler */ - return new_ptr ? FALSE : TRUE; -} - -static void -nm_default_wired_connection_class_init (NMDefaultWiredConnectionClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMExportedConnectionClass *exported_class = NM_EXPORTED_CONNECTION_CLASS (klass); - - g_type_class_add_private (klass, sizeof (NMDefaultWiredConnectionPrivate)); - - /* Virtual methods */ - object_class->constructor = constructor; - object_class->set_property = set_property; - object_class->get_property = get_property; - object_class->finalize = finalize; - - exported_class->update = update; - exported_class->do_delete = do_delete; - - /* Properties */ - g_object_class_install_property - (object_class, PROP_MAC, - g_param_spec_pointer (NM_DEFAULT_WIRED_CONNECTION_MAC, - "MAC", - "MAC Address", - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property - (object_class, PROP_IFACE, - g_param_spec_string (NM_DEFAULT_WIRED_CONNECTION_IFACE, - "Iface", - "Interface", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property - (object_class, PROP_READ_ONLY, - g_param_spec_boolean (NM_DEFAULT_WIRED_CONNECTION_READ_ONLY, - "ReadOnly", - "Read Only", - FALSE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - /* Signals */ - signals[TRY_UPDATE] = - g_signal_new ("try-update", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - 0, try_update_signal_accumulator, NULL, - _nm_marshal_POINTER__POINTER, - G_TYPE_POINTER, 1, - DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT); - - /* The 'deleted' signal is used to signal intentional deletions (like - * updating or user-requested deletion) rather than using the - * NMExportedConnection superclass' 'removed' signal, since that signal - * doesn't have the semantics we want; it gets emitted as a side-effect - * of various operations and is meant more for D-Bus clients instead - * of in-service uses. - */ - signals[DELETED] = - g_signal_new ("deleted", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - 0, NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, G_TYPE_POINTER); -} diff --git a/system-settings/src/nm-default-wired-connection.h b/system-settings/src/nm-default-wired-connection.h deleted file mode 100644 index 50c8b182e1..0000000000 --- a/system-settings/src/nm-default-wired-connection.h +++ /dev/null @@ -1,57 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager system settings service - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * (C) Copyright 2008 Novell, Inc. - * (C) Copyright 2009 Red Hat, Inc. - */ - -#ifndef NM_DEFAULT_WIRED_CONNECTION_H -#define NM_DEFAULT_WIRED_CONNECTION_H - -#include -#include "nm-sysconfig-connection.h" - -G_BEGIN_DECLS - -#define NM_TYPE_DEFAULT_WIRED_CONNECTION (nm_default_wired_connection_get_type ()) -#define NM_DEFAULT_WIRED_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEFAULT_WIRED_CONNECTION, NMDefaultWiredConnection)) -#define NM_DEFAULT_WIRED_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEFAULT_WIRED_CONNECTION, NMDefaultWiredConnectionClass)) -#define NM_IS_DEFAULT_WIRED_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEFAULT_WIRED_CONNECTION)) -#define NM_IS_DEFAULT_WIRED_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_DEFAULT_WIRED_CONNECTION)) -#define NM_DEFAULT_WIRED_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEFAULT_WIRED_CONNECTION, NMDefaultWiredConnectionClass)) - -#define NM_DEFAULT_WIRED_CONNECTION_MAC "mac" -#define NM_DEFAULT_WIRED_CONNECTION_IFACE "iface" -#define NM_DEFAULT_WIRED_CONNECTION_READ_ONLY "read-only" - -typedef struct { - NMSysconfigConnection parent; -} NMDefaultWiredConnection; - -typedef struct { - NMSysconfigConnectionClass parent; -} NMDefaultWiredConnectionClass; - -GType nm_default_wired_connection_get_type (void); - -NMDefaultWiredConnection *nm_default_wired_connection_new (const GByteArray *mac, - const char *iface, - gboolean read_only); - -G_END_DECLS - -#endif /* NM_DEFAULT_WIRED_CONNECTION_H */ diff --git a/system-settings/src/nm-inotify-helper.c b/system-settings/src/nm-inotify-helper.c deleted file mode 100644 index 589dbd6917..0000000000 --- a/system-settings/src/nm-inotify-helper.c +++ /dev/null @@ -1,211 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager system settings service - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * (C) Copyright 2008 Red Hat, Inc. - */ - -#include -#include -#include -#include - -#include "nm-marshal.h" -#include "nm-inotify-helper.h" - -G_DEFINE_TYPE (NMInotifyHelper, nm_inotify_helper, G_TYPE_OBJECT) - -#define NM_INOTIFY_HELPER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_INOTIFY_HELPER, NMInotifyHelperPrivate)) - -typedef struct { - int ifd; - - GHashTable *wd_refs; -} NMInotifyHelperPrivate; - -/* Signals */ -enum { - EVENT, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0 }; - -int -nm_inotify_helper_add_watch (NMInotifyHelper *self, const char *path) -{ - NMInotifyHelperPrivate *priv = NM_INOTIFY_HELPER_GET_PRIVATE (self); - int wd; - guint32 refcount; - - g_return_val_if_fail (priv->ifd >= 0, -1); - - /* We only care about modifications since we're just trying to get change - * notifications on hardlinks. - */ - - wd = inotify_add_watch (priv->ifd, path, IN_CLOSE_WRITE); - if (wd < 0) - return -1; - - refcount = GPOINTER_TO_UINT (g_hash_table_lookup (priv->wd_refs, GINT_TO_POINTER (wd))); - refcount++; - g_hash_table_replace (priv->wd_refs, GINT_TO_POINTER (wd), GUINT_TO_POINTER (refcount)); - - return wd; -} - -void -nm_inotify_helper_remove_watch (NMInotifyHelper *self, int wd) -{ - NMInotifyHelperPrivate *priv = NM_INOTIFY_HELPER_GET_PRIVATE (self); - guint32 refcount; - - g_return_if_fail (priv->ifd >= 0); - - refcount = GPOINTER_TO_UINT (g_hash_table_lookup (priv->wd_refs, GINT_TO_POINTER (wd))); - if (!refcount) - return; - - refcount--; - if (!refcount) { - g_hash_table_remove (priv->wd_refs, GINT_TO_POINTER (wd)); - inotify_rm_watch (priv->ifd, wd); - } else - g_hash_table_replace (priv->wd_refs, GINT_TO_POINTER (wd), GUINT_TO_POINTER (refcount)); -} - -static gboolean -inotify_event_handler (GIOChannel *channel, GIOCondition cond, gpointer user_data) -{ - NMInotifyHelper *self = NM_INOTIFY_HELPER (user_data); - struct inotify_event evt; - - /* read the notifications from the watch descriptor */ - while (g_io_channel_read_chars (channel, (gchar *) &evt, sizeof (struct inotify_event), NULL, NULL) == G_IO_STATUS_NORMAL) { - gchar filename[PATH_MAX + 1]; - - filename[0] = '\0'; - if (evt.len > 0) { - g_io_channel_read_chars (channel, - filename, - evt.len > PATH_MAX ? PATH_MAX : evt.len, - NULL, NULL); - } - - if (!(evt.mask & IN_IGNORED)) - g_signal_emit (self, signals[EVENT], 0, &evt, &filename[0]); - } - - return TRUE; -} - -static gboolean -init_inotify (NMInotifyHelper *self) -{ - NMInotifyHelperPrivate *priv = NM_INOTIFY_HELPER_GET_PRIVATE (self); - GIOChannel *channel; - guint source_id; - - priv->ifd = inotify_init (); - if (priv->ifd == -1) { - g_warning ("%s: couldn't initialize inotify", __func__); - return FALSE; - } - - /* Watch the inotify descriptor for file/directory change events */ - channel = g_io_channel_unix_new (priv->ifd); - if (!channel) { - g_warning ("%s: couldn't create new GIOChannel", __func__); - close (priv->ifd); - priv->ifd = -1; - return FALSE; - } - - g_io_channel_set_flags (channel, G_IO_FLAG_NONBLOCK, NULL); - g_io_channel_set_encoding (channel, NULL, NULL); - - source_id = g_io_add_watch (channel, - G_IO_IN | G_IO_ERR, - (GIOFunc) inotify_event_handler, - (gpointer) self); - g_io_channel_unref (channel); - return TRUE; -} - -NMInotifyHelper * -nm_inotify_helper_get (void) -{ - static NMInotifyHelper *singleton = NULL; - - if (!singleton) { - singleton = (NMInotifyHelper *) g_object_new (NM_TYPE_INOTIFY_HELPER, NULL); - if (!singleton) - return NULL; - - if (!init_inotify (singleton)) { - g_object_unref (singleton); - return NULL; - } - } else - g_object_ref (singleton); - - g_assert (singleton); - return singleton; -} - -static void -nm_inotify_helper_init (NMInotifyHelper *self) -{ - NMInotifyHelperPrivate *priv = NM_INOTIFY_HELPER_GET_PRIVATE (self); - - priv->wd_refs = g_hash_table_new (g_direct_hash, g_direct_equal); -} - -static void -finalize (GObject *object) -{ - NMInotifyHelperPrivate *priv = NM_INOTIFY_HELPER_GET_PRIVATE (object); - - if (priv->ifd >= 0) - close (priv->ifd); - - g_hash_table_destroy (priv->wd_refs); - - G_OBJECT_CLASS (nm_inotify_helper_parent_class)->finalize (object); -} - -static void -nm_inotify_helper_class_init (NMInotifyHelperClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (NMInotifyHelperPrivate)); - - /* Virtual methods */ - object_class->finalize = finalize; - - /* Signals */ - signals[EVENT] = - g_signal_new ("event", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (NMInotifyHelperClass, event), - NULL, NULL, - _nm_marshal_VOID__POINTER_STRING, - G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_STRING); -} - diff --git a/system-settings/src/nm-inotify-helper.h b/system-settings/src/nm-inotify-helper.h deleted file mode 100644 index 10d43ac99f..0000000000 --- a/system-settings/src/nm-inotify-helper.h +++ /dev/null @@ -1,54 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager system settings service - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * (C) Copyright 2008 Red Hat, Inc. - */ - -#ifndef __INOTIFY_HELPER_H__ -#define __INOTIFY_HELPER_H__ - -#include -#include -#include - -#define NM_TYPE_INOTIFY_HELPER (nm_inotify_helper_get_type ()) -#define NM_INOTIFY_HELPER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_INOTIFY_HELPER, NMInotifyHelper)) -#define NM_INOTIFY_HELPER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_INOTIFY_HELPER, NMInotifyHelperClass)) -#define NM_IS_INOTIFY_HELPER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_INOTIFY_HELPER)) -#define NM_IS_INOTIFY_HELPER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_INOTIFY_HELPER)) -#define NM_INOTIFY_HELPER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_INOTIFY_HELPER, NMInotifyHelperClass)) - -typedef struct { - GObject parent; -} NMInotifyHelper; - -typedef struct { - GObjectClass parent; - - /* signals */ - void (* event) (NMInotifyHelper *helper, struct inotify_event *evt, const char *filename); -} NMInotifyHelperClass; - -GType nm_inotify_helper_get_type (void); - -NMInotifyHelper * nm_inotify_helper_get (void); - -int nm_inotify_helper_add_watch (NMInotifyHelper *helper, const char *path); - -void nm_inotify_helper_remove_watch (NMInotifyHelper *helper, int wd); - -#endif /* __INOTIFY_HELPER_H__ */ diff --git a/system-settings/src/nm-polkit-helpers.c b/system-settings/src/nm-polkit-helpers.c deleted file mode 100644 index 496a6f7ed1..0000000000 --- a/system-settings/src/nm-polkit-helpers.c +++ /dev/null @@ -1,148 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager system settings service - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * (C) Copyright 2008 Novell, Inc. - * (C) Copyright 2008 Red Hat, Inc. - */ - -#include -#include "nm-polkit-helpers.h" -#include "nm-system-config-error.h" - -static gboolean -pk_io_watch_have_data (GIOChannel *channel, GIOCondition condition, gpointer user_data) -{ - int fd; - PolKitContext *pk_context = (PolKitContext *) user_data; - - fd = g_io_channel_unix_get_fd (channel); - polkit_context_io_func (pk_context, fd); - - return TRUE; -} - -static int -pk_io_add_watch (PolKitContext *pk_context, int fd) -{ - guint id = 0; - GIOChannel *channel; - - channel = g_io_channel_unix_new (fd); - if (channel == NULL) - goto out; - id = g_io_add_watch (channel, G_IO_IN, pk_io_watch_have_data, pk_context); - if (id == 0) { - g_io_channel_unref (channel); - goto out; - } - g_io_channel_unref (channel); - - out: - return id; -} - -static void -pk_io_remove_watch (PolKitContext *pk_context, int watch_id) -{ - g_source_remove (watch_id); -} - -PolKitContext * -create_polkit_context (GError **error) -{ - static PolKitContext *global_context = NULL; - PolKitError *pk_err = NULL; - - if (G_LIKELY (global_context)) - return polkit_context_ref (global_context); - - global_context = polkit_context_new (); - polkit_context_set_io_watch_functions (global_context, pk_io_add_watch, pk_io_remove_watch); - if (!polkit_context_init (global_context, &pk_err)) { - g_set_error (error, NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_GENERAL, - "%s (%d): %s", - pk_err ? polkit_error_get_error_name (pk_err) : "(unknown)", - pk_err ? polkit_error_get_error_code (pk_err) : -1, - pk_err ? polkit_error_get_error_message (pk_err) : "(unknown)"); - if (pk_err) - polkit_error_free (pk_err); - - /* PK 0.6's polkit_context_init() unrefs the global_context on failure */ -#if (POLKIT_VERSION_MAJOR == 0) && (POLKIT_VERSION_MINOR >= 7) - polkit_context_unref (global_context); -#endif - global_context = NULL; - } - - return global_context; -} - -gboolean -check_polkit_privileges (DBusGConnection *dbus_connection, - PolKitContext *pol_ctx, - DBusGMethodInvocation *context, - GError **err) -{ - DBusError dbus_error; - char *sender; - PolKitCaller *pk_caller; - PolKitAction *pk_action; - PolKitResult pk_result; - - dbus_error_init (&dbus_error); - sender = dbus_g_method_get_sender (context); - pk_caller = polkit_caller_new_from_dbus_name (dbus_g_connection_get_connection (dbus_connection), - sender, - &dbus_error); - g_free (sender); - - if (dbus_error_is_set (&dbus_error)) { - *err = g_error_new (NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_NOT_PRIVILEGED, - "Error getting information about caller: %s: %s", - dbus_error.name, dbus_error.message); - dbus_error_free (&dbus_error); - - if (pk_caller) - polkit_caller_unref (pk_caller); - - return FALSE; - } - - pk_action = polkit_action_new (); - polkit_action_set_action_id (pk_action, NM_SYSCONFIG_POLICY_ACTION); - -#if (POLKIT_VERSION_MAJOR == 0) && (POLKIT_VERSION_MINOR < 7) - pk_result = polkit_context_can_caller_do_action (pol_ctx, pk_action, pk_caller); -#else - pk_result = polkit_context_is_caller_authorized (pol_ctx, pk_action, pk_caller, TRUE, NULL); -#endif - polkit_caller_unref (pk_caller); - polkit_action_unref (pk_action); - - if (pk_result != POLKIT_RESULT_YES) { - *err = g_error_new (NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_NOT_PRIVILEGED, - "%s %s", - NM_SYSCONFIG_POLICY_ACTION, - polkit_result_to_string_representation (pk_result)); - return FALSE; - } - - return TRUE; -} diff --git a/system-settings/src/nm-polkit-helpers.h b/system-settings/src/nm-polkit-helpers.h deleted file mode 100644 index 1382648c13..0000000000 --- a/system-settings/src/nm-polkit-helpers.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager system settings service - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * (C) Copyright 2008 Novell, Inc. - * (C) Copyright 2008 Red Hat, Inc. - */ - -#ifndef NM_POLKIT_HELPERS_H -#define NM_POLKIT_HELPERS_H - -#include -#include -#include - -#define NM_SYSCONFIG_POLICY_ACTION "org.freedesktop.network-manager-settings.system.modify" - -PolKitContext *create_polkit_context (GError **error); -gboolean check_polkit_privileges (DBusGConnection *dbus_connection, - PolKitContext *pol_ctx, - DBusGMethodInvocation *context, - GError **err); - -#endif /* NM_POLKIT_HELPERS_H */ diff --git a/system-settings/src/nm-sysconfig-connection.c b/system-settings/src/nm-sysconfig-connection.c deleted file mode 100644 index c98c89ab1a..0000000000 --- a/system-settings/src/nm-sysconfig-connection.c +++ /dev/null @@ -1,344 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager system settings service - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * (C) Copyright 2008 Novell, Inc. - */ - -#include -#include "nm-sysconfig-connection.h" -#include "nm-system-config-error.h" -#include "nm-polkit-helpers.h" -#include "nm-dbus-glib-types.h" - -G_DEFINE_ABSTRACT_TYPE (NMSysconfigConnection, nm_sysconfig_connection, NM_TYPE_EXPORTED_CONNECTION) - -#define NM_SYSCONFIG_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SYSCONFIG_CONNECTION, NMSysconfigConnectionPrivate)) - -typedef struct { - DBusGConnection *dbus_connection; - PolKitContext *pol_ctx; - - DBusGProxy *proxy; -} NMSysconfigConnectionPrivate; - -static gboolean -update (NMExportedConnection *exported, - GHashTable *new_settings, - GError **err) -{ - NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (exported); - DBusGMethodInvocation *context; - - context = g_object_get_data (G_OBJECT (exported), NM_EXPORTED_CONNECTION_DBUS_METHOD_INVOCATION); - g_return_val_if_fail (context != NULL, FALSE); - - return check_polkit_privileges (priv->dbus_connection, priv->pol_ctx, context, err); -} - -static gboolean -do_delete (NMExportedConnection *exported, GError **err) -{ - NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (exported); - DBusGMethodInvocation *context; - - context = g_object_get_data (G_OBJECT (exported), NM_EXPORTED_CONNECTION_DBUS_METHOD_INVOCATION); - g_return_val_if_fail (context != NULL, FALSE); - - return check_polkit_privileges (priv->dbus_connection, priv->pol_ctx, context, err); -} - -static GValue * -string_to_gvalue (const char *str) -{ - GValue *val = g_slice_new0 (GValue); - - g_value_init (val, G_TYPE_STRING); - g_value_set_string (val, str); - return val; -} - -static void -copy_one_secret (gpointer key, gpointer value, gpointer user_data) -{ - const char *value_str = (const char *) value; - - if (value_str) { - g_hash_table_insert ((GHashTable *) user_data, - g_strdup ((char *) key), - string_to_gvalue (value_str)); - } -} - -static void -add_secrets (NMSetting *setting, - const char *key, - const GValue *value, - GParamFlags flags, - gpointer user_data) -{ - GHashTable *secrets = user_data; - - if (!(flags & NM_SETTING_PARAM_SECRET)) - return; - - if (G_VALUE_HOLDS_STRING (value)) { - const char *tmp; - - tmp = g_value_get_string (value); - if (tmp) - g_hash_table_insert (secrets, g_strdup (key), string_to_gvalue (tmp)); - } else if (G_VALUE_HOLDS (value, DBUS_TYPE_G_MAP_OF_STRING)) { - /* Flatten the string hash by pulling its keys/values out */ - g_hash_table_foreach (g_value_get_boxed (value), copy_one_secret, secrets); - } -} - -static void -destroy_gvalue (gpointer data) -{ - GValue *value = (GValue *) data; - - g_value_unset (value); - g_slice_free (GValue, value); -} - -static GHashTable * -real_get_secrets (NMSysconfigConnection *self, - const gchar *setting_name, - const gchar **hints, - gboolean request_new, - GError **error) -{ - NMConnection *connection; - GHashTable *settings = NULL; - GHashTable *secrets = NULL; - NMSetting *setting; - - connection = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (self)); - setting = nm_connection_get_setting_by_name (connection, setting_name); - if (!setting) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "%s.%d - Connection didn't have requested setting '%s'.", - __FILE__, __LINE__, setting_name); - return NULL; - } - - /* Returned secrets are a{sa{sv}}; this is the outer a{s...} hash that - * will contain all the individual settings hashes. - */ - settings = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, (GDestroyNotify) g_hash_table_destroy); - - /* Add the secrets from this setting to the inner secrets hash for this setting */ - secrets = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, destroy_gvalue); - nm_setting_enumerate_values (setting, add_secrets, secrets); - - g_hash_table_insert (settings, g_strdup (setting_name), secrets); - return settings; -} - -typedef struct { - NMSysconfigConnection *self; - char *setting_name; - DBusGMethodInvocation *context; -} GetUnixUserInfo; - -static GetUnixUserInfo * -get_unix_user_info_new (NMSysconfigConnection *self, - const char *setting_name, - DBusGMethodInvocation *context) -{ - GetUnixUserInfo *info; - - g_return_val_if_fail (self != NULL, NULL); - g_return_val_if_fail (setting_name != NULL, NULL); - g_return_val_if_fail (context != NULL, NULL); - - info = g_malloc0 (sizeof (GetUnixUserInfo)); - info->self = self; - info->setting_name = g_strdup (setting_name); - info->context = context; - return info; -} - -static void -get_unix_user_info_free (gpointer user_data) -{ - GetUnixUserInfo *info = user_data; - - g_free (info->setting_name); - g_free (info); -} - -static void -get_unix_user_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data) -{ - GetUnixUserInfo *info = user_data; - NMSysconfigConnection *self; - NMSysconfigConnectionPrivate *priv; - GError *error = NULL; - guint32 requestor_uid = G_MAXUINT32; - GHashTable *secrets; - - g_return_if_fail (info != NULL); - - self = info->self; - priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self); - - if (!dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_UINT, &requestor_uid, G_TYPE_INVALID)) - goto error; - - /* Non-root users need PolicyKit authorization */ - if (requestor_uid != 0) { - if (!check_polkit_privileges (priv->dbus_connection, priv->pol_ctx, info->context, &error)) - goto error; - } - - secrets = real_get_secrets (self, info->setting_name, NULL, FALSE, &error); - if (secrets) { - /* success; return secrets to caller */ - dbus_g_method_return (info->context, secrets); - g_hash_table_destroy (secrets); - return; - } - - if (!error) { - /* Shouldn't happen, but... */ - g_set_error (&error, NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_GENERAL, - "%s", "Could not get secrets from connection (unknown error ocurred)"); - } - -error: - dbus_g_method_return_error (info->context, error); - g_clear_error (&error); -} - -static void -service_get_secrets (NMExportedConnection *exported, - const gchar *setting_name, - const gchar **hints, - gboolean request_new, - DBusGMethodInvocation *context) -{ - NMSysconfigConnection *self = NM_SYSCONFIG_CONNECTION (exported); - NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self); - GetUnixUserInfo *info; - GError *error = NULL; - char *sender = NULL; - - sender = dbus_g_method_get_sender (context); - if (!sender) { - g_set_error (&error, NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_GENERAL, - "%s", "Could not determine D-Bus requestor to authorize GetSecrets request"); - goto out; - } - - if (priv->proxy) - g_object_unref (priv->proxy); - - priv->proxy = dbus_g_proxy_new_for_name (priv->dbus_connection, - DBUS_SERVICE_DBUS, - DBUS_PATH_DBUS, - DBUS_INTERFACE_DBUS); - if (!priv->proxy) { - g_set_error (&error, NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_GENERAL, - "%s", "Could not connect to D-Bus to authorize GetSecrets request"); - goto out; - } - - info = get_unix_user_info_new (self, setting_name, context); - if (!info) { - g_set_error (&error, NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_GENERAL, - "%s", "Not enough memory to authorize GetSecrets request"); - goto out; - } - - dbus_g_proxy_begin_call_with_timeout (priv->proxy, "GetConnectionUnixUser", - get_unix_user_cb, - info, - get_unix_user_info_free, - 5000, - G_TYPE_STRING, sender, - G_TYPE_INVALID); - -out: - if (error) { - dbus_g_method_return_error (context, error); - g_error_free (error); - } -} - -/* GObject */ - -static void -nm_sysconfig_connection_init (NMSysconfigConnection *self) -{ - NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self); - GError *err = NULL; - - priv->dbus_connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &err); - if (err) { - g_warning ("%s: error getting D-Bus connection: %s", - __func__, - (err && err->message) ? err->message : "(unknown)"); - g_error_free (err); - } - - priv->pol_ctx = create_polkit_context (&err); - if (!priv->pol_ctx) { - g_warning ("%s: error creating PolicyKit context: %s", - __func__, - (err && err->message) ? err->message : "(unknown)"); - } -} - -static void -dispose (GObject *object) -{ - NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (object); - - if (priv->proxy) - g_object_unref (priv->proxy); - - if (priv->pol_ctx) - polkit_context_unref (priv->pol_ctx); - - if (priv->dbus_connection) - dbus_g_connection_unref (priv->dbus_connection); - - G_OBJECT_CLASS (nm_sysconfig_connection_parent_class)->dispose (object); -} - -static void -nm_sysconfig_connection_class_init (NMSysconfigConnectionClass *sysconfig_connection_class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (sysconfig_connection_class); - NMExportedConnectionClass *connection_class = NM_EXPORTED_CONNECTION_CLASS (sysconfig_connection_class); - - g_type_class_add_private (sysconfig_connection_class, sizeof (NMSysconfigConnectionPrivate)); - - /* Virtual methods */ - object_class->dispose = dispose; - - connection_class->update = update; - connection_class->do_delete = do_delete; - connection_class->service_get_secrets = service_get_secrets; -} diff --git a/system-settings/src/nm-sysconfig-connection.h b/system-settings/src/nm-sysconfig-connection.h deleted file mode 100644 index 3acff25732..0000000000 --- a/system-settings/src/nm-sysconfig-connection.h +++ /dev/null @@ -1,47 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager system settings service - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * (C) Copyright 2008 Novell, Inc. - */ - -#ifndef NM_SYSCONFIG_CONNECTION_H -#define NM_SYSCONFIG_CONNECTION_H - -#include - -G_BEGIN_DECLS - -#define NM_TYPE_SYSCONFIG_CONNECTION (nm_sysconfig_connection_get_type ()) -#define NM_SYSCONFIG_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SYSCONFIG_CONNECTION, NMSysconfigConnection)) -#define NM_SYSCONFIG_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SYSCONFIG_CONNECTION, NMSysconfigConnectionClass)) -#define NM_IS_SYSCONFIG_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SYSCONFIG_CONNECTION)) -#define NM_IS_SYSCONFIG_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_SYSCONFIG_CONNECTION)) -#define NM_SYSCONFIG_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SYSCONFIG_CONNECTION, NMSysconfigConnectionClass)) - -typedef struct { - NMExportedConnection parent; -} NMSysconfigConnection; - -typedef struct { - NMExportedConnectionClass parent; -} NMSysconfigConnectionClass; - -GType nm_sysconfig_connection_get_type (void); - -G_END_DECLS - -#endif /* NM_SYSCONFIG_CONNECTION_H */ diff --git a/system-settings/src/nm-system-config-error.c b/system-settings/src/nm-system-config-error.c deleted file mode 100644 index 13d47462f9..0000000000 --- a/system-settings/src/nm-system-config-error.c +++ /dev/null @@ -1,59 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager system settings service - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2008 Novell, Inc. - * Copyright (C) 2008 Red Hat, Inc. - */ - -#include "nm-system-config-error.h" - -GQuark -nm_sysconfig_settings_error_quark (void) -{ - static GQuark ret = 0; - - if (ret == 0) - ret = g_quark_from_static_string ("nm_sysconfig_settings_error"); - - return ret; -} - -#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } - -GType -nm_sysconfig_settings_error_get_type (void) -{ - static GType etype = 0; - - if (etype == 0) { - static const GEnumValue values[] = { - ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_GENERAL, "GeneralError"), - ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_NOT_PRIVILEGED, "NotPrivileged"), - ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_ADD_NOT_SUPPORTED, "AddNotSupported"), - ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_UPDATE_NOT_SUPPORTED, "UpdateNotSupported"), - ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_DELETE_NOT_SUPPORTED, "DeleteNotSupported"), - ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_ADD_FAILED, "AddFailed"), - ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_SAVE_HOSTNAME_NOT_SUPPORTED, "SaveHostnameNotSupported"), - ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_SAVE_HOSTNAME_FAILED, "SaveHostnameFailed"), - { 0, 0, 0 } - }; - - etype = g_enum_register_static ("NMSysconfigSettingsError", values); - } - - return etype; -} diff --git a/system-settings/src/nm-system-config-error.h b/system-settings/src/nm-system-config-error.h deleted file mode 100644 index 63896fcd09..0000000000 --- a/system-settings/src/nm-system-config-error.h +++ /dev/null @@ -1,45 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager system settings service - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2008 Novell, Inc. - * Copyright (C) 2008 Red Hat, Inc. - */ - -#ifndef NM_SYSTEM_CONFIG_ERROR_H -#define NM_SYSTEM_CONFIG_ERROR_H - -#include -#include - -enum { - NM_SYSCONFIG_SETTINGS_ERROR_GENERAL = 0, - NM_SYSCONFIG_SETTINGS_ERROR_NOT_PRIVILEGED, - NM_SYSCONFIG_SETTINGS_ERROR_ADD_NOT_SUPPORTED, - NM_SYSCONFIG_SETTINGS_ERROR_UPDATE_NOT_SUPPORTED, - NM_SYSCONFIG_SETTINGS_ERROR_DELETE_NOT_SUPPORTED, - NM_SYSCONFIG_SETTINGS_ERROR_ADD_FAILED, - NM_SYSCONFIG_SETTINGS_ERROR_SAVE_HOSTNAME_NOT_SUPPORTED, - NM_SYSCONFIG_SETTINGS_ERROR_SAVE_HOSTNAME_FAILED, -}; - -#define NM_SYSCONFIG_SETTINGS_ERROR (nm_sysconfig_settings_error_quark ()) -#define NM_TYPE_SYSCONFIG_SETTINGS_ERROR (nm_sysconfig_settings_error_get_type ()) - -GQuark nm_sysconfig_settings_error_quark (void); -GType nm_sysconfig_settings_error_get_type (void); - -#endif /* NM_SYSTEM_CONFIG_ERROR_H */ diff --git a/system-settings/src/nm-system-config-hal-manager.c b/system-settings/src/nm-system-config-hal-manager.c deleted file mode 100644 index fc5c23cd8f..0000000000 --- a/system-settings/src/nm-system-config-hal-manager.c +++ /dev/null @@ -1,388 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager system settings service - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2008 Red Hat, Inc. - * Copyright (C) 2008 Novell, Inc. - */ - -#include -#include -#include -#include - -#include "nm-marshal.h" -#include "nm-dbus-glib-types.h" -#include "nm-system-config-hal-manager.h" - -NMSystemConfigHalManager *nm_system_config_hal_manager_get (DBusGConnection *g_connection); - -void nm_system_config_hal_manager_shutdown (NMSystemConfigHalManager *self); - -#define NUM_DEVICE_TYPES NM_DEVICE_TYPE_CDMA - -typedef struct { - DBusGConnection *g_connection; - DBusGProxy *proxy; - GHashTable *devices; -} NMSystemConfigHalManagerPrivate; - -#define NM_SYSTEM_CONFIG_HAL_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \ - NM_TYPE_SYSTEM_CONFIG_HAL_MANAGER, \ - NMSystemConfigHalManagerPrivate)) - -G_DEFINE_TYPE (NMSystemConfigHalManager, nm_system_config_hal_manager, G_TYPE_OBJECT) - -enum { - DEVICE_ADDED, - DEVICE_REMOVED, - - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0 }; - -static NMDeviceType -get_type_for_udi (NMSystemConfigHalManager *manager, const char *udi) -{ - NMSystemConfigHalManagerPrivate *priv = NM_SYSTEM_CONFIG_HAL_MANAGER_GET_PRIVATE (manager); - NMDeviceType devtype = NM_DEVICE_TYPE_UNKNOWN; - DBusGProxy *dev_proxy; - GError *error = NULL; - GSList *capabilities = NULL, *iter; - - dev_proxy = dbus_g_proxy_new_for_name (priv->g_connection, - "org.freedesktop.Hal", - udi, - "org.freedesktop.Hal.Device"); - if (!dev_proxy) - return NM_DEVICE_TYPE_UNKNOWN; - - if (!dbus_g_proxy_call_with_timeout (dev_proxy, - "GetPropertyStringList", 10000, &error, - G_TYPE_STRING, "info.capabilities", G_TYPE_INVALID, - DBUS_TYPE_G_LIST_OF_STRING, &capabilities, G_TYPE_INVALID)) { - g_error_free (error); - goto out; - } - - if (!g_slist_length (capabilities)) - goto out; - - for (iter = capabilities; iter && (devtype == NM_DEVICE_TYPE_UNKNOWN); iter = g_slist_next (iter)) { - if (!strcmp (iter->data, "net.80203")) - devtype = NM_DEVICE_TYPE_ETHERNET; - else if (!strcmp (iter->data, "net.80211")) - devtype = NM_DEVICE_TYPE_WIFI; - else if (!strcmp (iter->data, "modem")) { - GSList *csets = NULL, *elt; - - if (dbus_g_proxy_call_with_timeout (dev_proxy, - "GetPropertyStringList", 10000, &error, - G_TYPE_STRING, "modem.command_sets", G_TYPE_INVALID, - DBUS_TYPE_G_LIST_OF_STRING, &csets, G_TYPE_INVALID)) { - for (elt = csets; elt && (devtype == NM_DEVICE_TYPE_UNKNOWN); elt = g_slist_next (elt)) { - if (!strcmp (elt->data, "GSM-07.07")) - devtype = NM_DEVICE_TYPE_GSM; - else if (!strcmp (elt->data, "IS-707-A")) - devtype = NM_DEVICE_TYPE_CDMA; - } - - g_slist_foreach (csets, (GFunc) g_free, NULL); - g_slist_free (csets); - } - } - } - - g_boxed_free (DBUS_TYPE_G_LIST_OF_STRING, capabilities); - -out: - g_object_unref (dev_proxy); - return devtype; -} - -static void -device_added_cb (DBusGProxy *proxy, const char *udi, gpointer user_data) -{ - NMSystemConfigHalManager *manager = NM_SYSTEM_CONFIG_HAL_MANAGER (user_data); - NMSystemConfigHalManagerPrivate *priv = NM_SYSTEM_CONFIG_HAL_MANAGER_GET_PRIVATE (manager); - NMDeviceType devtype; - - if (!g_hash_table_lookup (priv->devices, udi)) { - devtype = get_type_for_udi (manager, udi); - if (devtype != NM_DEVICE_TYPE_UNKNOWN) { - g_hash_table_insert (priv->devices, g_strdup (udi), GUINT_TO_POINTER (devtype)); - g_signal_emit (manager, signals[DEVICE_ADDED], 0, udi, devtype); - } - } -} - -static void -device_removed_cb (DBusGProxy *proxy, const char *udi, gpointer user_data) -{ - NMSystemConfigHalManager *manager = NM_SYSTEM_CONFIG_HAL_MANAGER (user_data); - NMSystemConfigHalManagerPrivate *priv = NM_SYSTEM_CONFIG_HAL_MANAGER_GET_PRIVATE (manager); - NMDeviceType devtype; - - devtype = GPOINTER_TO_UINT (g_hash_table_lookup (priv->devices, udi)); - if (devtype != NM_DEVICE_TYPE_UNKNOWN) { - g_signal_emit (manager, signals[DEVICE_REMOVED], 0, udi, devtype); - g_hash_table_remove (priv->devices, udi); - } -} - -static void -device_new_capability_cb (DBusGProxy *proxy, - const char *udi, - const char *capability, - gpointer user_data) -{ - NMSystemConfigHalManager *manager = NM_SYSTEM_CONFIG_HAL_MANAGER (user_data); - NMSystemConfigHalManagerPrivate *priv = NM_SYSTEM_CONFIG_HAL_MANAGER_GET_PRIVATE (manager); - NMDeviceType devtype; - - if (!g_hash_table_lookup (priv->devices, udi)) { - devtype = get_type_for_udi (manager, udi); - if (devtype != NM_DEVICE_TYPE_UNKNOWN) { - g_hash_table_insert (priv->devices, g_strdup (udi), GUINT_TO_POINTER (devtype)); - g_signal_emit (manager, signals[DEVICE_ADDED], 0, udi, devtype); - } - } -} - -static void -initial_add_devices_of_type (NMSystemConfigHalManager *manager, const char *capability) -{ - NMSystemConfigHalManagerPrivate *priv = NM_SYSTEM_CONFIG_HAL_MANAGER_GET_PRIVATE (manager); - GSList *devices = NULL, *iter; - GError *error = NULL; - - if (!dbus_g_proxy_call_with_timeout (priv->proxy, - "FindDeviceByCapability", 10000, &error, - G_TYPE_STRING, capability, G_TYPE_INVALID, - DBUS_TYPE_G_LIST_OF_STRING, &devices, G_TYPE_INVALID)) { - g_warning ("%s: could not get device from HAL: %s (%d).", - __func__, error->message, error->code); - g_error_free (error); - return; - } - - for (iter = devices; iter; iter = g_slist_next (iter)) - device_added_cb (priv->proxy, (const char *) iter->data, manager); - - if (devices) - g_boxed_free (DBUS_TYPE_G_LIST_OF_STRING, devices); -} - -static gboolean -init_dbus (NMSystemConfigHalManager *manager, DBusGConnection *g_connection) -{ - NMSystemConfigHalManagerPrivate *priv = NM_SYSTEM_CONFIG_HAL_MANAGER_GET_PRIVATE (manager); - - priv->g_connection = g_connection; - priv->proxy = dbus_g_proxy_new_for_name (priv->g_connection, - "org.freedesktop.Hal", - "/org/freedesktop/Hal/Manager", - "org.freedesktop.Hal.Manager"); - if (!priv->proxy) { - g_warning ("Could not get the HAL object!"); - priv->g_connection = NULL; - return FALSE; - } - - dbus_g_proxy_add_signal (priv->proxy, "DeviceAdded", G_TYPE_STRING, G_TYPE_INVALID); - dbus_g_proxy_connect_signal (priv->proxy, "DeviceAdded", G_CALLBACK (device_added_cb), manager, NULL); - - dbus_g_proxy_add_signal (priv->proxy, "DeviceRemoved", G_TYPE_STRING, G_TYPE_INVALID); - dbus_g_proxy_connect_signal (priv->proxy, "DeviceRemoved", G_CALLBACK (device_removed_cb), manager, NULL); - - dbus_g_object_register_marshaller (_nm_marshal_VOID__STRING_STRING, - G_TYPE_NONE, - G_TYPE_STRING, G_TYPE_STRING, - G_TYPE_INVALID); - dbus_g_proxy_add_signal (priv->proxy, "NewCapability", G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID); - dbus_g_proxy_connect_signal (priv->proxy, "NewCapability", G_CALLBACK (device_new_capability_cb), manager, NULL); - - initial_add_devices_of_type (manager, "net.80203"); - initial_add_devices_of_type (manager, "net.80211"); - initial_add_devices_of_type (manager, "modem"); - - return TRUE; -} - -static NMSystemConfigHalManager * -nm_system_config_hal_manager_new (DBusGConnection *g_connection) -{ - NMSystemConfigHalManager *manager; - - g_return_val_if_fail (g_connection != NULL, NULL); - - manager = g_object_new (NM_TYPE_SYSTEM_CONFIG_HAL_MANAGER, NULL); - - if (!init_dbus (manager, g_connection)) { - g_object_unref (manager); - return NULL; - } - - return manager; -} - -NMSystemConfigHalManager * -nm_system_config_hal_manager_get (DBusGConnection *g_connection) -{ - static NMSystemConfigHalManager *singleton = NULL; - - if (!singleton) - singleton = nm_system_config_hal_manager_new (g_connection); - else - g_object_ref (singleton); - - return singleton; -} - -static void -nm_system_config_hal_manager_init (NMSystemConfigHalManager *manager) -{ - NMSystemConfigHalManagerPrivate *priv = NM_SYSTEM_CONFIG_HAL_MANAGER_GET_PRIVATE (manager); - - priv->devices = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); -} - -static void -signal_removed (gpointer key, gpointer data, gpointer user_data) -{ - NMSystemConfigHalManager *manager = NM_SYSTEM_CONFIG_HAL_MANAGER (user_data); - - g_signal_emit (manager, signals[DEVICE_REMOVED], 0, key, GPOINTER_TO_UINT (data)); -} - -void -nm_system_config_hal_manager_shutdown (NMSystemConfigHalManager *self) -{ - NMSystemConfigHalManagerPrivate *priv = NM_SYSTEM_CONFIG_HAL_MANAGER_GET_PRIVATE (self); - - g_hash_table_foreach (priv->devices, (GHFunc) signal_removed, self); - g_hash_table_remove_all (priv->devices); -} - -static void -dispose (GObject *object) -{ - NMSystemConfigHalManagerPrivate *priv = NM_SYSTEM_CONFIG_HAL_MANAGER_GET_PRIVATE (object); - - if (priv->devices) { - g_hash_table_remove_all (priv->devices); - g_hash_table_destroy (priv->devices); - } - - if (priv->proxy) { - g_object_unref (priv->proxy); - priv->proxy = NULL; - } - - priv->g_connection = NULL; - - G_OBJECT_CLASS (nm_system_config_hal_manager_parent_class)->dispose (object); -} - -static void -nm_system_config_hal_manager_class_init (NMSystemConfigHalManagerClass *manager_class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (manager_class); - - g_type_class_add_private (manager_class, sizeof (NMSystemConfigHalManagerPrivate)); - - /* virtual methods */ - object_class->dispose = dispose; - - /* signals */ - signals[DEVICE_ADDED] = - g_signal_new ("device-added", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMSystemConfigHalManagerClass, device_added), - NULL, NULL, - _nm_marshal_VOID__STRING_UINT, - G_TYPE_NONE, 2, - G_TYPE_STRING, - G_TYPE_UINT); - - signals[DEVICE_REMOVED] = - g_signal_new ("device-removed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMSystemConfigHalManagerClass, device_removed), - NULL, NULL, - _nm_marshal_VOID__STRING_UINT, - G_TYPE_NONE, 2, - G_TYPE_STRING, - G_TYPE_UINT); -} - -typedef struct { - NMDeviceType devtype; - GSList **list; -} GetDeviceInfo; - -static void -add_devices_of_type (gpointer key, gpointer data, gpointer user_data) -{ - GetDeviceInfo *info = (GetDeviceInfo *) user_data; - - if (GPOINTER_TO_UINT (data) == info->devtype) - *(info->list) = g_slist_append (*(info->list), g_strdup (key)); -} - -GSList * -nm_system_config_hal_manager_get_devices_of_type (NMSystemConfigHalManager *manager, - NMDeviceType devtype) -{ - NMSystemConfigHalManagerPrivate *priv; - GetDeviceInfo info; - GSList *list = NULL; - - g_return_val_if_fail (NM_IS_SYSTEM_CONFIG_HAL_MANAGER (manager), NULL); - g_return_val_if_fail (devtype <= NUM_DEVICE_TYPES, NULL); - - priv = NM_SYSTEM_CONFIG_HAL_MANAGER_GET_PRIVATE (manager); - info.devtype = devtype; - info.list = &list; - g_hash_table_foreach (priv->devices, (GHFunc) add_devices_of_type, &info); - - return list; -} - -NMDeviceType -nm_system_config_hal_manager_get_type_for_udi (NMSystemConfigHalManager *manager, - const char *udi) -{ - NMSystemConfigHalManagerPrivate *priv; - - g_return_val_if_fail (NM_IS_SYSTEM_CONFIG_HAL_MANAGER (manager), NM_DEVICE_TYPE_UNKNOWN); - g_return_val_if_fail (udi != NULL, NM_DEVICE_TYPE_UNKNOWN); - - priv = NM_SYSTEM_CONFIG_HAL_MANAGER_GET_PRIVATE (manager); - return GPOINTER_TO_UINT (g_hash_table_lookup (priv->devices, udi)); -} - -DBusGProxy * -nm_system_config_hal_manager_get_hal_proxy (NMSystemConfigHalManager *manager) -{ - g_return_val_if_fail (NM_IS_SYSTEM_CONFIG_HAL_MANAGER (manager), NULL); - - return NM_SYSTEM_CONFIG_HAL_MANAGER_GET_PRIVATE (manager)->proxy; -} - diff --git a/system-settings/src/nm-system-config-hal-manager.h b/system-settings/src/nm-system-config-hal-manager.h deleted file mode 100644 index 0ffdfdd9d4..0000000000 --- a/system-settings/src/nm-system-config-hal-manager.h +++ /dev/null @@ -1,58 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager system settings service - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2008 Red Hat, Inc. - * Copyright (C) 2008 Novell, Inc. - */ - -#ifndef NM_SYSTEM_CONFIG_HAL_MANAGER_H -#define NM_SYSTEM_CONFIG_HAL_MANAGER_H - -#include -#include -#include -#include "NetworkManager.h" - -#define NM_TYPE_SYSTEM_CONFIG_HAL_MANAGER (nm_system_config_hal_manager_get_type ()) -#define NM_SYSTEM_CONFIG_HAL_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SYSTEM_CONFIG_HAL_MANAGER, NMSystemConfigHalManager)) -#define NM_SYSTEM_CONFIG_HAL_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SYSTEM_CONFIG_HAL_MANAGER, NMSystemConfigHalManagerClass)) -#define NM_IS_SYSTEM_CONFIG_HAL_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SYSTEM_CONFIG_HAL_MANAGER)) -#define NM_IS_SYSTEM_CONFIG_HAL_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_SYSTEM_CONFIG_HAL_MANAGER)) -#define NM_SYSTEM_CONFIG_HAL_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SYSTEM_CONFIG_HAL_MANAGER, NMSystemConfigHalManagerClass)) - -typedef struct { - GObject parent; -} NMSystemConfigHalManager; - -typedef struct { - GObjectClass parent; - - /* Signals */ - void (*device_added) (NMSystemConfigHalManager *manager, const char *udi, NMDeviceType type); - void (*device_removed) (NMSystemConfigHalManager *manager, const char *udi, NMDeviceType type); -} NMSystemConfigHalManagerClass; - -GType nm_system_config_hal_manager_get_type (void); - -/* Returned list is allocated and must be freed by caller */ -GSList *nm_system_config_hal_manager_get_devices_of_type (NMSystemConfigHalManager *manager, NMDeviceType devtype); - -NMDeviceType nm_system_config_hal_manager_get_type_for_udi (NMSystemConfigHalManager *manager, const char *udi); - -DBusGProxy *nm_system_config_hal_manager_get_hal_proxy (NMSystemConfigHalManager *manager); - -#endif /* NM_SYSTEM_CONFIG_HAL_MANAGER_H */ diff --git a/system-settings/src/nm-system-config-interface.c b/system-settings/src/nm-system-config-interface.c deleted file mode 100644 index 54a9cee467..0000000000 --- a/system-settings/src/nm-system-config-interface.c +++ /dev/null @@ -1,163 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager system settings service - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2007 - 2008 Red Hat, Inc. - * Copyright (C) 2008 Novell, Inc. - */ - -#include "nm-system-config-interface.h" - -static void -interface_init (gpointer g_iface) -{ - GType iface_type = G_TYPE_FROM_INTERFACE (g_iface); - static gboolean initialized = FALSE; - - if (initialized) - return; - - /* Properties */ - g_object_interface_install_property - (g_iface, - g_param_spec_string (NM_SYSTEM_CONFIG_INTERFACE_NAME, - "Name", - "Plugin name", - NULL, - G_PARAM_READABLE)); - - g_object_interface_install_property - (g_iface, - g_param_spec_string (NM_SYSTEM_CONFIG_INTERFACE_INFO, - "Info", - "Plugin information", - NULL, - G_PARAM_READABLE)); - - g_object_interface_install_property - (g_iface, - g_param_spec_uint (NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES, - "Capabilities", - "Plugin capabilties", - NM_SYSTEM_CONFIG_INTERFACE_CAP_NONE, - NM_SYSTEM_CONFIG_INTERFACE_CAP_LAST - 1, - NM_SYSTEM_CONFIG_INTERFACE_CAP_NONE, - G_PARAM_READABLE)); - - g_object_interface_install_property - (g_iface, - g_param_spec_string (NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME, - "Hostname", - "Configured hostname", - NULL, - G_PARAM_READWRITE)); - - /* Signals */ - g_signal_new ("connection-added", - iface_type, - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMSystemConfigInterface, connection_added), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, - NM_TYPE_EXPORTED_CONNECTION); - - g_signal_new ("unmanaged-devices-changed", - iface_type, - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMSystemConfigInterface, unmanaged_devices_changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - initialized = TRUE; -} - - -GType -nm_system_config_interface_get_type (void) -{ - static GType system_config_interface_type = 0; - - if (!system_config_interface_type) { - const GTypeInfo system_config_interface_info = { - sizeof (NMSystemConfigInterface), /* class_size */ - interface_init, /* base_init */ - NULL, /* base_finalize */ - NULL, - NULL, /* class_finalize */ - NULL, /* class_data */ - 0, - 0, /* n_preallocs */ - NULL - }; - - system_config_interface_type = g_type_register_static (G_TYPE_INTERFACE, - "NMSystemConfigInterface", - &system_config_interface_info, - 0); - - g_type_interface_add_prerequisite (system_config_interface_type, G_TYPE_OBJECT); - } - - return system_config_interface_type; -} - -void -nm_system_config_interface_init (NMSystemConfigInterface *config, - NMSystemConfigHalManager *hal_manager) -{ - g_return_if_fail (config != NULL); - - if (NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->init) - NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->init (config, hal_manager); -} - -GSList * -nm_system_config_interface_get_connections (NMSystemConfigInterface *config) -{ - g_return_val_if_fail (config != NULL, NULL); - - if (NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->get_connections) - return NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->get_connections (config); - return NULL; -} - -GSList * -nm_system_config_interface_get_unmanaged_devices (NMSystemConfigInterface *config) -{ - g_return_val_if_fail (config != NULL, NULL); - - if (NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->get_unmanaged_devices) - return NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->get_unmanaged_devices (config); - return NULL; -} - -gboolean -nm_system_config_interface_add_connection (NMSystemConfigInterface *config, - NMConnection *connection, - GError **error) -{ - gboolean success = FALSE; - - g_return_val_if_fail (config != NULL, FALSE); - g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); - - if (NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->add_connection) - success = NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->add_connection (config, connection, error); - - return success; -} diff --git a/system-settings/src/nm-system-config-interface.h b/system-settings/src/nm-system-config-interface.h deleted file mode 100644 index 7715ce1f77..0000000000 --- a/system-settings/src/nm-system-config-interface.h +++ /dev/null @@ -1,133 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager system settings service - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2007 - 2008 Red Hat, Inc. - * Copyright (C) 2008 Novell, Inc. - */ - -#ifndef NM_SYSTEM_CONFIG_INTERFACE_H -#define NM_SYSTEM_CONFIG_INTERFACE_H - -#include -#include -#include -#include - -#include "nm-system-config-hal-manager.h" - -G_BEGIN_DECLS - -#define PLUGIN_PRINT(pname, fmt, args...) \ - { g_message (" " pname ": " fmt, ##args); } - -#define PLUGIN_WARN(pname, fmt, args...) \ - { g_warning (" " pname ": " fmt, ##args); } - - -/* Plugin's factory function that returns a GObject that implements - * NMSystemConfigInterface. - */ -GObject * nm_system_config_factory (void); - -/* NOTE: - * When passing NMConnection objects to NetworkManager, any properties - * of that NMConnection's NMSetting objects that are secrets must be set as - * GObject data items on the NMSetting object, _not_ inside the NMSetting - * object itself. This is to ensure that the secrets are only given to - * NetworkManager itself and not exposed to clients like nm-applet that need - * connection details, but not secrets. - */ - -#define NM_TYPE_SYSTEM_CONFIG_INTERFACE (nm_system_config_interface_get_type ()) -#define NM_SYSTEM_CONFIG_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SYSTEM_CONFIG_INTERFACE, NMSystemConfigInterface)) -#define NM_IS_SYSTEM_CONFIG_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SYSTEM_CONFIG_INTERFACE)) -#define NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), NM_TYPE_SYSTEM_CONFIG_INTERFACE, NMSystemConfigInterface)) - - -#define NM_SYSTEM_CONFIG_INTERFACE_NAME "name" -#define NM_SYSTEM_CONFIG_INTERFACE_INFO "info" -#define NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES "capabilities" -#define NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME "hostname" - -typedef enum { - NM_SYSTEM_CONFIG_INTERFACE_CAP_NONE = 0x00000000, - NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS = 0x00000001, - NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME = 0x00000002, - - NM_SYSTEM_CONFIG_INTERFACE_CAP_LAST = NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME -} NMSystemConfigInterfaceCapabilities; - -typedef enum { - NM_SYSTEM_CONFIG_INTERFACE_PROP_FIRST = 0x1000, - - NM_SYSTEM_CONFIG_INTERFACE_PROP_NAME = NM_SYSTEM_CONFIG_INTERFACE_PROP_FIRST, - NM_SYSTEM_CONFIG_INTERFACE_PROP_INFO, - NM_SYSTEM_CONFIG_INTERFACE_PROP_CAPABILITIES, - NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME, -} NMSystemConfigInterfaceProp; - - -typedef struct _NMSystemConfigInterface NMSystemConfigInterface; - -struct _NMSystemConfigInterface { - GTypeInterface g_iface; - - /* Called when the plugin is loaded to initialize it */ - void (*init) (NMSystemConfigInterface *config, NMSystemConfigHalManager *hal_manager); - - /* Returns the plugins currently known list of connections. The returned - * list is freed by the system settings service. - */ - GSList * (*get_connections) (NMSystemConfigInterface *config); - - /* - * Return a list of HAL UDIs of devices which NetworkManager should not - * manage. Returned list will be freed by the system settings service, and - * each element must be allocated using g_malloc() or its variants. - */ - GSList * (*get_unmanaged_devices) (NMSystemConfigInterface *config); - - /* - * Add a new connection. - */ - gboolean (*add_connection) (NMSystemConfigInterface *config, NMConnection *connection, GError **error); - - /* Signals */ - - /* Emitted when a new connection has been found by the plugin */ - void (*connection_added) (NMSystemConfigInterface *config, NMExportedConnection *connection); - - /* Emitted when the list of unmanaged devices changes */ - void (*unmanaged_devices_changed) (NMSystemConfigInterface *config); -}; - -GType nm_system_config_interface_get_type (void); - -void nm_system_config_interface_init (NMSystemConfigInterface *config, - NMSystemConfigHalManager *hal_manager); - -GSList *nm_system_config_interface_get_connections (NMSystemConfigInterface *config); - -GSList *nm_system_config_interface_get_unmanaged_devices (NMSystemConfigInterface *config); - -gboolean nm_system_config_interface_add_connection (NMSystemConfigInterface *config, - NMConnection *connection, - GError **error); - -G_END_DECLS - -#endif /* NM_SYSTEM_CONFIG_INTERFACE_H */ diff --git a/system-settings/src/nm-system-settings.conf b/system-settings/src/nm-system-settings.conf deleted file mode 100644 index 2f9a505434..0000000000 --- a/system-settings/src/nm-system-settings.conf +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - 512 - - diff --git a/system-settings/src/org.freedesktop.NetworkManagerSystemSettings.service.in b/system-settings/src/org.freedesktop.NetworkManagerSystemSettings.service.in deleted file mode 100644 index c5ed93fdcd..0000000000 --- a/system-settings/src/org.freedesktop.NetworkManagerSystemSettings.service.in +++ /dev/null @@ -1,5 +0,0 @@ -[D-BUS Service] -Name=org.freedesktop.NetworkManagerSystemSettings -Exec=@sbindir@/nm-system-settings --config /etc/NetworkManager/nm-system-settings.conf -User=root - -- cgit v1.2.3