Commit 2a932ebb authored by David Zeuthen's avatar David Zeuthen

Bug 23867 – UnixProcess vs. SystemBusName aliasing

For now, convert SystemBusName to UnixProcess when storing/checking
temporary authorizations. See

http://git.gnome.org/cgit/PolicyKit-gnome/commit/?id=ad5fe38a1f7a7a670c3d8e9384b9cd0d037c9222

for a test-case for this.
parent f8f132f0
......@@ -82,6 +82,7 @@ PolkitSystemBusName
polkit_system_bus_name_new
polkit_system_bus_name_get_name
polkit_system_bus_name_set_name
polkit_system_bus_name_get_process_sync
<SUBSECTION Standard>
PolkitSystemBusNameClass
POLKIT_SYSTEM_BUS_NAME
......
......@@ -28,6 +28,8 @@
#include "polkitsubject.h"
#include "polkitprivate.h"
#include "polkitunixprocess.h"
/**
* SECTION:polkitsystembusname
* @title: PolkitSystemBusName
......@@ -379,3 +381,45 @@ subject_iface_init (PolkitSubjectIface *subject_iface)
subject_iface->exists_finish = polkit_system_bus_name_exists_finish;
subject_iface->exists_sync = polkit_system_bus_name_exists_sync;
}
/* ---------------------------------------------------------------------------------------------------- */
/**
* polkit_system_bus_name_get_process_sync:
* @system_bus_name: A #PolkitSystemBusName.
* @cancellable: A #GCancellable or %NULL.
* @error: Return location for error or %NULL.
*
* Synchronously gets a #PolkitUnixProcess object for @system_bus_name.
*
* Returns: A #PolkitUnixProcess object or %NULL if @error is set.
**/
PolkitSubject *
polkit_system_bus_name_get_process_sync (PolkitSystemBusName *system_bus_name,
GCancellable *cancellable,
GError **error)
{
EggDBusConnection *connection;
PolkitSubject *ret;
pid_t pid;
ret = NULL;
connection = egg_dbus_connection_get_for_bus (EGG_DBUS_BUS_TYPE_SYSTEM);
if (!egg_dbus_bus_get_connection_unix_process_id_sync (egg_dbus_connection_get_bus (connection),
EGG_DBUS_CALL_FLAGS_NONE,
system_bus_name->name,
&pid,
cancellable,
error))
{
goto out;
}
ret = polkit_unix_process_new (pid);
out:
g_object_unref (connection);
return ret;
}
......@@ -46,11 +46,15 @@ typedef struct _PolkitSystemBusName PolkitSystemBusName;
#endif
typedef struct _PolkitSystemBusNameClass PolkitSystemBusNameClass;
GType polkit_system_bus_name_get_type (void) G_GNUC_CONST;
PolkitSubject *polkit_system_bus_name_new (const gchar *name);
const gchar *polkit_system_bus_name_get_name (PolkitSystemBusName *system_bus_name);
void polkit_system_bus_name_set_name (PolkitSystemBusName *system_bus_name,
const gchar *name);
GType polkit_system_bus_name_get_type (void) G_GNUC_CONST;
PolkitSubject *polkit_system_bus_name_new (const gchar *name);
const gchar *polkit_system_bus_name_get_name (PolkitSystemBusName *system_bus_name);
void polkit_system_bus_name_set_name (PolkitSystemBusName *system_bus_name,
const gchar *name);
/* TODO: add async version of get_process() method */
PolkitSubject *polkit_system_bus_name_get_process_sync (PolkitSystemBusName *system_bus_name,
GCancellable *cancellable,
GError **error);
G_END_DECLS
......
......@@ -1959,18 +1959,41 @@ temporary_authorization_store_has_authorization (TemporaryAuthorizationStore *st
{
GList *l;
gboolean ret;
PolkitSubject *subject_to_use;
g_return_val_if_fail (store != NULL, FALSE);
g_return_val_if_fail (POLKIT_IS_SUBJECT (subject), FALSE);
g_return_val_if_fail (action_id != NULL, FALSE);
/* XXX: for now, prefer to store the process */
if (POLKIT_IS_SYSTEM_BUS_NAME (subject))
{
GError *error;
error = NULL;
subject_to_use = polkit_system_bus_name_get_process_sync (POLKIT_SYSTEM_BUS_NAME (subject),
NULL,
&error);
if (subject_to_use == NULL)
{
g_warning ("Error getting process for system bus name `%s': %s",
polkit_system_bus_name_get_name (POLKIT_SYSTEM_BUS_NAME (subject)),
error->message);
g_error_free (error);
subject_to_use = g_object_ref (subject);
}
}
else
{
subject_to_use = g_object_ref (subject);
}
ret = FALSE;
for (l = store->authorizations; l != NULL; l = l->next) {
TemporaryAuthorization *authorization = l->data;
if (strcmp (action_id, authorization->action_id) == 0 &&
polkit_subject_equal (subject, authorization->subject))
polkit_subject_equal (subject_to_use, authorization->subject))
{
ret = TRUE;
if (out_tmp_authz_id != NULL)
......@@ -1980,6 +2003,7 @@ temporary_authorization_store_has_authorization (TemporaryAuthorizationStore *st
}
out:
g_object_unref (subject_to_use);
return ret;
}
......@@ -2095,12 +2119,35 @@ temporary_authorization_store_add_authorization (TemporaryAuthorizationStore *st
{
TemporaryAuthorization *authorization;
guint expiration_seconds;
PolkitSubject *subject_to_use;
g_return_val_if_fail (store != NULL, NULL);
g_return_val_if_fail (POLKIT_IS_SUBJECT (subject), NULL);
g_return_val_if_fail (action_id != NULL, NULL);
g_return_val_if_fail (!temporary_authorization_store_has_authorization (store, subject, action_id, NULL), NULL);
/* XXX: for now, prefer to store the process */
if (POLKIT_IS_SYSTEM_BUS_NAME (subject))
{
GError *error;
error = NULL;
subject_to_use = polkit_system_bus_name_get_process_sync (POLKIT_SYSTEM_BUS_NAME (subject),
NULL,
&error);
if (subject_to_use == NULL)
{
g_warning ("Error getting process for system bus name `%s': %s",
polkit_system_bus_name_get_name (POLKIT_SYSTEM_BUS_NAME (subject)),
error->message);
g_error_free (error);
subject_to_use = g_object_ref (subject);
}
}
else
{
subject_to_use = g_object_ref (subject);
}
/* TODO: right now the time the temporary authorization is kept is hard-coded - we
* could make it a propery on the PolkitBackendInteractiveAuthority class (so
* the local authority could read it from a config file) or a vfunc
......@@ -2111,7 +2158,7 @@ temporary_authorization_store_add_authorization (TemporaryAuthorizationStore *st
authorization = g_new0 (TemporaryAuthorization, 1);
authorization->id = g_strdup_printf ("tmpauthz%" G_GUINT64_FORMAT, store->serial++);
authorization->store = store;
authorization->subject = g_object_ref (subject);
authorization->subject = g_object_ref (subject_to_use);
authorization->session = g_object_ref (session);
authorization->action_id = g_strdup (action_id);
authorization->time_granted = time (NULL);
......@@ -2152,6 +2199,8 @@ temporary_authorization_store_add_authorization (TemporaryAuthorizationStore *st
store->authorizations = g_list_prepend (store->authorizations, authorization);
g_object_unref (subject_to_use);
return authorization->id;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment