hal: Branch 'master'

David Zeuthen david at kemper.freedesktop.org
Fri Apr 6 13:27:19 PDT 2007


 configure.in                                                 |   41 +-
 doc/man/Makefile.am                                          |    6 
 doc/man/hal-is-caller-privileged.1.in                        |   70 +++
 doc/spec/hal-spec-interfaces.xml                             |   32 +
 doc/spec/hal-spec-properties.xml                             |   61 ++-
 fdi/policy/10osvendor/20-acl-management.fdi                  |   22 -
 hald/Makefile.am                                             |    5 
 hald/access-check.c                                          |  193 ++++++++-
 hald/access-check.h                                          |    3 
 hald/ci-tracker.c                                            |   44 ++
 hald/ci-tracker.h                                            |    1 
 hald/ck-tracker.c                                            |   16 
 hald/ck-tracker.h                                            |    2 
 hald/device.c                                                |    8 
 hald/device.h                                                |    2 
 hald/hald.c                                                  |   12 
 hald/hald.h                                                  |    8 
 hald/hald_dbus.c                                             |  204 ++++++++--
 hald/hald_runner.c                                           |   65 ++-
 hald/linux/addons/addon-cpufreq.c                            |  115 +----
 hald/linux/addons/addon-dell-backlight.cpp                   |   56 ++
 hald/linux/addons/addon-macbook-backlight.c                  |   57 ++
 hald/linux/addons/addon-macbookpro-backlight.c               |   69 +++
 hald/linux/addons/addon-omap-backlight.c                     |   57 ++
 hald/run-hald.sh                                             |    3 
 libhal/libhal.c                                              |  219 +++++++----
 libhal/libhal.h                                              |    7 
 privileges/Makefile.am                                       |   31 +
 privileges/hal-device-file.priv                              |   70 +++
 privileges/hal-killswitch.priv                               |   28 +
 privileges/hal-power-cpufreq.privilege                       |   12 
 privileges/hal-power-hibernate.privilege                     |   11 
 privileges/hal-power-poweroff.privilege                      |   11 
 privileges/hal-power-reboot.privilege                        |   12 
 privileges/hal-power-suspend.privilege                       |   12 
 privileges/hal-power.priv                                    |   91 ++++
 privileges/hal-storage-fixed-mount-all-options.privilege     |   14 
 privileges/hal-storage-fixed-mount.privilege                 |   16 
 privileges/hal-storage-removable-mount-all-options.privilege |   14 
 privileges/hal-storage-removable-mount.privilege             |   15 
 privileges/hal-storage.priv                                  |   49 ++
 tools/Makefile.am                                            |   14 
 tools/hal-acl-tool.c                                         |  129 ++++--
 tools/hal-functions                                          |   50 ++
 tools/hal-is-caller-privileged.c                             |  181 +++++++++
 tools/hal-luks-setup                                         |   12 
 tools/hal-luks-teardown                                      |   11 
 tools/hal-storage-closetray.c                                |   16 
 tools/hal-storage-eject.c                                    |   19 
 tools/hal-storage-mount.c                                    |   64 ---
 tools/hal-storage-shared.c                                   |   64 ++-
 tools/hal-storage-shared.h                                   |    9 
 tools/hal-storage-unmount.c                                  |   19 
 tools/hal-system-killswitch-get-power                        |   13 
 tools/hal-system-killswitch-set-power                        |   15 
 tools/hal-system-lcd-get-brightness                          |   13 
 tools/hal-system-lcd-set-brightness                          |   13 
 tools/hal-system-power-hibernate                             |   24 -
 tools/hal-system-power-reboot                                |   25 -
 tools/hal-system-power-set-power-save                        |   16 
 tools/hal-system-power-shutdown                              |   25 -
 tools/hal-system-power-suspend                               |   24 -
 tools/hal-system-power-suspend-hybrid                        |   56 --
 tools/linux/Makefile.am                                      |    1 
 tools/linux/hal-system-power-hibernate-linux                 |    3 
 tools/linux/hal-system-power-reboot-linux                    |    3 
 tools/linux/hal-system-power-shutdown-linux                  |    3 
 tools/linux/hal-system-power-suspend-hybrid-linux            |   41 ++
 tools/linux/hal-system-power-suspend-linux                   |   15 
 69 files changed, 1907 insertions(+), 735 deletions(-)

New commits:
diff-tree 9893a20754f96c0091f6db169398ebcda7e82e07 (from 6538c9f78e2a3ef499c10923ecdee777d31e1fd3)
Author: David Zeuthen <davidz at redhat.com>
Date:   Fri Apr 6 16:27:06 2007 -0400

    port HAL over to use PolicyKit master
    
    In the process, include hal-functions and make out shell-script based
    method handlers share that.

diff --git a/configure.in b/configure.in
index bd4de78..aaf95c7 100644
--- a/configure.in
+++ b/configure.in
@@ -408,31 +408,39 @@ AC_SUBST(HALD_BACKEND)
 dnl DBUS API is subject to changes
 AC_DEFINE_UNQUOTED(DBUS_API_SUBJECT_TO_CHANGE, ,DBUS API is subject to change)
 
+# check for ConsoleKit
+AM_CONDITIONAL(HAVE_CONKIT, false)
+AC_ARG_ENABLE(console-kit, [  --enable-console-kit    Use ConsoleKit],enable_console_kit=$enableval,enable_console_kit=no)
+msg_conkit=no
+if test "x$enable_console_kit" != "xno"; then
+   AM_CONDITIONAL(HAVE_CONKIT, true)
+   AC_DEFINE(HAVE_CONKIT, [], [Set if we use ConsoleKit])
+   msg_conkit=yes
+fi
+
 # check for PolicyKit
 AM_CONDITIONAL(HAVE_POLKIT, false)
 AC_ARG_ENABLE(policy-kit, [  --enable-policy-kit     Use PolicyKit],enable_policy_kit=$enableval,enable_policy_kit=no)
 msg_polkit=no
 if test "x$enable_policy_kit" != "xno"; then
