diff options
author | Dan Winship <danw@redhat.com> | 2015-04-15 14:53:30 -0400 |
---|---|---|
committer | Dan Winship <danw@redhat.com> | 2015-08-10 09:41:26 -0400 |
commit | 4b823a86c9d4c0c3ce857042cc37dfb480e69673 (patch) | |
tree | b255bc80a3e31fecb35e7155a8ead697f1e68691 | |
parent | 073991f5a8271a1e7367ec330fc7c8cf54522ffb (diff) | |
download | NetworkManager-4b823a86c9d4c0c3ce857042cc37dfb480e69673.tar.gz |
core: port NMBusManager to gdbus
Also remove some now-unused NMBusManager API
-rw-r--r-- | include/nm-glib.h | 19 | ||||
-rw-r--r-- | src/nm-bus-manager.c | 587 | ||||
-rw-r--r-- | src/nm-bus-manager.h | 46 |
3 files changed, 297 insertions, 355 deletions
diff --git a/include/nm-glib.h b/include/nm-glib.h index b46feb7666..9b57c61331 100644 --- a/include/nm-glib.h +++ b/include/nm-glib.h @@ -258,4 +258,23 @@ _g_key_file_save_to_file (GKeyFile *key_file, #endif +#if GLIB_CHECK_VERSION (2, 36, 0) +#define g_credentials_get_unix_pid(creds, error) \ + G_GNUC_EXTENSION ({ \ + G_GNUC_BEGIN_IGNORE_DEPRECATIONS \ + (g_credentials_get_unix_pid) ((creds), (error)); \ + G_GNUC_END_IGNORE_DEPRECATIONS \ + }) +#else +#define g_credentials_get_unix_pid(creds, error) \ + G_GNUC_EXTENSION ({ \ + struct ucred *native_creds; \ + \ + native_creds = g_credentials_get_native ((creds), G_CREDENTIALS_TYPE_LINUX_UCRED); \ + g_assert (native_creds); \ + native_creds->pid; \ + }) +#endif + + #endif /* __NM_GLIB_H__ */ diff --git a/src/nm-bus-manager.c b/src/nm-bus-manager.c index 4ebc1666c5..584db5e8a6 100644 --- a/src/nm-bus-manager.c +++ b/src/nm-bus-manager.c @@ -29,10 +29,9 @@ #include "nm-default.h" #include "nm-dbus-interface.h" #include "nm-bus-manager.h" +#include "nm-core-internal.h" +#include "nm-dbus-compat.h" -#include <dbus/dbus.h> -#include <dbus/dbus-glib.h> -#include <dbus/dbus-glib-lowlevel.h> #include <string.h> #include "NetworkManagerUtils.h" @@ -41,7 +40,6 @@ enum { DBUS_CONNECTION_CHANGED = 0, - NAME_OWNER_CHANGED, PRIVATE_CONNECTION_NEW, PRIVATE_CONNECTION_DISCONNECTED, NUMBER_OF_SIGNALS @@ -58,22 +56,21 @@ G_DEFINE_TYPE(NMBusManager, nm_bus_manager, G_TYPE_OBJECT) typedef struct _PrivateServer PrivateServer; typedef struct { - DBusConnection *connection; - DBusGConnection *g_connection; + GDBusConnection *connection; GHashTable *exported; gboolean started; GSList *private_servers; PrivateServer *priv_server; - DBusGProxy *proxy; - guint proxy_destroy_id; + GDBusProxy *proxy; + guint bus_closed_id; guint reconnect_id; } NMBusManagerPrivate; static gboolean nm_bus_manager_init_bus (NMBusManager *self); -static void nm_bus_manager_cleanup (NMBusManager *self, gboolean dispose); +static void nm_bus_manager_cleanup (NMBusManager *self); static void start_reconnection_timeout (NMBusManager *self); static void object_destroyed (NMBusManager *self, gpointer object); @@ -111,82 +108,73 @@ struct _PrivateServer { const char *tag; GQuark detail; char *address; - DBusServer *server; + GDBusServer *server; GHashTable *connections; NMBusManager *manager; }; -static DBusHandlerResult -private_server_message_filter (DBusConnection *conn, - DBusMessage *message, - void *data) +static void +private_server_closed (GDBusConnection *conn, + gboolean remote_peer_vanished, + GError *error, + gpointer user_data) { - PrivateServer *s = data; - int fd; + PrivateServer *s = user_data; /* Clean up after the connection */ - if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL, "Disconnected")) { - nm_log_dbg (LOGD_CORE, "(%s) closed connection %p on private socket (fd %d).", - s->tag, conn, dbus_connection_get_unix_fd (conn, &fd) ? fd : -1); - - /* Emit this for the manager */ - g_signal_emit (s->manager, - signals[PRIVATE_CONNECTION_DISCONNECTED], - s->detail, - dbus_connection_get_g_connection (conn)); - - g_hash_table_remove (s->connections, conn); + nm_log_dbg (LOGD_CORE, "(%s) closed connection %p on private socket.", + s->tag, conn); - /* Let dbus-glib process the message too */ - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - } - - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -} + /* Emit this for the manager */ + g_signal_emit (s->manager, + signals[PRIVATE_CONNECTION_DISCONNECTED], + s->detail, + conn); -static dbus_bool_t -allow_only_root (DBusConnection *connection, unsigned long uid, void *data) -{ - return uid == 0; + g_hash_table_remove (s->connections, conn); } -static void -private_server_new_connection (DBusServer *server, - DBusConnection *conn, +static gboolean +private_server_new_connection (GDBusServer *server, + GDBusConnection *conn, gpointer user_data) { PrivateServer *s = user_data; static guint32 counter = 0; char *sender; - int fd; - if (!dbus_connection_add_filter (conn, private_server_message_filter, s, NULL)) { - dbus_connection_close (conn); - return; - } - dbus_connection_set_unix_user_function (conn, allow_only_root, NULL, NULL); - dbus_connection_setup_with_g_main (conn, NULL); + g_signal_connect (conn, "closed", G_CALLBACK (private_server_closed), s); /* Fake a sender since private connections don't have one */ sender = g_strdup_printf ("x:y:%d", counter++); - g_hash_table_insert (s->connections, dbus_connection_ref (conn), sender); + g_hash_table_insert (s->connections, g_object_ref (conn), sender); - nm_log_dbg (LOGD_CORE, "(%s) accepted connection %p on private socket (fd %d).", - s->tag, conn, dbus_connection_get_unix_fd (conn, &fd) ? fd : -1); + nm_log_dbg (LOGD_CORE, "(%s) accepted connection %p on private socket.", + s->tag, conn); /* Emit this for the manager */ g_signal_emit (s->manager, signals[PRIVATE_CONNECTION_NEW], s->detail, - dbus_connection_get_g_connection (conn)); + conn); + return TRUE; } static void -private_server_dbus_connection_destroy (DBusConnection *conn) +private_server_dbus_connection_destroy (GDBusConnection *conn) { - if (dbus_connection_get_is_connected (conn)) - dbus_connection_close (conn); - dbus_connection_unref (conn); + if (!g_dbus_connection_is_closed (conn)) + g_dbus_connection_close (conn, NULL, NULL, NULL); + g_object_unref (conn); +} + +static gboolean +private_server_authorize (GDBusAuthObserver *observer, + GIOStream *stream, + GCredentials *credentials, + gpointer user_data) +{ + return g_credentials_get_unix_user (credentials, NULL) == 0; } static PrivateServer * @@ -195,21 +183,32 @@ private_server_new (const char *path, NMBusManager *manager) { PrivateServer *s; - DBusServer *server; - DBusError error; - char *address; + GDBusAuthObserver *auth_observer; + GDBusServer *server; + GError *error = NULL; + char *address, *guid; unlink (path); address = g_strdup_printf ("unix:path=%s", path); nm_log_dbg (LOGD_CORE, "(%s) creating private socket %s.", tag, address); - dbus_error_init (&error); - server = dbus_server_listen (address, &error); + guid = g_dbus_generate_guid (); + auth_observer = g_dbus_auth_observer_new (); + g_signal_connect (auth_observer, "authorize-authenticated-peer", + G_CALLBACK (private_server_authorize), NULL); + server = g_dbus_server_new_sync (address, + G_DBUS_SERVER_FLAGS_NONE, + guid, + auth_observer, + NULL, &error); + g_free (guid); + g_object_unref (auth_observer); + if (!server) { nm_log_warn (LOGD_CORE, "(%s) failed to set up private socket %s: %s", - tag, address, error.message); - dbus_error_free (&error); + tag, address, error->message); + g_error_free (error); g_free (address); return NULL; } @@ -217,8 +216,8 @@ private_server_new (const char *path, s = g_malloc0 (sizeof (*s)); s->address = address; s->server = server; - dbus_server_setup_with_g_main (s->server, NULL); - dbus_server_set_new_connection_function (s->server, private_server_new_connection, s, NULL); + g_signal_connect (server, "new-connection", + G_CALLBACK (private_server_new_connection), s); s->connections = g_hash_table_new_full (g_direct_hash, g_direct_equal, (GDestroyNotify) private_server_dbus_connection_destroy, @@ -227,6 +226,8 @@ private_server_new (const char *path, s->detail = g_quark_from_string (tag); s->tag = g_quark_to_string (s->detail); + g_dbus_server_start (server); + return s; } @@ -238,8 +239,10 @@ private_server_free (gpointer ptr) unlink (s->address); g_free (s->address); g_hash_table_destroy (s->connections); - dbus_server_disconnect (s->server); - dbus_server_unref (s->server); + + g_dbus_server_stop (s->server); + g_object_unref (s->server); + memset (s, 0, sizeof (*s)); g_free (s); } @@ -253,10 +256,6 @@ nm_bus_manager_private_server_register (NMBusManager *self, PrivateServer *s; GSList *iter; -#if !HAVE_DBUS_GLIB_100 - g_assert_not_reached (); -#endif - g_return_if_fail (self != NULL); g_return_if_fail (path != NULL); g_return_if_fail (tag != NULL); @@ -274,12 +273,12 @@ nm_bus_manager_private_server_register (NMBusManager *self, } static const char * -private_server_get_connection_owner (PrivateServer *s, DBusGConnection *connection) +private_server_get_connection_owner (PrivateServer *s, GDBusConnection *connection) { g_return_val_if_fail (s != NULL, NULL); g_return_val_if_fail (connection != NULL, NULL); - return g_hash_table_lookup (s->connections, dbus_g_connection_get_connection (connection)); + return g_hash_table_lookup (s->connections, connection); } /**************************************************************/ @@ -291,52 +290,74 @@ _bus_get_unix_pid (NMBusManager *self, GError **error) { guint32 unix_pid = G_MAXUINT32; - - if (!dbus_g_proxy_call_with_timeout (NM_BUS_MANAGER_GET_PRIVATE (self)->proxy, - "GetConnectionUnixProcessID", 2000, error, - G_TYPE_STRING, sender, - G_TYPE_INVALID, - G_TYPE_UINT, &unix_pid, - G_TYPE_INVALID)) { + GVariant *ret; + + ret = _nm_dbus_proxy_call_sync (NM_BUS_MANAGER_GET_PRIVATE (self)->proxy, + "GetConnectionUnixProcessID", + g_variant_new ("(s)", sender), + G_VARIANT_TYPE ("(u)"), + G_DBUS_CALL_FLAGS_NONE, 2000, + NULL, error); + if (!ret) return FALSE; - } + + g_variant_get (ret, "(u)", &unix_pid); *out_pid = (gulong) unix_pid; return TRUE; } +static gboolean +_bus_get_unix_user (NMBusManager *self, + const char *sender, + gulong *out_user, + GError **error) +{ + guint32 unix_uid = G_MAXUINT32; + GVariant *ret; + + ret = _nm_dbus_proxy_call_sync (NM_BUS_MANAGER_GET_PRIVATE (self)->proxy, + "GetConnectionUnixUser", + g_variant_new ("(s)", sender), + G_VARIANT_TYPE ("(u)"), + G_DBUS_CALL_FLAGS_NONE, 2000, + NULL, error); + if (!ret) + return FALSE; + + g_variant_get (ret, "(u)", &unix_uid); + + *out_user = (gulong) unix_uid; + return TRUE; +} + /** - * _get_caller_info_from_context(): + * _get_caller_info(): * - * Given a dbus-glib method invocation, or a DBusConnection + DBusMessage, + * Given a GDBus method invocation, or a GDBusConnection + GDBusMessage, * return the sender and the UID of the sender. */ static gboolean _get_caller_info (NMBusManager *self, - DBusGMethodInvocation *context, - DBusConnection *connection, - DBusMessage *message, + GDBusMethodInvocation *context, + GDBusConnection *connection, + GDBusMessage *message, char **out_sender, gulong *out_uid, gulong *out_pid) { NMBusManagerPrivate *priv = NM_BUS_MANAGER_GET_PRIVATE (self); - DBusGConnection *gconn; - char *sender; - const char *priv_sender; - DBusError error; + const char *sender; GSList *iter; if (context) { - gconn = dbus_g_method_invocation_get_g_connection (context); - g_assert (gconn); - connection = dbus_g_connection_get_connection (gconn); + connection = g_dbus_method_invocation_get_connection (context); /* only bus connections will have a sender */ - sender = dbus_g_method_get_sender (context); + sender = g_dbus_method_invocation_get_sender (context); } else { g_assert (message); - sender = g_strdup (dbus_message_get_sender (message)); + sender = g_dbus_message_get_sender (message); } g_assert (connection); @@ -345,14 +366,25 @@ _get_caller_info (NMBusManager *self, for (iter = priv->private_servers; iter; iter = g_slist_next (iter)) { PrivateServer *s = iter->data; - priv_sender = g_hash_table_lookup (s->connections, connection); - if (priv_sender) { + sender = g_hash_table_lookup (s->connections, connection); + if (sender) { if (out_uid) *out_uid = 0; if (out_sender) - *out_sender = g_strdup (priv_sender); + *out_sender = g_strdup (sender); if (out_pid) { - if (!dbus_connection_get_unix_process_id (connection, out_pid)) + GCredentials *creds; + + creds = g_dbus_connection_get_peer_credentials (connection); + if (creds) { + pid_t pid; + + pid = g_credentials_get_unix_pid (creds, NULL); + if (pid == -1) + *out_pid = G_MAXULONG; + else + *out_pid = pid; + } else *out_pid = G_MAXULONG; } return TRUE; @@ -364,12 +396,8 @@ _get_caller_info (NMBusManager *self, /* Bus connections always have a sender */ g_assert (sender); if (out_uid) { - dbus_error_init (&error); - *out_uid = dbus_bus_get_unix_user (connection, sender, &error); - if (dbus_error_is_set (&error)) { - dbus_error_free (&error); + if (!_bus_get_unix_user (self, sender, out_uid, NULL)) { *out_uid = G_MAXULONG; - g_free (sender); return FALSE; } } @@ -377,7 +405,6 @@ _get_caller_info (NMBusManager *self, if (out_pid) { if (!_bus_get_unix_pid (self, sender, out_pid, NULL)) { *out_pid = G_MAXULONG; - g_free (sender); return FALSE; } } @@ -385,13 +412,12 @@ _get_caller_info (NMBusManager *self, if (out_sender) *out_sender = g_strdup (sender); - g_free (sender); return TRUE; } gboolean nm_bus_manager_get_caller_info (NMBusManager *self, - DBusGMethodInvocation *context, + GDBusMethodInvocation *context, char **out_sender, gulong *out_uid, gulong *out_pid) @@ -401,8 +427,8 @@ nm_bus_manager_get_caller_info (NMBusManager *self, gboolean nm_bus_manager_get_caller_info_from_message (NMBusManager *self, - DBusConnection *connection, - DBusMessage *message, + GDBusConnection *connection, + GDBusMessage *message, char **out_sender, gulong *out_uid, gulong *out_pid) @@ -417,7 +443,7 @@ nm_bus_manager_get_unix_user (NMBusManager *self, { NMBusManagerPrivate *priv = NM_BUS_MANAGER_GET_PRIVATE (self); GSList *iter; - DBusError error; + GError *error = NULL; g_return_val_if_fail (sender != NULL, FALSE); g_return_val_if_fail (out_uid != NULL, FALSE); @@ -438,11 +464,10 @@ nm_bus_manager_get_unix_user (NMBusManager *self, } /* Otherwise, a bus connection */ - dbus_error_init (&error); - *out_uid = dbus_bus_get_unix_user (priv->connection, sender, &error); - if (dbus_error_is_set (&error)) { + if (!_bus_get_unix_user (self, sender, out_uid, &error)) { nm_log_warn (LOGD_CORE, "Failed to get unix user for dbus sender '%s': %s", - sender, error.message); + sender, error->message); + g_error_free (error); return FALSE; } @@ -451,39 +476,31 @@ nm_bus_manager_get_unix_user (NMBusManager *self, /**************************************************************/ -#if HAVE_DBUS_GLIB_100 static void -private_connection_new (NMBusManager *self, DBusGConnection *connection) +private_connection_new (NMBusManager *self, GDBusConnection *connection) { NMBusManagerPrivate *priv = NM_BUS_MANAGER_GET_PRIVATE (self); GHashTableIter iter; - GObject *object; + GDBusInterfaceSkeleton *interface; const char *path; + GError *error = NULL; /* Register all exported objects on this private connection */ g_hash_table_iter_init (&iter, priv->exported); - while (g_hash_table_iter_next (&iter, (gpointer) &object, (gpointer) &path)) { - dbus_g_connection_register_g_object (connection, path, object); - nm_log_trace (LOGD_CORE, "(%s) registered %p (%s) at '%s' on private socket.", - PRIV_SOCK_TAG, object, G_OBJECT_TYPE_NAME (object), path); + while (g_hash_table_iter_next (&iter, (gpointer) &interface, (gpointer) &path)) { + if (g_dbus_interface_skeleton_export (interface, connection, path, &error)) { + nm_log_trace (LOGD_CORE, "(%s) registered %p (%s) at '%s' on private socket.", + PRIV_SOCK_TAG, interface, G_OBJECT_TYPE_NAME (interface), path); + } else { + nm_log_warn (LOGD_CORE, "(%s) could not register %p (%s) at '%s' on private socket: %s.", + PRIV_SOCK_TAG, interface, G_OBJECT_TYPE_NAME (interface), path, + error->message); + g_clear_error (&error); + } } } static void -private_connection_disconnected (NMBusManager *self, DBusGConnection *connection) -{ - NMBusManagerPrivate *priv = NM_BUS_MANAGER_GET_PRIVATE (self); - const char *owner; - - owner = private_server_get_connection_owner (priv->priv_server, connection); - g_assert (owner); - - /* Fake a NameOwnerChanged to let listerners know this owner has quit */ - g_signal_emit (G_OBJECT (self), signals[NAME_OWNER_CHANGED], - 0, owner, owner, NULL); -} - -static void private_server_setup (NMBusManager *self) { NMBusManagerPrivate *priv = NM_BUS_MANAGER_GET_PRIVATE (self); @@ -500,18 +517,12 @@ private_server_setup (NMBusManager *self) priv->priv_server = private_server_new (PRIV_SOCK_PATH, PRIV_SOCK_TAG, self); if (priv->priv_server) { priv->private_servers = g_slist_append (priv->private_servers, priv->priv_server); - g_signal_connect (self, NM_BUS_MANAGER_PRIVATE_CONNECTION_NEW "::" PRIV_SOCK_TAG, (GCallback) private_connection_new, NULL); - g_signal_connect (self, - NM_BUS_MANAGER_PRIVATE_CONNECTION_DISCONNECTED "::" PRIV_SOCK_TAG, - (GCallback) private_connection_disconnected, - NULL); } } -#endif /* HAVE_DBUS_GLIB_100 */ static void nm_bus_manager_init (NMBusManager *self) @@ -520,9 +531,7 @@ nm_bus_manager_init (NMBusManager *self) priv->exported = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free); -#if HAVE_DBUS_GLIB_100 private_server_setup (self); -#endif } static void @@ -546,7 +555,7 @@ nm_bus_manager_dispose (GObject *object) priv->private_servers = NULL; priv->priv_server = NULL; - nm_bus_manager_cleanup (self, TRUE); + nm_bus_manager_cleanup (self); if (priv->reconnect_id) { g_source_remove (priv->reconnect_id); @@ -573,14 +582,6 @@ nm_bus_manager_class_init (NMBusManagerClass *klass) NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_POINTER); - signals[NAME_OWNER_CHANGED] = - g_signal_new (NM_BUS_MANAGER_NAME_OWNER_CHANGED, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (NMBusManagerClass, name_owner_changed), - NULL, NULL, NULL, - G_TYPE_NONE, 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); - signals[PRIVATE_CONNECTION_NEW] = g_signal_new (NM_BUS_MANAGER_PRIVATE_CONNECTION_NEW, G_OBJECT_CLASS_TYPE (object_class), @@ -601,23 +602,16 @@ nm_bus_manager_class_init (NMBusManagerClass *klass) /* Only cleanup a specific dbus connection, not all our private data */ static void -nm_bus_manager_cleanup (NMBusManager *self, gboolean dispose) +nm_bus_manager_cleanup (NMBusManager *self) { NMBusManagerPrivate *priv = NM_BUS_MANAGER_GET_PRIVATE (self); - if (priv->proxy) { - if (dispose) { - g_signal_handler_disconnect (priv->proxy, priv->proxy_destroy_id); - priv->proxy_destroy_id = 0; - } - g_object_unref (priv->proxy); - priv->proxy = NULL; - } + g_clear_object (&priv->proxy); - if (priv->g_connection) { - dbus_g_connection_unref (priv->g_connection); - priv->g_connection = NULL; - priv->connection = NULL; + if (priv->connection) { + g_signal_handler_disconnect (priv->connection, priv->bus_closed_id); + priv->bus_closed_id = 0; + g_clear_object (&priv->connection); } priv->started = FALSE; @@ -642,7 +636,7 @@ nm_bus_manager_reconnect (gpointer user_data) } /* Try again */ - nm_bus_manager_cleanup (self, FALSE); + nm_bus_manager_cleanup (self); return TRUE; } @@ -658,81 +652,18 @@ start_reconnection_timeout (NMBusManager *self) priv->reconnect_id = g_timeout_add_seconds (3, nm_bus_manager_reconnect, self); } -char * -nm_bus_manager_get_name_owner (NMBusManager *self, - const char *name, - GError **error) -{ - char *owner = NULL; - - g_return_val_if_fail (NM_IS_BUS_MANAGER (self), NULL); - g_return_val_if_fail (name != NULL, NULL); - if (error) - g_return_val_if_fail (*error == NULL, NULL); - - if (!NM_BUS_MANAGER_GET_PRIVATE (self)->proxy) - return NULL; - - if (!dbus_g_proxy_call_with_timeout (NM_BUS_MANAGER_GET_PRIVATE (self)->proxy, - "GetNameOwner", 2000, error, - G_TYPE_STRING, name, - G_TYPE_INVALID, - G_TYPE_STRING, &owner, - G_TYPE_INVALID)) { - return NULL; - } - - return owner; -} - -gboolean -nm_bus_manager_name_has_owner (NMBusManager *self, - const char *name) -{ - gboolean has_owner = FALSE; - GError *err = NULL; - - g_return_val_if_fail (NM_IS_BUS_MANAGER (self), FALSE); - g_return_val_if_fail (name != NULL, FALSE); - - if (!NM_BUS_MANAGER_GET_PRIVATE (self)->proxy) - return FALSE; - - if (!dbus_g_proxy_call (NM_BUS_MANAGER_GET_PRIVATE (self)->proxy, - "NameHasOwner", &err, - G_TYPE_STRING, name, - G_TYPE_INVALID, - G_TYPE_BOOLEAN, &has_owner, - G_TYPE_INVALID)) { - nm_log_warn (LOGD_CORE, "NameHasOwner request failed: %s", - (err && err->message) ? err->message : "(unknown)"); - g_clear_error (&err); - } - - return has_owner; -} - -static void -proxy_name_owner_changed (DBusGProxy *proxy, - const char *name, - const char *old_owner, - const char *new_owner, - gpointer user_data) -{ - g_signal_emit (G_OBJECT (user_data), signals[NAME_OWNER_CHANGED], - 0, name, old_owner, new_owner); -} - static void -destroy_cb (DBusGProxy *proxy, gpointer user_data) +closed_cb (GDBusConnection *connection, + gboolean remote_peer_vanished, + GError *error, + gpointer user_data) { NMBusManager *self = NM_BUS_MANAGER (user_data); /* Clean up existing connection */ nm_log_warn (LOGD_CORE, "disconnected by the system bus."); - NM_BUS_MANAGER_GET_PRIVATE (self)->proxy = NULL; - nm_bus_manager_cleanup (self, FALSE); + nm_bus_manager_cleanup (self); g_signal_emit (G_OBJECT (self), signals[DBUS_CONNECTION_CHANGED], 0, NULL); @@ -743,43 +674,47 @@ static gboolean nm_bus_manager_init_bus (NMBusManager *self) { NMBusManagerPrivate *priv = NM_BUS_MANAGER_GET_PRIVATE (self); + GError *error = NULL; if (priv->connection) { nm_log_warn (LOGD_CORE, "DBus Manager already has a valid connection."); return FALSE; } - dbus_connection_set_change_sigpipe (TRUE); - - priv->g_connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, NULL); - if (!priv->g_connection) { + priv->connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); + if (!priv->connection) { /* Log with 'info' severity; there won't be a bus daemon in minimal * environments (eg, initrd) where we only want to use the private * socket. */ - nm_log_info (LOGD_CORE, "Could not connect to the system bus; only the " - "private D-Bus socket will be available."); + nm_log_info (LOGD_CORE, "Could not connect to the system bus (%s); only the " + "private D-Bus socket will be available.", + error->message); + g_error_free (error); return FALSE; } - priv->connection = dbus_g_connection_get_connection (priv->g_connection); - dbus_connection_set_exit_on_disconnect (priv->connection, FALSE); - - priv->proxy = dbus_g_proxy_new_for_name (priv->g_connection, - DBUS_SERVICE_DBUS, - DBUS_PATH_DBUS, - DBUS_INTERFACE_DBUS); - - priv->proxy_destroy_id = g_signal_connect (priv->proxy, "destroy", - G_CALLBACK (destroy_cb), self); + g_dbus_connection_set_exit_on_close (priv->connection, FALSE); + priv->bus_closed_id = g_signal_connect (priv->connection, "closed", + G_CALLBACK (closed_cb), self); + + priv->proxy = g_dbus_proxy_new_sync (priv->connection, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | + G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, + NULL, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + NULL, &error); + if (!priv->proxy) { + g_clear_object (&priv->connection); + nm_log_warn (LOGD_CORE, "Could not create org.freedesktop.DBus proxy (%s); only the " + "private D-Bus socket will be available.", + error->message); + g_error_free (error); + return FALSE; + } - dbus_g_proxy_add_signal (priv->proxy, "NameOwnerChanged", - G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, - G_TYPE_INVALID); - dbus_g_proxy_connect_signal (priv->proxy, - "NameOwnerChanged", - G_CALLBACK (proxy_name_owner_changed), - self, NULL); return TRUE; } @@ -791,6 +726,7 @@ gboolean nm_bus_manager_start_service (NMBusManager *self) { NMBusManagerPrivate *priv; + GVariant *ret; int result; GError *err = NULL; @@ -807,19 +743,23 @@ nm_bus_manager_start_service (NMBusManager *self) if (!priv->proxy) return FALSE; - if (!dbus_g_proxy_call (priv->proxy, "RequestName", &err, - G_TYPE_STRING, NM_DBUS_SERVICE, - G_TYPE_UINT, DBUS_NAME_FLAG_DO_NOT_QUEUE, - G_TYPE_INVALID, - G_TYPE_UINT, &result, - G_TYPE_INVALID)) { + ret = _nm_dbus_proxy_call_sync (priv->proxy, + "RequestName", + g_variant_new ("(su)", + NM_DBUS_SERVICE, + DBUS_NAME_FLAG_DO_NOT_QUEUE), + G_VARIANT_TYPE ("(u)"), + G_DBUS_CALL_FLAGS_NONE, -1, + NULL, &err); + if (!ret) { nm_log_err (LOGD_CORE, "Could not acquire the NetworkManager service.\n" - " Error: '%s'", - (err && err->message) ? err->message : "(unknown)"); + " Error: '%s'", err->message); g_error_free (err); return FALSE; } + g_variant_get (ret, "(u)", &result); + if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { nm_log_err (LOGD_CORE, "Could not acquire the NetworkManager service as it is already taken."); return FALSE; @@ -829,20 +769,12 @@ nm_bus_manager_start_service (NMBusManager *self) return priv->started; } -DBusConnection * -nm_bus_manager_get_dbus_connection (NMBusManager *self) -{ - g_return_val_if_fail (NM_IS_BUS_MANAGER (self), NULL); - - return NM_BUS_MANAGER_GET_PRIVATE (self)->connection; -} - -DBusGConnection * +GDBusConnection * nm_bus_manager_get_connection (NMBusManager *self) { g_return_val_if_fail (NM_IS_BUS_MANAGER (self), NULL); - return NM_BUS_MANAGER_GET_PRIVATE (self)->g_connection; + return NM_BUS_MANAGER_GET_PRIVATE (self)->connection; } static void @@ -858,9 +790,9 @@ nm_bus_manager_register_object (NMBusManager *self, { NMBusManagerPrivate *priv = NM_BUS_MANAGER_GET_PRIVATE (self); GHashTableIter iter; - DBusConnection *connection; + GDBusConnection *connection; - g_assert (G_IS_OBJECT (object)); + g_assert (G_IS_DBUS_INTERFACE_SKELETON (object)); if (g_hash_table_lookup (priv->exported, G_OBJECT (object))) g_return_if_reached (); @@ -868,27 +800,43 @@ nm_bus_manager_register_object (NMBusManager *self, g_hash_table_insert (priv->exported, G_OBJECT (object), g_strdup (path)); g_object_weak_ref (G_OBJECT (object), (GWeakNotify) object_destroyed, self); - if (priv->g_connection) - dbus_g_connection_register_g_object (priv->g_connection, path, G_OBJECT (object)); + if (priv->connection) { + g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (object), + priv->connection, path, NULL); + } if (priv->priv_server) { g_hash_table_iter_init (&iter, priv->priv_server->connections); while (g_hash_table_iter_next (&iter, (gpointer) &connection, NULL)) { - dbus_g_connection_register_g_object (dbus_connection_get_g_connection (connection), - path, - G_OBJECT (object)); + g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (object), + connection, path, NULL); } } } +gpointer +nm_bus_manager_get_registered_object (NMBusManager *self, + const char *path) +{ + NMBusManagerPrivate *priv = NM_BUS_MANAGER_GET_PRIVATE (self); + GHashTableIter iter; + GObject *object; + const char *export_path; + + g_hash_table_iter_init (&iter, priv->exported); + while (g_hash_table_iter_next (&iter, (gpointer *) &object, (gpointer *) &export_path)) { + if (!strcmp (path, export_path)) + return object; + } + return NULL; +} + void nm_bus_manager_unregister_object (NMBusManager *self, gpointer object) { NMBusManagerPrivate *priv = NM_BUS_MANAGER_GET_PRIVATE (self); - GHashTableIter iter; - DBusConnection *connection; - g_assert (G_IS_OBJECT (object)); + g_assert (G_IS_DBUS_INTERFACE_SKELETON (object)); if (!g_hash_table_lookup (priv->exported, G_OBJECT (object))) g_return_if_reached (); @@ -896,74 +844,69 @@ nm_bus_manager_unregister_object (NMBusManager *self, gpointer object) g_hash_table_remove (priv->exported, G_OBJECT (object)); g_object_weak_unref (G_OBJECT (object), (GWeakNotify) object_destroyed, self); - if (priv->g_connection) - dbus_g_connection_unregister_g_object (priv->g_connection, G_OBJECT (object)); - - if (priv->priv_server) { - g_hash_table_iter_init (&iter, priv->priv_server->connections); - while (g_hash_table_iter_next (&iter, (gpointer) &connection, NULL)) { - dbus_g_connection_unregister_g_object (dbus_connection_get_g_connection (connection), - G_OBJECT (object)); - } - } + g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (object)); } /** * nm_bus_manager_new_proxy: * @self: the #NMBusManager * @context: the method call context this proxy should be created + * @proxy_type: the type of #GDBusProxy to create * @name: any name on the message bus * @path: name of the object instance to call methods on * @iface: name of the interface to call methods on * - * Creates a new proxy for a name on a given bus. Since the process which - * called the D-Bus method could be coming from a private connection or the - * system bus connection, differnet proxies must be created for each case. This - * function abstracts that. + * Creates a new proxy (of type @proxy_type) for a name on a given bus. Since + * the process which called the D-Bus method could be coming from a private + * connection or the system bus connection, different proxies must be created + * for each case. This function abstracts that. * - * Returns: a #DBusGProxy capable of calling D-Bus methods of the calling process + * Returns: a #GDBusProxy capable of calling D-Bus methods of the calling process */ -DBusGProxy * +GDBusProxy * nm_bus_manager_new_proxy (NMBusManager *self, - DBusGMethodInvocation *context, + GDBusMethodInvocation *context, + GType proxy_type, const char *name, const char *path, const char *iface) { NMBusManagerPrivate *priv = NM_BUS_MANAGER_GET_PRIVATE (self); - DBusGConnection *connection; + GDBusConnection *connection; GSList *iter; const char *owner; + GDBusProxy *proxy; + GError *error = NULL; - connection = dbus_g_method_invocation_get_g_connection (context); + g_return_val_if_fail (g_type_is_a (proxy_type, G_TYPE_DBUS_PROXY), NULL); + + connection = g_dbus_method_invocation_get_connection (context); g_assert (connection); - /* Might be a private connection, for which we fake a sender */ + /* Might be a private connection, for which @name is fake */ for (iter = priv->private_servers; iter; iter = g_slist_next (iter)) { PrivateServer *s = iter->data; owner = private_server_get_connection_owner (s, connection); if (owner) { g_assert_cmpstr (owner, ==, name); - return dbus_g_proxy_new_for_peer (connection, path, iface); + name = NULL; + break; } } - return dbus_g_proxy_new_for_name (connection, name, path, iface); -} - -#if !HAVE_DBUS_GLIB_GMI_GET_CONNECTION -struct _HACKDBusGMethodInvocation { - DBusGConnection *connection; - /* ... */ -}; - -DBusGConnection * -dbus_g_method_invocation_get_g_connection (DBusGMethodInvocation *context) -{ - /* Evil hack; this method exists in dbus-glib >= 101, but if we don't - * have that, emulate it. - */ - return ((struct _HACKDBusGMethodInvocation *) context)->connection; + proxy = g_initable_new (proxy_type, NULL, &error, + "g-connection", connection, + "g-flags", (G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | + G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS), + "g-name", name, + "g-object-path", path, + "g-interface-name", iface, + NULL); + if (!proxy) { + nm_log_warn (LOGD_CORE, "Could not create proxy for %s on connection %s: %s", + iface, name, error->message); + g_error_free (error); + } + return proxy; } -#endif /* HAVE_DBUS_GLIB_GMI_GET_CONNECTION */ diff --git a/src/nm-bus-manager.h b/src/nm-bus-manager.h index 53dbe4498a..cf6a701f1a 100644 --- a/src/nm-bus-manager.h +++ b/src/nm-bus-manager.h @@ -23,17 +23,11 @@ #define __NM_BUS_MANAGER_H__ #include "config.h" -#include <dbus/dbus.h> -#include <dbus/dbus-glib.h> #include "nm-default.h" G_BEGIN_DECLS -typedef gboolean (* NMDBusSignalHandlerFunc) (DBusConnection * connection, - DBusMessage * message, - gpointer user_data); - #define NM_TYPE_BUS_MANAGER (nm_bus_manager_get_type ()) #define NM_BUS_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), NM_TYPE_BUS_MANAGER, NMBusManager)) #define NM_BUS_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), NM_TYPE_BUS_MANAGER, NMBusManagerClass)) @@ -42,7 +36,6 @@ typedef gboolean (* NMDBusSignalHandlerFunc) (DBusConnection * connection, #define NM_BUS_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), NM_TYPE_BUS_MANAGER, NMBusManagerClass)) #define NM_BUS_MANAGER_DBUS_CONNECTION_CHANGED "dbus-connection-changed" -#define NM_BUS_MANAGER_NAME_OWNER_CHANGED "name-owner-changed" #define NM_BUS_MANAGER_PRIVATE_CONNECTION_NEW "private-connection-new" #define NM_BUS_MANAGER_PRIVATE_CONNECTION_DISCONNECTED "private-connection-disconnected" @@ -55,18 +48,13 @@ typedef struct { /* Signals */ void (*dbus_connection_changed) (NMBusManager *mgr, - DBusConnection *connection); - - void (*name_owner_changed) (NMBusManager *mgr, - const char *name, - const char *old_owner, - const char *new_owner); + GDBusConnection *connection); void (*private_connection_new) (NMBusManager *mgr, - DBusGConnection *connection); + GDBusConnection *connection); void (*private_connection_disconnected) (NMBusManager *mgr, - DBusGConnection *connection); + GDBusConnection *connection); } NMBusManagerClass; GType nm_bus_manager_get_type (void); @@ -74,20 +62,12 @@ GType nm_bus_manager_get_type (void); NMBusManager * nm_bus_manager_get (void); void nm_bus_manager_setup (NMBusManager *instance); -char * nm_bus_manager_get_name_owner (NMBusManager *self, - const char *name, - GError **error); - gboolean nm_bus_manager_start_service (NMBusManager *self); -gboolean nm_bus_manager_name_has_owner (NMBusManager *self, - const char *name); - -DBusConnection * nm_bus_manager_get_dbus_connection (NMBusManager *self); -DBusGConnection * nm_bus_manager_get_connection (NMBusManager *self); +GDBusConnection * nm_bus_manager_get_connection (NMBusManager *self); gboolean nm_bus_manager_get_caller_info (NMBusManager *self, - DBusGMethodInvocation *context, + GDBusMethodInvocation *context, char **out_sender, gulong *out_uid, gulong *out_pid); @@ -97,8 +77,8 @@ gboolean nm_bus_manager_get_unix_user (NMBusManager *self, gulong *out_uid); gboolean nm_bus_manager_get_caller_info_from_message (NMBusManager *self, - DBusConnection *connection, - DBusMessage *message, + GDBusConnection *connection, + GDBusMessage *message, char **out_sender, gulong *out_uid, gulong *out_pid); @@ -109,20 +89,20 @@ void nm_bus_manager_register_object (NMBusManager *self, void nm_bus_manager_unregister_object (NMBusManager *self, gpointer object); +gpointer nm_bus_manager_get_registered_object (NMBusManager *self, + const char *path); + void nm_bus_manager_private_server_register (NMBusManager *self, const char *path, const char *tag); -DBusGProxy *nm_bus_manager_new_proxy (NMBusManager *self, - DBusGMethodInvocation *context, +GDBusProxy *nm_bus_manager_new_proxy (NMBusManager *self, + GDBusMethodInvocation *context, + GType proxy_type, const char *name, const char *path, const char *iface); -#if !HAVE_DBUS_GLIB_GMI_GET_CONNECTION -DBusGConnection *dbus_g_method_invocation_get_g_connection (DBusGMethodInvocation *context); -#endif - G_END_DECLS #endif /* __NM_BUS_MANAGER_H__ */ |