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