-	PKG_CHECK_MODULES(POLKIT, polkit >= 0.2,
+   if test "x$enable_console_kit" = "xno"; then
+      AC_MSG_ERROR([PolicyKit support requires building with ConsoleKit support too])
+   fi
+   PKG_CHECK_MODULES(POLKIT, libpolkit >= 0.3,
 		  	[AM_CONDITIONAL(HAVE_POLKIT, true)
 		   	AC_DEFINE(HAVE_POLKIT, [], [Set if we use PolicyKit])]
                         msg_polkit=yes,
 	          	[AM_CONDITIONAL(HAVE_POLKIT, false)])
-	AC_SUBST(POLKIT_CFLAGS)
-	AC_SUBST(POLKIT_LIBS)
-	if test "x$msg_polkit" != "xyes"; then
-	   AC_MSG_ERROR([PolicyKit not explicitly disabled and no PolicyKit found])
-	fi
-fi
+   AC_SUBST(POLKIT_CFLAGS)
+   AC_SUBST(POLKIT_LIBS)
+   if test "x$msg_polkit" != "xyes"; then
+      AC_MSG_ERROR([PolicyKit not explicitly disabled and no PolicyKit found])
+   fi
 
-# check for ConsoleKit
-AM_CONDITIONAL(HAVE_CONKIT, false)
-AC_ARG_ENABLE(console-kit, [  --enable-console-kit    Use ConsoleKit],enable_console_kit=$enableval,enable_console_kit=no)
-msg_conkit=no
-if test "x$enable_console_kit" != "xno"; then
-   AM_CONDITIONAL(HAVE_CONKIT, true)
-   AC_DEFINE(HAVE_CONKIT, [], [Set if we use ConsoleKit])
-   msg_conkit=yes
+   AC_CHECK_PROG(POLKIT_PRIVILEGE_FILE_VALIDATE, polkit-privilege-file-validate, polkit-privilege-file-validate)
+   if test -z "$POLKIT_PRIVILEGE_FILE_VALIDATE"; then
+      AC_MSG_ERROR([polkit-privilege-file-validate not found])
+   fi
 fi
 
 # check for ACL handling
@@ -440,6 +448,9 @@ AM_CONDITIONAL(HAVE_ACLMGMT, false)
 AC_ARG_ENABLE(acl-management, [  --enable-acl-management ACL management],enable_acl_management=$enableval,enable_acl_management=no)
 msg_aclmgmt=no
 if test "x$enable_acl_management" != "xno"; then
+   if test "x$enable_policy_kit" = "xno"; then
+      AC_MSG_ERROR([ACL management support requires building with PolicyKit support])
+   fi
    AM_CONDITIONAL(HAVE_ACLMGMT, true)
    AC_DEFINE(HAVE_ACLMGMT, [], [Set if we manage ACL's])
    msg_aclmgmt=yes
diff --git a/doc/man/Makefile.am b/doc/man/Makefile.am
index c54c16b..49f6de9 100644
--- a/doc/man/Makefile.am
+++ b/doc/man/Makefile.am
@@ -1,7 +1,11 @@
 
 if MAN_PAGES_ENABLED
 
-MAN_IN_FILES = hald.8.in lshal.1.in hal-get-property.1.in hal-set-property.1.in hal-find-by-property.1.in hal-find-by-capability.1.in hal-is-caller-locked-out.1.in hal-lock.1.in hal-disable-polling.1.in
+MAN_IN_FILES = hald.8.in lshal.1.in hal-get-property.1.in hal-set-property.1.in hal-find-by-property.1.in hal-find-by-capability.1.in hal-is-caller-locked-out.1.in hal-lock.1.in hal-disable-polling.1.in 
+
+if HAVE_POLKIT
+MAN_IN_FILES += hal-is-caller-privileged.1.in
+endif
 
 man_MANS = $(MAN_IN_FILES:.in=)
 
diff --git a/doc/man/hal-is-caller-privileged.1.in b/doc/man/hal-is-caller-privileged.1.in
new file mode 100644
index 0000000..9dd9f22
--- /dev/null
+++ b/doc/man/hal-is-caller-privileged.1.in
@@ -0,0 +1,70 @@
+.\" 
+.\" hal-is-caller-privileged manual page.
+.\" Copyright (C) 2007 David Zeuthen <david at fubar.dk>
+.\"
+.TH HAL-IS-CALLER-PRIVILEGED 1
+.SH NAME
+hal-is-caller-privileged \- determine if a caller is privileged
+.SH SYNOPSIS
+.PP
+.B hal-is-caller-privileged
+[options]
+
+.SH DESCRIPTION
+
+\fIhal-is-caller-privileged\fP determines if a specific caller has
+a given 
+.B PolicyKit
+privilege on given device. For
+more information about both the big picture,
+.B HAL
+and
+.B PolicyKit
+, refer to the \fIHAL spec\fP  (which can be found in 
+.I @docdir@/spec/hal-spec.html
+depending on the distribution) and also the 
+.B PolicyKit
+documentation.
+
+.SH OPTIONS
+The following options are supported:
+.TP
+.I "--udi"
+The UDI (\fIUnique Device Identifier\fP) of the device object.
+.TP
+.I "--privilege"
+The name of the privilege to check for.
+.TP
+.I "--caller"
+The unique D-Bus name on the system bus of the caller.
+.TP
+.I "--help"
+Print out usage.
+.TP
+.I "--version"
+Print the version.
+
+.SH RETURN VALUE
+.PP
+If an error occurs this program exits with a non-zero exit
+code. Otherwise the textual reply will be printed on stdout and this
+program will exit with exit code 0. Unprivileged callers (e.g. with a
+non-zero uid) can only ask about callers/processes that matches their
+own uid.
+
+.SH BUGS
+.PP
+Please send bug reports to either the distribution or the HAL
+mailing list, see 
+.I "http://lists.freedesktop.org/mailman/listinfo/hal"
+on how to subscribe.
+
+.SH SEE ALSO
+.PP
+\&\fIhald\fR\|(8), 
+\&\fIpolkit-check-caller\fR\|(1)
+
+.SH AUTHOR
+Written by David Zeuthen <david at fubar.dk> with a lot of help from many
+others.
+
diff --git a/doc/spec/hal-spec-interfaces.xml b/doc/spec/hal-spec-interfaces.xml
index a4746ca..eb21e6c 100644
--- a/doc/spec/hal-spec-interfaces.xml
+++ b/doc/spec/hal-spec-interfaces.xml
@@ -446,6 +446,38 @@ $ dbus-send --system --print-reply --des
             </entry>
           </row>
           <row>
+            <entry>IsCallerPrivileged</entry>
+            <entry>String</entry>
+            <entry>String privilege, String caller_unique_name</entry>
+            <entry>PermissionDenied, Error</entry>
+            <entry>
+              <para>
+                Determines whether a given process on the system
+                message bus is authorized according to PolicyKit on a
+                specific device for a specific PolicyKit
+                privilege. Unprivileged callers (e.g. with a non-zero
+                uid) can only ask
+                about <literal>caller_unique_name</literal> that
+                matches their own uid; if this is violated
+                <literal>PermissionDenied</literal> will be
+                thrown. This can be used ahead of time to see if a
+                given call will succeed or if it requires privilege
+                elevation (TODO: clarify this once PolicyKit can auth
+                over D-Bus).
+              </para>
+              <para>
+                Returns the textual representation of a PolKitResult
+                value on success. 
+              </para>
+              <para>
+                If HAL is not built with PolicyKit support, this
+                method always throws
+                the <literal>org.freedesktop.Hal.Device.Error</literal>
+                exception.
+              </para>
+            </entry>
+          </row>
+          <row>
             <entry>IsLockedByOthers</entry>
             <entry>Bool</entry>
             <entry>String interface_name</entry>
diff --git a/doc/spec/hal-spec-properties.xml b/doc/spec/hal-spec-properties.xml
index 36e4283..c4101ef 100644
--- a/doc/spec/hal-spec-properties.xml
+++ b/doc/spec/hal-spec-properties.xml
@@ -240,13 +240,42 @@
         
       <para>
         If ConsoleKit support is enabled, the variables
+        <literal>CK_NUM_SEATS</literal> (number of seats),        
+        <literal>CK_NUM_SESSIONS</literal> (number of sessions),        
         <literal>CK_SEATS</literal> (tab sep. list of seat-id's),
         <literal>CK_SEAT_seat-id</literal> (tab sep. list of session-id's for a seat),
+        <literal>CK_SEAT_NUM_SESSIONS_seat-id</literal> (number of sessions on a seat),        
+        <literal>CK_SESSION_SEAT_session-id</literal> (the seat that a session belongs to) and
         <literal>CK_SESSION_IS_ACTIVE_session-id</literal> (whether a given session is active) and
-        <literal>CK_SESSION_UID_session-id</literal> (the user of the session)
+        <literal>CK_SESSION_UID_session-id</literal> (the user of the session) and
         <literal>CK_SESSION_IS_LOCAL_session-id</literal> (whether a session is local),
-        will be exported as well.
+        <literal>CK_SESSION_HOSTNAME_session-id</literal> (host name of session's display if it's not local),
+        will be exported as well. Example:
       </para>
+
+      <programlisting>
+CK_NUM_SEATS=1
+CK_NUM_SESSIONS=2
+CK_SEATS=Seat1
+CK_SEAT_Seat1=Session1  Session3
+CK_SEAT_NUM_SESSIONS_Seat1=2
+CK_SESSION_IS_ACTIVE_Session1=true
+CK_SESSION_IS_ACTIVE_Session3=false
+CK_SESSION_IS_LOCAL_Session1=true
+CK_SESSION_IS_LOCAL_Session3=true
+CK_SESSION_SEAT_Session1=Seat1
+CK_SESSION_SEAT_Session3=Seat1
+CK_SESSION_UID_Session1=500
+CK_SESSION_UID_Session3=501
+      </programlisting>
+      
+      <para>
+        Note that all ConsoleKit object paths given are just base
+        names; the real D-Bus object path can be reconstructed by
+        appending <literal>/org/freedesktop/ConsoleKit/</literal>
+        prepended to the given identifer.
+      </para>
+
       <para>
         The HAL daemon is not suspended while callouts are executing. Thus,
         callouts can communicate with the HAL daemon using the D-BUS network
@@ -442,10 +471,32 @@
         and
         <literal>HAL_METHOD_INVOKED_BY_SYSTEMBUS_CONNECTION_NAME</literal>
         (the unique system bus connection name of the caller) are
-        set (If HAL, or a HAL addon, is invoking a method, then these
-        variables will both assume the value 0.)
+        set. Additionally, if HAL is built with ConsoleKit support, 
+        <literal>HAL_METHOD_INVOKED_BY_PID</literal> and
+        <literal>HAL_METHOD_INVOKED_BY_SELINUX_CONTEXT</literal> (but
+        only if the running system have SELinux enabled) will be
+        set. If HAL itself, or a HAL addon, is invoking a method, then
+        these variables will not be present. Here's an example
       </para>
-      
+
+      <programlisting>
+HAL_METHOD_INVOKED_BY_UID=500
+HAL_METHOD_INVOKED_BY_PID=22553
+HAL_METHOD_INVOKED_BY_SELINUX_CONTEXT=user_u:system_r:unconfined_t
+HAL_METHOD_INVOKED_BY_SYSTEMBUS_CONNECTION_NAME=:1.138
+      </programlisting>
+
+      <para>
+        In addition, with ConsoleKit
+        support, <literal>HAL_METHOD_INVOKED_BY_SESSION</literal> will
+        be set to (the basename) of the ConsoleKit session object path
+        but only if the caller is in a session. The method handler can
+        then use the previously
+        mentioned <literal>CK_SESSION_*</literal> to learn everything
+        about the context of the caller.
+        
+      </para>
+
       <informaltable>
         <tgroup cols="2">
           <thead>
diff --git a/fdi/policy/10osvendor/20-acl-management.fdi b/fdi/policy/10osvendor/20-acl-management.fdi
index 74665d4..28b3101 100644
--- a/fdi/policy/10osvendor/20-acl-management.fdi
+++ b/fdi/policy/10osvendor/20-acl-management.fdi
@@ -3,6 +3,7 @@
 <deviceinfo version="0.2">
   <device>
 
+    <!-- NOTE: if you add a new access.type value, remember to update privileges/hal-device-files.priv -->
 
     <!-- classification of devices where access can be controlled goes here -->
 
@@ -10,30 +11,35 @@
     <match key="info.capabilities" contains="alsa">
       <append key="info.capabilities" type="strlist">access_control</append>
       <merge key="access_control.file" type="copy_property">alsa.device_file</merge>
+      <merge key="access_control.type" type="string">sound</merge>
     </match>
 
     <!-- sound card (OSS) -->
     <match key="info.capabilities" contains="oss">
       <append key="info.capabilities" type="strlist">access_control</append>
       <merge key="access_control.file" type="copy_property">oss.device_file</merge>
+      <merge key="access_control.type" type="string">sound</merge>
     </match>
 
     <!-- video4linux devices -->
     <match key="info.capabilities" contains="video4linux">
       <append key="info.capabilities" type="strlist">access_control</append>
       <merge key="access_control.file" type="copy_property">video4linux.device</merge>
+      <merge key="access_control.type" type="string">video4linux</merge>
     </match>
 
     <!-- optical drives -->
     <match key="info.capabilities" contains="storage.cdrom">
       <append key="info.capabilities" type="strlist">access_control</append>
       <merge key="access_control.file" type="copy_property">block.device</merge>
+      <merge key="access_control.type" type="string">cdrom</merge>
     </match>
 
     <!-- DVB cards -->
     <match key="info.capabilities" contains="dvb">
       <append key="info.capabilities" type="strlist">access_control</append>
       <merge key="access_control.file" type="copy_property">dvb.device</merge>
+      <merge key="access_control.type" type="string">dvb</merge>
     </match>
 
     <!-- usb cameras -->
@@ -41,6 +47,7 @@
       <match key="info.capabilities" sibling_contains="camera">
 	<append key="info.capabilities" type="strlist">access_control</append>
 	<merge key="access_control.file" type="copy_property">usbraw.device</merge>
+        <merge key="access_control.type" type="string">camera</merge>
       </match>
     </match>
 
@@ -49,6 +56,7 @@
       <match key="info.capabilities" sibling_contains="scanner">
 	<append key="info.capabilities" type="strlist">access_control</append>
 	<merge key="access_control.file" type="copy_property">usbraw.device</merge>
+      <merge key="access_control.type" type="string">scanner</merge>
       </match>
     </match>
 
@@ -56,24 +64,14 @@
     <match key="info.capabilities" contains="ieee1394_unit.iidc">
       <append key="info.capabilities" type="strlist">access_control</append>
       <merge key="access_control.file" type="copy_property">@ieee1394_unit.originating_device:ieee1394.device</merge>
+      <merge key="access_control.type" type="string">ieee1394-iidc</merge>
     </match>
     <match key="info.capabilities" contains="ieee1394_unit.avc">
       <append key="info.capabilities" type="strlist">access_control</append>
       <merge key="access_control.file" type="copy_property">@ieee1394_unit.originating_device:ieee1394.device</merge>
+      <merge key="access_control.type" type="string">ieee1394-avc</merge>
     </match>
 
-    <!-- policy goes here - this can be amended by 3rd party packages,
-         e.g.  the flumotion package may provide a fdi-file that
-         appends the 'flumotion' user to access_control.grant_user for
-         e.g. webcam's or audio devices - see RH bug #140853 for
-         details. -->
-
-    <!-- grant access to local session whether it's active or not -->
-    <match key="info.capabilities" contains="access_control">
-      <merge key="access_control.grant_local_session" type="bool">true</merge>
-    </match>
-
-
     <!-- enforcement of policy goes here -->
 
     <!-- add / remove ACL's when devices are added and removed -->
diff --git a/hald/Makefile.am b/hald/Makefile.am
index 74647d1..47d9b44 100644
--- a/hald/Makefile.am
+++ b/hald/Makefile.am
@@ -15,7 +15,7 @@ INCLUDES = \
 	-DPCI_IDS_DIR=\""$(PCI_IDS_DIR)"\" \
 	-DUSB_IDS_DIR=\""$(USB_IDS_DIR)"\" \
 	-I$(top_srcdir) \
-	@GLIB_CFLAGS@ @DBUS_CFLAGS@
+	@GLIB_CFLAGS@ @DBUS_CFLAGS@ @POLKIT_CFLAGS@
 
 ## check_PROGRAMS = hald-test
 
@@ -72,8 +72,7 @@ if HAVE_CONKIT
 hald_SOURCES += ck-tracker.h ck-tracker.c
 endif
 
-
-hald_LDADD = @GLIB_LIBS@ @DBUS_LIBS@ -lm @HALD_OS_LIBS@ $(top_builddir)/hald/$(HALD_BACKEND)/libhald_$(HALD_BACKEND).la
+hald_LDADD = @GLIB_LIBS@ @DBUS_LIBS@ @POLKIT_LIBS@ -lm @HALD_OS_LIBS@ $(top_builddir)/hald/$(HALD_BACKEND)/libhald_$(HALD_BACKEND).la
 
 #### Init scripts fun
 SCRIPT_IN_FILES=haldaemon.in
diff --git a/hald/access-check.c b/hald/access-check.c
index a17d34f..d0e4018 100644
--- a/hald/access-check.c
+++ b/hald/access-check.c
@@ -38,7 +38,12 @@
 #include <dbus/dbus.h>
 #include <glib.h>
 
+#ifdef HAVE_POLKIT
+#include <libpolkit/libpolkit.h>
+#endif
+
 #include "hald.h"
+#include "hald_dbus.h"
 #include "logger.h"
 #include "access-check.h"
 
@@ -106,14 +111,102 @@ out:
 	return ret;
 }
 
+#ifdef HAVE_POLKIT
+static PolKitSeat *
+get_pk_seat_from_ck_seat (CKSeat *seat)
+{
+        PolKitSeat *pk_seat;
+        pk_seat = libpolkit_seat_new ();
+        libpolkit_seat_set_ck_objref (pk_seat, ck_seat_get_id (seat));
+        return pk_seat;
+}
+
+static PolKitSession *
+get_pk_session_from_ck_session (CKSession *session)
+{
+        CKSeat *seat;
+        PolKitSeat *pk_seat;
+        PolKitSession *pk_session;
+
+        seat = ck_session_get_seat (session);
+        if (seat == NULL) {
+                pk_seat = NULL;
+        } else {
+                pk_seat = get_pk_seat_from_ck_seat (seat);
+        }
+
+        pk_session = libpolkit_session_new ();
+        if (pk_seat != NULL) {
+                libpolkit_session_set_seat (pk_session, pk_seat);
+                libpolkit_seat_unref (pk_seat);
+        }
+        libpolkit_session_set_ck_objref (pk_session, ck_session_get_id (session));
+        libpolkit_session_set_uid (pk_session, ck_session_get_user (session));
+        libpolkit_session_set_ck_is_active (pk_session, ck_session_is_active (session));
+        libpolkit_session_set_ck_is_local (pk_session, ck_session_is_local (session));
+        if (!ck_session_is_local (session)) {
+                libpolkit_session_set_ck_remote_host (pk_session, ck_session_get_hostname (session));
+        }
+        return pk_session;
+}
+
+static PolKitCaller *
+get_pk_caller_from_ci_tracker (CITracker *cit, const char *caller_unique_sysbus_name)
+{
+        CICallerInfo *ci;
+        PolKitSession *pk_session;
+        PolKitCaller *pk_caller;
+        const char *ck_session_objpath;
+        
+        pk_caller = NULL;
+
+        ci = ci_tracker_get_info (cit, caller_unique_sysbus_name);
+        if (ci == NULL) {
+                HAL_ERROR (("Cannot get caller info for %s", caller_unique_sysbus_name));
+                goto out;
+        }
+        
+        ck_session_objpath = ci_tracker_caller_get_ck_session_path (ci);
+        if (ck_session_objpath == NULL) {
+                pk_session = NULL;
+        } else {
+                CKSession *session;
+                
+                session = ck_tracker_find_session (hald_dbus_get_ck_tracker (), ck_session_objpath);
+                if (session == NULL) {
+                        /* this should never happen */
+                        HAL_ERROR (("ck_session_objpath is not NULL, but CKTracker don't know about the session!"));
+                        goto out;
+                }
+                
+                pk_session = get_pk_session_from_ck_session (session);
+        }
+
+        pk_caller = libpolkit_caller_new ();
+        libpolkit_caller_set_dbus_name (pk_caller, caller_unique_sysbus_name);
+        libpolkit_caller_set_uid (pk_caller, ci_tracker_caller_get_uid (ci));
+        libpolkit_caller_set_pid (pk_caller, ci_tracker_caller_get_pid (ci));
+        libpolkit_caller_set_selinux_context (pk_caller, ci_tracker_caller_get_selinux_context (ci));
+        if (pk_session != NULL) {
+                libpolkit_caller_set_ck_session (pk_caller, pk_session);
+                libpolkit_session_unref (pk_session);
+        }
+
+out:
+        return pk_caller;
+}
+#endif
+
 /**
  * access_check_caller_have_access_to_device:
  * @cit: the CITracker object
- * @device: The device to check for
- * @privilege: the type of access; right now this can be #NULL or
- * "lock"; will be replaced by PolicyKit privileges in the future
+ * @device: the device to check for
+ * @privilege: the PolicyKit privilege to check for
  * @caller_unique_sysbus_name: The unique system bus connection
  * name (e.g. ":1.43") of the caller
+ * @polkit_result_out: where to store the #PolicyKitResult return 
+ * code. Will be ignored if HAL is not built with PolicyKit support
+ * or if it's #NULL.
  *
  * Determine if a given caller should have access to a device. This
  * depends on how the security is set up and may change according to
@@ -145,11 +238,21 @@ out:
  * Returns: TRUE iff the caller have access to the device.
  */
 gboolean
-access_check_caller_have_access_to_device (CITracker *cit, HalDevice *device, const char *privilege, const char *caller_unique_sysbus_name)
+access_check_caller_have_access_to_device (CITracker *cit, 
+                                           HalDevice *device, 
+                                           const char *privilege, 
+                                           const char *caller_unique_sysbus_name,
+                                           int        *polkit_result_out)
 #ifdef HAVE_CONKIT
 {
         gboolean ret;
         CICallerInfo *ci;
+#ifdef HAVE_POLKIT
+        PolKitCaller *pk_caller = NULL;
+        PolKitResource *pk_resource = NULL;
+        PolKitPrivilege *pk_privilege = NULL;
+        PolKitResult pk_result;
+#endif
 
         ret = FALSE;
 
@@ -159,35 +262,80 @@ access_check_caller_have_access_to_devic
                 goto out;
         }
 
+        /* HAL user and uid 0 are always allowed
+         * (TODO: is this sane? probably needs to go through PolicyKit too..) 
+         */
         if (ci_tracker_caller_get_uid (ci) == 0 ||
             ci_tracker_caller_get_uid (ci) == geteuid ()) {
                 ret = TRUE;
+#ifdef HAVE_POLKIT
+                if (polkit_result_out != NULL)
+                        *polkit_result_out = LIBPOLKIT_RESULT_YES;
+#endif
                 goto out;
         }
 
-        /* must be tracked by ConsoleKit */
-        if (ci_tracker_caller_get_ck_session_path (ci) == NULL) {
+        /* allow inactive sessions to lock interfaces on root computer device object 
+         * (TODO FIXME: restrict to local sessions?)
+         */
+        if (privilege != NULL && 
+            g_str_has_prefix (privilege, "hal-lock") && 
+            strcmp (hal_device_get_udi (device), "/org/freedesktop/Hal/devices/computer") == 0) {
+                ret = TRUE;
+#ifdef HAVE_POLKIT
+                if (polkit_result_out != NULL)
+                        *polkit_result_out = LIBPOLKIT_RESULT_YES;
+#endif
                 goto out;
         }
 
-        /* require caller to be local */
-        if (!ci_tracker_caller_is_local (ci))
+#ifdef HAVE_POLKIT
+        pk_caller = get_pk_caller_from_ci_tracker (cit, caller_unique_sysbus_name);
+        if (pk_caller == NULL)
                 goto out;
 
-        /* allow inactive sessions to lock interfaces on root computer device object */
-        if (privilege != NULL && 
-            strcmp (privilege, "lock") == 0 && 
-            strcmp (hal_device_get_udi (device), "/org/freedesktop/Hal/devices/computer") == 0) {
-                ret = TRUE;
+        pk_resource = libpolkit_resource_new ();
+        libpolkit_resource_set_resource_type (pk_resource, "hal");
+        libpolkit_resource_set_resource_id (pk_resource, hal_device_get_udi (device));
+
+        pk_privilege = libpolkit_privilege_new ();
+        libpolkit_privilege_set_privilege_id (pk_privilege, privilege);
+
+        pk_result = libpolkit_can_caller_access_resource (pk_context,
+                                                          pk_privilege,
+                                                          pk_resource,
+                                                          pk_caller);
+
+        if (polkit_result_out != NULL)
+                *polkit_result_out = pk_result;
+
+        if (pk_result != LIBPOLKIT_RESULT_YES)
+                goto out;
+#else
+        /* must be tracked by ConsoleKit */
+        if (ci_tracker_caller_get_ck_session_path (ci) == NULL) {
                 goto out;
         }
         
+        /* require caller to be local */
+        if (!ci_tracker_caller_is_local (ci))
+                goto out;
+        
         /* require caller to be in active session */
         if (!ci_tracker_caller_in_active_session (ci))
-                goto out;
+                        goto out;
+#endif
                 
         ret = TRUE;
 out:
+#ifdef HAVE_POLKIT
+        if (pk_caller != NULL)
+                libpolkit_caller_unref (pk_caller);
+        if (pk_resource != NULL)
+                libpolkit_resource_unref (pk_resource);
+        if (pk_privilege != NULL)
+                libpolkit_privilege_unref (pk_privilege);
+#endif
         return ret;
 }
 #else /* HAVE_CONKIT */
@@ -239,6 +387,9 @@ access_check_caller_locked_out (CITracke
         HalDevice *computer;
         gboolean is_locked;
         gboolean is_locked_by_self;
+        char *priv;
+
+        priv = g_strdup_printf ("hal-lock:%s", interface_name);
 
         global_lock_name = NULL;
         holders = NULL;
@@ -278,7 +429,8 @@ access_check_caller_locked_out (CITracke
                 for (n = 0; global_holders[n] != NULL; n++) {
                         if (strcmp (global_holders[n], caller_unique_sysbus_name) == 0) {
                                 /* we are holding the global lock... */
-                                if (access_check_caller_have_access_to_device (cit, device, NULL, global_holders[n])) {
+                                if (access_check_caller_have_access_to_device (
+                                            cit, device, priv, global_holders[n], NULL)) {
                                         /* only applies if the caller can access the device... */
                                         is_locked_by_self = TRUE;
                                         /* this is good enough; we are holding the lock ourselves */
@@ -289,7 +441,8 @@ access_check_caller_locked_out (CITracke
                                 /* Someone else is holding the global lock.. check if that someone
                                  * actually have access to the device...
                                  */
-                                if (access_check_caller_have_access_to_device (cit, device, NULL, global_holders[n])) {
+                                if (access_check_caller_have_access_to_device (
+                                            cit, device, priv, global_holders[n], NULL)) {
                                         /* They certainly do. Mark as locked. */
                                         is_locked = TRUE;
                                 }
@@ -314,6 +467,7 @@ out:
         g_strfreev (global_holders);
         g_strfreev (holders);
         g_free (global_lock_name);
+        g_free (priv);
         return ret;
 }
 
@@ -343,6 +497,9 @@ access_check_locked_by_others (CITracker
         char **holders;
         char **global_holders;
         HalDevice *computer;
+        char *priv;
+
+        priv = g_strdup_printf ("hal-lock:%s", interface_name);
 
         global_lock_name = NULL;
         holders = NULL;
@@ -375,7 +532,8 @@ access_check_locked_by_others (CITracker
                         if (caller_unique_sysbus_name == NULL || /* <-- callers using direct connection to hald */
                             strcmp (global_holders[n], caller_unique_sysbus_name) != 0) {
                                 /* someone else is holding the global lock... */
-                                if (access_check_caller_have_access_to_device (cit, device, NULL, global_holders[n])) {
+                                if (access_check_caller_have_access_to_device (
+                                            cit, device, priv, global_holders[n], NULL)) {
                                         /* ... and they can can access the device */
                                         goto out;
                                 }
@@ -390,6 +548,7 @@ out:
         g_strfreev (global_holders);
         g_strfreev (holders);
         g_free (global_lock_name);
+        g_free (priv);
         return ret;
 }
 
diff --git a/hald/access-check.h b/hald/access-check.h
index 3da49ed..2f3c34a 100644
--- a/hald/access-check.h
+++ b/hald/access-check.h
@@ -36,7 +36,8 @@ gboolean access_check_message_caller_is_
 gboolean access_check_caller_have_access_to_device  (CITracker   *cit,
                                                      HalDevice   *device,
                                                      const char  *privilege,
-                                                     const char  *caller_unique_sysbus_name);
+                                                     const char  *caller_unique_sysbus_name,
+                                                     int         *polkit_result_out);
 gboolean access_check_caller_locked_out             (CITracker   *cit,
                                                      HalDevice   *device,
                                                      const char  *caller_unique_sysbus_name,
diff --git a/hald/ci-tracker.c b/hald/ci-tracker.c
index af83654..43dc12c 100644
--- a/hald/ci-tracker.c
+++ b/hald/ci-tracker.c
@@ -54,6 +54,7 @@ struct CICallerInfo_s {
 	gboolean in_active_session;   /* caller is in an active session */
         gboolean is_local;            /* session is on a local seat */
 	char *session_objpath;        /* obj path of ConsoleKit session */
+        char *selinux_context;        /* SELinux security context */
 #endif
 	char *system_bus_unique_name; /* unique name of caller on the system bus */
 };
@@ -73,6 +74,7 @@ caller_info_free (CICallerInfo *ci)
 	g_free (ci->session_objpath);
 #endif
 	g_free (ci->system_bus_unique_name);
+        g_free (ci->selinux_context);
 	g_free (ci);
 }
 
@@ -172,7 +174,10 @@ ci_tracker_get_info (CITracker *cit, con
 	DBusMessage *message;
 	DBusMessage *reply;
 	DBusMessageIter iter;
+	DBusMessageIter sub_iter;
 	char *dbus_session_name;
+        char *str;
+        int num_elems;
 #endif /* HAVE_CONKIT */
 	
 	ci = NULL;
@@ -223,6 +228,38 @@ ci_tracker_get_info (CITracker *cit, con
 	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, &system_bus_unique_name);
+	reply = dbus_connection_send_with_reply_and_block (cit->dbus_connection, 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 error;
+        } 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)
+                        ci->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",
@@ -347,4 +384,11 @@ ci_tracker_caller_get_ck_session_path (C
 {
         return ci->session_objpath;
 }
+
+const char *
+ci_tracker_caller_get_selinux_context (CICallerInfo *ci)
+{
+        return ci->selinux_context;
+}
+
 #endif
diff --git a/hald/ci-tracker.h b/hald/ci-tracker.h
index 5b0794a..44e89ef 100644
--- a/hald/ci-tracker.h
+++ b/hald/ci-tracker.h
@@ -66,6 +66,7 @@ pid_t         ci_tracker_caller_get_pid 
 gboolean      ci_tracker_caller_is_local               (CICallerInfo *ci);
 gboolean      ci_tracker_caller_in_active_session      (CICallerInfo *ci);
 const char   *ci_tracker_caller_get_ck_session_path    (CICallerInfo *ci);
+const char   *ci_tracker_caller_get_selinux_context    (CICallerInfo *ci);
 #endif
 
 #endif /* CALLER_INFO_H */
diff --git a/hald/ck-tracker.c b/hald/ck-tracker.c
index 46d4850..34aa640 100644
--- a/hald/ck-tracker.c
+++ b/hald/ck-tracker.c
@@ -810,3 +810,19 @@ ck_tracker_new (void)
 	tracker->refcount = 1;
 	return tracker;
 }
+
+CKSession *
+ck_tracker_find_session (CKTracker *tracker, const char *ck_session_objpath)
+{
+        CKSession *session;
+        GSList *i;
+        for (i = tracker->sessions; i != NULL; i = g_slist_next (i)) {
+                session = i->data;
+                if (strcmp (session->session_objpath, ck_session_objpath) == 0) {
+                        goto out;
+                }
+        }
+        session = NULL;
+out:
+        return session;
+}
diff --git a/hald/ck-tracker.h b/hald/ck-tracker.h
index bcf92ad..33fe4b3 100644
--- a/hald/ck-tracker.h
+++ b/hald/ck-tracker.h
@@ -81,6 +81,8 @@ void        ck_tracker_unref            
 GSList     *ck_tracker_get_seats                  (CKTracker *tracker);
 GSList     *ck_tracker_get_sessions               (CKTracker *tracker);
 
+CKSession  *ck_tracker_find_session               (CKTracker *tracker, const char *ck_session_objpath);
+
 GSList     *ck_seat_get_sessions                  (CKSeat *seat);
 const char *ck_seat_get_id                        (CKSeat *seat);
 
diff --git a/hald/device.c b/hald/device.c
index e95cc19..d163078 100644
--- a/hald/device.c
+++ b/hald/device.c
@@ -1829,3 +1829,11 @@ hal_device_client_disconnected (const ch
         }
 }
 
+gboolean 
+hal_device_is_lock_exclusive (HalDevice *device, const char *lock_name)
+{
+        char buf[256];
+	g_snprintf (buf, sizeof (buf), "info.named_locks.%s.exclusive", lock_name);
+	return hal_device_property_get_bool (device, buf);
+}
+
diff --git a/hald/device.h b/hald/device.h
index 1942e2f..cda0bc4 100644
--- a/hald/device.h
+++ b/hald/device.h
@@ -218,6 +218,8 @@ gboolean      hal_device_acquire_lock (H
 
 gboolean      hal_device_release_lock (HalDevice *device, const char *lock_name, const char *sender);
 
+gboolean      hal_device_is_lock_exclusive (HalDevice *device, const char *lock_name);
+
 char        **hal_device_get_lock_holders (HalDevice *device, const char *lock_name);
 
 int           hal_device_get_num_lock_holders (HalDevice *device, const char *lock_name);
diff --git a/hald/hald.c b/hald/hald.c
index 9135440..3392068 100644
--- a/hald/hald.c
+++ b/hald/hald.c
@@ -265,6 +265,10 @@ dbus_bool_t hald_is_verbose = FALSE;
 dbus_bool_t hald_use_syslog = FALSE;
 dbus_bool_t hald_debug_exit_after_probing = FALSE;
 
+#ifdef HAVE_POLKIT
+PolKitContext *pk_context;
+#endif
+
 static int sigterm_unix_signal_pipe_fds[2];
 static GIOChannel *sigterm_iochn;
 
@@ -397,6 +401,7 @@ main (int argc, char *argv[])
 	guint sigterm_iochn_listener_source_id;
 	char *path;
 	char newpath[512];
+        GError *g_error;
 
 	openlog ("hald", LOG_PID, LOG_DAEMON);
 
@@ -616,6 +621,13 @@ main (int argc, char *argv[])
 	/* Finally, setup unix signal handler for TERM */
 	signal (SIGTERM, handle_sigterm);
 
+#ifdef HAVE_POLKIT
+        g_error = NULL;
+        pk_context = libpolkit_context_new (&g_error);
+        if (pk_context == NULL)
+                DIE (("Could not create PolicyKit context: %s", g_error->message));
+#endif
+
 	/* set up the local dbus server */
 	if (!hald_dbus_local_server_init ())
 		return 1;
diff --git a/hald/hald.h b/hald/hald.h
index a919537..207b0c4 100644
--- a/hald/hald.h
+++ b/hald/hald.h
@@ -29,9 +29,17 @@
 #include <stdarg.h>
 #include <stdint.h>
 #include <dbus/dbus.h>
+#ifdef HAVE_POLKIT
+#include <libpolkit/libpolkit.h>
+#endif
 
 #include "device_store.h"
 
+#ifdef HAVE_POLKIT
+extern PolKitContext *pk_context;
+#endif
+
+
 HalDeviceStore *hald_get_gdl (void);
 HalDeviceStore *hald_get_tdl (void);
 
diff --git a/hald/hald_dbus.c b/hald/hald_dbus.c
index 90dc9f7..c1727ee 100644
--- a/hald/hald_dbus.c
+++ b/hald/hald_dbus.c
@@ -2042,13 +2042,6 @@ device_acquire_interface_lock (DBusConne
 
 	sender = dbus_message_get_sender (message);
 
-        if (!local_interface) {
-                if (!access_check_caller_have_access_to_device (ci_tracker, d, "lock", sender)) {
-                        raise_permission_denied (connection, message, "AcquireInterfaceLock: no access to device");
-                        return DBUS_HANDLER_RESULT_HANDLED;
-                }
-        }
-
 	dbus_error_init (&error);
 	if (!dbus_message_get_args (message, &error,
 				    DBUS_TYPE_STRING, &interface_name,
@@ -2058,6 +2051,17 @@ device_acquire_interface_lock (DBusConne
 		return DBUS_HANDLER_RESULT_HANDLED;
 	}
 
+        if (!local_interface) {
+                char *privilege;
+                privilege = g_strdup_printf ("hal-lock:%s", interface_name);
+                if (!access_check_caller_have_access_to_device (ci_tracker, d, privilege, sender, NULL)) {
+                        g_free (privilege);
+                        raise_permission_denied (connection, message, "AcquireInterfaceLock: no access to device");
+                        return DBUS_HANDLER_RESULT_HANDLED;
+                }
+                g_free (privilege);
+        }
+
         if (!hal_device_acquire_lock (d, interface_name, exclusive, sender)) {
 		raise_interface_already_locked (connection, message, interface_name);
 		return DBUS_HANDLER_RESULT_HANDLED;
@@ -2099,13 +2103,6 @@ device_release_interface_lock (DBusConne
 
 	sender = dbus_message_get_sender (message);
 
-        if (!local_interface) {
-                if (!access_check_caller_have_access_to_device (ci_tracker, d, "lock", sender)) {
-                        raise_permission_denied (connection, message, "ReleaseInterfaceLock: no access to device");
-                        return DBUS_HANDLER_RESULT_HANDLED;
-                }
-        }
-
 	dbus_error_init (&error);
 	if (!dbus_message_get_args (message, &error,
 				    DBUS_TYPE_STRING, &interface_name,
@@ -2114,6 +2111,8 @@ device_release_interface_lock (DBusConne
 		return DBUS_HANDLER_RESULT_HANDLED;
 	}
 
+        /* don't require privileges to _release_ a lock */
+
         if (!hal_device_release_lock (d, interface_name, sender)) {
 		raise_interface_not_locked (connection, message, interface_name);
 		return DBUS_HANDLER_RESULT_HANDLED;
@@ -2161,6 +2160,7 @@ device_is_caller_locked_out (DBusConnect
         /* only allow HAL helpers / privileged users to ask this question */
         if (!local_interface && !access_check_message_caller_is_root_or_hal (ci_tracker, message)) {
                 raise_permission_denied (connection, message, "IsCallerLockedOut: not privileged");
+		return DBUS_HANDLER_RESULT_HANDLED;
         }
 
 	dbus_error_init (&error);
@@ -2188,6 +2188,110 @@ device_is_caller_locked_out (DBusConnect
 	return DBUS_HANDLER_RESULT_HANDLED;
 }
 
+/*------------------------------------------------------------------------*/
+
+#ifdef HAVE_POLKIT
+static DBusHandlerResult
+device_is_caller_privileged (DBusConnection *connection, DBusMessage *message, dbus_bool_t local_interface)
+{
+	const char *udi;
+	HalDevice *d;
+	DBusMessage *reply;
+	DBusError error;
+	const char *sender;
+	char *privilege;
+	char *caller_sysbus_name;
+        int polkit_result;
+        const char *result;
+        DBusMessageIter iter;
+
+	HAL_TRACE (("entering"));
+
+	udi = dbus_message_get_path (message);
+
+	d = hal_device_store_find (hald_get_gdl (), udi);
+	if (d == NULL)
+		d = hal_device_store_find (hald_get_tdl (), udi);
+
+	if (d == NULL) {
+		raise_no_such_device (connection, message, udi);
+		return DBUS_HANDLER_RESULT_HANDLED;
+	}
+
+	sender = dbus_message_get_sender (message);
+
+	dbus_error_init (&error);
+	if (!dbus_message_get_args (message, &error,
+				    DBUS_TYPE_STRING, &privilege,
+				    DBUS_TYPE_STRING, &caller_sysbus_name,
+				    DBUS_TYPE_INVALID)) {
+		raise_syntax (connection, message, "IsCallerPrivileged");
+		return DBUS_HANDLER_RESULT_HANDLED;
+	}
+
+        /* check whether we want to answer this question... */
+        if (!local_interface && !access_check_message_caller_is_root_or_hal (ci_tracker, message)) {
+                CICallerInfo *ci_sender;
+                CICallerInfo *ci_target;
+
+                if ((ci_sender = ci_tracker_get_info (ci_tracker, sender)) == NULL) {
+                        raise_error (connection, message, 
+                                     "org.freedesktop.Hal.Error", 
+                                     "Could not determine caller info for sender");
+                        return DBUS_HANDLER_RESULT_HANDLED;
+                }
+                if ((ci_target = ci_tracker_get_info (ci_tracker, caller_sysbus_name)) == NULL) {
+                        raise_error (connection, message, 
+                                     "org.freedesktop.Hal.Error", 
+                                     "Could not determine caller info for target");
+                        return DBUS_HANDLER_RESULT_HANDLED;
+                }
+
+                /* now check that sender uid(name) == uid(caller_sysbus_name)... */
+                if (ci_tracker_caller_get_uid (ci_sender) != ci_tracker_caller_get_uid (ci_target)) {
+                        raise_permission_denied (connection, message, 
+                                                 "IsCallerPrivileged: not privileged/authorized to know");
+                        return DBUS_HANDLER_RESULT_HANDLED;
+                }
+        }
+
+
+        polkit_result = -1;
+        access_check_caller_have_access_to_device (
+                ci_tracker, d, privilege, caller_sysbus_name, &polkit_result);
+        result = libpolkit_result_to_string_representation (polkit_result);
+
+        if (polkit_result < 0 || result == NULL) {
+		raise_error (connection, message, 
+                             "org.freedesktop.Hal.Error", 
+                             "Could not determine whether caller is privileged");
+		return DBUS_HANDLER_RESULT_HANDLED;
+        }
+
+	reply = dbus_message_new_method_return (message);
+	if (reply == NULL)
+		DIE (("No memory"));
+
+	dbus_message_iter_init_append (reply, &iter);
+	dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &result);
+
+	if (!dbus_connection_send (connection, reply, NULL))
+		DIE (("No memory"));
+
+	dbus_message_unref (reply);
+	return DBUS_HANDLER_RESULT_HANDLED;
+}
+#else /* HAVE_POLKIT */
+static DBusHandlerResult
+device_is_caller_privileged (DBusConnection *connection, DBusMessage *message, dbus_bool_t local_interface)
+{
+        /* we don't have PolicyKit */
+        raise_error (connection, message, 
+                     "org.freedesktop.Hal.Device.Error", 
+                     "HAL is not built with PolicyKit support");
+        return DBUS_HANDLER_RESULT_HANDLED;
+}
+#endif /* HAVE_POLKIT */
 
 /*------------------------------------------------------------------------*/
 
@@ -3646,23 +3750,52 @@ hald_exec_method (HalDevice *d, CICaller
 	int type;
 	GString *stdin_str = NULL;
 	DBusMessageIter iter;
-	char *extra_env[3];
-	char uid_export[128];
-	char sender_export[128];
+	char *extra_env[6];
+	char uid_export[256];
+        char pid_export[256];
+        char selinux_context_export[256];
+	char sender_export[256];
+        char ck_session_path_export[256];
 	MethodInvocation *mi;
 
-	/* add calling uid */
+	/* add extra information about the caller... */
 	extra_env[0] = NULL;
 	extra_env[1] = NULL;
 	extra_env[2] = NULL;
+	extra_env[3] = NULL;
+	extra_env[4] = NULL;
+	extra_env[5] = NULL;
 	if (local_interface) {
 		extra_env[0] = "HAL_METHOD_INVOKED_BY_UID=0";
 	} else {
+                int n;
+                const char *selinux_context;
+                const char *ck_session_path;
+
+                n = 0;
 		sprintf (uid_export, "HAL_METHOD_INVOKED_BY_UID=%u", ci_tracker_caller_get_uid (ci));
-		extra_env[0] = uid_export;
+		extra_env[n++] = uid_export;
 		snprintf (sender_export, sizeof (sender_export), 
-			  "HAL_METHOD_INVOKED_BY_SYSTEMBUS_CONNECTION_NAME=%s", dbus_message_get_sender (message));
-		extra_env[1] = sender_export;
+			  "HAL_METHOD_INVOKED_BY_SYSTEMBUS_CONNECTION_NAME=%s", 
+                          dbus_message_get_sender (message));
+		extra_env[n++] = sender_export;
+#ifdef HAVE_CONKIT
+		sprintf (pid_export, "HAL_METHOD_INVOKED_BY_PID=%u", ci_tracker_caller_get_pid (ci));
+		extra_env[n++] = pid_export;
+                selinux_context = ci_tracker_caller_get_selinux_context (ci);
+                if (selinux_context != NULL) {
+                        sprintf (selinux_context_export, "HAL_METHOD_INVOKED_BY_SELINUX_CONTEXT=%s", selinux_context);
+                        extra_env[n++] = selinux_context_export;
+                }
+
+                /* caller may, or may not, be in a session.. if he is, export the session he belongs to... */
+                ck_session_path = ci_tracker_caller_get_ck_session_path (ci);
+                if (ck_session_path != NULL) {
+                        sprintf (ck_session_path_export, "HAL_METHOD_INVOKED_BY_SESSION=%s", 
+                                 g_basename (ck_session_path));
+                        extra_env[n++] = ck_session_path_export;
+                }
+#endif /* HAVE_CONKIT */
 	}
 
 	/* prepare stdin with parameters */
@@ -4021,6 +4154,11 @@ do_introspect (DBusConnection  *connecti
 				       "      <arg name=\"caller_sysbus_name\" direction=\"in\" type=\"s\"/>\n"
 				       "      <arg name=\"whether_caller_is_locked_out\" direction=\"out\" type=\"b\"/>\n"
 				       "    </method>\n"
+				       "    <method name=\"IsCallerPrivileged\">\n"
+				       "      <arg name=\"privilege\" direction=\"in\" type=\"s\"/>\n"
+				       "      <arg name=\"caller_sysbus_name\" direction=\"in\" type=\"s\"/>\n"
+				       "      <arg name=\"result\" direction=\"out\" type=\"s\"/>\n"
+				       "    </method>\n"
 				       "    <method name=\"IsLockedByOthers\">\n"
 				       "      <arg name=\"interface_name\" direction=\"in\" type=\"s\"/>\n"
 				       "      <arg name=\"whether_it_is_locked_by_others\" direction=\"out\" type=\"b\"/>\n"
@@ -4307,6 +4445,10 @@ hald_dbus_filter_handle_methods (DBusCon
 		return device_is_caller_locked_out (connection, message, local_interface);
 	} else if (dbus_message_is_method_call (message,
 						"org.freedesktop.Hal.Device",
+						"IsCallerPrivileged")) {
+		return device_is_caller_privileged (connection, message, local_interface);
+	} else if (dbus_message_is_method_call (message,
+						"org.freedesktop.Hal.Device",
 						"IsLockedByOthers")) {
 		return device_is_locked_by_others (connection, message, local_interface);
 	} else if (dbus_message_is_method_call (message,
@@ -4470,15 +4612,9 @@ hald_dbus_filter_handle_methods (DBusCon
                 if (d == NULL)
                         goto out;
 
-                /* bypass security checks on direct connections */
-                if (!local_interface) {
-                        if (!access_check_caller_have_access_to_device (ci_tracker, d, NULL, caller)) {
-                                HAL_INFO (("Caller '%s' does not have access to device '%s'", caller, udi));
-                                /* TODO: need to fix up reason */
-                                raise_permission_denied (connection, message, "Not in active session");
-                                return DBUS_HANDLER_RESULT_HANDLED;
-                        }
-                }
+                /* no security checks; each method implementation is supposed to 
+                 * check this (with e.g. PolicyKit) itself... 
+                 */
 
                 /* check if the interface on the device is locked by someone else 
                  *
@@ -4947,16 +5083,22 @@ validate_lock_for_device (HalDeviceStore
                 holders = hal_device_get_lock_holders (device, locked_interfaces[n]);
                 if (holders == NULL)
                         continue;
+
                 for (m = 0; holders[m] != NULL; m++) {
+                        char *privilege;
+
                         HAL_INFO (("Validating lock holder '%s' on interface '%s' on udi '%s'",
                                    holders[m], locked_interfaces[n], hal_device_get_udi (device)));
 
-                        if (!access_check_caller_have_access_to_device (ci_tracker, device, "lock", holders[m])) {
+                        privilege = g_strdup_printf ("hal-lock:%s", locked_interfaces[n]);
+                        if (!access_check_caller_have_access_to_device (
+                                    ci_tracker, device, privilege, holders[m], NULL)) {
                                 HAL_INFO (("Kicking out lock holder '%s' on interface '%s' on udi '%s' "
                                            "as he no longer has access to the device",
                                            holders[m], locked_interfaces[n], hal_device_get_udi (device)));
                                 hal_device_release_lock (device, locked_interfaces[n], holders[m]);
                         }
+                        g_free (privilege);
 
                 }
                 g_strfreev (holders);
diff --git a/hald/hald_runner.c b/hald/hald_runner.c
index fd4514e..36ae7ad 100644
--- a/hald/hald_runner.c
+++ b/hald/hald_runner.c
@@ -341,10 +341,12 @@ add_property_to_msg (HalDevice * device,
 static void
 add_env (DBusMessageIter * iter, const gchar * key, const gchar * value)
 {
-	gchar *env;
-	env = g_strdup_printf ("%s=%s", key, value);
-	dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &env);
-	g_free (env);
+        if (value != NULL) {
+                gchar *env;
+                env = g_strdup_printf ("%s=%s", key, value);
+                dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &env);
+                g_free (env);
+        }
 }
 
 static void
@@ -366,8 +368,14 @@ add_basic_env (DBusMessageIter * iter, c
 	}
 	add_env (iter, "UDI", udi);
 	add_env (iter, "HALD_DIRECT_ADDR", hald_dbus_local_server_addr ());
+
+        /* I'm sure it would be easy to remove use of getenv(3) to add these variables... */
+
+	add_env (iter, "LD_LIBRARY_PATH", getenv ("LD_LIBRARY_PATH"));
 #ifdef HAVE_POLKIT
 	add_env (iter, "HAVE_POLKIT", "1");
+        add_env (iter, "POLKIT_PRIVILEGE_DIR", getenv ("POLKIT_PRIVILEGE_DIR"));
+        add_env (iter, "POLKIT_DEBUG", getenv ("POLKIT_DEBUG"));
 #endif
 
 
@@ -379,16 +387,21 @@ add_basic_env (DBusMessageIter * iter, c
 		GString *seats_string;
 		char *s;
 		char *p;
+                int num_seats;
+                int num_sessions_total;
 
 		seats_string = g_string_new ("");
 
 		seats = ck_tracker_get_seats (ck_tracker);
+                num_seats = g_slist_length (seats);
+                num_sessions_total = 0;
 		for (i = seats; i != NULL; i = g_slist_next (i)) {
 			GSList *j;
 			CKSeat *seat;
 			GSList *sessions;
 			const char *seat_id;
 			GString *sessions_string;
+                        int num_sessions;
 
 			sessions_string = g_string_new ("");
 
@@ -404,9 +417,12 @@ add_basic_env (DBusMessageIter * iter, c
 			g_string_append (seats_string, seat_id);
 
 			sessions = ck_seat_get_sessions (seat);
+                        num_sessions = g_slist_length (sessions);
+                        num_sessions_total += num_sessions;
 			for (j = sessions; j != NULL; j = g_slist_next (j)) {
 				CKSession *session;
 				const char *session_id;
+                                const char *q;
 
 				session = j->data;
 				/* basename again; e.g. Session1 rather than /org/freedesktop/ConsoleKit/Session1 */
@@ -417,13 +433,17 @@ add_basic_env (DBusMessageIter * iter, c
 				}
 				g_string_append (sessions_string, session_id);
 
-				/* for each Session, export IS_ACTIVE and UID 
+				/* for each Session, export IS_ACTIVE, UID, IS_LOCAL, HOSTNAME
 				 *
+                                 * CK_SESSION_SEAT_Session2=Seat1
 				 * CK_SESSION_IS_ACTIVE_Session2=true|false
 				 * CK_SESSION_UID_Session2=501
 				 * CK_SESSION_IS_LOCAL_Session2=true|false
 				 * CK_SESSION_HOSTNAME_Session2=192.168.1.112
 				 */
+				s = g_strdup_printf ("CK_SESSION_SEAT_%s", session_id);
+				add_env (iter, s, seat_id);
+				g_free (s);
 				s = g_strdup_printf ("CK_SESSION_IS_ACTIVE_%s", session_id);
 				add_env (iter, s, ck_session_is_active (session) ? "true" : "false");
 				g_free (s);
@@ -435,22 +455,30 @@ add_basic_env (DBusMessageIter * iter, c
 				s = g_strdup_printf ("CK_SESSION_IS_LOCAL_%s", session_id);
 				add_env (iter, s, ck_session_is_local (session) ? "true" : "false");
 				g_free (s);
-				s = g_strdup_printf ("CK_SESSION_HOSTNAME_%s", session_id);
-				p = g_strdup_printf ("%s", ck_session_get_hostname (session));
-				add_env (iter, s, p);
-				g_free (s);
-				g_free (p);
+				q = ck_session_get_hostname (session);
+                                if (q != NULL && strlen (q) > 0) {
+                                        s = g_strdup_printf ("CK_SESSION_HOSTNAME_%s", session_id);
+                                        add_env (iter, s, q);
+                                        g_free (s);
+                                }
 			}
 
 			/* for each Seat, export sessions on each seat 
 			 *
 			 * CK_SEAT_Seat1=Session1 Session3 Session7
+                         * CK_SEAT_NUM_SESSIONS_Seat1=3
 			 */
 			s = g_strdup_printf ("CK_SEAT_%s", seat_id);
 			add_env (iter, s, sessions_string->str);
 			g_string_free (sessions_string, TRUE);
 			g_free (s);
 
+			s = g_strdup_printf ("CK_SEAT_NUM_SESSIONS_%s", seat_id);
+                        p = g_strdup_printf ("%d", num_sessions);
+                        add_env (iter, s, p);
+                        g_free (p);
+			g_free (s);
+
 		}
 
 		/* Export all detected seats 
@@ -459,6 +487,23 @@ add_basic_env (DBusMessageIter * iter, c
 		 */
 		add_env (iter, "CK_SEATS", seats_string->str);
 		g_string_free (seats_string, TRUE);
+
+		/* Export total number of sessions
+		 *
+		 * CK_NUM_SESSIONS=5
+		 */
+                p = g_strdup_printf ("%d", num_sessions_total);
+                add_env (iter, "CK_NUM_SESSIONS", p);
+                g_free (p);
+
+		/* Export number of seats
+		 *
+		 * CK_NUM_SEATS=5
+		 */
+                p = g_strdup_printf ("%d", num_seats);
+                add_env (iter, "CK_NUM_SEATS", p);
+                g_free (p);
+
 	}
 #endif /* HAVE_CONKIT */
 
diff --git a/hald/linux/addons/addon-cpufreq.c b/hald/linux/addons/addon-cpufreq.c
index 1b330c5..bf6fba6 100644
--- a/hald/linux/addons/addon-cpufreq.c
+++ b/hald/linux/addons/addon-cpufreq.c
@@ -39,10 +39,6 @@
 #include "libhal/libhal.h"
 #include "../../logger.h"
 
-#ifdef HAVE_POLKIT
-#include <libpolkit.h>
-#endif
-
 #define MAX_LINE_SIZE				255
 #define CPUFREQ_POLKIT_PRIVILEGE		"hal-power-cpufreq"
 #define DBUS_INTERFACE				"org.freedesktop.Hal.Device.CPUFreq"
@@ -85,6 +81,10 @@ static gboolean dbus_raise_governor_init
 /** list holding all cpufreq objects (userspace, ondemand, etc.) */
 static GSList *cpufreq_objs = NULL;
 
+static LibHalContext *halctx = NULL;
+
+static char *udi = NULL;
+
 /******************** helper functions **********************/
 
 /** reads one integer from filename and stores it in val */
@@ -918,80 +918,43 @@ static gboolean dbus_raise_error(DBusCon
  *
  * checks if caller of message possesses the CPUFREQ_POLKIT_PRIVILGE 
  */
-static gboolean dbus_is_privileged(DBusConnection *connection, DBusMessage *message,
-				   DBusError *error)
+static gboolean 
+dbus_is_privileged (DBusConnection *connection, DBusMessage *message, DBusError *error)
 {
-	LibPolKitContext	*polctx			= NULL;
-	char			*caller_unix_user_str;
-	const char		*caller_dbus_name;
-	unsigned long		caller_unix_user;
-	DBusConnection		*connection_new;
-	gboolean		out_is_allowed;
-	gboolean		out_is_temporary;
-	LibPolKitResult		res;
-
-	connection_new = dbus_bus_get(DBUS_BUS_SYSTEM, error);
-	if (dbus_error_is_set(error)) {
-		dbus_raise_error(connection, message, CPUFREQ_ERROR_GENERAL,
-				 "Cannot get connection to system bus");
-		return FALSE;
-	}
-
-	polctx = libpolkit_new_context(connection_new);
-	if (polctx == NULL) {
-		dbus_raise_error(connection, message, CPUFREQ_ERROR_GENERAL,
-				 "Cannot get PolicyKit context");
-		return FALSE;
-	}
-
-	caller_dbus_name = dbus_message_get_sender(message);
-	if (caller_dbus_name == NULL) {
-		dbus_raise_error(connection, message, CPUFREQ_ERROR_GENERAL,
-				 "Cannot get D-Bus connection name of caller");
-		goto Error;
-	}
-		
-	caller_unix_user = dbus_bus_get_unix_user(connection_new, caller_dbus_name, error);
-	if (dbus_error_is_set(error)) {
-		dbus_raise_error(connection, message, CPUFREQ_ERROR_GENERAL,
-				 "Cannot get unix user of caller");
-		dbus_error_free(error);
-		goto Error;
-	}
-
-	HAL_DEBUG(("Connection name of caller: %s", caller_dbus_name));
-	HAL_DEBUG(("Unix user id of caller: %ld", caller_unix_user));
-
-	caller_unix_user_str = g_strdup_printf("%ld", caller_unix_user);
-	res = libpolkit_is_uid_allowed_for_privilege(polctx,
-						     caller_dbus_name,
-						     caller_unix_user_str,
-						     CPUFREQ_POLKIT_PRIVILEGE,
-						     getenv("UDI"),
-						     &out_is_allowed,
-						     &out_is_temporary,
-						     NULL);
-	g_free(caller_unix_user_str);
+        gboolean ret;
+        char *polkit_result;
+        const char *invoked_by_syscon_name;
+
+        ret = FALSE;
+        polkit_result = NULL;
+
+        invoked_by_syscon_name = dbus_message_get_sender (message);
+        
+        polkit_result = libhal_device_is_caller_privileged (halctx,
+                                                            udi,
+                                                            CPUFREQ_POLKIT_PRIVILEGE,
+                                                            invoked_by_syscon_name,
+                                                            error);
+        if (polkit_result == NULL) {
+		dbus_raise_error (connection, message, CPUFREQ_ERROR_GENERAL,
+                                  "Cannot determine if caller is privileged");
+                goto out;
+        }
+        if (strcmp (polkit_result, "yes") != 0) {
 
-	if (res != LIBPOLKIT_RESULT_OK) {
-		dbus_raise_error(connection, message, CPUFREQ_ERROR_GENERAL,
-				 "Cannot lookup privilege: %d", res);
-		goto Error;
-	}
-	
-	if (!out_is_allowed) {
-		HAL_DEBUG(("caller don't possess privilege"));
-		dbus_raise_error(connection, message, CPUFREQ_ERROR_PERMISSION_DENIED,
-				 "%s refused uid %d", CPUFREQ_POLKIT_PRIVILEGE, caller_unix_user);
-		goto Error;
-	}
+		dbus_raise_error (connection, message, 
+                                  "org.freedesktop.Hal.Device.PermissionDeniedByPolicy",
+                                  "%s %s <-- (privilege, result)",
+                                  CPUFREQ_POLKIT_PRIVILEGE, polkit_result);
+                goto out;
+        }
 
-	HAL_DEBUG(("Caller is privileged"));
-	return out_is_allowed;
+        ret = TRUE;
 
-Error:
-	libpolkit_free_context(polctx);
-	return FALSE;
+out:
+        if (polkit_result != NULL)
+                libhal_free_string (polkit_result);
+        return ret;
 }
 #endif
 
@@ -1257,8 +1220,8 @@ gboolean dbus_init(void)
 {
 	DBusError	dbus_error;
 	DBusConnection	*dbus_connection;
-	char		*udi		= getenv("UDI");
-	LibHalContext	*halctx		= NULL;
+
+        udi = getenv("UDI");
 
 	dbus_error_init(&dbus_error);
 
diff --git a/hald/linux/addons/addon-dell-backlight.cpp b/hald/linux/addons/addon-dell-backlight.cpp
index 39a73b6..20658aa 100644
--- a/hald/linux/addons/addon-dell-backlight.cpp
+++ b/hald/linux/addons/addon-dell-backlight.cpp
@@ -119,6 +119,58 @@ write_backlight (u32 newBacklightValue, 
 		HAL_DEBUG (("Wrote %d to the BAT backlight", curValue));
 }
 
+static gboolean
+check_priv (DBusConnection *connection, DBusMessage *message, const char *udi, const char *privilege)
+#ifdef HAVE_POLKIT
+{
+        gboolean ret;
+        char *polkit_result;
+        const char *invoked_by_syscon_name;
+        DBusMessage *reply;
+        DBusError error;
+
+        ret = FALSE;
+        polkit_result = NULL;
+
+        invoked_by_syscon_name = dbus_message_get_sender (message);
+        
+        dbus_error_init (&error);
+        polkit_result = libhal_device_is_caller_privileged (halctx,
+                                                            udi,
+                                                            privilege,
+                                                            invoked_by_syscon_name,
+                                                            &error);
+        if (polkit_result == NULL) {
+                reply = dbus_message_new_error_printf (message,
+                                                       "org.freedesktop.Hal.Device.Error",
+                                                       "Cannot determine if caller is privileged",
+                                                       privilege, polkit_result);
+                dbus_connection_send (connection, reply, NULL);
+                goto out;
+        }
+        if (strcmp (polkit_result, "yes") != 0) {
+
+                reply = dbus_message_new_error_printf (message,
+                                                       "org.freedesktop.Hal.Device.PermissionDeniedByPolicy",
+                                                       "%s %s <-- (privilege, result)",
+                                                       privilege, polkit_result);
+                dbus_connection_send (connection, reply, NULL);
+                goto out;
+        }
+
+        ret = TRUE;
+
+out:
+        if (polkit_result != NULL)
+                libhal_free_string (polkit_result);
+        return ret;
+}
+#else
+{
+        return TRUE;
+}
+#endif
+
 static DBusHandlerResult
 filter_function (DBusConnection *connection, DBusMessage *message, void *userdata)
 {
@@ -127,6 +179,10 @@ filter_function (DBusConnection *connect
 	dbus_bool_t AC;
 	dbus_error_init (&err);
 
+        if (!check_priv (connection, message, dbus_message_get_path (message), "hal-power-lcd-panel")) {
+                return DBUS_HANDLER_RESULT_HANDLED;
+        }
+
 	/* Mechanism to ensure that we always set the AC brightness when we are on AC-power etc. */
 	AC = libhal_device_get_property_bool (halctx, 
 					     "/org/freedesktop/Hal/devices/acpi_AC",
diff --git a/hald/linux/addons/addon-macbook-backlight.c b/hald/linux/addons/addon-macbook-backlight.c
index 5314f3c..4841f1d 100644
--- a/hald/linux/addons/addon-macbook-backlight.c
+++ b/hald/linux/addons/addon-macbook-backlight.c
@@ -177,6 +177,59 @@ backlight_get (void)
 	return (register_get () >> 1) & 0x7fff;
 }
 
+static gboolean
+check_priv (DBusConnection *connection, DBusMessage *message, const char *udi, const char *privilege)
+#ifdef HAVE_POLKIT
+{
+        gboolean ret;
+        char *polkit_result;
+        const char *invoked_by_syscon_name;
+        DBusMessage *reply;
+        DBusError error;
+
+        ret = FALSE;
+        polkit_result = NULL;
+
+        invoked_by_syscon_name = dbus_message_get_sender (message);
+        
+        dbus_error_init (&error);
+        polkit_result = libhal_device_is_caller_privileged (halctx,
+                                                            udi,
+                                                            privilege,
+                                                            invoked_by_syscon_name,
+                                                            &error);
+        if (polkit_result == NULL) {
+                reply = dbus_message_new_error_printf (message,
+                                                       "org.freedesktop.Hal.Device.Error",
+                                                       "Cannot determine if caller is privileged",
+                                                       privilege, polkit_result);
+                dbus_connection_send (connection, reply, NULL);
+                goto out;
+        }
+        if (strcmp (polkit_result, "yes") != 0) {
+
+                reply = dbus_message_new_error_printf (message,
+                                                       "org.freedesktop.Hal.Device.PermissionDeniedByPolicy",
+                                                       "%s %s <-- (privilege, result)",
+                                                       privilege, polkit_result);
+                dbus_connection_send (connection, reply, NULL);
+                goto out;
+        }
+
+        ret = TRUE;
+
+out:
+        if (polkit_result != NULL)
+                libhal_free_string (polkit_result);
+        return ret;
+}
+#else
+{
+        return TRUE;
+}
+#endif
+
+
 #define BACKLIGHT_OBJECT \
   "/org/freedesktop/Hal/devices/macbook_backlight"
 #define BACKLIGHT_IFACE \
@@ -198,6 +251,10 @@ filter_function (DBusConnection * connec
 	int level;
 	int ret;
 
+        if (!check_priv (connection, message, dbus_message_get_path (message), "hal-power-lcd-panel")) {
+                return DBUS_HANDLER_RESULT_HANDLED;
+        }
+
 	reply = NULL;
 	ret = 0;
 
diff --git a/hald/linux/addons/addon-macbookpro-backlight.c b/hald/linux/addons/addon-macbookpro-backlight.c
index 8870f17..f6da198 100644
--- a/hald/linux/addons/addon-macbookpro-backlight.c
+++ b/hald/linux/addons/addon-macbookpro-backlight.c
@@ -215,6 +215,58 @@ read_keyboard_backlight (void)
 }
 #endif
 
+static gboolean
+check_priv (DBusConnection *connection, DBusMessage *message, const char *udi, const char *privilege)
+#ifdef HAVE_POLKIT
+{
+        gboolean ret;
+        char *polkit_result;
+        const char *invoked_by_syscon_name;
+        DBusMessage *reply;
+        DBusError error;
+
+        ret = FALSE;
+        polkit_result = NULL;
+
+        invoked_by_syscon_name = dbus_message_get_sender (message);
+        
+        dbus_error_init (&error);
+        polkit_result = libhal_device_is_caller_privileged (halctx,
+                                                            udi,
+                                                            privilege,
+                                                            invoked_by_syscon_name,
+                                                            &error);
+        if (polkit_result == NULL) {
+                reply = dbus_message_new_error_printf (message,
+                                                       "org.freedesktop.Hal.Device.Error",
+                                                       "Cannot determine if caller is privileged",
+                                                       privilege, polkit_result);
+                dbus_connection_send (connection, reply, NULL);
+                goto out;
+        }
+        if (strcmp (polkit_result, "yes") != 0) {
+
+                reply = dbus_message_new_error_printf (message,
+                                                       "org.freedesktop.Hal.Device.PermissionDeniedByPolicy",
+                                                       "%s %s <-- (privilege, result)",
+                                                       privilege, polkit_result);
+                dbus_connection_send (connection, reply, NULL);
+                goto out;
+        }
+
+        ret = TRUE;
+
+out:
+        if (polkit_result != NULL)
+                libhal_free_string (polkit_result);
+        return ret;
+}
+#else
+{
+        return TRUE;
+}
+#endif
+
 static int last_keyboard_brightness = -1;
 
 static DBusHandlerResult
@@ -222,6 +274,9 @@ filter_function (DBusConnection *connect
 {
 	DBusError err;
 	DBusMessage *reply;
+        const char *udi;
+
+        udi = dbus_message_get_path (message);
 
 	/*dbg ("filter_function: sender=%s destination=%s obj_path=%s interface=%s method=%s", 
 	     dbus_message_get_sender (message), 
@@ -237,6 +292,9 @@ filter_function (DBusConnection *connect
 					 "SetBrightness")) {
 		int brightness;
 
+                if (!check_priv (connection, message, udi, "hal-power-lcd-panel"))
+                        goto error;
+
 		dbus_error_init (&err);
 		if (dbus_message_get_args (message, 
 					   &err,
@@ -271,6 +329,9 @@ filter_function (DBusConnection *connect
 						"GetBrightness")) {
 		int brightness;
 
+                if (!check_priv (connection, message, udi, "hal-power-lcd-panel"))
+                        goto error;
+
 		dbus_error_init (&err);
 		if (dbus_message_get_args (message, 
 					   &err,
@@ -299,6 +360,9 @@ filter_function (DBusConnection *connect
 						"GetBrightness")) {
 		int brightness[2];
 
+                if (!check_priv (connection, message, udi, "hal-power-light-sensor"))
+                        goto error;
+
 		brightness[0] = read_light_sensor (FALSE); /* right */
 		brightness[1] = read_light_sensor (TRUE); /* left */
 
@@ -323,6 +387,9 @@ filter_function (DBusConnection *connect
 						"org.freedesktop.Hal.Device.KeyboardBacklight", 
 						"GetBrightness")) {
 
+                if (!check_priv (connection, message, udi, "hal-power-keyboard-backlight"))
+                        goto error;
+
 		/* I can't get this working so just cache last SetBrightness value :-/ */
 		if (last_keyboard_brightness == -1 ) {
 			reply = dbus_message_new_error (message,
@@ -365,6 +432,8 @@ filter_function (DBusConnection *connect
 						"SetBrightness")) {
 		int brightness;
 
+                if (!check_priv (connection, message, udi, "hal-power-keyboard-backlight"))
+                        goto error;
 
 		dbus_error_init (&err);
 		if (dbus_message_get_args (message, 
diff --git a/hald/linux/addons/addon-omap-backlight.c b/hald/linux/addons/addon-omap-backlight.c
index f7a443d..94a9a12 100644
--- a/hald/linux/addons/addon-omap-backlight.c
+++ b/hald/linux/addons/addon-omap-backlight.c
@@ -122,6 +122,59 @@ static void write_backlight(struct backl
     close(fd);
 }
 
+static gboolean
+check_priv (DBusConnection *connection, DBusMessage *message, const char *udi, const char *privilege)
+#ifdef HAVE_POLKIT
+{
+        gboolean ret;
+        char *polkit_result;
+        const char *invoked_by_syscon_name;
+        DBusMessage *reply;
+        DBusError error;
+
+        ret = FALSE;
+        polkit_result = NULL;
+
+        invoked_by_syscon_name = dbus_message_get_sender (message);
+        
+        dbus_error_init (&error);
+        polkit_result = libhal_device_is_caller_privileged (halctx,
+                                                            udi,
+                                                            privilege,
+                                                            invoked_by_syscon_name,
+                                                            &error);
+        if (polkit_result == NULL) {
+                reply = dbus_message_new_error_printf (message,
+                                                       "org.freedesktop.Hal.Device.Error",
+                                                       "Cannot determine if caller is privileged",
+                                                       privilege, polkit_result);
+                dbus_connection_send (connection, reply, NULL);
+                goto out;
+        }
+        if (strcmp (polkit_result, "yes") != 0) {
+
+                reply = dbus_message_new_error_printf (message,
+                                                       "org.freedesktop.Hal.Device.PermissionDeniedByPolicy",
+                                                       "%s %s <-- (privilege, result)",
+                                                       privilege, polkit_result);
+                dbus_connection_send (connection, reply, NULL);
+                goto out;
+        }
+
+        ret = TRUE;
+
+out:
+        if (polkit_result != NULL)
+                libhal_free_string (polkit_result);
+        return ret;
+}
+#else
+{
+        return TRUE;
+}
+#endif
+
+
 /* DBus filter function */
 static DBusHandlerResult
 filter_function (DBusConnection *connection, DBusMessage *message, void *userdata)
@@ -129,6 +182,10 @@ filter_function (DBusConnection *connect
 	DBusError err;
 	DBusMessage *reply;
 
+        if (!check_priv (connection, message, dbus_message_get_path (message), "hal-power-lcd-panel")) {
+                return DBUS_HANDLER_RESULT_HANDLED;
+        }
+
 #ifdef DEBUG_OMAP_BL
 	dbg ("filter_function: sender=%s destination=%s obj_path=%s interface=%s method=%s", 
 	     dbus_message_get_sender (message), 
diff --git a/hald/run-hald.sh b/hald/run-hald.sh
index 88d55e1..d3e4c73 100755
--- a/hald/run-hald.sh
+++ b/hald/run-hald.sh
@@ -14,6 +14,8 @@ if [ "$1" = "--skip-fdi-install" ] ; the
     shift
 else
     rm -rf .local-fdi
+    make -C ../privileges install DESTDIR=`pwd`/.local-fdi prefix=/
+
     make -C ../fdi install DESTDIR=`pwd`/.local-fdi prefix=/ && \
     if [ ! -d $information_fdidir ] ; then
     	echo "ERROR: You need to checkout hal-info in the same level"
@@ -26,6 +28,7 @@ export HAL_FDI_SOURCE_PREPROBE=.local-fd
 export HAL_FDI_SOURCE_INFORMATION=.local-fdi/share/hal/fdi/information
 export HAL_FDI_SOURCE_POLICY=.local-fdi/share/hal/fdi/policy
 export HAL_FDI_CACHE_NAME=.local-fdi/hald-local-fdi-cache
+export POLKIT_PRIVILEGE_DIR=`pwd`/.local-fdi/etc/PolicyKit/privileges
 
 ./hald --daemon=no --verbose=yes $@
 #./hald --daemon=no
diff --git a/libhal/libhal.c b/libhal/libhal.c
index b3d7cce..013d8c1 100644
--- a/libhal/libhal.c
+++ b/libhal/libhal.c
@@ -77,7 +77,7 @@ static char **libhal_get_string_array_fr
 static dbus_bool_t libhal_property_fill_value_from_variant (LibHalProperty *p, DBusMessageIter *var_iter);
 
 
-/** 
+/**
  * libhal_free_string_array:
  * @str_array: the array to be freed
  *
@@ -159,7 +159,7 @@ oom:
 
 }
 
-/** 
+/**
  * libhal_free_string:
  * @str: the nul-terminated sting to free
  *
@@ -188,7 +188,7 @@ struct LibHalPropertySet_s {
 				      *	  if there are no properties */
 };
 
-/** 
+/**
  * LibHalProperty:
  *
  * Represents a property. Opaque.
@@ -215,7 +215,7 @@ struct LibHalProperty_s {
 				      *	  the last */
 };
 
-/** 
+/**
  * LibHalContext:
  *
  * Context for connection to the HAL daemon. Opaque, use the
@@ -565,7 +565,7 @@ libhal_property_set_sort (LibHalProperty
 	}
 }
 
-/** 
+/**
  * libhal_free_property_set:
  * @set: property-set to free
  *
@@ -617,7 +617,7 @@ libhal_property_set_get_num_elems (LibHa
 }
 
 
-/** 
+/**
  * libhal_psi_init:
  * @iter: iterator object
  * @set: property set to iterate over
@@ -651,7 +651,7 @@ libhal_psi_has_more (LibHalPropertySetIt
 	return iter->idx < iter->set->num_properties;
 }
 
-/** 
+/**
  * libhal_psi_next:
  * @iter: iterator object
  *
@@ -678,7 +678,7 @@ libhal_psi_get_type (LibHalPropertySetIt
 	return iter->cur_prop->type;
 }
 
-/** 
+/**
  * libhal_psi_get_key:
  * @iter: iterator object
  *
@@ -694,7 +694,7 @@ libhal_psi_get_key (LibHalPropertySetIte
 	return iter->cur_prop->key;
 }
 
-/** 
+/**
  * libhal_psi_get_string:
  * @iter: iterator object
  *
@@ -710,7 +710,7 @@ libhal_psi_get_string (LibHalPropertySet
 	return iter->cur_prop->v.str_value;
 }
 
-/** 
+/**
  * libhal_psi_get_int:
  * @iter: iterator object
  *
@@ -738,7 +738,7 @@ libhal_psi_get_uint64 (LibHalPropertySet
 	return iter->cur_prop->v.uint64_value;
 }
 
-/** 
+/**
  * libhal_psi_get_double:
  * @iter: iterator object
  *
@@ -766,7 +766,7 @@ libhal_psi_get_bool (LibHalPropertySetIt
 	return iter->cur_prop->v.bool_value;
 }
 
-/** 
+/**
  * libhal_psi_get_strlist:
  * @iter: iterator object
  *
@@ -957,7 +957,7 @@ filter_func (DBusConnection * connection
 	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 }
 
-/** 
+/**
  * libhal_get_all_devices:
  * @ctx: the context for the connection to hald
  * @num_devices: the number of devices will be stored here
@@ -1022,7 +1022,7 @@ libhal_get_all_devices (LibHalContext *c
 	return hal_device_names;
 }
 
-/** 
+/**
  * libhal_device_get_property_type:
  * @ctx: the context for the connection to hald
  * @udi: the Unique Device Id
@@ -1082,7 +1082,7 @@ libhal_device_get_property_type (LibHalC
 	return type;
 }
 
-/** 
+/**
  * libhal_device_get_property_strlist:
  * @ctx: the context for the connection to hald
  * @udi: unique Device Id
@@ -1154,7 +1154,7 @@ libhal_device_get_property_strlist (LibH
 	return our_strings;
 }
 
-/** 
+/**
  * libhal_device_get_property_string:
  * @ctx: the context for the connection to hald
  * @udi: the Unique Device Id
@@ -1235,7 +1235,7 @@ libhal_device_get_property_string (LibHa
 	return value;
 }
 
-/** 
+/**
  * libhal_device_get_property_int:
  * @ctx: the context for the connection to hald
  * @udi: the Unique Device Id
@@ -1308,7 +1308,7 @@ libhal_device_get_property_int (LibHalCo
 	return value;
 }
 
-/** 
+/**
  * libhal_device_get_property_uint64:
  * @ctx: the context for the connection to hald
  * @udi: the Unique Device Id
@@ -1380,7 +1380,7 @@ libhal_device_get_property_uint64 (LibHa
 	return value;
 }
 
-/** 
+/**
  * libhal_device_get_property_double:
  * @ctx: the context for the connection to hald
  * @udi: the Unique Device Id
@@ -1452,7 +1452,7 @@ libhal_device_get_property_double (LibHa
 	return (double) value;
 }
 
-/** 
+/**
  * libhal_device_get_property_bool:
  * @ctx: the context for the connection to hald
  * @udi: the Unique Device Id
@@ -1621,7 +1621,7 @@ libhal_device_set_property_helper (LibHa
 	return TRUE;
 }
 
-/** 
+/**
  * libhal_device_set_property_string:
  * @ctx: the context for the connection to hald
  * @udi: the Unique Device Id
@@ -1650,7 +1650,7 @@ libhal_device_set_property_string (LibHa
 						  value, 0, 0, 0.0f, FALSE, error);
 }
 
-/** 
+/**
  * libhal_device_set_property_int:
  * @ctx: the context for the connection to hald
  * @udi: the Unique Device Id
@@ -1676,7 +1676,7 @@ libhal_device_set_property_int (LibHalCo
 						  NULL, value, 0, 0.0f, FALSE, error);
 }
 
-/** 
+/**
  * libhal_device_set_property_uint64:
  * @ctx: the context for the connection to hald
  * @udi: the Unique Device Id
@@ -1702,7 +1702,7 @@ libhal_device_set_property_uint64 (LibHa
 						  NULL, 0, value, 0.0f, FALSE, error);
 }
 
-/** 
+/**
  * libhal_device_set_property_double:
  * @ctx: the context for the connection to hald
  * @udi: the Unique Device Id
@@ -1728,7 +1728,7 @@ libhal_device_set_property_double (LibHa
 						  NULL, 0, 0, value, FALSE, error);
 }
 
-/** 
+/**
  * libhal_device_set_property_bool:
  * @ctx: the context for the connection to hald
  * @udi: the Unique Device Id
@@ -1755,7 +1755,7 @@ libhal_device_set_property_bool (LibHalC
 }
 
 
-/** 
+/**
  * libhal_device_remove_property:
  * @ctx: the context for the connection to hald
  * @udi: the Unique Device Id
@@ -1835,7 +1835,7 @@ libhal_device_property_strlist_append (L
 	return TRUE;
 }
 
-/** 
+/**
  * libhal_device_property_strlist_prepend:
  * @ctx: the context for the connection to hald
  * @udi: the Unique Device Id
@@ -1890,7 +1890,7 @@ libhal_device_property_strlist_prepend (
 	return TRUE;
 }
 
-/** 
+/**
  * libhal_device_property_strlist_remove_index:
  * @ctx: the context for the connection to hald
  * @udi: the Unique Device Id
@@ -1945,7 +1945,7 @@ libhal_device_property_strlist_remove_in
 	return TRUE;
 }
 
-/** 
+/**
  * libhal_device_property_strlist_remove:
  * @ctx: the context for the connection to hald
  * @udi: the Unique Device Id
@@ -2000,7 +2000,7 @@ libhal_device_property_strlist_remove (L
 }
 
 
-/** 
+/**
  * libhal_device_lock:
  * @ctx: the context for the connection to hald
  * @udi: the Unique Device Id
@@ -2072,7 +2072,7 @@ libhal_device_lock (LibHalContext *ctx,
 	return TRUE;
 }
 
-/** 
+/**
  * libhal_device_unlock:
  * @ctx: the context for the connection to hald
  * @udi: the Unique Device Id
@@ -2126,7 +2126,7 @@ libhal_device_unlock (LibHalContext *ctx
 }
 
 
-/** 
+/**
  * libhal_new_device:
  * @ctx: the context for the connection to hald
  * @error: pointer to an initialized dbus error object for returning errors or NULL
@@ -2199,7 +2199,7 @@ libhal_new_device (LibHalContext *ctx, D
 }
 
 
-/** 
+/**
  * libhal_device_commit_to_gdl:
  * @ctx: the context for the connection to hald
  * @temp_udi: the temporary unique device id as returned by libhal_new_device()
@@ -2264,7 +2264,7 @@ libhal_device_commit_to_gdl (LibHalConte
 	return TRUE;
 }
 
-/** 
+/**
  * libhal_remove_device:
  * @ctx: the context for the connection to hald
  * @udi: the Unique device id.
@@ -2321,7 +2321,7 @@ libhal_remove_device (LibHalContext *ctx
 	return TRUE;
 }
 
-/** 
+/**
  * libhal_device_exists:
  * @ctx: the context for the connection to hald
  * @udi: the Unique device id.
@@ -2391,7 +2391,7 @@ libhal_device_exists (LibHalContext *ctx
 	return value;
 }
 
-/** 
+/**
  * libhal_device_property_exists:
  * @ctx: the context for the connection to hald
  * @udi: the Unique device id.
@@ -2462,7 +2462,7 @@ libhal_device_property_exists (LibHalCon
 	return value;
 }
 
-/** 
+/**
  * libhal_merge_properties:
  * @ctx: the context for the connection to hald
  * @target_udi: the Unique device id of target device to merge to
@@ -2604,7 +2604,7 @@ libhal_device_matches (LibHalContext *ct
 	return value;
 }
 
-/** 
+/**
  * libhal_device_print:
  * @ctx: the context for the connection to hald
  * @udi: the Unique Device Id
@@ -2686,7 +2686,7 @@ libhal_device_print (LibHalContext *ctx,
 	return TRUE;
 }
 
-/** 
+/**
  * libhal_manager_find_device_string_match:
  * @ctx: the context for the connection to hald
  * @key: name of the property
@@ -2761,7 +2761,7 @@ libhal_manager_find_device_string_match 
 }
 
 
-/** 
+/**
  * libhal_device_add_capability:
  * @ctx: the context for the connection to hald
  * @udi: the Unique Device Id
@@ -2816,7 +2816,7 @@ libhal_device_add_capability (LibHalCont
 	return TRUE;
 }
 
-/** 
+/**
  * libhal_device_query_capability:
  * @ctx: the context for the connection to hald
  * @udi: the Unique Device Id
@@ -2855,7 +2855,7 @@ libhal_device_query_capability (LibHalCo
 	return ret;
 }
 
-/** 
+/**
  * libhal_find_device_by_capability:
  * @ctx: the context for the connection to hald
  * @capability: the capability name
@@ -2925,7 +2925,7 @@ libhal_find_device_by_capability (LibHal
 	return hal_device_names;
 }
 
-/** 
+/**
  * libhal_device_property_watch_all:
  * @ctx: the context for the connection to hald
  * @error: pointer to an initialized dbus error object for returning errors or NULL
@@ -2951,7 +2951,7 @@ libhal_device_property_watch_all (LibHal
 }
 
 
-/** 
+/**
  * libhal_device_add_property_watch:
  * @ctx: the context for the connection to hald
  * @udi: the Unique Device Id
@@ -2986,7 +2986,7 @@ libhal_device_add_property_watch (LibHal
 }
 
 
-/** 
+/**
  * libhal_device_remove_property_watch:
  * @ctx: the context for the connection to hald
  * @udi: the Unique Device Id
@@ -3017,7 +3017,7 @@ libhal_device_remove_property_watch (Lib
 }
 
 
-/** 
+/**
  * libhal_ctx_new:
  *
  * Create a new LibHalContext
@@ -3045,7 +3045,7 @@ libhal_ctx_new (void)
 	return ctx;
 }
 
-/** 
+/**
  * libhal_ctx_set_cache:
  * @ctx: context to enable/disable cache for
  * @use_cache: whether or not to use cache
@@ -3064,7 +3064,7 @@ libhal_ctx_set_cache (LibHalContext *ctx
 	return TRUE;
 }
 
-/** 
+/**
  * libhal_ctx_set_dbus_connection:
  * @ctx: context to set connection for
  * @conn: DBus connection to use
@@ -3085,7 +3085,7 @@ libhal_ctx_set_dbus_connection (LibHalCo
 	return TRUE;
 }
 
-/** 
+/**
  * libhal_ctx_get_dbus_connection:
  * @ctx: context to get connection for
  *
@@ -3102,7 +3102,7 @@ libhal_ctx_get_dbus_connection (LibHalCo
 }
 
 
-/** 
+/**
  * libhal_ctx_init:
  * @ctx: Context for connection to hald (D-BUS connection should be set with libhal_ctx_set_dbus_connection)
  * @error: pointer to an initialized dbus error object for returning errors or NULL
@@ -3153,7 +3153,7 @@ libhal_ctx_init (LibHalContext *ctx, DBu
 	return TRUE;
 }
 
-/** 
+/**
  * libhal_ctx_init_direct:
  * @error: pointer to an initialized dbus error object for returning errors or NULL
  *
@@ -3194,7 +3194,7 @@ out:
 	return ctx;
 }
 
-/** 
+/**
  * libhal_ctx_shutdown:
  * @ctx: the context for the connection to hald
  * @error: pointer to an initialized dbus error object for returning errors or NULL
@@ -3237,7 +3237,7 @@ libhal_ctx_shutdown (LibHalContext *ctx,
 	return TRUE;
 }
 
-/** 
+/**
  * libhal_ctx_free:
  * @ctx: pointer to a LibHalContext
  *
@@ -3252,7 +3252,7 @@ libhal_ctx_free (LibHalContext *ctx)
 	return TRUE;
 }
 
-/** 
+/**
  * libhal_ctx_set_device_added:
  * @ctx: the context for the connection to hald
  * @callback: the function to call when a device is added
@@ -3270,7 +3270,7 @@ libhal_ctx_set_device_added (LibHalConte
 	return TRUE;
 }
 
-/** 
+/**
  * libhal_ctx_set_device_removed:
  * @ctx: the context for the connection to hald
  * @callback: the function to call when a device is removed
@@ -3288,7 +3288,7 @@ libhal_ctx_set_device_removed (LibHalCon
 	return TRUE;
 }
 
-/** 
+/**
  * libhal_ctx_set_device_new_capability:
  * @ctx: the context for the connection to hald
  * @callback: the function to call when a device gains a new capability
@@ -3306,7 +3306,7 @@ libhal_ctx_set_device_new_capability (Li
 	return TRUE;
 }
 
-/** 
+/**
  * libhal_ctx_set_device_lost_capability:
  * @ctx: the context for the connection to hald
  * @callback: the function to call when a device loses a capability
@@ -3324,7 +3324,7 @@ libhal_ctx_set_device_lost_capability (L
 	return TRUE;
 }
 
-/** 
+/**
  * libhal_ctx_set_device_property_modified:
  * @ctx: the context for the connection to hald
  * @callback: the function to call when a property is modified on a device
@@ -3342,7 +3342,7 @@ libhal_ctx_set_device_property_modified 
 	return TRUE;
 }
 
-/** 
+/**
  * libhal_ctx_set_device_condition:
  * @ctx: the context for the connection to hald
  * @callback: the function to call when a device emits a condition
@@ -3360,7 +3360,7 @@ libhal_ctx_set_device_condition (LibHalC
 	return TRUE;
 }
 
-/** 
+/**
  * libhal_string_array_length:
  * @str_array: array of strings to consider
  *
@@ -3383,7 +3383,7 @@ libhal_string_array_length (char **str_a
 }
 
 
-/** 
+/**
  * libhal_device_rescan:
  * @ctx: the context for the connection to hald
  * @udi: the Unique id of device
@@ -3443,7 +3443,7 @@ libhal_device_rescan (LibHalContext *ctx
 	return result;
 }
 
-/** 
+/**
  * libhal_device_reprobe:
  * @ctx: the context for the connection to hald
  * @udi: the Unique id of device
@@ -3504,7 +3504,7 @@ libhal_device_reprobe (LibHalContext *ct
 	return result;
 }
 
-/** 
+/**
  * libhal_device_emit_condition:
  * @ctx: the context for the connection to hald
  * @udi: the Unique Device Id
@@ -3577,7 +3577,7 @@ dbus_bool_t libhal_device_emit_condition
 	return result;	
 }
 
-/** 
+/**
  * libhal_device_addon_is_ready:
  * @ctx: the context for the connection to hald
  * @udi: the Unique Device Id
@@ -3642,7 +3642,7 @@ libhal_device_addon_is_ready (LibHalCont
 	return result;	
 }
 
-/** 
+/**
  * libhal_device_claim_interface:
  * @ctx: the context for the connection to hald
  * @udi: the Unique Device Id
@@ -4500,7 +4500,7 @@ libhal_device_is_caller_locked_out (LibH
 }
 
 
-/** 
+/**
  * libhal_ctx_set_global_interface_lock_acquired:
  * @ctx: the context for the connection to hald
  * @callback: the callback
@@ -4517,7 +4517,7 @@ libhal_ctx_set_global_interface_lock_acq
 	return TRUE;
 }
 
-/** 
+/**
  * libhal_ctx_set_global_interface_lock_released:
  * @ctx: the context for the connection to hald
  * @callback: the callback
@@ -4535,7 +4535,7 @@ libhal_ctx_set_global_interface_lock_rel
 }
 
 
-/** 
+/**
  * libhal_ctx_set_interface_lock_acquired:
  * @ctx: the context for the connection to hald
  * @callback: the callback
@@ -4552,7 +4552,7 @@ libhal_ctx_set_interface_lock_acquired (
 	return TRUE;
 }
 
-/** 
+/**
  * libhal_ctx_set_interface_lock_released:
  * @ctx: the context for the connection to hald
  * @callback: the callback
@@ -4639,3 +4639,84 @@ libhal_device_is_locked_by_others (LibHa
 	return value;
 }
 
+/**
+ * libhal_device_is_caller_privileged:
+ * @ctx: the context for the connection to hald
+ * @udi: the Unique id of device
+ * @privilege: the privilege to check for
+ * @caller: the caller to check for
+ * @error: pointer to an initialized dbus error object for returning errors
+ * 
+ * Determines if a given caller have a given privilege on a given
+ * device. Will always error out if HAL is not built with PolicyKit
+ * support.
+ * 
+ * Returns: The textual reply from PolicyKit. See the #PolicyKitResult
+ * enumeration in the PolicyKit documentation for details. The caller
+ * is responsible for freeing this string with the function
+ * libhal_free_string().
+ **/
+char*
+libhal_device_is_caller_privileged (LibHalContext *ctx,
+                                    const char *udi,
+                                    const char *privilege,
+                                    const char *caller,
+                                    DBusError *error)
+{
+	DBusMessage *message;
+	DBusMessageIter iter;
+	DBusMessage *reply;
+	DBusMessageIter reply_iter;
+        char *dbus_str;
+        char *value;
+
+	LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL);
+	LIBHAL_CHECK_PARAM_VALID(udi, "*udi", NULL);
+	LIBHAL_CHECK_PARAM_VALID(privilege, "*privilege", NULL);
+	LIBHAL_CHECK_PARAM_VALID(caller, "*caller", NULL);
+
+	message = dbus_message_new_method_call ("org.freedesktop.Hal",
+						udi,
+						"org.freedesktop.Hal.Device",
+						"IsCallerPrivileged");
+
+	if (message == NULL) {
+		fprintf (stderr,
+			 "%s %d : Couldn't allocate D-BUS message\n",
+			 __FILE__, __LINE__);
+		return NULL;
+	}
+
+	dbus_message_iter_init_append (message, &iter);
+	dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &privilege);
+	dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &caller);
+	
+	reply = dbus_connection_send_with_reply_and_block (ctx->connection,
+							   message, -1,
+							   error);
+
+	if (error != NULL && dbus_error_is_set (error)) {
+		dbus_message_unref (message);
+		return NULL;
+	}
+
+	dbus_message_unref (message);
+
+	if (reply == NULL)
+		return NULL;
+
+	/* now analyze reply */
+	dbus_message_iter_init (reply, &reply_iter);
+	if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_STRING) {
+		dbus_message_unref (message);
+		dbus_message_unref (reply);
+		return NULL;
+	}
+	dbus_message_iter_get_basic (&reply_iter, &dbus_str);
+	value = (char *) ((dbus_str != NULL) ? strdup (dbus_str) : NULL);
+	if (value == NULL) {
+		fprintf (stderr, "%s %d : error allocating memory\n", __FILE__, __LINE__);
+	}
+	dbus_message_unref (reply);
+	return value;
+}
diff --git a/libhal/libhal.h b/libhal/libhal.h
index 015406c..9df5dad 100644
--- a/libhal/libhal.h
+++ b/libhal/libhal.h
@@ -713,6 +713,13 @@ dbus_bool_t libhal_device_is_locked_by_o
                                                const char *interface,
                                                DBusError *error);
 
+/* Determine if a given caller is privileged (requires HAL to be built with PolicyKit support) */
+char* libhal_device_is_caller_privileged (LibHalContext *ctx,
+                                          const char *udi,
+                                          const char *privilege,
+                                          const char *caller,
+                                          DBusError *error);
+
 
 #if defined(__cplusplus)
 }
diff --git a/privileges/Makefile.am b/privileges/Makefile.am
index 805dc67..9754140 100644
--- a/privileges/Makefile.am
+++ b/privileges/Makefile.am
@@ -1,17 +1,26 @@
 
 if HAVE_POLKIT
-polkit_privilegedir = $(sysconfdir)/PolicyKit/privilege.d
+polkit_privilegedir = $(sysconfdir)/PolicyKit/privileges
+
+dist_polkit_privilege_DATA =    \
+	hal-storage.priv	\
+	hal-power.priv		\
+	hal-killswitch.priv
+
+if HAVE_ACLMGMT
+dist_polkit_privilege_DATA += hal-device-file.priv
+endif
+
+check:
+	for f in $(dist_polkit_privilege_DATA); do \
+          echo "Validating privilege file: $$f"; \
+          $(POLKIT_PRIVILEGE_FILE_VALIDATE) --file $(srcdir)/$$f; \
+          if [ "$$?" != "0" ]; then \
+            echo "failed"; \
+            exit 1; \
+          fi; \
+        done
 
-dist_polkit_privilege_DATA =                              \
-	hal-storage-fixed-mount.privilege                 \
-	hal-storage-fixed-mount-all-options.privilege     \
-	hal-storage-removable-mount.privilege             \
-	hal-storage-removable-mount-all-options.privilege \
-	hal-power-suspend.privilege                       \
-	hal-power-hibernate.privilege                     \
-	hal-power-poweroff.privilege                      \
-	hal-power-reboot.privilege                        \
-	hal-power-cpufreq.privilege
 endif
 
 clean-local :
diff --git a/privileges/hal-device-file.priv b/privileges/hal-device-file.priv
new file mode 100644
index 0000000..0888f50
--- /dev/null
+++ b/privileges/hal-device-file.priv
@@ -0,0 +1,70 @@
+# -*- Conf -*-
+#
+# Privilege definitions for HAL's ACL management mechanism.
+#
+# Copyright (c) 2007 David Zeuthen <david at fubar.dk>
+# 
+# HAL is licensed to you under your choice of the the Academic Free
+# License Version 2.1, or the GNU General Public License version
+# 2. Some individual source files may be under the GPL only. See
+# COPYING for details.
+#
+# NOTE: If you make changes to this file, make sure to validate the
+# file using the polkit-privilege-file-validate(1) tool. Changes made
+# to this file are applied instantly.
+
+# Directly access sound devices
+[Privilege hal-device-file-sound]
+AllowRemoteInactive=no
+AllowRemoteActive=no
+AllowLocalInactive=no
+AllowLocalActive=yes
+
+# Directly access video4linux devices
+[Privilege hal-device-file-video4linux]
+AllowRemoteInactive=no
+AllowRemoteActive=no
+AllowLocalInactive=no
+AllowLocalActive=yes
+
+# Directly access optical drives
+[Privilege hal-device-file-cdrom]
+AllowRemoteInactive=no
+AllowRemoteActive=no
+AllowLocalInactive=yes
+AllowLocalActive=yes
+
+# Directly access DVB devices
+[Privilege hal-device-file-dvb]
+AllowRemoteInactive=no
+AllowRemoteActive=no
+AllowLocalInactive=no
+AllowLocalActive=yes
+
+# Directly access digital cameras
+[Privilege hal-device-file-camera]
+AllowRemoteInactive=no
+AllowRemoteActive=no
+AllowLocalInactive=no
+AllowLocalActive=yes
+
+# Directly access scanners
+[Privilege hal-device-file-scanner]
+AllowRemoteInactive=no
+AllowRemoteActive=no
+AllowLocalInactive=no
+AllowLocalActive=yes
+
+# Directly access Firewire IIDC devices
+[Privilege hal-device-file-ieee1394-iidc]
+AllowRemoteInactive=no
+AllowRemoteActive=no
+AllowLocalInactive=no
+AllowLocalActive=yes
+
+# Directly access Firewire AVC devices
+[Privilege hal-device-file-ieee1394-avc]
+AllowRemoteInactive=no
+AllowRemoteActive=no
+AllowLocalInactive=no
+AllowLocalActive=yes
diff --git a/privileges/hal-killswitch.priv b/privileges/hal-killswitch.priv
new file mode 100644
index 0000000..413aa4b
--- /dev/null
+++ b/privileges/hal-killswitch.priv
@@ -0,0 +1,28 @@
+# -*- Conf -*-
+#
+# Privilege definitions for HAL's RF kill switching mechanism.
+#
+# Copyright (c) 2007 David Zeuthen <david at fubar.dk>
+# 
+# HAL is licensed to you under your choice of the the Academic Free
+# License Version 2.1, or the GNU General Public License version
+# 2. Some individual source files may be under the GPL only. See
+# COPYING for details.
+#
+# NOTE: If you make changes to this file, make sure to validate the
+# file using the polkit-privilege-file-validate(1) tool. Changes made
+# to this file are applied instantly.
+
+# Turn Bluetooth radio on/off
+[Privilege hal-killswitch-bluetooth]
+AllowRemoteInactive=no
+AllowRemoteActive=no
+AllowLocalInactive=no
+AllowLocalActive=yes
+
+# Turn Wireless 802.11 radio on/off
+[Privilege hal-killswitch-wlan]
+AllowRemoteInactive=no
+AllowRemoteActive=no
+AllowLocalInactive=no
+AllowLocalActive=yes
diff --git a/privileges/hal-power-cpufreq.privilege b/privileges/hal-power-cpufreq.privilege
deleted file mode 100644
index 49df022..0000000
--- a/privileges/hal-power-cpufreq.privilege
+++ /dev/null
@@ -1,12 +0,0 @@
-
-# This privilege specifies who is allowed to control CPUFreq
-# via the org.freedesktop.Hal.Device.CPUFreq interface
-
-[Privilege]
-RequiredPrivileges=
-SufficientPrivileges=desktop-console
-Allow=uid:root
-Deny=
-CanObtain=True
-CanGrant=True
-ObtainRequireRoot=False
diff --git a/privileges/hal-power-hibernate.privilege b/privileges/hal-power-hibernate.privilege
deleted file mode 100644
index 0fd5037..0000000
--- a/privileges/hal-power-hibernate.privilege
+++ /dev/null
@@ -1,11 +0,0 @@
-
-# This privilege specifies who is allowed to hibernate the system.
-
-[Privilege]
-RequiredPrivileges=
-SufficientPrivileges=desktop-console
-Allow=uid:root
-Deny=
-CanObtain=True
-CanGrant=True
-ObtainRequireRoot=False
diff --git a/privileges/hal-power-poweroff.privilege b/privileges/hal-power-poweroff.privilege
deleted file mode 100644
index 4c7dce0..0000000
--- a/privileges/hal-power-poweroff.privilege
+++ /dev/null
@@ -1,11 +0,0 @@
-
-# This privilege specifies who is allowed to power off the system.
-
-[Privilege]
-RequiredPrivileges=desktop-console
-SufficientPrivileges=
-Allow=uid:__all__
-Deny=
-CanObtain=True
-CanGrant=True
-ObtainRequireRoot=False
diff --git a/privileges/hal-power-reboot.privilege b/privileges/hal-power-reboot.privilege
deleted file mode 100644
index 58fe826..0000000
--- a/privileges/hal-power-reboot.privilege
+++ /dev/null
@@ -1,12 +0,0 @@
-
-# This privilege specifies who is allowed to reboot the system.
-
-[Privilege]
-RequiredPrivileges=desktop-console
-SufficientPrivileges=
-Allow=uid:__all__
-Deny=
-CanObtain=True
-CanGrant=True
-ObtainRequireRoot=False
-
diff --git a/privileges/hal-power-suspend.privilege b/privileges/hal-power-suspend.privilege
deleted file mode 100644
index 2f39d07..0000000
--- a/privileges/hal-power-suspend.privilege
+++ /dev/null
@@ -1,12 +0,0 @@
-
-# This privilege specifies who is allowed to suspend the system.
-
-[Privilege]
-RequiredPrivileges=
-SufficientPrivileges=desktop-console
-Allow=uid:root
-Deny=
-CanObtain=True
-CanGrant=True
-ObtainRequireRoot=False
-
diff --git a/privileges/hal-power.priv b/privileges/hal-power.priv
new file mode 100644
index 0000000..da5d8e0
--- /dev/null
+++ b/privileges/hal-power.priv
@@ -0,0 +1,91 @@
+# -*- Conf -*-
+#
+# Privilege definitions for HAL's power management mechanisms.
+#
+# Copyright (c) 2007 David Zeuthen <david at fubar.dk>
+# 
+# HAL is licensed to you under your choice of the the Academic Free
+# License Version 2.1, or the GNU General Public License version
+# 2. Some individual source files may be under the GPL only. See
+# COPYING for details.
+#
+# NOTE: If you make changes to this file, make sure to validate the
+# file using the polkit-privilege-file-validate(1) tool. Changes made
+# to this file are applied instantly.
+
+# Shutdown the computer
+[Privilege hal-power-shutdown]
+AllowRemoteInactive=no
+AllowRemoteActive=no
+AllowLocalInactive=no
+AllowLocalActive=yes
+
+# Shutdown computer when multiple users are logged in
+[Privilege hal-power-shutdown-multiple-sessions]
+AllowRemoteInactive=no
+AllowRemoteActive=no
+AllowLocalInactive=no
+AllowLocalActive=auth_root
+
+# Reboot the computer
+[Privilege hal-power-reboot]
+AllowRemoteInactive=no
+AllowRemoteActive=no
+AllowLocalInactive=no
+AllowLocalActive=yes
+
+# Reboot the computer when multiple users are logged in
+[Privilege hal-power-reboot-multiple-sessions]
+AllowRemoteInactive=no
+AllowRemoteActive=no
+AllowLocalInactive=no
+AllowLocalActive=auth_root
+
+# Configure the system to prefer power savings
+[Privilege hal-power-set-powersave]
+AllowRemoteInactive=no
+AllowRemoteActive=no
+AllowLocalInactive=no
+AllowLocalActive=yes
+
+# Suspend the system
+[Privilege hal-power-suspend]
+AllowRemoteInactive=no
+AllowRemoteActive=no
+AllowLocalInactive=no
+AllowLocalActive=yes
+
+# Hibernate the system
+[Privilege hal-power-hibernate]
+AllowRemoteInactive=no
+AllowRemoteActive=no
+AllowLocalInactive=no
+AllowLocalActive=yes
+
+# Configure CPU frequency scaling
+[Privilege hal-power-cpufreq]
+AllowRemoteInactive=no
+AllowRemoteActive=no
+AllowLocalInactive=no
+AllowLocalActive=yes
+
+# Set laptop panel brightness
+[Privilege hal-power-lcd-panel]
+AllowRemoteInactive=no
+AllowRemoteActive=no
+AllowLocalInactive=no
+AllowLocalActive=yes
+
+# Read values from ambient light sensor
+[Privilege hal-power-light-sensor]
+AllowRemoteInactive=no
+AllowRemoteActive=no
+AllowLocalInactive=no
+AllowLocalActive=yes
+
+# Set the keyboard backlight
+[Privilege hal-power-keyboard-backlight]
+AllowRemoteInactive=no
+AllowRemoteActive=no
+AllowLocalInactive=no
+AllowLocalActive=yes
diff --git a/privileges/hal-storage-fixed-mount-all-options.privilege b/privileges/hal-storage-fixed-mount-all-options.privilege
deleted file mode 100644
index 825cb2f..0000000
--- a/privileges/hal-storage-fixed-mount-all-options.privilege
+++ /dev/null
@@ -1,14 +0,0 @@
-
-# This privilege specifies what users can mount volumes from internal
-# drives using mount options besides those specified in the
-# volume.mount.valid_options on the volume in question (such as
-# uid=<userid>).
-
-[Privilege]
-RequiredPrivileges=desktop-console
-SufficientPrivileges=
-Allow=
-Deny=
-CanObtain=True
-CanGrant=True
-ObtainRequireRoot=True
diff --git a/privileges/hal-storage-fixed-mount.privilege b/privileges/hal-storage-fixed-mount.privilege
deleted file mode 100644
index 5d839ef..0000000
--- a/privileges/hal-storage-fixed-mount.privilege
+++ /dev/null
@@ -1,16 +0,0 @@
-
-# This privilege specifies what users can mount volumes from internal
-# drives using only the mount options as specified by the property
-# volume.mount.valid_options on the volume in question. If mount
-# options besides these are needed, one will need the privilege
-# hal-storage-fixed-mount-all-options.privilege.
-#
-
-[Privilege]
-RequiredPrivileges=desktop-console
-SufficientPrivileges=
-Allow=
-Deny=
-CanObtain=True
-CanGrant=True
-ObtainRequireRoot=True
diff --git a/privileges/hal-storage-removable-mount-all-options.privilege b/privileges/hal-storage-removable-mount-all-options.privilege
deleted file mode 100644
index 52186e9..0000000
--- a/privileges/hal-storage-removable-mount-all-options.privilege
+++ /dev/null
@@ -1,14 +0,0 @@
-
-# This privilege specifies what users can mount volumes from removable
-# or hotpluggable drives using mount options besides those specified
-# in the volume.mount.valid_options on the volume in question (such as
-# uid=<userid>).
-
-[Privilege]
-RequiredPrivileges=desktop-console
-SufficientPrivileges=
-Allow=
-Deny=
-CanObtain=True
-CanGrant=True
-ObtainRequireRoot=False
diff --git a/privileges/hal-storage-removable-mount.privilege b/privileges/hal-storage-removable-mount.privilege
deleted file mode 100644
index 9d6928f..0000000
--- a/privileges/hal-storage-removable-mount.privilege
+++ /dev/null
@@ -1,15 +0,0 @@
-
-# This privilege specifies what users can mount volumes from removable
-# or hotpluggable drives using only the mount options as specified by
-# the property volume.mount.valid_options on the volume in
-# question. If mount options besides these are needed, one will need
-# the privilege hal-removable-fixed-mount-all-options.privilege.
-
-[Privilege]
-RequiredPrivileges=desktop-console
-SufficientPrivileges=
-Allow=uid:__all__
-Deny=
-CanObtain=True
-CanGrant=True
-ObtainRequireRoot=False
diff --git a/privileges/hal-storage.priv b/privileges/hal-storage.priv
new file mode 100644
index 0000000..2022833
--- /dev/null
+++ b/privileges/hal-storage.priv
@@ -0,0 +1,49 @@
+# -*- Conf -*-
+#
+# Privilege definitions for HAL's drives/media mechanims.
+#
+# Copyright (c) 2007 David Zeuthen <david at fubar.dk>
+# 
+# HAL is licensed to you under your choice of the the Academic Free
+# License Version 2.1, or the GNU General Public License version
+# 2. Some individual source files may be under the GPL only. See
+# COPYING for details.
+#
+# NOTE: If you make changes to this file, make sure to validate the
+# file using the polkit-privilege-file-validate(1) tool. Changes made
+# to this file are instantly applied.
+
+# Mount file systems from internal drives
+[Privilege hal-storage-mount-fixed]
+AllowRemoteInactive=no
+AllowRemoteActive=no
+AllowLocalInactive=no
+AllowLocalActive=auth_self_keep_always
+
+# Mount file systems from removable/hotpluggable drives
+[Privilege hal-storage-mount-removable]
+AllowRemoteInactive=no
+AllowRemoteActive=no
+AllowLocalInactive=no
+AllowLocalActive=yes
+
+# Unmount file systems mounted by other users
+[Privilege hal-storage-unmount-others]
+AllowRemoteInactive=no
+AllowRemoteActive=no
+AllowLocalInactive=no
+AllowLocalActive=auth_self_keep_always
+
+# Eject media from drives
+[Privilege hal-storage-eject]
+AllowRemoteInactive=no
+AllowRemoteActive=no
+AllowLocalInactive=no
+AllowLocalActive=yes
+
+# Set up decryption for encrypted storage devices
+[Privilege hal-storage-crypto-setup]
+AllowRemoteInactive=no
+AllowRemoteActive=no
+AllowLocalInactive=no
+AllowLocalActive=yes
diff --git a/tools/Makefile.am b/tools/Makefile.am
index d8839e6..0fca49c 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -33,6 +33,10 @@ bin_PROGRAMS =                    \
 	hal-lock		  \
 	hal-disable-polling
 
+if HAVE_POLKIT
+bin_PROGRAMS += hal-is-caller-privileged
+endif
+
 lshal_SOURCES = lshal.c
 lshal_LDADD = @GLIB_LIBS@ $(top_builddir)/libhal/libhal.la
 
@@ -60,6 +64,11 @@ hal_lock_LDADD = @GLIB_LIBS@ @DBUS_LIBS@
 hal_disable_polling_SOURCES = hal-disable-polling.c
 hal_disable_polling_LDADD = @GLIB_LIBS@ @DBUS_LIBS@ $(top_builddir)/libhal/libhal.la
 
+if HAVE_POLKIT
+hal_is_caller_privileged_SOURCES = hal-is-caller-privileged.c
+hal_is_caller_privileged_LDADD = @DBUS_LIBS@ $(top_builddir)/libhal/libhal.la
+endif
+
 libexec_PROGRAMS =                          \
 	hal-storage-mount	            \
 	hal-storage-unmount 	            \
@@ -83,7 +92,7 @@ if HAVE_ACLMGMT
 libexec_PROGRAMS += hal-acl-tool
 
 hal_acl_tool_SOURCES = hal-acl-tool.c
-hal_acl_tool_LDADD = @GLIB_LIBS@ $(top_builddir)/libhal/libhal.la
+hal_acl_tool_LDADD = @GLIB_LIBS@ @POLKIT_LIBS@ $(top_builddir)/libhal/libhal.la
 endif
 
 hal_system_power_pm_is_supported_SOURCES = hal-system-power-pm-is-supported.c
@@ -132,7 +141,8 @@ script_SCRIPTS =				\
 	hal-system-lcd-set-brightness		\
 	hal-system-power-set-power-save		\
 	hal-system-killswitch-get-power		\
-	hal-system-killswitch-set-power
+	hal-system-killswitch-set-power		\
+	hal-functions
 
 EXTRA_DIST=$(man_MANS) $(MAN_IN_FILES) gen-libgphoto-hal-fdi $(script_SCRIPTS)
 
diff --git a/tools/hal-acl-tool.c b/tools/hal-acl-tool.c
index e272575..e110ac3 100644
--- a/tools/hal-acl-tool.c
+++ b/tools/hal-acl-tool.c
@@ -33,6 +33,7 @@
 
 #include <glib.h>
 #include <libhal.h>
+#include <libpolkit/libpolkit.h>
 
 /* How this works (or "An introduction to this code")
  *
@@ -111,6 +112,8 @@ enum {
 	HAL_ACL_GID
 };
 
+static PolKitContext *pk_context = NULL;
+
 static void
 hal_acl_free (ACLCurrent *ha)
 {
@@ -336,6 +339,7 @@ visit_seats_and_sessions (SeatSessionVis
 	/* for all seats */
 	for (i = 0; seats[i] != NULL; i++) {
 		char *seat = seats[i];
+                char *seat_id;
 		char **sessions;
 		int num_sessions_on_seat;
 
@@ -349,11 +353,13 @@ visit_seats_and_sessions (SeatSessionVis
 		sessions = g_strsplit (s, "\t", 0);
 		num_sessions_on_seat = g_strv_length (sessions);
 
-		visitor_cb (seat, num_sessions_on_seat, NULL, 0, FALSE, FALSE, user_data);
+                seat_id = g_strdup_printf ("/org/freedesktop/ConsoleKit/%s", seat);
+		visitor_cb (seat_id, num_sessions_on_seat, NULL, 0, FALSE, FALSE, user_data);
 
 		/* for all sessions on seat */
 		for (j = 0; sessions[j] != NULL; j++) {
 			char *session = sessions[j];
+                        char *session_id;
 			gboolean session_is_local;
 			gboolean session_is_active;
 			uid_t session_uid;
@@ -390,11 +396,15 @@ visit_seats_and_sessions (SeatSessionVis
 				goto out;
 			}
 
-			visitor_cb (seat, num_sessions_on_seat, 
-				    session, session_uid, session_is_local, session_is_active, user_data);
+                        session_id = g_strdup_printf ("/org/freedesktop/ConsoleKit/%s", session);
+
+			visitor_cb (seat_id, num_sessions_on_seat, 
+				    session_id, session_uid, session_is_local, session_is_active, user_data);
 
+                        g_free (session_id);
 		}
 		g_strfreev (sessions);
+                g_free (seat_id);
 	}
 	g_strfreev (seats);
 
@@ -409,14 +419,7 @@ typedef struct {
 	/* identifying the device */
 	char *udi;      /* HAL UDI of device */
 	char *device;   /* device file */
-
-	/* policy for how to apply ACL's (must be set by the caller prior to visiting the device) */
-
-	/* access is granted to any session on a local seat */
-	gboolean grant_to_local_seat;
-
-	/* access is granted only to active sessions on local seats */
-	gboolean grant_to_local_seat_active_only;
+        char *type;     /* type of device, access_control.type - used by PolicyKit */
 
 	/* will be set by the visitor */
 	GSList *uid;    /* list of uid's (int) that should have access to this device */
@@ -569,10 +572,17 @@ acl_for_device_set_device (ACLForDevice 
 }
 
 static void
+acl_for_device_set_type (ACLForDevice *afd, const char *type)
+{
+	afd->type = g_strdup (type);
+}
+
+static void
 acl_for_device_free (ACLForDevice* afd)
 {
 	g_free (afd->udi);
 	g_free (afd->device);
+	g_free (afd->type);
 	g_slist_free (afd->uid);
 	g_slist_free (afd->gid);
 	g_free (afd);
@@ -607,6 +617,12 @@ acl_device_added_visitor (const char *se
 	 */
 	for (i = afd_list; i != NULL; i = g_slist_next (i)) {
 		ACLForDevice *afd = (ACLForDevice *) i->data;
+                PolKitResult pk_result;
+                PolKitSeat *pk_seat;
+                PolKitSession *pk_session;
+                PolKitResource *pk_resource;
+                PolKitPrivilege *pk_privilege;
+                char *priv_name;
 
 		if (session_id == NULL) {
 			/* we only grant access to sessions - someone suggested that if a device is tied
@@ -619,26 +635,39 @@ acl_device_added_visitor (const char *se
 			continue;
 		}
 
+                pk_seat = libpolkit_seat_new ();
+                libpolkit_seat_set_ck_objref (pk_seat, seat_id);
 
-		/* apply the policy defined by grant_to_local_seat and grant_to_local_seat_active_only */
-
-		/* we only grant access to local seats... */
-		if (!session_is_local)
-			continue;
-
-		/* don't bother giving ACL's to root - he's almighty anyway */
-		if (session_uid == 0)
-			continue;
-
-		if (afd->grant_to_local_seat)
+                pk_session = libpolkit_session_new ();
+                libpolkit_session_set_seat (pk_session, pk_seat);
+                libpolkit_seat_unref (pk_seat);
+                libpolkit_session_set_ck_objref (pk_session, session_id);
+                libpolkit_session_set_uid (pk_session, session_uid);
+                libpolkit_session_set_ck_is_active (pk_session, session_is_active);
+                libpolkit_session_set_ck_is_local (pk_session, session_is_local);
+                /* TODO: FIXME: libpolkit_session_set_ck_remote_host (pk_session, );*/ 
+
+                pk_resource = libpolkit_resource_new();
+                libpolkit_resource_set_resource_type (pk_resource, "hal");
+                libpolkit_resource_set_resource_id (pk_resource, afd->udi);
+
+                pk_privilege = libpolkit_privilege_new();
+                priv_name = g_strdup_printf ("hal-device-file-%s", afd->type);
+                libpolkit_privilege_set_privilege_id (pk_privilege, priv_name);
+                g_free (priv_name);
+
+                /* Now ask PolicyKit if the given session should have access */
+                pk_result = libpolkit_can_session_access_resource (pk_context, 
+                                                                   pk_privilege,
+                                                                   pk_resource,
+                                                                   pk_session);
+                if (pk_result == LIBPOLKIT_RESULT_YES) {
 			afd_grant_to_uid (afd, session_uid);
-		else {
-			if (afd->grant_to_local_seat_active_only) {
-				if (session_is_active) {
-					afd_grant_to_uid (afd, session_uid);
-				}
-			}
-		}
+                }
+
+                libpolkit_privilege_unref (pk_privilege);
+                libpolkit_resource_unref (pk_resource);
+                libpolkit_session_unref (pk_session);
 	}
 
 }
@@ -778,6 +807,7 @@ acl_device_added (void)
 	char *s;
 	char *udi;
 	char *device;
+	char *type;
 	GSList *afd_list = NULL;
 	ACLForDevice *afd = NULL;
 
@@ -789,17 +819,15 @@ acl_device_added (void)
 	if ((device = getenv ("HAL_PROP_ACCESS_CONTROL_FILE")) == NULL)
 		goto out;
 
+	if ((type = getenv ("HAL_PROP_ACCESS_CONTROL_TYPE")) == NULL)
+		goto out;
+
 	afd = acl_for_device_new (udi);
 	acl_for_device_set_device (afd, device);
+	acl_for_device_set_type (afd, type);
 	afd_list = g_slist_prepend (NULL, afd);
 
 	/* get ACL granting policy from HAL properties */
-	if ((s = getenv ("HAL_PROP_ACCESS_CONTROL_GRANT_LOCAL_SESSION")) != NULL) {
-		afd->grant_to_local_seat = (strcmp (s, "true") == 0);
-	}
-	if ((s = getenv ("HAL_PROP_ACCESS_CONTROL_GRANT_LOCAL_ACTIVE_SESSION")) != NULL) {
-		afd->grant_to_local_seat_active_only = (strcmp (s, "true") == 0);
-	}
 	if ((s = getenv ("HAL_PROP_ACCESS_CONTROL_GRANT_USER")) != NULL) {
 		char **sv;
 		sv = g_strsplit (s, "\t", 0);
@@ -900,6 +928,7 @@ acl_reconfigure_all (void)
 		LibHalPropertySet *props;
 		LibHalPropertySetIterator psi;
 		char *device = NULL;
+                char *type = NULL;
 		ACLForDevice *afd;
 		char **sv;
 
@@ -916,10 +945,8 @@ acl_reconfigure_all (void)
 			key = libhal_psi_get_key (&psi);
 			if (strcmp (key, "access_control.file") == 0) {
 				device = libhal_psi_get_string (&psi);
-			} else if (strcmp (key, "access_control.grant_local_session") == 0) {
-				afd->grant_to_local_seat = libhal_psi_get_bool (&psi);
-			} else if (strcmp (key, "access_control.grant_local_active_session") == 0) {
-				afd->grant_to_local_seat_active_only = libhal_psi_get_bool (&psi);
+			} else if (strcmp (key, "access_control.type") == 0) {
+				type = libhal_psi_get_string (&psi);
 			} else if (strcmp (key, "access_control.grant_user") == 0) {
 				sv = libhal_psi_get_strlist (&psi);
 				afd_grant_to_uid_from_userlist (afd, sv);
@@ -933,11 +960,17 @@ acl_reconfigure_all (void)
 		if (device == NULL) {
 			printf ("%d: access_control.file not set for '%s'\n", getpid (), udis[i]);
 			goto out;
-		} else {
-			acl_for_device_set_device (afd, device);
-			afd_list = g_slist_prepend (afd_list, afd);
 		}
 
+		if (type == NULL) {
+			printf ("%d: access_control.type not set for '%s'\n", getpid (), udis[i]);
+			goto out;
+		}
+
+                acl_for_device_set_device (afd, device);
+                acl_for_device_set_type (afd, type);
+                afd_list = g_slist_prepend (afd_list, afd);
+
 		libhal_free_property_set (props);
 	}
 	libhal_free_string_array (udis);
@@ -1025,10 +1058,11 @@ acl_unlock (void)
 	printf ("%d: released lock on " PACKAGE_LOCALSTATEDIR "/lib/hal/acl-list\n", getpid ());
 }
 
-
 int
 main (int argc, char *argv[])
 {
+        GError *g_error;
+
 	if (argc != 2) {
 		printf ("hal-acl-tool should only be invoked by hald\n");
 		goto out;
@@ -1038,6 +1072,15 @@ main (int argc, char *argv[])
 		goto out;
 	}
 
+        printf ("foo='%s'\n", getenv ("POLKIT_PRIVILEGE_DIR"));
+
+        g_error = NULL;
+        pk_context = libpolkit_context_new (&g_error);
+        if (pk_context == NULL) {
+                printf ("Could not create PolicyKit context: %s", g_error->message);
+                goto out;
+        }
+
 	if (strcmp (argv[1], "--add-device") == 0) {
 		acl_device_added ();
 	} else if (strcmp (argv[1], "--remove-device") == 0) {
diff --git a/tools/hal-functions b/tools/hal-functions
new file mode 100755
index 0000000..347b952
--- /dev/null
+++ b/tools/hal-functions
@@ -0,0 +1,50 @@
+# -*-Shell-script-*-
+#
+# hal-functions         This file contains functions to be used by most or all
+#                       hal shell scripts
+
+hal_check_priv() {
+    if [ "$HAVE_POLKIT" = "1" -a -n $HAL_METHOD_INVOKED_BY_SYSTEMBUS_CONNECTION_NAME ]; then
+        local PRIVILEGE
+        local PK_RESULT
+        local RET
+        PRIVILEGE=$1
+        PK_RESULT=`hal-is-caller-privileged --udi $UDI --privilege $PRIVILEGE \
+            --caller $HAL_METHOD_INVOKED_BY_SYSTEMBUS_CONNECTION_NAME`
+        RET=$?
+        if [ "$RET" != "0" ]; then
+            echo "org.freedesktop.Hal.Device.Error" >&2
+            echo "Cannot determine if caller is privileged" >&2
+            exit 1
+        fi
+        if [ "$PK_RESULT" != "yes" ] ;then
+            echo "org.freedesktop.Hal.Device.PermissionDeniedByPolicy" >&2
+            echo "$PRIVILEGE $PK_RESULT <-- (privilege, result)" >&2
+            exit 1
+        fi
+    fi
+}
+
+hal_call_backend() {
+    local PROGRAM
+    PROGRAM=$(basename $0)
+    if [ -n "$HALD_UNAME_S" -a -x ./$HALD_UNAME_S/$PROGRAM-$HALD_UNAME_S ]; then
+        ./$HALD_UNAME_S/$PROGRAM-$HALD_UNAME_S $@
+    else
+        echo "org.freedesktop.Hal.Device.UnknownError" >&2
+        echo "No back-end for your operating system" >&2
+        exit 1
+    fi
+}
+
+hal_exec_backend() {
+    local PROGRAM
+    PROGRAM=$(basename $0)
+    if [ -n "$HALD_UNAME_S" -a -x ./$HALD_UNAME_S/$PROGRAM-$HALD_UNAME_S ]; then
+        exec ./$HALD_UNAME_S/$PROGRAM-$HALD_UNAME_S $@
+    else
+        echo "org.freedesktop.Hal.Device.UnknownError" >&2
+        echo "No back-end for your operating system" >&2
+        exit 1
+    fi
+}
diff --git a/tools/hal-is-caller-privileged.c b/tools/hal-is-caller-privileged.c
new file mode 100644
index 0000000..fe87571
--- /dev/null
+++ b/tools/hal-is-caller-privileged.c
@@ -0,0 +1,181 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * hal-is-caller-privileged.c : Determine if a caller is privileged
+ *
+ * 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
+ *
+ **************************************************************************/
+
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <getopt.h>
+
+#include <libhal.h>
+
+/** 
+ *  usage:
+ *  @argc:                Number of arguments given to program
+ *  @argv:                Arguments given to program
+ *
+ *  Print out program usage. 
+ */
+static void
+usage (int argc, char *argv[])
+{
+	fprintf (stderr,
+                 "\n"
+                 "usage : hal-is-caller-privileged --udi <udi> --privileged <interface>\n"
+                 "                                 --caller <caller-name>\n"
+                 "                                 [--help] [--version]\n");
+	fprintf (stderr,
+                 "\n"
+                 "        --udi            Unique Device Id\n"
+                 "        --privilege      Privilege to check for\n"
+                 "        --caller         The name of the caller\n"
+                 "        --version        Show version and exit\n"
+                 "        --help           Show this information and exit\n"
+                 "\n"
+                 "This program determines if a given process on the system bus is\n"
+                 "has a given PolicyKit privilege for a given device. If an error\n"
+                 "occurs this program exits with a non-zero exit code. Otherwise\n"
+                 "the textual reply will be printed on stdout and this program will\n"
+                 "exit with exit code 0. Note that only the super user (root)\n"
+                 "or other privileged users can use this tool.\n"
+                 "\n");
+}
+
+/** 
+ *  main:
+ *  @argc:                Number of arguments given to program
+ *  @argv:                Arguments given to program
+ *
+ *  Returns:              Return code
+ *
+ *  Main entry point 
+ */
+int
+main (int argc, char *argv[])
+{
+	char *udi = NULL;
+	char *privilege = NULL;
+	char *caller = NULL;
+        dbus_bool_t is_version = FALSE;
+        char *polkit_result;
+	DBusError error;
+        LibHalContext *hal_ctx;
+
+	if (argc <= 1) {
+		usage (argc, argv);
+		return 1;
+	}
+
+	while (1) {
+		int c;
+		int option_index = 0;
+		const char *opt;
+		static struct option long_options[] = {
+			{"udi", 1, NULL, 0},
+			{"privilege", 1, NULL, 0},
+			{"caller", 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, "udi") == 0) {
+				udi = strdup (optarg);
+			} else if (strcmp (opt, "caller") == 0) {
+				caller = strdup (optarg);
+			} else if (strcmp (opt, "privilege") == 0) {
+				privilege = strdup (optarg);
+			}
+			break;
+
+		default:
+			usage (argc, argv);
+			return 1;
+			break;
+		}
+	}
+
+	if (is_version) {
+		printf ("hal-is-caller-privileged " PACKAGE_VERSION "\n");
+		return 0;
+	}
+
+	if (udi == NULL || caller == NULL || privilege == NULL) {
+		usage (argc, argv);
+		return 1;
+	}
+
+	dbus_error_init (&error);	
+	if ((hal_ctx = libhal_ctx_new ()) == NULL) {
+		fprintf (stderr, "error: libhal_ctx_new\n");
+		return 1;
+	}
+	if (!libhal_ctx_set_dbus_connection (hal_ctx, dbus_bus_get (DBUS_BUS_SYSTEM, &error))) {
+		fprintf (stderr, "error: libhal_ctx_set_dbus_connection: %s: %s\n", error.name, error.message);
+		LIBHAL_FREE_DBUS_ERROR (&error);
+		return 1;
+	}
+	if (!libhal_ctx_init (hal_ctx, &error)) {
+		if (dbus_error_is_set(&error)) {
+			fprintf (stderr, "error: libhal_ctx_init: %s: %s\n", error.name, error.message);
+			dbus_error_free (&error);
+		}
+		fprintf (stderr, "Could not initialise connection to hald.\n"
+				 "Normally this means the HAL daemon (hald) is not running or not ready.\n");
+		return 1;
+	}
+
+        polkit_result = libhal_device_is_caller_privileged (hal_ctx,
+                                                            udi,
+                                                            privilege,
+                                                            caller,
+                                                            &error);
+        if (dbus_error_is_set (&error)) {
+		fprintf (stderr, "error: %s: %s\n", error.name, error.message);
+		dbus_error_free (&error);
+		return 1;
+        }
+
+        printf ("%s\n", polkit_result);
+        return 0;
+}
diff --git a/tools/hal-luks-setup b/tools/hal-luks-setup
index 4e91d55..91b0cb8 100755
--- a/tools/hal-luks-setup
+++ b/tools/hal-luks-setup
@@ -6,6 +6,8 @@
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License version 2.
 
+. hal-functions
+
 locked_out() {
 	echo "org.freedesktop.Hal.Device.InterfaceLocked" >&2
 	echo "Enclosing drive/volume is locked" >&2
@@ -37,10 +39,6 @@ if [ -n "$HAL_METHOD_INVOKED_BY_SYSTEMBU
     fi
 fi
 
-if [ -n "$HALD_UNAME_S" -a -x ./$HALD_UNAME_S/hal-luks-setup-$HALD_UNAME_S ]; then
-    exec ./$HALD_UNAME_S/hal-luks-setup-$HALD_UNAME_S $@
-else
-    echo "org.freedesktop.Hal.Device.UnknownError" >&2
-    echo "No back-end for your operating system" >&2
-    exit 1
-fi
+hal_check_priv hal-storage-crypto-setup
+
+hal_exec_backend
diff --git a/tools/hal-luks-teardown b/tools/hal-luks-teardown
index 1c987d0..f1753d0 100755
--- a/tools/hal-luks-teardown
+++ b/tools/hal-luks-teardown
@@ -38,10 +38,7 @@ if [ -n "$HAL_METHOD_INVOKED_BY_SYSTEMBU
     fi
 fi
 
-if [ -n "$HALD_UNAME_S" -a -x ./$HALD_UNAME_S/hal-luks-teardown-$HALD_UNAME_S ]; then
-    exec ./$HALD_UNAME_S/hal-luks-teardown-$HALD_UNAME_S $@
-else
-    echo "org.freedesktop.Hal.Device.UnknownError" >&2
-    echo "No back-end for your operating system" >&2
-    exit 1
-fi
+# TODO: this is a little sketchy; we should check for hal-storage-crypto-teardown-others
+hal_check_priv hal-storage-crypto-setup
+
+hal_exec_backend
diff --git a/tools/hal-storage-closetray.c b/tools/hal-storage-closetray.c
index 2d8f5de..7d89c9c 100644
--- a/tools/hal-storage-closetray.c
+++ b/tools/hal-storage-closetray.c
@@ -36,9 +36,6 @@
 
 #include <libhal.h>
 #include <libhal-storage.h>
-#ifdef HAVE_POLKIT
-#include <libpolkit.h>
-#endif
 
 #include "hal-storage-shared.h"
 
@@ -77,9 +74,6 @@ main (int argc, char *argv[])
 	DBusError error;
 	LibHalContext *hal_ctx = NULL;
 	DBusConnection *system_bus = NULL;
-#ifdef HAVE_POLKIT
-	LibPolKitContext *pol_ctx = NULL;
-#endif
 	char *invoked_by_uid;
 	char *invoked_by_syscon_name;
 	int i;
@@ -117,13 +111,6 @@ main (int argc, char *argv[])
 		}
 		usage ();
 	}
-#ifdef HAVE_POLKIT
-	pol_ctx = libpolkit_new_context (system_bus);
-	if (pol_ctx == NULL) {
-		printf ("Cannot get libpolkit context\n");
-		unknown_closetray_error ("Cannot get libpolkit context");
-	}
-#endif
 
 	/* read from stdin */
 	if (strlen (fgets (closetray_options, sizeof (closetray_options), stdin)) > 0)
@@ -160,9 +147,6 @@ main (int argc, char *argv[])
 
 	/* use handle_eject() with the closetray option */
 	handle_eject (hal_ctx, 
-#ifdef HAVE_POLKIT
-		      pol_ctx, 
-#endif
 		      libhal_drive_get_udi (drive),
 		      drive,
 		      libhal_drive_get_device_file (drive),
diff --git a/tools/hal-storage-eject.c b/tools/hal-storage-eject.c
index 0364c5f..90d31f7 100644
--- a/tools/hal-storage-eject.c
+++ b/tools/hal-storage-eject.c
@@ -35,9 +35,6 @@
 
 #include <libhal.h>
 #include <libhal-storage.h>
-#ifdef HAVE_POLKIT
-#include <libpolkit.h>
-#endif
 
 #include "hal-storage-shared.h"
 
@@ -82,9 +79,6 @@ main (int argc, char *argv[])
 	DBusError error;
 	LibHalContext *hal_ctx = NULL;
 	DBusConnection *system_bus = NULL;
-#ifdef HAVE_POLKIT
-	LibPolKitContext *pol_ctx = NULL;
-#endif
 	char *invoked_by_uid;
 	char *invoked_by_syscon_name;
 	char **volume_udis;
@@ -124,13 +118,6 @@ main (int argc, char *argv[])
 		}
 		usage ();
 	}
-#ifdef HAVE_POLKIT
-	pol_ctx = libpolkit_new_context (system_bus);
-	if (pol_ctx == NULL) {
-		printf ("Cannot get libpolkit context\n");
-		unknown_eject_error ("Cannot get libpolkit context");
-	}
-#endif
 
 	/* read from stdin */
 	if (strlen (fgets (eject_options, sizeof (eject_options), stdin)) > 0)
@@ -203,9 +190,6 @@ main (int argc, char *argv[])
 				unknown_eject_error ("Cannot obtain lock on /media/.hal-mtab");
 			}
 			handle_unmount (hal_ctx, 
-#ifdef HAVE_POLKIT
-					pol_ctx, 
-#endif
 					udi, volume_to_unmount, drive, 
 					libhal_volume_get_device_file (volume_to_unmount), 
 					invoked_by_uid, invoked_by_syscon_name,
@@ -224,9 +208,6 @@ main (int argc, char *argv[])
 
 	/* now attempt the eject */
 	handle_eject (hal_ctx, 
-#ifdef HAVE_POLKIT
-		      pol_ctx, 
-#endif
 		      libhal_drive_get_udi (drive),
 		      drive,
 		      libhal_drive_get_device_file (drive),
diff --git a/tools/hal-storage-mount.c b/tools/hal-storage-mount.c
index a5d0221..2730def 100644
--- a/tools/hal-storage-mount.c
+++ b/tools/hal-storage-mount.c
@@ -51,9 +51,6 @@
 
 #include <libhal.h>
 #include <libhal-storage.h>
-#ifdef HAVE_POLKIT
-#include <libpolkit.h>
-#endif
 
 #include "hal-storage-shared.h"
 
@@ -145,10 +142,10 @@ cannot_remount (const char *device)
 
 #ifdef HAVE_POLKIT
 static void
-permission_denied_privilege (const char *privilege, const char *uid)
+permission_denied_privilege (const char *privilege, const char *result)
 {
 	fprintf (stderr, "org.freedesktop.Hal.Device.PermissionDeniedByPolicy\n");
-	fprintf (stderr, "%s refused uid %s\n", privilege, uid);
+	fprintf (stderr, "%s %s <-- (privilege, result)\n", privilege, result);
 	exit (1);
 }
 #endif
@@ -443,9 +440,6 @@ map_fstype (const char *fstype)
 
 static void
 handle_mount (LibHalContext *hal_ctx, 
-#ifdef HAVE_POLKIT
-	      LibPolKitContext *pol_ctx, 
-#endif
 	      const char *udi,
 	      LibHalVolume *volume, LibHalDrive *drive, const char *device, 
 	      const char *invoked_by_uid, const char *invoked_by_syscon_name)
@@ -470,10 +464,6 @@ handle_mount (LibHalContext *hal_ctx, 
 	gboolean pol_change_uid;
 	char *privilege;
 	gboolean is_remount;
-#ifdef HAVE_POLKIT
-	gboolean allowed_by_privilege;
-	gboolean is_temporary_privilege;
-#endif
 	gboolean explicit_mount_point_given;
 	const char *end;
 #ifdef __FreeBSD__
@@ -740,15 +730,15 @@ handle_mount (LibHalContext *hal_ctx, 
 
 	if (pol_is_fixed) {
 		if (pol_change_uid) {
-			privilege = "hal-storage-fixed-mount-all-options";
+			privilege = "hal-storage-mount-fixed-extra-options";
 		} else {
-			privilege = "hal-storage-fixed-mount";
+			privilege = "hal-storage-mount-fixed";
 		}
 	} else {
 		if (pol_change_uid) {
-			privilege = "hal-storage-removable-mount-all-options";
+			privilege = "hal-storage-mount-removable-extra-options"; /* TODO: rethink "extra-options" */
 		} else {
-			privilege = "hal-storage-removable-mount";
+			privilege = "hal-storage-mount-removable";
 		}
 	}
 
@@ -759,22 +749,20 @@ handle_mount (LibHalContext *hal_ctx, 
 
 #ifdef HAVE_POLKIT
         if (invoked_by_syscon_name != NULL) {
-                if (libpolkit_is_uid_allowed_for_privilege (pol_ctx, 
-                                                            invoked_by_syscon_name,
-                                                            invoked_by_uid,
-                                                            privilege,
-                                                            udi,
-                                                            &allowed_by_privilege,
-                                                            &is_temporary_privilege,
-                                                            NULL) != LIBPOLKIT_RESULT_OK) {
-                        printf ("cannot lookup privilege\n");
-                        unknown_error ("Cannot lookup privilege from PolicyKit");
+                char *polkit_result;
+                dbus_error_init (&error);
+                polkit_result = libhal_device_is_caller_privileged (hal_ctx,
+                                                                    udi,
+                                                                    privilege,
+                                                                    invoked_by_syscon_name,
+                                                                    &error);
+                if (polkit_result == NULL){
+                        unknown_error ("IsCallerPrivileged() failed");
                 }
-
-                if (!allowed_by_privilege) {
-                        printf ("caller don't possess privilege\n");
-                        permission_denied_privilege (privilege, invoked_by_uid);
+                if (strcmp (polkit_result, "yes") != 0) {
+                        permission_denied_privilege (privilege, polkit_result);
                 }
+                libhal_free_string (polkit_result);
         }
 #endif
 
@@ -994,9 +982,6 @@ main (int argc, char *argv[])
 	DBusError error;
 	LibHalContext *hal_ctx = NULL;
 	DBusConnection *system_bus = NULL;
-#ifdef HAVE_POLKIT
-	LibPolKitContext *pol_ctx = NULL;
-#endif
 	char *invoked_by_uid;
 	char *invoked_by_syscon_name;
 
@@ -1034,13 +1019,6 @@ main (int argc, char *argv[])
 		}
 		usage ();
 	}
-#ifdef HAVE_POLKIT
-	pol_ctx = libpolkit_new_context (system_bus);
-	if (pol_ctx == NULL) {
-		printf ("Cannot get libpolkit context\n");
-		unknown_error ("Cannot get libpolkit context");
-	}
-#endif
 
 	volume = libhal_volume_from_udi (hal_ctx, udi);
 	if (volume == NULL) {
@@ -1051,9 +1029,6 @@ main (int argc, char *argv[])
 			usage ();
 		} else {
 			handle_mount (hal_ctx, 
-#ifdef HAVE_POLKIT
-				      pol_ctx, 
-#endif
 				      udi, NULL, drive, device, invoked_by_uid, 
 				      invoked_by_syscon_name);
 		}
@@ -1071,9 +1046,6 @@ main (int argc, char *argv[])
 			unknown_error ("Cannot get drive from hal");
 		
 		handle_mount (hal_ctx, 
-#ifdef HAVE_POLKIT
-			      pol_ctx, 
-#endif
 			      udi, volume, drive, device, invoked_by_uid, 
 			      invoked_by_syscon_name);
 
diff --git a/tools/hal-storage-shared.c b/tools/hal-storage-shared.c
index 26e7ccd..2c8f3ca 100644
--- a/tools/hal-storage-shared.c
+++ b/tools/hal-storage-shared.c
@@ -259,10 +259,10 @@ not_mounted_by_hal (const char *detail)
 }
 
 static void
-permission_denied_privilege (const char *privilege, const char *uid)
+permission_denied_privilege (const char *privilege, const char *result)
 {
 	fprintf (stderr, "org.freedesktop.Hal.Device.PermissionDeniedByPolicy\n");
-	fprintf (stderr, "%s refused uid %s\n", privilege, uid);
+	fprintf (stderr, "%s %s <-- (privilege, result)\n", privilege, result);
 	exit (1);
 }
 
@@ -276,9 +276,6 @@ permission_denied_volume_ignore (const c
 
 void
 handle_unmount (LibHalContext *hal_ctx, 
-#ifdef HAVE_POLKIT
-		LibPolKitContext *pol_ctx, 
-#endif
 		const char *udi,
 		LibHalVolume *volume, LibHalDrive *drive, const char *device, 
 		const char *invoked_by_uid, const char *invoked_by_syscon_name,
@@ -410,14 +407,39 @@ line_found:
 		not_mounted_by_hal ("Device to unmount is not in /media/.hal-mtab so it is not mounted by HAL");
 	}
 
-	/* bail out, unless if we got the "hal-storage-can-unmount-volumes-mounted-by-others" privilege only
-	 * if mounted_by_other_uid==TRUE 
+        /* NOTE: it doesn't make sense to require a privilege a'la
+         * "hal-storage-unmount" because we only allow user to unmount
+         * volumes mounted by himself in the first place... and it
+         * would be odd to allow Mount() but disallow Unmount()...
+         */
+
+	/* if mounted_by_other_uid==TRUE: bail out, unless if we got the 
+         *                                "hal-storage-unmount-volumes-mounted-by-others"
 	 *
 	 * We allow uid 0 to actually ensure that Unmount(options=["lazy"], "/dev/blah") works from addon-storage.
 	 */
 	if ((strcmp (invoked_by_uid, "0") != 0) && mounted_by_other_uid) {
-		/* TODO: actually check for privilege "hal-storage-can-unmount-volumes-mounted-by-others" */
-		permission_denied_privilege ("hal-storage-can-unmount-volumes-mounted-by-others", invoked_by_uid);
+                const char *privilege = "hal-storage-unmount-others";
+#ifdef HAVE_POLKIT
+                if (invoked_by_syscon_name != NULL) {
+                        char *polkit_result;
+                        dbus_error_init (&error);
+                        polkit_result = libhal_device_is_caller_privileged (hal_ctx,
+                                                                            udi,
+                                                                            privilege,
+                                                                            invoked_by_syscon_name,
+                                                                            &error);
+                        if (polkit_result == NULL){
+                                unknown_error ("IsCallerPrivileged() failed");
+                        }
+                        if (strcmp (polkit_result, "yes") != 0) {
+                                permission_denied_privilege (privilege, polkit_result);
+                        }
+                        libhal_free_string (polkit_result);
+                }
+#else
+                permission_denied_privilege (privilege, "no");
+#endif
 	}
 
 	/* create new .hal-mtab~ file without the entry we're going to unmount */
@@ -512,9 +534,6 @@ line_found:
 
 void
 handle_eject (LibHalContext *hal_ctx, 
-#ifdef HAVE_POLKIT
-	      LibPolKitContext *pol_ctx, 
-#endif
 	      const char *udi,
 	      LibHalDrive *drive, const char *device, 
 	      const char *invoked_by_uid, const char *invoked_by_syscon_name,
@@ -528,6 +547,7 @@ handle_eject (LibHalContext *hal_ctx, 
 	int na;
 	int fd;
 	int num_excl_tries;
+        DBusError error;
 
 	/* When called here all the file systems from this device is
 	 * already unmounted. That's actually guaranteed; see
@@ -571,7 +591,25 @@ try_open_excl_again:
 	}
 	close (fd);
 
-	/* TODO: should we require privileges here? */
+#ifdef HAVE_POLKIT
+        if (invoked_by_syscon_name != NULL) {
+                char *polkit_result;
+                const char *privilege = "hal-storage-eject";
+                dbus_error_init (&error);
+                polkit_result = libhal_device_is_caller_privileged (hal_ctx,
+                                                                    udi,
+                                                                    privilege,
+                                                                    invoked_by_syscon_name,
+                                                                    &error);
+                if (polkit_result == NULL){
+                        unknown_error ("IsCallerPrivileged() failed");
+                }
+                if (strcmp (polkit_result, "yes") != 0) {
+                        permission_denied_privilege (privilege, polkit_result);
+                }
+                libhal_free_string (polkit_result);
+        }
+#endif
 
 #ifdef DEBUG
 	printf ("device                           = %s\n", device);
diff --git a/tools/hal-storage-shared.h b/tools/hal-storage-shared.h
index 529cf49..1910085 100644
--- a/tools/hal-storage-shared.h
+++ b/tools/hal-storage-shared.h
@@ -26,9 +26,6 @@
 
 #include <libhal.h>
 #include <libhal-storage.h>
-#ifdef HAVE_POLKIT
-#include <libpolkit.h>
-#endif
 
 /*#define DEBUG*/
 #define DEBUG
@@ -49,18 +46,12 @@ void unknown_error (const char *detail);
 void bailout_if_drive_is_locked (LibHalContext *hal_ctx, LibHalDrive *drive, const char *invoked_by_syscon_name);
 
 void handle_unmount (LibHalContext *hal_ctx, 
-#ifdef HAVE_POLKIT
-		     LibPolKitContext *pol_ctx, 
-#endif
 		     const char *udi,
 		     LibHalVolume *volume, LibHalDrive *drive, const char *device, 
 		     const char *invoked_by_uid, const char *invoked_by_syscon_name,
 		     gboolean option_lazy, gboolean option_force);
 
 void handle_eject (LibHalContext *hal_ctx, 
-#ifdef HAVE_POLKIT
-		   LibPolKitContext *pol_ctx, 
-#endif
 		   const char *udi,
 		   LibHalDrive *drive, const char *device, 
 		   const char *invoked_by_uid, const char *invoked_by_syscon_name,
diff --git a/tools/hal-storage-unmount.c b/tools/hal-storage-unmount.c
index 9476033..0ea4d5e 100644
--- a/tools/hal-storage-unmount.c
+++ b/tools/hal-storage-unmount.c
@@ -50,9 +50,6 @@
 
 #include <libhal.h>
 #include <libhal-storage.h>
-#ifdef HAVE_POLKIT
-#include <libpolkit.h>
-#endif
 
 #include "hal-storage-shared.h"
 
@@ -81,9 +78,6 @@ main (int argc, char *argv[])
 	DBusError error;
 	LibHalContext *hal_ctx = NULL;
 	DBusConnection *system_bus = NULL;
-#ifdef HAVE_POLKIT
-	LibPolKitContext *pol_ctx = NULL;
-#endif
 	char *invoked_by_uid;
 	char *invoked_by_syscon_name;
 	int i;
@@ -127,13 +121,6 @@ main (int argc, char *argv[])
 		}
 		usage ();
 	}
-#ifdef HAVE_POLKIT
-	pol_ctx = libpolkit_new_context (system_bus);
-	if (pol_ctx == NULL) {
-		printf ("Cannot get libpolkit context\n");
-		unknown_error ("Cannot get libpolkit context");
-	}
-#endif
 
 	/* read from stdin */
 	if (strlen (fgets (unmount_options, sizeof (unmount_options), stdin)) > 0)
@@ -180,9 +167,6 @@ main (int argc, char *argv[])
 			usage ();
 		} else {
 			handle_unmount (hal_ctx, 
-#ifdef HAVE_POLKIT
-					pol_ctx, 
-#endif
 					udi, NULL, drive, device, invoked_by_uid, 
 					invoked_by_syscon_name, use_lazy, use_force);
 		}
@@ -200,9 +184,6 @@ main (int argc, char *argv[])
 			unknown_error ("Cannot get drive from hal");
 
 		handle_unmount (hal_ctx, 
-#ifdef HAVE_POLKIT
-				pol_ctx, 
-#endif
 				udi, volume, drive, device, invoked_by_uid, 
 				invoked_by_syscon_name, use_lazy, use_force);
 
diff --git a/tools/hal-system-killswitch-get-power b/tools/hal-system-killswitch-get-power
index 67ba021..8f46226 100755
--- a/tools/hal-system-killswitch-get-power
+++ b/tools/hal-system-killswitch-get-power
@@ -7,6 +7,8 @@
 # the Free Software Foundation; either version 2 of the License, or
 # (at your option) any later version.
 
+. hal-functions
+
 # Check for environment variables
 if [ -z "$HAL_PROP_KILLSWITCH_ACCESS_METHOD" ]; then
         echo "org.freedesktop.Hal.Device.UnknownError" >&2
@@ -15,12 +17,5 @@ if [ -z "$HAL_PROP_KILLSWITCH_ACCESS_MET
 	exit 1
 fi
 
-# TODO: check privilege
-
-if [ -n "$HALD_UNAME_S" -a -x ./$HALD_UNAME_S/hal-system-killswitch-get-power-$HALD_UNAME_S ]; then
-    exec ./$HALD_UNAME_S/hal-system-killswitch-get-power-$HALD_UNAME_S $@
-else
-    echo "org.freedesktop.Hal.Device.UnknownError" >&2
-    echo "No back-end for your operating system" >&2
-    exit 1
-fi
+hal_check_priv hal-killswitch-$HAL_PROP_KILLSWITCH_TYPE
+hal_exec_backend
diff --git a/tools/hal-system-killswitch-set-power b/tools/hal-system-killswitch-set-power
index 4175c60..cc65c81 100755
--- a/tools/hal-system-killswitch-set-power
+++ b/tools/hal-system-killswitch-set-power
@@ -7,6 +7,8 @@
 # the Free Software Foundation; either version 2 of the License, or
 # (at your option) any later version.
 
+. hal-functions
+
 # Check for environment variables
 if [ -z "$HAL_PROP_KILLSWITCH_ACCESS_METHOD" ] ; then
         echo "org.freedesktop.Hal.Device.UnknownError" >&2
@@ -15,16 +17,9 @@ if [ -z "$HAL_PROP_KILLSWITCH_ACCESS_MET
         exit 1
 fi
 
-# TODO: check privilege
-
-# read value for set bluetooth power
+# read value for setting power
 read value
 export value
 
-if [ -n "$HALD_UNAME_S" -a -x ./$HALD_UNAME_S/hal-system-killswitch-set-power-$HALD_UNAME_S ]; then
-    exec ./$HALD_UNAME_S/hal-system-killswitch-set-power-$HALD_UNAME_S $@
-else
-    echo "org.freedesktop.Hal.Device.UnknownError" >&2
-    echo "No back-end for your operating system" >&2
-    exit 1
-fi
+hal_check_priv hal-killswitch-$HAL_PROP_KILLSWITCH_TYPE
+hal_exec_backend
diff --git a/tools/hal-system-lcd-get-brightness b/tools/hal-system-lcd-get-brightness
index e647095..afa92d2 100755
--- a/tools/hal-system-lcd-get-brightness
+++ b/tools/hal-system-lcd-get-brightness
@@ -7,6 +7,8 @@
 # the Free Software Foundation; either version 2 of the License, or
 # (at your option) any later version.
 
+. hal-functions
+
 # Check for environment variables
 if [ -z "$HAL_PROP_LAPTOP_PANEL_ACCESS_METHOD" -a -z "$HAL_PROP_LINUX_SYSFS_PATH" ]; then
         echo "org.freedesktop.Hal.Device.UnknownError" >&2
@@ -15,12 +17,5 @@ if [ -z "$HAL_PROP_LAPTOP_PANEL_ACCESS_M
 	exit 1
 fi
 
-# TODO: check privilege
-
-if [ -n "$HALD_UNAME_S" -a -x ./$HALD_UNAME_S/hal-system-lcd-get-brightness-$HALD_UNAME_S ]; then
-    exec ./$HALD_UNAME_S/hal-system-lcd-get-brightness-$HALD_UNAME_S $@
-else
-    echo "org.freedesktop.Hal.Device.UnknownError" >&2
-    echo "No back-end for your operating system" >&2
-    exit 1
-fi
+hal_check_priv hal-power-lcd-panel
+hal_exec_backend
diff --git a/tools/hal-system-lcd-set-brightness b/tools/hal-system-lcd-set-brightness
index f288f99..94c324b 100755
--- a/tools/hal-system-lcd-set-brightness
+++ b/tools/hal-system-lcd-set-brightness
@@ -7,6 +7,8 @@
 # the Free Software Foundation; either version 2 of the License, or
 # (at your option) any later version.
 
+. hal-functions
+
 # Check for environment variables
 if [ -z "$HAL_PROP_LAPTOP_PANEL_ACCESS_METHOD" -a -z "$HAL_PROP_LINUX_SYSFS_PATH" ] || 
    [ -z "$HAL_PROP_LAPTOP_PANEL_NUM_LEVELS" ] ; then
@@ -16,8 +18,6 @@ if [ -z "$HAL_PROP_LAPTOP_PANEL_ACCESS_M
         exit 1
 fi
 
-# TODO: check privilege
-
 # read value for set brightness
 read value
 
@@ -30,10 +30,5 @@ fi
 
 export value
 
-if [ -n "$HALD_UNAME_S" -a -x ./$HALD_UNAME_S/hal-system-lcd-set-brightness-$HALD_UNAME_S ]; then
-    exec ./$HALD_UNAME_S/hal-system-lcd-set-brightness-$HALD_UNAME_S $@
-else
-    echo "org.freedesktop.Hal.Device.UnknownError" >&2
-    echo "No back-end for your operating system" >&2
-    exit 1
-fi
+hal_check_priv hal-power-lcd-panel
+hal_exec_backend
diff --git a/tools/hal-system-power-hibernate b/tools/hal-system-power-hibernate
index ffdd330..c1d81db 100755
--- a/tools/hal-system-power-hibernate
+++ b/tools/hal-system-power-hibernate
@@ -1,24 +1,6 @@
 #!/bin/sh
 
-PRIVILEGE=hal-power-hibernate
-if [ "$HAVE_POLKIT" = "1" ] ; then
-    if [ "$HAL_METHOD_INVOKED_BY_UID" != "0" ] ; then
-	RESULT=$(polkit-is-privileged --privilege $PRIVILEGE \
-	    --user $HAL_METHOD_INVOKED_BY_UID \
-	    --system-bus-unique-name $HAL_METHOD_INVOKED_BY_SYSTEMBUS_CONNECTION_NAME 2>&1)
-	IS_PRIVILEGED=$?
-	if [ "$IS_PRIVILEGED" != "0" ] ; then
-	    echo org.freedesktop.Hal.Device.PermissionDeniedByPolicy >&2
-	    echo $PRIVILEGE refused uid $HAL_METHOD_INVOKED_BY_UID >&2
-	    exit 1
-	fi
-    fi
-fi
+. hal-functions
 
-if [ -n "$HALD_UNAME_S" -a -x ./$HALD_UNAME_S/hal-system-power-hibernate-$HALD_UNAME_S ]; then
-    exec ./$HALD_UNAME_S/hal-system-power-hibernate-$HALD_UNAME_S $@
-else
-    echo "org.freedesktop.Hal.Device.UnknownError" >&2
-    echo "No back-end for your operating system" >&2
-    exit 1
-fi
+hal_check_priv hal-power-hibernate
+hal_exec_backend
diff --git a/tools/hal-system-power-reboot b/tools/hal-system-power-reboot
index 1c93aac..5b551ad 100755
--- a/tools/hal-system-power-reboot
+++ b/tools/hal-system-power-reboot
@@ -1,24 +1,11 @@
 #!/bin/sh
 
-PRIVILEGE=hal-power-reboot
-if [ "$HAVE_POLKIT" = "1" ] ; then
-    if [ "$HAL_METHOD_INVOKED_BY_UID" != "0" ] ; then
-	RESULT=$(polkit-is-privileged --privilege $PRIVILEGE \
-	    --user $HAL_METHOD_INVOKED_BY_UID \
-	    --system-bus-unique-name $HAL_METHOD_INVOKED_BY_SYSTEMBUS_CONNECTION_NAME 2>&1)
-	IS_PRIVILEGED=$?
-	if [ "$IS_PRIVILEGED" != "0" ] ; then
-	    echo org.freedesktop.Hal.Device.PermissionDeniedByPolicy >&2
-	    echo $PRIVILEGE refused uid $HAL_METHOD_INVOKED_BY_UID >&2
-	    exit 1
-	fi
-    fi
-fi
+. hal-functions
 
-if [ -n "$HALD_UNAME_S" -a -x ./$HALD_UNAME_S/hal-system-power-reboot-$HALD_UNAME_S ]; then
-    exec ./$HALD_UNAME_S/hal-system-power-reboot-$HALD_UNAME_S $@
+if [ "$CK_NUM_SESSIONS" -gt "1" ] ; then
+    hal_check_priv hal-power-reboot-multiple-sessions
 else
-    echo "org.freedesktop.Hal.Device.UnknownError" >&2
-    echo "No back-end for your operating system" >&2
-    exit 1
+    hal_check_priv hal-power-reboot
 fi
+
+hal_exec_backend
diff --git a/tools/hal-system-power-set-power-save b/tools/hal-system-power-set-power-save
index a7bd972..3cd88dc 100755
--- a/tools/hal-system-power-set-power-save
+++ b/tools/hal-system-power-set-power-save
@@ -1,15 +1,11 @@
 #!/bin/sh
 
+. hal-functions
+
 read value
 
-if [ -n "$HALD_UNAME_S" -a -x ./$HALD_UNAME_S/hal-system-power-set-power-save-$HALD_UNAME_S ]; then
-    ./$HALD_UNAME_S/hal-system-power-set-power-save-$HALD_UNAME_S $value
-    if [ "x$?" = "x0" ]; then
-        hal-set-property --udi $HAL_PROP_INFO_UDI \
-        --key "power_management.is_powersave_set" --bool "$value"
-    fi
-else
-    echo "org.freedesktop.Hal.Device.UnknownError" >&2
-    echo "No back-end for your operating system" >&2
-    exit 1
+hal_check_priv hal-power-set-powersave
+hal_call_backend $value
+if [ "$?" = "0" ]; then
+    hal-set-property --udi $UDI --key "power_management.is_powersave_set" --bool "$value"
 fi
diff --git a/tools/hal-system-power-shutdown b/tools/hal-system-power-shutdown
index df3d14a..6016214 100755
--- a/tools/hal-system-power-shutdown
+++ b/tools/hal-system-power-shutdown
@@ -1,24 +1,11 @@
 #!/bin/sh
 
-PRIVILEGE=hal-power-poweroff
-if [ "$HAVE_POLKIT" = "1" ] ; then
-    if [ "$HAL_METHOD_INVOKED_BY_UID" != "0" ] ; then
-	RESULT=$(polkit-is-privileged --privilege $PRIVILEGE \
-	    --user $HAL_METHOD_INVOKED_BY_UID \
-	    --system-bus-unique-name $HAL_METHOD_INVOKED_BY_SYSTEMBUS_CONNECTION_NAME 2>&1)
-	IS_PRIVILEGED=$?
-	if [ "$IS_PRIVILEGED" != "0" ] ; then
-	    echo org.freedesktop.Hal.Device.PermissionDeniedByPolicy >&2
-	    echo $PRIVILEGE refused uid $HAL_METHOD_INVOKED_BY_UID >&2
-	    exit 1
-	fi
-    fi
-fi
+. hal-functions
 
-if [ -n "$HALD_UNAME_S" -a -x ./$HALD_UNAME_S/hal-system-power-shutdown-$HALD_UNAME_S ]; then
-    exec ./$HALD_UNAME_S/hal-system-power-shutdown-$HALD_UNAME_S $@
+if [ "$CK_NUM_SESSIONS" -gt "1" ] ; then
+    hal_check_priv hal-power-shutdown-multiple-sessions
 else
-    echo "org.freedesktop.Hal.Device.UnknownError" >&2
-    echo "No back-end for your operating system" >&2
-    exit 1
+    hal_check_priv hal-power-shutdown
 fi
+
+hal_exec_backend
diff --git a/tools/hal-system-power-suspend b/tools/hal-system-power-suspend
index bd698b7..43f7346 100755
--- a/tools/hal-system-power-suspend
+++ b/tools/hal-system-power-suspend
@@ -1,24 +1,6 @@
 #!/bin/sh
 
-PRIVILEGE=hal-power-suspend
-if [ "$HAVE_POLKIT" = "1" ] ; then
-    if [ "$HAL_METHOD_INVOKED_BY_UID" != "0" ] ; then
-	RESULT=$(polkit-is-privileged --privilege $PRIVILEGE \
-	    --user $HAL_METHOD_INVOKED_BY_UID \
-	    --system-bus-unique-name $HAL_METHOD_INVOKED_BY_SYSTEMBUS_CONNECTION_NAME 2>&1)
-	IS_PRIVILEGED=$?
-	if [ "$IS_PRIVILEGED" != "0" ] ; then
-	    echo org.freedesktop.Hal.Device.PermissionDeniedByPolicy >&2
-	    echo $PRIVILEGE refused uid $HAL_METHOD_INVOKED_BY_UID >&2
-	    exit 1
-	fi
-    fi
-fi
+. hal-functions
 
-if [ -n "$HALD_UNAME_S" -a -x ./$HALD_UNAME_S/hal-system-power-suspend-$HALD_UNAME_S ]; then
-    exec ./$HALD_UNAME_S/hal-system-power-suspend-$HALD_UNAME_S $@
-else
-    echo "org.freedesktop.Hal.Device.UnknownError" >&2
-    echo "No back-end for your operating system" >&2
-    exit 1
-fi
+hal_check_priv hal-power-suspend
+hal_exec_backend
diff --git a/tools/hal-system-power-suspend-hybrid b/tools/hal-system-power-suspend-hybrid
index e851fe8..43f7346 100755
--- a/tools/hal-system-power-suspend-hybrid
+++ b/tools/hal-system-power-suspend-hybrid
@@ -1,56 +1,6 @@
 #!/bin/sh
 
-PRIVILEGE=hal-power-suspend
-if [ "$HAVE_POLKIT" = "1" ] ; then
-    if [ "$HAL_METHOD_INVOKED_BY_UID" != "0" ] ; then
-	RESULT=$(polkit-is-privileged --privilege $PRIVILEGE \
-	    --user $HAL_METHOD_INVOKED_BY_UID \
-	    --system-bus-unique-name $HAL_METHOD_INVOKED_BY_SYSTEMBUS_CONNECTION_NAME 2>&1)
-	IS_PRIVILEGED=$?
-	if [ "$IS_PRIVILEGED" != "0" ] ; then
-	    echo org.freedesktop.Hal.Device.PermissionDeniedByPolicy >&2
-	    echo $PRIVILEGE refused uid $HAL_METHOD_INVOKED_BY_UID >&2
-	    exit 1
-	fi
-    fi
-fi
+. hal-functions
 
-alarm_not_supported() {
-	echo org.freedesktop.Hal.Device.SystemPowerManagement.AlarmNotSupported >&2
-	echo Waking the system up is not supported >&2
-	exit 1
-}
-
-unsupported() {
-	echo org.freedesktop.Hal.Device.SystemPowerManagement.NotSupported >&2
-	echo No suspend-hybrid method found >&2
-	exit 1
-}
-
-read seconds_to_sleep
-
-# Make a suitable command line argument so that the tools can do the correct
-# quirks for video resume.
-# Passing the quirks to the tool allows the tool to not depend on HAL for data.
-QUIRKS=""
-[ "$HAL_PROP_POWER_MANAGEMENT_QUIRK_S3_BIOS" = "true" ] && QUIRKS="$QUIRKS --quirk-s3-bios"
-[ "$HAL_PROP_POWER_MANAGEMENT_QUIRK_S3_MODE" = "true" ] && QUIRKS="$QUIRKS --quirk-s3-mode"
-[ "$HAL_PROP_POWER_MANAGEMENT_QUIRK_DPMS_SUSPEND" = "true" ] && QUIRKS="$QUIRKS --quirk-dpms-suspend"
-[ "$HAL_PROP_POWER_MANAGEMENT_QUIRK_DPMS_ON" = "true" ] && QUIRKS="$QUIRKS --quirk-dpms-on"
-[ "$HAL_PROP_POWER_MANAGEMENT_QUIRK_VBESTATE_RESTORE" = "true" ] && QUIRKS="$QUIRKS --quirk-vbestate"
-[ "$HAL_PROP_POWER_MANAGEMENT_QUIRK_VBEMODE_RESTORE" = "true" ] && QUIRKS="$QUIRKS --quirk-vbemode"
-[ "$HAL_PROP_POWER_MANAGEMENT_QUIRK_VGA_MODE_3" = "true" ] && QUIRKS="$QUIRKS --quirk-vga-mode3"
-[ "$HAL_PROP_POWER_MANAGEMENT_QUIRK_VBE_POST" = "true" ] && QUIRKS="$QUIRKS --quirk-vbepost"
-[ "$HAL_PROP_POWER_MANAGEMENT_QUIRK_RADEON_OFF" = "true" ] && QUIRKS="$QUIRKS --quirk-radeon-off"
-
-if [ -x "/usr/sbin/pm-suspend-hybrid" ] ; then
-    if [ $seconds_to_sleep != "0" ] ; then
-	alarm_not_supported
-    fi
-    /usr/sbin/pm-suspend-hybrid $QUIRKS
-    RET=$?
-else
-    unsupported
-fi
-
-exit $RET
+hal_check_priv hal-power-suspend
+hal_exec_backend
diff --git a/tools/linux/Makefile.am b/tools/linux/Makefile.am
index ea4e873..cd1fb80 100644
--- a/tools/linux/Makefile.am
+++ b/tools/linux/Makefile.am
@@ -10,6 +10,7 @@ script_SCRIPTS =					\
 	hal-luks-teardown-linux                       	\
 	hal-luks-remove-linux		                \
 	hal-system-power-suspend-linux			\
+	hal-system-power-suspend-hybrid-linux		\
 	hal-system-power-hibernate-linux		\
 	hal-system-power-shutdown-linux			\
 	hal-system-power-reboot-linux			\
diff --git a/tools/linux/hal-system-power-hibernate-linux b/tools/linux/hal-system-power-hibernate-linux
index 250e191..101a301 100755
--- a/tools/linux/hal-system-power-hibernate-linux
+++ b/tools/linux/hal-system-power-hibernate-linux
@@ -1,5 +1,8 @@
 #!/bin/sh
 
+echo "safety valve; exiting here... TODO: remove me"
+exit 0
+
 POWERSAVED_SUSPEND2DISK="dbus-send --system --dest=com.novell.powersave \
                          --print-reply /com/novell/powersave \
                          com.novell.powersave.action.SuspendToDisk"
diff --git a/tools/linux/hal-system-power-reboot-linux b/tools/linux/hal-system-power-reboot-linux
index 5c1d93d..79725cd 100755
--- a/tools/linux/hal-system-power-reboot-linux
+++ b/tools/linux/hal-system-power-reboot-linux
@@ -1,5 +1,8 @@
 #!/bin/sh
 
+echo "safety valve; exiting here... TODO: remove me"
+exit 0
+
 unsupported() {
 	echo "org.freedesktop.Hal.Device.SystemPowerManagement.NotSupported" >&2
 	echo "No reboot command found" >&2
diff --git a/tools/linux/hal-system-power-shutdown-linux b/tools/linux/hal-system-power-shutdown-linux
index 6a9811e..aa77a1d 100755
--- a/tools/linux/hal-system-power-shutdown-linux
+++ b/tools/linux/hal-system-power-shutdown-linux
@@ -1,5 +1,8 @@
 #!/bin/sh
 
+echo "safety valve; exiting here... TODO: remove me"
+exit 0
+
 unsupported() {
 	echo "org.freedesktop.Hal.Device.SystemPowerManagement.NotSupported" >&2
 	echo "No shutdown command found" >&2
diff --git a/tools/linux/hal-system-power-suspend-hybrid-linux b/tools/linux/hal-system-power-suspend-hybrid-linux
new file mode 100755
index 0000000..3bd1f0c
--- /dev/null
+++ b/tools/linux/hal-system-power-suspend-hybrid-linux
@@ -0,0 +1,41 @@
+#!/bin/sh
+
+alarm_not_supported() {
+	echo org.freedesktop.Hal.Device.SystemPowerManagement.AlarmNotSupported >&2
+	echo Waking the system up is not supported >&2
+	exit 1
+}
+
+unsupported() {
+	echo org.freedesktop.Hal.Device.SystemPowerManagement.NotSupported >&2
+	echo No suspend method found >&2
+	exit 1
+}
+
+read seconds_to_sleep
+
+echo "safety valve; exiting here... TODO: remove me"
+exit 0
+
+if [ -x "/usr/sbin/pm-suspend-hybrid" ] ; then
+    if [ $seconds_to_sleep != "0" ] ; then
+	alarm_not_supported
+    fi
+    /usr/sbin/pm-suspend-hybrid $QUIRKS
+    RET=$?
+else
+    unsupported
+fi
+
+# Refresh devices as a resume can do funny things
+for type in button battery ac_adapter
+do
+	devices=`hal-find-by-capability --capability $type`
+	for device in $devices
+	do
+		dbus-send --system --print-reply --dest=org.freedesktop.Hal \
+			  $device org.freedesktop.Hal.Device.Rescan
+	done
+done
+
+exit $RET
diff --git a/tools/linux/hal-system-power-suspend-linux b/tools/linux/hal-system-power-suspend-linux
index 8139842..9e3d2b3 100755
--- a/tools/linux/hal-system-power-suspend-linux
+++ b/tools/linux/hal-system-power-suspend-linux
@@ -18,6 +18,9 @@ unsupported() {
 
 read seconds_to_sleep
 
+echo "safety valve; exiting here... TODO: remove me"
+exit 0
+
 # Make a suitable command line argument so that the tools can do the correct
 # quirks for video resume.
 # Passing the quirks to the tool allows the tool to not depend on HAL for data.
@@ -32,7 +35,7 @@ QUIRKS=""
 [ "$HAL_PROP_POWER_MANAGEMENT_QUIRK_VBE_POST" = "true" ] && QUIRKS="$QUIRKS --quirk-vbepost"
 [ "$HAL_PROP_POWER_MANAGEMENT_QUIRK_RADEON_OFF" = "true" ] && QUIRKS="$QUIRKS --quirk-radeon-off"
 
-#PMU systems cannot use /sys/power/state yet, so use a helper to issue an ioctl
+# PMU systems cannot use /sys/power/state yet, so use a helper to issue an ioctl
 if [ "$HAL_PROP_LAPTOP_PANEL_ACCESS_METHOD" = "pmu" ]; then
 	hal-system-power-pmu sleep
 	if [ $? -ne 0 ]; then
@@ -42,7 +45,7 @@ if [ "$HAL_PROP_LAPTOP_PANEL_ACCESS_METH
 	exit 0
 fi
 
-#ALTLinux only supports powersave
+# ALTLinux only supports powersave
 if [ -f "/etc/altlinux-release" ]; then
 	if [ -x /usr/bin/powersave ] ; then
 	        $POWERSAVED_SUSPEND2RAM
@@ -52,7 +55,7 @@ if [ -f "/etc/altlinux-release" ]; then
 		unsupported
 	fi
 
-#Mandriva supports suspend-scripts 
+# Mandriva supports suspend-scripts 
 elif [ -f "/etc/mandriva-release" ] ; then 
     # TODO: fix pmsuspend to take a --wakeup-alarm argument 
     if [ $seconds_to_sleep != "0" ] ; then 
@@ -67,7 +70,7 @@ elif [ -f "/etc/mandriva-release" ] ; th
 	unsupported 
     fi 
 
-#RedHat/Fedora and SUSE support pm-utils
+# RedHat/Fedora and SUSE support pm-utils
 elif [ -f "/etc/redhat-release" ] || [ -f "/etc/fedora-release" ] \
 		|| [ -f "/etc/SuSE-release" ] ; then
 	# TODO: fix pm-suspend to take a --wakeup-alarm argument
@@ -84,7 +87,7 @@ elif [ -f "/etc/redhat-release" ] || [ -
 		unsupported
 	fi
 
-#Other distros just need to have *any* tools installed
+# Other distros just need to have *any* tools installed
 else
 	if [ -x "/usr/bin/powersave" ] ; then
 	    $POWERSAVED_SUSPEND2RAM
@@ -105,7 +108,7 @@ else
 	    fi
 	fi
 
-#Refresh devices as a resume can do funny things
+# Refresh devices as a resume can do funny things
 for type in button battery ac_adapter
 do
 	devices=`hal-find-by-capability --capability $type`


More information about the hal-commit mailing list