PolicyKit: Branch 'master'
David Zeuthen
david at kemper.freedesktop.org
Sat Nov 17 13:43:19 PST 2007
configure.in | 3
doc/man/polkit-action.xml | 104 +++++++++
policy/org.freedesktop.policykit.policy.in | 10
src/kit/kit-file.c | 6
src/kit/kit-spawn.c | 18 +
src/polkit-dbus/Makefile.am | 11 -
src/polkit-dbus/polkit-set-default-helper.c | 303 ++++++++++++++++++++++++++++
src/polkit/Makefile.am | 14 -
src/polkit/polkit-error.c | 3
src/polkit/polkit-error.h | 4
src/polkit/polkit-policy-default.c | 127 +++++++++++
src/polkit/polkit-policy-default.h | 13 +
src/polkit/polkit-policy-file-entry.c | 189 +++++++++++++++++
src/polkit/polkit-policy-file-entry.h | 6
tools/polkit-action.c | 253 ++++++++++++++++++++---
tools/polkit-bash-completion.sh | 30 +-
16 files changed, 1031 insertions(+), 63 deletions(-)
New commits:
commit f631d726602360d16dd8154f88a12754f3af0863
Author: David Zeuthen <davidz at redhat.com>
Date: Sat Nov 17 16:43:25 2007 -0500
add API for overriding defaults and make polkit-action(1) use this API.
diff --git a/configure.in b/configure.in
index 1c8cff9..cfc4b98 100644
--- a/configure.in
+++ b/configure.in
@@ -530,6 +530,9 @@ if test "${POLKIT_AUTHDB}" = default ; then
echo "NOTE: The directories ${localstatedir}/run/PolicyKit and ${localstatedir}/lib/PolicyKit will be"
echo " owned by group ${POLKIT_GROUP} and will be mode 770."
echo
+ echo "NOTE: The directory ${localstatedir}/run/PolicyKit-public will be"
+ echo " owned by group ${POLKIT_GROUP} and will be mode 775."
+ echo
echo "NOTE: ${libexecdir}/polkit-read-auth-helper will be owned by"
echo " group ${POLKIT_GROUP} and installed with mode 2755 (setgid binary)."
echo
diff --git a/doc/man/polkit-action.xml b/doc/man/polkit-action.xml
index 430717c..3d1cc29 100644
--- a/doc/man/polkit-action.xml
+++ b/doc/man/polkit-action.xml
@@ -13,13 +13,18 @@
<refnamediv>
<refname>polkit-action</refname>
- <refpurpose>List registered PolicyKit actions</refpurpose>
+ <refpurpose>List and modify registered PolicyKit actions</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>polkit-action</command>
<arg><option>--action <replaceable>action</replaceable></option></arg>
+ <arg><option>--reset-defaults <replaceable>action</replaceable></option></arg>
+ <arg><option>--show-overrides</option></arg>
+ <arg><option>--set-defaults-any <replaceable>action</replaceable> <replaceable>value</replaceable></option></arg>
+ <arg><option>--set-defaults-inactive <replaceable>action</replaceable> <replaceable>value</replaceable></option></arg>
+ <arg><option>--set-defaults-active <replaceable>action</replaceable> <replaceable>value</replaceable></option></arg>
<arg><option>--version</option></arg>
<arg><option>--help</option></arg>
</cmdsynopsis>
@@ -28,8 +33,8 @@
<refsect1>
<title>DESCRIPTION</title>
<para>
- polkit-action is used to list the PolicyKit actions that are
- registered on the system.
+ polkit-action is used to list and modify the PolicyKit actions
+ that are registered on the system.
</para>
</refsect1>
@@ -44,6 +49,93 @@
</para>
</listitem>
</varlistentry>
+
+ <varlistentry>
+ <term><option>--reset-defaults <replaceable>action</replaceable></option></term>
+ <listitem>
+ <para>
+ Reset the defaults for the specified action to the factory
+ defaults. The authorization needed to do this is
+ <emphasis>org.freedesktop.policykit.modify-defaults</emphasis>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--show-overrides</option></term>
+ <listitem>
+ <para>
+ Prints all actions for where the defaults are overridden.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--set-defaults-any <replaceable>action</replaceable> <replaceable>value</replaceable></option></term>
+ <listitem>
+ <para>
+ Override the <emphasis>any</emphasis> stanza for the given
+ action with the supplied value. The authorization needed
+ to do this is <emphasis>org.freedesktop.policykit.modify-defaults</emphasis>.
+ Valid values for <emphasis>value</emphasis> are
+ <emphasis>no</emphasis>,
+ <emphasis>auth_admin_one_shot</emphasis>,
+ <emphasis>auth_admin</emphasis>,
+ <emphasis>auth_admin_keep_session</emphasis>,
+ <emphasis>auth_admin_keep_always</emphasis>,
+ <emphasis>auth_self_one_shot</emphasis>,
+ <emphasis>auth_self</emphasis>,
+ <emphasis>auth_self_keep_session</emphasis>,
+ <emphasis>auth_self_keep_always</emphasis>,
+ and <emphasis>yes</emphasis>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--set-defaults-inactive <replaceable>action</replaceable> <replaceable>value</replaceable></option></term>
+ <listitem>
+ <para>
+ Override the <emphasis>inactive</emphasis> stanza for the given
+ action with the supplied value. The authorization needed
+ to do this is <emphasis>org.freedesktop.policykit.modify-defaults</emphasis>.
+ Valid values for <emphasis>value</emphasis> are
+ <emphasis>no</emphasis>,
+ <emphasis>auth_admin_one_shot</emphasis>,
+ <emphasis>auth_admin</emphasis>,
+ <emphasis>auth_admin_keep_session</emphasis>,
+ <emphasis>auth_admin_keep_always</emphasis>,
+ <emphasis>auth_self_one_shot</emphasis>,
+ <emphasis>auth_self</emphasis>,
+ <emphasis>auth_self_keep_session</emphasis>,
+ <emphasis>auth_self_keep_always</emphasis>,
+ and <emphasis>yes</emphasis>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--set-defaults-active <replaceable>action</replaceable> <replaceable>value</replaceable></option></term>
+ <listitem>
+ <para>
+ Override the <emphasis>active</emphasis> stanza for the given
+ action with the supplied value. The authorization needed
+ to do this is <emphasis>org.freedesktop.policykit.modify-defaults</emphasis>.
+ Valid values for <emphasis>value</emphasis> are
+ <emphasis>no</emphasis>,
+ <emphasis>auth_admin_one_shot</emphasis>,
+ <emphasis>auth_admin</emphasis>,
+ <emphasis>auth_admin_keep_session</emphasis>,
+ <emphasis>auth_admin_keep_always</emphasis>,
+ <emphasis>auth_self_one_shot</emphasis>,
+ <emphasis>auth_self</emphasis>,
+ <emphasis>auth_self_keep_session</emphasis>,
+ <emphasis>auth_self_keep_always</emphasis>,
+ and <emphasis>yes</emphasis>.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><option>--version</option></term>
@@ -69,12 +161,12 @@
<title>COMPLETION</title>
<para>
PolicyKit ships with a collection of shell functions such that
- completion on actions works when using the
+ completion on options, <emphasis>action</emphasis>
+ and <emphasis>value</emphasis> works when using the
<citerefentry>
<refentrytitle>bash</refentrytitle><manvolnum>1</manvolnum>
</citerefentry>
- shell. For polkit-action, completion is enabled for
- the <option>--action</option> argument.
+ shell.
</para>
</refsect1>
diff --git a/policy/org.freedesktop.policykit.policy.in b/policy/org.freedesktop.policykit.policy.in
index efbeaeb..14e7af6 100644
--- a/policy/org.freedesktop.policykit.policy.in
+++ b/policy/org.freedesktop.policykit.policy.in
@@ -46,4 +46,14 @@ file are instantly applied.
</defaults>
</action>
+ <action id="org.freedesktop.policykit.modify-defaults">
+ <_description>Modify defaults for implicit authorizations</_description>
+ <_message>Authentication is required to modify the defaults for implicit authorizations</_message>
+ <defaults>
+ <allow_any>no</allow_any>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>auth_admin_keep_always</allow_active>
+ </defaults>
+ </action>
+
</policyconfig>
diff --git a/src/kit/kit-file.c b/src/kit/kit-file.c
index 832e058..f6b53c8 100644
--- a/src/kit/kit-file.c
+++ b/src/kit/kit-file.c
@@ -60,7 +60,8 @@
* Reads an entire file into allocated memory.
*
* Returns: #TRUE if the file was read into memory; #FALSE if an error
- * occured and errno will be set.
+ * occured and errno will be set. On OOM, errno will be set to
+ * ENOMEM. If the file doesn't exist, errno will be set to ENOENT.
*/
kit_bool_t
kit_file_get_contents (const char *path, char **out_contents, size_t *out_contents_size)
@@ -81,9 +82,10 @@ kit_file_get_contents (const char *path, char **out_contents, size_t *out_conten
fd = -1;
ret = FALSE;
*out_contents = NULL;
+ p = NULL;
fd = open (path, O_RDONLY);
- if (fd == 0)
+ if (fd == -1)
goto out;
p = kit_malloc (BUF_SIZE);
diff --git a/src/kit/kit-spawn.c b/src/kit/kit-spawn.c
index fb4be3e..9fe7739 100644
--- a/src/kit/kit-spawn.c
+++ b/src/kit/kit-spawn.c
@@ -198,23 +198,27 @@ kit_spawn_sync (const char *working_directory,
envp_to_use = environ;
if (stdin != NULL) {
- if (pipe (stdin_pipe) != 0)
+ if (pipe (stdin_pipe) != 0) {
goto out;
+ }
}
if (stdout != NULL) {
- if (pipe (stdout_pipe) != 0)
+ if (pipe (stdout_pipe) != 0) {
goto out;
+ }
}
if (stderr != NULL) {
- if (pipe (stderr_pipe) != 0)
+ if (pipe (stderr_pipe) != 0) {
goto out;
+ }
}
pid = fork ();
- if (pid == -1)
+ if (pid == -1) {
goto out;
+ }
if (pid == 0) {
/* child */
@@ -326,6 +330,7 @@ kit_spawn_sync (const char *working_directory,
NULL);
if (ret < 0 && errno != EINTR) {
+ kit_warning ("4");
goto out;
}
@@ -333,6 +338,7 @@ kit_spawn_sync (const char *working_directory,
num_written = _write_to (stdin_pipe[1], wp);
if (num_written == -1) {
+ kit_warning ("3");
goto out;
}
@@ -349,6 +355,7 @@ kit_spawn_sync (const char *working_directory,
close (stdout_pipe[0]);
stdout_pipe[0] = -1;
} else if (num_read == -1) {
+ kit_warning ("2");
goto out;
}
}
@@ -359,12 +366,14 @@ kit_spawn_sync (const char *working_directory,
close (stderr_pipe[0]);
stderr_pipe[0] = -1;
} else if (num_read == -1) {
+ kit_warning ("1");
goto out;
}
}
}
if (waitpid (pid, out_exit_status, 0) == -1) {
+ kit_warning ("0");
goto out;
}
pid = -1;
@@ -377,6 +386,7 @@ kit_spawn_sync (const char *working_directory,
} else {
ret = FALSE;
errno = WEXITSTATUS (*out_exit_status) - 128;
+ kit_warning ("kiddo died with errno %d: %m!", errno);
}
out:
diff --git a/src/polkit-dbus/Makefile.am b/src/polkit-dbus/Makefile.am
index e9b5f9a..6c5a165 100644
--- a/src/polkit-dbus/Makefile.am
+++ b/src/polkit-dbus/Makefile.am
@@ -28,19 +28,28 @@ libpolkit_dbus_la_LIBADD = @DBUS_LIBS@ $(top_builddir)/src/polkit/libpolkit.la $
libpolkit_dbus_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
if POLKIT_AUTHDB_DEFAULT
-libexec_PROGRAMS = polkit-read-auth-helper
+libexec_PROGRAMS = polkit-read-auth-helper polkit-set-default-helper
polkit_read_auth_helper_SOURCES = polkit-read-auth-helper.c
polkit_read_auth_helper_CFLAGS = @DBUS_CFLAGS@
polkit_read_auth_helper_LDADD = $(top_builddir)/src/polkit/libpolkit.la libpolkit-dbus.la
+polkit_set_default_helper_SOURCES = polkit-set-default-helper.c
+polkit_set_default_helper_CFLAGS = @DBUS_CFLAGS@
+polkit_set_default_helper_LDADD = $(top_builddir)/src/polkit/libpolkit.la libpolkit-dbus.la
+
# polkit-read-auth-helper needs to be setgid $POLKIT_GROUP to be able
# to read authorization files in /var/lib/PolicyKit and
# /var/run/PolicyKit
#
+# polkit-set-default-helper needs to be setgid $POLKIT_GROUP to be able
+# to write .override files in /var/lib/PolicyKit-public
+#
install-exec-hook:
-chgrp $(POLKIT_GROUP) $(DESTDIR)$(libexecdir)/polkit-read-auth-helper
-chmod 2755 $(DESTDIR)$(libexecdir)/polkit-read-auth-helper
+ -chgrp $(POLKIT_GROUP) $(DESTDIR)$(libexecdir)/polkit-set-default-helper
+ -chmod 2755 $(DESTDIR)$(libexecdir)/polkit-set-default-helper
endif
## note that TESTS has special meaning (stuff to use in make check)
diff --git a/src/polkit-dbus/polkit-set-default-helper.c b/src/polkit-dbus/polkit-set-default-helper.c
new file mode 100644
index 0000000..ffaaa2a
--- /dev/null
+++ b/src/polkit-dbus/polkit-set-default-helper.c
@@ -0,0 +1,303 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/***************************************************************************
+ *
+ * polkit-set-default-helper.c : setgid polkituser helper for PolicyKit
+ * to set defaults
+ *
+ * Copyright (C) 2007 David Zeuthen, <david at fubar.dk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ **************************************************************************/
+
+#define _GNU_SOURCE
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <security/pam_appl.h>
+#include <grp.h>
+#include <pwd.h>
+#include <syslog.h>
+#include <errno.h>
+#include <string.h>
+#include <utime.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <utime.h>
+
+#include <polkit/polkit-private.h>
+#include <polkit-dbus/polkit-dbus.h>
+
+static polkit_bool_t
+check_for_auth (uid_t caller_uid, pid_t caller_pid)
+{
+ polkit_bool_t ret;
+ DBusError error;
+ DBusConnection *bus;
+ PolKitCaller *caller;
+ PolKitAction *action;
+ PolKitContext *context;
+ PolKitError *pk_error;
+ PolKitResult pk_result;
+
+ ret = FALSE;
+
+ dbus_error_init (&error);
+ bus = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
+ if (bus == NULL) {
+ fprintf (stderr, "polkit-set-default-helper: cannot connect to system bus: %s: %s\n",
+ error.name, error.message);
+ dbus_error_free (&error);
+ goto out;
+ }
+
+ caller = polkit_caller_new_from_pid (bus, caller_pid, &error);
+ if (caller == NULL) {
+ fprintf (stderr, "polkit-set-default-helper: cannot get caller from pid: %s: %s\n",
+ error.name, error.message);
+ goto out;
+ }
+
+ action = polkit_action_new ();
+ if (action == NULL) {
+ fprintf (stderr, "polkit-set-default-helper: cannot allocate PolKitAction\n");
+ goto out;
+ }
+
+ if (!polkit_action_set_action_id (action, "org.freedesktop.policykit.modify-defaults")) {
+ fprintf (stderr, "polkit-set-default-helper: cannot set action_id\n");
+ goto out;
+ }
+
+ context = polkit_context_new ();
+ if (context == NULL) {
+ fprintf (stderr, "polkit-set-default-helper: cannot allocate PolKitContext\n");
+ goto out;
+ }
+
+ pk_error = NULL;
+ if (!polkit_context_init (context, &pk_error)) {
+ fprintf (stderr, "polkit-set-default-helper: cannot initialize polkit context: %s: %s\n",
+ polkit_error_get_error_name (pk_error),
+ polkit_error_get_error_message (pk_error));
+ polkit_error_free (pk_error);
+ goto out;
+ }
+
+ pk_result = polkit_context_is_caller_authorized (context, action, caller, TRUE, &pk_error);
+ if (polkit_error_is_set (pk_error)) {
+
+ fprintf (stderr, "polkit-set-default-helper: cannot determine if caller is authorized: %s: %s\n",
+ polkit_error_get_error_name (pk_error),
+ polkit_error_get_error_message (pk_error));
+ polkit_error_free (pk_error);
+ goto out;
+ }
+
+ if (pk_result != POLKIT_RESULT_YES) {
+ goto out;
+ }
+
+ ret = TRUE;
+out:
+
+ return ret;
+}
+
+static polkit_bool_t
+set_default (const char *action_id, const char *any, const char *inactive, const char *active)
+{
+ char *path;
+ char *contents;
+ polkit_bool_t ret;
+
+ path = NULL;
+ contents = NULL;
+ ret = FALSE;
+
+ path = kit_strdup_printf (PACKAGE_LOCALSTATE_DIR "/lib/PolicyKit-public/%s.override", action_id);
+ if (path == NULL)
+ goto out;
+
+ contents = kit_strdup_printf ("%s:%s:%s",
+ any, inactive, active);
+ if (contents == NULL)
+ goto out;
+
+ if (!kit_file_set_contents (path, 0464, contents, strlen (contents))) {
+ kit_warning ("Error writing override file '%s': %m\n", path);
+ goto out;
+ }
+
+ ret = TRUE;
+
+out:
+ if (path == NULL)
+ kit_free (path);
+ if (contents == NULL)
+ kit_free (contents);
+ return ret;
+}
+
+static polkit_bool_t
+clear_default (const char *action_id)
+{
+ char *path;
+ polkit_bool_t ret;
+
+ ret = FALSE;
+
+ path = kit_strdup_printf (PACKAGE_LOCALSTATE_DIR "/lib/PolicyKit-public/%s.override", action_id);
+ if (path == NULL)
+ goto out;
+
+ if (unlink (path) != 0) {
+ kit_warning ("Error unlinking file %s: %m", path);
+ }
+
+ ret = TRUE;
+
+out:
+ if (path == NULL)
+ kit_free (path);
+ return ret;
+
+}
+
+int
+main (int argc, char *argv[])
+{
+ int ret;
+ gid_t egid;
+ struct group *group;
+ uid_t caller_uid;
+ struct passwd *pw;
+ uid_t uid_for_polkit_user;
+
+ ret = 1;
+ /* clear the entire environment to avoid attacks using with libraries honoring environment variables */
+ if (clearenv () != 0)
+ goto out;
+ /* set a minimal environment */
+ setenv ("PATH", "/usr/sbin:/usr/bin:/sbin:/bin", 1);
+
+ openlog ("polkit-set-default-helper", LOG_CONS | LOG_PID, LOG_AUTHPRIV);
+
+ /* check for correct invocation */
+ if (! (argc == 3 || argc == 6)) {
+ syslog (LOG_NOTICE, "inappropriate use of helper, wrong number of arguments [uid=%d]", getuid ());
+ fprintf (stderr, "polkit-set-default-helper: wrong number of arguments. This incident has been logged.\n");
+ goto out;
+ }
+
+ caller_uid = getuid ();
+
+ /* check we're running with a non-tty stdin */
+ if (isatty (STDIN_FILENO) != 0) {
+ syslog (LOG_NOTICE, "inappropriate use of helper, stdin is a tty [uid=%d]", getuid ());
+ fprintf (stderr, "polkit-set-default-helper: inappropriate use of helper, stdin is a tty. This incident has been logged.\n");
+ goto out;
+ }
+
+ /* check that we are setgid polkituser */
+ egid = getegid ();
+ group = getgrgid (egid);
+ if (group == NULL) {
+ fprintf (stderr, "polkit-set-default-helper: cannot lookup group info for gid %d\n", egid);
+ goto out;
+ }
+ if (strcmp (group->gr_name, POLKIT_GROUP) != 0) {
+ fprintf (stderr, "polkit-set-default-helper: needs to be setgid " POLKIT_GROUP "\n");
+ goto out;
+ }
+
+ pw = getpwnam (POLKIT_USER);
+ if (pw == NULL) {
+ fprintf (stderr, "polkit-set-default-helper: cannot lookup uid for " POLKIT_USER "\n");
+ goto out;
+ }
+ uid_for_polkit_user = pw->pw_uid;
+
+ /*----------------------------------------------------------------------------------------------------*/
+
+ /* uid 0 is allowed to set anything */
+ if (caller_uid != 0) {
+ /* see if calling user has the
+ *
+ * org.freedesktop.policykit.modify-defaults
+ *
+ * authorization
+ */
+ if (!check_for_auth (caller_uid, getppid ())) {
+ goto out;
+ }
+ }
+
+ PolKitResult any;
+ PolKitResult inactive;
+ PolKitResult active;
+
+ if (!polkit_action_validate_id (argv[1])) {
+ goto out;
+ }
+
+ /* sanity check */
+ if (argc == 3) {
+ if (strcmp (argv[2], "clear") != 0)
+ goto out;
+
+ if (!clear_default (argv[1]))
+ goto out;
+ } else if (argc == 6) {
+ if (strcmp (argv[2], "set") != 0)
+ goto out;
+
+ if (!polkit_result_from_string_representation (argv[3], &any)) {
+ goto out;
+ }
+ if (!polkit_result_from_string_representation (argv[4], &inactive)) {
+ goto out;
+ }
+ if (!polkit_result_from_string_representation (argv[5], &active)) {
+ goto out;
+ }
+
+ if (!set_default (argv[1], argv[3], argv[4], argv[5]))
+ goto out;
+ } else {
+ goto out;
+ }
+
+ /* trigger a reload */
+ if (utimes (PACKAGE_LOCALSTATE_DIR "/lib/misc/PolicyKit.reload", NULL) != 0) {
+ kit_warning ("Error updating access+modification time on file '%s': %m\n",
+ PACKAGE_LOCALSTATE_DIR "/lib/misc/PolicyKit.reload");
+ }
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
diff --git a/src/polkit/Makefile.am b/src/polkit/Makefile.am
index f1d2273..caba5e0 100644
--- a/src/polkit/Makefile.am
+++ b/src/polkit/Makefile.am
@@ -125,20 +125,26 @@ if POLKIT_AUTHDB_DEFAULT
# polkit-auth-read-helper is used to read it) and the $POLKIT_GROUP
# group needs to be able to write files there.
#
+# The /var/lib/PolicyKit-public is used for storing world-readable
+# information. Only $POLKIT_GROUP may write to it.
+#
# The /var/lib/misc/PolicyKit.reload file is used for triggering that
# authorizations have changed; it needs to be world readable and
# writeable for the $POLKIT_GROUP group (FHS 2.3 suggests that
# location)
#
install-data-local:
- -mkdir -p $(DESTDIR)$(localstatedir)/lib/misc
- -touch $(DESTDIR)$(localstatedir)/lib/misc/PolicyKit.reload
+ mkdir -p $(DESTDIR)$(localstatedir)/lib/misc
+ touch $(DESTDIR)$(localstatedir)/lib/misc/PolicyKit.reload
-chgrp $(POLKIT_GROUP) $(DESTDIR)$(localstatedir)/lib/misc/PolicyKit.reload
-chmod 775 $(DESTDIR)$(localstatedir)/lib/misc/PolicyKit.reload
- -mkdir -p $(DESTDIR)$(localstatedir)/lib/PolicyKit
- -mkdir -p $(DESTDIR)$(localstatedir)/run/PolicyKit
+ mkdir -p $(DESTDIR)$(localstatedir)/lib/PolicyKit-public
+ mkdir -p $(DESTDIR)$(localstatedir)/lib/PolicyKit
+ mkdir -p $(DESTDIR)$(localstatedir)/run/PolicyKit
+ -chgrp $(POLKIT_GROUP) $(DESTDIR)$(localstatedir)/lib/PolicyKit-public
-chgrp $(POLKIT_GROUP) $(DESTDIR)$(localstatedir)/lib/PolicyKit
-chgrp $(POLKIT_GROUP) $(DESTDIR)$(localstatedir)/run/PolicyKit
+ -chmod 775 $(DESTDIR)$(localstatedir)/lib/PolicyKit-public
-chmod 770 $(DESTDIR)$(localstatedir)/lib/PolicyKit
-chmod 770 $(DESTDIR)$(localstatedir)/run/PolicyKit
endif
diff --git a/src/polkit/polkit-error.c b/src/polkit/polkit-error.c
index e7105db..0d8d792 100644
--- a/src/polkit/polkit-error.c
+++ b/src/polkit/polkit-error.c
@@ -86,7 +86,8 @@ static const char *error_names[POLKIT_ERROR_NUM_ERROR_CODES] = {
"NotAuthorizedToRevokeAuthorizationsFromOtherUsers",
"NotAuthorizedToGrantAuthorization",
"AuthorizationAlreadyExists",
- "NotSupported"
+ "NotSupported",
+ "NotAuthorizedToModifyDefaults",
};
/**
diff --git a/src/polkit/polkit-error.h b/src/polkit/polkit-error.h
index 472d670..4b47552 100644
--- a/src/polkit/polkit-error.h
+++ b/src/polkit/polkit-error.h
@@ -54,6 +54,9 @@ POLKIT_BEGIN_DECLS
* similar authorization already (modulo time of grant and who granted).
* @POLKIT_ERROR_NOT_SUPPORTED: The operation is not supported by the
* authorization database backend
+ * @POLKIT_ERROR_NOT_AUTHORIZED_TO_MODIFY_DEFAULTS: An attempt was
+ * made to modify the defaults for implicit authorizations and the
+ * calling process is not authorized.
* @POLKIT_ERROR_NUM_ERROR_CODES: Number of error codes. This may change
* from version to version; do not rely on it.
*
@@ -69,6 +72,7 @@ typedef enum
POLKIT_ERROR_NOT_AUTHORIZED_TO_GRANT_AUTHORIZATION,
POLKIT_ERROR_AUTHORIZATION_ALREADY_EXISTS,
POLKIT_ERROR_NOT_SUPPORTED,
+ POLKIT_ERROR_NOT_AUTHORIZED_TO_MODIFY_DEFAULTS,
POLKIT_ERROR_NUM_ERROR_CODES
} PolKitErrorCode;
diff --git a/src/polkit/polkit-policy-default.c b/src/polkit/polkit-policy-default.c
index c1e8173..7590b16 100644
--- a/src/polkit/polkit-policy-default.c
+++ b/src/polkit/polkit-policy-default.c
@@ -65,6 +65,88 @@ struct _PolKitPolicyDefault
PolKitResult default_active;
};
+/**
+ * polkit_policy_default_new:
+ *
+ * Construct a new object with all defaults set as restrictive as possible.
+ *
+ * Returns: a new object or #NULL on OOM.
+ *
+ * Since: 0.7
+ */
+PolKitPolicyDefault *
+polkit_policy_default_new (void)
+{
+ PolKitPolicyDefault *pd;
+
+ pd = kit_new0 (PolKitPolicyDefault, 1);
+ if (pd == NULL)
+ goto out;
+ pd->refcount = 1;
+ pd->default_any = POLKIT_RESULT_NO;
+ pd->default_inactive = POLKIT_RESULT_NO;
+ pd->default_active = POLKIT_RESULT_NO;
+out:
+ return pd;
+}
+
+/**
+ * polkit_policy_default_clone:
+ * @policy_default: object to clone
+ *
+ * Create a new object with the same value as the given object
+ *
+ * Returns: a new object or #NULL on OOM.
+ *
+ * Since: 0.7
+ */
+PolKitPolicyDefault *
+polkit_policy_default_clone (PolKitPolicyDefault *policy_default)
+{
+ PolKitPolicyDefault *pd;
+
+ kit_return_val_if_fail (policy_default != NULL, NULL);
+
+ pd = polkit_policy_default_new ();
+ if (pd == NULL)
+ goto out;
+ pd->refcount = 1;
+ pd->default_any = policy_default->default_any;
+ pd->default_inactive = policy_default->default_inactive;
+ pd->default_active = policy_default->default_active;
+out:
+ return pd;
+}
+
+
+/**
+ * polkit_policy_default_equals:
+ * @a: a #PolKitPolicyDefault object
+ * @b: a #PolKitPolicyDefault object
+ *
+ * Compare if two objects are equal.
+ *
+ * Returns: %TRUE only if the objects are equal
+ */
+polkit_bool_t
+polkit_policy_default_equals (PolKitPolicyDefault *a, PolKitPolicyDefault *b)
+{
+ polkit_bool_t ret;
+
+ kit_return_val_if_fail (a != NULL, FALSE);
+ kit_return_val_if_fail (b != NULL, FALSE);
+
+ if (a->default_any == b->default_any &&
+ a->default_inactive == b->default_inactive &&
+ a->default_active == b->default_active) {
+ ret = TRUE;
+ } else {
+ ret = FALSE;
+ }
+
+ return ret;
+}
+
PolKitPolicyDefault *
_polkit_policy_default_new (PolKitResult defaults_allow_any,
PolKitResult defaults_allow_inactive,
@@ -233,6 +315,51 @@ out:
}
/**
+ * polkit_policy_default_set_allow_any:
+ * @policy_default: the object
+ * @value: the value to set
+ *
+ * Set default policy.
+ *
+ **/
+void
+polkit_policy_default_set_allow_any (PolKitPolicyDefault *policy_default, PolKitResult value)
+{
+ kit_return_if_fail (policy_default != NULL);
+ policy_default->default_any = value;
+}
+
+/**
+ * polkit_policy_default_set_allow_inactive:
+ * @policy_default: the object
+ * @value: the value to set
+ *
+ * Set default policy.
+ *
+ **/
+void
+polkit_policy_default_set_allow_inactive (PolKitPolicyDefault *policy_default, PolKitResult value)
+{
+ kit_return_if_fail (policy_default != NULL);
+ policy_default->default_inactive = value;
+}
+
+/**
+ * polkit_policy_default_set_allow_active:
+ * @policy_default: the object
+ * @value: the value to set
+ *
+ * Set default policy.
+ *
+ **/
+void
+polkit_policy_default_set_allow_active (PolKitPolicyDefault *policy_default, PolKitResult value)
+{
+ kit_return_if_fail (policy_default != NULL);
+ policy_default->default_active = value;
+}
+
+/**
* polkit_policy_default_get_allow_any:
* @policy_default: the object
*
diff --git a/src/polkit/polkit-policy-default.h b/src/polkit/polkit-policy-default.h
index a9f6146..3da429d 100644
--- a/src/polkit/polkit-policy-default.h
+++ b/src/polkit/polkit-policy-default.h
@@ -42,9 +42,13 @@ POLKIT_BEGIN_DECLS
struct _PolKitPolicyDefault;
typedef struct _PolKitPolicyDefault PolKitPolicyDefault;
+PolKitPolicyDefault *polkit_policy_default_new (void);
PolKitPolicyDefault *polkit_policy_default_ref (PolKitPolicyDefault *policy_default);
void polkit_policy_default_unref (PolKitPolicyDefault *policy_default);
void polkit_policy_default_debug (PolKitPolicyDefault *policy_default);
+PolKitPolicyDefault *polkit_policy_default_clone (PolKitPolicyDefault *policy_default);
+
+polkit_bool_t polkit_policy_default_equals (PolKitPolicyDefault *a, PolKitPolicyDefault *b);
PolKitResult polkit_policy_default_can_session_do_action (PolKitPolicyDefault *policy_default,
PolKitAction *action,
@@ -54,9 +58,14 @@ PolKitResult polkit_policy_default_can_caller_do_action (PolKitPolicyDefault *po
PolKitAction *action,
PolKitCaller *caller);
-PolKitResult polkit_policy_default_get_allow_any (PolKitPolicyDefault *policy_default);
+PolKitResult polkit_policy_default_get_allow_any (PolKitPolicyDefault *policy_default);
PolKitResult polkit_policy_default_get_allow_inactive (PolKitPolicyDefault *policy_default);
-PolKitResult polkit_policy_default_get_allow_active (PolKitPolicyDefault *policy_default);
+PolKitResult polkit_policy_default_get_allow_active (PolKitPolicyDefault *policy_default);
+
+void polkit_policy_default_set_allow_any (PolKitPolicyDefault *policy_default, PolKitResult value);
+void polkit_policy_default_set_allow_inactive (PolKitPolicyDefault *policy_default, PolKitResult value);
+void polkit_policy_default_set_allow_active (PolKitPolicyDefault *policy_default, PolKitResult value);
+
/* TODO: export knobs for "default policy" */
diff --git a/src/polkit/polkit-policy-file-entry.c b/src/polkit/polkit-policy-file-entry.c
index 13ddd31..19aa39e 100644
--- a/src/polkit/polkit-policy-file-entry.c
+++ b/src/polkit/polkit-policy-file-entry.c
@@ -31,6 +31,7 @@
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
+#include <sys/wait.h>
#include <pwd.h>
#include <grp.h>
#include <unistd.h>
@@ -63,6 +64,7 @@ struct _PolKitPolicyFileEntry
{
int refcount;
char *action;
+ PolKitPolicyDefault *defaults_factory;
PolKitPolicyDefault *defaults;
char *policy_description;
@@ -79,9 +81,15 @@ _polkit_policy_file_entry_new (const char *action_id,
PolKitResult defaults_allow_active,
KitHash *annotations)
{
+ char *path;
+ char *contents;
+ size_t contents_size;
PolKitPolicyFileEntry *pfe;
- kit_return_val_if_fail (action_id != NULL, NULL);
+ path = NULL;
+ contents = NULL;
+
+ kit_return_val_if_fail (action_id != NULL && polkit_action_validate_id (action_id), NULL);
pfe = kit_new0 (PolKitPolicyFileEntry, 1);
if (pfe == NULL)
@@ -100,16 +108,65 @@ _polkit_policy_file_entry_new (const char *action_id,
defaults_allow_active = POLKIT_RESULT_NO;
}
- pfe->defaults = _polkit_policy_default_new (defaults_allow_any,
- defaults_allow_inactive,
- defaults_allow_active);
+ pfe->defaults_factory = _polkit_policy_default_new (defaults_allow_any,
+ defaults_allow_inactive,
+ defaults_allow_active);
+ if (pfe->defaults_factory == NULL)
+ goto error;
+
+ pfe->defaults = polkit_policy_default_clone (pfe->defaults_factory);
if (pfe->defaults == NULL)
goto error;
+ /* read override file */
+ path = kit_strdup_printf (PACKAGE_LOCALSTATE_DIR "/lib/PolicyKit-public/%s.override", action_id);
+ if (path == NULL)
+ goto error;
+ if (!kit_file_get_contents (path, &contents, &contents_size)) {
+ /* it's not a failure if the file doesn't exist */
+ if (errno != ENOENT)
+ goto error;
+
+ errno = 0;
+ contents = NULL;
+ }
+
+ if (contents != NULL) {
+ char **tokens;
+ size_t num_tokens;
+ PolKitResult any;
+ PolKitResult inactive;
+ PolKitResult active;
+
+ tokens = kit_strsplit (contents, ':', &num_tokens);
+ if (num_tokens != 3)
+ goto error;
+
+ if (!polkit_result_from_string_representation (tokens[0], &any)) {
+ goto error;
+ }
+ if (!polkit_result_from_string_representation (tokens[1], &inactive)) {
+ goto error;
+ }
+ if (!polkit_result_from_string_representation (tokens[2], &active)) {
+ goto error;
+ }
+
+ polkit_policy_default_set_allow_any (pfe->defaults, any);
+ polkit_policy_default_set_allow_inactive (pfe->defaults, inactive);
+ polkit_policy_default_set_allow_active (pfe->defaults, active);
+ }
+
+
pfe->annotations = annotations;
+ kit_free (path);
+ kit_free (contents);
+
return pfe;
error:
+ kit_free (path);
+ kit_free (contents);
if (pfe != NULL)
polkit_policy_file_entry_unref (pfe);
return NULL;
@@ -218,6 +275,9 @@ polkit_policy_file_entry_unref (PolKitPolicyFileEntry *policy_file_entry)
kit_free (policy_file_entry->action);
+ if (policy_file_entry->defaults_factory != NULL)
+ polkit_policy_default_unref (policy_file_entry->defaults_factory);
+
if (policy_file_entry->defaults != NULL)
polkit_policy_default_unref (policy_file_entry->defaults);
@@ -267,7 +327,7 @@ polkit_policy_file_entry_get_id (PolKitPolicyFileEntry *policy_file_entry)
*
* Get the the default policy for this policy.
*
- * Returns: A #PolKitPolicyDefault object - caller shall not unref this object.
+ * Returns: A #PolKitPolicyDefault object - caller shall not unref or modify this object.
**/
PolKitPolicyDefault *
polkit_policy_file_entry_get_default (PolKitPolicyFileEntry *policy_file_entry)
@@ -276,6 +336,125 @@ polkit_policy_file_entry_get_default (PolKitPolicyFileEntry *policy_file_entry)
return policy_file_entry->defaults;
}
+/**
+ * polkit_policy_file_entry_get_default_factory:
+ * @policy_file_entry: the file entry
+ *
+ * Get the factory defaults for the entry. This may be different that
+ * what polkit_policy_file_entry_get_default() returns if the function
+ * polkit_policy_file_entry_set_default() have been used to change the
+ * defaults.
+ *
+ * Returns: A #PolKitPolicyDefault object - caller shall not unref or modify this object.
+ *
+ * Since: 0.7
+ */
+PolKitPolicyDefault *
+polkit_policy_file_entry_get_default_factory (PolKitPolicyFileEntry *policy_file_entry)
+{
+ kit_return_val_if_fail (policy_file_entry != NULL, NULL);
+ return policy_file_entry->defaults_factory;
+}
+
+/**
+ * polkit_policy_file_entry_set_default:
+ * @policy_file_entry: the file entry
+ * @defaults: the new defaults to set
+ * @error: return location for error or #NULL
+ *
+ * Set new defaults for a given policy file entry; subsequent calls to
+ * polkit_policy_file_get_default() will return these values. Note
+ * that the old defaults are not modified; they are still available via
+ * polkit_policy_file_entry_get_default_factory().
+ *
+ * This operation requires the
+ * org.freedesktop.policykit.modify-defaults authorization and will
+ * fail if the caller lacks it.
+ *
+ * Returns: %TRUE if the given defaults was set; %FALSE if @error is set.
+ *
+ * Since: 0.7
+ */
+polkit_bool_t
+polkit_policy_file_entry_set_default (PolKitPolicyFileEntry *policy_file_entry,
+ PolKitPolicyDefault *defaults,
+ PolKitError **error)
+{
+ char *helper_argv[7] = {PACKAGE_LIBEXEC_DIR "/polkit-set-default-helper",
+ NULL, /* arg1: action_id */
+ NULL, /* arg2: "clear" or "set" */
+ NULL, /* arg3: result_any */
+ NULL, /* arg4: result_inactive */
+ NULL, /* arg5: result_active */
+ NULL};
+ polkit_bool_t ret;
+ int exit_status;
+ PolKitResult any;
+ PolKitResult inactive;
+ PolKitResult active;
+
+ ret = FALSE;
+
+ kit_return_val_if_fail (policy_file_entry != NULL, FALSE);
+ kit_return_val_if_fail (defaults != NULL, FALSE);
+
+ if (polkit_policy_default_equals (policy_file_entry->defaults, defaults)) {
+ /* no point in doing extra work.. */
+ ret = TRUE;
+ goto out;
+ }
+
+ any = polkit_policy_default_get_allow_any (defaults);
+ inactive = polkit_policy_default_get_allow_inactive (defaults);
+ active = polkit_policy_default_get_allow_active (defaults);
+
+ helper_argv[1] = policy_file_entry->action;
+
+ if (polkit_policy_default_equals (policy_file_entry->defaults_factory, defaults)) {
+ helper_argv[2] = "clear";
+ helper_argv[3] = NULL;
+ } else {
+ helper_argv[2] = "set";
+ helper_argv[3] = (char *) polkit_result_to_string_representation (any);
+ helper_argv[4] = (char *) polkit_result_to_string_representation (inactive);
+ helper_argv[5] = (char *) polkit_result_to_string_representation (active);
+ helper_argv[6] = NULL;
+ }
+
+ if (!kit_spawn_sync (NULL, /* const char *working_directory */
+ helper_argv, /* char **argv */
+ NULL, /* char **envp */
+ NULL, /* char *stdin */
+ NULL, /* char **stdout */
+ NULL, /* char **stderr */
+ &exit_status)) { /* int *exit_status */
+ polkit_error_set_error (error,
+ POLKIT_ERROR_GENERAL_ERROR,
+ "Error spawning set-default helper: %m");
+ goto out;
+ }
+
+ if (!WIFEXITED (exit_status)) {
+ kit_warning ("Revoke helper crashed!");
+ polkit_error_set_error (error,
+ POLKIT_ERROR_GENERAL_ERROR,
+ "set-default helper crashed!");
+ goto out;
+ } else if (WEXITSTATUS(exit_status) != 0) {
+ polkit_error_set_error (error,
+ POLKIT_ERROR_NOT_AUTHORIZED_TO_MODIFY_DEFAULTS,
+ "uid %d is not authorized to modify defaults for implicit authorization for action %s (requires org.freedesktop.policykit.modify-defaults)",
+ getuid (), policy_file_entry->action);
+ } else {
+ ret = TRUE;
+ }
+
+out:
+ return ret;
+
+}
+
+
typedef struct {
PolKitPolicyFileEntry *pfe;
PolKitPolicyFileEntryAnnotationsForeachFunc cb;
diff --git a/src/polkit/polkit-policy-file-entry.h b/src/polkit/polkit-policy-file-entry.h
index 1317025..79375b0 100644
--- a/src/polkit/polkit-policy-file-entry.h
+++ b/src/polkit/polkit-policy-file-entry.h
@@ -33,6 +33,7 @@
#include <polkit/polkit-types.h>
#include <polkit/polkit-result.h>
#include <polkit/polkit-policy-default.h>
+#include <polkit/polkit-error.h>
POLKIT_BEGIN_DECLS
@@ -71,6 +72,11 @@ polkit_bool_t polkit_policy_file_entry_annotations_foreach (PolKitPolic
const char *polkit_policy_file_entry_get_annotation (PolKitPolicyFileEntry *policy_file_entry,
const char *key);
+PolKitPolicyDefault *polkit_policy_file_entry_get_default_factory (PolKitPolicyFileEntry *policy_file_entry);
+polkit_bool_t polkit_policy_file_entry_set_default (PolKitPolicyFileEntry *policy_file_entry,
+ PolKitPolicyDefault *defaults,
+ PolKitError **error);
+
POLKIT_END_DECLS
#endif /* POLKIT_POLICY_FILE_ENTRY_H */
diff --git a/tools/polkit-action.c b/tools/polkit-action.c
index f0ae680..a4e04a9 100644
--- a/tools/polkit-action.c
+++ b/tools/polkit-action.c
@@ -59,30 +59,54 @@ _print_annotations (PolKitPolicyFileEntry *policy_file_entry,
static void
_print_details_for_entry (PolKitPolicyFileEntry *pfe)
{
+ int n;
const char *action_id;
PolKitPolicyDefault *def;
- PolKitResult default_any;
- PolKitResult default_inactive;
- PolKitResult default_active;
+ PolKitPolicyDefault *def_factory;
action_id = polkit_policy_file_entry_get_id (pfe);
def = polkit_policy_file_entry_get_default (pfe);
- default_any = polkit_policy_default_get_allow_any (def);
- default_inactive = polkit_policy_default_get_allow_inactive (def);
- default_active = polkit_policy_default_get_allow_active (def);
+ def_factory = polkit_policy_file_entry_get_default_factory (pfe);
printf ("action_id: %s\n"
"description: %s\n"
- "message: %s\n"
- "default_any: %s\n"
- "default_inactive: %s\n"
- "default_active: %s\n",
+ "message: %s\n",
action_id,
polkit_policy_file_entry_get_action_description (pfe),
- polkit_policy_file_entry_get_action_message (pfe),
- polkit_result_to_string_representation (default_any),
- polkit_result_to_string_representation (default_inactive),
- polkit_result_to_string_representation (default_active));
+ polkit_policy_file_entry_get_action_message (pfe));
+
+ for (n = 0; n < 3; n++) {
+ PolKitResult result;
+ PolKitResult result_factory;
+ char *str;
+
+ switch (n) {
+ default:
+ case 0:
+ str = "default_any: ";
+ result = polkit_policy_default_get_allow_any (def);
+ result_factory = polkit_policy_default_get_allow_any (def_factory);
+ break;
+ case 1:
+ str = "default_inactive:";
+ result = polkit_policy_default_get_allow_inactive (def);
+ result_factory = polkit_policy_default_get_allow_inactive (def_factory);
+ break;
+ case 2:
+ str = "default_active: ";
+ result = polkit_policy_default_get_allow_active (def);
+ result_factory = polkit_policy_default_get_allow_active (def_factory);
+ break;
+ }
+
+ if (result == result_factory) {
+ printf ("%s %s\n", str, polkit_result_to_string_representation (result));
+ } else {
+ printf ("%s %s (factory default: %s)\n", str,
+ polkit_result_to_string_representation (result),
+ polkit_result_to_string_representation (result_factory));
+ }
+ }
polkit_policy_file_entry_annotations_foreach (pfe, _print_annotations, NULL);
}
@@ -100,6 +124,26 @@ _print_entry (PolKitPolicyCache *policy_cache,
return FALSE;
}
+static polkit_bool_t
+_print_entry_override (PolKitPolicyCache *policy_cache,
+ PolKitPolicyFileEntry *pfe,
+ void *user_data)
+{
+ const char *action_id;
+ PolKitPolicyDefault *def;
+ PolKitPolicyDefault *def_factory;
+
+ def = polkit_policy_file_entry_get_default (pfe);
+ def_factory = polkit_policy_file_entry_get_default_factory (pfe);
+
+ if (!polkit_policy_default_equals (def, def_factory)) {
+ action_id = polkit_policy_file_entry_get_id (pfe);
+ printf ("%s\n", action_id);
+ }
+
+ return FALSE;
+}
+
int
main (int argc, char *argv[])
{
@@ -109,25 +153,54 @@ main (int argc, char *argv[])
PolKitPolicyCache *cache;
PolKitError *error;
char *action_id;
+ char *reset_action_id;
+ char *set_def_any_action_id;
+ char *set_def_inactive_action_id;
+ char *set_def_active_action_id;
+ PolKitResult set_def_any_value;
+ PolKitResult set_def_inactive_value;
+ PolKitResult set_def_active_value;
+ polkit_bool_t show_overrides;
ret = 1;
action_id = NULL;
+ reset_action_id = NULL;
+ set_def_any_action_id = NULL;
+ set_def_inactive_action_id = NULL;
+ set_def_active_action_id = NULL;
+ show_overrides = FALSE;
for (n = 1; n < argc; n++) {
if (strcmp (argv[n], "--help") == 0) {
usage (argc, argv);
return 0;
- }
- if (strcmp (argv[n], "--version") == 0) {
+ } else if (strcmp (argv[n], "--version") == 0) {
printf ("polkit-action " PACKAGE_VERSION "\n");
return 0;
- }
- if (strcmp (argv[n], "--action") == 0 && n + 1 < argc) {
- action_id = argv[n+1];
+ } else if (strcmp (argv[n], "--action") == 0 && n + 1 < argc) {
+ action_id = argv[++n];
+ } else if (strcmp (argv[n], "--reset-defaults") == 0 && n + 1 < argc) {
+ reset_action_id = argv[++n];
+ } else if (strcmp (argv[n], "--show-overrides") == 0) {
+ show_overrides = TRUE;
+ } else if (strcmp (argv[n], "--set-defaults-any") == 0 && n + 2 < argc) {
+ set_def_any_action_id = argv[++n];
+ if (!polkit_result_from_string_representation (argv[++n], &set_def_any_value))
+ usage (argc, argv);
+ } else if (strcmp (argv[n], "--set-defaults-inactive") == 0 && n + 2 < argc) {
+ set_def_inactive_action_id = argv[++n];
+ if (!polkit_result_from_string_representation (argv[++n], &set_def_inactive_value))
+ usage (argc, argv);
+ } else if (strcmp (argv[n], "--set-defaults-active") == 0 && n + 2 < argc) {
+ set_def_active_action_id = argv[++n];
+ if (!polkit_result_from_string_representation (argv[++n], &set_def_active_value))
+ usage (argc, argv);
+ } else {
+ usage (argc, argv);
+ return 0;
}
}
-
ctx = polkit_context_new ();
if (ctx == NULL)
goto out;
@@ -145,18 +218,140 @@ main (int argc, char *argv[])
goto out;
}
- if (action_id != NULL) {
- PolKitPolicyFileEntry *pfe;
- pfe = polkit_policy_cache_get_entry_by_id (cache, action_id);
- if (pfe == NULL) {
- fprintf (stderr, "Cannot find policy file entry for action id '%s'\n", action_id);
- goto out;
- }
- _print_details_for_entry (pfe);
- } else {
+ if (argc == 1) {
polkit_policy_cache_foreach (cache, _print_entry, NULL);
+ goto done;
}
+ if (show_overrides) {
+ polkit_policy_cache_foreach (cache, _print_entry_override, NULL);
+ goto done;
+ }
+
+ while (TRUE) {
+ if (reset_action_id != NULL) {
+ PolKitPolicyDefault *def;
+ PolKitPolicyFileEntry *pfe;
+ PolKitError *pk_error;
+
+ pfe = polkit_policy_cache_get_entry_by_id (cache, reset_action_id);
+ if (pfe == NULL) {
+ fprintf (stderr, "Cannot find policy file entry for action id '%s'\n", reset_action_id);
+ goto out;
+ }
+ def = polkit_policy_file_entry_get_default_factory (pfe);
+
+ pk_error = NULL;
+ if (!polkit_policy_file_entry_set_default (pfe, def, &pk_error)) {
+ fprintf (stderr, "Error: code=%d: %s: %s\n",
+ polkit_error_get_error_code (pk_error),
+ polkit_error_get_error_name (pk_error),
+ polkit_error_get_error_message (pk_error));
+ polkit_error_free (pk_error);
+ goto out;
+ }
+
+ reset_action_id = NULL;
+ }
+
+ if (set_def_any_action_id != NULL) {
+ PolKitPolicyDefault *def;
+ PolKitPolicyFileEntry *pfe;
+ PolKitError *pk_error;
+
+ pfe = polkit_policy_cache_get_entry_by_id (cache, set_def_any_action_id);
+ if (pfe == NULL) {
+ fprintf (stderr, "Cannot find policy file entry for action id '%s'\n", set_def_any_action_id);
+ goto out;
+ }
+
+ def = polkit_policy_default_clone (polkit_policy_file_entry_get_default (pfe));
+ polkit_policy_default_set_allow_any (def, set_def_any_value);
+ pk_error = NULL;
+ if (!polkit_policy_file_entry_set_default (pfe, def, &pk_error)) {
+ fprintf (stderr, "Error: code=%d: %s: %s\n",
+ polkit_error_get_error_code (pk_error),
+ polkit_error_get_error_name (pk_error),
+ polkit_error_get_error_message (pk_error));
+ polkit_error_free (pk_error);
+ goto out;
+ }
+ polkit_policy_default_unref (def);
+
+ set_def_any_action_id = NULL;
+ }
+
+ if (set_def_inactive_action_id != NULL) {
+ PolKitPolicyDefault *def;
+ PolKitPolicyFileEntry *pfe;
+ PolKitError *pk_error;
+
+ pfe = polkit_policy_cache_get_entry_by_id (cache, set_def_inactive_action_id);
+ if (pfe == NULL) {
+ fprintf (stderr, "Cannot find policy file entry for action id '%s'\n", set_def_inactive_action_id);
+ goto out;
+ }
+
+ def = polkit_policy_default_clone (polkit_policy_file_entry_get_default (pfe));
+ polkit_policy_default_set_allow_inactive (def, set_def_inactive_value);
+ pk_error = NULL;
+ if (!polkit_policy_file_entry_set_default (pfe, def, &pk_error)) {
+ fprintf (stderr, "Error: code=%d: %s: %s\n",
+ polkit_error_get_error_code (pk_error),
+ polkit_error_get_error_name (pk_error),
+ polkit_error_get_error_message (pk_error));
+ polkit_error_free (pk_error);
+ goto out;
+ }
+ polkit_policy_default_unref (def);
+
+ set_def_inactive_action_id = NULL;
+ }
+
+ if (set_def_active_action_id != NULL) {
+ PolKitPolicyDefault *def;
+ PolKitPolicyFileEntry *pfe;
+ PolKitError *pk_error;
+
+ pfe = polkit_policy_cache_get_entry_by_id (cache, set_def_active_action_id);
+ if (pfe == NULL) {
+ fprintf (stderr, "Cannot find policy file entry for action id '%s'\n", set_def_active_action_id);
+ goto out;
+ }
+
+ def = polkit_policy_default_clone (polkit_policy_file_entry_get_default (pfe));
+ polkit_policy_default_set_allow_active (def, set_def_active_value);
+ pk_error = NULL;
+ if (!polkit_policy_file_entry_set_default (pfe, def, &pk_error)) {
+ fprintf (stderr, "Error: code=%d: %s: %s\n",
+ polkit_error_get_error_code (pk_error),
+ polkit_error_get_error_name (pk_error),
+ polkit_error_get_error_message (pk_error));
+ polkit_error_free (pk_error);
+ goto out;
+ }
+ polkit_policy_default_unref (def);
+
+ set_def_active_action_id = NULL;
+ }
+
+ if (action_id != NULL) {
+ PolKitPolicyFileEntry *pfe;
+ pfe = polkit_policy_cache_get_entry_by_id (cache, action_id);
+ if (pfe == NULL) {
+ fprintf (stderr, "Cannot find policy file entry for action id '%s'\n", action_id);
+ goto out;
+ }
+ _print_details_for_entry (pfe);
+
+ action_id = NULL;
+ } else {
+ goto done;
+ }
+ }
+
+done:
+
polkit_context_unref (ctx);
ret = 0;
diff --git a/tools/polkit-bash-completion.sh b/tools/polkit-bash-completion.sh
index 635159e..2f94048 100644
--- a/tools/polkit-bash-completion.sh
+++ b/tools/polkit-bash-completion.sh
@@ -85,15 +85,27 @@ __polkit_action() {
local IFS=$'\n'
local cur="${COMP_WORDS[COMP_CWORD]}"
- if [ $COMP_CWORD = 1 ]; then
- COMPREPLY=($(IFS=: compgen -S' ' -W "--action:--version:--help" -- $cur))
- else
- case "${COMP_WORDS[1]}" in
- --action)
- COMPREPLY=($(compgen -W "$(polkit-action)" -- $cur))
- ;;
- esac
- fi
+ case $COMP_CWORD in
+ 1)
+ COMPREPLY=($(IFS=: compgen -S' ' -W "--action:--reset-defaults:--set-defaults-any:--set-defaults-inactive:--set-defaults-active:--show-overrides:--version:--help" -- $cur))
+ ;;
+ 2)
+ case "${COMP_WORDS[1]}" in
+ --action|--set-defaults-any|--set-defaults-inactive|--set-defaults-active)
+ COMPREPLY=($(compgen -W "$(polkit-action)" -- $cur))
+ ;;
+ --reset-defaults)
+ COMPREPLY=($(compgen -W "$(polkit-action --show-overrides)" -- $cur))
+ ;;
+ esac
+ ;;
+ 3)
+ case "${COMP_WORDS[1]}" in
+ --set-defaults-any|--set-defaults-inactive|--set-defaults-active)
+ COMPREPLY=($(IFS=: compgen -S' ' -W "yes:no:auth_admin_one_shot:auth_admin:auth_admin_keep_session:auth_admin_keep_always:auth_self_one_shot:auth_self:auth_self_keep_session:auth_self_keep_always" -- $cur))
+ ;;
+ esac
+ esac
}
####################################################################################################
More information about the hal-commit
mailing list