libnm-glib: get permissions synchronously at startup

Many clients using libnm-glib (often command-line ones like nm-tool
or nmcli) aren't long-lived enough for NM to get their UID from
the bus daemon and validate their permissions via PolicyKit.  So
when the NMClient object is created, get the permissions synchronously
(with a very low timeout to prevent unecessary blocking) to ensure
that the client is still on the bus when NM asks for it's credentials.

Avoids a ton of messages like:

NetworkManager[10274]: <warn> error requesting auth for org.freedesktop.NetworkManager.enable-disable-wwan: (6) Remote Exception invoking org.freedesktop.PolicyKit1.Authority.CheckAuthorization() on /org/freedesktop/PolicyKit1/Authority at name org.freedesktop.PolicyKit1: org.freedesktop.DBus.Error.NameHasNoOwner: Remote Exception invoking org.freedesktop.DBus.GetConnectionUnixUser() on / at name org.freedesktop.DBus: org.freedesktop.DBus.Error.NameHasNoOwner: Could not get UID of name ':1.95': no such name
This commit is contained in:
Dan Williams
2010-08-09 17:54:40 -05:00
parent 11ed2f737f
commit d3b26a9c57

View File

@@ -322,12 +322,8 @@ nm_permission_result_to_client (const char *nm)
}
static void
get_permissions_reply (DBusGProxy *proxy,
GHashTable *permissions,
GError *error,
gpointer user_data)
update_permissions (NMClient *self, GHashTable *permissions)
{
NMClient *self = NM_CLIENT (user_data);
NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (self);
GHashTableIter iter;
gpointer key, value;
@@ -335,13 +331,11 @@ get_permissions_reply (DBusGProxy *proxy,
NMClientPermissionResult perm_result;
GList *keys, *keys_iter;
priv->perm_call = NULL;
/* get list of old permissions for change notification */
keys = g_hash_table_get_keys (priv->permissions);
g_hash_table_remove_all (priv->permissions);
if (!error) {
if (permissions) {
/* Process new permissions */
g_hash_table_iter_init (&iter, permissions);
while (g_hash_table_iter_next (&iter, &key, &value)) {
@@ -380,12 +374,31 @@ get_permissions_reply (DBusGProxy *proxy,
g_list_free (keys);
}
static DBusGProxyCall *
get_permissions (NMClient *self)
static void
get_permissions_sync (NMClient *self)
{
return org_freedesktop_NetworkManager_get_permissions_async (NM_CLIENT_GET_PRIVATE (self)->client_proxy,
get_permissions_reply,
self);
gboolean success;
GHashTable *permissions = NULL;
success = dbus_g_proxy_call_with_timeout (NM_CLIENT_GET_PRIVATE (self)->client_proxy,
"GetPermissions", 3000, NULL,
G_TYPE_INVALID,
DBUS_TYPE_G_MAP_OF_STRING, &permissions, G_TYPE_INVALID);
update_permissions (self, success ? permissions : NULL);
if (permissions)
g_hash_table_destroy (permissions);
}
static void
get_permissions_reply (DBusGProxy *proxy,
GHashTable *permissions,
GError *error,
gpointer user_data)
{
NMClient *self = NM_CLIENT (user_data);
NM_CLIENT_GET_PRIVATE (self)->perm_call = NULL;
update_permissions (NM_CLIENT (user_data), error ? NULL : permissions);
}
static void
@@ -394,8 +407,11 @@ client_recheck_permissions (DBusGProxy *proxy, gpointer user_data)
NMClient *self = NM_CLIENT (user_data);
NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (self);
if (!priv->perm_call)
priv->perm_call = get_permissions (self);
if (!priv->perm_call) {
priv->perm_call = org_freedesktop_NetworkManager_get_permissions_async (NM_CLIENT_GET_PRIVATE (self)->client_proxy,
get_permissions_reply,
self);
}
}
static GObject*
@@ -445,7 +461,7 @@ constructor (GType type,
G_CALLBACK (client_recheck_permissions),
object,
NULL);
priv->perm_call = get_permissions (NM_CLIENT (object));
get_permissions_sync (NM_CLIENT (object));
priv->bus_proxy = dbus_g_proxy_new_for_name (connection,
"org.freedesktop.DBus",