Hello community, here is the log from the commit of package polkit for openSUSE:12.1 checked in at 2011-11-05 11:22:39 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:12.1/polkit (Old) and /work/SRC/openSUSE:12.1/.polkit.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "polkit", Maintainer is "" Changes: -------- --- /work/SRC/openSUSE:12.1/polkit/polkit.changes 2011-10-24 13:19:54.000000000 +0200 +++ /work/SRC/openSUSE:12.1/.polkit.new/polkit.changes 2011-11-05 11:57:29.000000000 +0100 @@ -1,0 +2,7 @@ +Wed Nov 2 10:30:03 UTC 2011 - lnus...@suse.de + +- pick some patches from git to add support for + org.freedesktop.policykit.imply, disable debug spam and allow + unprivileged users to query authorizations (bnc#698250) + +------------------------------------------------------------------- New: ---- 0001-Add-support-for-the-org.freedesktop.policykit.imply-a.diff 0002-Add-no-debug-option-and-use-this-for-D-Bus-activation.diff 0003-Bug-41025-Add-org.freedesktop.policykit.owner-annotat.diff ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ polkit.spec ++++++ --- /var/tmp/diff_new_pack.NS0VP6/_old 2011-11-05 11:57:31.000000000 +0100 +++ /var/tmp/diff_new_pack.NS0VP6/_new 2011-11-05 11:57:31.000000000 +0100 @@ -27,6 +27,12 @@ Group: System/Libraries Source0: http://hal.freedesktop.org/releases/%{name}-%{version}.tar.gz Source99: baselibs.conf +# PATCH-FIX-UPSTREAM Add support for the org.freedesktop.policykit.imply annotation +Patch0: 0001-Add-support-for-the-org.freedesktop.policykit.imply-a.diff +# PATCH-FIX-UPSTREAM Add --no-debug option and use this for D-Bus activation +Patch1: 0002-Add-no-debug-option-and-use-this-for-D-Bus-activation.diff +# PATCH-FIX-UPSTREAM allow unprivileged users to check authorizations +Patch2: 0003-Bug-41025-Add-org.freedesktop.policykit.owner-annotat.diff BuildRequires: glib2-devel >= 2.25.12 BuildRequires: gobject-introspection-devel >= 0.6.2 BuildRequires: gtk-doc @@ -87,6 +93,9 @@ %prep %setup -q +%patch0 -p1 +%patch1 -p1 +%patch2 -p1 %build export V=1 ++++++ 0001-Add-support-for-the-org.freedesktop.policykit.imply-a.diff ++++++ >From 6bbd5189e967e8ddc36100bf22cd12bcb152ab5f Mon Sep 17 00:00:00 2001 From: David Zeuthen <dav...@redhat.com> Date: Tue, 20 Sep 2011 14:13:12 -0400 Subject: [PATCH 1/3] Add support for the org.freedesktop.policykit.imply annotation For example, GNOME control center can now defined e.g. <action id="org.zee.example.meta"> <description>Meta Action</description> <message>Example of a meta action, blabla</message> <defaults> <allow_any>no</allow_any> <allow_inactive>no</allow_inactive> <allow_active>auth_admin_keep</allow_active> </defaults> <annotate key="org.freedesktop.policykit.imply">org.freedesktop.udisks2.ata-smart-selftest org.freedesktop.udisks2.encrypted-lock-others org.freedesktop.udisks2.filesystem-unmount-others</annotate> </action> and set up a single GtkLockButton for a PolkitPermission for action id "org.zee.example.meta". When unlocked the given subject will now be authorized for the actions mentioned in the annotation. Example test program: int main (int argc, char *argv[]) { PolkitSubject *subject; GtkWidget *window; GtkWidget *table; GMainLoop *loop; guint n; gtk_init (&argc, &argv); subject = polkit_unix_process_new (getpid ()); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); table = gtk_table_new (1, 2, FALSE); for (n = 1; n < argc; n++) { const gchar *action_id = argv[n]; GPermission *permission; GtkWidget *label; GtkWidget *lock_button; GError *error = NULL; label = gtk_label_new (action_id); permission = polkit_permission_new_sync (action_id, subject, NULL, &error); if (permission == NULL) { g_error ("Error constructing permission for action_id %s: %s (%s, %d)", action_id, error->message, g_quark_to_string (error->domain), error->code); goto out; } lock_button = gtk_lock_button_new (permission); g_object_unref (permission); gtk_table_attach (GTK_TABLE (table), label, 0, 1, n - 1, n, GTK_FILL, GTK_FILL, 0, 0); gtk_table_attach (GTK_TABLE (table), lock_button, 1, 2, n - 1, n, GTK_FILL, GTK_FILL, 0, 0); } gtk_container_add (GTK_CONTAINER (window), table); gtk_widget_show_all (window); loop = g_main_loop_new (NULL, FALSE); g_main_loop_run (loop); out: ; } Compile with: gcc -o showpolkit showpolkit.c `pkg-config --cflags --libs polkit-gobject-1 gtk+-3.0` -g -O0 Run with: ./showpolkit org.freedesktop.udisks2.ata-smart-selftest org.freedesktop.udisks2.encrypted-lock-others org.freedesktop.udisks2.filesystem-unmount-others org.zee.example.meta Signed-off-by: David Zeuthen <dav...@redhat.com> --- docs/man/polkit.xml | 25 +++++++- .../polkitbackendinteractiveauthority.c | 67 ++++++++++++++++++++ 2 files changed, 90 insertions(+), 2 deletions(-) diff --git a/docs/man/polkit.xml b/docs/man/polkit.xml index bcb276b..bfa5ccd 100644 --- a/docs/man/polkit.xml +++ b/docs/man/polkit.xml @@ -369,8 +369,7 @@ System Context | | the <literal>key</literal> attribute and the value is specified using the <literal>value</literal> attribute. This element may appear zero or more times. See - <citerefentry><refentrytitle>pkexec</refentrytitle><manvolnum>1</manvolnum></citerefentry> - for an example of how this can be used. </para></listitem> + below for known annotations. </para></listitem> </varlistentry> <varlistentry> <term><emphasis>vendor</emphasis></term> @@ -398,6 +397,28 @@ System Context | | <citerefentry><refentrytitle>pkaction</refentrytitle><manvolnum>1</manvolnum></citerefentry> command. </para> + + <refsect2><title>Known annotations</title> + <para> + The <literal>org.freedesktop.policykit.exec.path</literal> + annotation is used by the <command>pkexec</command> program + shipped with PolicyKit - see the + <citerefentry><refentrytitle>pkexec</refentrytitle><manvolnum>1</manvolnum></citerefentry> + man page for details. + </para> + <para> + The <literal>org.freedesktop.policykit.imply</literal> + annotation (its value is a string containing a space separated + list of action identifiers) can be used to define <emphasis>meta + actions</emphasis>. The way it works is that if a subject is + authorized for an action with this annotation, then it is also + authorized for any action specified by the annotation. A typical + use of this annotation is when defining an UI shell with a + single lock button that should unlock multiple actions from + distinct mechanisms. + </para> + </refsect2> + </refsect1> <refsect1 id="polkit-author"><title>AUTHOR</title> diff --git a/src/polkitbackend/polkitbackendinteractiveauthority.c b/src/polkitbackend/polkitbackendinteractiveauthority.c index 8b32459..3566248 100644 --- a/src/polkitbackend/polkitbackendinteractiveauthority.c +++ b/src/polkitbackend/polkitbackendinteractiveauthority.c @@ -148,6 +148,7 @@ static PolkitAuthorizationResult *check_authorization_sync (PolkitBackendAuthori PolkitDetails *details, PolkitCheckAuthorizationFlags flags, PolkitImplicitAuthorization *out_implicit_authorization, + gboolean checking_imply, GError **error); static gboolean polkit_backend_interactive_authority_register_authentication_agent (PolkitBackendAuthority *authority, @@ -890,6 +891,7 @@ polkit_backend_interactive_authority_check_authorization (PolkitBackendAuthority details, flags, &implicit_authorization, + FALSE, /* checking_imply */ &error); if (error != NULL) { @@ -964,6 +966,7 @@ check_authorization_sync (PolkitBackendAuthority *authority, PolkitDetails *details, PolkitCheckAuthorizationFlags flags, PolkitImplicitAuthorization *out_implicit_authorization, + gboolean checking_imply, GError **error) { PolkitBackendInteractiveAuthority *interactive_authority; @@ -979,12 +982,15 @@ check_authorization_sync (PolkitBackendAuthority *authority, PolkitImplicitAuthorization implicit_authorization; const gchar *tmp_authz_id; PolkitDetails *result_details; + GList *actions; + GList *l; interactive_authority = POLKIT_BACKEND_INTERACTIVE_AUTHORITY (authority); priv = POLKIT_BACKEND_INTERACTIVE_AUTHORITY_GET_PRIVATE (interactive_authority); result = NULL; + actions = NULL; user_of_subject = NULL; groups_of_user = NULL; subject_str = NULL; @@ -1095,6 +1101,64 @@ check_authorization_sync (PolkitBackendAuthority *authority, goto out; } + /* then see if implied by another action that the subject is authorized for + * (but only one level deep to avoid infinite recursion) + * + * TODO: if this is slow, we can maintain a hash table for looking up what + * actions implies a given action + */ + if (!checking_imply) + { + actions = polkit_backend_action_pool_get_all_actions (priv->action_pool, NULL); + for (l = actions; l != NULL; l = l->next) + { + PolkitActionDescription *imply_ad = POLKIT_ACTION_DESCRIPTION (l->data); + const gchar *imply; + imply = polkit_action_description_get_annotation (imply_ad, "org.freedesktop.policykit.imply"); + if (imply != NULL) + { + gchar **tokens; + guint n; + tokens = g_strsplit (imply, " ", 0); + for (n = 0; tokens[n] != NULL; n++) + { + if (g_strcmp0 (tokens[n], action_id) == 0) + { + PolkitAuthorizationResult *implied_result = NULL; + PolkitImplicitAuthorization implied_implicit_authorization; + GError *implied_error = NULL; + const gchar *imply_action_id; + + imply_action_id = polkit_action_description_get_action_id (imply_ad); + + /* g_debug ("%s is implied by %s, checking", action_id, imply_action_id); */ + implied_result = check_authorization_sync (authority, caller, subject, + imply_action_id, + details, flags, + &implied_implicit_authorization, TRUE, + &implied_error); + if (implied_result != NULL) + { + if (polkit_authorization_result_get_is_authorized (implied_result)) + { + g_debug (" is authorized (implied by %s)", imply_action_id); + result = implied_result; + /* cleanup */ + g_object_unref (result_details); + g_strfreev (tokens); + goto out; + } + g_object_unref (implied_result); + } + if (implied_error != NULL) + g_error_free (implied_error); + } + } + g_strfreev (tokens); + } + } + } + if (implicit_authorization != POLKIT_IMPLICIT_AUTHORIZATION_NOT_AUTHORIZED) { if (implicit_authorization == POLKIT_IMPLICIT_AUTHORIZATION_AUTHENTICATION_REQUIRED_RETAINED || @@ -1118,6 +1182,9 @@ check_authorization_sync (PolkitBackendAuthority *authority, g_debug (" not authorized"); } out: + g_list_foreach (actions, (GFunc) g_object_unref, NULL); + g_list_free (actions); + g_free (subject_str); g_list_foreach (groups_of_user, (GFunc) g_object_unref, NULL); -- 1.7.3.4 ++++++ 0002-Add-no-debug-option-and-use-this-for-D-Bus-activation.diff ++++++ >From 3811e51b81320a574bb31aa64b6af56340012527 Mon Sep 17 00:00:00 2001 From: David Zeuthen <dav...@redhat.com> Date: Tue, 18 Oct 2011 13:13:16 -0400 Subject: [PATCH 2/3] Add --no-debug option and use this for D-Bus activation Signed-off-by: David Zeuthen <dav...@redhat.com> --- data/org.freedesktop.PolicyKit1.service.in | 2 +- src/polkitd/main.c | 27 ++++++++++++++++++++++++++- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/data/org.freedesktop.PolicyKit1.service.in b/data/org.freedesktop.PolicyKit1.service.in index 5a54ca1..b6cd02b 100644 --- a/data/org.freedesktop.PolicyKit1.service.in +++ b/data/org.freedesktop.PolicyKit1.service.in @@ -1,4 +1,4 @@ [D-BUS Service] Name=org.freedesktop.PolicyKit1 -Exec=@libexecdir@/polkitd +Exec=@libexecdir@/polkitd --no-debug User=root diff --git a/src/polkitd/main.c b/src/polkitd/main.c index 33ea511..b21723f 100644 --- a/src/polkitd/main.c +++ b/src/polkitd/main.c @@ -22,6 +22,9 @@ #include "config.h" #include <signal.h> + +#include <glib-unix.h> + #include <polkit/polkit.h> #include <polkitbackend/polkitbackend.h> @@ -33,8 +36,10 @@ static PolkitBackendAuthority *authority = NULL; static gpointer registration_id = NULL; static GMainLoop *loop = NULL; static gboolean opt_replace = FALSE; +static gboolean opt_no_debug = FALSE; static GOptionEntry opt_entries[] = { - {"replace", 0, 0, G_OPTION_ARG_NONE, &opt_replace, "Replace existing daemon", NULL}, + {"replace", 'r', 0, G_OPTION_ARG_NONE, &opt_replace, "Replace existing daemon", NULL}, + {"no-debug", 'n', 0, G_OPTION_ARG_NONE, &opt_no_debug, "Don't print debug information", NULL}, {NULL } }; @@ -120,6 +125,26 @@ main (int argc, goto out; } + /* If --no-debug is requested don't clutter stdout/stderr etc. + */ + if (opt_no_debug) + { + gint dev_null_fd; + dev_null_fd = open ("/dev/null", O_RDWR); + if (dev_null_fd >= 0) + { + dup2 (dev_null_fd, STDIN_FILENO); + dup2 (dev_null_fd, STDOUT_FILENO); + dup2 (dev_null_fd, STDERR_FILENO); + close (dev_null_fd); + } + else + { + g_warning ("Error opening /dev/null: %m"); + } + } + + loop = g_main_loop_new (NULL, FALSE); sigint_id = _g_posix_signal_watch_add (SIGINT, -- 1.7.3.4 ++++++ 0003-Bug-41025-Add-org.freedesktop.policykit.owner-annotat.diff ++++++ >From 5cd68a3aa8d5d0fdbbd3baef0601350bd43a0e4d Mon Sep 17 00:00:00 2001 From: David Zeuthen <dav...@redhat.com> Date: Tue, 18 Oct 2011 15:45:40 -0400 Subject: [PATCH 3/3] =?UTF-8?q?Bug=2041025=20=E2=80=93=20Add=20org.freedesktop.policykit.owner=20annotation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows daemons running as a designated uid to check authorizations. Based on a patch from Christopher James Halse Rogers <chalserog...@gmail.com>. https://bugs.freedesktop.org/show_bug.cgi?id=41025 Signed-off-by: David Zeuthen <dav...@redhat.com> --- docs/man/polkit.xml | 13 +++ .../polkitbackendinteractiveauthority.c | 81 +++++++++++++++++-- 2 files changed, 85 insertions(+), 9 deletions(-) diff --git a/docs/man/polkit.xml b/docs/man/polkit.xml index bfa5ccd..ae67f7c 100644 --- a/docs/man/polkit.xml +++ b/docs/man/polkit.xml @@ -417,6 +417,19 @@ System Context | | single lock button that should unlock multiple actions from distinct mechanisms. </para> + <para> + The <literal>org.freedesktop.policykit.owner</literal> + annotation can be used to define a set of users who can query + whether a client is authorized to perform this action. If this + annotation is not specified then only root can query whether a + client running as a different user is authorized for an action. + The value of this annotation is a string containing a space + separated list of <link + linkend="PolkitIdentity-struct">PolkitIdentity</link> entries, + for example <literal>"unix-user:42 unix-user:colord"</literal>. + A typical use of this annotation is for a daemon process that + runs as a system user rather than root. + </para> </refsect2> </refsect1> diff --git a/src/polkitbackend/polkitbackendinteractiveauthority.c b/src/polkitbackend/polkitbackendinteractiveauthority.c index 3566248..99c4782 100644 --- a/src/polkitbackend/polkitbackendinteractiveauthority.c +++ b/src/polkitbackend/polkitbackendinteractiveauthority.c @@ -749,6 +749,62 @@ polkit_backend_interactive_authority_check_authorization_finish (PolkitBackendAu return result; } +static gboolean +may_identity_check_authorization (PolkitBackendInteractiveAuthority *interactive_authority, + const gchar *action_id, + PolkitIdentity *identity) +{ + PolkitBackendInteractiveAuthorityPrivate *priv = POLKIT_BACKEND_INTERACTIVE_AUTHORITY_GET_PRIVATE (interactive_authority); + gboolean ret = FALSE; + PolkitActionDescription *action_desc = NULL; + const gchar *owners = NULL; + gchar **tokens = NULL; + guint n; + + /* uid 0 may check anything */ + if (POLKIT_IS_UNIX_USER (identity) && polkit_unix_user_get_uid (POLKIT_UNIX_USER (identity)) == 0) + { + ret = TRUE; + goto out; + } + + action_desc = polkit_backend_action_pool_get_action (priv->action_pool, action_id, NULL); + if (action_desc == NULL) + goto out; + + owners = polkit_action_description_get_annotation (action_desc, "org.freedesktop.policykit.owner"); + if (owners == NULL) + goto out; + + tokens = g_strsplit (owners, " ", 0); + for (n = 0; tokens != NULL && tokens[n] != NULL; n++) + { + PolkitIdentity *owner_identity; + GError *error = NULL; + owner_identity = polkit_identity_from_string (tokens[n], &error); + if (owner_identity == NULL) + { + g_warning ("Error parsing owner identity %d of action_id %s: %s (%s, %d)", + n, action_id, error->message, g_quark_to_string (error->domain), error->code); + g_error_free (error); + continue; + } + if (polkit_identity_equal (identity, owner_identity)) + { + ret = TRUE; + g_object_unref (owner_identity); + goto out; + } + g_object_unref (owner_identity); + } + + out: + g_clear_object (&action_desc); + g_strfreev (tokens); + + return ret; +} + static void polkit_backend_interactive_authority_check_authorization (PolkitBackendAuthority *authority, PolkitSubject *caller, @@ -851,22 +907,29 @@ polkit_backend_interactive_authority_check_authorization (PolkitBackendAuthority g_strfreev (detail_keys); } } + + /* Not anyone is allowed to check that process XYZ is allowed to do ABC. + * We only allow this if, and only if, + * + * - processes may check for another process owned by the *same* user but not + * if details are passed (otherwise you'd be able to spoof the dialog) + * + * - processes running as uid 0 may check anything and pass any details + * + * - if the action_id has the "org.freedesktop.policykit.owner" annotation + * then any uid referenced by that annotation is also allowed to check + * to check anything and pass any details + */ if (!polkit_identity_equal (user_of_caller, user_of_subject) || has_details) { - /* we only allow trusted callers (uid 0 + others) to check authorizations for subjects - * they don't own - and only if there are no details passed (to avoid spoofing dialogs). - * - * TODO: allow other uids like 'haldaemon'? - */ - if (!POLKIT_IS_UNIX_USER (user_of_caller) || - polkit_unix_user_get_uid (POLKIT_UNIX_USER (user_of_caller)) != 0) + if (!may_identity_check_authorization (interactive_authority, action_id, user_of_caller)) { if (has_details) { g_simple_async_result_set_error (simple, POLKIT_ERROR, POLKIT_ERROR_NOT_AUTHORIZED, - "Only trusted callers (e.g. uid 0) can use CheckAuthorization() and " + "Only trusted callers (e.g. uid 0 or an action owner) can use CheckAuthorization() and " "pass details"); } else @@ -874,7 +937,7 @@ polkit_backend_interactive_authority_check_authorization (PolkitBackendAuthority g_simple_async_result_set_error (simple, POLKIT_ERROR, POLKIT_ERROR_NOT_AUTHORIZED, - "Only trusted callers (e.g. uid 0) can use CheckAuthorization() for " + "Only trusted callers (e.g. uid 0 or an action owner) can use CheckAuthorization() for " "subjects belonging to other identities"); } g_simple_async_result_complete (simple); -- 1.7.3.4 -- To unsubscribe, e-mail: opensuse-commit+unsubscr...@opensuse.org For additional commands, e-mail: opensuse-commit+h...@opensuse.org