PolicyKit: Branch 'master' - 4 commits
Colin Walters
walters at kemper.freedesktop.org
Mon Nov 11 16:01:53 PST 2013
src/polkit/polkitpermission.c | 2
src/polkit/polkitsubject.c | 4
src/polkit/polkitsystembusname.c | 171 +++++++++++-----
src/polkitbackend/polkitbackendsessionmonitor-systemd.c | 63 ++---
src/programs/pkcheck.c | 4
src/programs/pkttyagent.c | 12 -
test/polkitbackend/test-polkitbackendjsauthority.c | 8
7 files changed, 163 insertions(+), 101 deletions(-)
New commits:
commit a4f1c2a546f3685121418a040081f0bac220fd94
Author: Colin Walters <walters at verbum.org>
Date: Thu Nov 7 17:24:30 2013 -0500
Use G_GNUC_BEGIN_IGNORE_DEPRECATIONS to avoid warning spam
In these cases, we can't every drop use of our API which we deprecated
for external callers; for example where a (deprecated) command line is
invoking the deprecated API.
This patch avoids having polkit developers get spammed by unfixable
warnings.
diff --git a/src/polkit/polkitsubject.c b/src/polkit/polkitsubject.c
index aed5795..b86e0b9 100644
--- a/src/polkit/polkitsubject.c
+++ b/src/polkit/polkitsubject.c
@@ -247,11 +247,15 @@ polkit_subject_from_string (const gchar *str,
}
else if (sscanf (str, "unix-process:%d:%" G_GUINT64_FORMAT, &scanned_pid, &scanned_starttime) == 2)
{
+ G_GNUC_BEGIN_IGNORE_DEPRECATIONS
subject = polkit_unix_process_new_full (scanned_pid, scanned_starttime);
+ G_GNUC_END_IGNORE_DEPRECATIONS
}
else if (sscanf (str, "unix-process:%d", &scanned_pid) == 1)
{
+ G_GNUC_BEGIN_IGNORE_DEPRECATIONS
subject = polkit_unix_process_new (scanned_pid);
+ G_GNUC_END_IGNORE_DEPRECATIONS
if (polkit_unix_process_get_start_time (POLKIT_UNIX_PROCESS (subject)) == 0)
{
g_object_unref (subject);
diff --git a/src/programs/pkcheck.c b/src/programs/pkcheck.c
index 11b2e26..5781893 100644
--- a/src/programs/pkcheck.c
+++ b/src/programs/pkcheck.c
@@ -399,11 +399,15 @@ main (int argc, char *argv[])
}
else if (sscanf (argv[n], "%i,%" G_GUINT64_FORMAT, &pid, &pid_start_time) == 2)
{
+ G_GNUC_BEGIN_IGNORE_DEPRECATIONS
subject = polkit_unix_process_new_full (pid, pid_start_time);
+ G_GNUC_END_IGNORE_DEPRECATIONS
}
else if (sscanf (argv[n], "%i", &pid) == 1)
{
+ G_GNUC_BEGIN_IGNORE_DEPRECATIONS
subject = polkit_unix_process_new (pid);
+ G_GNUC_END_IGNORE_DEPRECATIONS
}
else
{
diff --git a/src/programs/pkttyagent.c b/src/programs/pkttyagent.c
index e5088bb..423b728 100644
--- a/src/programs/pkttyagent.c
+++ b/src/programs/pkttyagent.c
@@ -111,9 +111,17 @@ main (int argc, char *argv[])
if (sscanf (opt_process, "%i,%" G_GUINT64_FORMAT, &pid, &pid_start_time)
== 2)
- subject = polkit_unix_process_new_full (pid, pid_start_time);
+ {
+ G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+ subject = polkit_unix_process_new_full (pid, pid_start_time);
+ G_GNUC_END_IGNORE_DEPRECATIONS
+ }
else if (sscanf (opt_process, "%i", &pid) == 1)
- subject = polkit_unix_process_new (pid);
+ {
+ G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+ subject = polkit_unix_process_new (pid);
+ G_GNUC_END_IGNORE_DEPRECATIONS
+ }
else
{
g_printerr (_("%s: Invalid process specifier `%s'\n"),
commit 6d3d0a8ffb0fd8ae59eb35593b305ec87da8858d
Author: Colin Walters <walters at verbum.org>
Date: Sat Nov 9 13:48:21 2013 -0500
Port internals non-deprecated PolkitProcess API where possible
We can't port everything, but in PolkitPermission and these test
cases, we can use _for_owner() with the right information.
diff --git a/src/polkit/polkitpermission.c b/src/polkit/polkitpermission.c
index 22d195f..f8a666e 100644
--- a/src/polkit/polkitpermission.c
+++ b/src/polkit/polkitpermission.c
@@ -122,7 +122,7 @@ polkit_permission_constructed (GObject *object)
PolkitPermission *permission = POLKIT_PERMISSION (object);
if (permission->subject == NULL)
- permission->subject = polkit_unix_process_new (getpid ());
+ permission->subject = polkit_unix_process_new_for_owner (getpid (), 0, getuid ());
if (G_OBJECT_CLASS (polkit_permission_parent_class)->constructed != NULL)
G_OBJECT_CLASS (polkit_permission_parent_class)->constructed (object);
diff --git a/test/polkitbackend/test-polkitbackendjsauthority.c b/test/polkitbackend/test-polkitbackendjsauthority.c
index a4de6b1..dfb894f 100644
--- a/test/polkitbackend/test-polkitbackendjsauthority.c
+++ b/test/polkitbackend/test-polkitbackendjsauthority.c
@@ -74,8 +74,8 @@ test_get_admin_identities_for_action_id (const gchar *action_id,
authority = get_authority ();
- caller = polkit_unix_process_new (getpid ());
- subject = polkit_unix_process_new (getpid ());
+ caller = polkit_unix_process_new_for_owner (getpid (), 0, getuid ());
+ subject = polkit_unix_process_new_for_owner (getpid (), 0, getuid ());
user_for_subject = polkit_identity_from_string ("unix-user:root", &error);
g_assert_no_error (error);
@@ -340,8 +340,8 @@ rules_test_func (gconstpointer user_data)
authority = get_authority ();
- caller = polkit_unix_process_new (getpid ());
- subject = polkit_unix_process_new (getpid ());
+ caller = polkit_unix_process_new_for_owner (getpid (), 0, getuid ());
+ subject = polkit_unix_process_new_for_owner (getpid (), 0, getuid ());
user_for_subject = polkit_identity_from_string (tc->identity, &error);
g_assert_no_error (error);
commit bfa5036bfb93582c5a87c44b847957479d911e38
Author: Colin Walters <walters at verbum.org>
Date: Sat Nov 9 09:32:52 2013 -0500
PolkitSystemBusName: Retrieve both pid and uid
For polkit_system_bus_name_get_process_sync(), as pointed out by
Miloslav Trmac, we can securely retrieve the owner uid as well from
the system bus, rather than (racily) looking it up internally.
This avoids use of a deprecated API.
However, this is not a security fix because nothing in the polkit
codebase itself actually retrieves the uid from the result of this API
call. But, it might be useful in the future.
diff --git a/src/polkit/polkitsystembusname.c b/src/polkit/polkitsystembusname.c
index 51e4a69..8daa12c 100644
--- a/src/polkit/polkitsystembusname.c
+++ b/src/polkit/polkitsystembusname.c
@@ -341,6 +341,116 @@ subject_iface_init (PolkitSubjectIface *subject_iface)
/* ---------------------------------------------------------------------------------------------------- */
+typedef struct {
+ GError **error;
+ guint retrieved_uid : 1;
+ guint retrieved_pid : 1;
+ guint caught_error : 1;
+
+ guint32 uid;
+ guint32 pid;
+} AsyncGetBusNameCredsData;
+
+static void
+on_retrieved_unix_uid_pid (GObject *src,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ AsyncGetBusNameCredsData *data = user_data;
+ GVariant *v;
+
+ v = g_dbus_connection_call_finish ((GDBusConnection*)src, res,
+ data->caught_error ? NULL : data->error);
+ if (!v)
+ {
+ data->caught_error = TRUE;
+ }
+ else
+ {
+ guint32 value;
+ g_variant_get (v, "(u)", &value);
+ g_variant_unref (v);
+ if (!data->retrieved_uid)
+ {
+ data->retrieved_uid = TRUE;
+ data->uid = value;
+ }
+ else
+ {
+ g_assert (!data->retrieved_pid);
+ data->retrieved_pid = TRUE;
+ data->pid = value;
+ }
+ }
+}
+
+static gboolean
+polkit_system_bus_name_get_creds_sync (PolkitSystemBusName *system_bus_name,
+ guint32 *out_uid,
+ guint32 *out_pid,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gboolean ret = FALSE;
+ AsyncGetBusNameCredsData data = { 0, };
+ GDBusConnection *connection = NULL;
+ GMainContext *tmp_context = NULL;
+
+ connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, cancellable, error);
+ if (connection == NULL)
+ goto out;
+
+ data.error = error;
+
+ tmp_context = g_main_context_new ();
+ g_main_context_push_thread_default (tmp_context);
+
+ /* Do two async calls as it's basically as fast as one sync call.
+ */
+ g_dbus_connection_call (connection,
+ "org.freedesktop.DBus", /* name */
+ "/org/freedesktop/DBus", /* object path */
+ "org.freedesktop.DBus", /* interface name */
+ "GetConnectionUnixUser", /* method */
+ g_variant_new ("(s)", system_bus_name->name),
+ G_VARIANT_TYPE ("(u)"),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ cancellable,
+ on_retrieved_unix_uid_pid,
+ &data);
+ g_dbus_connection_call (connection,
+ "org.freedesktop.DBus", /* name */
+ "/org/freedesktop/DBus", /* object path */
+ "org.freedesktop.DBus", /* interface name */
+ "GetConnectionUnixProcessID", /* method */
+ g_variant_new ("(s)", system_bus_name->name),
+ G_VARIANT_TYPE ("(u)"),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ cancellable,
+ on_retrieved_unix_uid_pid,
+ &data);
+
+ while (!((data.retrieved_uid && data.retrieved_pid) || data.caught_error))
+ g_main_context_iteration (tmp_context, TRUE);
+
+ if (out_uid)
+ *out_uid = data.uid;
+ if (out_pid)
+ *out_pid = data.pid;
+ ret = TRUE;
+ out:
+ if (tmp_context)
+ {
+ g_main_context_pop_thread_default (tmp_context);
+ g_main_context_unref (tmp_context);
+ }
+ if (connection != NULL)
+ g_object_unref (connection);
+ return ret;
+}
+
/**
* polkit_system_bus_name_get_process_sync:
* @system_bus_name: A #PolkitSystemBusName.
@@ -357,43 +467,21 @@ polkit_system_bus_name_get_process_sync (PolkitSystemBusName *system_bus_name,
GCancellable *cancellable,
GError **error)
{
- GDBusConnection *connection;
- PolkitSubject *ret;
- GVariant *result;
+ PolkitSubject *ret = NULL;
guint32 pid;
+ guint32 uid;
g_return_val_if_fail (POLKIT_IS_SYSTEM_BUS_NAME (system_bus_name), NULL);
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
- ret = NULL;
-
- connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, cancellable, error);
- if (connection == NULL)
+ if (!polkit_system_bus_name_get_creds_sync (system_bus_name, &uid, &pid,
+ cancellable, error))
goto out;
- result = g_dbus_connection_call_sync (connection,
- "org.freedesktop.DBus", /* name */
- "/org/freedesktop/DBus", /* object path */
- "org.freedesktop.DBus", /* interface name */
- "GetConnectionUnixProcessID", /* method */
- g_variant_new ("(s)", system_bus_name->name),
- G_VARIANT_TYPE ("(u)"),
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- cancellable,
- error);
- if (result == NULL)
- goto out;
-
- g_variant_get (result, "(u)", &pid);
- g_variant_unref (result);
-
- ret = polkit_unix_process_new (pid);
+ ret = polkit_unix_process_new_for_owner (pid, 0, uid);
out:
- if (connection != NULL)
- g_object_unref (connection);
return ret;
}
@@ -413,42 +501,19 @@ polkit_system_bus_name_get_user_sync (PolkitSystemBusName *system_bus_name,
GCancellable *cancellable,
GError **error)
{
- GDBusConnection *connection;
- PolkitUnixUser *ret;
- GVariant *result;
+ PolkitUnixUser *ret = NULL;
guint32 uid;
g_return_val_if_fail (POLKIT_IS_SYSTEM_BUS_NAME (system_bus_name), NULL);
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
- ret = NULL;
-
- connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, cancellable, error);
- if (connection == NULL)
- goto out;
-
- result = g_dbus_connection_call_sync (connection,
- "org.freedesktop.DBus", /* name */
- "/org/freedesktop/DBus", /* object path */
- "org.freedesktop.DBus", /* interface name */
- "GetConnectionUnixUser", /* method */
- g_variant_new ("(s)", system_bus_name->name),
- G_VARIANT_TYPE ("(u)"),
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- cancellable,
- error);
- if (result == NULL)
+ if (!polkit_system_bus_name_get_creds_sync (system_bus_name, &uid, NULL,
+ cancellable, error))
goto out;
- g_variant_get (result, "(u)", &uid);
- g_variant_unref (result);
-
ret = (PolkitUnixUser*)polkit_unix_user_new (uid);
out:
- if (connection != NULL)
- g_object_unref (connection);
return ret;
}
commit 26d0c0578211fb96fc8fe75572aa11ad6ecbf9b8
Author: Colin Walters <walters at verbum.org>
Date: Thu Nov 7 15:57:50 2013 -0500
sessionmonitor-systemd: Deduplicate code paths
We had the code to go from pid -> session duplicated. If we have a
PolkitSystemBusName, convert it to a PolkitUnixProcess.
Then we can do PolkitUnixProcess -> pid -> session in one place.
This is just a code cleanup.
https://bugs.freedesktop.org/show_bug.cgi?id=69538
diff --git a/src/polkitbackend/polkitbackendsessionmonitor-systemd.c b/src/polkitbackend/polkitbackendsessionmonitor-systemd.c
index 0185310..756b728 100644
--- a/src/polkitbackend/polkitbackendsessionmonitor-systemd.c
+++ b/src/polkitbackend/polkitbackendsessionmonitor-systemd.c
@@ -313,61 +313,42 @@ polkit_backend_session_monitor_get_session_for_subject (PolkitBackendSessionMoni
PolkitSubject *subject,
GError **error)
{
- PolkitSubject *session;
-
- session = NULL;
+ PolkitUnixProcess *tmp_process = NULL;
+ PolkitUnixProcess *process = NULL;
+ PolkitSubject *session = NULL;
+ char *session_id = NULL;
+ pid_t pid;
if (POLKIT_IS_UNIX_PROCESS (subject))
- {
- gchar *session_id;
- pid_t pid;
-
- pid = polkit_unix_process_get_pid (POLKIT_UNIX_PROCESS (subject));
- if (sd_pid_get_session (pid, &session_id) < 0)
- goto out;
-
- session = polkit_unix_session_new (session_id);
- free (session_id);
- }
+ process = POLKIT_UNIX_PROCESS (subject); /* We already have a process */
else if (POLKIT_IS_SYSTEM_BUS_NAME (subject))
{
- guint32 pid;
- gchar *session_id;
- GVariant *result;
-
- result = g_dbus_connection_call_sync (monitor->system_bus,
- "org.freedesktop.DBus",
- "/org/freedesktop/DBus",
- "org.freedesktop.DBus",
- "GetConnectionUnixProcessID",
- g_variant_new ("(s)", polkit_system_bus_name_get_name (POLKIT_SYSTEM_BUS_NAME (subject))),
- G_VARIANT_TYPE ("(u)"),
- G_DBUS_CALL_FLAGS_NONE,
- -1, /* timeout_msec */
- NULL, /* GCancellable */
- error);
- if (result == NULL)
- goto out;
- g_variant_get (result, "(u)", &pid);
- g_variant_unref (result);
-
- if (sd_pid_get_session (pid, &session_id) < 0)
- goto out;
-
- session = polkit_unix_session_new (session_id);
- free (session_id);
+ /* Convert bus name to process */
+ tmp_process = (PolkitUnixProcess*)polkit_system_bus_name_get_process_sync (POLKIT_SYSTEM_BUS_NAME (subject), NULL, error);
+ if (!tmp_process)
+ goto out;
+ process = tmp_process;
}
else
{
g_set_error (error,
POLKIT_ERROR,
POLKIT_ERROR_NOT_SUPPORTED,
- "Cannot get user for subject of type %s",
+ "Cannot get session for subject of type %s",
g_type_name (G_TYPE_FROM_INSTANCE (subject)));
}
- out:
+ /* Now do process -> pid -> session */
+ g_assert (process != NULL);
+ pid = polkit_unix_process_get_pid (process);
+ if (sd_pid_get_session (pid, &session_id) < 0)
+ goto out;
+
+ session = polkit_unix_session_new (session_id);
+ free (session_id);
+ out:
+ if (tmp_process) g_object_unref (tmp_process);
return session;
}
More information about the hal-commit
mailing list