PolicyKit: Branch 'master'
David Zeuthen
david at kemper.freedesktop.org
Sun Apr 15 15:51:23 PDT 2007
Makefile.am | 11
configure.in | 196 ++++++++
doc/api/Makefile.am | 2
doc/api/libpolkit-dbus/Makefile.am | 67 ++
doc/api/libpolkit-dbus/libpolkit-dbus-docs.xml | 109 ++++
doc/api/libpolkit-dbus/version.xml | 1
doc/api/libpolkit-grant/Makefile.am | 67 ++
doc/api/libpolkit-grant/libpolkit-grant-docs.xml | 109 ++++
doc/api/libpolkit-grant/version.xml | 1
doc/api/libpolkit/libpolkit-docs.xml | 3
libpolkit-dbus/Makefile.am | 31 +
libpolkit-dbus/libpolkit-dbus.c | 540 +++++++++++++++++++++++
libpolkit-dbus/libpolkit-dbus.h | 41 +
libpolkit-grant/Makefile.am | 54 ++
libpolkit-grant/libpolkit-grant.c | 465 +++++++++++++++++++
libpolkit-grant/libpolkit-grant.h | 344 ++++++++++++++
libpolkit-grant/polkit-grant-helper.c | 514 +++++++++++++++++++++
libpolkit.pc.in | 2
libpolkit/Makefile.am | 8
libpolkit/libpolkit-action.c | 26 -
libpolkit/libpolkit-action.h | 11
libpolkit/libpolkit-caller.c | 220 ++-------
libpolkit/libpolkit-caller.h | 34 -
libpolkit/libpolkit-context.c | 26 -
libpolkit/libpolkit-context.h | 8
libpolkit/libpolkit-debug.c | 12
libpolkit/libpolkit-error.c | 6
libpolkit/libpolkit-error.h | 4
libpolkit/libpolkit-module.c | 70 +-
libpolkit/libpolkit-module.h | 18
libpolkit/libpolkit-policy-cache.h | 4
libpolkit/libpolkit-policy-default.c | 22
libpolkit/libpolkit-policy-default.h | 16
libpolkit/libpolkit-policy-file-entry.h | 4
libpolkit/libpolkit-policy-file.h | 4
libpolkit/libpolkit-resource.c | 40 +
libpolkit/libpolkit-resource.h | 16
libpolkit/libpolkit-result.c | 6
libpolkit/libpolkit-result.h | 23
libpolkit/libpolkit-seat.c | 33 +
libpolkit/libpolkit-seat.h | 19
libpolkit/libpolkit-session.c | 339 +++-----------
libpolkit/libpolkit-session.h | 38 -
libpolkit/libpolkit-types.h | 56 ++
libpolkit/libpolkit-utils.c | 153 ++++++
libpolkit/libpolkit-utils.h | 37 +
libpolkit/libpolkit.h | 15
modules/Makefile.am | 2
modules/PolicyKit.conf | 1
modules/allow-all/polkit-module-allow-all.c | 17
modules/default/polkit-module-default.c | 17
modules/deny-all/polkit-module-deny-all.c | 17
modules/grant/Makefile.am | 25 +
modules/grant/polkit-module-grant.c | 194 ++++++++
modules/run-program/polkit-module-run-program.c | 70 +-
tools/Makefile.am | 9
tools/polkit-check-caller.c | 2
tools/polkit-check-session.c | 2
tools/polkit-grant.c | 425 ++++++++++++++++++
tools/polkit-policy-file-validate.c | 2
60 files changed, 3950 insertions(+), 658 deletions(-)
New commits:
diff-tree a0570c50359b7044c38c46fd0527bb8bcb45e271 (from 192f04cef946c0ebe5f90c8dbecc933b6ac3c197)
Author: David Zeuthen <davidz at redhat.com>
Date: Sun Apr 15 18:51:19 2007 -0400
add grant functionality + lots of other changes
- Split libpolkit into three libraries
- libpolkit : to be used only by mechanisms and modules
- libpolkit-dbus : utility library for libpolkit to get caller, session
etc. info from the bus and ConsoleKit
- libpolkit-grant : client side library for obtaining privileges; uses
a setgid helper internally
- grant functionality
- a helper library, libpolkit-grant, to gain privileges
- includes a setgid $POLKIT_GROUP helper to write granted privileges
- a PK module, to read and interpret granted privileges
- a cmdline app, polkit-grant, using said library
- Other changes
- so it turns out that sizeof(bool) != sizeof(gboolean), sizeof(dbus_bool_t)
This blows so define our own polkit_bool_t type
- add some validation routines
The grant functionality, especially the setgid helper needs thorough
security review before we can release it.
diff --git a/Makefile.am b/Makefile.am
index 3270435..cf1dbb7 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,11 +1,14 @@
## Process this file with automake to produce Makefile.in
-SUBDIRS = libpolkit modules doc tools policy
+SUBDIRS = libpolkit libpolkit-dbus libpolkit-grant modules doc tools policy
+
+pamdir = $(sysconfdir)/pam.d
+pam_DATA = polkit
pkgconfigdir = $(libdir)/pkgconfig
-pkgconfig_DATA = libpolkit.pc
+pkgconfig_DATA = libpolkit.pc libpolkit-dbus.pc libpolkit-grant.pc
-DISTCLEANFILES = libpolkit.pc
+DISTCLEANFILES = libpolkit.pc libpolkit-dbus.pc libpolkit-grant.pc
# Creating ChangeLog from git log (taken from cairo/Makefile.am):
ChangeLog: $(srcdir)/ChangeLog
@@ -26,7 +29,7 @@ $(srcdir)/ChangeLog:
.PHONY: ChangeLog $(srcdir)/ChangeLog
-EXTRA_DIST = HACKING libpolkit.pc.in mkinstalldirs ChangeLog
+EXTRA_DIST = HACKING polkit.in libpolkit.pc.in libpolkit-dbus.pc.in libpolkit-grant.pc.in mkinstalldirs ChangeLog
clean-local :
rm -f *~
diff --git a/configure.in b/configure.in
index 6f839e8..126b9b1 100644
--- a/configure.in
+++ b/configure.in
@@ -161,15 +161,187 @@ if test "x$GCC" = "xyes"; then
LDFLAGS="-Wl,--as-needed $LDFLAGS"
fi
+dnl ---------------------------------------------------------------------------
+dnl - User and group
+dnl ---------------------------------------------------------------------------
+
+AC_ARG_WITH(polkit_user,[ --with-polkit-user=<user> user for PolicyKit])
+if test -z "$with_polkit_user" ; then
+ POLKIT_USER=polkit
+else
+ POLKIT_USER=$with_polkit_user
+fi
+AC_SUBST(POLKIT_USER)
+AC_DEFINE_UNQUOTED(POLKIT_USER, "$POLKIT_USER", [User for PolicyKit])
+
+AC_ARG_WITH(polkit_group,[ --with-polkit-group=<grp> group for PolicyKit])
+if test -z "$with_polkit_group" ; then
+ POLKIT_GROUP=polkit
+else
+ POLKIT_GROUP=$with_polkit_group
+fi
+AC_SUBST(POLKIT_GROUP)
+AC_DEFINE_UNQUOTED(POLKIT_GROUP,"$POLKIT_GROUP", [Group for PolicyKit])
+
+dnl ---------------------------------------------------------------------------
+dnl - Check for PAM
+dnl ---------------------------------------------------------------------------
+
+withval=""
+AC_ARG_WITH(pam-prefix,
+[ --with-pam-prefix=<prefix> specify where pam files go],[
+if test x$withval != x; then
+ AC_MSG_RESULT("PAM files will be installed in prefix ${withval}.")
+fi])
+if test x$withval != x; then
+ PAM_PREFIX_UNEXPANDED="$withval"
+else
+ PAM_PREFIX_UNEXPANDED="$sysconfdir"
+fi
+PAM_PREFIX=`eval echo $PAM_PREFIX_UNEXPANDED`
+AC_SUBST(PAM_PREFIX)
+
+have_pam=no
+AC_CHECK_LIB(pam, pam_start, have_pam=yes)
+if test x$have_pam = xno; then
+ AC_ERROR([Could not find pam/pam-devel, please install the needed packages.])
+else
+ AUTH_LIBS="${AUTH_LIBS} -lpam"
+ AC_DEFINE(HAVE_PAM, 1, [Define if PAM support is included])
+
+ # On Linux, sigtimedwait() is in libc; on Solaris, it's in librt.
+ have_timedwait=no
+ AC_CHECK_LIB(c, sigtimedwait, [have_timedwait=yes])
+ if test "$have_timedwait" = no ; then
+ AC_CHECK_LIB(rt, sigtimedwait, [AUTH_LIBS="${AUTH_LIBS} -lrt"])
+ fi
+
+ AC_MSG_CHECKING(how to call pam_strerror)
+ AC_CACHE_VAL(ac_cv_pam_strerror_args,
+ [AC_TRY_COMPILE([#include <stdio.h>
+ #include <stdlib.h>
+ #include <security/pam_appl.h>],
+ [pam_handle_t *pamh = 0;
+ char *s = pam_strerror(pamh, PAM_SUCCESS);],
+ [ac_pam_strerror_args=2],
+ [AC_TRY_COMPILE([#include <stdio.h>
+ #include <stdlib.h>
+ #include <security/pam_appl.h>],
+ [char *s =
+ pam_strerror(PAM_SUCCESS);],
+ [ac_pam_strerror_args=1],
+ [ac_pam_strerror_args=0])])
+ ac_cv_pam_strerror_args=$ac_pam_strerror_args])
+ ac_pam_strerror_args=$ac_cv_pam_strerror_args
+ if test "$ac_pam_strerror_args" = 1 ; then
+ AC_MSG_RESULT(one argument)
+ elif test "$ac_pam_strerror_args" = 2 ; then
+ AC_DEFINE(PAM_STRERROR_TWO_ARGS, 1, [Define if pam_strerror takes two arguments])
+ AC_MSG_RESULT(two arguments)
+ else
+ AC_MSG_RESULT(unknown)
+ fi
+
+fi
+
+AM_CONDITIONAL(HAVE_PAM, test x$have_pam = xyes)
+AC_SUBST(HAVE_PAM)
+AC_SUBST(AUTH_LIBS)
+
+AC_CHECK_HEADER(security/pam_modutil.h, [AC_DEFINE(HAVE_PAM_MODUTIL_H, [], "Have pam_modutil.h")])
+AC_CHECK_HEADER(security/pam_ext.h, [AC_DEFINE(HAVE_PAM_EXT_H, [], "Have pam_ext.h")])
+AC_CHECK_LIB(pam, pam_vsyslog, [AC_DEFINE(HAVE_PAM_VSYSLOG, [], "Have pam_vsyslog")])
+
+AC_ARG_WITH(pam-module-dir, [ --with-pam-module-dir=[dirname] directory to install PAM security module])
+if ! test -z "$with_pam_module_dir"; then
+ PAM_MODULE_DIR=$with_pam_module_dir
+else
+ PAM_MODULE_DIR="/lib/security"
+fi
+
+AC_SUBST(PAM_MODULE_DIR)
+
+AC_ARG_WITH(os-type, [ --with-os-type=<os> distribution or OS (redhat)])
+
+#### Check our operating system (distro-tweaks required)
+if test "z$with_os_type" = "z"; then
+ AC_CHECK_FILE(/etc/redhat-release,distro_type="redhat")
+ AC_CHECK_FILE(/etc/SuSE-release,distro_type="suse")
+ if test "z$distro_type" = "z"; then
+ echo "Linux distribution autodetection failed, specify the distribution to target using --with-os-type="
+ else
+ operating_system=`echo ${distro_type} | tr '[[:upper:]]' '[[:lower:]]' `
+ fi
+fi
+
+#### Sort out OS (distro-tweaks required)
+if test x$with_os_type = x; then
+ if test x$operating_system = xredhat ; then
+ with_os_type=redhat
+ elif test x$operating_system = xsuse ; then
+ with_os_type=suse
+ else
+ with_os_type=unknown
+ fi
+fi
+
+# (distro-tweaks required)
+AM_CONDITIONAL(OS_TYPE_UNKNOWN, test x$with_os_type = xunknown, [Running on unknown OS])
+AM_CONDITIONAL(OS_TYPE_RED_HAT, test x$with_os_type = xredhat, [Running on Red Hat OS'es])
+AM_CONDITIONAL(OS_TYPE_SUSE, test x$with_os_type = xsuse, [Running on SUSE OS'es])
+
+AC_ARG_WITH(pam-include, [ --with-pam-include=<file> pam file to include])
+
+#### Set up pam file to include (distro-tweaks required)
+if ! test -z "$with_pam_include"; then
+ PAM_FILE_INCLUDE_AUTH=$with_pam_include
+ PAM_FILE_INCLUDE_ACCOUNT=$with_pam_include
+ PAM_FILE_INCLUDE_PASSWORD=$with_pam_include
+ PAM_FILE_INCLUDE_SESSION=$with_pam_include
+elif test x$with_os_type = xredhat ; then
+ PAM_FILE_INCLUDE_AUTH=system-auth
+ PAM_FILE_INCLUDE_ACCOUNT=system-auth
+ PAM_FILE_INCLUDE_PASSWORD=system-auth
+ PAM_FILE_INCLUDE_SESSION=system-auth
+elif test x$with_os_type = xsuse ; then
+ PAM_FILE_INCLUDE_AUTH=common-auth
+ PAM_FILE_INCLUDE_ACCOUNT=common-account
+ PAM_FILE_INCLUDE_PASSWORD=common-password
+ PAM_FILE_INCLUDE_SESSION=common-session
+else
+ PAM_FILE_INCLUDE_AUTH=system-auth
+ PAM_FILE_INCLUDE_ACCOUNT=system-auth
+ PAM_FILE_INCLUDE_PASSWORD=system-auth
+ PAM_FILE_INCLUDE_SESSION=system-auth
+fi
+
+AC_SUBST(PAM_FILE_INCLUDE_AUTH)
+AC_SUBST(PAM_FILE_INCLUDE_ACCOUNT)
+AC_SUBST(PAM_FILE_INCLUDE_PASSWORD)
+AC_SUBST(PAM_FILE_INCLUDE_SESSION)
+AC_DEFINE_UNQUOTED(PAM_FILE_INCLUDE_AUTH, "$PAM_FILE_INCLUDE_AUTH", [pam file auth])
+AC_DEFINE_UNQUOTED(PAM_FILE_INCLUDE_ACCOUNT, "$PAM_FILE_INCLUDE_ACCOUNT", [pam file account])
+AC_DEFINE_UNQUOTED(PAM_FILE_INCLUDE_PASSWORD, "$PAM_FILE_INCLUDE_PASSWORD", [pam file password])
+AC_DEFINE_UNQUOTED(PAM_FILE_INCLUDE_SESSION, "$PAM_FILE_INCLUDE_SESSION", [pam file session])
+
AC_OUTPUT([
libpolkit.pc
+libpolkit-dbus.pc
+libpolkit-grant.pc
Makefile
+polkit
libpolkit/Makefile
+libpolkit-dbus/Makefile
+libpolkit-grant/Makefile
tools/Makefile
doc/Makefile
doc/api/Makefile
doc/api/libpolkit/Makefile
doc/api/libpolkit/version.xml
+doc/api/libpolkit-dbus/Makefile
+doc/api/libpolkit-dbus/version.xml
+doc/api/libpolkit-grant/Makefile
+doc/api/libpolkit-grant/version.xml
doc/spec/Makefile
doc/spec/polkit-spec.xml.in
doc/man/Makefile
@@ -179,6 +351,7 @@ modules/default/Makefile
modules/allow-all/Makefile
modules/deny-all/Makefile
modules/run-program/Makefile
+modules/grant/Makefile
])
dnl ==========================================================================
@@ -202,9 +375,32 @@ echo "
xmlto: ${XMLTO}
xmllint: ${XMLLINT}
+ user for PolicyKit: ${POLKIT_USER}
+ group for PolicyKit: ${POLKIT_GROUP}
+
+ Distribution/OS: ${with_os_type}
+
+ PAM support: ${have_pam}
+ PAM file auth: ${PAM_FILE_INCLUDE_AUTH}
+ PAM file account: ${PAM_FILE_INCLUDE_ACCOUNT}
+ PAM file password: ${PAM_FILE_INCLUDE_PASSWORD}
+ PAM file session: ${PAM_FILE_INCLUDE_SESSION}
+
Maintainer mode: ${USE_MAINTAINER_MODE}
Building verbose mode: ${enable_verbose_mode}
Building api docs: ${enable_gtk_doc}
Building docs: ${enable_docbook_docs}
Building man pages: ${enable_man_pages}
"
+
+echo "NOTE: Remember to create user '${POLKIT_USER}' and group '${POLKIT_GROUP}' before 'make install'"
+echo
+
+echo "NOTE: ${libexecdir}/polkit-grant-helper will be owner by group"
+echo " '${POLKIT_USER}', and installed with mode 2755 (setgid binary)."
+echo " The directories ${localstatedir}/run/PolicyKit and ${localstatedir}/lib/PolicyKit will be"
+echo " owned by user '${POLKIT_USER}' and group '${POLKIT_GROUP}' and will be of mode 775."
+echo
+
+echo "NOTE: For packaging, remember to retain the modes and ownership."
+echo
diff --git a/doc/api/Makefile.am b/doc/api/Makefile.am
index 3c12eb0..46809b2 100644
--- a/doc/api/Makefile.am
+++ b/doc/api/Makefile.am
@@ -1,6 +1,6 @@
## Process this file with automake to create Makefile.in.
-SUBDIRS = libpolkit
+SUBDIRS = libpolkit libpolkit-dbus libpolkit-grant
MAINTAINERCLEANFILES = \
*~ \
diff --git a/doc/api/libpolkit-dbus/Makefile.am b/doc/api/libpolkit-dbus/Makefile.am
new file mode 100644
index 0000000..c539267
--- /dev/null
+++ b/doc/api/libpolkit-dbus/Makefile.am
@@ -0,0 +1,67 @@
+## Process this file with automake to create Makefile.in.
+
+NULL =
+
+AUTOMAKE_OPTIONS = 1.7
+
+# The name of the module.
+DOC_MODULE=libpolkit-dbus
+
+# The top-level SGML file.
+DOC_MAIN_SGML_FILE=libpolkit-dbus-docs.xml
+
+# Extra options to supply to gtkdoc-scan
+#SCAN_OPTIONS=--deprecated-guards="CAIRO_DISABLE_DEPRECATED"
+
+# The directory containing the source code. Relative to $(srcdir)
+DOC_SOURCE_DIR=../../../libpolkit-dbus
+
+# Used for dependencies
+HFILE_GLOB=$(top_srcdir)/libpolkit-dbus/*.h
+CFILE_GLOB=$(top_srcdir)/libpolkit-dbus/*.c
+
+# Headers to ignore
+IGNORE_HFILES= \
+ $(NULL)
+
+# CFLAGS and LDFLAGS for compiling scan program. Only needed
+# if $(DOC_MODULE).types is non-empty.
+INCLUDES = \
+ $(GLIB_CFLAGS) \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ $(NULL)
+
+GTKDOC_LIBS = \
+ $(GLIB_LIBS) \
+ $(top_builddir)/libpolkit-dbus/libpolkit-dbus.la \
+ $(NULL)
+
+# Extra options to supply to gtkdoc-mkdb
+MKDB_OPTIONS=--sgml-mode --output-format=xml
+
+# Extra options to supply to gtkdoc-mktmpl
+MKTMPL_OPTIONS=
+
+# Non-autogenerated SGML files to be included in $(DOC_MAIN_SGML_FILE)
+content_files = \
+ version.xml \
+ $(NULL)
+
+# Images to copy into HTML directory
+HTML_IMAGES =
+
+# Extra options to supply to gtkdoc-fixref
+FIXXREF_OPTIONS=
+
+MAINTAINERCLEANFILES = \
+ *~ \
+ Makefile.in \
+ libpolkit-dbus.types \
+ libpolkit-dbus-*.txt \
+ $(NULL)
+
+include $(top_srcdir)/gtk-doc.make
+
+# Version information for marking the documentation
+EXTRA_DIST += version.xml.in
diff --git a/doc/api/libpolkit-dbus/libpolkit-dbus-docs.xml b/doc/api/libpolkit-dbus/libpolkit-dbus-docs.xml
new file mode 100644
index 0000000..9dcf978
--- /dev/null
+++ b/doc/api/libpolkit-dbus/libpolkit-dbus-docs.xml
@@ -0,0 +1,109 @@
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
+<!ENTITY version SYSTEM "version.xml">
+]>
+<book id="index" xmlns:xi="http://www.w3.org/2003/XInclude">
+ <bookinfo>
+ <title>PolicyKit D-Bus Helper Library Reference Manual</title>
+ <releaseinfo>Version &version;</releaseinfo>
+ <authorgroup>
+ <author>
+ <firstname>David</firstname>
+ <surname>Zeuthen</surname>
+ <affiliation>
+ <address>
+ <email>david at fubar.dk</email>
+ </address>
+ </affiliation>
+ </author>
+ </authorgroup>
+
+ <copyright>
+ <year>2007</year>
+ <holder>The PolicyKit Authors</holder>
+ </copyright>
+
+ <legalnotice>
+ <para>
+ Permission is granted to copy, distribute and/or modify this
+ document under the terms of the <citetitle>GNU Free
+ Documentation License</citetitle>, Version 1.1 or any later
+ version published by the Free Software Foundation with no
+ Invariant Sections, no Front-Cover Texts, and no Back-Cover
+ Texts. You may obtain a copy of the <citetitle>GNU Free
+ Documentation License</citetitle> from the Free Software
+ Foundation by visiting <ulink type="http"
+ url="http://www.fsf.org">their Web site</ulink> or by writing
+ to:
+
+ <address>
+ The Free Software Foundation, Inc.,
+ <street>59 Temple Place</street> - Suite 330,
+ <city>Boston</city>, <state>MA</state> <postcode>02111-1307</postcode>,
+ <country>USA</country>
+ </address>
+ </para>
+
+ <para>
+ Many of the names used by companies to distinguish their
+ products and services are claimed as trademarks. Where those
+ names appear in any GNOME documentation, and those trademarks
+ are made aware to the members of the GNOME Documentation
+ Project, the names have been printed in caps or initial caps.
+ </para>
+ </legalnotice>
+ </bookinfo>
+
+ <reference>
+ <title>API Reference</title>
+
+ <partintro>
+ <para>
+ This part presents the class and function reference for the
+ PolicyKit D-Bus helper library.
+ </para>
+ </partintro>
+ <xi:include href="xml/libpolkit-dbus.xml"/>
+ </reference>
+
+ <index>
+ <title>Index</title>
+ </index>
+
+ <!-- License -->
+
+ <appendix id="license">
+ <title>License</title>
+
+ <para>
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the <citetitle>GNU General
+ Public License</citetitle> as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option)
+ any later version.
+ </para>
+
+ <para>
+ This library 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
+ <citetitle>GNU Library General Public License</citetitle> for
+ more details.
+ </para>
+
+ <para>
+ You may obtain a copy of the <citetitle>GNU General
+ Public License</citetitle> from the Free Software Foundation by
+ visiting <ulink type="http" url="http://www.fsf.org">their Web
+ site</ulink> or by writing to:
+
+ <address>
+ Free Software Foundation, Inc.
+ <street>59 Temple Place</street> - Suite 330
+ <city>Boston</city>, <state>MA</state> <postcode>02111-1307</postcode>
+ <country>USA</country>
+ </address>
+ </para>
+ </appendix>
+</book>
diff --git a/doc/api/libpolkit-dbus/libpolkit-dbus.types b/doc/api/libpolkit-dbus/libpolkit-dbus.types
new file mode 100644
index 0000000..e69de29
diff --git a/doc/api/libpolkit-dbus/version.xml b/doc/api/libpolkit-dbus/version.xml
new file mode 100644
index 0000000..be58634
--- /dev/null
+++ b/doc/api/libpolkit-dbus/version.xml
@@ -0,0 +1 @@
+0.3
diff --git a/doc/api/libpolkit-grant/Makefile.am b/doc/api/libpolkit-grant/Makefile.am
new file mode 100644
index 0000000..f65956e
--- /dev/null
+++ b/doc/api/libpolkit-grant/Makefile.am
@@ -0,0 +1,67 @@
+## Process this file with automake to create Makefile.in.
+
+NULL =
+
+AUTOMAKE_OPTIONS = 1.7
+
+# The name of the module.
+DOC_MODULE=libpolkit-grant
+
+# The top-level SGML file.
+DOC_MAIN_SGML_FILE=libpolkit-grant-docs.xml
+
+# Extra options to supply to gtkdoc-scan
+#SCAN_OPTIONS=--deprecated-guards="CAIRO_DISABLE_DEPRECATED"
+
+# The directory containing the source code. Relative to $(srcdir)
+DOC_SOURCE_DIR=../../../libpolkit-grant
+
+# Used for dependencies
+HFILE_GLOB=$(top_srcdir)/libpolkit-grant/*.h
+CFILE_GLOB=$(top_srcdir)/libpolkit-grant/*.c
+
+# Headers to ignore
+IGNORE_HFILES= \
+ $(NULL)
+
+# CFLAGS and LDFLAGS for compiling scan program. Only needed
+# if $(DOC_MODULE).types is non-empty.
+INCLUDES = \
+ $(GLIB_CFLAGS) \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ $(NULL)
+
+GTKDOC_LIBS = \
+ $(GLIB_LIBS) \
+ $(top_builddir)/libpolkit-grant/libpolkit-grant.la \
+ $(NULL)
+
+# Extra options to supply to gtkdoc-mkdb
+MKDB_OPTIONS=--sgml-mode --output-format=xml
+
+# Extra options to supply to gtkdoc-mktmpl
+MKTMPL_OPTIONS=
+
+# Non-autogenerated SGML files to be included in $(DOC_MAIN_SGML_FILE)
+content_files = \
+ version.xml \
+ $(NULL)
+
+# Images to copy into HTML directory
+HTML_IMAGES =
+
+# Extra options to supply to gtkdoc-fixref
+FIXXREF_OPTIONS=
+
+MAINTAINERCLEANFILES = \
+ *~ \
+ Makefile.in \
+ libpolkit-grant.types \
+ libpolkit-grant-*.txt \
+ $(NULL)
+
+include $(top_srcdir)/gtk-doc.make
+
+# Version information for marking the documentation
+EXTRA_DIST += version.xml.in
diff --git a/doc/api/libpolkit-grant/libpolkit-grant-docs.xml b/doc/api/libpolkit-grant/libpolkit-grant-docs.xml
new file mode 100644
index 0000000..0ca0f9f
--- /dev/null
+++ b/doc/api/libpolkit-grant/libpolkit-grant-docs.xml
@@ -0,0 +1,109 @@
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
+<!ENTITY version SYSTEM "version.xml">
+]>
+<book id="index" xmlns:xi="http://www.w3.org/2003/XInclude">
+ <bookinfo>
+ <title>PolicyKit Granting Library Reference Manual</title>
+ <releaseinfo>Version &version;</releaseinfo>
+ <authorgroup>
+ <author>
+ <firstname>David</firstname>
+ <surname>Zeuthen</surname>
+ <affiliation>
+ <address>
+ <email>david at fubar.dk</email>
+ </address>
+ </affiliation>
+ </author>
+ </authorgroup>
+
+ <copyright>
+ <year>2007</year>
+ <holder>The PolicyKit Authors</holder>
+ </copyright>
+
+ <legalnotice>
+ <para>
+ Permission is granted to copy, distribute and/or modify this
+ document under the terms of the <citetitle>GNU Free
+ Documentation License</citetitle>, Version 1.1 or any later
+ version published by the Free Software Foundation with no
+ Invariant Sections, no Front-Cover Texts, and no Back-Cover
+ Texts. You may obtain a copy of the <citetitle>GNU Free
+ Documentation License</citetitle> from the Free Software
+ Foundation by visiting <ulink type="http"
+ url="http://www.fsf.org">their Web site</ulink> or by writing
+ to:
+
+ <address>
+ The Free Software Foundation, Inc.,
+ <street>59 Temple Place</street> - Suite 330,
+ <city>Boston</city>, <state>MA</state> <postcode>02111-1307</postcode>,
+ <country>USA</country>
+ </address>
+ </para>
+
+ <para>
+ Many of the names used by companies to distinguish their
+ products and services are claimed as trademarks. Where those
+ names appear in any GNOME documentation, and those trademarks
+ are made aware to the members of the GNOME Documentation
+ Project, the names have been printed in caps or initial caps.
+ </para>
+ </legalnotice>
+ </bookinfo>
+
+ <reference>
+ <title>API Reference</title>
+
+ <partintro>
+ <para>
+ This part presents the class and function reference for the
+ PolicyKit granting helper library.
+ </para>
+ </partintro>
+ <xi:include href="xml/libpolkit-grant.xml"/>
+ </reference>
+
+ <index>
+ <title>Index</title>
+ </index>
+
+ <!-- License -->
+
+ <appendix id="license">
+ <title>License</title>
+
+ <para>
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the <citetitle>GNU General
+ Public License</citetitle> as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option)
+ any later version.
+ </para>
+
+ <para>
+ This library 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
+ <citetitle>GNU Library General Public License</citetitle> for
+ more details.
+ </para>
+
+ <para>
+ You may obtain a copy of the <citetitle>GNU General
+ Public License</citetitle> from the Free Software Foundation by
+ visiting <ulink type="http" url="http://www.fsf.org">their Web
+ site</ulink> or by writing to:
+
+ <address>
+ Free Software Foundation, Inc.
+ <street>59 Temple Place</street> - Suite 330
+ <city>Boston</city>, <state>MA</state> <postcode>02111-1307</postcode>
+ <country>USA</country>
+ </address>
+ </para>
+ </appendix>
+</book>
diff --git a/doc/api/libpolkit-grant/libpolkit-grant.types b/doc/api/libpolkit-grant/libpolkit-grant.types
new file mode 100644
index 0000000..e69de29
diff --git a/doc/api/libpolkit-grant/version.xml b/doc/api/libpolkit-grant/version.xml
new file mode 100644
index 0000000..be58634
--- /dev/null
+++ b/doc/api/libpolkit-grant/version.xml
@@ -0,0 +1 @@
+0.3
diff --git a/doc/api/libpolkit/libpolkit-docs.xml b/doc/api/libpolkit/libpolkit-docs.xml
index c802ef0..b0f538f 100644
--- a/doc/api/libpolkit/libpolkit-docs.xml
+++ b/doc/api/libpolkit/libpolkit-docs.xml
@@ -64,6 +64,7 @@
PolicyKit library.
</para>
</partintro>
+ <xi:include href="xml/libpolkit-types.xml"/>
<xi:include href="xml/libpolkit-error.xml"/>
<xi:include href="xml/libpolkit-result.xml"/>
<xi:include href="xml/libpolkit-context.xml"/>
@@ -77,6 +78,8 @@
<xi:include href="xml/libpolkit-session.xml"/>
<xi:include href="xml/libpolkit-caller.xml"/>
<xi:include href="xml/libpolkit-module.xml"/>
+ <xi:include href="xml/libpolkit-debug.xml"/>
+ <xi:include href="xml/libpolkit-utils.xml"/>
</reference>
<index>
diff --git a/libpolkit-dbus/Makefile.am b/libpolkit-dbus/Makefile.am
new file mode 100644
index 0000000..3a51c3a
--- /dev/null
+++ b/libpolkit-dbus/Makefile.am
@@ -0,0 +1,31 @@
+## Process this file with automake to produce Makefile.in
+
+INCLUDES = \
+ -I$(top_builddir) -I$(top_srcdir) \
+ -DPACKAGE_LIBEXEC_DIR=\""$(libexecdir)"\" \
+ -DPACKAGE_SYSCONF_DIR=\""$(sysconfdir)"\" \
+ -DPACKAGE_DATA_DIR=\""$(datadir)"\" \
+ -DPACKAGE_BIN_DIR=\""$(bindir)"\" \
+ -DPACKAGE_LOCALSTATEDIR=\""$(localstatedir)"\" \
+ -DPACKAGE_LOCALE_DIR=\""$(localedir)"\" \
+ -DPACKAGE_LIB_DIR=\""$(libdir)"\" \
+ -D_POSIX_PTHREAD_SEMANTICS -D_REENTRANT \
+ @GLIB_CFLAGS@ @DBUS_CFLAGS@
+
+lib_LTLIBRARIES=libpolkit-dbus.la
+
+libpolkit_dbusincludedir=$(includedir)/PolicyKit/libpolkit-dbus
+
+libpolkit_dbusinclude_HEADERS = \
+ libpolkit-dbus.h
+
+libpolkit_dbus_la_SOURCES = \
+ libpolkit-dbus.h libpolkit-dbus.c
+
+libpolkit_dbus_la_LIBADD = @DBUS_LIBS@ $(top_builddir)/libpolkit/libpolkit.la
+
+libpolkit_dbus_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
+
+clean-local :
+ rm -f *~ $(BUILT_SOURCES)
+
diff --git a/libpolkit-dbus/libpolkit-dbus.c b/libpolkit-dbus/libpolkit-dbus.c
new file mode 100644
index 0000000..6c4995a
--- /dev/null
+++ b/libpolkit-dbus/libpolkit-dbus.c
@@ -0,0 +1,540 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/***************************************************************************
+ *
+ * libpolkit-dbus.h : helper library for obtaining seat, session and
+ * caller information via D-Bus and ConsoleKit
+ *
+ * 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
+ *
+ **************************************************************************/
+
+/**
+ * SECTION:libpolkit-dbus
+ * @short_description: Helper library for obtaining seat, session and caller information via D-Bus and ConsoleKit.
+ *
+ * Helper library for obtaining seat, session and caller information
+ * via D-Bus and ConsoleKit.
+ **/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <time.h>
+#include <glib.h>
+#include <string.h>
+
+#include "libpolkit-dbus.h"
+
+
+/**
+ * libpolkit_session_new_from_objpath:
+ * @con: D-Bus system bus connection
+ * @objpath: object path of ConsoleKit session object
+ * @uid: the user owning the session or -1 if unknown
+ * @error: D-Bus error
+ *
+ * This function will construct a #PolKitSession object by querying
+ * the ConsoleKit daemon for information. Note that this will do a lot
+ * of blocking IO so it is best avoided if your process already
+ * tracks/caches all the information. If you pass in @uid as a
+ * non-negative number, a round trip can be saved.
+ *
+ * Returns: the new object or #NULL if an error occured (in which case
+ * @error will be set)
+ **/
+PolKitSession *
+libpolkit_session_new_from_objpath (DBusConnection *con, const char *objpath, uid_t uid, DBusError *error)
+{
+ PolKitSeat *seat;
+ PolKitSession *session;
+ DBusMessage *message;
+ DBusMessage *reply;
+ char *str;
+ dbus_bool_t is_active;
+ dbus_bool_t is_local;
+ char *remote_host;
+ char *seat_path;
+
+ g_return_val_if_fail (con != NULL, NULL);
+ g_return_val_if_fail (objpath != NULL, NULL);
+ g_return_val_if_fail (error != NULL, NULL);
+ g_return_val_if_fail (! dbus_error_is_set (error), NULL);
+
+ session = NULL;
+ remote_host = NULL;
+ seat_path = NULL;
+
+ message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit",
+ objpath,
+ "org.freedesktop.ConsoleKit.Session",
+ "IsActive");
+ reply = dbus_connection_send_with_reply_and_block (con, message, -1, error);
+ if (reply == NULL || dbus_error_is_set (error)) {
+ g_warning ("Error doing Session.IsActive on ConsoleKit: %s: %s", error->name, error->message);
+ dbus_message_unref (message);
+ if (reply != NULL)
+ dbus_message_unref (reply);
+ goto out;
+ }
+ if (!dbus_message_get_args (reply, NULL,
+ DBUS_TYPE_BOOLEAN, &is_active,
+ DBUS_TYPE_INVALID)) {
+ g_warning ("Invalid IsActive reply from CK");
+ goto out;
+ }
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+
+ message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit",
+ objpath,
+ "org.freedesktop.ConsoleKit.Session",
+ "IsLocal");
+ reply = dbus_connection_send_with_reply_and_block (con, message, -1, error);
+ if (reply == NULL || dbus_error_is_set (error)) {
+ g_warning ("Error doing Session.IsLocal on ConsoleKit: %s: %s", error->name, error->message);
+ dbus_message_unref (message);
+ if (reply != NULL)
+ dbus_message_unref (reply);
+ goto out;
+ }
+ if (!dbus_message_get_args (reply, NULL,
+ DBUS_TYPE_BOOLEAN, &is_local,
+ DBUS_TYPE_INVALID)) {
+ g_warning ("Invalid IsLocal reply from CK");
+ goto out;
+ }
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+
+ if (!is_local) {
+ message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit",
+ objpath,
+ "org.freedesktop.ConsoleKit.Session",
+ "GetRemoteHostName");
+ reply = dbus_connection_send_with_reply_and_block (con, message, -1, error);
+ if (reply == NULL || dbus_error_is_set (error)) {
+ g_warning ("Error doing Session.GetRemoteHostName on ConsoleKit: %s: %s",
+ error->name, error->message);
+ dbus_message_unref (message);
+ if (reply != NULL)
+ dbus_message_unref (reply);
+ goto out;
+ }
+ if (!dbus_message_get_args (reply, NULL,
+ DBUS_TYPE_STRING, &str,
+ DBUS_TYPE_INVALID)) {
+ g_warning ("Invalid GetRemoteHostName reply from CK");
+ goto out;
+ }
+ remote_host = g_strdup (str);
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+ }
+
+ message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit",
+ objpath,
+ "org.freedesktop.ConsoleKit.Session",
+ "GetSeatId");
+ reply = dbus_connection_send_with_reply_and_block (con, message, -1, error);
+ if (reply == NULL || dbus_error_is_set (error)) {
+ g_warning ("Error doing Session.GetSeatId on ConsoleKit: %s: %s",
+ error->name, error->message);
+ dbus_message_unref (message);
+ if (reply != NULL)
+ dbus_message_unref (reply);
+ goto out;
+ }
+ if (!dbus_message_get_args (reply, NULL,
+ DBUS_TYPE_OBJECT_PATH, &str,
+ DBUS_TYPE_INVALID)) {
+ g_warning ("Invalid GetSeatId reply from CK");
+ goto out;
+ }
+ seat_path = g_strdup (str);
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+
+ if ((int) uid == -1) {
+ message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit",
+ objpath,
+ "org.freedesktop.ConsoleKit.Session",
+ "GetUnixUser");
+ reply = dbus_connection_send_with_reply_and_block (con, message, -1, error);
+ if (reply == NULL || dbus_error_is_set (error)) {
+ g_warning ("Error doing Session.GetUnixUser on ConsoleKit: %s: %s",error->name, error->message);
+ dbus_message_unref (message);
+ if (reply != NULL)
+ dbus_message_unref (reply);
+ goto out;
+ }
+ if (!dbus_message_get_args (reply, NULL,
+ DBUS_TYPE_INT32, &uid,
+ DBUS_TYPE_INVALID)) {
+ g_warning ("Invalid GetUnixUser reply from CK");
+ goto out;
+ }
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+ }
+
+ session = libpolkit_session_new ();
+ if (session == NULL) {
+ goto out;
+ }
+ if (!libpolkit_session_set_ck_objref (session, objpath)) {
+ libpolkit_session_unref (session);
+ session = NULL;
+ goto out;
+ }
+ if (!libpolkit_session_set_ck_is_active (session, is_active)) {
+ libpolkit_session_unref (session);
+ session = NULL;
+ goto out;
+ }
+ if (!libpolkit_session_set_ck_is_local (session, is_local)) {
+ libpolkit_session_unref (session);
+ session = NULL;
+ goto out;
+ }
+ if (!is_local) {
+ if (!libpolkit_session_set_ck_remote_host (session, remote_host)) {
+ libpolkit_session_unref (session);
+ session = NULL;
+ goto out;
+ }
+
+ }
+
+ seat = libpolkit_seat_new ();
+ if (seat == NULL) {
+ libpolkit_session_unref (session);
+ session = NULL;
+ goto out;
+ }
+ if (!libpolkit_seat_set_ck_objref (seat, seat_path)) {
+ libpolkit_seat_unref (seat);
+ seat = NULL;
+ libpolkit_session_unref (session);
+ session = NULL;
+ goto out;
+ }
+ if (!libpolkit_seat_validate (seat)) {
+ libpolkit_seat_unref (seat);
+ seat = NULL;
+ libpolkit_session_unref (session);
+ session = NULL;
+ goto out;
+ }
+
+ if (!libpolkit_session_set_seat (session, seat)) {
+ libpolkit_seat_unref (seat);
+ seat = NULL;
+ libpolkit_session_unref (session);
+ session = NULL;
+ goto out;
+ }
+ libpolkit_seat_unref (seat); /* session object now owns this object */
+ seat = NULL;
+
+ if (!libpolkit_session_validate (session)) {
+ libpolkit_session_unref (session);
+ session = NULL;
+ goto out;
+ }
+
+out:
+ g_free (remote_host);
+ g_free (seat_path);
+ return session;
+}
+
+/**
+ * libpolkit_session_new_from_cookie:
+ * @con: D-Bus system bus connection
+ * @cookie: a ConsoleKit XDG_SESSION_COOKIE
+ * @error: D-Bus error
+ *
+ * This function will construct a #PolKitSession object by querying
+ * the ConsoleKit daemon for information. Note that this will do a lot
+ * of blocking IO so it is best avoided if your process already
+ * tracks/caches all the information.
+ *
+ * Returns: the new object or #NULL if an error occured (in which case
+ * @error will be set)
+ **/
+PolKitSession *
+libpolkit_session_new_from_cookie (DBusConnection *con, const char *cookie, DBusError *error)
+{
+ PolKitSession *session;
+ DBusMessage *message;
+ DBusMessage *reply;
+ char *str;
+ char *objpath;
+
+ g_return_val_if_fail (con != NULL, NULL);
+ g_return_val_if_fail (cookie != NULL, NULL);
+ g_return_val_if_fail (error != NULL, NULL);
+ g_return_val_if_fail (! dbus_error_is_set (error), NULL);
+
+ objpath = NULL;
+ session = NULL;
+
+ message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit",
+ "/org/freedesktop/ConsoleKit/Manager",
+ "org.freedesktop.ConsoleKit.Manager",
+ "GetSessionForCookie");
+ dbus_message_append_args (message, DBUS_TYPE_STRING, &cookie, DBUS_TYPE_INVALID);
+ reply = dbus_connection_send_with_reply_and_block (con, message, -1, error);
+ if (reply == NULL || dbus_error_is_set (error)) {
+ g_warning ("Error doing Manager.GetSessionForCookie on ConsoleKit: %s: %s",
+ error->name, error->message);
+ dbus_message_unref (message);
+ if (reply != NULL)
+ dbus_message_unref (reply);
+ goto out;
+ }
+ if (!dbus_message_get_args (reply, NULL,
+ DBUS_TYPE_OBJECT_PATH, &str,
+ DBUS_TYPE_INVALID)) {
+ g_warning ("Invalid GetSessionForCookie reply from CK");
+ goto out;
+ }
+ objpath = g_strdup (str);
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+
+ session = libpolkit_session_new_from_objpath (con, objpath, -1, error);
+
+out:
+ g_free (objpath);
+ return session;
+}
+
+
+/**
+ * libpolkit_caller_new_from_dbus_name:
+ * @con: D-Bus system bus connection
+ * @dbus_name: unique system bus connection name
+ * @error: D-Bus error
+ *
+ * This function will construct a #PolKitCaller object by querying
+ * both the system bus daemon and the ConsoleKit daemon for
+ * information. Note that this will do a lot of blocking IO so it is
+ * best avoided if your process already tracks/caches all the
+ * information.
+ *
+ * Returns: the new object or #NULL if an error occured (in which case
+ * @error will be set)
+ **/
+PolKitCaller *
+libpolkit_caller_new_from_dbus_name (DBusConnection *con, const char *dbus_name, DBusError *error)
+{
+ PolKitCaller *caller;
+ pid_t pid;
+ uid_t uid;
+ char *selinux_context;
+ char *ck_session_objpath;
+ PolKitSession *session;
+ DBusMessage *message;
+ DBusMessage *reply;
+ DBusMessageIter iter;
+ DBusMessageIter sub_iter;
+ char *str;
+ int num_elems;
+
+ g_return_val_if_fail (con != NULL, NULL);
+ g_return_val_if_fail (dbus_name != NULL, NULL);
+ g_return_val_if_fail (error != NULL, NULL);
+ g_return_val_if_fail (! dbus_error_is_set (error), NULL);
+
+ selinux_context = NULL;
+ ck_session_objpath = NULL;
+
+ caller = NULL;
+ session = NULL;
+
+ uid = dbus_bus_get_unix_user (con, dbus_name, error);
+ if (uid == ((unsigned long) -1) || dbus_error_is_set (error)) {
+ g_warning ("Could not get uid for connection: %s %s", error->name, error->message);
+ goto out;
+ }
+
+ message = dbus_message_new_method_call ("org.freedesktop.DBus",
+ "/org/freedesktop/DBus/Bus",
+ "org.freedesktop.DBus",
+ "GetConnectionUnixProcessID");
+ dbus_message_iter_init_append (message, &iter);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &dbus_name);
+ reply = dbus_connection_send_with_reply_and_block (con, message, -1, error);
+ if (reply == NULL || dbus_error_is_set (error)) {
+ g_warning ("Error doing GetConnectionUnixProcessID on Bus: %s: %s", error->name, error->message);
+ dbus_message_unref (message);
+ if (reply != NULL)
+ dbus_message_unref (reply);
+ goto out;
+ }
+ dbus_message_iter_init (reply, &iter);
+ dbus_message_iter_get_basic (&iter, &pid);
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+
+ message = dbus_message_new_method_call ("org.freedesktop.DBus",
+ "/org/freedesktop/DBus/Bus",
+ "org.freedesktop.DBus",
+ "GetConnectionSELinuxSecurityContext");
+ dbus_message_iter_init_append (message, &iter);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &dbus_name);
+ reply = dbus_connection_send_with_reply_and_block (con, message, -1, error);
+ /* SELinux might not be enabled */
+ if (dbus_error_is_set (error) &&
+ strcmp (error->name, "org.freedesktop.DBus.Error.SELinuxSecurityContextUnknown") == 0) {
+ dbus_message_unref (message);
+ if (reply != NULL)
+ dbus_message_unref (reply);
+ dbus_error_init (error);
+ } else if (reply == NULL || dbus_error_is_set (error)) {
+ g_warning ("Error doing GetConnectionSELinuxSecurityContext on Bus: %s: %s", error->name, error->message);
+ dbus_message_unref (message);
+ if (reply != NULL)
+ dbus_message_unref (reply);
+ goto out;
+ } else {
+ /* TODO: verify signature */
+ dbus_message_iter_init (reply, &iter);
+ dbus_message_iter_recurse (&iter, &sub_iter);
+ dbus_message_iter_get_fixed_array (&sub_iter, (void *) &str, &num_elems);
+ if (str != NULL && num_elems > 0)
+ selinux_context = g_strndup (str, num_elems);
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+ }
+
+ message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit",
+ "/org/freedesktop/ConsoleKit/Manager",
+ "org.freedesktop.ConsoleKit.Manager",
+ "GetSessionForUnixProcess");
+ dbus_message_iter_init_append (message, &iter);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT32, &pid);
+ reply = dbus_connection_send_with_reply_and_block (con, message, -1, error);
+ if (reply == NULL || dbus_error_is_set (error)) {
+ g_warning ("Error doing GetSessionForUnixProcess on ConsoleKit: %s: %s", error->name, error->message);
+ dbus_message_unref (message);
+ if (reply != NULL)
+ dbus_message_unref (reply);
+ /* OK, this is not a catastrophe; just means the caller is not a
+ * member of any session or that ConsoleKit is not available..
+ */
+ goto not_in_session;
+ }
+ dbus_message_iter_init (reply, &iter);
+ dbus_message_iter_get_basic (&iter, &str);
+ ck_session_objpath = g_strdup (str);
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+
+ session = libpolkit_session_new_from_objpath (con, ck_session_objpath, uid, error);
+ if (session == NULL) {
+ g_warning ("Got a session objpath but couldn't construct session object!");
+ goto out;
+ }
+ if (!libpolkit_session_validate (session)) {
+ libpolkit_session_unref (session);
+ session = NULL;
+ goto out;
+ }
+
+not_in_session:
+
+ caller = libpolkit_caller_new ();
+ if (caller == NULL) {
+ if (session != NULL) {
+ libpolkit_session_unref (session);
+ session = NULL;
+ }
+ goto out;
+ }
+
+ if (!libpolkit_caller_set_dbus_name (caller, dbus_name)) {
+ if (session != NULL) {
+ libpolkit_session_unref (session);
+ session = NULL;
+ }
+ libpolkit_caller_unref (caller);
+ caller = NULL;
+ goto out;
+ }
+ if (!libpolkit_caller_set_uid (caller, uid)) {
+ if (session != NULL) {
+ libpolkit_session_unref (session);
+ session = NULL;
+ }
+ libpolkit_caller_unref (caller);
+ caller = NULL;
+ goto out;
+ }
+ if (!libpolkit_caller_set_pid (caller, pid)) {
+ if (session != NULL) {
+ libpolkit_session_unref (session);
+ session = NULL;
+ }
+ libpolkit_caller_unref (caller);
+ caller = NULL;
+ goto out;
+ }
+ if (selinux_context != NULL) {
+ if (!libpolkit_caller_set_selinux_context (caller, selinux_context)) {
+ if (session != NULL) {
+ libpolkit_session_unref (session);
+ session = NULL;
+ }
+ libpolkit_caller_unref (caller);
+ caller = NULL;
+ goto out;
+ }
+ }
+ if (session != NULL) {
+ if (!libpolkit_caller_set_ck_session (caller, session)) {
+ if (session != NULL) {
+ libpolkit_session_unref (session);
+ session = NULL;
+ }
+ libpolkit_caller_unref (caller);
+ caller = NULL;
+ goto out;
+ }
+ libpolkit_session_unref (session); /* caller object now own this object */
+ session = NULL;
+ }
+
+ if (!libpolkit_caller_validate (caller)) {
+ libpolkit_caller_unref (caller);
+ caller = NULL;
+ goto out;
+ }
+
+out:
+ g_free (selinux_context);
+ g_free (ck_session_objpath);
+ return caller;
+}
diff --git a/libpolkit-dbus/libpolkit-dbus.h b/libpolkit-dbus/libpolkit-dbus.h
new file mode 100644
index 0000000..dd8d019
--- /dev/null
+++ b/libpolkit-dbus/libpolkit-dbus.h
@@ -0,0 +1,41 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/***************************************************************************
+ *
+ * libpolkit-dbus.h : helper library for obtaining seat, session and
+ * caller information via D-Bus and ConsoleKit
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+#ifndef LIBPOLKIT_DBUS_H
+#define LIBPOLKIT_DBUS_H
+
+#include <libpolkit/libpolkit.h>
+#include <dbus/dbus.h>
+
+PolKitSession *libpolkit_session_new_from_objpath (DBusConnection *con, const char *objpath, uid_t uid, DBusError *error);
+PolKitSession *libpolkit_session_new_from_cookie (DBusConnection *con, const char *cookie, DBusError *error);
+
+PolKitCaller *libpolkit_caller_new_from_dbus_name (DBusConnection *con, const char *dbus_name, DBusError *error);
+
+
+#endif /* LIBPOLKIT_DBUS_H */
+
+
diff --git a/libpolkit-grant/Makefile.am b/libpolkit-grant/Makefile.am
new file mode 100644
index 0000000..01ebcfe
--- /dev/null
+++ b/libpolkit-grant/Makefile.am
@@ -0,0 +1,54 @@
+## Process this file with automake to produce Makefile.in
+
+INCLUDES = \
+ -I$(top_builddir) -I$(top_srcdir) \
+ -DPACKAGE_LIBEXEC_DIR=\""$(libexecdir)"\" \
+ -DPACKAGE_SYSCONF_DIR=\""$(sysconfdir)"\" \
+ -DPACKAGE_DATA_DIR=\""$(datadir)"\" \
+ -DPACKAGE_BIN_DIR=\""$(bindir)"\" \
+ -DPACKAGE_LOCALSTATE_DIR=\""$(localstatedir)"\" \
+ -DPACKAGE_LOCALE_DIR=\""$(localedir)"\" \
+ -DPACKAGE_LIB_DIR=\""$(libdir)"\" \
+ -D_POSIX_PTHREAD_SEMANTICS -D_REENTRANT \
+ @GLIB_CFLAGS@ @DBUS_CFLAGS@
+
+lib_LTLIBRARIES=libpolkit-grant.la
+
+libpolkit_grantincludedir=$(includedir)/PolicyKit/libpolkit-grant
+
+libpolkit_grantinclude_HEADERS = \
+ libpolkit-grant.h
+
+libpolkit_grant_la_SOURCES = \
+ libpolkit-grant.h libpolkit-grant.c
+
+libpolkit_grant_la_LIBADD = @GLIB_LIBS@ @DBUS_LIBS@ $(top_builddir)/libpolkit/libpolkit.la
+
+libpolkit_grant_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
+
+libexec_PROGRAMS = polkit-grant-helper
+
+polkit_grant_helper_SOURCES = polkit-grant-helper.c
+polkit_grant_helper_LDADD = @GLIB_LIBS@ @DBUS_LIBS@ @AUTH_LIBS@ $(top_builddir)/libpolkit/libpolkit.la $(top_builddir)/libpolkit-dbus/libpolkit-dbus.la
+
+polkit_grant_alwaysdir = $(localstatedir)/lib/PolicyKit
+dist_polkit_grant_always_DATA =
+
+polkit_grant_sessiondir = $(localstatedir)/run/PolicyKit
+dist_polkit_grant_session_DATA =
+
+
+clean-local :
+ rm -f *~ $(BUILT_SOURCES)
+
+# Hmm.. we could make the directories 750 and require that all mechanisms using
+# libpolkit (e.g. with a need for polkit-module-grant.so to look there) just
+# be part of $(POLKIT_GROUP)...
+#
+install-data-local:
+ -chown :$(POLKIT_GROUP) $(DESTDIR)$(libexecdir)/polkit-grant-helper
+ -chmod 2755 $(DESTDIR)$(libexecdir)/polkit-grant-helper
+ -chown $(POLKIT_USER):$(POLKIT_GROUP) $(DESTDIR)$(localstatedir)/lib/PolicyKit
+ -chown $(POLKIT_USER):$(POLKIT_GROUP) $(DESTDIR)$(localstatedir)/run/PolicyKit
+ -chmod 775 $(DESTDIR)$(localstatedir)/lib/PolicyKit
+ -chmod 775 $(DESTDIR)$(localstatedir)/run/PolicyKit
diff --git a/libpolkit-grant/libpolkit-grant.c b/libpolkit-grant/libpolkit-grant.c
new file mode 100644
index 0000000..d15f8a0
--- /dev/null
+++ b/libpolkit-grant/libpolkit-grant.c
@@ -0,0 +1,465 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/***************************************************************************
+ *
+ * libpolkit-grant.c : library for obtaining privileges
+ *
+ * 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
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/wait.h>
+
+#include <glib.h>
+#include "libpolkit-grant.h"
+
+/**
+ * SECTION:libpolkit-grant
+ * @short_description: Obtain privileges through authentication.
+ *
+ * These functions are used to obtain privileges for a user that is
+ * able to successfully authenticate.
+ **/
+
+/**
+ * PolKitGrant:
+ *
+ * Objects of this class are used to obtain privileges for a user that
+ * is able to successfully authenticate.
+ **/
+struct PolKitGrant
+{
+ int refcount;
+
+ PolKitGrantAddIOWatch func_add_io_watch;
+ PolKitGrantAddChildWatch func_add_child_watch;
+ PolKitGrantRemoveWatch func_remove_watch;
+ PolKitGrantType func_type;
+ PolKitGrantConversationPromptEchoOff func_prompt_echo_off;
+ PolKitGrantConversationPromptEchoOn func_prompt_echo_on;
+ PolKitGrantConversationErrorMessage func_error_message;
+ PolKitGrantConversationTextInfo func_text_info;
+ PolKitGrantOverrideGrantType func_override_grant_type;
+ PolKitGrantDone func_done;
+ void *user_data;
+
+ int child_stdin;
+ int child_stdout;
+ GPid child_pid;
+ FILE *child_stdout_f;
+
+ int child_watch_id;
+ int io_watch_id;
+
+ gboolean success;
+ gboolean auth_in_progress;
+};
+
+/**
+ * libpolkit_grant_new:
+ * @void:
+ *
+ * Creates a #PolKitGrant object.
+ *
+ * Returns: the new object or #NULL on error.
+ **/
+PolKitGrant *
+libpolkit_grant_new (void)
+{
+ PolKitGrant *polkit_grant;
+ polkit_grant = g_new0 (PolKitGrant, 1);
+ polkit_grant->refcount = 1;
+ return polkit_grant;
+}
+
+/**
+ * libpolkit_grant_ref:
+ * @polkit_grant: the object
+ *
+ * Increase reference count.
+ *
+ * Returns: the object.
+ **/
+PolKitGrant *
+libpolkit_grant_ref (PolKitGrant *polkit_grant)
+{
+ g_return_val_if_fail (polkit_grant != NULL, NULL);
+
+ polkit_grant->refcount++;
+ return polkit_grant;
+}
+
+/**
+ * libpolkit_grant_unref:
+ * @polkit_grant: the object
+ *
+ * Decreases the reference count of the object. If it becomes zero,
+ * the object is freed. Before freeing, reference counts on embedded
+ * objects are decresed by one.
+ **/
+void
+libpolkit_grant_unref (PolKitGrant *polkit_grant)
+{
+ g_return_if_fail (polkit_grant != NULL);
+
+ polkit_grant->refcount--;
+ if (polkit_grant->refcount > 0)
+ return;
+
+ if (polkit_grant->io_watch_id > 0) {
+ polkit_grant->func_remove_watch (polkit_grant, polkit_grant->io_watch_id);
+ }
+ if (polkit_grant->child_watch_id > 0) {
+ polkit_grant->func_remove_watch (polkit_grant, polkit_grant->child_watch_id);
+ }
+ if (polkit_grant->child_pid > 0) {
+ kill (polkit_grant->child_pid, SIGTERM);
+ }
+ if (polkit_grant->child_stdout_f != NULL) {
+ fclose (polkit_grant->child_stdout_f);
+ }
+ if (polkit_grant->child_stdout >= 0) {
+ close (polkit_grant->child_stdout);
+ }
+ if (polkit_grant->child_stdin >= 0) {
+ close (polkit_grant->child_stdin);
+ }
+
+ g_free (polkit_grant);
+}
+
+/**
+ * libpolkit_grant_set_functions:
+ * @polkit_grant: the object
+ * @func_add_io_watch: Callback function
+ * @func_add_child_watch: Callback function
+ * @func_remove_watch: Callback function
+ * @func_type: Callback function
+ * @func_prompt_echo_off: Callback function
+ * @func_prompt_echo_on: Callback function
+ * @func_error_message: Callback function
+ * @func_text_info: Callback function
+ * @func_override_grant_type: Callback function
+ * @func_done: Callback function
+ * @user_data: User data that will be passed to the callback functions.
+ *
+ * Set callback functions used for authentication.
+ **/
+void
+libpolkit_grant_set_functions (PolKitGrant *polkit_grant,
+ PolKitGrantAddIOWatch func_add_io_watch,
+ PolKitGrantAddChildWatch func_add_child_watch,
+ PolKitGrantRemoveWatch func_remove_watch,
+ PolKitGrantType func_type,
+ PolKitGrantConversationPromptEchoOff func_prompt_echo_off,
+ PolKitGrantConversationPromptEchoOn func_prompt_echo_on,
+ PolKitGrantConversationErrorMessage func_error_message,
+ PolKitGrantConversationTextInfo func_text_info,
+ PolKitGrantOverrideGrantType func_override_grant_type,
+ PolKitGrantDone func_done,
+ void *user_data)
+{
+ g_return_if_fail (polkit_grant != NULL);
+ g_return_if_fail (func_add_io_watch != NULL);
+ g_return_if_fail (func_add_child_watch != NULL);
+ g_return_if_fail (func_remove_watch != NULL);
+ g_return_if_fail (func_type != NULL);
+ g_return_if_fail (func_prompt_echo_off != NULL);
+ g_return_if_fail (func_prompt_echo_on != NULL);
+ g_return_if_fail (func_error_message != NULL);
+ g_return_if_fail (func_text_info != NULL);
+ g_return_if_fail (func_override_grant_type != NULL);
+ polkit_grant->func_add_io_watch = func_add_io_watch;
+ polkit_grant->func_add_child_watch = func_add_child_watch;
+ polkit_grant->func_remove_watch = func_remove_watch;
+ polkit_grant->func_type = func_type;
+ polkit_grant->func_prompt_echo_off = func_prompt_echo_off;
+ polkit_grant->func_prompt_echo_on = func_prompt_echo_on;
+ polkit_grant->func_error_message = func_error_message;
+ polkit_grant->func_text_info = func_text_info;
+ polkit_grant->func_override_grant_type = func_override_grant_type;
+ polkit_grant->func_done = func_done;
+ polkit_grant->user_data = user_data;
+}
+
+
+/**
+ * libpolkit_grant_child_func:
+ * @polkit_grant: the object
+ * @pid: pid of the child
+ * @exit_code: exit code of the child
+ *
+ * Method that the application must call when a child process
+ * registered with the supplied function of type
+ * #PolKitGrantAddChildWatch terminates.
+ **/
+void
+libpolkit_grant_child_func (PolKitGrant *polkit_grant, pid_t pid, int exit_code)
+{
+ g_return_if_fail (polkit_grant != NULL);
+ g_return_if_fail (polkit_grant->auth_in_progress);
+
+ polkit_grant->success = (exit_code == 0);
+ polkit_grant->func_done (polkit_grant, polkit_grant->success, polkit_grant->user_data);
+}
+
+
+/**
+ * libpolkit_grant_io_func:
+ * @polkit_grant: the object
+ * @fd: the file descriptor passed to the supplied function of type #PolKitGrantAddIOWatch.
+ *
+ * Method that the application must call when there is data to read
+ * from a file descriptor registered with the supplied function of
+ * type #PolKitGrantAddIOWatch.
+ **/
+void
+libpolkit_grant_io_func (PolKitGrant *polkit_grant, int fd)
+{
+ char *line = NULL;
+ size_t line_len = 0;
+ char *id;
+ size_t id_len;
+ char *response;
+
+ g_return_if_fail (polkit_grant != NULL);
+ g_return_if_fail (polkit_grant->auth_in_progress);
+
+ while (getline (&line, &line_len, polkit_grant->child_stdout_f) != -1) {
+ if (strlen (line) > 0 &&
+ line[strlen (line) - 1] == '\n')
+ line[strlen (line) - 1] = '\0';
+
+ //printf ("from child '%s'\n", line);
+
+ response = NULL;
+
+ id = "PAM_PROMPT_ECHO_OFF ";
+ if (g_str_has_prefix (line, id)) {
+ id_len = strlen (id);
+ response = polkit_grant->func_prompt_echo_off (polkit_grant,
+ line + id_len,
+ polkit_grant->user_data);
+ goto processed;
+ }
+
+ id = "PAM_PROMPT_ECHO_ON ";
+ if (g_str_has_prefix (line, id)) {
+ id_len = strlen (id);
+ response = polkit_grant->func_prompt_echo_on (polkit_grant,
+ line + id_len,
+ polkit_grant->user_data);
+ goto processed;
+ }
+
+ id = "PAM_ERROR_MSG ";
+ if (g_str_has_prefix (line, id)) {
+ id_len = strlen (id);
+ polkit_grant->func_error_message (polkit_grant,
+ line + id_len,
+ polkit_grant->user_data);
+ goto processed;
+ }
+
+ id = "PAM_TEXT_INFO ";
+ if (g_str_has_prefix (line, id)) {
+ id_len = strlen (id);
+ polkit_grant->func_text_info (polkit_grant,
+ line + id_len,
+ polkit_grant->user_data);
+ goto processed;
+ }
+
+ id = "POLKIT_GRANT_HELPER_TELL_TYPE ";
+ if (g_str_has_prefix (line, id)) {
+ PolKitResult result;
+ id_len = strlen (id);
+ if (!libpolkit_result_from_string_representation (line + id_len, &result)) {
+ /* TODO: danger will robinson */
+ }
+ polkit_grant->func_type (polkit_grant,
+ result,
+ polkit_grant->user_data);
+ goto processed;
+ }
+
+ id = "POLKIT_GRANT_HELPER_ASK_OVERRIDE_GRANT_TYPE ";
+ if (g_str_has_prefix (line, id)) {
+ PolKitResult override;
+ PolKitResult result;
+ id_len = strlen (id);
+ if (!libpolkit_result_from_string_representation (line + id_len, &result)) {
+ /* TODO: danger will robinson */
+ }
+ override = polkit_grant->func_override_grant_type (polkit_grant,
+ result,
+ polkit_grant->user_data);
+ response = g_strdup (libpolkit_result_to_string_representation (override));
+ goto processed;
+ }
+
+ processed:
+ if (response != NULL) {
+ /* add a newline if there isn't one already... */
+ if (response[strlen (response) - 1] != '\n') {
+ char *old = response;
+ response = g_strdup_printf ("%s\n", response);
+ g_free (old);
+ }
+ write (polkit_grant->child_stdin, response, strlen (response));
+ free (response);
+ }
+ }
+
+ if (line != NULL)
+ free (line);
+}
+
+/**
+ * libpolkit_grant_cancel_auth:
+ * @polkit_grant: the object
+ *
+ * Cancel an authentication in progress
+ **/
+void
+libpolkit_grant_cancel_auth (PolKitGrant *polkit_grant)
+{
+ GPid pid;
+ g_return_if_fail (polkit_grant != NULL);
+ g_return_if_fail (polkit_grant->auth_in_progress);
+
+ pid = polkit_grant->child_pid;
+ polkit_grant->child_pid = 0;
+ kill (pid, SIGTERM);
+ polkit_grant->func_done (polkit_grant, FALSE, polkit_grant->user_data);
+}
+
+/**
+ * libpolkit_grant_initiate_auth:
+ * @polkit_grant: the object
+ * @action: Action requested by caller
+ * @resource: Resource in question
+ * @caller: Caller in question
+ *
+ * Initiate authentication to obtain the privilege for the given
+ * @caller to perform the specified @action on the given
+ * @resource. The caller of this method must have setup callback
+ * functions using the method libpolkit_grant_set_functions() prior to
+ * calling this method.
+ *
+ * Implementation-wise, this class uses a secure (e.g. as in that it
+ * checks all information and fundamenally don't trust the caller;
+ * e.g. the #PolKitGrant class) setgid helper that does all the heavy
+ * lifting.
+ *
+ * The caller of this method must iterate the mainloop context in
+ * order for authentication to make progress.
+ *
+ * Returns: #TRUE only if authentication have been initiated.
+ **/
+polkit_bool_t
+libpolkit_grant_initiate_auth (PolKitGrant *polkit_grant,
+ PolKitAction *action,
+ PolKitResource *resource,
+ PolKitCaller *caller)
+{
+ char *dbus_name;
+ char *action_id;
+ char *resource_type;
+ char *resource_id;
+ GError *g_error;
+ const char *helper_argv[6];
+
+ g_return_val_if_fail (polkit_grant != NULL, FALSE);
+ /* check that callback functions have been properly set up */
+ g_return_val_if_fail (polkit_grant->func_done != NULL, FALSE);
+
+ if (!libpolkit_caller_get_dbus_name (caller, &dbus_name))
+ goto error;
+
+ if (!libpolkit_action_get_action_id (action, &action_id))
+ goto error;
+
+ if (!libpolkit_resource_get_resource_type (resource, &resource_type))
+ goto error;
+
+ if (!libpolkit_resource_get_resource_id (resource, &resource_id))
+ goto error;
+
+ /* TODO: verify incoming args */
+
+ //helper_argv[0] = "/home/davidz/Hacking/PolicyKit/libpolkit-grant/.libs/polkit-grant-helper";
+ helper_argv[0] = PACKAGE_LIBEXEC_DIR "/polkit-grant-helper";
+ helper_argv[1] = dbus_name;
+ helper_argv[2] = action_id;
+ helper_argv[3] = resource_type;
+ helper_argv[4] = resource_id;
+ helper_argv[5] = NULL;
+
+ polkit_grant->child_stdin = -1;
+ polkit_grant->child_stdout = -1;
+
+ g_error = NULL;
+ if (!g_spawn_async_with_pipes (NULL,
+ (char **) helper_argv,
+ NULL,
+ G_SPAWN_DO_NOT_REAP_CHILD |
+ 0,//G_SPAWN_STDERR_TO_DEV_NULL,
+ NULL,
+ NULL,
+ &polkit_grant->child_pid,
+ &polkit_grant->child_stdin,
+ &polkit_grant->child_stdout,
+ NULL,
+ &g_error)) {
+ fprintf (stderr, "Cannot spawn helper: %s.\n", g_error->message);
+ g_error_free (g_error);
+ goto error;
+ }
+
+ polkit_grant->child_watch_id = polkit_grant->func_add_child_watch (polkit_grant, polkit_grant->child_pid);
+ if (polkit_grant->child_watch_id == 0)
+ goto error;
+
+ polkit_grant->io_watch_id = polkit_grant->func_add_io_watch (polkit_grant, polkit_grant->child_stdout);
+ if (polkit_grant->io_watch_id == 0)
+ goto error;
+
+ /* so we can use getline... */
+ polkit_grant->child_stdout_f = fdopen (polkit_grant->child_stdout, "r");
+ if (polkit_grant->child_stdout_f == NULL)
+ goto error;
+
+ polkit_grant->success = FALSE;
+
+ polkit_grant->auth_in_progress = TRUE;
+
+ return TRUE;
+error:
+ return FALSE;
+}
diff --git a/libpolkit-grant/libpolkit-grant.h b/libpolkit-grant/libpolkit-grant.h
new file mode 100644
index 0000000..0ba8925
--- /dev/null
+++ b/libpolkit-grant/libpolkit-grant.h
@@ -0,0 +1,344 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/***************************************************************************
+ *
+ * libpolkit-grant.h : library for obtaining privileges
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+#ifndef LIBPOLKIT_GRANT_H
+#define LIBPOLKIT_GRANT_H
+
+#include <libpolkit/libpolkit.h>
+
+struct PolKitGrant;
+typedef struct PolKitGrant PolKitGrant;
+
+/**
+ * PolKitGrantType:
+ * @polkit_grant: the grant object
+ * @grant_type: the current type of what privilege to obtain
+ * @user_data: user data pointed as passed into libpolkit_grant_set_functions()
+ *
+ * Type for callback function that describes to what extent the
+ * privilege can be obtained; e.g. whether the user can keep it
+ * (e.g. forever, for the session or not keep it at all).
+ *
+ * See also #PolKitGrantOverrideGrantType for discussion on the type
+ * of user interfaces one should put up depending on the value of
+ * @grant_type.
+ **/
+typedef void (*PolKitGrantType) (PolKitGrant *polkit_grant,
+ PolKitResult grant_type,
+ void *user_data);
+
+/**
+ * PolKitGrantConversationPromptEchoOff:
+ * @polkit_grant: the grant object
+ * @prompt: prompt passed by the authentication layer; do not free this string
+ * @user_data: user data pointed as passed into libpolkit_grant_set_functions()
+ *
+ * Type for callback function that is invoked when the authentication
+ * layer needs to ask the user a secret and the UI should NOT echo what
+ * the user types on the screen.
+ *
+ * Returns: the answer obtained from the user; must be allocated with
+ * malloc(3) and will be freed by the #PolKitGrant class.
+ **/
+typedef char* (*PolKitGrantConversationPromptEchoOff) (PolKitGrant *polkit_grant,
+ const char *prompt,
+ void *user_data);
+
+/**
+ * PolKitGrantConversationPromptEchoOn:
+ * @polkit_grant: the grant object
+ * @prompt: prompt passed by the authentication layer; do not free this string
+ * @user_data: user data pointed as passed into libpolkit_grant_set_functions()
+ *
+ * Type for callback function that is invoked when the authentication
+ * layer needs to ask the user a secret and the UI should echo what
+ * the user types on the screen.
+ *
+ * Returns: the answer obtained from the user; must be allocated with
+ * malloc(3) and will be freed by the #PolKitGrant class.
+ **/
+typedef char* (*PolKitGrantConversationPromptEchoOn) (PolKitGrant *polkit_grant,
+ const char *prompt,
+ void *user_data);
+
+/**
+ * PolKitGrantConversationErrorMessage:
+ * @polkit_grant: the grant object
+ * @error_message: error message passed by the authentication layer; do not free this string
+ * @user_data: user data pointed as passed into libpolkit_grant_set_functions()
+ *
+ * Type for callback function that is invoked when the authentication
+ * layer produces an error message that should be displayed in the UI.
+ **/
+typedef void (*PolKitGrantConversationErrorMessage) (PolKitGrant *polkit_grant,
+ const char *error_message,
+ void *user_data);
+
+/**
+ * PolKitGrantConversationTextInfo:
+ * @polkit_grant: the grant object
+ * @text_info: information passed by the authentication layer; do not free this string
+ * @user_data: user data pointed as passed into libpolkit_grant_set_functions()
+ *
+ * Type for callback function that is invoked when the authentication
+ * layer produces an informational message that should be displayed in
+ * the UI.
+ **/
+typedef void (*PolKitGrantConversationTextInfo) (PolKitGrant *polkit_grant,
+ const char *text_info,
+ void *user_data);
+
+/**
+ * PolKitGrantOverrideGrantType:
+ * @polkit_grant: the grant object
+ * @grant_type: the current type of what privilege to obtain; this is
+ * the same value as passed to the callback of type #PolKitGrantType.
+ * @user_data: user data pointed as passed into libpolkit_grant_set_functions()
+ *
+ * Type for callback function that enables the UI to request a lesser
+ * privilege than is obtainable. This callback is invoked when the
+ * user have successfully authenticated but before the privilege is
+ * granted.
+ *
+ * Basically, this callback enables a program to provide an user
+ * interface like this:
+ *
+ * <programlisting>
+ * +------------------------------------------------------------+
+ * | You need to authenticate to access the volume 'Frobnicator |
+ * | Adventures Vol 2' |
+ * | |
+ * | Password: [_________________] |
+ * | |
+ * [ [x] Remember this decision |
+ * | [ ] for this session |
+ * | [*] for this and future sessions |
+ * | |
+ * | [Cancel] [Authenticate] |
+ * +------------------------------------------------------------+
+ * </programlisting>
+ *
+ * This dialog assumes that @grant_type passed was
+ * #LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_ALWAYS. By ticking the
+ * check boxes in the dialog, the user can override this to either
+ * #LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_SESSION or
+ * #LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH. Thus, the user can
+ * voluntarily choose to obtain a lesser privilege.
+ *
+ * Another example, would be that the @grant_type passed was
+ * #LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_SESSION. Then the dialog
+ * should look like this:
+ *
+ * <programlisting>
+ * +------------------------------------------------------------+
+ * | You need to authenticate to access the volume 'Frobnicator |
+ * | Adventures Vol 2' |
+ * | |
+ * | Password: [_________________] |
+ * | |
+ * [ [x] Remember this decision for the rest of the session |
+ * | |
+ * | [Cancel] [Authenticate] |
+ * +------------------------------------------------------------+
+ * </programlisting>
+ *
+ * Finally, if the @grant_type value passed is
+ * e.g. #LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH, there are no options to
+ * click.:
+ *
+ * <programlisting>
+ * +------------------------------------------------------------+
+ * | You need to authenticate to access the volume 'Frobnicator |
+ * | Adventures Vol 2' |
+ * | |
+ * | Password: [_________________] |
+ * | |
+ * | [Cancel] [Authenticate] |
+ * +------------------------------------------------------------+
+ * </programlisting>
+ *
+ * Of course, these examples also applies to
+ * #LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH and friends.
+ *
+ * Returns: the desired type of what privilege to obtain; note that it
+ * won't work asking for more privileges than what @grant_type
+ * specifies; the passed value is properly checked in the secure
+ * setgid granting helper mentioned in
+ * libpolkit_grant_initiate_auth().
+ **/
+typedef PolKitResult (*PolKitGrantOverrideGrantType) (PolKitGrant *polkit_grant,
+ PolKitResult grant_type,
+ void *user_data);
+
+/**
+ * PolKitGrantDone:
+ * @polkit_grant: the grant object
+ * @gained_privilege: whether the privilege was obtained
+ * @user_data: user data pointed as passed into libpolkit_grant_set_functions()
+ *
+ * This function is called when the granting process ends; either if
+ * successful or if it was canceled using
+ * e.g. libpolkit_grant_cancel_auth().
+ **/
+typedef void (*PolKitGrantDone) (PolKitGrant *polkit_grant,
+ polkit_bool_t gained_privilege,
+ void *user_data);
+
+/**
+ * PolKitGrantAddChildWatch:
+ * @polkit_grant: the grant object
+ * @pid: the child pid to watch
+ *
+ * Type for function supplied by the application to integrate a watch
+ * on a child process into the applications main loop. The
+ * application must call libpolkit_grant_child_func() when the
+ * child dies
+ *
+ * For glib mainloop, the function will typically look like this:
+ *
+ * <programlisting>
+ * static void
+ * child_watch_func (GPid pid,
+ * gint status,
+ * gpointer user_data)
+ * {
+ * PolKitGrant *polkit_grant = user_data;
+ * libpolkit_grant_child_func (polkit_grant, pid, WEXITSTATUS (status));
+ * }
+ *
+ * static int
+ * add_child_watch (PolKitGrant *polkit_grant, pid_t pid)
+ * {
+ * return g_child_watch_add (pid, child_watch_func, polkit_grant);
+ * }
+ * </programlisting>
+ *
+ * Returns: 0 if the watch couldn't be set up; otherwise an unique
+ * identifier for the watch.
+ **/
+typedef int (*PolKitGrantAddChildWatch) (PolKitGrant *polkit_grant,
+ pid_t pid);
+
+/**
+ * PolKitGrantAddIOWatch:
+ * @polkit_grant: the grant object
+ * @fd: the file descriptor to watch
+ *
+ * Type for function supplied by the application to integrate a watch
+ * on a file descriptor into the applications main loop. The
+ * application must call libpolkit_grant_io_func() when there is data
+ * to read from the file descriptor.
+ *
+ * For glib mainloop, the function will typically look like this:
+ *
+ * <programlisting>
+ * static gboolean
+ * io_watch_have_data (GIOChannel *channel, GIOCondition condition, gpointer user_data)
+ * {
+ * int fd;
+ * PolKitGrant *polkit_grant = user_data;
+ * fd = g_io_channel_unix_get_fd (channel);
+ * libpolkit_grant_io_func (polkit_grant, fd);
+ * return TRUE;
+ * }
+ *
+ * static int
+ * add_io_watch (PolKitGrant *polkit_grant, int fd)
+ * {
+ * guint id = 0;
+ * GIOChannel *channel;
+ * channel = g_io_channel_unix_new (fd);
+ * if (channel == NULL)
+ * goto out;
+ * id = g_io_add_watch (channel, G_IO_IN, io_watch_have_data, polkit_grant);
+ * if (id == 0) {
+ * g_io_channel_unref (channel);
+ * goto out;
+ * }
+ * g_io_channel_unref (channel);
+ * out:
+ * return id;
+ * }
+ * </programlisting>
+ *
+ * Returns: 0 if the watch couldn't be set up; otherwise an unique
+ * identifier for the watch.
+ **/
+typedef int (*PolKitGrantAddIOWatch) (PolKitGrant *polkit_grant,
+ int fd);
+
+/**
+ * PolKitGrantRemoveWatch:
+ * @polkit_grant: the grant object
+ * @watch_id: the id obtained from using the supplied function
+ * of type #PolKitGrantAddIOWatch or #PolKitGrantAddChildWatch.
+ *
+ * Type for function supplied by the application to remove a watch set
+ * up via the supplied function of type #PolKitGrantAddIOWatch or type
+ * #PolKitGrantAddChildWatch.
+ *
+ * For glib mainloop, the function will typically look like this:
+ *
+ * <programlisting>
+ * static void
+ * remove_watch (PolKitGrant *polkit_auth, int watch_id)
+ * {
+ * g_source_remove (watch_id);
+ * }
+ * </programlisting>
+ *
+ **/
+typedef void (*PolKitGrantRemoveWatch) (PolKitGrant *polkit_grant,
+ int watch_id);
+
+PolKitGrant *libpolkit_grant_new (void);
+PolKitGrant *libpolkit_grant_ref (PolKitGrant *polkit_grant);
+void libpolkit_grant_unref (PolKitGrant *polkit_grant);
+void libpolkit_grant_set_functions (PolKitGrant *polkit_grant,
+ PolKitGrantAddIOWatch func_add_io_watch,
+ PolKitGrantAddChildWatch func_add_child_watch,
+ PolKitGrantRemoveWatch func_remove_watch,
+ PolKitGrantType func_type,
+ PolKitGrantConversationPromptEchoOff func_prompt_echo_off,
+ PolKitGrantConversationPromptEchoOn func_prompt_echo_on,
+ PolKitGrantConversationErrorMessage func_error_message,
+ PolKitGrantConversationTextInfo func_text_info,
+ PolKitGrantOverrideGrantType func_override_grant_type,
+ PolKitGrantDone func_done,
+ void *user_data);
+polkit_bool_t libpolkit_grant_initiate_auth (PolKitGrant *polkit_grant,
+ PolKitAction *action,
+ PolKitResource *resource,
+ PolKitCaller *caller);
+
+void libpolkit_grant_cancel_auth (PolKitGrant *polkit_grant);
+
+void libpolkit_grant_io_func (PolKitGrant *polkit_grant, int fd);
+void libpolkit_grant_child_func (PolKitGrant *polkit_grant, pid_t pid, int exit_code);
+
+
+#endif /* LIBPOLKIT_GRANT_H */
+
+
diff --git a/libpolkit-grant/polkit-grant-helper.c b/libpolkit-grant/polkit-grant-helper.c
new file mode 100644
index 0000000..cd48810
--- /dev/null
+++ b/libpolkit-grant/polkit-grant-helper.c
@@ -0,0 +1,514 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/***************************************************************************
+ *
+ * polkit-grant-helper.c : setgid 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
+ *
+ **************************************************************************/
+
+/* TODO: FIXME: XXX: this code needs security review before it can be released! */
+
+#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 <security/pam_appl.h>
+#include <grp.h>
+#include <pwd.h>
+
+#include <glib.h>
+
+#include <libpolkit-dbus/libpolkit-dbus.h>
+
+static int
+conversation_function (int n,
+ const struct pam_message **msg,
+ struct pam_response **resp,
+ void *data)
+{
+ struct pam_response *aresp;
+ char buf[PAM_MAX_RESP_SIZE];
+ int i;
+
+ data = data;
+ if (n <= 0 || n > PAM_MAX_NUM_MSG)
+ return PAM_CONV_ERR;
+
+ if ((aresp = calloc(n, sizeof *aresp)) == NULL)
+ return PAM_BUF_ERR;
+
+ for (i = 0; i < n; ++i) {
+ aresp[i].resp_retcode = 0;
+ aresp[i].resp = NULL;
+ switch (msg[i]->msg_style) {
+ case PAM_PROMPT_ECHO_OFF:
+ fprintf (stdout, "PAM_PROMPT_ECHO_OFF ");
+ goto conv1;
+ case PAM_PROMPT_ECHO_ON:
+ fprintf (stdout, "PAM_PROMPT_ECHO_ON ");
+ conv1:
+ fputs (msg[i]->msg, stdout);
+ if (strlen (msg[i]->msg) > 0 &&
+ msg[i]->msg[strlen (msg[i]->msg) - 1] != '\n')
+ fputc ('\n', stdout);
+ fflush (stdout);
+
+ if (fgets (buf, sizeof buf, stdin) == NULL)
+ goto error;
+ if (strlen (buf) > 0 &&
+ buf[strlen (buf) - 1] == '\n')
+ buf[strlen (buf) - 1] = '\0';
+
+ aresp[i].resp = strdup (buf);
+ if (aresp[i].resp == NULL)
+ goto error;
+ break;
+
+ case PAM_ERROR_MSG:
+ fprintf (stdout, "PAM_ERROR_MSG ");
+ goto conv2;
+
+ case PAM_TEXT_INFO:
+ fprintf (stdout, "PAM_TEXT_INFO ");
+ conv2:
+ fputs(msg[i]->msg, stdout);
+ if (strlen(msg[i]->msg) > 0 &&
+ msg[i]->msg[strlen (msg[i]->msg) - 1] != '\n')
+ fputc ('\n', stdout);
+
+ fflush (stdout);
+ break;
+ default:
+ goto error;
+ }
+ }
+ *resp = aresp;
+ return PAM_SUCCESS;
+
+error:
+ for (i = 0; i < n; ++i) {
+ if (aresp[i].resp != NULL) {
+ memset (aresp[i].resp, 0, strlen(aresp[i].resp));
+ free (aresp[i].resp);
+ }
+ }
+ memset (aresp, 0, n * sizeof *aresp);
+ *resp = NULL;
+ return PAM_CONV_ERR;
+}
+
+static polkit_bool_t
+do_auth (const char *user_to_auth)
+{
+ struct pam_conv pam_conversation;
+ pam_handle_t *pam_h;
+ const void *authed_user;
+ int rc;
+
+ pam_conversation.conv = conversation_function;
+ pam_conversation.appdata_ptr = NULL;
+
+ /* start the pam stack */
+ rc = pam_start ("polkit",
+ user_to_auth,
+ &pam_conversation,
+ &pam_h);
+ if (rc != PAM_SUCCESS) {
+ fprintf (stderr, "pam_start failed: %s\n", pam_strerror (pam_h, rc));
+ goto error;
+ }
+
+ /* is user really user? */
+ rc = pam_authenticate (pam_h, 0);
+ if (rc != PAM_SUCCESS) {
+ fprintf (stderr, "pam_authenticated failed: %s\n", pam_strerror (pam_h, rc));
+ goto error;
+ }
+
+ /* permitted access? */
+ rc = pam_acct_mgmt (pam_h, 0);
+ if (rc != PAM_SUCCESS) {
+ fprintf (stderr, "pam_acct_mgmt failed: %s\n", pam_strerror (pam_h, rc));
+ goto error;
+ }
+
+ /* did we auth the right user? */
+ rc = pam_get_item (pam_h, PAM_USER, &authed_user);
+ if (rc != PAM_SUCCESS) {
+ fprintf (stderr, "pam_get_item failed: %s\n", pam_strerror (pam_h, rc));
+ goto error;
+ }
+
+ if (strcmp (authed_user, user_to_auth) != 0) {
+ fprintf (stderr, "Tried to auth user '%s' but we got auth for user '%s' instead",
+ user_to_auth, (const char *) authed_user);
+ goto error;
+ }
+
+ return TRUE;
+ /* TODO: we should probably clean up */
+error:
+ return FALSE;
+}
+
+static polkit_bool_t
+verify_with_polkit (const char *dbus_name,
+ const char *action_name,
+ const char *resource_type,
+ const char *resource_name,
+ PolKitResult *result,
+ char **out_session_objpath)
+{
+ PolKitCaller *caller;
+ PolKitSession *session;
+ char *str;
+ DBusConnection *bus;
+ DBusError error;
+ PolKitContext *pol_ctx;
+ PolKitAction *action;
+ PolKitResource *resource;
+
+ dbus_error_init (&error);
+ bus = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
+ if (bus == NULL) {
+ fprintf (stderr, "cannot connect to system bus: %s: %s\n", error.name, error.message);
+ dbus_error_free (&error);
+ goto out;
+ }
+
+ action = libpolkit_action_new ();
+ libpolkit_action_set_action_id (action, action_name);
+
+ if (resource_type != NULL && resource_name != NULL) {
+ resource = libpolkit_resource_new ();
+ libpolkit_resource_set_resource_type (resource, resource_type);
+ libpolkit_resource_set_resource_id (resource, resource_name);
+ } else {
+ resource = NULL;
+ }
+
+ caller = libpolkit_caller_new_from_dbus_name (bus, dbus_name, &error);
+ if (caller == NULL) {
+ fprintf (stderr, "cannot get caller from dbus name\n");
+ goto out;
+ }
+
+ if (!libpolkit_caller_get_ck_session (caller, &session)) {
+ fprintf (stderr, "caller is not in a session\n");
+ goto out;
+ }
+ if (!libpolkit_session_get_ck_objref (session, &str)) {
+ fprintf (stderr, "cannot get session ck objpath\n");
+ goto out;
+ }
+ *out_session_objpath = g_strdup (str);
+ if (*out_session_objpath == NULL)
+ goto out;
+
+ //libpolkit_caller_debug (caller);
+
+ pol_ctx = libpolkit_context_new ();
+ if (!libpolkit_context_init (pol_ctx, NULL)) {
+ fprintf (stderr, "cannot init polkit\n");
+ goto out;
+ }
+
+ *result = libpolkit_context_can_caller_access_resource (pol_ctx, action, resource, caller);
+
+ if (*result != LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH &&
+ *result != LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH_KEEP_SESSION &&
+ *result != LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH_KEEP_ALWAYS &&
+ *result != LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH &&
+ *result != LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_SESSION &&
+ *result != LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_ALWAYS) {
+ fprintf (stderr, "given auth type is bogus\n");
+ goto out;
+ }
+
+ return TRUE;
+ /* TODO: we should probably clean up */
+out:
+ return FALSE;
+}
+
+static polkit_bool_t
+get_and_validate_override_details (PolKitResult *result)
+{
+ char buf[256];
+ PolKitResult desired_result;
+
+ if (fgets (buf, sizeof buf, stdin) == NULL)
+ goto error;
+ if (strlen (buf) > 0 &&
+ buf[strlen (buf) - 1] == '\n')
+ buf[strlen (buf) - 1] = '\0';
+
+ fprintf (stderr, "User said '%s'\n", buf);
+
+ if (!libpolkit_result_from_string_representation (buf, &desired_result))
+ goto error;
+
+ fprintf (stderr, "Testing for voluntarily downgrade from '%s' to '%s'\n",
+ libpolkit_result_to_string_representation (*result),
+ libpolkit_result_to_string_representation (desired_result));
+
+ /* See the huge comment in main() below...
+ *
+ * it comes down to this... users can only choose a more restricted granting type...
+ *
+ */
+ switch (*result) {
+ case LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH:
+ if (desired_result != LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH)
+ goto error;
+ break;
+ case LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH_KEEP_SESSION:
+ if (desired_result != LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH &&
+ desired_result != LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH_KEEP_SESSION)
+ goto error;
+ break;
+ case LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH_KEEP_ALWAYS:
+ if (desired_result != LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH &&
+ desired_result != LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH_KEEP_SESSION &&
+ desired_result != LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH_KEEP_ALWAYS)
+ goto error;
+ break;
+
+ case LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH:
+ if (desired_result != LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH)
+ goto error;
+ break;
+ case LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_SESSION:
+ if (desired_result != LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH &&
+ desired_result != LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_SESSION)
+ goto error;
+ break;
+ case LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_ALWAYS:
+ if (desired_result != LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH &&
+ desired_result != LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_SESSION &&
+ desired_result != LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_ALWAYS)
+ goto error;
+ break;
+
+ default:
+ /* we should never reach this */
+ goto error;
+ }
+
+ if (*result != desired_result) {
+ fprintf (stderr, "Voluntarily downgrading from '%s' to '%s'\n",
+ libpolkit_result_to_string_representation (*result),
+ libpolkit_result_to_string_representation (desired_result));
+ }
+
+ *result = desired_result;
+
+ return TRUE;
+error:
+ return FALSE;
+}
+
+/* synopsis: /usr/libexec/polkit-grant-helper <auth-type> <dbus-name> <action-name> <resource-type> <resource-name>
+ *
+ * <dbus-name> : unique name of caller on the system message bus to grant privilege to
+ * <action-name> : the PolicyKit action
+ * <resource-type> : resource-type
+ * <resource-name> : resource-name
+ *
+ * PAM interaction happens via stdin/stdout.
+ *
+ * If auth fails, we exit with code 1.
+ * If input is not valid we exit with code 2.
+ * If any other error occur we exit with code 3
+ * If privilege was grant, we exit code 0.
+ */
+
+int
+main (int argc, char *argv[])
+{
+ int ret;
+ uid_t invoking_user_id;
+ const char *invoking_user_name;
+ const char *dbus_name;
+ const char *action_name;
+ const char *resource_type;
+ const char *resource_name;
+ PolKitResult result;
+ const char *user_to_auth;
+ char *session_objpath;
+ gid_t egid;
+ struct group *group;
+ struct passwd *pw;
+
+ ret = 3;
+
+ if (argc != 5) {
+ fprintf (stderr, "wrong use\n");
+ goto out;
+ }
+
+ /* check user */
+ invoking_user_id = getuid ();
+ if (invoking_user_id == 0) {
+ fprintf (stderr, "it only makes sense to run polkit-grant-helper as non-root\n");
+ goto out;
+ }
+ pw = getpwuid (invoking_user_id);
+ if (pw == NULL) {
+ fprintf (stderr, "cannot lookup passwd info for uid %d\n", invoking_user_id);
+ goto out;
+ }
+ invoking_user_name = strdup (pw->pw_name);
+ if (invoking_user_name == NULL) {
+ fprintf (stderr, "OOM allocating memory for invoking user name\n");
+ goto out;
+ }
+
+ fprintf (stderr, "invoking user '%s'\n", invoking_user_name);
+
+ /* check group */
+ egid = getegid ();
+ group = getgrgid (egid);
+ if (group == NULL) {
+ fprintf (stderr, "cannot lookup group info for gid %d\n", egid);
+ goto out;
+ }
+ if (strcmp (group->gr_name, POLKIT_GROUP) != 0) {
+ fprintf (stderr, "polkit-grant-helper needs to be setgid " POLKIT_GROUP "\n");
+ goto out;
+ }
+
+ fprintf (stderr, "Hello world %d %d %d %d!\n", getuid(), geteuid(), getgid(), getegid());
+
+ /* clear the entire environment to avoid attacks using with libraries honoring environment variables */
+ if (clearenv () != 0)
+ goto out;
+ /* hmm; seems like some library (libdbus) don't like environ==NULL .. TODO: file bug */
+ setenv ("PATH", "/bin:/usr/bin", 1);
+
+ dbus_name = argv[1];
+ action_name = argv[2];
+ resource_type = argv[3];
+ resource_name = argv[4];
+
+ fprintf (stderr, "dbus_name = %s\n", dbus_name);
+ fprintf (stderr, "action_name = %s\n", action_name);
+ fprintf (stderr, "resource_type = %s\n", resource_type);
+ fprintf (stderr, "resource_name = %s\n", resource_name);
+
+ ret = 2;
+
+ /* we don't trust the user one bit...so..
+ *
+ * verify that the given thing to auth for really supports grant by auth in the requested way
+ */
+ if (!verify_with_polkit (dbus_name, action_name, resource_type, resource_name, &result, &session_objpath))
+ goto out;
+
+ /* tell user about the grant details; e.g. whether it's auth_self_keep_always or auth_self etc. */
+ fprintf (stdout, "POLKIT_GRANT_HELPER_TELL_TYPE %s\n", libpolkit_result_to_string_representation (result));
+ fflush (stdout);
+
+ /* figure out what user to auth */
+ if (result == LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH ||
+ result == LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH_KEEP_SESSION ||
+ result == LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH_KEEP_ALWAYS) {
+ user_to_auth = "root";
+ } else {
+ user_to_auth = invoking_user_name;
+ }
+
+ /* OK, start auth! */
+ if (!do_auth (user_to_auth))
+ goto out;
+
+ /* ask user if he want to slim down grant type...
+ * e.g. he might want to go from auth_self_keep_always to auth_self_keep_session..
+ *
+ * See docs for the PolKitGrantOverrideGrantType callback type for use cases.
+ */
+ fprintf (stdout, "POLKIT_GRANT_HELPER_ASK_OVERRIDE_GRANT_TYPE %s\n",
+ libpolkit_result_to_string_representation (result));
+ fflush (stdout);
+
+ if (!get_and_validate_override_details (&result))
+ goto out;
+
+ /* TODO: FIXME: XXX: this format of storing granted privileges needs be redone
+ *
+ * this concerns these two files
+ * - libpolkit-grant/polkit-grant-helper.c
+ * - modules/grant/polkit-module-grant.c
+ */
+
+ /*
+ * /var/lib/PolicyKit/uid_<uid>_<action>_<resource-hash>.grant
+ * uid_<uid>_<action>.grant
+ *
+ * /var/run/PolicyKit/session_<session>_<uid>_<action>_<resource-hash>.grant
+ * session_<session>_<uid>_<action>.grant
+ * dbus_<dbusname>_<uid>_<action>_<resource-hash>.grant
+ */
+
+ char *grant_file;
+ const char *session_name;
+ char *resource_str_to_hash;
+ guint resource_hash;
+ session_name = g_basename (session_objpath);
+ resource_str_to_hash = g_strdup_printf ("%s:%s", resource_type, resource_name);
+ resource_hash = g_str_hash (resource_str_to_hash);
+ g_free (resource_str_to_hash);
+
+ switch (result) {
+ case LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH:
+ case LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH:
+ grant_file = g_strdup_printf (PACKAGE_LOCALSTATE_DIR "/run/PolicyKit/dbus_%s_%d_%s_%u.grant",
+ dbus_name, invoking_user_id, action_name, resource_hash);
+ break;
+
+ case LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH_KEEP_SESSION:
+ case LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_SESSION:
+ grant_file = g_strdup_printf (PACKAGE_LOCALSTATE_DIR "/run/PolicyKit/session_%s_%d_%s_%u.grant",
+ session_name, invoking_user_id, action_name, resource_hash);
+ break;
+
+ case LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_ALWAYS:
+ case LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH_KEEP_ALWAYS:
+ grant_file = g_strdup_printf (PACKAGE_LOCALSTATE_DIR "/lib/PolicyKit/uid_%d_%s_%u.grant",
+ invoking_user_id, action_name, resource_hash);
+ break;
+ default:
+ /* should never happen */
+ goto out;
+ }
+
+ umask (~0464);
+ fprintf (stderr, "file is '%s'\n", grant_file);
+ FILE *f = fopen (grant_file, "w");
+ fclose (f);
+
+ ret = 0;
+out:
+ return ret;
+}
diff --git a/libpolkit.pc.in b/libpolkit.pc.in
index 20a2f77..3f36d2d 100644
--- a/libpolkit.pc.in
+++ b/libpolkit.pc.in
@@ -6,6 +6,6 @@ includedir=@includedir@
Name: libpolkit
Description: library for querying system-wide policy
Version: @VERSION@
-Requires: glib-2.0 dbus-1
+Requires: glib-2.0
Libs: -L${libdir} -lpolkit
Cflags: -I${includedir}/PolicyKit
diff --git a/libpolkit/Makefile.am b/libpolkit/Makefile.am
index f0bb035..457f07a 100644
--- a/libpolkit/Makefile.am
+++ b/libpolkit/Makefile.am
@@ -10,7 +10,8 @@ INCLUDES = \
-DPACKAGE_LOCALE_DIR=\""$(localedir)"\" \
-DPACKAGE_LIB_DIR=\""$(libdir)"\" \
-D_POSIX_PTHREAD_SEMANTICS -D_REENTRANT \
- @GLIB_CFLAGS@ @DBUS_CFLAGS@
+ -DPOLKIT_COMPILATION \
+ @GLIB_CFLAGS@
lib_LTLIBRARIES=libpolkit.la
@@ -18,6 +19,7 @@ libpolkitincludedir=$(includedir)/Policy
libpolkitinclude_HEADERS = \
libpolkit.h \
+ libpolkit-types.h \
libpolkit-error.h \
libpolkit-result.h \
libpolkit-context.h \
@@ -34,6 +36,7 @@ libpolkitinclude_HEADERS =
libpolkit_la_SOURCES = \
libpolkit.h \
+ libpolkit-types.h \
libpolkit-error.h libpolkit-error.c \
libpolkit-result.h libpolkit-result.c \
libpolkit-context.h libpolkit-context.c \
@@ -47,9 +50,10 @@ libpolkit_la_SOURCES =
libpolkit-policy-cache.h libpolkit-policy-cache.c \
libpolkit-policy-default.h libpolkit-policy-default.c \
libpolkit-debug.h libpolkit-debug.c \
+ libpolkit-utils.h libpolkit-utils.c \
libpolkit-module.h libpolkit-module.c
-libpolkit_la_LIBADD = @GLIB_LIBS@ @DBUS_LIBS@ -ldl
+libpolkit_la_LIBADD = @GLIB_LIBS@ -ldl
libpolkit_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
diff --git a/libpolkit/libpolkit-action.c b/libpolkit/libpolkit-action.c
index 19bd3dd..34ef594 100644
--- a/libpolkit/libpolkit-action.c
+++ b/libpolkit/libpolkit-action.c
@@ -39,6 +39,7 @@
#include <glib.h>
#include "libpolkit-debug.h"
#include "libpolkit-action.h"
+#include "libpolkit-utils.h"
/**
* SECTION:libpolkit-action
@@ -121,14 +122,18 @@ libpolkit_action_unref (PolKitAction *ac
* @action_id: action identifier
*
* Set the action identifier
+ *
+ * Returns: #TRUE only if the value validated and was set
**/
-void
+polkit_bool_t
libpolkit_action_set_action_id (PolKitAction *action, const char *action_id)
{
- g_return_if_fail (action != NULL);
+ g_return_val_if_fail (action != NULL, FALSE);
+ g_return_val_if_fail (_pk_validate_identifier (action_id), FALSE);
if (action->id != NULL)
g_free (action->id);
action->id = g_strdup (action_id);
+ return TRUE;
}
/**
@@ -140,7 +145,7 @@ libpolkit_action_set_action_id (PolKitAc
*
* Returns: TRUE iff the value was returned.
**/
-bool
+polkit_bool_t
libpolkit_action_get_action_id (PolKitAction *action, char **out_action_id)
{
g_return_val_if_fail (action != NULL, FALSE);
@@ -237,3 +242,18 @@ libpolkit_action_param_foreach (PolKitAc
g_hash_table_foreach (action->params, _hash_cb, &data);
}
+/**
+ * libpolkit_action_validate:
+ * @action: the object
+ *
+ * Validate the object
+ *
+ * Returns: #TRUE iff the object is valid.
+ **/
+polkit_bool_t
+libpolkit_action_validate (PolKitAction *action)
+{
+ g_return_val_if_fail (action != NULL, FALSE);
+ g_return_val_if_fail (action->id != NULL, FALSE);
+ return TRUE;
+}
diff --git a/libpolkit/libpolkit-action.h b/libpolkit/libpolkit-action.h
index 1f7b192..df4888f 100644
--- a/libpolkit/libpolkit-action.h
+++ b/libpolkit/libpolkit-action.h
@@ -23,10 +23,14 @@
*
**************************************************************************/
+#if !defined (POLKIT_COMPILATION) && !defined(_POLKIT_INSIDE_POLKIT_H)
+#error "Only <libpolkit/libpolkit.h> can be included directly, this file may disappear or change contents."
+#endif
+
#ifndef LIBPOLKIT_ACTION_H
#define LIBPOLKIT_ACTION_H
-#include <stdbool.h>
+#include <libpolkit/libpolkit-types.h>
struct PolKitAction;
typedef struct PolKitAction PolKitAction;
@@ -48,14 +52,15 @@ typedef void (*PolKitActionParamForeachF
PolKitAction *libpolkit_action_new (void);
PolKitAction *libpolkit_action_ref (PolKitAction *action);
void libpolkit_action_unref (PolKitAction *action);
-void libpolkit_action_set_action_id (PolKitAction *action, const char *action_id);
-bool libpolkit_action_get_action_id (PolKitAction *action, char **out_action_id);
+polkit_bool_t libpolkit_action_set_action_id (PolKitAction *action, const char *action_id);
+polkit_bool_t libpolkit_action_get_action_id (PolKitAction *action, char **out_action_id);
void libpolkit_action_set_param (PolKitAction *action, const char *key, const char *value);
const char *libpolkit_action_get_param (PolKitAction *action, const char *key);
void libpolkit_action_param_foreach (PolKitAction *action, PolKitActionParamForeachFunc cb, void *user_data);
void libpolkit_action_debug (PolKitAction *action);
+polkit_bool_t libpolkit_action_validate (PolKitAction *action);
#endif /* LIBPOLKIT_ACTION_H */
diff --git a/libpolkit/libpolkit-caller.c b/libpolkit/libpolkit-caller.c
index c029d41..c9808ae 100644
--- a/libpolkit/libpolkit-caller.c
+++ b/libpolkit/libpolkit-caller.c
@@ -46,6 +46,7 @@
#include <glib.h>
#include "libpolkit-debug.h"
#include "libpolkit-caller.h"
+#include "libpolkit-utils.h"
/**
* PolKitCaller:
@@ -57,7 +58,7 @@ struct PolKitCaller
{
int refcount;
char *dbus_name;
- pid_t uid;
+ uid_t uid;
pid_t pid;
char *selinux_context;
PolKitSession *session;
@@ -124,14 +125,18 @@ libpolkit_caller_unref (PolKitCaller *ca
* @dbus_name: unique system bus connection name
*
* Set the callers unique system bus connection name.
+ *
+ * Returns: #TRUE only if the value validated and was set
**/
-void
+polkit_bool_t
libpolkit_caller_set_dbus_name (PolKitCaller *caller, const char *dbus_name)
{
- g_return_if_fail (caller != NULL);
+ g_return_val_if_fail (caller != NULL, FALSE);
+ g_return_val_if_fail (_pk_validate_unique_bus_name (dbus_name), FALSE);
if (caller->dbus_name != NULL)
g_free (caller->dbus_name);
caller->dbus_name = g_strdup (dbus_name);
+ return TRUE;
}
/**
@@ -140,12 +145,15 @@ libpolkit_caller_set_dbus_name (PolKitCa
* @uid: UNIX user id
*
* Set the callers UNIX user id.
+ *
+ * Returns: #TRUE only if the value validated and was set
**/
-void
+polkit_bool_t
libpolkit_caller_set_uid (PolKitCaller *caller, uid_t uid)
{
- g_return_if_fail (caller != NULL);
+ g_return_val_if_fail (caller != NULL, FALSE);
caller->uid = uid;
+ return TRUE;
}
/**
@@ -154,12 +162,15 @@ libpolkit_caller_set_uid (PolKitCaller *
* @pid: UNIX process id
*
* Set the callers UNIX process id.
+ *
+ * Returns: #TRUE only if the value validated and was set
**/
-void
+polkit_bool_t
libpolkit_caller_set_pid (PolKitCaller *caller, pid_t pid)
{
- g_return_if_fail (caller != NULL);
+ g_return_val_if_fail (caller != NULL, FALSE);
caller->pid = pid;
+ return TRUE;
}
/**
@@ -168,14 +179,20 @@ libpolkit_caller_set_pid (PolKitCaller *
* @selinux_context: SELinux security context
*
* Set the callers SELinux security context.
+ *
+ * Returns: #TRUE only if the value validated and was set
**/
-void
+polkit_bool_t
libpolkit_caller_set_selinux_context (PolKitCaller *caller, const char *selinux_context)
{
- g_return_if_fail (caller != NULL);
+ g_return_val_if_fail (caller != NULL, FALSE);
+ /* TODO: probably should have a separate validation function for SELinux contexts */
+ g_return_val_if_fail (_pk_validate_identifier (selinux_context), FALSE);
+
if (caller->selinux_context != NULL)
g_free (caller->selinux_context);
caller->selinux_context = g_strdup (selinux_context);
+ return TRUE;
}
/**
@@ -186,14 +203,18 @@ libpolkit_caller_set_selinux_context (Po
* Set the callers session. The reference count on the given object
* will be increased by one. If an existing session object was set
* already, the reference count on that one will be decreased by one.
+ *
+ * Returns: #TRUE only if the value validated and was set
**/
-void
+polkit_bool_t
libpolkit_caller_set_ck_session (PolKitCaller *caller, PolKitSession *session)
{
- g_return_if_fail (caller != NULL);
+ g_return_val_if_fail (caller != NULL, FALSE);
+ g_return_val_if_fail (libpolkit_session_validate (session), FALSE);
if (caller->session != NULL)
libpolkit_session_unref (caller->session);
caller->session = session != NULL ? libpolkit_session_ref (session) : NULL;
+ return TRUE;
}
/**
@@ -205,7 +226,7 @@ libpolkit_caller_set_ck_session (PolKitC
*
* Returns: TRUE iff the value is returned
**/
-bool
+polkit_bool_t
libpolkit_caller_get_dbus_name (PolKitCaller *caller, char **out_dbus_name)
{
g_return_val_if_fail (caller != NULL, FALSE);
@@ -223,7 +244,7 @@ libpolkit_caller_get_dbus_name (PolKitCa
*
* Returns: TRUE iff the value is returned
**/
-bool
+polkit_bool_t
libpolkit_caller_get_uid (PolKitCaller *caller, uid_t *out_uid)
{
g_return_val_if_fail (caller != NULL, FALSE);
@@ -241,7 +262,7 @@ libpolkit_caller_get_uid (PolKitCaller *
*
* Returns: TRUE iff the value is returned
**/
-bool
+polkit_bool_t
libpolkit_caller_get_pid (PolKitCaller *caller, pid_t *out_pid)
{
g_return_val_if_fail (caller != NULL, FALSE);
@@ -260,7 +281,7 @@ libpolkit_caller_get_pid (PolKitCaller *
*
* Returns: TRUE iff the value is returned
**/
-bool
+polkit_bool_t
libpolkit_caller_get_selinux_context (PolKitCaller *caller, char **out_selinux_context)
{
g_return_val_if_fail (caller != NULL, FALSE);
@@ -279,7 +300,7 @@ libpolkit_caller_get_selinux_context (Po
*
* Returns: TRUE iff the value is returned
**/
-bool
+polkit_bool_t
libpolkit_caller_get_ck_session (PolKitCaller *caller, PolKitSession **out_session)
{
g_return_val_if_fail (caller != NULL, FALSE);
@@ -289,154 +310,6 @@ libpolkit_caller_get_ck_session (PolKitC
}
/**
- * libpolkit_caller_new_from_dbus_name:
- * @con: D-Bus system bus connection
- * @dbus_name: unique system bus connection name
- * @error: D-Bus error
- *
- * This function will construct a #PolKitCaller object by querying
- * both the system bus daemon and the ConsoleKit daemon for
- * information. Note that this will do a lot of blocking IO so it is
- * best avoided if your process already tracks/caches all the
- * information.
- *
- * Returns: the new object or #NULL if an error occured (in which case
- * @error will be set)
- **/
-PolKitCaller *
-libpolkit_caller_new_from_dbus_name (DBusConnection *con, const char *dbus_name, DBusError *error)
-{
- PolKitCaller *caller;
- pid_t pid;
- uid_t uid;
- char *selinux_context;
- char *ck_session_objpath;
- PolKitSession *session;
- DBusMessage *message;
- DBusMessage *reply;
- DBusMessageIter iter;
- DBusMessageIter sub_iter;
- char *str;
- int num_elems;
-
- g_return_val_if_fail (con != NULL, NULL);
- g_return_val_if_fail (dbus_name != NULL, NULL);
- g_return_val_if_fail (error != NULL, NULL);
- g_return_val_if_fail (! dbus_error_is_set (error), NULL);
-
- selinux_context = NULL;
- ck_session_objpath = NULL;
-
- caller = NULL;
- session = NULL;
-
- uid = dbus_bus_get_unix_user (con, dbus_name, error);
- if (uid == ((unsigned long) -1) || dbus_error_is_set (error)) {
- g_warning ("Could not get uid for connection: %s %s", error->name, error->message);
- goto out;
- }
-
- message = dbus_message_new_method_call ("org.freedesktop.DBus",
- "/org/freedesktop/DBus/Bus",
- "org.freedesktop.DBus",
- "GetConnectionUnixProcessID");
- dbus_message_iter_init_append (message, &iter);
- dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &dbus_name);
- reply = dbus_connection_send_with_reply_and_block (con, message, -1, error);
- if (reply == NULL || dbus_error_is_set (error)) {
- g_warning ("Error doing GetConnectionUnixProcessID on Bus: %s: %s", error->name, error->message);
- dbus_message_unref (message);
- if (reply != NULL)
- dbus_message_unref (reply);
- goto out;
- }
- dbus_message_iter_init (reply, &iter);
- dbus_message_iter_get_basic (&iter, &pid);
- dbus_message_unref (message);
- dbus_message_unref (reply);
-
- message = dbus_message_new_method_call ("org.freedesktop.DBus",
- "/org/freedesktop/DBus/Bus",
- "org.freedesktop.DBus",
- "GetConnectionSELinuxSecurityContext");
- dbus_message_iter_init_append (message, &iter);
- dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &dbus_name);
- reply = dbus_connection_send_with_reply_and_block (con, message, -1, error);
- /* SELinux might not be enabled */
- if (dbus_error_is_set (error) &&
- strcmp (error->name, "org.freedesktop.DBus.Error.SELinuxSecurityContextUnknown") == 0) {
- dbus_message_unref (message);
- if (reply != NULL)
- dbus_message_unref (reply);
- dbus_error_init (error);
- } else if (reply == NULL || dbus_error_is_set (error)) {
- g_warning ("Error doing GetConnectionSELinuxSecurityContext on Bus: %s: %s", error->name, error->message);
- dbus_message_unref (message);
- if (reply != NULL)
- dbus_message_unref (reply);
- goto out;
- } else {
- /* TODO: verify signature */
- dbus_message_iter_init (reply, &iter);
- dbus_message_iter_recurse (&iter, &sub_iter);
- dbus_message_iter_get_fixed_array (&sub_iter, (void *) &str, &num_elems);
- if (str != NULL && num_elems > 0)
- selinux_context = g_strndup (str, num_elems);
- dbus_message_unref (message);
- dbus_message_unref (reply);
- }
-
- message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit",
- "/org/freedesktop/ConsoleKit/Manager",
- "org.freedesktop.ConsoleKit.Manager",
- "GetSessionForUnixProcess");
- dbus_message_iter_init_append (message, &iter);
- dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT32, &pid);
- reply = dbus_connection_send_with_reply_and_block (con, message, -1, error);
- if (reply == NULL || dbus_error_is_set (error)) {
- g_warning ("Error doing GetSessionForUnixProcess on ConsoleKit: %s: %s", error->name, error->message);
- dbus_message_unref (message);
- if (reply != NULL)
- dbus_message_unref (reply);
- /* OK, this is not a catastrophe; just means the caller is not a
- * member of any session or that ConsoleKit is not available..
- */
- goto not_in_session;
- }
- dbus_message_iter_init (reply, &iter);
- dbus_message_iter_get_basic (&iter, &str);
- ck_session_objpath = g_strdup (str);
- dbus_message_unref (message);
- dbus_message_unref (reply);
-
- session = libpolkit_session_new_from_objpath (con, ck_session_objpath, uid, error);
- if (session == NULL) {
- g_warning ("Got a session objpath but couldn't construct session object!");
- }
-
-not_in_session:
- _pk_debug ("uid %d", uid);
- _pk_debug ("pid %d", pid);
- _pk_debug ("selinux context '%s'", selinux_context != NULL ? selinux_context : "(not set)");
- _pk_debug ("ck session '%s'", ck_session_objpath != NULL ? ck_session_objpath : "(not in a session)");
-
- caller = libpolkit_caller_new ();
- libpolkit_caller_set_dbus_name (caller, dbus_name);
- libpolkit_caller_set_uid (caller, uid);
- libpolkit_caller_set_pid (caller, pid);
- libpolkit_caller_set_selinux_context (caller, selinux_context);
- if (session != NULL) {
- libpolkit_caller_set_ck_session (caller, session);
- libpolkit_session_unref (session); /* we own this session object */
- }
-
-out:
- g_free (selinux_context);
- g_free (ck_session_objpath);
- return caller;
-}
-
-/**
* libpolkit_caller_debug:
* @caller: the object
*
@@ -451,3 +324,22 @@ libpolkit_caller_debug (PolKitCaller *ca
if (caller->session != NULL)
libpolkit_session_debug (caller->session);
}
+
+
+/**
+ * libpolkit_caller_validate:
+ * @caller: the object
+ *
+ * Validate the object
+ *
+ * Returns: #TRUE iff the object is valid.
+ **/
+polkit_bool_t
+libpolkit_caller_validate (PolKitCaller *caller)
+{
+ g_return_val_if_fail (caller != NULL, FALSE);
+ g_return_val_if_fail (caller->pid > 0, FALSE);
+ g_return_val_if_fail (caller->dbus_name != NULL, FALSE);
+ /* NOTE TODO FIXME: remove need to have a dbus name set */
+ return TRUE;
+}
diff --git a/libpolkit/libpolkit-caller.h b/libpolkit/libpolkit-caller.h
index 2c9d93e..bb91f6e 100644
--- a/libpolkit/libpolkit-caller.h
+++ b/libpolkit/libpolkit-caller.h
@@ -23,35 +23,35 @@
*
**************************************************************************/
+#if !defined (POLKIT_COMPILATION) && !defined(_POLKIT_INSIDE_POLKIT_H)
+#error "Only <libpolkit/libpolkit.h> can be included directly, this file may disappear or change contents."
+#endif
+
#ifndef LIBPOLKIT_CALLER_H
#define LIBPOLKIT_CALLER_H
-#include <stdbool.h>
-#include <sys/types.h>
-#include <dbus/dbus.h>
-
+#include <libpolkit/libpolkit-types.h>
#include <libpolkit/libpolkit-session.h>
+#include <sys/types.h>
struct PolKitCaller;
typedef struct PolKitCaller PolKitCaller;
PolKitCaller *libpolkit_caller_new (void);
-PolKitCaller *libpolkit_caller_new_from_dbus_name (DBusConnection *con, const char *dbus_name, DBusError *error);
PolKitCaller *libpolkit_caller_ref (PolKitCaller *caller);
void libpolkit_caller_unref (PolKitCaller *caller);
-void libpolkit_caller_set_dbus_name (PolKitCaller *caller, const char *dbus_name);
-void libpolkit_caller_set_uid (PolKitCaller *caller, uid_t uid);
-void libpolkit_caller_set_pid (PolKitCaller *caller, pid_t pid);
-void libpolkit_caller_set_selinux_context (PolKitCaller *caller, const char *selinux_context);
-void libpolkit_caller_set_ck_session (PolKitCaller *caller, PolKitSession *session);
-bool libpolkit_caller_get_dbus_name (PolKitCaller *caller, char **out_dbus_name);
-bool libpolkit_caller_get_uid (PolKitCaller *caller, uid_t *out_uid);
-bool libpolkit_caller_get_pid (PolKitCaller *caller, pid_t *out_pid);
-bool libpolkit_caller_get_selinux_context (PolKitCaller *caller, char **out_selinux_context);
-bool libpolkit_caller_get_ck_session (PolKitCaller *caller, PolKitSession **out_session);
+polkit_bool_t libpolkit_caller_set_dbus_name (PolKitCaller *caller, const char *dbus_name);
+polkit_bool_t libpolkit_caller_set_uid (PolKitCaller *caller, uid_t uid);
+polkit_bool_t libpolkit_caller_set_pid (PolKitCaller *caller, pid_t pid);
+polkit_bool_t libpolkit_caller_set_selinux_context (PolKitCaller *caller, const char *selinux_context);
+polkit_bool_t libpolkit_caller_set_ck_session (PolKitCaller *caller, PolKitSession *session);
+polkit_bool_t libpolkit_caller_get_dbus_name (PolKitCaller *caller, char **out_dbus_name);
+polkit_bool_t libpolkit_caller_get_uid (PolKitCaller *caller, uid_t *out_uid);
+polkit_bool_t libpolkit_caller_get_pid (PolKitCaller *caller, pid_t *out_pid);
+polkit_bool_t libpolkit_caller_get_selinux_context (PolKitCaller *caller, char **out_selinux_context);
+polkit_bool_t libpolkit_caller_get_ck_session (PolKitCaller *caller, PolKitSession **out_session);
void libpolkit_caller_debug (PolKitCaller *caller);
+polkit_bool_t libpolkit_caller_validate (PolKitCaller *caller);
#endif /* LIBPOLKIT_H */
-
-
diff --git a/libpolkit/libpolkit-context.c b/libpolkit/libpolkit-context.c
index 61a3599..49f70f4 100644
--- a/libpolkit/libpolkit-context.c
+++ b/libpolkit/libpolkit-context.c
@@ -94,7 +94,7 @@ libpolkit_context_new (void)
return pk_context;
}
-static bool
+static polkit_bool_t
unload_modules (PolKitContext *pk_context)
{
GSList *i;
@@ -109,11 +109,11 @@ unload_modules (PolKitContext *pk_contex
return TRUE;
}
-static bool
+static polkit_bool_t
load_modules (PolKitContext *pk_context, PolKitError **error)
{
const char *config_file;
- bool ret;
+ polkit_bool_t ret;
char *buf;
char *end;
char line[256];
@@ -272,7 +272,7 @@ _policy_dir_events (PolKitContext
*
* Returns: #FALSE if @error was set, otherwise #TRUE
**/
-bool
+polkit_bool_t
libpolkit_context_init (PolKitContext *pk_context, PolKitError **error)
{
const char *dirname;
@@ -508,7 +508,7 @@ libpolkit_context_is_resource_associated
*/
PolKitResult
libpolkit_context_can_session_access_resource (PolKitContext *pk_context,
- PolKitAction *action,
+ PolKitAction *action,
PolKitResource *resource,
PolKitSession *session)
{
@@ -520,13 +520,18 @@ libpolkit_context_can_session_access_res
current_result = LIBPOLKIT_RESULT_NO;
+ /* resource may actually by NULL */
+ if (action == NULL || session == NULL)
+ goto out;
+
cache = libpolkit_context_get_policy_cache (pk_context);
if (cache == NULL)
goto out;
_pk_debug ("entering libpolkit_can_session_access_resource()");
libpolkit_action_debug (action);
- libpolkit_resource_debug (resource);
+ if (resource != NULL)
+ libpolkit_resource_debug (resource);
libpolkit_session_debug (session);
pfe = libpolkit_policy_cache_get_entry (cache, action);
@@ -629,7 +634,7 @@ out:
*/
PolKitResult
libpolkit_context_can_caller_access_resource (PolKitContext *pk_context,
- PolKitAction *action,
+ PolKitAction *action,
PolKitResource *resource,
PolKitCaller *caller)
{
@@ -641,13 +646,18 @@ libpolkit_context_can_caller_access_reso
current_result = LIBPOLKIT_RESULT_NO;
+ /* resource may actually by NULL */
+ if (action == NULL || caller == NULL)
+ goto out;
+
cache = libpolkit_context_get_policy_cache (pk_context);
if (cache == NULL)
goto out;
_pk_debug ("entering libpolkit_can_caller_access_resource()");
libpolkit_action_debug (action);
- libpolkit_resource_debug (resource);
+ if (resource != NULL)
+ libpolkit_resource_debug (resource);
libpolkit_caller_debug (caller);
pfe = libpolkit_policy_cache_get_entry (cache, action);
diff --git a/libpolkit/libpolkit-context.h b/libpolkit/libpolkit-context.h
index b16e598..cf0f2c4 100644
--- a/libpolkit/libpolkit-context.h
+++ b/libpolkit/libpolkit-context.h
@@ -23,10 +23,14 @@
*
**************************************************************************/
+#if !defined (POLKIT_COMPILATION) && !defined(_POLKIT_INSIDE_POLKIT_H)
+#error "Only <libpolkit/libpolkit.h> can be included directly, this file may disappear or change contents."
+#endif
+
#ifndef LIBPOLKIT_CONTEXT_H
#define LIBPOLKIT_CONTEXT_H
-#include <stdbool.h>
+#include <libpolkit/libpolkit-types.h>
#include <libpolkit/libpolkit-error.h>
#include <libpolkit/libpolkit-result.h>
#include <libpolkit/libpolkit-context.h>
@@ -136,7 +140,7 @@ void libpolkit_context_set_con
void libpolkit_context_set_file_monitor (PolKitContext *pk_context,
PolKitContextFileMonitorAddWatch add_watch_func,
PolKitContextFileMonitorRemoveWatch remove_watch_func);
-bool libpolkit_context_init (PolKitContext *pk_context,
+polkit_bool_t libpolkit_context_init (PolKitContext *pk_context,
PolKitError **error);
PolKitContext *libpolkit_context_ref (PolKitContext *pk_context);
void libpolkit_context_unref (PolKitContext *pk_context);
diff --git a/libpolkit/libpolkit-debug.c b/libpolkit/libpolkit-debug.c
index 37a8fb2..d81b7e7 100644
--- a/libpolkit/libpolkit-debug.c
+++ b/libpolkit/libpolkit-debug.c
@@ -25,7 +25,7 @@
/**
* SECTION:libpolkit-debug
- * @short_description: Debug functions.
+ * @short_description: Internal debug functions for libpolkit.
*
* These functions are used for debug purposes
**/
@@ -34,13 +34,13 @@
# include <config.h>
#endif
-#include <stdbool.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <sys/time.h>
#include <time.h>
+#include "libpolkit-types.h"
#include "libpolkit-debug.h"
/**
@@ -53,13 +53,13 @@ void
_pk_debug (const char *format, ...)
{
va_list args;
- static bool show_debug = false;
- static bool init = false;
+ static polkit_bool_t show_debug = FALSE;
+ static polkit_bool_t init = FALSE;
if (!init) {
- init = true;
+ init = TRUE;
if (getenv ("POLKIT_DEBUG") != NULL) {
- show_debug = true;
+ show_debug = TRUE;
}
}
diff --git a/libpolkit/libpolkit-error.c b/libpolkit/libpolkit-error.c
index 1ca8c4e..e6cf33b 100644
--- a/libpolkit/libpolkit-error.c
+++ b/libpolkit/libpolkit-error.c
@@ -34,7 +34,6 @@
# include <config.h>
#endif
-#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -46,6 +45,7 @@
#include <glib.h>
+#include "libpolkit-types.h"
#include "libpolkit-error.h"
/**
@@ -55,7 +55,7 @@
**/
struct PolKitError
{
- bool is_static;
+ polkit_bool_t is_static;
PolKitErrorCode error_code;
char *error_message;
};
@@ -127,7 +127,7 @@ polkit_error_set_error (PolKitError **er
return;
e = g_new0 (PolKitError, 1);
- e->is_static = false;
+ e->is_static = FALSE;
e->error_code = error_code;
va_start (args, format);
e->error_message = g_strdup_vprintf (format, args);
diff --git a/libpolkit/libpolkit-error.h b/libpolkit/libpolkit-error.h
index eaaf827..d5d5e8e 100644
--- a/libpolkit/libpolkit-error.h
+++ b/libpolkit/libpolkit-error.h
@@ -23,6 +23,10 @@
*
**************************************************************************/
+#if !defined (POLKIT_COMPILATION) && !defined(_POLKIT_INSIDE_POLKIT_H)
+#error "Only <libpolkit/libpolkit.h> can be included directly, this file may disappear or change contents."
+#endif
+
#ifndef LIBPOLKIT_ERROR_H
#define LIBPOLKIT_ERROR_H
diff --git a/libpolkit/libpolkit-module.c b/libpolkit/libpolkit-module.c
index 505a0b7..7e1440f 100644
--- a/libpolkit/libpolkit-module.c
+++ b/libpolkit/libpolkit-module.c
@@ -64,7 +64,7 @@ struct PolKitModuleInterface
PolKitModuleCanSessionAccessResource func_can_session_access_resource;
PolKitModuleCanCallerAccessResource func_can_caller_access_resource;
- bool builtin_have_action_regex;
+ polkit_bool_t builtin_have_action_regex;
regex_t builtin_action_regex_compiled;
GSList *builtin_users;
@@ -109,13 +109,13 @@ _parse_builtin_remove_option (int *argc,
(*argc)--;
}
-static bool
+static polkit_bool_t
_parse_builtin (PolKitModuleInterface *mi, int *argc, char *argv[])
{
int n;
- bool ret;
+ polkit_bool_t ret;
- ret = false;
+ ret = FALSE;
for (n = 1; n < *argc; ) {
if (g_str_has_prefix (argv[n], "action=")) {
@@ -131,7 +131,7 @@ _parse_builtin (PolKitModuleInterface *m
_pk_debug ("Regex '%s' didn't compile", regex);
goto error;
}
- mi->builtin_have_action_regex = true;
+ mi->builtin_have_action_regex = TRUE;
_pk_debug ("Compiled regex '%s' for option 'action=' OK", regex);
@@ -165,7 +165,7 @@ _parse_builtin (PolKitModuleInterface *m
}
}
- ret = true;
+ ret = TRUE;
error:
return ret;
@@ -187,7 +187,7 @@ libpolkit_module_interface_load_module (
{
void *handle;
PolKitModuleInterface *mi;
- bool (*func) (PolKitModuleInterface *);
+ polkit_bool_t (*func) (PolKitModuleInterface *);
mi = NULL;
@@ -556,12 +556,12 @@ libpolkit_module_control_to_string_repre
*
* Returns: TRUE if the textual representation was valid, otherwise FALSE
**/
-bool
+polkit_bool_t
libpolkit_module_control_from_string_representation (const char *string, PolKitModuleControl *out_module_control)
{
int n;
- g_return_val_if_fail (out_module_control != NULL, false);
+ g_return_val_if_fail (out_module_control != NULL, FALSE);
for (n = 0; n < LIBPOLKIT_MODULE_CONTROL_N_CONTROLS; n++) {
if (mapping[n].str == NULL)
@@ -572,9 +572,9 @@ libpolkit_module_control_from_string_rep
}
}
- return false;
+ return FALSE;
found:
- return true;
+ return TRUE;
}
@@ -609,23 +609,23 @@ libpolkit_module_get_user_data (PolKit
return module_interface->module_user_data;
}
-static bool
+static polkit_bool_t
_check_action (PolKitModuleInterface *module_interface, PolKitAction *action)
{
- bool ret;
+ polkit_bool_t ret;
- ret = false;
+ ret = FALSE;
if (module_interface->builtin_have_action_regex) {
char *action_name;
if (libpolkit_action_get_action_id (action, &action_name)) {
if (regexec (&module_interface->builtin_action_regex_compiled,
action_name, 0, NULL, 0) == 0) {
- ret = true;
+ ret = TRUE;
}
}
} else {
- ret = true;
+ ret = TRUE;
}
return ret;
@@ -633,7 +633,7 @@ _check_action (PolKitModuleInterface *mo
/*----*/
-static bool
+static polkit_bool_t
_check_uid_in_list (GSList *list, uid_t given_uid)
{
GSList *i;
@@ -641,36 +641,36 @@ _check_uid_in_list (GSList *list, uid_t
for (i = list; i != NULL; i = g_slist_next (i)) {
uid_t uid = GPOINTER_TO_INT (i->data);
if (given_uid == uid)
- return true;
+ return TRUE;
}
- return false;
+ return FALSE;
}
-static bool
+static polkit_bool_t
_check_users_for_session (PolKitModuleInterface *module_interface, PolKitSession *session)
{
uid_t uid;
GSList *list;
if ((list = module_interface->builtin_users) == NULL)
- return true;
+ return TRUE;
if (session == NULL)
- return false;
+ return FALSE;
if (!libpolkit_session_get_uid (session, &uid))
- return false;
+ return FALSE;
return _check_uid_in_list (list, uid);
}
-static bool
+static polkit_bool_t
_check_users_for_caller (PolKitModuleInterface *module_interface, PolKitCaller *caller)
{
uid_t uid;
GSList *list;
if ((list = module_interface->builtin_users) == NULL)
- return true;
+ return TRUE;
if (caller == NULL)
- return false;
+ return FALSE;
if (!libpolkit_caller_get_uid (caller, &uid))
- return false;
+ return FALSE;
return _check_uid_in_list (list, uid);
}
@@ -688,15 +688,15 @@ _check_users_for_caller (PolKitModuleInt
*
* Returns: TRUE if, and only if, the module is confined from handling the request
**/
-bool
+polkit_bool_t
libpolkit_module_interface_check_builtin_confinement_for_session (PolKitModuleInterface *module_interface,
PolKitContext *pk_context,
PolKitAction *action,
PolKitResource *resource,
PolKitSession *session)
{
- bool ret;
- ret = true;
+ polkit_bool_t ret;
+ ret = TRUE;
g_return_val_if_fail (module_interface != NULL, ret);
@@ -706,7 +706,7 @@ libpolkit_module_interface_check_builtin
goto out;
/* not confined */
- ret = false;
+ ret = FALSE;
out:
return ret;
}
@@ -724,15 +724,15 @@ out:
*
* Returns: TRUE if, and only if, the module is confined from handling the request
**/
-bool
+polkit_bool_t
libpolkit_module_interface_check_builtin_confinement_for_caller (PolKitModuleInterface *module_interface,
PolKitContext *pk_context,
PolKitAction *action,
PolKitResource *resource,
PolKitCaller *caller)
{
- bool ret;
- ret = true;
+ polkit_bool_t ret;
+ ret = TRUE;
g_return_val_if_fail (module_interface != NULL, ret);
@@ -742,7 +742,7 @@ libpolkit_module_interface_check_builtin
goto out;
/* not confined */
- ret = false;
+ ret = FALSE;
out:
return ret;
}
diff --git a/libpolkit/libpolkit-module.h b/libpolkit/libpolkit-module.h
index 7088491..bb4bbc9 100644
--- a/libpolkit/libpolkit-module.h
+++ b/libpolkit/libpolkit-module.h
@@ -23,10 +23,14 @@
*
**************************************************************************/
+#if !defined (POLKIT_COMPILATION) && !defined(_POLKIT_INSIDE_POLKIT_H)
+#error "Only <libpolkit/libpolkit.h> can be included directly, this file may disappear or change contents."
+#endif
+
#ifndef LIBPOLKIT_MODULE_H
#define LIBPOLKIT_MODULE_H
-#include <stdbool.h>
+#include <libpolkit/libpolkit-types.h>
#include <libpolkit/libpolkit.h>
struct PolKitModuleInterface;
@@ -42,9 +46,9 @@ typedef struct PolKitModuleInterface Pol
*
* Returns: Whether the module was initialized.
**/
-typedef bool (*PolKitModuleInitialize) (PolKitModuleInterface *module_interface,
- int argc,
- char *argv[]);
+typedef polkit_bool_t (*PolKitModuleInitialize) (PolKitModuleInterface *module_interface,
+ int argc,
+ char *argv[]);
/**
* PolKitModuleShutdown:
@@ -176,7 +180,7 @@ typedef enum
const char *
libpolkit_module_control_to_string_representation (PolKitModuleControl module_control);
-bool
+polkit_bool_t
libpolkit_module_control_from_string_representation (const char *string, PolKitModuleControl *out_module_control);
PolKitModuleInterface *libpolkit_module_interface_load_module (const char *name,
@@ -186,14 +190,14 @@ PolKitModuleInterface *libpolkit_module_
PolKitModuleControl libpolkit_module_interface_get_control (PolKitModuleInterface *module_interface);
-bool
+polkit_bool_t
libpolkit_module_interface_check_builtin_confinement_for_session (PolKitModuleInterface *module_interface,
PolKitContext *pk_context,
PolKitAction *action,
PolKitResource *resource,
PolKitSession *session);
-bool
+polkit_bool_t
libpolkit_module_interface_check_builtin_confinement_for_caller (PolKitModuleInterface *module_interface,
PolKitContext *pk_context,
PolKitAction *action,
diff --git a/libpolkit/libpolkit-policy-cache.h b/libpolkit/libpolkit-policy-cache.h
index 92378a7..12cf00e 100644
--- a/libpolkit/libpolkit-policy-cache.h
+++ b/libpolkit/libpolkit-policy-cache.h
@@ -23,6 +23,10 @@
*
**************************************************************************/
+#if !defined (POLKIT_COMPILATION) && !defined(_POLKIT_INSIDE_POLKIT_H)
+#error "Only <libpolkit/libpolkit.h> can be included directly, this file may disappear or change contents."
+#endif
+
#ifndef LIBPOLKIT_POLICY_CACHE_H
#define LIBPOLKIT_POLICY_CACHE_H
diff --git a/libpolkit/libpolkit-policy-default.c b/libpolkit/libpolkit-policy-default.c
index 852c3aa..1cba253 100644
--- a/libpolkit/libpolkit-policy-default.c
+++ b/libpolkit/libpolkit-policy-default.c
@@ -228,19 +228,18 @@ libpolkit_policy_default_debug (PolKitPo
**/
PolKitResult
libpolkit_policy_default_can_session_access_resource (PolKitPolicyDefault *policy_default,
- PolKitAction *action,
- PolKitResource *resource,
- PolKitSession *session)
+ PolKitAction *action,
+ PolKitResource *resource,
+ PolKitSession *session)
{
- bool is_local;
- bool is_active;
+ polkit_bool_t is_local;
+ polkit_bool_t is_active;
PolKitResult ret;
ret = LIBPOLKIT_RESULT_NO;
g_return_val_if_fail (policy_default != NULL, ret);
g_return_val_if_fail (action != NULL, ret);
- g_return_val_if_fail (resource != NULL, ret);
g_return_val_if_fail (session != NULL, ret);
if (!libpolkit_session_get_ck_is_local (session, &is_local))
@@ -280,12 +279,12 @@ out:
**/
PolKitResult
libpolkit_policy_default_can_caller_access_resource (PolKitPolicyDefault *policy_default,
- PolKitAction *action,
- PolKitResource *resource,
- PolKitCaller *caller)
+ PolKitAction *action,
+ PolKitResource *resource,
+ PolKitCaller *caller)
{
- bool is_local;
- bool is_active;
+ polkit_bool_t is_local;
+ polkit_bool_t is_active;
PolKitSession *session;
PolKitResult ret;
@@ -293,7 +292,6 @@ libpolkit_policy_default_can_caller_acce
g_return_val_if_fail (policy_default != NULL, ret);
g_return_val_if_fail (action != NULL, ret);
- g_return_val_if_fail (resource != NULL, ret);
g_return_val_if_fail (caller != NULL, ret);
if (!libpolkit_caller_get_ck_session (caller, &session))
diff --git a/libpolkit/libpolkit-policy-default.h b/libpolkit/libpolkit-policy-default.h
index 9daaee1..19cce21 100644
--- a/libpolkit/libpolkit-policy-default.h
+++ b/libpolkit/libpolkit-policy-default.h
@@ -23,6 +23,10 @@
*
**************************************************************************/
+#if !defined (POLKIT_COMPILATION) && !defined(_POLKIT_INSIDE_POLKIT_H)
+#error "Only <libpolkit/libpolkit.h> can be included directly, this file may disappear or change contents."
+#endif
+
#ifndef LIBPOLKIT_POLICY_DEFAULT_H
#define LIBPOLKIT_POLICY_DEFAULT_H
@@ -41,13 +45,13 @@ void libpolkit_policy
void libpolkit_policy_default_debug (PolKitPolicyDefault *policy_default);
PolKitResult libpolkit_policy_default_can_session_access_resource (PolKitPolicyDefault *policy_default,
- PolKitAction *action,
- PolKitResource *resource,
- PolKitSession *session);
+ PolKitAction *action,
+ PolKitResource *resource,
+ PolKitSession *session);
PolKitResult libpolkit_policy_default_can_caller_access_resource (PolKitPolicyDefault *policy_default,
- PolKitAction *action,
- PolKitResource *resource,
- PolKitCaller *caller);
+ PolKitAction *action,
+ PolKitResource *resource,
+ PolKitCaller *caller);
/* TODO: export knobs for "default policy" */
diff --git a/libpolkit/libpolkit-policy-file-entry.h b/libpolkit/libpolkit-policy-file-entry.h
index 1d76f83..f9aeb01 100644
--- a/libpolkit/libpolkit-policy-file-entry.h
+++ b/libpolkit/libpolkit-policy-file-entry.h
@@ -23,6 +23,10 @@
*
**************************************************************************/
+#if !defined (POLKIT_COMPILATION) && !defined(_POLKIT_INSIDE_POLKIT_H)
+#error "Only <libpolkit/libpolkit.h> can be included directly, this file may disappear or change contents."
+#endif
+
#ifndef LIBPOLKIT_POLICY_FILE_ENTRY_H
#define LIBPOLKIT_POLICY_FILE_ENTRY_H
diff --git a/libpolkit/libpolkit-policy-file.h b/libpolkit/libpolkit-policy-file.h
index b09f508..cdd9096 100644
--- a/libpolkit/libpolkit-policy-file.h
+++ b/libpolkit/libpolkit-policy-file.h
@@ -23,6 +23,10 @@
*
**************************************************************************/
+#if !defined (POLKIT_COMPILATION) && !defined(_POLKIT_INSIDE_POLKIT_H)
+#error "Only <libpolkit/libpolkit.h> can be included directly, this file may disappear or change contents."
+#endif
+
#ifndef LIBPOLKIT_POLICY_FILE_H
#define LIBPOLKIT_POLICY_FILE_H
diff --git a/libpolkit/libpolkit-resource.c b/libpolkit/libpolkit-resource.c
index f401eb1..dd68b72 100644
--- a/libpolkit/libpolkit-resource.c
+++ b/libpolkit/libpolkit-resource.c
@@ -39,6 +39,7 @@
#include <glib.h>
#include "libpolkit-debug.h"
#include "libpolkit-resource.h"
+#include "libpolkit-utils.h"
/**
* SECTION:libpolkit-resource
@@ -122,15 +123,18 @@ libpolkit_resource_unref (PolKitResource
* @resource_type: type of resource
*
* Set the type of the resource. TODO: link to wtf this is.
+ *
+ * Returns: #TRUE only if the value validated and was set
**/
-void
+polkit_bool_t
libpolkit_resource_set_resource_type (PolKitResource *resource, const char *resource_type)
{
- g_return_if_fail (resource != NULL);
-
+ g_return_val_if_fail (resource != NULL, FALSE);
+ g_return_val_if_fail (_pk_validate_identifier (resource_type), FALSE);
if (resource->type != NULL)
g_free (resource->type);
resource->type = g_strdup (resource_type);
+ return TRUE;
}
/**
@@ -139,15 +143,18 @@ libpolkit_resource_set_resource_type (Po
* @resource_id: identifier of resource
*
* set the identifier of the resource. TODO: link to wtf this is.
+ *
+ * Returns: #TRUE only if the value validated and was set
**/
-void
+polkit_bool_t
libpolkit_resource_set_resource_id (PolKitResource *resource, const char *resource_id)
{
- g_return_if_fail (resource != NULL);
-
+ g_return_val_if_fail (resource != NULL, FALSE);
+ g_return_val_if_fail (_pk_validate_identifier (resource_id), FALSE);
if (resource->id != NULL)
g_free (resource->id);
resource->id = g_strdup (resource_id);
+ return TRUE;
}
/**
@@ -159,7 +166,7 @@ libpolkit_resource_set_resource_id (PolK
*
* Returns: TRUE iff the value was returned.
**/
-bool
+polkit_bool_t
libpolkit_resource_get_resource_type (PolKitResource *resource, char **out_resource_type)
{
g_return_val_if_fail (resource != NULL, FALSE);
@@ -181,7 +188,7 @@ libpolkit_resource_get_resource_type (Po
*
* Returns: TRUE iff the value was returned.
**/
-bool
+polkit_bool_t
libpolkit_resource_get_resource_id (PolKitResource *resource, char **out_resource_id)
{
g_return_val_if_fail (resource != NULL, FALSE);
@@ -206,3 +213,20 @@ libpolkit_resource_debug (PolKitResource
g_return_if_fail (resource != NULL);
_pk_debug ("PolKitResource: refcount=%d type=%s id=%s", resource->refcount, resource->type, resource->id);
}
+
+/**
+ * libpolkit_resource_validate:
+ * @resource: the object
+ *
+ * Validate the object
+ *
+ * Returns: #TRUE iff the object is valid.
+ **/
+polkit_bool_t
+libpolkit_resource_validate (PolKitResource *resource)
+{
+ g_return_val_if_fail (resource != NULL, FALSE);
+ g_return_val_if_fail (resource->type != NULL, FALSE);
+ g_return_val_if_fail (resource->id != NULL, FALSE);
+ return TRUE;
+}
diff --git a/libpolkit/libpolkit-resource.h b/libpolkit/libpolkit-resource.h
index e050b86..427b6e7 100644
--- a/libpolkit/libpolkit-resource.h
+++ b/libpolkit/libpolkit-resource.h
@@ -23,10 +23,14 @@
*
**************************************************************************/
+#if !defined (POLKIT_COMPILATION) && !defined(_POLKIT_INSIDE_POLKIT_H)
+#error "Only <libpolkit/libpolkit.h> can be included directly, this file may disappear or change contents."
+#endif
+
#ifndef LIBPOLKIT_RESOURCE_H
#define LIBPOLKIT_RESOURCE_H
-#include <stdbool.h>
+#include <libpolkit/libpolkit-types.h>
struct PolKitResource;
typedef struct PolKitResource PolKitResource;
@@ -34,13 +38,15 @@ typedef struct PolKitResource PolKitReso
PolKitResource *libpolkit_resource_new (void);
PolKitResource *libpolkit_resource_ref (PolKitResource *resource);
void libpolkit_resource_unref (PolKitResource *resource);
-void libpolkit_resource_set_resource_type (PolKitResource *resource, const char *resource_type);
-void libpolkit_resource_set_resource_id (PolKitResource *resource, const char *resource_id);
-bool libpolkit_resource_get_resource_type (PolKitResource *resource, char **out_resource_type);
-bool libpolkit_resource_get_resource_id (PolKitResource *resource, char **out_resource_id);
+polkit_bool_t libpolkit_resource_set_resource_type (PolKitResource *resource, const char *resource_type);
+polkit_bool_t libpolkit_resource_set_resource_id (PolKitResource *resource, const char *resource_id);
+polkit_bool_t libpolkit_resource_get_resource_type (PolKitResource *resource, char **out_resource_type);
+polkit_bool_t libpolkit_resource_get_resource_id (PolKitResource *resource, char **out_resource_id);
void libpolkit_resource_debug (PolKitResource *resource);
+polkit_bool_t libpolkit_resource_validate (PolKitResource *resource);
+
#endif /* LIBPOLKIT_RESOURCE_H */
diff --git a/libpolkit/libpolkit-result.c b/libpolkit/libpolkit-result.c
index 393c96d..05d787e 100644
--- a/libpolkit/libpolkit-result.c
+++ b/libpolkit/libpolkit-result.c
@@ -94,7 +94,7 @@ libpolkit_result_to_string_representatio
*
* Returns: TRUE if the textual representation was valid, otherwise FALSE
**/
-bool
+polkit_bool_t
libpolkit_result_from_string_representation (const char *string, PolKitResult *out_result)
{
int n;
@@ -110,7 +110,7 @@ libpolkit_result_from_string_representat
}
}
- return false;
+ return FALSE;
found:
- return true;
+ return TRUE;
}
diff --git a/libpolkit/libpolkit-result.h b/libpolkit/libpolkit-result.h
index bb76b9b..74da794 100644
--- a/libpolkit/libpolkit-result.h
+++ b/libpolkit/libpolkit-result.h
@@ -23,10 +23,14 @@
*
**************************************************************************/
+#if !defined (POLKIT_COMPILATION) && !defined(_POLKIT_INSIDE_POLKIT_H)
+#error "Only <libpolkit/libpolkit.h> can be included directly, this file may disappear or change contents."
+#endif
+
#ifndef LIBPOLKIT_RESULT_H
#define LIBPOLKIT_RESULT_H
-#include <stdbool.h>
+#include <libpolkit/libpolkit-types.h>
/**
* PolKitResult:
@@ -34,17 +38,17 @@
* @LIBPOLKIT_RESULT_NOT_AUTHORIZED_TO_KNOW: The caller of libpolkit is not sufficiently privilege to know the answer.
* @LIBPOLKIT_RESULT_NO: Access denied.
* @LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH: Access denied, but authentication of the caller as
- * root will grant access to only that caller.
+ * root will grant access to the resource... but the access isn't permanent
* @LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH_KEEP_SESSION: Access denied, but authentication of the caller as
- * root will grant access for the remainder of the session the caller stems from.
+ * root will grant access to the resource for the remainder of the session
* @LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH_KEEP_ALWAYS: Access denied, but authentication of the caller as
- * root will grant access to the user of the caller in the future.
+ * root will grant access to the resource in the future.
* @LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH: Access denied, but authentication of the caller as
- * his user will grant access to only that caller.
+ * himself will grant access to the resource... but the access isn't permanent
* @LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_SESSION: Access denied, but authentication of the caller as
- * his user will grant access for the remainder of the session the caller stems from.
+ * himself will grant access to the resource for the remainder of the session
* @LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_ALWAYS: Access denied, but authentication of the caller as
- * his user will grant access to the user of the caller in the future.
+ * himself will grant access to the resource in the future.
* @LIBPOLKIT_RESULT_YES: Access granted.
* @LIBPOLKIT_RESULT_N_RESULTS: Number of result codes
*
@@ -58,12 +62,15 @@ typedef enum
LIBPOLKIT_RESULT_UNKNOWN_ACTION,
LIBPOLKIT_RESULT_NOT_AUTHORIZED_TO_KNOW,
LIBPOLKIT_RESULT_NO,
+
LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH,
LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH_KEEP_SESSION,
LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH_KEEP_ALWAYS,
+
LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH,
LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_SESSION,
LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_ALWAYS,
+
LIBPOLKIT_RESULT_YES,
LIBPOLKIT_RESULT_N_RESULTS
} PolKitResult;
@@ -71,7 +78,7 @@ typedef enum
const char *
libpolkit_result_to_string_representation (PolKitResult result);
-bool
+polkit_bool_t
libpolkit_result_from_string_representation (const char *string, PolKitResult *out_result);
#endif /* LIBPOLKIT_RESULT_H */
diff --git a/libpolkit/libpolkit-seat.c b/libpolkit/libpolkit-seat.c
index 0af95dc..8a51991 100644
--- a/libpolkit/libpolkit-seat.c
+++ b/libpolkit/libpolkit-seat.c
@@ -39,6 +39,7 @@
#include <glib.h>
#include "libpolkit-debug.h"
#include "libpolkit-seat.h"
+#include "libpolkit-utils.h"
/**
* SECTION:libpolkit-seat
@@ -116,14 +117,18 @@ libpolkit_seat_unref (PolKitSeat *seat)
* @ck_objref: the D-Bus object path to the ConsoleKit seat object
*
* Set the D-Bus object path to the ConsoleKit seat object.
+ *
+ * Returns: #TRUE only if the value validated and was set
**/
-void
+polkit_bool_t
libpolkit_seat_set_ck_objref (PolKitSeat *seat, const char *ck_objref)
{
- g_return_if_fail (seat != NULL);
+ g_return_val_if_fail (seat != NULL, FALSE);
+ g_return_val_if_fail (_pk_validate_identifier (ck_objref), FALSE);
if (seat->ck_objref != NULL)
g_free (seat->ck_objref);
seat->ck_objref = g_strdup (ck_objref);
+ return TRUE;
}
/**
@@ -135,13 +140,13 @@ libpolkit_seat_set_ck_objref (PolKitSeat
*
* Returns: TRUE iff the value is returned
**/
-bool
+polkit_bool_t
libpolkit_seat_get_ck_objref (PolKitSeat *seat, char **out_ck_objref)
{
- g_return_val_if_fail (seat != NULL, false);
- g_return_val_if_fail (out_ck_objref != NULL, false);
+ g_return_val_if_fail (seat != NULL, FALSE);
+ g_return_val_if_fail (out_ck_objref != NULL, FALSE);
*out_ck_objref = seat->ck_objref;
- return true;
+ return TRUE;
}
/**
@@ -156,3 +161,19 @@ libpolkit_seat_debug (PolKitSeat *seat)
g_return_if_fail (seat != NULL);
_pk_debug ("PolKitSeat: refcount=%d objpath=%s", seat->refcount, seat->ck_objref);
}
+
+/**
+ * libpolkit_seat_validate:
+ * @seat: the object
+ *
+ * Validate the object
+ *
+ * Returns: #TRUE iff the object is valid.
+ **/
+polkit_bool_t
+libpolkit_seat_validate (PolKitSeat *seat)
+{
+ g_return_val_if_fail (seat != NULL, FALSE);
+ g_return_val_if_fail (seat->ck_objref != NULL, FALSE);
+ return TRUE;
+}
diff --git a/libpolkit/libpolkit-seat.h b/libpolkit/libpolkit-seat.h
index 046f9f6..7de9fe9 100644
--- a/libpolkit/libpolkit-seat.h
+++ b/libpolkit/libpolkit-seat.h
@@ -23,21 +23,26 @@
*
**************************************************************************/
+#if !defined (POLKIT_COMPILATION) && !defined(_POLKIT_INSIDE_POLKIT_H)
+#error "Only <libpolkit/libpolkit.h> can be included directly, this file may disappear or change contents."
+#endif
+
#ifndef LIBPOLKIT_SEAT_H
#define LIBPOLKIT_SEAT_H
-#include <stdbool.h>
+#include <libpolkit/libpolkit-types.h>
struct PolKitSeat;
typedef struct PolKitSeat PolKitSeat;
-PolKitSeat *libpolkit_seat_new (void);
-PolKitSeat *libpolkit_seat_ref (PolKitSeat *seat);
-void libpolkit_seat_unref (PolKitSeat *seat);
-void libpolkit_seat_set_ck_objref (PolKitSeat *seat, const char *ck_objref);
-bool libpolkit_seat_get_ck_objref (PolKitSeat *seat, char **out_ck_objref);
+PolKitSeat *libpolkit_seat_new (void);
+PolKitSeat *libpolkit_seat_ref (PolKitSeat *seat);
+void libpolkit_seat_unref (PolKitSeat *seat);
+polkit_bool_t libpolkit_seat_set_ck_objref (PolKitSeat *seat, const char *ck_objref);
+polkit_bool_t libpolkit_seat_get_ck_objref (PolKitSeat *seat, char **out_ck_objref);
-void libpolkit_seat_debug (PolKitSeat *seat);
+void libpolkit_seat_debug (PolKitSeat *seat);
+polkit_bool_t libpolkit_seat_validate (PolKitSeat *seat);
#endif /* LIBPOLKIT_SEAT_H */
diff --git a/libpolkit/libpolkit-session.c b/libpolkit/libpolkit-session.c
index a5d0a9f..c93019c 100644
--- a/libpolkit/libpolkit-session.c
+++ b/libpolkit/libpolkit-session.c
@@ -39,7 +39,7 @@
#include <glib.h>
#include "libpolkit-debug.h"
#include "libpolkit-session.h"
-
+#include "libpolkit-utils.h"
/**
* SECTION:libpolkit-session
@@ -60,8 +60,8 @@ struct PolKitSession
uid_t uid;
PolKitSeat *seat;
char *ck_objref;
- bool is_active;
- bool is_local;
+ polkit_bool_t is_active;
+ polkit_bool_t is_local;
char *remote_host;
};
@@ -126,12 +126,15 @@ libpolkit_session_unref (PolKitSession *
* @uid: UNIX user id
*
* Set the UNIX user id of the user owning the session.
+ *
+ * Returns: #TRUE only if the value validated and was set
**/
-void
+polkit_bool_t
libpolkit_session_set_uid (PolKitSession *session, uid_t uid)
{
- g_return_if_fail (session != NULL);
+ g_return_val_if_fail (session != NULL, FALSE);
session->uid = uid;
+ return TRUE;
}
/**
@@ -140,14 +143,18 @@ libpolkit_session_set_uid (PolKitSession
* @ck_objref: D-Bus object path
*
* Set the D-Bus object path to the ConsoleKit session object.
+ *
+ * Returns: #TRUE only if the value validated and was set
**/
-void
+polkit_bool_t
libpolkit_session_set_ck_objref (PolKitSession *session, const char *ck_objref)
{
- g_return_if_fail (session != NULL);
+ g_return_val_if_fail (session != NULL, FALSE);
+ g_return_val_if_fail (_pk_validate_identifier (ck_objref), FALSE);
if (session->ck_objref != NULL)
g_free (session->ck_objref);
session->ck_objref = g_strdup (ck_objref);
+ return TRUE;
}
/**
@@ -156,12 +163,15 @@ libpolkit_session_set_ck_objref (PolKitS
* @is_active: whether ConsoleKit reports the session as active
*
* Set whether ConsoleKit regard the session as active.
+ *
+ * Returns: #TRUE only if the value validated and was set
**/
-void
-libpolkit_session_set_ck_is_active (PolKitSession *session, bool is_active)
+polkit_bool_t
+libpolkit_session_set_ck_is_active (PolKitSession *session, polkit_bool_t is_active)
{
- g_return_if_fail (session != NULL);
+ g_return_val_if_fail (session != NULL, FALSE);
session->is_active = is_active;
+ return TRUE;
}
/**
@@ -170,12 +180,15 @@ libpolkit_session_set_ck_is_active (PolK
* @is_local: whether ConsoleKit reports the session as local
*
* Set whether ConsoleKit regard the session as local.
+ *
+ * Returns: #TRUE only if the value validated and was set
**/
-void
-libpolkit_session_set_ck_is_local (PolKitSession *session, bool is_local)
+polkit_bool_t
+libpolkit_session_set_ck_is_local (PolKitSession *session, polkit_bool_t is_local)
{
- g_return_if_fail (session != NULL);
+ g_return_val_if_fail (session != NULL, FALSE);
session->is_local = is_local;
+ return TRUE;
}
/**
@@ -186,14 +199,19 @@ libpolkit_session_set_ck_is_local (PolKi
*
* Set the remote host/display that ConsoleKit reports the session to
* occur at.
+ *
+ * Returns: #TRUE only if the value validated and was set
**/
-void
+polkit_bool_t
libpolkit_session_set_ck_remote_host (PolKitSession *session, const char *remote_host)
{
- g_return_if_fail (session != NULL);
+ g_return_val_if_fail (session != NULL, FALSE);
+ /* TODO: FIXME: probably need to allow a lot more here */
+ g_return_val_if_fail (_pk_validate_identifier (remote_host), FALSE);
if (session->remote_host != NULL)
g_free (session->remote_host);
session->remote_host = g_strdup (remote_host);
+ return TRUE;
}
/**
@@ -205,14 +223,18 @@ libpolkit_session_set_ck_remote_host (Po
* the given object will be increased by one. If an existing seat
* object was set already, the reference count on that one will be
* decreased by one.
+ *
+ * Returns: #TRUE only if the value validated and was set
**/
-void
+polkit_bool_t
libpolkit_session_set_seat (PolKitSession *session, PolKitSeat *seat)
{
- g_return_if_fail (session != NULL);
+ g_return_val_if_fail (session != NULL, FALSE);
+ g_return_val_if_fail (libpolkit_seat_validate (seat), FALSE);
if (session->seat != NULL)
libpolkit_seat_unref (session->seat);
session->seat = seat != NULL ? libpolkit_seat_ref (seat) : NULL;
+ return TRUE;
}
/**
@@ -224,7 +246,7 @@ libpolkit_session_set_seat (PolKitSessio
*
* Returns: TRUE iff the value is returned
**/
-bool
+polkit_bool_t
libpolkit_session_get_uid (PolKitSession *session, uid_t *out_uid)
{
g_return_val_if_fail (session != NULL, FALSE);
@@ -242,7 +264,7 @@ libpolkit_session_get_uid (PolKitSession
*
* Returns: TRUE iff the value is returned
**/
-bool
+polkit_bool_t
libpolkit_session_get_ck_objref (PolKitSession *session, char **out_ck_objref)
{
g_return_val_if_fail (session != NULL, FALSE);
@@ -260,8 +282,8 @@ libpolkit_session_get_ck_objref (PolKitS
*
* Returns: TRUE iff the value is returned
**/
-bool
-libpolkit_session_get_ck_is_active (PolKitSession *session, bool *out_is_active)
+polkit_bool_t
+libpolkit_session_get_ck_is_active (PolKitSession *session, polkit_bool_t *out_is_active)
{
g_return_val_if_fail (session != NULL, FALSE);
g_return_val_if_fail (out_is_active != NULL, FALSE);
@@ -278,8 +300,8 @@ libpolkit_session_get_ck_is_active (PolK
*
* Returns: TRUE iff the value is returned
**/
-bool
-libpolkit_session_get_ck_is_local (PolKitSession *session, bool *out_is_local)
+polkit_bool_t
+libpolkit_session_get_ck_is_local (PolKitSession *session, polkit_bool_t *out_is_local)
{
g_return_val_if_fail (session != NULL, FALSE);
g_return_val_if_fail (out_is_local != NULL, FALSE);
@@ -298,7 +320,7 @@ libpolkit_session_get_ck_is_local (PolKi
*
* Returns: TRUE iff the value is returned
**/
-bool
+polkit_bool_t
libpolkit_session_get_ck_remote_host (PolKitSession *session, char **out_remote_host)
{
g_return_val_if_fail (session != NULL, FALSE);
@@ -317,7 +339,7 @@ libpolkit_session_get_ck_remote_host (Po
*
* Returns: TRUE iff the value is returned
**/
-bool
+polkit_bool_t
libpolkit_session_get_seat (PolKitSession *session, PolKitSeat **out_seat)
{
g_return_val_if_fail (session != NULL, FALSE);
@@ -327,245 +349,6 @@ libpolkit_session_get_seat (PolKitSessio
}
/**
- * libpolkit_session_new_from_objpath:
- * @con: D-Bus system bus connection
- * @objpath: object path of ConsoleKit session object
- * @uid: the user owning the session or -1 if unknown
- * @error: D-Bus error
- *
- * This function will construct a #PolKitSession object by querying
- * the ConsoleKit daemon for information. Note that this will do a lot
- * of blocking IO so it is best avoided if your process already
- * tracks/caches all the information. If you pass in @uid as a
- * non-negative number, a round trip can be saved.
- *
- * Returns: the new object or #NULL if an error occured (in which case
- * @error will be set)
- **/
-PolKitSession *
-libpolkit_session_new_from_objpath (DBusConnection *con, const char *objpath, uid_t uid, DBusError *error)
-{
- PolKitSeat *seat;
- PolKitSession *session;
- DBusMessage *message;
- DBusMessage *reply;
- char *str;
- bool is_active;
- bool is_local;
- char *remote_host;
- char *seat_path;
-
- g_return_val_if_fail (con != NULL, NULL);
- g_return_val_if_fail (objpath != NULL, NULL);
- g_return_val_if_fail (error != NULL, NULL);
- g_return_val_if_fail (! dbus_error_is_set (error), NULL);
-
- session = NULL;
- remote_host = NULL;
- seat_path = NULL;
-
- message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit",
- objpath,
- "org.freedesktop.ConsoleKit.Session",
- "IsActive");
- reply = dbus_connection_send_with_reply_and_block (con, message, -1, error);
- if (reply == NULL || dbus_error_is_set (error)) {
- g_warning ("Error doing Session.IsActive on ConsoleKit: %s: %s", error->name, error->message);
- dbus_message_unref (message);
- if (reply != NULL)
- dbus_message_unref (reply);
- goto out;
- }
- if (!dbus_message_get_args (reply, NULL,
- DBUS_TYPE_BOOLEAN, &is_active,
- DBUS_TYPE_INVALID)) {
- g_warning ("Invalid IsActive reply from CK");
- goto out;
- }
- dbus_message_unref (message);
- dbus_message_unref (reply);
-
- message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit",
- objpath,
- "org.freedesktop.ConsoleKit.Session",
- "IsLocal");
- reply = dbus_connection_send_with_reply_and_block (con, message, -1, error);
- if (reply == NULL || dbus_error_is_set (error)) {
- g_warning ("Error doing Session.IsLocal on ConsoleKit: %s: %s", error->name, error->message);
- dbus_message_unref (message);
- if (reply != NULL)
- dbus_message_unref (reply);
- goto out;
- }
- if (!dbus_message_get_args (reply, NULL,
- DBUS_TYPE_BOOLEAN, &is_local,
- DBUS_TYPE_INVALID)) {
- g_warning ("Invalid IsLocal reply from CK");
- goto out;
- }
- dbus_message_unref (message);
- dbus_message_unref (reply);
-
- if (!is_local) {
- message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit",
- objpath,
- "org.freedesktop.ConsoleKit.Session",
- "GetRemoteHostName");
- reply = dbus_connection_send_with_reply_and_block (con, message, -1, error);
- if (reply == NULL || dbus_error_is_set (error)) {
- g_warning ("Error doing Session.GetRemoteHostName on ConsoleKit: %s: %s",
- error->name, error->message);
- dbus_message_unref (message);
- if (reply != NULL)
- dbus_message_unref (reply);
- goto out;
- }
- if (!dbus_message_get_args (reply, NULL,
- DBUS_TYPE_STRING, &str,
- DBUS_TYPE_INVALID)) {
- g_warning ("Invalid GetRemoteHostName reply from CK");
- goto out;
- }
- remote_host = g_strdup (str);
- dbus_message_unref (message);
- dbus_message_unref (reply);
- }
-
- message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit",
- objpath,
- "org.freedesktop.ConsoleKit.Session",
- "GetSeatId");
- reply = dbus_connection_send_with_reply_and_block (con, message, -1, error);
- if (reply == NULL || dbus_error_is_set (error)) {
- g_warning ("Error doing Session.GetSeatId on ConsoleKit: %s: %s",
- error->name, error->message);
- dbus_message_unref (message);
- if (reply != NULL)
- dbus_message_unref (reply);
- goto out;
- }
- if (!dbus_message_get_args (reply, NULL,
- DBUS_TYPE_OBJECT_PATH, &str,
- DBUS_TYPE_INVALID)) {
- g_warning ("Invalid GetSeatId reply from CK");
- goto out;
- }
- seat_path = g_strdup (str);
- dbus_message_unref (message);
- dbus_message_unref (reply);
-
- if ((int) uid == -1) {
- message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit",
- objpath,
- "org.freedesktop.ConsoleKit.Session",
- "GetUnixUser");
- reply = dbus_connection_send_with_reply_and_block (con, message, -1, error);
- if (reply == NULL || dbus_error_is_set (error)) {
- g_warning ("Error doing Session.GetUnixUser on ConsoleKit: %s: %s",error->name, error->message);
- dbus_message_unref (message);
- if (reply != NULL)
- dbus_message_unref (reply);
- goto out;
- }
- if (!dbus_message_get_args (reply, NULL,
- DBUS_TYPE_INT32, &uid,
- DBUS_TYPE_INVALID)) {
- g_warning ("Invalid GetUnixUser reply from CK");
- goto out;
- }
- dbus_message_unref (message);
- dbus_message_unref (reply);
- }
-
- _pk_debug ("is_active %d", is_active);
- _pk_debug ("is_local %d", is_local);
- _pk_debug ("uid %d", uid);
- if (!is_local) {
- _pk_debug ("remote host '%s'", remote_host);
- }
- _pk_debug ("ck seat '%s'", seat_path);
-
- session = libpolkit_session_new ();
- libpolkit_session_set_ck_objref (session, objpath);
- libpolkit_session_set_ck_is_active (session, is_active);
- libpolkit_session_set_ck_is_local (session, is_local);
- if (!is_local) {
- libpolkit_session_set_ck_remote_host (session, remote_host);
- }
- seat = libpolkit_seat_new ();
- libpolkit_seat_set_ck_objref (seat, seat_path);
- libpolkit_session_set_seat (session, seat);
- libpolkit_seat_unref (seat); /* we own this now */
-
-out:
- g_free (remote_host);
- g_free (seat_path);
- return session;
-}
-
-/**
- * libpolkit_session_new_from_cookie:
- * @con: D-Bus system bus connection
- * @cookie: a ConsoleKit XDG_SESSION_COOKIE
- * @error: D-Bus error
- *
- * This function will construct a #PolKitSession object by querying
- * the ConsoleKit daemon for information. Note that this will do a lot
- * of blocking IO so it is best avoided if your process already
- * tracks/caches all the information.
- *
- * Returns: the new object or #NULL if an error occured (in which case
- * @error will be set)
- **/
-PolKitSession *
-libpolkit_session_new_from_cookie (DBusConnection *con, const char *cookie, DBusError *error)
-{
- PolKitSession *session;
- DBusMessage *message;
- DBusMessage *reply;
- char *str;
- char *objpath;
-
- g_return_val_if_fail (con != NULL, NULL);
- g_return_val_if_fail (cookie != NULL, NULL);
- g_return_val_if_fail (error != NULL, NULL);
- g_return_val_if_fail (! dbus_error_is_set (error), NULL);
-
- objpath = NULL;
- session = NULL;
-
- message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit",
- "/org/freedesktop/ConsoleKit/Manager",
- "org.freedesktop.ConsoleKit.Manager",
- "GetSessionForCookie");
- dbus_message_append_args (message, DBUS_TYPE_STRING, &cookie, DBUS_TYPE_INVALID);
- reply = dbus_connection_send_with_reply_and_block (con, message, -1, error);
- if (reply == NULL || dbus_error_is_set (error)) {
- g_warning ("Error doing Manager.GetSessionForCookie on ConsoleKit: %s: %s",
- error->name, error->message);
- dbus_message_unref (message);
- if (reply != NULL)
- dbus_message_unref (reply);
- goto out;
- }
- if (!dbus_message_get_args (reply, NULL,
- DBUS_TYPE_OBJECT_PATH, &str,
- DBUS_TYPE_INVALID)) {
- g_warning ("Invalid GetSessionForCookie reply from CK");
- goto out;
- }
- objpath = g_strdup (str);
- dbus_message_unref (message);
- dbus_message_unref (reply);
-
- session = libpolkit_session_new_from_objpath (con, objpath, -1, error);
-
-out:
- g_free (objpath);
- return session;
-}
-
-/**
* libpolkit_session_debug:
* @session: the object
*
@@ -581,3 +364,31 @@ libpolkit_session_debug (PolKitSession *
if (session->seat != NULL)
libpolkit_seat_debug (session->seat);
}
+
+
+/**
+ * libpolkit_session_validate:
+ * @session: the object
+ *
+ * Validate the object
+ *
+ * Returns: #TRUE iff the object is valid.
+ **/
+polkit_bool_t
+libpolkit_session_validate (PolKitSession *session)
+{
+ polkit_bool_t ret;
+ g_return_val_if_fail (session != NULL, FALSE);
+
+ ret = FALSE;
+ if (session->is_local) {
+ if (session->remote_host != NULL)
+ goto error;
+ } else {
+ if (session->remote_host == NULL)
+ goto error;
+ }
+ ret = TRUE;
+error:
+ return TRUE;
+}
diff --git a/libpolkit/libpolkit-session.h b/libpolkit/libpolkit-session.h
index 44821a9..2ee4bda 100644
--- a/libpolkit/libpolkit-session.h
+++ b/libpolkit/libpolkit-session.h
@@ -23,36 +23,38 @@
*
**************************************************************************/
+#if !defined (POLKIT_COMPILATION) && !defined(_POLKIT_INSIDE_POLKIT_H)
+#error "Only <libpolkit/libpolkit.h> can be included directly, this file may disappear or change contents."
+#endif
+
#ifndef LIBPOLKIT_SESSION_H
#define LIBPOLKIT_SESSION_H
-#include <stdbool.h>
-#include <sys/types.h>
-#include <dbus/dbus.h>
-
+#include <libpolkit/libpolkit-types.h>
#include <libpolkit/libpolkit-seat.h>
+#include <sys/types.h>
+
struct PolKitSession;
typedef struct PolKitSession PolKitSession;
PolKitSession *libpolkit_session_new (void);
-PolKitSession *libpolkit_session_new_from_objpath (DBusConnection *con, const char *objpath, uid_t uid, DBusError *error);
-PolKitSession *libpolkit_session_new_from_cookie (DBusConnection *con, const char *cookie, DBusError *error);
PolKitSession *libpolkit_session_ref (PolKitSession *session);
void libpolkit_session_unref (PolKitSession *session);
-void libpolkit_session_set_uid (PolKitSession *session, uid_t uid);
-void libpolkit_session_set_seat (PolKitSession *session, PolKitSeat *seat);
-void libpolkit_session_set_ck_objref (PolKitSession *session, const char *ck_objref);
-void libpolkit_session_set_ck_is_active (PolKitSession *session, bool is_active);
-void libpolkit_session_set_ck_is_local (PolKitSession *session, bool is_local);
-void libpolkit_session_set_ck_remote_host (PolKitSession *session, const char *remote_host);
-bool libpolkit_session_get_uid (PolKitSession *session, uid_t *out_uid);
-bool libpolkit_session_get_seat (PolKitSession *session, PolKitSeat **out_seat);
-bool libpolkit_session_get_ck_objref (PolKitSession *session, char **out_ck_objref);
-bool libpolkit_session_get_ck_is_active (PolKitSession *session, bool *out_is_active);
-bool libpolkit_session_get_ck_is_local (PolKitSession *session, bool *out_is_local);
-bool libpolkit_session_get_ck_remote_host (PolKitSession *session, char **out_remote_host);
+polkit_bool_t libpolkit_session_set_uid (PolKitSession *session, uid_t uid);
+polkit_bool_t libpolkit_session_set_seat (PolKitSession *session, PolKitSeat *seat);
+polkit_bool_t libpolkit_session_set_ck_objref (PolKitSession *session, const char *ck_objref);
+polkit_bool_t libpolkit_session_set_ck_is_active (PolKitSession *session, polkit_bool_t is_active);
+polkit_bool_t libpolkit_session_set_ck_is_local (PolKitSession *session, polkit_bool_t is_local);
+polkit_bool_t libpolkit_session_set_ck_remote_host (PolKitSession *session, const char *remote_host);
+polkit_bool_t libpolkit_session_get_uid (PolKitSession *session, uid_t *out_uid);
+polkit_bool_t libpolkit_session_get_seat (PolKitSession *session, PolKitSeat **out_seat);
+polkit_bool_t libpolkit_session_get_ck_objref (PolKitSession *session, char **out_ck_objref);
+polkit_bool_t libpolkit_session_get_ck_is_active (PolKitSession *session, polkit_bool_t *out_is_active);
+polkit_bool_t libpolkit_session_get_ck_is_local (PolKitSession *session, polkit_bool_t *out_is_local);
+polkit_bool_t libpolkit_session_get_ck_remote_host (PolKitSession *session, char **out_remote_host);
void libpolkit_session_debug (PolKitSession *session);
+polkit_bool_t libpolkit_session_validate (PolKitSession *session);
#endif /* LIBPOLKIT_SESSION_H */
diff --git a/libpolkit/libpolkit-types.h b/libpolkit/libpolkit-types.h
new file mode 100644
index 0000000..75b4679
--- /dev/null
+++ b/libpolkit/libpolkit-types.h
@@ -0,0 +1,56 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/***************************************************************************
+ *
+ * libpolkit-types.h : fundamental types such as polkit_bool_t
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+#if !defined (POLKIT_COMPILATION) && !defined(_POLKIT_INSIDE_POLKIT_H)
+#error "Only <libpolkit/libpolkit.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef LIBPOLKIT_TYPES_H
+#define LIBPOLKIT_TYPES_H
+
+/**
+ * SECTION:libpolkit-types
+ * @short_description: Basic types.
+ *
+ * Typedefs for common primitive types.
+ **/
+
+/**
+ * polkit_bool_t:
+ *
+ * A boolean, valid values are #TRUE and #FALSE.
+ */
+typedef int polkit_bool_t;
+
+#ifndef TRUE
+# define TRUE 1
+#endif
+#ifndef FALSE
+# define FALSE 0
+#endif
+
+#endif /* LIBPOLKIT_TYPES_H */
+
+
diff --git a/libpolkit/libpolkit-utils.c b/libpolkit/libpolkit-utils.c
new file mode 100644
index 0000000..c0aca7d
--- /dev/null
+++ b/libpolkit/libpolkit-utils.c
@@ -0,0 +1,153 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/***************************************************************************
+ *
+ * libpolkit-utils.c : internal utilities used in libpolkit
+ *
+ * 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 <stdarg.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <time.h>
+#include <glib.h>
+#include <string.h>
+
+#include "libpolkit-utils.h"
+#include "libpolkit-debug.h"
+
+/**
+ * SECTION:libpolkit-utils
+ * @short_description: Internal utility functions for libpolkit.
+ *
+ * Internal utility functions for libpolkit.
+ **/
+
+/**
+ * _pk_validate_identifier:
+ * @identifier: the NUL-terminated string to validate
+ *
+ * Validates strings used for an identifier; PolicyKit conventions
+ * state that identifiers must be NUL-terminated ASCII strings less
+ * than 256 bytes and only contain the characters "[a-z][A-Z]0-9]._-:/"
+ *
+ * Returns: #TRUE iff the identifier validates
+ **/
+polkit_bool_t
+_pk_validate_identifier (const char *identifier)
+{
+ unsigned int n;
+ polkit_bool_t ret;
+
+ g_return_val_if_fail (identifier != NULL, FALSE);
+
+ ret = FALSE;
+ for (n = 0; identifier[n] != '\0'; n++) {
+ char c = identifier[n];
+
+ if (n >= 255) {
+ _pk_debug ("identifier too long");
+ goto out;
+ }
+
+ if ((c >= 'a' && c <= 'z') ||
+ (c >= 'A' && c <= 'Z') ||
+ (c >= '0' && c <= '9') ||
+ c == '.' ||
+ c == '_' ||
+ c == '-' ||
+ c == ':' ||
+ c == '/')
+ continue;
+
+ _pk_debug ("invalid character in identifier");
+ goto out;
+ }
+
+ ret = TRUE;
+out:
+ return ret;
+}
+
+
+/* Determine wether the given character is valid as a second or later character in a bus name */
+#define VALID_BUS_NAME_CHARACTER(c) \
+ ( ((c) >= '0' && (c) <= '9') || \
+ ((c) >= 'A' && (c) <= 'Z') || \
+ ((c) >= 'a' && (c) <= 'z') || \
+ ((c) == '_') || ((c) == '-'))
+
+polkit_bool_t
+_pk_validate_unique_bus_name (const char *unique_bus_name)
+{
+ int len;
+ const char *s;
+ const char *end;
+ const char *last_dot;
+ polkit_bool_t ret;
+
+ ret = FALSE;
+
+ if (unique_bus_name == NULL)
+ goto error;
+
+ len = strlen (unique_bus_name);
+ if (len == 0)
+ goto error;
+
+ end = unique_bus_name + len;
+ last_dot = NULL;
+
+ s = unique_bus_name;
+
+ /* check special cases of first char so it doesn't have to be done
+ * in the loop. Note we know len > 0
+ */
+ if (*s == ':') {
+ /* unique name */
+ ++s;
+ while (s != end) {
+ if (*s == '.') {
+ if (G_UNLIKELY ((s + 1) == end))
+ goto error;
+ if (G_UNLIKELY (!VALID_BUS_NAME_CHARACTER (*(s + 1))))
+ goto error;
+ ++s; /* we just validated the next char, so skip two */
+ } else if (G_UNLIKELY (!VALID_BUS_NAME_CHARACTER (*s))) {
+ goto error;
+ }
+ ++s;
+ }
+ } else {
+ goto error;
+ }
+
+ ret = TRUE;
+
+error:
+ if (!ret)
+ _pk_debug ("name '%s' did not validate", unique_bus_name);
+ return ret;
+}
diff --git a/libpolkit/libpolkit-utils.h b/libpolkit/libpolkit-utils.h
new file mode 100644
index 0000000..00512c6
--- /dev/null
+++ b/libpolkit/libpolkit-utils.h
@@ -0,0 +1,37 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/***************************************************************************
+ *
+ * libpolkit-utils.h : internal utilities used in libpolkit
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+#ifndef LIBPOLKIT_UTILS_H
+#define LIBPOLKIT_UTILS_H
+
+#include <libpolkit/libpolkit-types.h>
+
+polkit_bool_t _pk_validate_identifier (const char *identifier);
+
+polkit_bool_t _pk_validate_unique_bus_name (const char *unique_bus_name);
+
+#endif /* LIBPOLKIT_UTILS_H */
+
+
diff --git a/libpolkit/libpolkit.h b/libpolkit/libpolkit.h
index 4088a8e..889b00d 100644
--- a/libpolkit/libpolkit.h
+++ b/libpolkit/libpolkit.h
@@ -26,7 +26,22 @@
#ifndef LIBPOLKIT_H
#define LIBPOLKIT_H
+#define _POLKIT_INSIDE_POLKIT_H 1
+#include <libpolkit/libpolkit-types.h>
+#include <libpolkit/libpolkit-error.h>
+#include <libpolkit/libpolkit-result.h>
#include <libpolkit/libpolkit-context.h>
+#include <libpolkit/libpolkit-action.h>
+#include <libpolkit/libpolkit-resource.h>
+#include <libpolkit/libpolkit-seat.h>
+#include <libpolkit/libpolkit-session.h>
+#include <libpolkit/libpolkit-caller.h>
+#include <libpolkit/libpolkit-policy-file-entry.h>
+#include <libpolkit/libpolkit-policy-file.h>
+#include <libpolkit/libpolkit-policy-cache.h>
+#include <libpolkit/libpolkit-policy-default.h>
+#include <libpolkit/libpolkit-module.h>
+#undef _POLKIT_INSIDE_POLKIT_H
#endif /* LIBPOLKIT_H */
diff --git a/modules/Makefile.am b/modules/Makefile.am
index b4eee78..010ed66 100644
--- a/modules/Makefile.am
+++ b/modules/Makefile.am
@@ -1,5 +1,5 @@
-SUBDIRS = default allow-all deny-all run-program
+SUBDIRS = default allow-all deny-all run-program grant
polkitconfdir = $(sysconfdir)/PolicyKit
dist_polkitconf_DATA = PolicyKit.conf
diff --git a/modules/PolicyKit.conf b/modules/PolicyKit.conf
index ee8120b..c3c6dd9 100644
--- a/modules/PolicyKit.conf
+++ b/modules/PolicyKit.conf
@@ -3,3 +3,4 @@
# NOTE: Changes made to this file may be applied instantly
advise polkit-module-default.so
+advise polkit-module-grant.so
diff --git a/modules/allow-all/polkit-module-allow-all.c b/modules/allow-all/polkit-module-allow-all.c
index eddee16..3da56c2 100644
--- a/modules/allow-all/polkit-module-allow-all.c
+++ b/modules/allow-all/polkit-module-allow-all.c
@@ -27,15 +27,16 @@
# include <config.h>
#endif
-#include <libpolkit/libpolkit-module.h>
+#include <stddef.h>
+#include <libpolkit/libpolkit.h>
/* The symbol that libpolkit looks up when loading this module */
-bool libpolkit_module_set_functions (PolKitModuleInterface *module_interface);
+polkit_bool_t libpolkit_module_set_functions (PolKitModuleInterface *module_interface);
-static bool
+static polkit_bool_t
_module_init (PolKitModuleInterface *module_interface, int argc, char *argv[])
{
- return true;
+ return TRUE;
}
static void
@@ -63,12 +64,12 @@ _module_can_caller_access_resource (PolK
return LIBPOLKIT_RESULT_YES;
}
-bool
+polkit_bool_t
libpolkit_module_set_functions (PolKitModuleInterface *module_interface)
{
- bool ret;
+ polkit_bool_t ret;
- ret = false;
+ ret = FALSE;
if (module_interface == NULL)
goto out;
@@ -77,7 +78,7 @@ libpolkit_module_set_functions (PolKitMo
libpolkit_module_set_func_can_session_access_resource (module_interface, _module_can_session_access_resource);
libpolkit_module_set_func_can_caller_access_resource (module_interface, _module_can_caller_access_resource);
- ret = true;
+ ret = TRUE;
out:
return ret;
}
diff --git a/modules/default/polkit-module-default.c b/modules/default/polkit-module-default.c
index 09b25e3..86a0635 100644
--- a/modules/default/polkit-module-default.c
+++ b/modules/default/polkit-module-default.c
@@ -27,17 +27,18 @@
# include <config.h>
#endif
-#include <libpolkit/libpolkit-module.h>
+#include <stddef.h>
+#include <libpolkit/libpolkit.h>
/* The symbol that libpolkit looks up when loading this module */
-bool libpolkit_module_set_functions (PolKitModuleInterface *module_interface);
+polkit_bool_t libpolkit_module_set_functions (PolKitModuleInterface *module_interface);
-static bool
+static polkit_bool_t
_module_init (PolKitModuleInterface *module_interface,
int argc,
char *argv[])
{
- return true;
+ return TRUE;
}
static void
@@ -87,12 +88,12 @@ _module_can_caller_access_resource (PolK
caller);
}
-bool
+polkit_bool_t
libpolkit_module_set_functions (PolKitModuleInterface *module_interface)
{
- bool ret;
+ polkit_bool_t ret;
- ret = false;
+ ret = FALSE;
if (module_interface == NULL)
goto out;
@@ -101,7 +102,7 @@ libpolkit_module_set_functions (PolKitMo
libpolkit_module_set_func_can_session_access_resource (module_interface, _module_can_session_access_resource);
libpolkit_module_set_func_can_caller_access_resource (module_interface, _module_can_caller_access_resource);
- ret = true;
+ ret = TRUE;
out:
return ret;
}
diff --git a/modules/deny-all/polkit-module-deny-all.c b/modules/deny-all/polkit-module-deny-all.c
index 7562312..e2eb517 100644
--- a/modules/deny-all/polkit-module-deny-all.c
+++ b/modules/deny-all/polkit-module-deny-all.c
@@ -27,15 +27,16 @@
# include <config.h>
#endif
-#include <libpolkit/libpolkit-module.h>
+#include <stddef.h>
+#include <libpolkit/libpolkit.h>
/* The symbol that libpolkit looks up when loading this module */
-bool libpolkit_module_set_functions (PolKitModuleInterface *module_interface);
+polkit_bool_t libpolkit_module_set_functions (PolKitModuleInterface *module_interface);
-static bool
+static polkit_bool_t
_module_init (PolKitModuleInterface *module_interface, int argc, char *argv[])
{
- return true;
+ return TRUE;
}
static void
@@ -63,12 +64,12 @@ _module_can_caller_access_resource (PolK
return LIBPOLKIT_RESULT_NO;
}
-bool
+polkit_bool_t
libpolkit_module_set_functions (PolKitModuleInterface *module_interface)
{
- bool ret;
+ polkit_bool_t ret;
- ret = false;
+ ret = FALSE;
if (module_interface == NULL)
goto out;
@@ -77,7 +78,7 @@ libpolkit_module_set_functions (PolKitMo
libpolkit_module_set_func_can_session_access_resource (module_interface, _module_can_session_access_resource);
libpolkit_module_set_func_can_caller_access_resource (module_interface, _module_can_caller_access_resource);
- ret = true;
+ ret = TRUE;
out:
return ret;
}
diff --git a/modules/grant/Makefile.am b/modules/grant/Makefile.am
new file mode 100644
index 0000000..0b7c5f1
--- /dev/null
+++ b/modules/grant/Makefile.am
@@ -0,0 +1,25 @@
+## Process this file with automake to produce Makefile.in
+
+INCLUDES = \
+ -I$(top_builddir) -I$(top_srcdir) \
+ -DPACKAGE_LIBEXEC_DIR=\""$(libexecdir)"\" \
+ -DPACKAGE_SYSCONF_DIR=\""$(sysconfdir)"\" \
+ -DPACKAGE_DATA_DIR=\""$(datadir)"\" \
+ -DPACKAGE_BIN_DIR=\""$(bindir)"\" \
+ -DPACKAGE_LOCALSTATE_DIR=\""$(localstatedir)"\" \
+ -DPACKAGE_LOCALE_DIR=\""$(localedir)"\" \
+ -D_POSIX_PTHREAD_SEMANTICS -D_REENTRANT \
+ @GLIB_CFLAGS@ @DBUS_CFLAGS@
+
+polkitmoduledir = $(libdir)/PolicyKit/modules
+polkitmodule_LTLIBRARIES = \
+ polkit-module-grant.la \
+ $(NULL)
+
+
+polkit_module_grant_la_SOURCES = polkit-module-grant.c
+polkit_module_grant_la_LDFLAGS = -no-undefined -module -avoid-version
+polkit_module_grant_la_LIBADD = $(top_builddir)/libpolkit/libpolkit.la @GLIB_LIBS@
+
+clean-local :
+ rm -f *~
diff --git a/modules/grant/polkit-module-grant.c b/modules/grant/polkit-module-grant.c
new file mode 100644
index 0000000..15a06c0
--- /dev/null
+++ b/modules/grant/polkit-module-grant.c
@@ -0,0 +1,194 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/***************************************************************************
+ *
+ * polkit-module-grant.c : determine policy by looking at grants
+ *
+ * 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
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <libpolkit/libpolkit.h>
+#include <glib.h>
+
+/* The symbol that libpolkit looks up when loading this module */
+polkit_bool_t libpolkit_module_set_functions (PolKitModuleInterface *module_interface);
+
+static polkit_bool_t
+_module_init (PolKitModuleInterface *module_interface, int argc, char *argv[])
+{
+ return TRUE;
+}
+
+static void
+_module_shutdown (PolKitModuleInterface *module_interface)
+{
+}
+
+
+
+static PolKitResult
+_module_can_session_access_resource (PolKitModuleInterface *module_interface,
+ PolKitContext *pk_context,
+ PolKitAction *action,
+ PolKitResource *resource,
+ PolKitSession *session)
+{
+ return LIBPOLKIT_RESULT_UNKNOWN_ACTION;
+}
+
+static PolKitResult
+_module_can_caller_access_resource (PolKitModuleInterface *module_interface,
+ PolKitContext *pk_context,
+ PolKitAction *action,
+ PolKitResource *resource,
+ PolKitCaller *caller)
+{
+ char *grant_file;
+ PolKitSession *session;
+ PolKitResult result;
+
+ result = LIBPOLKIT_RESULT_UNKNOWN_ACTION;
+
+ /* file format:
+ *
+ * file: /var/[lib,run]/PolicyKit/grant/<action-name>.grant
+ *
+ * contents:
+ * <uid1>[ <session-objpath>]\n # only makes sense for run
+ * <uid2>\n
+ * ...
+ *
+ * - run is used for temporarily granted privileges
+ * - lib is used for permanently granted privileges
+ *
+ * FHS guarantees that the files /var/run/PolicyKit are
+ * deleted upon reboots so we just need to ensure that
+ * ConsoleKit session id's are unique per system (TODO: Ask Jon
+ * to make ConsoleKit guarantee this).
+ */
+
+ uid_t invoking_user_id;
+ char *action_name;
+ char *session_objpath;
+ const char *session_name;
+ char *resource_type;
+ char *resource_id;
+ char *resource_str_to_hash;
+ char *dbus_name;
+ guint resource_hash;
+
+ if (!libpolkit_action_get_action_id (action, &action_name))
+ goto out;
+ if (!libpolkit_caller_get_uid (caller, &invoking_user_id))
+ goto out;
+
+ if (resource == NULL)
+ goto out;
+ if (!libpolkit_resource_get_resource_type (resource, &resource_type))
+ goto out;
+ if (!libpolkit_resource_get_resource_id (resource, &resource_id))
+ goto out;
+
+ session_name = NULL;
+ if (!libpolkit_caller_get_ck_session (caller, &session))
+ goto out;
+ if (!libpolkit_caller_get_dbus_name (caller, &dbus_name))
+ goto out;
+ if (!libpolkit_session_get_ck_objref (session, &session_objpath))
+ goto out;
+
+ session_name = g_basename (session_objpath);
+ resource_str_to_hash = g_strdup_printf ("%s:%s", resource_type, resource_id);
+ resource_hash = g_str_hash (resource_str_to_hash);
+ g_free (resource_str_to_hash);
+
+ /* TODO: FIXME: XXX: this format of storing granted privileges needs be redone
+ *
+ * this concerns these two files
+ * - libpolkit-grant/polkit-grant-helper.c
+ * - modules/grant/polkit-module-grant.c
+ */
+
+ /*
+ * /var/lib/PolicyKit/uid_<uid>_<action>_<resource-hash>.grant
+ * uid_<uid>_<action>.grant
+ *
+ * /var/run/PolicyKit/session_<session>_<uid>_<action>_<resource-hash>.grant
+ * session_<session>_<uid>_<action>.grant
+ * dbus_<dbusname>_<uid>_<action>_<resource-hash>.grant
+ */
+
+ grant_file = g_strdup_printf (PACKAGE_LOCALSTATE_DIR "/run/PolicyKit/dbus_%s_%d_%s_%u.grant",
+ dbus_name, invoking_user_id, action_name, resource_hash);
+ if (g_file_test (grant_file, G_FILE_TEST_EXISTS)) {
+ result = LIBPOLKIT_RESULT_YES;
+ g_free (grant_file);
+ goto out;
+ }
+ g_free (grant_file);
+
+ grant_file = g_strdup_printf (PACKAGE_LOCALSTATE_DIR "/run/PolicyKit/session_%s_%d_%s_%u.grant",
+ session_name, invoking_user_id, action_name, resource_hash);
+ if (g_file_test (grant_file, G_FILE_TEST_EXISTS)) {
+ result = LIBPOLKIT_RESULT_YES;
+ g_free (grant_file);
+ goto out;
+ }
+ g_free (grant_file);
+
+ grant_file = g_strdup_printf (PACKAGE_LOCALSTATE_DIR "/lib/PolicyKit/uid_%d_%s_%u.grant",
+ invoking_user_id, action_name, resource_hash);
+ if (g_file_test (grant_file, G_FILE_TEST_EXISTS)) {
+ result = LIBPOLKIT_RESULT_YES;
+ g_free (grant_file);
+ goto out;
+ }
+ g_free (grant_file);
+
+
+out:
+ return result;
+}
+
+polkit_bool_t
+libpolkit_module_set_functions (PolKitModuleInterface *module_interface)
+{
+ polkit_bool_t ret;
+
+ ret = FALSE;
+ if (module_interface == NULL)
+ goto out;
+
+ libpolkit_module_set_func_initialize (module_interface, _module_init);
+ libpolkit_module_set_func_shutdown (module_interface, _module_shutdown);
+ libpolkit_module_set_func_can_session_access_resource (module_interface, _module_can_session_access_resource);
+ libpolkit_module_set_func_can_caller_access_resource (module_interface, _module_can_caller_access_resource);
+
+ ret = TRUE;
+out:
+ return ret;
+}
diff --git a/modules/run-program/polkit-module-run-program.c b/modules/run-program/polkit-module-run-program.c
index 8f02e57..ecbc126 100644
--- a/modules/run-program/polkit-module-run-program.c
+++ b/modules/run-program/polkit-module-run-program.c
@@ -27,18 +27,18 @@
# include <config.h>
#endif
-#include <libpolkit/libpolkit-module.h>
+#include <libpolkit/libpolkit.h>
#include <glib.h>
/* The symbol that libpolkit looks up when loading this module */
-bool libpolkit_module_set_functions (PolKitModuleInterface *module_interface);
+polkit_bool_t libpolkit_module_set_functions (PolKitModuleInterface *module_interface);
typedef struct {
int program_argc;
char **program_argv;
} UserData;
-static bool
+static polkit_bool_t
_module_init (PolKitModuleInterface *module_interface, int argc, char *argv[])
{
int n;
@@ -77,12 +77,12 @@ _module_init (PolKitModuleInterface *mod
libpolkit_module_set_user_data (module_interface, user_data);
- return true;
+ return TRUE;
error:
if (user_data->program_argv != NULL)
g_strfreev (user_data->program_argv);
g_free (user_data);
- return false;
+ return FALSE;
}
static void
@@ -120,7 +120,7 @@ _add_action_param_to_env (PolKitAction *
g_free (upper);
}
-static bool
+static polkit_bool_t
_add_action_to_env (PolKitAction *action, GPtrArray *envp)
{
char *p_id;
@@ -129,12 +129,12 @@ _add_action_to_env (PolKitAction *action
g_ptr_array_add (envp, g_strdup_printf ("POLKIT_ACTION_ID=%s", p_id));
libpolkit_action_param_foreach (action, _add_action_param_to_env, envp);
- return true;
+ return TRUE;
error:
- return false;
+ return FALSE;
}
-static bool
+static polkit_bool_t
_add_resource_to_env (PolKitResource *resource, GPtrArray *envp)
{
char *r_type;
@@ -145,30 +145,30 @@ _add_resource_to_env (PolKitResource *re
goto error;
g_ptr_array_add (envp, g_strdup_printf ("POLKIT_RESOURCE_TYPE=%s", r_type));
g_ptr_array_add (envp, g_strdup_printf ("POLKIT_RESOURCE_ID=%s", r_id));
- return true;
+ return TRUE;
error:
- return false;
+ return FALSE;
}
-static bool
+static polkit_bool_t
_add_seat_to_env (PolKitSeat *seat, GPtrArray *envp)
{
char *s_ck_objref;
if (!libpolkit_seat_get_ck_objref (seat, &s_ck_objref))
goto error;
g_ptr_array_add (envp, g_strdup_printf ("POLKIT_SEAT_CK_OBJREF=%s", s_ck_objref));
- return true;
+ return TRUE;
error:
- return false;
+ return FALSE;
}
-static bool
+static polkit_bool_t
_add_session_to_env (PolKitSession *session, GPtrArray *envp)
{
uid_t s_uid;
char *s_ck_objref;
- bool s_ck_is_active;
- bool s_ck_is_local;
+ polkit_bool_t s_ck_is_active;
+ polkit_bool_t s_ck_is_local;
char *s_ck_remote_host;
PolKitSeat *s_seat;
@@ -194,12 +194,12 @@ _add_session_to_env (PolKitSession *sess
g_ptr_array_add (envp, g_strdup_printf ("POLKIT_SESSION_CK_IS_LOCAL=%d", s_ck_is_local));
if (!s_ck_is_local)
g_ptr_array_add (envp, g_strdup_printf ("POLKIT_SESSION_CK_REMOTE_HOST=%s", s_ck_remote_host));
- return true;
+ return TRUE;
error:
- return false;
+ return FALSE;
}
-static bool
+static polkit_bool_t
_add_caller_to_env (PolKitCaller *caller, GPtrArray *envp)
{
uid_t c_uid;
@@ -227,23 +227,23 @@ _add_caller_to_env (PolKitCaller *caller
g_ptr_array_add (envp, g_strdup_printf ("POLKIT_CALLER_DBUS_NAME=%s", c_dbus_name));
if (c_selinux_context != NULL)
g_ptr_array_add (envp, g_strdup_printf ("POLKIT_CALLER_SELINUX_CONTEXT=%s", c_selinux_context));
- return true;
+ return TRUE;
error:
- return false;
+ return FALSE;
}
-static bool
+static polkit_bool_t
_run_program (UserData *user_data, char **envp, PolKitResult *result)
{
int n;
int exit_status;
GError *g_error;
char *prog_stdout;
- bool ret;
+ polkit_bool_t ret;
g_error = NULL;
prog_stdout = NULL;
- ret = false;
+ ret = FALSE;
if (!g_spawn_sync ("/",
user_data->program_argv,
@@ -274,7 +274,7 @@ _run_program (UserData *user_data, char
goto error;
}
- ret = true;
+ ret = TRUE;
error:
g_free (prog_stdout);
return ret;
@@ -301,8 +301,9 @@ _module_can_session_access_resource (Pol
if (!_add_action_to_env (action, envp))
goto error;
- if (!_add_resource_to_env (resource, envp))
- goto error;
+ if (resource != NULL)
+ if (!_add_resource_to_env (resource, envp))
+ goto error;
if (!_add_session_to_env (session, envp))
goto error;
g_ptr_array_add (envp, g_strdup ("PATH=/usr/bin:/bin"));
@@ -338,8 +339,9 @@ _module_can_caller_access_resource (PolK
envp = g_ptr_array_new ();
if (!_add_action_to_env (action, envp))
goto error;
- if (!_add_resource_to_env (resource, envp))
- goto error;
+ if (resource != NULL)
+ if (!_add_resource_to_env (resource, envp))
+ goto error;
if (!_add_caller_to_env (caller, envp))
goto error;
g_ptr_array_add (envp, g_strdup ("PATH=/usr/bin:/bin"));
@@ -356,12 +358,12 @@ error:
return result;
}
-bool
+polkit_bool_t
libpolkit_module_set_functions (PolKitModuleInterface *module_interface)
{
- bool ret;
+ polkit_bool_t ret;
- ret = false;
+ ret = FALSE;
if (module_interface == NULL)
goto out;
@@ -370,7 +372,7 @@ libpolkit_module_set_functions (PolKitMo
libpolkit_module_set_func_can_session_access_resource (module_interface, _module_can_session_access_resource);
libpolkit_module_set_func_can_caller_access_resource (module_interface, _module_can_caller_access_resource);
- ret = true;
+ ret = TRUE;
out:
return ret;
}
diff --git a/tools/Makefile.am b/tools/Makefile.am
index 8b8475b..4524d70 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -11,17 +11,20 @@ INCLUDES = \
@GLIB_CFLAGS@ \
@DBUS_CFLAGS@
-bin_PROGRAMS = polkit-check-caller polkit-check-session polkit-policy-file-validate
+bin_PROGRAMS = polkit-check-caller polkit-check-session polkit-policy-file-validate polkit-grant
polkit_check_caller_SOURCES = polkit-check-caller.c
-polkit_check_caller_LDADD = @GLIB_LIBS@ @DBUS_LIBS@ $(top_builddir)/libpolkit/libpolkit.la
+polkit_check_caller_LDADD = @GLIB_LIBS@ @DBUS_LIBS@ $(top_builddir)/libpolkit/libpolkit.la $(top_builddir)/libpolkit-dbus/libpolkit-dbus.la
polkit_check_session_SOURCES = polkit-check-session.c
-polkit_check_session_LDADD = @GLIB_LIBS@ @DBUS_LIBS@ $(top_builddir)/libpolkit/libpolkit.la
+polkit_check_session_LDADD = @GLIB_LIBS@ @DBUS_LIBS@ $(top_builddir)/libpolkit/libpolkit.la $(top_builddir)/libpolkit-dbus/libpolkit-dbus.la
polkit_policy_file_validate_SOURCES = polkit-policy-file-validate.c
polkit_policy_file_validate_LDADD = $(top_builddir)/libpolkit/libpolkit.la
+polkit_grant_SOURCES = polkit-grant.c
+polkit_grant_LDADD = @GLIB_LIBS@ @DBUS_LIBS@ $(top_builddir)/libpolkit/libpolkit.la $(top_builddir)/libpolkit-grant/libpolkit-grant.la $(top_builddir)/libpolkit-dbus/libpolkit-dbus.la
+
clean-local :
rm -f *~
diff --git a/tools/polkit-check-caller.c b/tools/polkit-check-caller.c
index 49c6f03..32a2a94 100644
--- a/tools/polkit-check-caller.c
+++ b/tools/polkit-check-caller.c
@@ -35,7 +35,7 @@
#include <unistd.h>
#include <errno.h>
-#include <libpolkit/libpolkit.h>
+#include <libpolkit-dbus/libpolkit-dbus.h>
#include <glib.h>
diff --git a/tools/polkit-check-session.c b/tools/polkit-check-session.c
index cbde113..0b8472c 100644
--- a/tools/polkit-check-session.c
+++ b/tools/polkit-check-session.c
@@ -35,7 +35,7 @@
#include <unistd.h>
#include <errno.h>
-#include <libpolkit/libpolkit.h>
+#include <libpolkit-dbus/libpolkit-dbus.h>
#include <glib.h>
diff --git a/tools/polkit-grant.c b/tools/polkit-grant.c
new file mode 100644
index 0000000..d993b5f
--- /dev/null
+++ b/tools/polkit-grant.c
@@ -0,0 +1,425 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/***************************************************************************
+ *
+ * polkit-grant.c : grant privileges to a user through authentication
+ *
+ * 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
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define _GNU_SOURCE
+#include <getopt.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <grp.h>
+#include <unistd.h>
+#include <errno.h>
+#include <termios.h>
+
+#include <libpolkit-dbus/libpolkit-dbus.h>
+#include <libpolkit-grant/libpolkit-grant.h>
+
+#include <glib.h>
+
+static void
+usage (int argc, char *argv[])
+{
+ fprintf (stderr,
+ "\n"
+ "usage : polkit-grant\n"
+ " --action <action>\n"
+ " --resource-type <type> --resource-id <id>\n"
+ " [--version] [--help]\n");
+ fprintf (stderr,
+ "\n"
+ " --action Requested action\n"
+ " --resource-type Type of resource\n"
+ " --resource-id Identifier of resource\n"
+ " --version Show version and exit\n"
+ " --help Show this information and exit\n"
+ "\n"
+ "TODO.\n");
+}
+
+typedef struct {
+ gboolean gained_privilege;
+ GMainLoop *loop;
+} UserData;
+
+static void
+conversation_type (PolKitGrant *polkit_grant, PolKitResult auth_type, void *user_data)
+{
+ switch (auth_type) {
+ case LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH:
+ case LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH_KEEP_SESSION:
+ case LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH_KEEP_ALWAYS:
+ printf ("Authentication as root is required.\n");
+ break;
+
+ case LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH:
+ case LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_SESSION:
+ case LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_ALWAYS:
+ printf ("Authentication is required.\n");
+ break;
+
+ default:
+ /* should never happen */
+ exit (1);
+ }
+}
+
+static char *
+conversation_pam_prompt_echo_off (PolKitGrant *polkit_grant, const char *request, void *user_data)
+{
+ char *lineptr = NULL;
+ size_t linelen = 0;
+ struct termios old, new;
+ char *result;
+
+ printf ("%s", request);
+
+ /* Turn echo off */
+ if (tcgetattr (fileno (stdout), &old) != 0) {
+ exit (1);
+ }
+ new = old;
+ new.c_lflag &= ~ECHO;
+ if (tcsetattr (fileno (stdout), TCSAFLUSH, &new) != 0) {
+ exit (1);
+ }
+
+ getline (&lineptr, &linelen, stdin);
+
+ /* Restore terminal. */
+ tcsetattr (fileno (stdout), TCSAFLUSH, &old);
+
+ result = strdup (lineptr);
+ free (lineptr);
+ return result;
+}
+
+static char *
+conversation_pam_prompt_echo_on (PolKitGrant *polkit_grant, const char *request, void *user_data)
+{
+ char *lineptr = NULL;
+ size_t linelen = 0;
+ char *result;
+ printf ("%s", request);
+ getline (&lineptr, &linelen, stdin);
+ result = strdup (lineptr);
+ free (lineptr);
+ return result;
+}
+
+static void
+conversation_pam_error_msg (PolKitGrant *polkit_grant, const char *msg, void *user_data)
+{
+ printf ("error_msg='%s'\n", msg);
+}
+
+static void
+conversation_pam_text_info (PolKitGrant *polkit_grant, const char *msg, void *user_data)
+{
+ printf ("text_info='%s'\n", msg);
+}
+
+static PolKitResult
+conversation_override_grant_type (PolKitGrant *polkit_grant, PolKitResult auth_type, void *user_data)
+{
+ char *lineptr = NULL;
+ size_t linelen = 0;
+ polkit_bool_t keep_session = FALSE;
+ polkit_bool_t keep_always = FALSE;
+ PolKitResult overridden_auth_type;
+
+ switch (auth_type) {
+ case LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH:
+ case LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH:
+ break;
+ case LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH_KEEP_SESSION:
+ case LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_SESSION:
+ printf ("Keep this privilege for the session? [no/session]?\n");
+ getline (&lineptr, &linelen, stdin);
+ if (g_str_has_prefix (lineptr, "no")) {
+ ;
+ } else if (g_str_has_prefix (lineptr, "session")) {
+ keep_session = TRUE;
+ } else {
+ printf ("Valid responses are 'no' and 'session'. Exiting.\n");
+ exit (1);
+ }
+ free (lineptr);
+ break;
+ case LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH_KEEP_ALWAYS:
+ case LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_ALWAYS:
+ printf ("Keep this privilege for the session or always? [no/session/always]?\n");
+ getline (&lineptr, &linelen, stdin);
+ if (g_str_has_prefix (lineptr, "no")) {
+ ;
+ } else if (g_str_has_prefix (lineptr, "session")) {
+ keep_session = TRUE;
+ } else if (g_str_has_prefix (lineptr, "always")) {
+ keep_always = TRUE;
+ } else {
+ printf ("Valid responses are 'no', 'session' and 'always'. Exiting.\n");
+ exit (1);
+ }
+ free (lineptr);
+ break;
+ default:
+ /* should never happen */
+ exit (1);
+ }
+
+ switch (auth_type) {
+ case LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH:
+ case LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH_KEEP_SESSION:
+ case LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH_KEEP_ALWAYS:
+ overridden_auth_type = LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH;
+ if (keep_session)
+ overridden_auth_type = LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH_KEEP_SESSION;
+ else if (keep_always)
+ overridden_auth_type = LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH_KEEP_ALWAYS;
+ break;
+
+ case LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH:
+ case LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_SESSION:
+ case LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_ALWAYS:
+ overridden_auth_type = LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH;
+ if (keep_session)
+ overridden_auth_type = LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_SESSION;
+ else if (keep_always)
+ overridden_auth_type = LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_ALWAYS;
+ break;
+
+ default:
+ /* should never happen */
+ exit (1);
+ }
+
+ return overridden_auth_type;
+}
+
+static void
+conversation_done (PolKitGrant *polkit_grant, polkit_bool_t gained_privilege, void *user_data)
+{
+ UserData *ud = user_data;
+ ud->gained_privilege = gained_privilege;
+ g_main_loop_quit (ud->loop);
+}
+
+
+
+
+static void
+child_watch_func (GPid pid,
+ gint status,
+ gpointer user_data)
+{
+ PolKitGrant *polkit_grant = user_data;
+ libpolkit_grant_child_func (polkit_grant, pid, WEXITSTATUS (status));
+}
+
+static int
+add_child_watch (PolKitGrant *polkit_grant, pid_t pid)
+{
+ return g_child_watch_add (pid, child_watch_func, polkit_grant);
+}
+
+static gboolean
+io_watch_have_data (GIOChannel *channel, GIOCondition condition, gpointer user_data)
+{
+ int fd;
+ PolKitGrant *polkit_grant = user_data;
+ fd = g_io_channel_unix_get_fd (channel);
+ libpolkit_grant_io_func (polkit_grant, fd);
+ return TRUE;
+}
+
+static int
+add_io_watch (PolKitGrant *polkit_grant, int fd)
+{
+ guint id = 0;
+ GIOChannel *channel;
+ channel = g_io_channel_unix_new (fd);
+ if (channel == NULL)
+ goto out;
+ id = g_io_add_watch (channel, G_IO_IN, io_watch_have_data, polkit_grant);
+ if (id == 0) {
+ g_io_channel_unref (channel);
+ goto out;
+ }
+ g_io_channel_unref (channel);
+out:
+ return id;
+}
+
+static void
+remove_watch (PolKitGrant *polkit_auth, int watch_id)
+{
+ g_source_remove (watch_id);
+}
+
+int
+main (int argc, char *argv[])
+{
+ char *action_id = NULL;
+ char *resource_type = NULL;
+ char *resource_id = NULL;
+ gboolean is_version = FALSE;
+ DBusConnection *bus;
+ DBusError error;
+ PolKitContext *pol_ctx;
+ PolKitCaller *caller;
+ PolKitAction *action;
+ PolKitResource *resource;
+ PolKitError *p_error;
+ PolKitGrant *polkit_grant;
+ int ret;
+ UserData ud;
+
+ ret = 2;
+
+ if (argc <= 1) {
+ usage (argc, argv);
+ return 1;
+ }
+
+ while (1) {
+ int c;
+ int option_index = 0;
+ const char *opt;
+ static struct option long_options[] = {
+ {"action", 1, NULL, 0},
+ {"resource-type", 1, NULL, 0},
+ {"resource-id", 1, NULL, 0},
+ {"version", 0, NULL, 0},
+ {"help", 0, NULL, 0},
+ {NULL, 0, NULL, 0}
+ };
+
+ c = getopt_long (argc, argv, "",
+ long_options, &option_index);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 0:
+ opt = long_options[option_index].name;
+
+ if (strcmp (opt, "help") == 0) {
+ usage (argc, argv);
+ return 0;
+ } else if (strcmp (opt, "version") == 0) {
+ is_version = TRUE;
+ } else if (strcmp (opt, "action") == 0) {
+ action_id = strdup (optarg);
+ } else if (strcmp (opt, "resource-type") == 0) {
+ resource_type = strdup (optarg);
+ } else if (strcmp (opt, "resource-id") == 0) {
+ resource_id = strdup (optarg);
+ }
+ break;
+
+ default:
+ usage (argc, argv);
+ goto error;
+ }
+ }
+
+ if (is_version) {
+ printf ("polkit-grant " PACKAGE_VERSION "\n");
+ return 0;
+ }
+
+ if (action_id == NULL || resource_type == NULL || resource_id == NULL) {
+ usage (argc, argv);
+ goto error;
+ }
+
+ ud.loop = g_main_loop_new (NULL, TRUE);
+
+ dbus_error_init (&error);
+ bus = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
+ if (bus == NULL) {
+ fprintf (stderr, "error: dbus_bus_get(): %s: %s\n", error.name, error.message);
+ goto error;
+ }
+
+ p_error = NULL;
+ pol_ctx = libpolkit_context_new ();
+ if (!libpolkit_context_init (pol_ctx, &p_error)) {
+ fprintf (stderr, "error: libpolkit_context_init: %s\n", polkit_error_get_error_message (p_error));
+ polkit_error_free (p_error);
+ goto error;
+ }
+
+ action = libpolkit_action_new ();
+ libpolkit_action_set_action_id (action, action_id);
+
+ resource = libpolkit_resource_new ();
+ libpolkit_resource_set_resource_type (resource, resource_type);
+ libpolkit_resource_set_resource_id (resource, resource_id);
+
+ caller = libpolkit_caller_new_from_dbus_name (bus, dbus_bus_get_unique_name (bus), &error);
+ if (caller == NULL) {
+ if (dbus_error_is_set (&error)) {
+ fprintf (stderr, "error: libpolkit_caller_new_from_dbus_name(): %s: %s\n",
+ error.name, error.message);
+ goto error;
+ }
+ }
+
+ polkit_grant = libpolkit_grant_new ();
+ libpolkit_grant_set_functions (polkit_grant,
+ add_io_watch,
+ add_child_watch,
+ remove_watch,
+ conversation_type,
+ conversation_pam_prompt_echo_off,
+ conversation_pam_prompt_echo_on,
+ conversation_pam_error_msg,
+ conversation_pam_text_info,
+ conversation_override_grant_type,
+ conversation_done,
+ &ud);
+
+ if (!libpolkit_grant_initiate_auth (polkit_grant,
+ action,
+ resource,
+ caller)) {
+ printf ("Failed to initiate privilege grant.\n");
+ ret = 1;
+ goto error;
+ }
+ g_main_loop_run (ud.loop);
+ libpolkit_grant_unref (polkit_grant);
+
+ printf ("Privilege grant done.. result=%d\n", ud.gained_privilege);
+
+ ret = ud.gained_privilege ? 0 : 1;
+
+error:
+ return ret;
+}
diff --git a/tools/polkit-policy-file-validate.c b/tools/polkit-policy-file-validate.c
index 604d7c4..3d2353d 100644
--- a/tools/polkit-policy-file-validate.c
+++ b/tools/polkit-policy-file-validate.c
@@ -36,7 +36,7 @@
#include <unistd.h>
#include <errno.h>
-#include <libpolkit/libpolkit-policy-file.h>
+#include <libpolkit/libpolkit.h>
static void
usage (int argc, char *argv[])
More information about the hal-commit
mailing list