PolicyKit: Branch 'master'
David Zeuthen
david at kemper.freedesktop.org
Tue Oct 30 15:23:00 PDT 2007
polkit-dbus/Makefile.am | 22
polkit-dbus/polkit-explicit-grant-helper.c | 252 -------
polkit-dbus/polkit-revoke-helper.c | 347 ----------
polkit-grant/Makefile.am | 38 +
polkit-grant/polkit-authorization-db-dummy-write.c | 98 +++
polkit-grant/polkit-authorization-db-write.c | 671 +++++++++++++++++++++
polkit-grant/polkit-explicit-grant-helper.c | 252 +++++++
polkit-grant/polkit-revoke-helper.c | 347 ++++++++++
polkit/polkit-authorization-db-dummy.c | 54 -
polkit/polkit-authorization-db.c | 480 ---------------
polkit/polkit-private.h | 16
11 files changed, 1431 insertions(+), 1146 deletions(-)
New commits:
commit d9d790870b0372162091b00e19e38a24472a306d
Author: David Zeuthen <davidz at redhat.com>
Date: Tue Oct 30 18:21:04 2007 -0400
move authdb write functions to libpolkit-grant
This is primarily to keep libpolkit as minimal as possible as all that
mechanisms will ever need is the ability to read from the authdb.
diff --git a/polkit-dbus/Makefile.am b/polkit-dbus/Makefile.am
index 754cbd2..3c7fac1 100644
--- a/polkit-dbus/Makefile.am
+++ b/polkit-dbus/Makefile.am
@@ -28,37 +28,17 @@ libpolkit_dbus_la_LIBADD = @DBUS_LIBS@ $(top_builddir)/polkit/libpolkit.la $(SEL
libpolkit_dbus_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
if POLKIT_AUTHDB_DEFAULT
-libexec_PROGRAMS = polkit-explicit-grant-helper polkit-revoke-helper polkit-read-auth-helper
-
-polkit_explicit_grant_helper_SOURCES = polkit-explicit-grant-helper.c
-polkit_explicit_grant_helper_CFLAGS = @DBUS_CFLAGS@
-polkit_explicit_grant_helper_LDADD = $(top_builddir)/polkit/libpolkit.la $(top_builddir)/polkit-dbus/libpolkit-dbus.la
-
-polkit_revoke_helper_SOURCES = polkit-revoke-helper.c
-polkit_revoke_helper_CFLAGS = @DBUS_CFLAGS@
-polkit_revoke_helper_LDADD = $(top_builddir)/polkit/libpolkit.la $(top_builddir)/polkit-dbus/libpolkit-dbus.la
+libexec_PROGRAMS = polkit-read-auth-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)/polkit/libpolkit.la $(top_builddir)/polkit-dbus/libpolkit-dbus.la
-# polkit-explicit-grant-helper needs to be setgid $POLKIT_GROUP to be
-# able to edit authorization files in /var/lib/PolicyKit and
-# /var/run/PolicyKit
-#
-# polkit-revoke-helper needs to be setgid $POLKIT_GROUP to be able to
-# edit authorization files in /var/lib/PolicyKit and
-# /var/run/PolicyKit
-#
# 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
#
install-exec-hook:
- -chgrp $(POLKIT_GROUP) $(DESTDIR)$(libexecdir)/polkit-explicit-grant-helper
- -chmod 2755 $(DESTDIR)$(libexecdir)/polkit-explicit-grant-helper
- -chgrp $(POLKIT_GROUP) $(DESTDIR)$(libexecdir)/polkit-revoke-helper
- -chmod 2755 $(DESTDIR)$(libexecdir)/polkit-revoke-helper
-chgrp $(POLKIT_GROUP) $(DESTDIR)$(libexecdir)/polkit-read-auth-helper
-chmod 2755 $(DESTDIR)$(libexecdir)/polkit-read-auth-helper
endif
diff --git a/polkit-dbus/polkit-explicit-grant-helper.c b/polkit-dbus/polkit-explicit-grant-helper.c
deleted file mode 100644
index 45f2bc4..0000000
--- a/polkit-dbus/polkit-explicit-grant-helper.c
+++ /dev/null
@@ -1,252 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
-/***************************************************************************
- *
- * polkit-explicit-grant-helper.c : setgid polkituser explicit grant
- * helper for PolicyKit
- *
- * 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/time.h>
-#include <sys/types.h>
-#include <sys/stat.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 <polkit-dbus/polkit-dbus.h>
-#include <polkit/polkit-private.h>
-
-static polkit_bool_t
-check_pid_for_authorization (pid_t caller_pid, const char *action_id)
-{
- polkit_bool_t ret;
- DBusError error;
- DBusConnection *bus;
- PolKitCaller *caller;
- PolKitAction *action;
- PolKitContext *context;
-
- ret = FALSE;
-
- dbus_error_init (&error);
- bus = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
- if (bus == NULL) {
- fprintf (stderr, "polkit-read-auth-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-read-auth-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-read-auth-helper: cannot allocate PolKitAction\n");
- goto out;
- }
- if (!polkit_action_set_action_id (action, action_id)) {
- fprintf (stderr, "polkit-read-auth-helper: cannot set action_id\n");
- goto out;
- }
-
- context = polkit_context_new ();
- if (context == NULL) {
- fprintf (stderr, "polkit-read-auth-helper: cannot allocate PolKitContext\n");
- goto out;
- }
- if (!polkit_context_init (context, NULL)) {
- fprintf (stderr, "polkit-read-auth-helper: cannot initialize polkit\n");
- goto out;
- }
-
- if (polkit_context_is_caller_authorized (context, action, caller, FALSE) != POLKIT_RESULT_YES) {
- //fprintf (stderr,
- // "polkit-read-auth-helper: uid %d (pid %d) does not have the "
- // "org.freedesktop.policykit.read-other-authorizations authorization\n",
- // caller_uid, caller_pid);
- goto out;
- }
-
- ret = TRUE;
-out:
-
- return ret;
-}
-
-int
-main (int argc, char *argv[])
-{
- int ret;
- gid_t egid;
- struct group *group;
- uid_t invoking_uid;
- char *action_id;
- char *endp;
- char grant_line[512];
- struct timeval now;
-
- 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-explicit-grant-helper", LOG_CONS | LOG_PID, LOG_AUTHPRIV);
-
- /* check for correct invocation */
- if (argc != 5) {
- syslog (LOG_NOTICE, "inappropriate use of helper, wrong number of arguments [uid=%d]", getuid ());
- fprintf (stderr, "polkit-explicit-grant-helper: wrong number of arguments. This incident has been logged.\n");
- goto out;
- }
-
- /* 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-explicit-grant-helper: inappropriate use of helper, stdin is a tty. This incident has been logged.\n");
- goto out;
- }
-
- invoking_uid = getuid ();
-
- /* check that we are setgid polkituser */
- egid = getegid ();
- group = getgrgid (egid);
- if (group == NULL) {
- fprintf (stderr, "polkit-explicit-grant-helper: cannot lookup group info for gid %d\n", egid);
- goto out;
- }
- if (strcmp (group->gr_name, POLKIT_GROUP) != 0) {
- fprintf (stderr, "polkit-explicit-grant-helper: needs to be setgid " POLKIT_GROUP "\n");
- goto out;
- }
-
- /*----------------------------------------------------------------------------------------------------*/
-
- /* check and validate incoming parameters */
-
- /* first one is action_id */
- action_id = argv[1];
- if (!polkit_action_validate_id (action_id)) {
- syslog (LOG_NOTICE, "action_id is malformed [uid=%d]", getuid ());
- fprintf (stderr, "polkit-explicit-grant-helper: action_id is malformed. This incident has been logged.\n");
- goto out;
- }
-
- char *authc_str;
- PolKitAuthorizationConstraint *authc;
-
- /* second is the auth constraint */
- authc_str = argv[2];
- authc = polkit_authorization_constraint_from_string (authc_str);
- if (authc == NULL) {
- syslog (LOG_NOTICE, "auth constraint is malformed [uid=%d]", getuid ());
- fprintf (stderr, "polkit-explicit-grant-helper: auth constraint is malformed. This incident has been logged.\n");
- goto out;
- }
-
-#define TARGET_UID 0
- int target;
- uid_t target_uid = -1;
-
- /* (third, fourth) is one of: ("uid", uid) */
- if (strcmp (argv[3], "uid") == 0) {
-
- target = TARGET_UID;
- target_uid = strtol (argv[4], &endp, 10);
- if (*endp != '\0') {
- syslog (LOG_NOTICE, "target uid is malformed [uid=%d]", getuid ());
- fprintf (stderr, "polkit-explicit-grant-helper: target uid is malformed. This incident has been logged.\n");
- goto out;
- }
- } else {
- syslog (LOG_NOTICE, "target type is malformed [uid=%d]", getuid ());
- fprintf (stderr, "polkit-explicit-grant-helper: target type is malformed. This incident has been logged.\n");
- goto out;
- }
-
-
- //fprintf (stderr, "action_id=%s constraint=%s uid=%d\n", action_id, authc_str, target_uid);
-
- /* OK, we're done parsing ... check if the user is authorized */
-
- if (invoking_uid != 0) {
- /* see if calling user is authorized for
- *
- * org.freedesktop.policykit.grant
- */
- if (!check_pid_for_authorization (getppid (), "org.freedesktop.policykit.grant")) {
- goto out;
- }
- }
-
- /* he is.. proceed to add the grant */
-
- umask (002);
-
- if (gettimeofday (&now, NULL) != 0) {
- fprintf (stderr, "polkit-explicit-grant-helper: error calling gettimeofday: %m");
- return FALSE;
- }
-
- if (snprintf (grant_line,
- sizeof (grant_line),
- "grant:%s:%Lu:%d:%s\n",
- action_id,
- (polkit_uint64_t) now.tv_sec,
- invoking_uid,
- authc_str) >= (int) sizeof (grant_line)) {
- fprintf (stderr, "polkit-explicit-grant-helper: str to add is too long!\n");
- goto out;
- }
-
- if (_polkit_authorization_db_auth_file_add (PACKAGE_LOCALSTATE_DIR "/lib/PolicyKit",
- FALSE,
- target_uid,
- grant_line)) {
- ret = 0;
- }
-
-out:
-
- return ret;
-}
-
diff --git a/polkit-dbus/polkit-revoke-helper.c b/polkit-dbus/polkit-revoke-helper.c
deleted file mode 100644
index 8e28d65..0000000
--- a/polkit-dbus/polkit-revoke-helper.c
+++ /dev/null
@@ -1,347 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
-/***************************************************************************
- *
- * polkit-revoke-helper.c : setgid polkituser revoke helper for PolicyKit
- *
- * 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/time.h>
-#include <sys/types.h>
-#include <sys/stat.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 <polkit-dbus/polkit-dbus.h>
-
-static polkit_bool_t
-check_for_revoke_authorization (pid_t caller_pid)
-{
- polkit_bool_t ret;
- DBusError error;
- DBusConnection *bus;
- PolKitCaller *caller;
- PolKitAction *action;
- PolKitContext *context;
-
- ret = FALSE;
-
- dbus_error_init (&error);
- bus = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
- if (bus == NULL) {
- fprintf (stderr, "polkit-read-auth-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-read-auth-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-read-auth-helper: cannot allocate PolKitAction\n");
- goto out;
- }
- if (!polkit_action_set_action_id (action, "org.freedesktop.policykit.revoke")) {
- fprintf (stderr, "polkit-read-auth-helper: cannot set action_id\n");
- goto out;
- }
-
- context = polkit_context_new ();
- if (context == NULL) {
- fprintf (stderr, "polkit-read-auth-helper: cannot allocate PolKitContext\n");
- goto out;
- }
- if (!polkit_context_init (context, NULL)) {
- fprintf (stderr, "polkit-read-auth-helper: cannot initialize polkit\n");
- goto out;
- }
-
- if (polkit_context_is_caller_authorized (context, action, caller, FALSE) != POLKIT_RESULT_YES) {
- goto out;
- }
-
- ret = TRUE;
-out:
-
- return ret;
-}
-
-
-static int
-_write_to_fd (int fd, const char *str, ssize_t str_len)
-{
- int ret;
- ssize_t written;
-
- ret = 0;
-
- written = 0;
- while (written < str_len) {
- ssize_t ret;
- ret = write (fd, str + written, str_len - written);
- if (ret < 0) {
- if (errno == EAGAIN || errno == EINTR) {
- continue;
- } else {
- goto out;
- }
- }
- written += ret;
- }
-
- ret = 1;
-
-out:
- return ret;
-}
-
-int
-main (int argc, char *argv[])
-{
- int ret;
- gid_t egid;
- struct group *group;
- uid_t invoking_uid;
- char *entry_to_remove;
- int n;
- int len;
- char *p;
- char *scope;
- uid_t uid_to_revoke;
- char *endp;
- FILE *f;
- int fd;
- char path[256];
- char path_tmp[256];
- char line[512];
- char *root;
- char *target_type;
- char *target_value;
- struct passwd *pw;
-
- 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-revoke-helper", LOG_CONS | LOG_PID, LOG_AUTHPRIV);
-
- /* check for correct invocation */
- if (argc != 4) {
- syslog (LOG_NOTICE, "inappropriate use of helper, wrong number of arguments [uid=%d]", getuid ());
- fprintf (stderr, "polkit-revoke-helper: wrong number of arguments. This incident has been logged.\n");
- goto out;
- }
-
- /* 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-revoke-helper: inappropriate use of helper, stdin is a tty. This incident has been logged.\n");
- goto out;
- }
-
- invoking_uid = getuid ();
-
- /* check that we are setgid polkituser */
- egid = getegid ();
- group = getgrgid (egid);
- if (group == NULL) {
- fprintf (stderr, "polkit-revoke-helper: cannot lookup group info for gid %d\n", egid);
- goto out;
- }
- if (strcmp (group->gr_name, POLKIT_GROUP) != 0) {
- fprintf (stderr, "polkit-revoke-helper: needs to be setgid " POLKIT_GROUP "\n");
- goto out;
- }
-
- entry_to_remove = argv[1];
- target_type = argv[2];
- target_value = argv[3];
-
- /*----------------------------------------------------------------------------------------------------*/
-
- /* paranoia: we have to validate the entry_to_remove argument
- * and determine if the process who invoked us is sufficiently
- * privileged.
- *
- * As we're setuid root we don't want to pull in libpolkit and
- * as we only need to parse the first two entries... we do it
- * right here
- */
- p = entry_to_remove;
- len = strlen (entry_to_remove);
- for (n = 0; n < len; n++) {
- if (p[n] == ':')
- goto found;
- }
- fprintf (stderr, "polkit-revoke-helper: entry_to_remove malformed\n");
- goto out;
-found:
- scope = strndup (entry_to_remove, n);
- if (scope == NULL) {
- fprintf (stderr, "polkit-revoke-helper: OOM\n");
- goto out;
- }
-
- if (strcmp (target_type, "uid") == 0) {
- uid_to_revoke = strtol (target_value, &endp, 10);
- if (*endp != '\0') {
- fprintf (stderr, "polkit-revoke-helper: cannot parse uid\n");
- goto out;
- }
- } else {
- fprintf (stderr, "polkit-revoke-helper: unknown target type\n");
- goto out;
- }
-
- /* OK, we're done parsing ... */
-
- if (invoking_uid != 0) {
- /* Check that the caller is privileged to do this... */
- if (invoking_uid != uid_to_revoke) {
-
- /* see if calling user has the
- *
- * org.freedesktop.policykit.revoke
- *
- * authorization
- */
- if (!check_for_revoke_authorization (getppid ())) {
- goto out;
- }
- }
- }
-
- if (strcmp (scope, "process") == 0) {
- root = PACKAGE_LOCALSTATE_DIR "/run/PolicyKit";
- } else if (strcmp (scope, "session") == 0) {
- root = PACKAGE_LOCALSTATE_DIR "/run/PolicyKit";
- } else if (strcmp (scope, "always") == 0) {
- root = PACKAGE_LOCALSTATE_DIR "/lib/PolicyKit";
- } else if (strcmp (scope, "grant") == 0) {
- root = PACKAGE_LOCALSTATE_DIR "/lib/PolicyKit";
- } else {
- fprintf (stderr, "polkit-revoke-helper: unknown scope '%s'\n", scope);
- goto out;
- }
-
- pw = getpwuid (uid_to_revoke);
- if (pw == NULL) {
- fprintf (stderr, "polkit-revoke-helper: cannot lookup user name for uid %d\n", uid_to_revoke);
- goto out;
- }
-
- if (snprintf (path, sizeof (path), "%s/user-%s.auths", root, pw->pw_name) >= (int) sizeof (path)) {
- fprintf (stderr, "polkit-revoke-helper: string was truncated (1)\n");
- goto out;
- }
- if (snprintf (path_tmp, sizeof (path_tmp), "%s/user-%s.auths.XXXXXX", root, pw->pw_name) >= (int) sizeof (path)) {
- fprintf (stderr, "polkit-revoke-helper: string was truncated (2)\n");
- goto out;
- }
-
- f = fopen (path, "r");
- if (f == NULL) {
- fprintf (stderr, "Cannot open file '%s': %m\n", path);
- goto out;
- }
-
- fd = mkstemp (path_tmp);
- if (fd < 0) {
- fprintf (stderr, "Cannot create file '%s': %m\n", path_tmp);
- goto out;
- }
- if (fchmod (fd, 0464) != 0) {
- fprintf (stderr, "Cannot change mode for '%s' to 0460: %m\n", path_tmp);
- close (fd);
- unlink (path_tmp);
- goto out;
- }
-
-
- /* read one line at a time */
- while (fgets (line, sizeof (line), f) != NULL) {
- size_t line_len;
-
- line_len = strlen (line);
- if (line_len > 1 && line[line_len - 1] == '\n') {
- if (strncmp (line, entry_to_remove, line_len - 1) == 0) {
- /* woho, found it */
- continue;
- }
- }
-
- /* otherwise, just write the line to the temporary file */
- if (!_write_to_fd (fd, line, line_len)) {
- fprintf (stderr, "Error write to file '%s': %m\n", path_tmp);
- close (fd);
- unlink (path_tmp);
- goto out;
- }
- }
-
- fclose (f);
- close (fd);
-
- if (rename (path_tmp, path) != 0) {
- fprintf (stderr, "Error renaming %s to %s: %m\n", path_tmp, path);
- unlink (path_tmp);
- goto out;
- }
-
- /* we're good now (if triggering a reload fails, so be it, we
- * still did what the caller asked...)
- */
- ret = 0;
-
- /* trigger a reload */
- if (utimes (PACKAGE_LOCALSTATE_DIR "/lib/misc/PolicyKit.reload", NULL) != 0) {
- fprintf (stderr, "Error updating access+modification time on file '%s': %m\n",
- PACKAGE_LOCALSTATE_DIR "/lib/misc/PolicyKit.reload");
- }
-
-out:
-
- return ret;
-}
-
diff --git a/polkit-grant/Makefile.am b/polkit-grant/Makefile.am
index 741ef72..c7e68d4 100644
--- a/polkit-grant/Makefile.am
+++ b/polkit-grant/Makefile.am
@@ -10,18 +10,28 @@ INCLUDES = \
-DPACKAGE_LOCALE_DIR=\""$(localedir)"\" \
-DPACKAGE_LIB_DIR=\""$(libdir)"\" \
-D_POSIX_PTHREAD_SEMANTICS -D_REENTRANT \
+ -DPOLKIT_COMPILATION \
@GLIB_CFLAGS@ @DBUS_CFLAGS@
lib_LTLIBRARIES=libpolkit-grant.la
libpolkit_grantincludedir=$(includedir)/PolicyKit/polkit-grant
-libpolkit_grantinclude_HEADERS = \
+libpolkit_grantinclude_HEADERS = \
polkit-grant.h
-libpolkit_grant_la_SOURCES = \
+libpolkit_grant_la_SOURCES = \
polkit-grant.h polkit-grant.c
+
+if POLKIT_AUTHDB_DUMMY
+libpolkit_grant_la_SOURCES += polkit-authorization-db-dummy-write.c
+endif
+
+if POLKIT_AUTHDB_DEFAULT
+libpolkit_grant_la_SOURCES += polkit-authorization-db-write.c
+endif
+
libpolkit_grant_la_LIBADD = @GLIB_LIBS@ @DBUS_LIBS@ $(top_builddir)/polkit/libpolkit.la
libpolkit_grant_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
@@ -31,14 +41,22 @@ libpolkit_grant_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE
# adjust the PAM stuff in data/Makefile.am
#
if POLKIT_AUTHDB_DEFAULT
-libexec_PROGRAMS = polkit-grant-helper polkit-grant-helper-pam
+libexec_PROGRAMS = polkit-grant-helper polkit-grant-helper-pam polkit-explicit-grant-helper polkit-revoke-helper
polkit_grant_helper_SOURCES = polkit-grant-helper.c
-polkit_grant_helper_LDADD = @GLIB_LIBS@ @DBUS_LIBS@ $(top_builddir)/polkit/libpolkit.la $(top_builddir)/polkit-dbus/libpolkit-dbus.la
+polkit_grant_helper_LDADD = @GLIB_LIBS@ @DBUS_LIBS@ $(top_builddir)/polkit/libpolkit.la $(top_builddir)/polkit-dbus/libpolkit-dbus.la $(top_builddir)/polkit-grant/libpolkit-grant.la
polkit_grant_helper_pam_SOURCES = polkit-grant-helper-pam.c
polkit_grant_helper_pam_LDADD = @AUTH_LIBS@
+polkit_explicit_grant_helper_SOURCES = polkit-explicit-grant-helper.c
+polkit_explicit_grant_helper_CFLAGS = @DBUS_CFLAGS@
+polkit_explicit_grant_helper_LDADD = $(top_builddir)/polkit/libpolkit.la $(top_builddir)/polkit-dbus/libpolkit-dbus.la
+
+polkit_revoke_helper_SOURCES = polkit-revoke-helper.c
+polkit_revoke_helper_CFLAGS = @DBUS_CFLAGS@
+polkit_revoke_helper_LDADD = $(top_builddir)/polkit/libpolkit.la $(top_builddir)/polkit-dbus/libpolkit-dbus.la
+
# polkit-grant-helper needs to be setgid polkituser to be able to
# write cookies to /var/lib/PolicyKit and /var/run/PolicyKit
#
@@ -48,11 +66,23 @@ polkit_grant_helper_pam_LDADD = @AUTH_LIBS@
# we make it owned by the polkitiuser group and non-readable /
# non-executable to the world
#
+# polkit-explicit-grant-helper needs to be setgid $POLKIT_GROUP to be
+# able to edit authorization files in /var/lib/PolicyKit and
+# /var/run/PolicyKit
+#
+# polkit-revoke-helper needs to be setgid $POLKIT_GROUP to be able to
+# edit authorization files in /var/lib/PolicyKit and
+# /var/run/PolicyKit
+#
install-exec-hook:
-chgrp $(POLKIT_GROUP) $(DESTDIR)$(libexecdir)/polkit-grant-helper
-chmod 2755 $(DESTDIR)$(libexecdir)/polkit-grant-helper
-chgrp $(POLKIT_GROUP) $(DESTDIR)$(libexecdir)/polkit-grant-helper-pam
-chmod 4750 $(DESTDIR)$(libexecdir)/polkit-grant-helper-pam
+ -chgrp $(POLKIT_GROUP) $(DESTDIR)$(libexecdir)/polkit-explicit-grant-helper
+ -chmod 2755 $(DESTDIR)$(libexecdir)/polkit-explicit-grant-helper
+ -chgrp $(POLKIT_GROUP) $(DESTDIR)$(libexecdir)/polkit-revoke-helper
+ -chmod 2755 $(DESTDIR)$(libexecdir)/polkit-revoke-helper
endif
clean-local :
diff --git a/polkit-grant/polkit-authorization-db-dummy-write.c b/polkit-grant/polkit-authorization-db-dummy-write.c
new file mode 100644
index 0000000..8f55c14
--- /dev/null
+++ b/polkit-grant/polkit-authorization-db-dummy-write.c
@@ -0,0 +1,98 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/***************************************************************************
+ *
+ * polkit-authorization-db.c : Dummy authorization database
+ *
+ * Copyright (C) 2007 David Zeuthen, <david at fubar.dk>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * 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
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <pwd.h>
+
+#include <glib.h>
+
+#include <polkit/polkit-debug.h>
+#include <polkit/polkit-authorization-db.h>
+#include <polkit/polkit-utils.h>
+#include <polkit/polkit-private.h>
+
+/* PolKitAuthorizationDB structure is defined in polkit/polkit-private.h */
+
+polkit_bool_t
+polkit_authorization_db_add_entry_process (PolKitAuthorizationDB *authdb,
+ PolKitAction *action,
+ PolKitCaller *caller,
+ uid_t user_authenticated_as)
+{
+ return FALSE;
+}
+
+polkit_bool_t
+polkit_authorization_db_add_entry_session (PolKitAuthorizationDB *authdb,
+ PolKitAction *action,
+ PolKitCaller *caller,
+ uid_t user_authenticated_as)
+{
+ return FALSE;
+}
+
+polkit_bool_t
+polkit_authorization_db_add_entry_always (PolKitAuthorizationDB *authdb,
+ PolKitAction *action,
+ PolKitCaller *caller,
+ uid_t user_authenticated_as)
+{
+ return FALSE;
+}
+
+polkit_bool_t
+polkit_authorization_db_grant_to_uid (PolKitAuthorizationDB *authdb,
+ PolKitAction *action,
+ uid_t uid,
+ PolKitAuthorizationConstraint *constraint,
+ PolKitError **error)
+{
+ polkit_error_set_error (error, POLKIT_ERROR_NOT_SUPPORTED, "Not supported");
+ return FALSE;
+}
+
+polkit_bool_t
+polkit_authorization_db_revoke_entry (PolKitAuthorizationDB *authdb,
+ PolKitAuthorization *auth,
+ PolKitError **error)
+{
+ polkit_error_set_error (error, POLKIT_ERROR_NOT_SUPPORTED, "Not supported");
+ return FALSE;
+}
+
+
diff --git a/polkit-grant/polkit-authorization-db-write.c b/polkit-grant/polkit-authorization-db-write.c
new file mode 100644
index 0000000..946759b
--- /dev/null
+++ b/polkit-grant/polkit-authorization-db-write.c
@@ -0,0 +1,671 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/***************************************************************************
+ *
+ * polkit-authorization-db.c : Represents the authorization database
+ *
+ * Copyright (C) 2007 David Zeuthen, <david at fubar.dk>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * 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
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <pwd.h>
+
+#include <glib.h>
+
+#include <polkit/polkit-debug.h>
+#include <polkit/polkit-authorization-db.h>
+#include <polkit/polkit-utils.h>
+#include <polkit/polkit-private.h>
+
+/**
+ * SECTION:polkit-authorization-db
+ **/
+
+
+static polkit_bool_t
+_write_to_fd (int fd, const char *str, ssize_t str_len)
+{
+ polkit_bool_t ret;
+ ssize_t written;
+
+ ret = FALSE;
+
+ written = 0;
+ while (written < str_len) {
+ ssize_t ret;
+ ret = write (fd, str + written, str_len - written);
+ if (ret < 0) {
+ if (errno == EAGAIN || errno == EINTR) {
+ continue;
+ } else {
+ goto out;
+ }
+ }
+ written += ret;
+ }
+
+ ret = TRUE;
+
+out:
+ return ret;
+}
+
+polkit_bool_t
+_polkit_authorization_db_auth_file_add (const char *root, polkit_bool_t transient, uid_t uid, char *str_to_add)
+{
+ int fd;
+ char *contents;
+ gsize contents_size;
+ char *path;
+ char *path_tmp;
+ GError *error;
+ polkit_bool_t ret;
+ struct stat statbuf;
+ struct passwd *pw;
+
+ ret = FALSE;
+ path = NULL;
+ path_tmp = NULL;
+ contents = NULL;
+
+ pw = getpwuid (uid);
+ if (pw == NULL) {
+ g_warning ("cannot lookup user name for uid %d\n", uid);
+ goto out;
+ }
+
+ path = g_strdup_printf ("%s/user-%s.auths", root, pw->pw_name);
+ path_tmp = g_strdup_printf ("%s.XXXXXX", path);
+
+ if (stat (path, &statbuf) != 0 && errno == ENOENT) {
+ //fprintf (stderr, "path=%s does not exist (egid=%d): %m!\n", path, getegid ());
+
+ g_free (path_tmp);
+ path_tmp = path;
+ path = NULL;
+
+ /* Write a nice blurb if we're creating the file for the first time */
+
+ contents = g_strdup_printf (
+ "# This file lists authorizations for user %s\n"
+ "%s"
+ "# \n"
+ "# File format may change at any time; do not rely on it. To manage\n"
+ "# authorizations use polkit-auth(1) instead.\n"
+ "\n",
+ pw->pw_name,
+ transient ? "# (these are temporary and will be removed on the next system boot)\n" : "");
+ contents_size = strlen (contents);
+ } else {
+ error = NULL;
+ if (!g_file_get_contents (path, &contents, &contents_size, &error)) {
+ g_warning ("Cannot read authorizations file %s: %s", path, error->message);
+ g_error_free (error);
+ goto out;
+ }
+ }
+
+ if (path != NULL) {
+ fd = mkstemp (path_tmp);
+ if (fd < 0) {
+ fprintf (stderr, "Cannot create file '%s': %m\n", path_tmp);
+ goto out;
+ }
+ if (fchmod (fd, 0464) != 0) {
+ fprintf (stderr, "Cannot change mode for '%s' to 0460: %m\n", path_tmp);
+ close (fd);
+ unlink (path_tmp);
+ goto out;
+ }
+ } else {
+ fd = open (path_tmp, O_RDWR|O_CREAT, 0464);
+ if (fd < 0) {
+ fprintf (stderr, "Cannot create file '%s': %m\n", path_tmp);
+ goto out;
+ }
+ }
+
+ if (!_write_to_fd (fd, contents, contents_size)) {
+ g_warning ("Cannot write to temporary authorizations file %s: %m", path_tmp);
+ close (fd);
+ if (unlink (path_tmp) != 0) {
+ g_warning ("Cannot unlink %s: %m", path_tmp);
+ }
+ goto out;
+ }
+ if (!_write_to_fd (fd, str_to_add, strlen (str_to_add))) {
+ g_warning ("Cannot write to temporary authorizations file %s: %m", path_tmp);
+ close (fd);
+ if (unlink (path_tmp) != 0) {
+ g_warning ("Cannot unlink %s: %m", path_tmp);
+ }
+ goto out;
+ }
+ close (fd);
+
+ if (path != NULL) {
+ if (rename (path_tmp, path) != 0) {
+ g_warning ("Cannot rename %s to %s: %m", path_tmp, path);
+ if (unlink (path_tmp) != 0) {
+ g_warning ("Cannot unlink %s: %m", path_tmp);
+ }
+ goto out;
+ }
+ }
+
+ /* trigger a reload */
+ if (utimes (PACKAGE_LOCALSTATE_DIR "/lib/misc/PolicyKit.reload", NULL) != 0) {
+ g_warning ("Error updating access+modification time on file '%s': %m\n",
+ PACKAGE_LOCALSTATE_DIR "/lib/misc/PolicyKit.reload");
+ }
+
+ ret = TRUE;
+
+out:
+ if (contents != NULL)
+ g_free (contents);
+ if (path != NULL)
+ g_free (path);
+ if (path_tmp != NULL)
+ g_free (path_tmp);
+ return ret;
+}
+
+
+/**
+ * polkit_authorization_db_add_entry_process:
+ * @authdb: the authorization database
+ * @action: the action
+ * @caller: the caller
+ * @user_authenticated_as: the user that was authenticated
+ *
+ * Write an entry to the authorization database to indicate that the
+ * given caller is authorized for the given action.
+ *
+ * Note that this function should only be used by
+ * <literal>libpolkit-grant</literal> or other sufficiently privileged
+ * processes that deals with managing authorizations. It should never
+ * be used by mechanisms or applications. The caller must have
+ * egid=polkituser and umask set so creating files with mode 0460 will
+ * work.
+ *
+ * This function is in <literal>libpolkit-grant</literal>.
+ *
+ * Returns: #TRUE if an entry was written to the authorization
+ * database, #FALSE if the caller of this function is not sufficiently
+ * privileged.
+ *
+ * Since: 0.7
+ */
+polkit_bool_t
+polkit_authorization_db_add_entry_process (PolKitAuthorizationDB *authdb,
+ PolKitAction *action,
+ PolKitCaller *caller,
+ uid_t user_authenticated_as)
+{
+ char *action_id;
+ uid_t caller_uid;
+ pid_t caller_pid;
+ char *grant_line;
+ polkit_bool_t ret;
+ polkit_uint64_t pid_start_time;
+ struct timeval now;
+ PolKitAuthorizationConstraint *constraint;
+ char cbuf[256];
+
+ g_return_val_if_fail (authdb != NULL, FALSE);
+ g_return_val_if_fail (action != NULL, FALSE);
+ g_return_val_if_fail (caller != NULL, FALSE);
+
+ if (!polkit_action_get_action_id (action, &action_id))
+ return FALSE;
+
+ if (!polkit_caller_get_pid (caller, &caller_pid))
+ return FALSE;
+
+ if (!polkit_caller_get_uid (caller, &caller_uid))
+ return FALSE;
+
+ pid_start_time = polkit_sysdeps_get_start_time_for_pid (caller_pid);
+ if (pid_start_time == 0)
+ return FALSE;
+
+ if (gettimeofday (&now, NULL) != 0) {
+ g_warning ("Error calling gettimeofday: %m");
+ return FALSE;
+ }
+
+ constraint = polkit_authorization_constraint_get_from_caller (caller);
+ if (polkit_authorization_constraint_to_string (constraint, cbuf, sizeof (cbuf)) >= sizeof (cbuf)) {
+ g_warning ("buffer for auth constraint is too small");
+ return FALSE;
+ }
+
+ grant_line = g_strdup_printf ("process:%d:%Lu:%s:%Lu:%d:%s\n",
+ caller_pid,
+ pid_start_time,
+ action_id,
+ (polkit_uint64_t) now.tv_sec,
+ user_authenticated_as,
+ cbuf);
+
+ ret = _polkit_authorization_db_auth_file_add (PACKAGE_LOCALSTATE_DIR "/run/PolicyKit",
+ TRUE,
+ caller_uid,
+ grant_line);
+ g_free (grant_line);
+ return ret;
+}
+
+/**
+ * polkit_authorization_db_add_entry_session:
+ * @authdb: the authorization database
+ * @action: the action
+ * @caller: the caller
+ * @user_authenticated_as: the user that was authenticated
+ *
+ * Write an entry to the authorization database to indicate that the
+ * session for the given caller is authorized for the given action for
+ * the remainer of the session.
+ *
+ * Note that this function should only be used by
+ * <literal>libpolkit-grant</literal> or other sufficiently privileged
+ * processes that deals with managing authorizations. It should never
+ * be used by mechanisms or applications. The caller must have
+ * egid=polkituser and umask set so creating files with mode 0460 will
+ * work.
+ *
+ * This function is in <literal>libpolkit-grant</literal>.
+ *
+ * Returns: #TRUE if an entry was written to the authorization
+ * database, #FALSE if the caller of this function is not sufficiently
+ * privileged.
+ *
+ * Since: 0.7
+ */
+polkit_bool_t
+polkit_authorization_db_add_entry_session (PolKitAuthorizationDB *authdb,
+ PolKitAction *action,
+ PolKitCaller *caller,
+ uid_t user_authenticated_as)
+{
+ uid_t session_uid;
+ char *action_id;
+ char *grant_line;
+ PolKitSession *session;
+ char *session_objpath;
+ polkit_bool_t ret;
+ struct timeval now;
+ PolKitAuthorizationConstraint *constraint;
+ char cbuf[256];
+
+ g_return_val_if_fail (authdb != NULL, FALSE);
+ g_return_val_if_fail (action != NULL, FALSE);
+ g_return_val_if_fail (caller != NULL, FALSE);
+
+ if (!polkit_action_get_action_id (action, &action_id))
+ return FALSE;
+
+ if (!polkit_caller_get_ck_session (caller, &session))
+ return FALSE;
+
+ if (!polkit_session_get_ck_objref (session, &session_objpath))
+ return FALSE;
+
+ if (!polkit_session_get_uid (session, &session_uid))
+ return FALSE;
+
+ constraint = polkit_authorization_constraint_get_from_caller (caller);
+ if (polkit_authorization_constraint_to_string (constraint, cbuf, sizeof (cbuf)) >= sizeof (cbuf)) {
+ g_warning ("buffer for auth constraint is too small");
+ return FALSE;
+ }
+
+ if (gettimeofday (&now, NULL) != 0) {
+ g_warning ("Error calling gettimeofday: %m");
+ return FALSE;
+ }
+
+ grant_line = g_strdup_printf ("session:%s:%s:%Lu:%d:%s\n",
+ session_objpath,
+ action_id,
+ (polkit_uint64_t) now.tv_sec,
+ user_authenticated_as,
+ cbuf);
+
+ ret = _polkit_authorization_db_auth_file_add (PACKAGE_LOCALSTATE_DIR "/run/PolicyKit",
+ TRUE,
+ session_uid,
+ grant_line);
+ g_free (grant_line);
+ return ret;
+}
+
+/**
+ * polkit_authorization_db_add_entry_always:
+ * @authdb: the authorization database
+ * @action: the action
+ * @caller: the caller
+ * @user_authenticated_as: the user that was authenticated
+ *
+ * Write an entry to the authorization database to indicate that the
+ * given user is authorized for the given action.
+ *
+ * Note that this function should only be used by
+ * <literal>libpolkit-grant</literal> or other sufficiently privileged
+ * processes that deals with managing authorizations. It should never
+ * be used by mechanisms or applications. The caller must have
+ * egid=polkituser and umask set so creating files with mode 0460 will
+ * work.
+ *
+ * This function is in <literal>libpolkit-grant</literal>.
+ *
+ * Returns: #TRUE if an entry was written to the authorization
+ * database, #FALSE if the caller of this function is not sufficiently
+ * privileged.
+ *
+ * Since: 0.7
+ */
+polkit_bool_t
+polkit_authorization_db_add_entry_always (PolKitAuthorizationDB *authdb,
+ PolKitAction *action,
+ PolKitCaller *caller,
+ uid_t user_authenticated_as)
+{
+ uid_t uid;
+ char *action_id;
+ char *grant_line;
+ polkit_bool_t ret;
+ struct timeval now;
+ PolKitAuthorizationConstraint *constraint;
+ char cbuf[256];
+
+ g_return_val_if_fail (authdb != NULL, FALSE);
+ g_return_val_if_fail (action != NULL, FALSE);
+ g_return_val_if_fail (caller != NULL, FALSE);
+
+ if (!polkit_caller_get_uid (caller, &uid))
+ return FALSE;
+
+ if (!polkit_action_get_action_id (action, &action_id))
+ return FALSE;
+
+ if (gettimeofday (&now, NULL) != 0) {
+ g_warning ("Error calling gettimeofday: %m");
+ return FALSE;
+ }
+
+ constraint = polkit_authorization_constraint_get_from_caller (caller);
+ if (polkit_authorization_constraint_to_string (constraint, cbuf, sizeof (cbuf)) >= sizeof (cbuf)) {
+ g_warning ("buffer for auth constraint is too small");
+ return FALSE;
+ }
+
+ grant_line = g_strdup_printf ("always:%s:%Lu:%d:%s\n",
+ action_id,
+ (polkit_uint64_t) now.tv_sec,
+ user_authenticated_as,
+ cbuf);
+
+ ret = _polkit_authorization_db_auth_file_add (PACKAGE_LOCALSTATE_DIR "/lib/PolicyKit",
+ FALSE,
+ uid,
+ grant_line);
+ g_free (grant_line);
+ return ret;
+}
+
+/**
+ * polkit_authorization_db_revoke_entry:
+ * @authdb: the authorization database
+ * @auth: the authorization to revoke
+ * @error: return location for error
+ *
+ * Removes an authorization from the authorization database. This uses
+ * a privileged helper /usr/libexec/polkit-revoke-helper.
+ *
+ * This function is in <literal>libpolkit-grant</literal>.
+ *
+ * Returns: #TRUE if the authorization was revoked, #FALSE otherwise and error is set
+ *
+ * Since: 0.7
+ */
+polkit_bool_t
+polkit_authorization_db_revoke_entry (PolKitAuthorizationDB *authdb,
+ PolKitAuthorization *auth,
+ PolKitError **error)
+{
+ GError *g_error;
+ char *helper_argv[] = {PACKAGE_LIBEXEC_DIR "/polkit-revoke-helper", "", NULL, NULL, NULL};
+ const char *auth_file_entry;
+ gboolean ret;
+ gint exit_status;
+
+ ret = FALSE;
+
+ g_return_val_if_fail (authdb != NULL, FALSE);
+ g_return_val_if_fail (auth != NULL, FALSE);
+
+ auth_file_entry = _polkit_authorization_get_authfile_entry (auth);
+ //g_debug ("should delete line '%s'", auth_file_entry);
+
+ helper_argv[1] = (char *) auth_file_entry;
+ helper_argv[2] = "uid";
+ helper_argv[3] = g_strdup_printf ("%d", polkit_authorization_get_uid (auth));
+
+ g_error = NULL;
+ if (!g_spawn_sync (NULL, /* const gchar *working_directory */
+ helper_argv, /* gchar **argv */
+ NULL, /* gchar **envp */
+ 0, /* GSpawnFlags flags */
+ NULL, /* GSpawnChildSetupFunc child_setup */
+ NULL, /* gpointer user_data */
+ NULL, /* gchar **standard_output */
+ NULL, /* gchar **standard_error */
+ &exit_status, /* gint *exit_status */
+ &g_error)) { /* GError **error */
+ polkit_error_set_error (error,
+ POLKIT_ERROR_GENERAL_ERROR,
+ "Error spawning revoke helper: %s",
+ g_error->message);
+ g_error_free (g_error);
+ goto out;
+ }
+
+ if (!WIFEXITED (exit_status)) {
+ g_warning ("Revoke helper crashed!");
+ polkit_error_set_error (error,
+ POLKIT_ERROR_GENERAL_ERROR,
+ "Revoke helper crashed!");
+ goto out;
+ } else if (WEXITSTATUS(exit_status) != 0) {
+ polkit_error_set_error (error,
+ POLKIT_ERROR_NOT_AUTHORIZED_TO_REVOKE_AUTHORIZATIONS_FROM_OTHER_USERS,
+ "uid %d is not authorized to revoke authorizations from uid %d (requires org.freedesktop.policykit.revoke)",
+ getuid (), polkit_authorization_get_uid (auth));
+ } else {
+ ret = TRUE;
+ }
+
+out:
+ g_free (helper_argv[3]);
+ return ret;
+}
+
+typedef struct {
+ char *action_id;
+ PolKitAuthorizationConstraint *constraint;
+} CheckDataGrant;
+
+static polkit_bool_t
+_check_auth_for_grant (PolKitAuthorizationDB *authdb, PolKitAuthorization *auth, void *user_data)
+{
+ uid_t pimp;
+ polkit_bool_t ret;
+ CheckDataGrant *cd = (CheckDataGrant *) user_data;
+
+ ret = FALSE;
+
+ if (strcmp (polkit_authorization_get_action_id (auth), cd->action_id) != 0)
+ goto no_match;
+
+ if (!polkit_authorization_was_granted_explicitly (auth, &pimp))
+ goto no_match;
+
+ if (!polkit_authorization_constraint_equal (polkit_authorization_get_constraint (auth), cd->constraint))
+ goto no_match;
+
+ ret = TRUE;
+
+no_match:
+ return ret;
+}
+
+/**
+ * polkit_authorization_db_grant_to_uid:
+ * @authdb: authorization database
+ * @action: action
+ * @uid: uid to grant to
+ * @constraint: what constraint to put on the authorization
+ * @error: return location for error
+ *
+ * Grants an authorization to a user for a specific action. This
+ * requires the org.freedesktop.policykit.grant authorization.
+ *
+ * This function is in <literal>libpolkit-grant</literal>.
+ *
+ * Returns: #TRUE if the authorization was granted, #FALSE otherwise
+ * and error will be set
+ *
+ * Since: 0.7
+ */
+polkit_bool_t
+polkit_authorization_db_grant_to_uid (PolKitAuthorizationDB *authdb,
+ PolKitAction *action,
+ uid_t uid,
+ PolKitAuthorizationConstraint *constraint,
+ PolKitError **error)
+{
+ GError *g_error;
+ char *helper_argv[6] = {PACKAGE_LIBEXEC_DIR "/polkit-explicit-grant-helper", NULL, NULL, NULL, NULL, NULL};
+ gboolean ret;
+ gint exit_status;
+ char cbuf[256];
+ CheckDataGrant cd;
+
+ ret = FALSE;
+
+ g_return_val_if_fail (authdb != NULL, FALSE);
+ g_return_val_if_fail (action != NULL, FALSE);
+ g_return_val_if_fail (constraint != NULL, FALSE);
+
+ if (!polkit_action_get_action_id (action, &(cd.action_id))) {
+ polkit_error_set_error (error,
+ POLKIT_ERROR_GENERAL_ERROR,
+ "Given action does not have action_id set");
+ goto out;
+ }
+
+ if (polkit_authorization_constraint_to_string (constraint, cbuf, sizeof (cbuf)) >= sizeof (cbuf)) {
+ g_warning ("buffer for auth constraint is too small");
+ polkit_error_set_error (error,
+ POLKIT_ERROR_GENERAL_ERROR,
+ "buffer for auth constraint is too small");
+ goto out;
+ }
+
+ /* check if we have the auth already */
+ cd.constraint = constraint;
+ if (!polkit_authorization_db_foreach_for_uid (authdb,
+ uid,
+ _check_auth_for_grant,
+ &cd,
+ error)) {
+ /* happens if caller can't read auths of target user */
+ if (error != NULL && polkit_error_is_set (*error)) {
+ goto out;
+ }
+ } else {
+ /* so it did exist.. */
+ polkit_error_set_error (error,
+ POLKIT_ERROR_AUTHORIZATION_ALREADY_EXISTS,
+ "An authorization for uid %d for the action %s with constraint '%s' already exists",
+ uid, cd.action_id, cbuf);
+ goto out;
+ }
+
+
+ helper_argv[1] = cd.action_id;
+ helper_argv[2] = cbuf;
+ helper_argv[3] = "uid";
+ helper_argv[4] = g_strdup_printf ("%d", uid);
+ helper_argv[5] = NULL;
+
+ g_error = NULL;
+ if (!g_spawn_sync (NULL, /* const gchar *working_directory */
+ helper_argv, /* gchar **argv */
+ NULL, /* gchar **envp */
+ 0, /* GSpawnFlags flags */
+ NULL, /* GSpawnChildSetupFunc child_setup */
+ NULL, /* gpointer user_data */
+ NULL, /* gchar **standard_output */
+ NULL, /* gchar **standard_error */
+ &exit_status, /* gint *exit_status */
+ &g_error)) { /* GError **error */
+ polkit_error_set_error (error,
+ POLKIT_ERROR_GENERAL_ERROR,
+ "Error spawning explicit grant helper: %s",
+ g_error->message);
+ g_error_free (g_error);
+ goto out;
+ }
+
+ if (!WIFEXITED (exit_status)) {
+ g_warning ("Explicit grant helper crashed!");
+ polkit_error_set_error (error,
+ POLKIT_ERROR_GENERAL_ERROR,
+ "Explicit grant helper crashed!");
+ goto out;
+ } else if (WEXITSTATUS(exit_status) != 0) {
+ polkit_error_set_error (error,
+ POLKIT_ERROR_NOT_AUTHORIZED_TO_GRANT_AUTHORIZATION,
+ "uid %d is not authorized to grant authorization for action %s to uid %d (requires org.freedesktop.policykit.grant)",
+ getuid (), cd.action_id, uid);
+ } else {
+ ret = TRUE;
+ }
+
+out:
+ g_free (helper_argv[4]);
+ return ret;
+
+}
diff --git a/polkit-grant/polkit-explicit-grant-helper.c b/polkit-grant/polkit-explicit-grant-helper.c
new file mode 100644
index 0000000..45f2bc4
--- /dev/null
+++ b/polkit-grant/polkit-explicit-grant-helper.c
@@ -0,0 +1,252 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/***************************************************************************
+ *
+ * polkit-explicit-grant-helper.c : setgid polkituser explicit grant
+ * helper for PolicyKit
+ *
+ * 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/time.h>
+#include <sys/types.h>
+#include <sys/stat.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 <polkit-dbus/polkit-dbus.h>
+#include <polkit/polkit-private.h>
+
+static polkit_bool_t
+check_pid_for_authorization (pid_t caller_pid, const char *action_id)
+{
+ polkit_bool_t ret;
+ DBusError error;
+ DBusConnection *bus;
+ PolKitCaller *caller;
+ PolKitAction *action;
+ PolKitContext *context;
+
+ ret = FALSE;
+
+ dbus_error_init (&error);
+ bus = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
+ if (bus == NULL) {
+ fprintf (stderr, "polkit-read-auth-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-read-auth-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-read-auth-helper: cannot allocate PolKitAction\n");
+ goto out;
+ }
+ if (!polkit_action_set_action_id (action, action_id)) {
+ fprintf (stderr, "polkit-read-auth-helper: cannot set action_id\n");
+ goto out;
+ }
+
+ context = polkit_context_new ();
+ if (context == NULL) {
+ fprintf (stderr, "polkit-read-auth-helper: cannot allocate PolKitContext\n");
+ goto out;
+ }
+ if (!polkit_context_init (context, NULL)) {
+ fprintf (stderr, "polkit-read-auth-helper: cannot initialize polkit\n");
+ goto out;
+ }
+
+ if (polkit_context_is_caller_authorized (context, action, caller, FALSE) != POLKIT_RESULT_YES) {
+ //fprintf (stderr,
+ // "polkit-read-auth-helper: uid %d (pid %d) does not have the "
+ // "org.freedesktop.policykit.read-other-authorizations authorization\n",
+ // caller_uid, caller_pid);
+ goto out;
+ }
+
+ ret = TRUE;
+out:
+
+ return ret;
+}
+
+int
+main (int argc, char *argv[])
+{
+ int ret;
+ gid_t egid;
+ struct group *group;
+ uid_t invoking_uid;
+ char *action_id;
+ char *endp;
+ char grant_line[512];
+ struct timeval now;
+
+ 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-explicit-grant-helper", LOG_CONS | LOG_PID, LOG_AUTHPRIV);
+
+ /* check for correct invocation */
+ if (argc != 5) {
+ syslog (LOG_NOTICE, "inappropriate use of helper, wrong number of arguments [uid=%d]", getuid ());
+ fprintf (stderr, "polkit-explicit-grant-helper: wrong number of arguments. This incident has been logged.\n");
+ goto out;
+ }
+
+ /* 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-explicit-grant-helper: inappropriate use of helper, stdin is a tty. This incident has been logged.\n");
+ goto out;
+ }
+
+ invoking_uid = getuid ();
+
+ /* check that we are setgid polkituser */
+ egid = getegid ();
+ group = getgrgid (egid);
+ if (group == NULL) {
+ fprintf (stderr, "polkit-explicit-grant-helper: cannot lookup group info for gid %d\n", egid);
+ goto out;
+ }
+ if (strcmp (group->gr_name, POLKIT_GROUP) != 0) {
+ fprintf (stderr, "polkit-explicit-grant-helper: needs to be setgid " POLKIT_GROUP "\n");
+ goto out;
+ }
+
+ /*----------------------------------------------------------------------------------------------------*/
+
+ /* check and validate incoming parameters */
+
+ /* first one is action_id */
+ action_id = argv[1];
+ if (!polkit_action_validate_id (action_id)) {
+ syslog (LOG_NOTICE, "action_id is malformed [uid=%d]", getuid ());
+ fprintf (stderr, "polkit-explicit-grant-helper: action_id is malformed. This incident has been logged.\n");
+ goto out;
+ }
+
+ char *authc_str;
+ PolKitAuthorizationConstraint *authc;
+
+ /* second is the auth constraint */
+ authc_str = argv[2];
+ authc = polkit_authorization_constraint_from_string (authc_str);
+ if (authc == NULL) {
+ syslog (LOG_NOTICE, "auth constraint is malformed [uid=%d]", getuid ());
+ fprintf (stderr, "polkit-explicit-grant-helper: auth constraint is malformed. This incident has been logged.\n");
+ goto out;
+ }
+
+#define TARGET_UID 0
+ int target;
+ uid_t target_uid = -1;
+
+ /* (third, fourth) is one of: ("uid", uid) */
+ if (strcmp (argv[3], "uid") == 0) {
+
+ target = TARGET_UID;
+ target_uid = strtol (argv[4], &endp, 10);
+ if (*endp != '\0') {
+ syslog (LOG_NOTICE, "target uid is malformed [uid=%d]", getuid ());
+ fprintf (stderr, "polkit-explicit-grant-helper: target uid is malformed. This incident has been logged.\n");
+ goto out;
+ }
+ } else {
+ syslog (LOG_NOTICE, "target type is malformed [uid=%d]", getuid ());
+ fprintf (stderr, "polkit-explicit-grant-helper: target type is malformed. This incident has been logged.\n");
+ goto out;
+ }
+
+
+ //fprintf (stderr, "action_id=%s constraint=%s uid=%d\n", action_id, authc_str, target_uid);
+
+ /* OK, we're done parsing ... check if the user is authorized */
+
+ if (invoking_uid != 0) {
+ /* see if calling user is authorized for
+ *
+ * org.freedesktop.policykit.grant
+ */
+ if (!check_pid_for_authorization (getppid (), "org.freedesktop.policykit.grant")) {
+ goto out;
+ }
+ }
+
+ /* he is.. proceed to add the grant */
+
+ umask (002);
+
+ if (gettimeofday (&now, NULL) != 0) {
+ fprintf (stderr, "polkit-explicit-grant-helper: error calling gettimeofday: %m");
+ return FALSE;
+ }
+
+ if (snprintf (grant_line,
+ sizeof (grant_line),
+ "grant:%s:%Lu:%d:%s\n",
+ action_id,
+ (polkit_uint64_t) now.tv_sec,
+ invoking_uid,
+ authc_str) >= (int) sizeof (grant_line)) {
+ fprintf (stderr, "polkit-explicit-grant-helper: str to add is too long!\n");
+ goto out;
+ }
+
+ if (_polkit_authorization_db_auth_file_add (PACKAGE_LOCALSTATE_DIR "/lib/PolicyKit",
+ FALSE,
+ target_uid,
+ grant_line)) {
+ ret = 0;
+ }
+
+out:
+
+ return ret;
+}
+
diff --git a/polkit-grant/polkit-revoke-helper.c b/polkit-grant/polkit-revoke-helper.c
new file mode 100644
index 0000000..8e28d65
--- /dev/null
+++ b/polkit-grant/polkit-revoke-helper.c
@@ -0,0 +1,347 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/***************************************************************************
+ *
+ * polkit-revoke-helper.c : setgid polkituser revoke helper for PolicyKit
+ *
+ * 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/time.h>
+#include <sys/types.h>
+#include <sys/stat.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 <polkit-dbus/polkit-dbus.h>
+
+static polkit_bool_t
+check_for_revoke_authorization (pid_t caller_pid)
+{
+ polkit_bool_t ret;
+ DBusError error;
+ DBusConnection *bus;
+ PolKitCaller *caller;
+ PolKitAction *action;
+ PolKitContext *context;
+
+ ret = FALSE;
+
+ dbus_error_init (&error);
+ bus = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
+ if (bus == NULL) {
+ fprintf (stderr, "polkit-read-auth-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-read-auth-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-read-auth-helper: cannot allocate PolKitAction\n");
+ goto out;
+ }
+ if (!polkit_action_set_action_id (action, "org.freedesktop.policykit.revoke")) {
+ fprintf (stderr, "polkit-read-auth-helper: cannot set action_id\n");
+ goto out;
+ }
+
+ context = polkit_context_new ();
+ if (context == NULL) {
+ fprintf (stderr, "polkit-read-auth-helper: cannot allocate PolKitContext\n");
+ goto out;
+ }
+ if (!polkit_context_init (context, NULL)) {
+ fprintf (stderr, "polkit-read-auth-helper: cannot initialize polkit\n");
+ goto out;
+ }
+
+ if (polkit_context_is_caller_authorized (context, action, caller, FALSE) != POLKIT_RESULT_YES) {
+ goto out;
+ }
+
+ ret = TRUE;
+out:
+
+ return ret;
+}
+
+
+static int
+_write_to_fd (int fd, const char *str, ssize_t str_len)
+{
+ int ret;
+ ssize_t written;
+
+ ret = 0;
+
+ written = 0;
+ while (written < str_len) {
+ ssize_t ret;
+ ret = write (fd, str + written, str_len - written);
+ if (ret < 0) {
+ if (errno == EAGAIN || errno == EINTR) {
+ continue;
+ } else {
+ goto out;
+ }
+ }
+ written += ret;
+ }
+
+ ret = 1;
+
+out:
+ return ret;
+}
+
+int
+main (int argc, char *argv[])
+{
+ int ret;
+ gid_t egid;
+ struct group *group;
+ uid_t invoking_uid;
+ char *entry_to_remove;
+ int n;
+ int len;
+ char *p;
+ char *scope;
+ uid_t uid_to_revoke;
+ char *endp;
+ FILE *f;
+ int fd;
+ char path[256];
+ char path_tmp[256];
+ char line[512];
+ char *root;
+ char *target_type;
+ char *target_value;
+ struct passwd *pw;
+
+ 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-revoke-helper", LOG_CONS | LOG_PID, LOG_AUTHPRIV);
+
+ /* check for correct invocation */
+ if (argc != 4) {
+ syslog (LOG_NOTICE, "inappropriate use of helper, wrong number of arguments [uid=%d]", getuid ());
+ fprintf (stderr, "polkit-revoke-helper: wrong number of arguments. This incident has been logged.\n");
+ goto out;
+ }
+
+ /* 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-revoke-helper: inappropriate use of helper, stdin is a tty. This incident has been logged.\n");
+ goto out;
+ }
+
+ invoking_uid = getuid ();
+
+ /* check that we are setgid polkituser */
+ egid = getegid ();
+ group = getgrgid (egid);
+ if (group == NULL) {
+ fprintf (stderr, "polkit-revoke-helper: cannot lookup group info for gid %d\n", egid);
+ goto out;
+ }
+ if (strcmp (group->gr_name, POLKIT_GROUP) != 0) {
+ fprintf (stderr, "polkit-revoke-helper: needs to be setgid " POLKIT_GROUP "\n");
+ goto out;
+ }
+
+ entry_to_remove = argv[1];
+ target_type = argv[2];
+ target_value = argv[3];
+
+ /*----------------------------------------------------------------------------------------------------*/
+
+ /* paranoia: we have to validate the entry_to_remove argument
+ * and determine if the process who invoked us is sufficiently
+ * privileged.
+ *
+ * As we're setuid root we don't want to pull in libpolkit and
+ * as we only need to parse the first two entries... we do it
+ * right here
+ */
+ p = entry_to_remove;
+ len = strlen (entry_to_remove);
+ for (n = 0; n < len; n++) {
+ if (p[n] == ':')
+ goto found;
+ }
+ fprintf (stderr, "polkit-revoke-helper: entry_to_remove malformed\n");
+ goto out;
+found:
+ scope = strndup (entry_to_remove, n);
+ if (scope == NULL) {
+ fprintf (stderr, "polkit-revoke-helper: OOM\n");
+ goto out;
+ }
+
+ if (strcmp (target_type, "uid") == 0) {
+ uid_to_revoke = strtol (target_value, &endp, 10);
+ if (*endp != '\0') {
+ fprintf (stderr, "polkit-revoke-helper: cannot parse uid\n");
+ goto out;
+ }
+ } else {
+ fprintf (stderr, "polkit-revoke-helper: unknown target type\n");
+ goto out;
+ }
+
+ /* OK, we're done parsing ... */
+
+ if (invoking_uid != 0) {
+ /* Check that the caller is privileged to do this... */
+ if (invoking_uid != uid_to_revoke) {
+
+ /* see if calling user has the
+ *
+ * org.freedesktop.policykit.revoke
+ *
+ * authorization
+ */
+ if (!check_for_revoke_authorization (getppid ())) {
+ goto out;
+ }
+ }
+ }
+
+ if (strcmp (scope, "process") == 0) {
+ root = PACKAGE_LOCALSTATE_DIR "/run/PolicyKit";
+ } else if (strcmp (scope, "session") == 0) {
+ root = PACKAGE_LOCALSTATE_DIR "/run/PolicyKit";
+ } else if (strcmp (scope, "always") == 0) {
+ root = PACKAGE_LOCALSTATE_DIR "/lib/PolicyKit";
+ } else if (strcmp (scope, "grant") == 0) {
+ root = PACKAGE_LOCALSTATE_DIR "/lib/PolicyKit";
+ } else {
+ fprintf (stderr, "polkit-revoke-helper: unknown scope '%s'\n", scope);
+ goto out;
+ }
+
+ pw = getpwuid (uid_to_revoke);
+ if (pw == NULL) {
+ fprintf (stderr, "polkit-revoke-helper: cannot lookup user name for uid %d\n", uid_to_revoke);
+ goto out;
+ }
+
+ if (snprintf (path, sizeof (path), "%s/user-%s.auths", root, pw->pw_name) >= (int) sizeof (path)) {
+ fprintf (stderr, "polkit-revoke-helper: string was truncated (1)\n");
+ goto out;
+ }
+ if (snprintf (path_tmp, sizeof (path_tmp), "%s/user-%s.auths.XXXXXX", root, pw->pw_name) >= (int) sizeof (path)) {
+ fprintf (stderr, "polkit-revoke-helper: string was truncated (2)\n");
+ goto out;
+ }
+
+ f = fopen (path, "r");
+ if (f == NULL) {
+ fprintf (stderr, "Cannot open file '%s': %m\n", path);
+ goto out;
+ }
+
+ fd = mkstemp (path_tmp);
+ if (fd < 0) {
+ fprintf (stderr, "Cannot create file '%s': %m\n", path_tmp);
+ goto out;
+ }
+ if (fchmod (fd, 0464) != 0) {
+ fprintf (stderr, "Cannot change mode for '%s' to 0460: %m\n", path_tmp);
+ close (fd);
+ unlink (path_tmp);
+ goto out;
+ }
+
+
+ /* read one line at a time */
+ while (fgets (line, sizeof (line), f) != NULL) {
+ size_t line_len;
+
+ line_len = strlen (line);
+ if (line_len > 1 && line[line_len - 1] == '\n') {
+ if (strncmp (line, entry_to_remove, line_len - 1) == 0) {
+ /* woho, found it */
+ continue;
+ }
+ }
+
+ /* otherwise, just write the line to the temporary file */
+ if (!_write_to_fd (fd, line, line_len)) {
+ fprintf (stderr, "Error write to file '%s': %m\n", path_tmp);
+ close (fd);
+ unlink (path_tmp);
+ goto out;
+ }
+ }
+
+ fclose (f);
+ close (fd);
+
+ if (rename (path_tmp, path) != 0) {
+ fprintf (stderr, "Error renaming %s to %s: %m\n", path_tmp, path);
+ unlink (path_tmp);
+ goto out;
+ }
+
+ /* we're good now (if triggering a reload fails, so be it, we
+ * still did what the caller asked...)
+ */
+ ret = 0;
+
+ /* trigger a reload */
+ if (utimes (PACKAGE_LOCALSTATE_DIR "/lib/misc/PolicyKit.reload", NULL) != 0) {
+ fprintf (stderr, "Error updating access+modification time on file '%s': %m\n",
+ PACKAGE_LOCALSTATE_DIR "/lib/misc/PolicyKit.reload");
+ }
+
+out:
+
+ return ret;
+}
+
diff --git a/polkit/polkit-authorization-db-dummy.c b/polkit/polkit-authorization-db-dummy.c
index 3a5ea82..8936605 100644
--- a/polkit/polkit-authorization-db-dummy.c
+++ b/polkit/polkit-authorization-db-dummy.c
@@ -46,10 +46,7 @@
#include "polkit-utils.h"
#include "polkit-private.h"
-struct _PolKitAuthorizationDB
-{
- int refcount;
-};
+/* PolKitAuthorizationDB structure is defined in polkit/polkit-private.h */
PolKitAuthorizationDBCapability
polkit_authorization_db_get_capabilities (void)
@@ -180,52 +177,3 @@ polkit_authorization_db_foreach_for_action_for_uid (PolKitAuthorizationDB
{
return FALSE;
}
-
-polkit_bool_t
-polkit_authorization_db_add_entry_process (PolKitAuthorizationDB *authdb,
- PolKitAction *action,
- PolKitCaller *caller,
- uid_t user_authenticated_as)
-{
- return FALSE;
-}
-
-polkit_bool_t
-polkit_authorization_db_add_entry_session (PolKitAuthorizationDB *authdb,
- PolKitAction *action,
- PolKitCaller *caller,
- uid_t user_authenticated_as)
-{
- return FALSE;
-}
-
-polkit_bool_t
-polkit_authorization_db_add_entry_always (PolKitAuthorizationDB *authdb,
- PolKitAction *action,
- PolKitCaller *caller,
- uid_t user_authenticated_as)
-{
- return FALSE;
-}
-
-polkit_bool_t
-polkit_authorization_db_grant_to_uid (PolKitAuthorizationDB *authdb,
- PolKitAction *action,
- uid_t uid,
- PolKitAuthorizationConstraint *constraint,
- PolKitError **error)
-{
- polkit_error_set_error (error, POLKIT_ERROR_NOT_SUPPORTED, "Not supported");
- return FALSE;
-}
-
-polkit_bool_t
-polkit_authorization_db_revoke_entry (PolKitAuthorizationDB *authdb,
- PolKitAuthorization *auth,
- PolKitError **error)
-{
- polkit_error_set_error (error, POLKIT_ERROR_NOT_SUPPORTED, "Not supported");
- return FALSE;
-}
-
-
diff --git a/polkit/polkit-authorization-db.c b/polkit/polkit-authorization-db.c
index 30a5970..a47d4dc 100644
--- a/polkit/polkit-authorization-db.c
+++ b/polkit/polkit-authorization-db.c
@@ -49,10 +49,13 @@
/**
* SECTION:polkit-authorization-db
* @title: Authorization Database
- * @short_description: An interface to the database storing authorizations
+ * @short_description: Reading from and writing to the database storing authorizations
*
- * This class is used to represent entries in the authorization
- * database.
+ * This class presents an abstraction of the authorization database as
+ * well as methods for reading and writing to it.
+ *
+ * The reading parts are in <literal>libpolkit</literal> and the
+ * writing parts are in <literal>libpolkit-grant</literal>.
*
* Since: 0.7
**/
@@ -60,16 +63,14 @@
/**
* PolKitAuthorizationDB:
*
- * Objects of this class are used to represent entries in the
- * authorization database.
+ * Objects of this class are used to represent the authorization
+ * database.
*
* Since: 0.7
**/
-struct _PolKitAuthorizationDB
-{
- int refcount;
- GHashTable *uid_to_authlist;
-};
+struct _PolKitAuthorizationDB;
+
+/* PolKitAuthorizationDB structure is defined in polkit/polkit-private.h */
static void
_free_authlist (GSList *authlist)
@@ -897,462 +898,3 @@ out:
return ret;
}
-
-/**
- * polkit_authorization_db_add_entry_process:
- * @authdb: the authorization database
- * @action: the action
- * @caller: the caller
- * @user_authenticated_as: the user that was authenticated
- *
- * Write an entry to the authorization database to indicate that the
- * given caller is authorized for the given action.
- *
- * Note that this function should only be used by
- * <literal>libpolkit-grant</literal> or other sufficiently privileged
- * processes that deals with managing authorizations. It should never
- * be used by mechanisms or applications. The caller must have
- * egid=polkituser and umask set so creating files with mode 0460 will
- * work.
- *
- * Returns: #TRUE if an entry was written to the authorization
- * database, #FALSE if the caller of this function is not sufficiently
- * privileged.
- *
- * Since: 0.7
- */
-polkit_bool_t
-polkit_authorization_db_add_entry_process (PolKitAuthorizationDB *authdb,
- PolKitAction *action,
- PolKitCaller *caller,
- uid_t user_authenticated_as)
-{
- char *action_id;
- uid_t caller_uid;
- pid_t caller_pid;
- char *grant_line;
- polkit_bool_t ret;
- polkit_uint64_t pid_start_time;
- struct timeval now;
- PolKitAuthorizationConstraint *constraint;
- char cbuf[256];
-
- g_return_val_if_fail (authdb != NULL, FALSE);
- g_return_val_if_fail (action != NULL, FALSE);
- g_return_val_if_fail (caller != NULL, FALSE);
-
- if (!polkit_action_get_action_id (action, &action_id))
- return FALSE;
-
- if (!polkit_caller_get_pid (caller, &caller_pid))
- return FALSE;
-
- if (!polkit_caller_get_uid (caller, &caller_uid))
- return FALSE;
-
- pid_start_time = polkit_sysdeps_get_start_time_for_pid (caller_pid);
- if (pid_start_time == 0)
- return FALSE;
-
- if (gettimeofday (&now, NULL) != 0) {
- g_warning ("Error calling gettimeofday: %m");
- return FALSE;
- }
-
- constraint = polkit_authorization_constraint_get_from_caller (caller);
- if (polkit_authorization_constraint_to_string (constraint, cbuf, sizeof (cbuf)) >= sizeof (cbuf)) {
- g_warning ("buffer for auth constraint is too small");
- return FALSE;
- }
-
- grant_line = g_strdup_printf ("process:%d:%Lu:%s:%Lu:%d:%s\n",
- caller_pid,
- pid_start_time,
- action_id,
- (polkit_uint64_t) now.tv_sec,
- user_authenticated_as,
- cbuf);
-
- ret = _polkit_authorization_db_auth_file_add (PACKAGE_LOCALSTATE_DIR "/run/PolicyKit",
- TRUE,
- caller_uid,
- grant_line);
- g_free (grant_line);
- return ret;
-}
-
-/**
- * polkit_authorization_db_add_entry_session:
- * @authdb: the authorization database
- * @action: the action
- * @caller: the caller
- * @user_authenticated_as: the user that was authenticated
- *
- * Write an entry to the authorization database to indicate that the
- * session for the given caller is authorized for the given action for
- * the remainer of the session.
- *
- * Note that this function should only be used by
- * <literal>libpolkit-grant</literal> or other sufficiently privileged
- * processes that deals with managing authorizations. It should never
- * be used by mechanisms or applications. The caller must have
- * egid=polkituser and umask set so creating files with mode 0460 will
- * work.
- *
- * Returns: #TRUE if an entry was written to the authorization
- * database, #FALSE if the caller of this function is not sufficiently
- * privileged.
- *
- * Since: 0.7
- */
-polkit_bool_t
-polkit_authorization_db_add_entry_session (PolKitAuthorizationDB *authdb,
- PolKitAction *action,
- PolKitCaller *caller,
- uid_t user_authenticated_as)
-{
- uid_t session_uid;
- char *action_id;
- char *grant_line;
- PolKitSession *session;
- char *session_objpath;
- polkit_bool_t ret;
- struct timeval now;
- PolKitAuthorizationConstraint *constraint;
- char cbuf[256];
-
- g_return_val_if_fail (authdb != NULL, FALSE);
- g_return_val_if_fail (action != NULL, FALSE);
- g_return_val_if_fail (caller != NULL, FALSE);
-
- if (!polkit_action_get_action_id (action, &action_id))
- return FALSE;
-
- if (!polkit_caller_get_ck_session (caller, &session))
- return FALSE;
-
- if (!polkit_session_get_ck_objref (session, &session_objpath))
- return FALSE;
-
- if (!polkit_session_get_uid (session, &session_uid))
- return FALSE;
-
- constraint = polkit_authorization_constraint_get_from_caller (caller);
- if (polkit_authorization_constraint_to_string (constraint, cbuf, sizeof (cbuf)) >= sizeof (cbuf)) {
- g_warning ("buffer for auth constraint is too small");
- return FALSE;
- }
-
- if (gettimeofday (&now, NULL) != 0) {
- g_warning ("Error calling gettimeofday: %m");
- return FALSE;
- }
-
- grant_line = g_strdup_printf ("session:%s:%s:%Lu:%d:%s\n",
- session_objpath,
- action_id,
- (polkit_uint64_t) now.tv_sec,
- user_authenticated_as,
- cbuf);
-
- ret = _polkit_authorization_db_auth_file_add (PACKAGE_LOCALSTATE_DIR "/run/PolicyKit",
- TRUE,
- session_uid,
- grant_line);
- g_free (grant_line);
- return ret;
-}
-
-/**
- * polkit_authorization_db_add_entry_always:
- * @authdb: the authorization database
- * @action: the action
- * @caller: the caller
- * @user_authenticated_as: the user that was authenticated
- *
- * Write an entry to the authorization database to indicate that the
- * given user is authorized for the given action.
- *
- * Note that this function should only be used by
- * <literal>libpolkit-grant</literal> or other sufficiently privileged
- * processes that deals with managing authorizations. It should never
- * be used by mechanisms or applications. The caller must have
- * egid=polkituser and umask set so creating files with mode 0460 will
- * work.
- *
- * Returns: #TRUE if an entry was written to the authorization
- * database, #FALSE if the caller of this function is not sufficiently
- * privileged.
- *
- * Since: 0.7
- */
-polkit_bool_t
-polkit_authorization_db_add_entry_always (PolKitAuthorizationDB *authdb,
- PolKitAction *action,
- PolKitCaller *caller,
- uid_t user_authenticated_as)
-{
- uid_t uid;
- char *action_id;
- char *grant_line;
- polkit_bool_t ret;
- struct timeval now;
- PolKitAuthorizationConstraint *constraint;
- char cbuf[256];
-
- g_return_val_if_fail (authdb != NULL, FALSE);
- g_return_val_if_fail (action != NULL, FALSE);
- g_return_val_if_fail (caller != NULL, FALSE);
-
- if (!polkit_caller_get_uid (caller, &uid))
- return FALSE;
-
- if (!polkit_action_get_action_id (action, &action_id))
- return FALSE;
-
- if (gettimeofday (&now, NULL) != 0) {
- g_warning ("Error calling gettimeofday: %m");
- return FALSE;
- }
-
- constraint = polkit_authorization_constraint_get_from_caller (caller);
- if (polkit_authorization_constraint_to_string (constraint, cbuf, sizeof (cbuf)) >= sizeof (cbuf)) {
- g_warning ("buffer for auth constraint is too small");
- return FALSE;
- }
-
- grant_line = g_strdup_printf ("always:%s:%Lu:%d:%s\n",
- action_id,
- (polkit_uint64_t) now.tv_sec,
- user_authenticated_as,
- cbuf);
-
- ret = _polkit_authorization_db_auth_file_add (PACKAGE_LOCALSTATE_DIR "/lib/PolicyKit",
- FALSE,
- uid,
- grant_line);
- g_free (grant_line);
- return ret;
-}
-
-/**
- * polkit_authorization_db_revoke_entry:
- * @authdb: the authorization database
- * @auth: the authorization to revoke
- * @error: return location for error
- *
- * Removes an authorization from the authorization database. This uses
- * a privileged helper /usr/libexec/polkit-revoke-helper.
- *
- * Returns: #TRUE if the authorization was revoked, #FALSE otherwise and error is set
- *
- * Since: 0.7
- */
-polkit_bool_t
-polkit_authorization_db_revoke_entry (PolKitAuthorizationDB *authdb,
- PolKitAuthorization *auth,
- PolKitError **error)
-{
- GError *g_error;
- char *helper_argv[] = {PACKAGE_LIBEXEC_DIR "/polkit-revoke-helper", "", NULL, NULL, NULL};
- const char *auth_file_entry;
- gboolean ret;
- gint exit_status;
-
- ret = FALSE;
-
- g_return_val_if_fail (authdb != NULL, FALSE);
- g_return_val_if_fail (auth != NULL, FALSE);
-
- auth_file_entry = _polkit_authorization_get_authfile_entry (auth);
- //g_debug ("should delete line '%s'", auth_file_entry);
-
- helper_argv[1] = (char *) auth_file_entry;
- helper_argv[2] = "uid";
- helper_argv[3] = g_strdup_printf ("%d", polkit_authorization_get_uid (auth));
-
- g_error = NULL;
- if (!g_spawn_sync (NULL, /* const gchar *working_directory */
- helper_argv, /* gchar **argv */
- NULL, /* gchar **envp */
- 0, /* GSpawnFlags flags */
- NULL, /* GSpawnChildSetupFunc child_setup */
- NULL, /* gpointer user_data */
- NULL, /* gchar **standard_output */
- NULL, /* gchar **standard_error */
- &exit_status, /* gint *exit_status */
- &g_error)) { /* GError **error */
- polkit_error_set_error (error,
- POLKIT_ERROR_GENERAL_ERROR,
- "Error spawning revoke helper: %s",
- g_error->message);
- g_error_free (g_error);
- goto out;
- }
-
- if (!WIFEXITED (exit_status)) {
- g_warning ("Revoke helper crashed!");
- polkit_error_set_error (error,
- POLKIT_ERROR_GENERAL_ERROR,
- "Revoke helper crashed!");
- goto out;
- } else if (WEXITSTATUS(exit_status) != 0) {
- polkit_error_set_error (error,
- POLKIT_ERROR_NOT_AUTHORIZED_TO_REVOKE_AUTHORIZATIONS_FROM_OTHER_USERS,
- "uid %d is not authorized to revoke authorizations from uid %d (requires org.freedesktop.policykit.revoke)",
- getuid (), polkit_authorization_get_uid (auth));
- } else {
- ret = TRUE;
- }
-
-out:
- g_free (helper_argv[3]);
- return ret;
-}
-
-typedef struct {
- char *action_id;
- PolKitAuthorizationConstraint *constraint;
-} CheckDataGrant;
-
-static polkit_bool_t
-_check_auth_for_grant (PolKitAuthorizationDB *authdb, PolKitAuthorization *auth, void *user_data)
-{
- uid_t pimp;
- polkit_bool_t ret;
- CheckDataGrant *cd = (CheckDataGrant *) user_data;
-
- ret = FALSE;
-
- if (strcmp (polkit_authorization_get_action_id (auth), cd->action_id) != 0)
- goto no_match;
-
- if (!polkit_authorization_was_granted_explicitly (auth, &pimp))
- goto no_match;
-
- if (!polkit_authorization_constraint_equal (polkit_authorization_get_constraint (auth), cd->constraint))
- goto no_match;
-
- ret = TRUE;
-
-no_match:
- return ret;
-}
-
-/**
- * polkit_authorization_db_grant_to_uid:
- * @authdb: authorization database
- * @action: action
- * @uid: uid to grant to
- * @constraint: what constraint to put on the authorization
- * @error: return location for error
- *
- * Grants an authorization to a user for a specific action. This
- * requires the org.freedesktop.policykit.grant authorization.
- *
- * Returns: #TRUE if the authorization was granted, #FALSE otherwise
- * and error will be set
- *
- * Since: 0.7
- */
-polkit_bool_t
-polkit_authorization_db_grant_to_uid (PolKitAuthorizationDB *authdb,
- PolKitAction *action,
- uid_t uid,
- PolKitAuthorizationConstraint *constraint,
- PolKitError **error)
-{
- GError *g_error;
- char *helper_argv[6] = {PACKAGE_LIBEXEC_DIR "/polkit-explicit-grant-helper", NULL, NULL, NULL, NULL, NULL};
- gboolean ret;
- gint exit_status;
- char cbuf[256];
- CheckDataGrant cd;
-
- ret = FALSE;
-
- g_return_val_if_fail (authdb != NULL, FALSE);
- g_return_val_if_fail (action != NULL, FALSE);
- g_return_val_if_fail (constraint != NULL, FALSE);
-
- if (!polkit_action_get_action_id (action, &(cd.action_id))) {
- polkit_error_set_error (error,
- POLKIT_ERROR_GENERAL_ERROR,
- "Given action does not have action_id set");
- goto out;
- }
-
- if (polkit_authorization_constraint_to_string (constraint, cbuf, sizeof (cbuf)) >= sizeof (cbuf)) {
- g_warning ("buffer for auth constraint is too small");
- polkit_error_set_error (error,
- POLKIT_ERROR_GENERAL_ERROR,
- "buffer for auth constraint is too small");
- goto out;
- }
-
- /* check if we have the auth already */
- cd.constraint = constraint;
- if (!polkit_authorization_db_foreach_for_uid (authdb,
- uid,
- _check_auth_for_grant,
- &cd,
- error)) {
- /* happens if caller can't read auths of target user */
- if (error != NULL && polkit_error_is_set (*error)) {
- goto out;
- }
- } else {
- /* so it did exist.. */
- polkit_error_set_error (error,
- POLKIT_ERROR_AUTHORIZATION_ALREADY_EXISTS,
- "An authorization for uid %d for the action %s with constraint '%s' already exists",
- uid, cd.action_id, cbuf);
- goto out;
- }
-
-
- helper_argv[1] = cd.action_id;
- helper_argv[2] = cbuf;
- helper_argv[3] = "uid";
- helper_argv[4] = g_strdup_printf ("%d", uid);
- helper_argv[5] = NULL;
-
- g_error = NULL;
- if (!g_spawn_sync (NULL, /* const gchar *working_directory */
- helper_argv, /* gchar **argv */
- NULL, /* gchar **envp */
- 0, /* GSpawnFlags flags */
- NULL, /* GSpawnChildSetupFunc child_setup */
- NULL, /* gpointer user_data */
- NULL, /* gchar **standard_output */
- NULL, /* gchar **standard_error */
- &exit_status, /* gint *exit_status */
- &g_error)) { /* GError **error */
- polkit_error_set_error (error,
- POLKIT_ERROR_GENERAL_ERROR,
- "Error spawning explicit grant helper: %s",
- g_error->message);
- g_error_free (g_error);
- goto out;
- }
-
- if (!WIFEXITED (exit_status)) {
- g_warning ("Explicit grant helper crashed!");
- polkit_error_set_error (error,
- POLKIT_ERROR_GENERAL_ERROR,
- "Explicit grant helper crashed!");
- goto out;
- } else if (WEXITSTATUS(exit_status) != 0) {
- polkit_error_set_error (error,
- POLKIT_ERROR_NOT_AUTHORIZED_TO_GRANT_AUTHORIZATION,
- "uid %d is not authorized to grant authorization for action %s to uid %d (requires org.freedesktop.policykit.grant)",
- getuid (), cd.action_id, uid);
- } else {
- ret = TRUE;
- }
-
-out:
- g_free (helper_argv[4]);
- return ret;
-
-}
diff --git a/polkit/polkit-private.h b/polkit/polkit-private.h
index 30e5eb4..e0c8c14 100644
--- a/polkit/polkit-private.h
+++ b/polkit/polkit-private.h
@@ -87,6 +87,22 @@ void _polkit_policy_file_entry_set_descriptions (PolKitPolicyFileEntry *pfe,
const char *policy_message);
+#ifdef POLKIT_AUTHDB_DUMMY
+struct _PolKitAuthorizationDB
+{
+ /*< private >*/
+ int refcount;
+};
+#elif POLKIT_AUTHDB_DEFAULT
+struct _PolKitAuthorizationDB
+{
+ /*< private >*/
+ int refcount;
+ GHashTable *uid_to_authlist;
+};
+
+#endif
+
POLKIT_END_DECLS
#endif /* POLKIT_PRIVATE_H */
More information about the hal-commit
mailing list