hal: Branch 'master'

David Zeuthen david at kemper.freedesktop.org
Mon Apr 9 12:22:03 PDT 2007


 hald/access-check.c                            |   42 ++++++----
 hald/access-check.h                            |    3 
 hald/ci-tracker.c                              |   94 ++++++++++++++++++++++++
 hald/debug-hald.sh                             |    3 
 hald/hald_dbus.c                               |   62 ++++++++++-----
 hald/linux/addons/addon-cpufreq.c              |    3 
 hald/linux/addons/addon-dell-backlight.cpp     |   11 +-
 hald/linux/addons/addon-macbookpro-backlight.c |   27 ++++--
 hald/run-hald.sh                               |    3 
 hald/valgrind-hald.sh                          |    2 
 libhal/libhal.c                                |   24 +++++-
 libhal/libhal.h                                |    3 
 policy/Makefile.am                             |    3 
 policy/hal-device-file.policy                  |   16 ++++
 tools/Makefile.am                              |    2 
 tools/hal-acl-tool.c                           |    1 
 tools/hal-functions                            |    8 +-
 tools/hal-is-caller-privileged.c               |   48 ++++++++++--
 tools/hal-storage-mount.c                      |   97 ++++++++++++++-----------
 tools/hal-storage-shared.c                     |   14 ++-
 20 files changed, 339 insertions(+), 127 deletions(-)

New commits:
diff-tree e4b6fcb25a2a954ca201781246cfae7acfb80214 (from c994c40ad21a3a956690757eb0193e73fdc8bf72)
Author: David Zeuthen <davidz at redhat.com>
Date:   Mon Apr 9 15:22:00 2007 -0400

    take advantage of new parameter API in PolKitAction
    
    These actions currently set parameters
    
     hal-storage-mount-[removable|fixed]:
      - fstype
      - mount-point
      - mount-options
    
     hal-lock
      - interface

diff --git a/hald/access-check.c b/hald/access-check.c
index 7a97845..2051b76 100644
--- a/hald/access-check.c
+++ b/hald/access-check.c
@@ -207,7 +207,8 @@ out:
  * access_check_caller_have_access_to_device:
  * @cit: the CITracker object
  * @device: the device to check for
- * @privilege: the PolicyKit privilege to check for
+ * @action: the PolicyKit action to check for
+ * @action_params: parameters (a #NULL terminated list of key/value pairs) to the action or #NULL
  * @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 
@@ -244,13 +245,15 @@ 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,
-                                           int        *polkit_result_out)
+access_check_caller_have_access_to_device (CITracker   *cit, 
+                                           HalDevice   *device, 
+                                           const char  *action, 
+                                           const char **action_params,
+                                           const char  *caller_unique_sysbus_name,
+                                           int         *polkit_result_out)
 #ifdef HAVE_CONKIT
 {
+        int n;
         gboolean ret;
         CICallerInfo *ci;
 #ifdef HAVE_POLKIT
@@ -284,8 +287,8 @@ access_check_caller_have_access_to_devic
         /* 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") && 
+        if (action != NULL && 
+            strcmp (action, "hal-lock") == 0 &&
             strcmp (hal_device_get_udi (device), "/org/freedesktop/Hal/devices/computer") == 0) {
                 ret = TRUE;
 #ifdef HAVE_POLKIT
@@ -296,6 +299,12 @@ access_check_caller_have_access_to_devic
         }
 
 #ifdef HAVE_POLKIT
+        pk_action = libpolkit_action_new ();
+        libpolkit_action_set_action_id (pk_action, action);
+        for (n = 0; action_params[n] != NULL; n += 2) {
+                libpolkit_action_set_param (pk_action, action_params[n], action_params[n+1]);
+        }
+        
         pk_caller = get_pk_caller_from_ci_tracker (cit, caller_unique_sysbus_name);
         if (pk_caller == NULL)
                 goto out;
@@ -304,9 +313,6 @@ access_check_caller_have_access_to_devic
         libpolkit_resource_set_resource_type (pk_resource, "hal");
         libpolkit_resource_set_resource_id (pk_resource, hal_device_get_udi (device));
 
-        pk_action = libpolkit_action_new ();
-        libpolkit_action_set_action_id (pk_action, privilege);
-
         pk_result = libpolkit_context_can_caller_access_resource (pk_context,
                                                                   pk_action,
                                                                   pk_resource,
@@ -393,9 +399,9 @@ access_check_caller_locked_out (CITracke
         HalDevice *computer;
         gboolean is_locked;
         gboolean is_locked_by_self;
-        char *priv;
+        const char *action_params[3] = {"interface", "", NULL};
 
-        priv = g_strdup_printf ("hal-lock:%s", interface_name);
+        action_params[1] = interface_name;
 
         global_lock_name = NULL;
         holders = NULL;
@@ -436,7 +442,7 @@ access_check_caller_locked_out (CITracke
                         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, priv, global_holders[n], NULL)) {
+                                            cit, device, "hal-lock", action_params, 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 */
@@ -448,7 +454,7 @@ access_check_caller_locked_out (CITracke
                                  * actually have access to the device...
                                  */
                                 if (access_check_caller_have_access_to_device (
-                                            cit, device, priv, global_holders[n], NULL)) {
+                                            cit, device, "hal-lock", action_params, global_holders[n], NULL)) {
                                         /* They certainly do. Mark as locked. */
                                         is_locked = TRUE;
                                 }
@@ -473,7 +479,6 @@ out:
         g_strfreev (global_holders);
         g_strfreev (holders);
         g_free (global_lock_name);
-        g_free (priv);
         return ret;
 }
 
@@ -504,6 +509,9 @@ access_check_locked_by_others (CITracker
         char **global_holders;
         HalDevice *computer;
         char *priv;
+        const char *action_params[3] = {"interface", "", NULL};
+
+        action_params[1] = interface_name;
 
         priv = g_strdup_printf ("hal-lock:%s", interface_name);
 
@@ -539,7 +547,7 @@ access_check_locked_by_others (CITracker
                             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, priv, global_holders[n], NULL)) {
+                                            cit, device, "hal-lock", action_params, global_holders[n], NULL)) {
                                         /* ... and they can can access the device */
                                         goto out;
                                 }
diff --git a/hald/access-check.h b/hald/access-check.h
index 2f3c34a..2b9a896 100644
--- a/hald/access-check.h
+++ b/hald/access-check.h
@@ -35,7 +35,8 @@ gboolean access_check_message_caller_is_
                                                      DBusMessage *message);
 gboolean access_check_caller_have_access_to_device  (CITracker   *cit,
                                                      HalDevice   *device,
-                                                     const char  *privilege,
+                                                     const char  *action,
+                                                     const char **action_params,
                                                      const char  *caller_unique_sysbus_name,
                                                      int         *polkit_result_out);
 gboolean access_check_caller_locked_out             (CITracker   *cit,
diff --git a/hald/ci-tracker.c b/hald/ci-tracker.c
index e1d31eb..085e0d8 100644
--- a/hald/ci-tracker.c
+++ b/hald/ci-tracker.c
@@ -41,6 +41,97 @@
 #include "logger.h"
 #include "ci-tracker.h"
 
+/* ripped from dbus/dbus-marshal-validate.c and adapted */
+
+/**
+ * Determine wether the given character is valid as the first character
+ * in a bus name.
+ */
+#define VALID_INITIAL_BUS_NAME_CHARACTER(c)         \
+  ( ((c) >= 'A' && (c) <= 'Z') ||               \
+    ((c) >= 'a' && (c) <= 'z') ||               \
+    ((c) == '_') || ((c) == '-'))
+
+
+/**
+ * Determine wether the given character is valid as a second or later
+ * character in a bus name
+ */
+#define VALID_BUS_NAME_CHARACTER(c)                 \
+  ( ((c) >= '0' && (c) <= '9') ||               \
+    ((c) >= 'A' && (c) <= 'Z') ||               \
+    ((c) >= 'a' && (c) <= 'z') ||               \
+    ((c) == '_') || ((c) == '-'))
+
+static gboolean
+validate_bus_name (const char *name)
+{
+        int len;
+        const char *s;
+        const char *end;
+        const char *last_dot;
+        gboolean ret;
+
+        s = name;
+        len = strlen (name);
+        end = name + len;
+        last_dot = NULL;
+
+        ret = FALSE;
+
+        /* check special cases of first char so it doesn't have to be done
+         * in the loop. Note we know len > 0
+         */
+        if (*s == ':') {
+                /* unique name */
+                ++s;
+                while (s != end) {
+                        if (*s == '.') {
+                                if (G_UNLIKELY ((s + 1) == end))
+                                        goto error;
+                                if (G_UNLIKELY (!VALID_BUS_NAME_CHARACTER (*(s + 1))))
+                                        goto error;
+                                ++s; /* we just validated the next char, so skip two */
+                        } else if (G_UNLIKELY (!VALID_BUS_NAME_CHARACTER (*s))) {
+                                goto error;
+                        }
+                        ++s;
+                }
+                return TRUE;
+        } else if (G_UNLIKELY (*s == '.')) /* disallow starting with a . */ {
+                goto error;
+        } else if (G_UNLIKELY (!VALID_INITIAL_BUS_NAME_CHARACTER (*s))) {
+                goto error;
+        } else {
+                ++s;
+        }
+        
+        while (s != end) {
+                if (*s == '.') {
+                        if (G_UNLIKELY ((s + 1) == end))
+                                goto error;
+                        else if (G_UNLIKELY (!VALID_INITIAL_BUS_NAME_CHARACTER (*(s + 1))))
+                                goto error;
+                        last_dot = s;
+                        ++s; /* we just validated the next char, so skip two */
+                } else if (G_UNLIKELY (!VALID_BUS_NAME_CHARACTER (*s))) {
+                        goto error;
+                }
+                ++s;
+        }
+        
+        if (G_UNLIKELY (last_dot == NULL))
+                goto error;
+
+        ret = TRUE;
+
+error:
+        if (!ret)
+                HAL_INFO (("name '%s' did not validate", name));
+        return ret;
+}
+
+
 struct CITracker_s {
         GHashTable *connection_name_to_caller_info;
         DBusConnection *dbus_connection;
@@ -185,6 +276,9 @@ ci_tracker_get_info (CITracker *cit, con
 	if (system_bus_unique_name == NULL)
 		goto error;
 
+        if (!validate_bus_name (system_bus_unique_name))
+                goto error;
+
 	/*HAL_INFO (("========================="));
 	  HAL_INFO (("Looking up CICallerInfo for system_bus_unique_name = %s", system_bus_unique_name));*/
 
diff --git a/hald/debug-hald.sh b/hald/debug-hald.sh
index 6a378ba..7d81989 100755
--- a/hald/debug-hald.sh
+++ b/hald/debug-hald.sh
@@ -17,8 +17,7 @@ if [ "$1" = "--skip-fdi-install" ] ; the
 else
     rm -rf $HALD_TMPDIR
     mkdir -p $HALD_TMPDIR
-    make -C ../privileges install DESTDIR=$HALD_TMPDIR prefix=/
-
+    make -C ../policy install DESTDIR=$HALD_TMPDIR prefix=/
     make -C ../fdi install DESTDIR=$HALD_TMPDIR prefix=/ && \
     if [ ! -d $information_fdidir ] ; then
     	echo "ERROR: You need to checkout hal-info in the same level"
diff --git a/hald/hald_dbus.c b/hald/hald_dbus.c
index 9e19bf6..3db89e0 100644
--- a/hald/hald_dbus.c
+++ b/hald/hald_dbus.c
@@ -2052,14 +2052,13 @@ device_acquire_interface_lock (DBusConne
 	}
 
         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);
+                const char *action_params[3] = {"interface", "", NULL};
+                action_params[1] = interface_name;
+                if (!access_check_caller_have_access_to_device (ci_tracker, d, "hal-lock", 
+                                                                action_params, sender, NULL)) {
                         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)) {
@@ -2199,11 +2198,13 @@ device_is_caller_privileged (DBusConnect
 	DBusMessage *reply;
 	DBusError error;
 	const char *sender;
-	char *privilege;
+	char *action;
 	char *caller_sysbus_name;
         int polkit_result;
         const char *result;
         DBusMessageIter iter;
+        DBusMessageIter array_iter;
+        GPtrArray *params;
 
 	HAL_TRACE (("entering"));
 
@@ -2220,14 +2221,27 @@ device_is_caller_privileged (DBusConnect
 
 	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");
+        if (strcmp (dbus_message_get_signature (message), "sass") != 0) {
+ 		raise_syntax (connection, message, "IsCallerPrivileged");
 		return DBUS_HANDLER_RESULT_HANDLED;
-	}
+        }
+
+        params = g_ptr_array_new ();
+
+	dbus_error_init (&error);
+        dbus_message_iter_init (message, &iter);
+        dbus_message_iter_get_basic (&iter, &action);
+        dbus_message_iter_next (&iter);
+        dbus_message_iter_recurse (&iter, &array_iter);
+        while (dbus_message_iter_get_arg_type (&array_iter) == DBUS_TYPE_STRING) {
+                const char *param;
+                dbus_message_iter_get_basic (&array_iter, &param);
+                g_ptr_array_add (params, g_strdup (param));
+                dbus_message_iter_next (&array_iter);
+        }
+        g_ptr_array_add (params, NULL);
+        dbus_message_iter_next (&iter);
+        dbus_message_iter_get_basic (&iter, &caller_sysbus_name);
 
         /* check whether we want to answer this question... */
         if (!local_interface && !access_check_message_caller_is_root_or_hal (ci_tracker, message)) {
@@ -2238,12 +2252,16 @@ device_is_caller_privileged (DBusConnect
                         raise_error (connection, message, 
                                      "org.freedesktop.Hal.Error", 
                                      "Could not determine caller info for sender");
+                        g_ptr_array_foreach (params, (GFunc) g_free, NULL);
+                        g_ptr_array_free (params, TRUE);
                         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");
+                        g_ptr_array_foreach (params, (GFunc) g_free, NULL);
+                        g_ptr_array_free (params, TRUE);
                         return DBUS_HANDLER_RESULT_HANDLED;
                 }
 
@@ -2251,6 +2269,8 @@ device_is_caller_privileged (DBusConnect
                 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");
+                        g_ptr_array_foreach (params, (GFunc) g_free, NULL);
+                        g_ptr_array_free (params, TRUE);
                         return DBUS_HANDLER_RESULT_HANDLED;
                 }
         }
@@ -2258,9 +2278,12 @@ device_is_caller_privileged (DBusConnect
 
         polkit_result = -1;
         access_check_caller_have_access_to_device (
-                ci_tracker, d, privilege, caller_sysbus_name, &polkit_result);
+                ci_tracker, d, action, (const char **) params->pdata, caller_sysbus_name, &polkit_result);
         result = libpolkit_result_to_string_representation (polkit_result);
 
+                        g_ptr_array_foreach (params, (GFunc) g_free, NULL);
+                        g_ptr_array_free (params, TRUE);
+
         if (polkit_result < 0 || result == NULL) {
 		raise_error (connection, message, 
                              "org.freedesktop.Hal.Error", 
@@ -4159,7 +4182,8 @@ do_introspect (DBusConnection  *connecti
 				       "      <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=\"action\" direction=\"in\" type=\"s\"/>\n"
+                                       "      <arg name=\"action_parameters\" type=\"as\"/>\n"
 				       "      <arg name=\"caller_sysbus_name\" direction=\"in\" type=\"s\"/>\n"
 				       "      <arg name=\"result\" direction=\"out\" type=\"s\"/>\n"
 				       "    </method>\n"
@@ -5089,21 +5113,19 @@ validate_lock_for_device (HalDeviceStore
                         continue;
 
                 for (m = 0; holders[m] != NULL; m++) {
-                        char *privilege;
+                        const char *action_params[3] = {"interface", "", NULL};
+                        action_params[1] = locked_interfaces[n];
 
                         HAL_INFO (("Validating lock holder '%s' on interface '%s' on udi '%s'",
                                    holders[m], locked_interfaces[n], hal_device_get_udi (device)));
 
-                        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)) {
+                                    ci_tracker, device, "hal-lock", action_params, 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/linux/addons/addon-cpufreq.c b/hald/linux/addons/addon-cpufreq.c
index bf6fba6..7ace00c 100644
--- a/hald/linux/addons/addon-cpufreq.c
+++ b/hald/linux/addons/addon-cpufreq.c
@@ -933,6 +933,7 @@ dbus_is_privileged (DBusConnection *conn
         polkit_result = libhal_device_is_caller_privileged (halctx,
                                                             udi,
                                                             CPUFREQ_POLKIT_PRIVILEGE,
+                                                            NULL,
                                                             invoked_by_syscon_name,
                                                             error);
         if (polkit_result == NULL) {
@@ -944,7 +945,7 @@ dbus_is_privileged (DBusConnection *conn
 
 		dbus_raise_error (connection, message, 
                                   "org.freedesktop.Hal.Device.PermissionDeniedByPolicy",
-                                  "%s %s <-- (privilege, result)",
+                                  "%s %s <-- (action, result)",
                                   CPUFREQ_POLKIT_PRIVILEGE, polkit_result);
                 goto out;
         }
diff --git a/hald/linux/addons/addon-dell-backlight.cpp b/hald/linux/addons/addon-dell-backlight.cpp
index 20658aa..b3282b5 100644
--- a/hald/linux/addons/addon-dell-backlight.cpp
+++ b/hald/linux/addons/addon-dell-backlight.cpp
@@ -120,7 +120,7 @@ write_backlight (u32 newBacklightValue, 
 }
 
 static gboolean
-check_priv (DBusConnection *connection, DBusMessage *message, const char *udi, const char *privilege)
+check_priv (DBusConnection *connection, DBusMessage *message, const char *udi, const char *action)
 #ifdef HAVE_POLKIT
 {
         gboolean ret;
@@ -137,14 +137,15 @@ check_priv (DBusConnection *connection, 
         dbus_error_init (&error);
         polkit_result = libhal_device_is_caller_privileged (halctx,
                                                             udi,
-                                                            privilege,
+                                                            action,
+                                                            NULL,
                                                             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);
+                                                       action, polkit_result);
                 dbus_connection_send (connection, reply, NULL);
                 goto out;
         }
@@ -152,8 +153,8 @@ check_priv (DBusConnection *connection, 
 
                 reply = dbus_message_new_error_printf (message,
                                                        "org.freedesktop.Hal.Device.PermissionDeniedByPolicy",
-                                                       "%s %s <-- (privilege, result)",
-                                                       privilege, polkit_result);
+                                                       "%s %s <-- (action, result)",
+                                                       action, polkit_result);
                 dbus_connection_send (connection, reply, NULL);
                 goto out;
         }
diff --git a/hald/linux/addons/addon-macbookpro-backlight.c b/hald/linux/addons/addon-macbookpro-backlight.c
index f6da198..d636661 100644
--- a/hald/linux/addons/addon-macbookpro-backlight.c
+++ b/hald/linux/addons/addon-macbookpro-backlight.c
@@ -216,7 +216,11 @@ read_keyboard_backlight (void)
 #endif
 
 static gboolean
-check_priv (DBusConnection *connection, DBusMessage *message, const char *udi, const char *privilege)
+check_priv (DBusConnection *connection, 
+            DBusMessage *message, 
+            const char *udi, 
+            const char *action,
+            char **action_params)
 #ifdef HAVE_POLKIT
 {
         gboolean ret;
@@ -233,14 +237,15 @@ check_priv (DBusConnection *connection, 
         dbus_error_init (&error);
         polkit_result = libhal_device_is_caller_privileged (halctx,
                                                             udi,
-                                                            privilege,
+                                                            action,
+                                                            action_params,
                                                             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);
+                                                       "Cannot determine if caller is privileged for action '%s'",
+                                                       action);
                 dbus_connection_send (connection, reply, NULL);
                 goto out;
         }
@@ -248,8 +253,8 @@ check_priv (DBusConnection *connection, 
 
                 reply = dbus_message_new_error_printf (message,
                                                        "org.freedesktop.Hal.Device.PermissionDeniedByPolicy",
-                                                       "%s %s <-- (privilege, result)",
-                                                       privilege, polkit_result);
+                                                       "%s %s <-- (action, result)",
+                                                       action, polkit_result);
                 dbus_connection_send (connection, reply, NULL);
                 goto out;
         }
@@ -292,7 +297,7 @@ filter_function (DBusConnection *connect
 					 "SetBrightness")) {
 		int brightness;
 
-                if (!check_priv (connection, message, udi, "hal-power-lcd-panel"))
+                if (!check_priv (connection, message, udi, "hal-power-lcd-panel", NULL))
                         goto error;
 
 		dbus_error_init (&err);
@@ -329,7 +334,7 @@ filter_function (DBusConnection *connect
 						"GetBrightness")) {
 		int brightness;
 
-                if (!check_priv (connection, message, udi, "hal-power-lcd-panel"))
+                if (!check_priv (connection, message, udi, "hal-power-lcd-panel", NULL))
                         goto error;
 
 		dbus_error_init (&err);
@@ -360,7 +365,7 @@ filter_function (DBusConnection *connect
 						"GetBrightness")) {
 		int brightness[2];
 
-                if (!check_priv (connection, message, udi, "hal-power-light-sensor"))
+                if (!check_priv (connection, message, udi, "hal-power-light-sensor", NULL))
                         goto error;
 
 		brightness[0] = read_light_sensor (FALSE); /* right */
@@ -387,7 +392,7 @@ filter_function (DBusConnection *connect
 						"org.freedesktop.Hal.Device.KeyboardBacklight", 
 						"GetBrightness")) {
 
-                if (!check_priv (connection, message, udi, "hal-power-keyboard-backlight"))
+                if (!check_priv (connection, message, udi, "hal-power-keyboard-backlight", NULL))
                         goto error;
 
 		/* I can't get this working so just cache last SetBrightness value :-/ */
@@ -432,7 +437,7 @@ filter_function (DBusConnection *connect
 						"SetBrightness")) {
 		int brightness;
 
-                if (!check_priv (connection, message, udi, "hal-power-keyboard-backlight"))
+                if (!check_priv (connection, message, udi, "hal-power-keyboard-backlight", NULL))
                         goto error;
 
 		dbus_error_init (&err);
diff --git a/hald/run-hald.sh b/hald/run-hald.sh
index ca57424..07ebfe6 100755
--- a/hald/run-hald.sh
+++ b/hald/run-hald.sh
@@ -17,8 +17,7 @@ if [ "$1" = "--skip-fdi-install" ] ; the
 else
     rm -rf $HALD_TMPDIR
     mkdir -p $HALD_TMPDIR
-    make -C ../privileges install DESTDIR=$HALD_TMPDIR prefix=/
-
+    make -C ../policy install DESTDIR=$HALD_TMPDIR prefix=/
     make -C ../fdi install DESTDIR=$HALD_TMPDIR prefix=/ && \
     if [ ! -d $information_fdidir ] ; then
     	echo "ERROR: You need to checkout hal-info in the same level"
diff --git a/hald/valgrind-hald.sh b/hald/valgrind-hald.sh
index 0246702..32eab92 100755
--- a/hald/valgrind-hald.sh
+++ b/hald/valgrind-hald.sh
@@ -16,7 +16,9 @@ if [ "$1" = "--skip-fdi-install" ] ; the
     shift
 else
     rm -rf $HALD_TMPDIR
+    mkdir -p $HALD_TMPDIR
     make -C ../fdi install DESTDIR=$HALD_TMPDIR prefix=/ && \
+    make -C ../policy install DESTDIR=$HALD_TMPDIR prefix=/
     if [ ! -d $information_fdidir ] ; then
     	echo "ERROR: You need to checkout hal-info in the same level"
     	echo "directory as hal to get the information fdi files."
diff --git a/libhal/libhal.c b/libhal/libhal.c
index 013d8c1..9bc8a42 100644
--- a/libhal/libhal.c
+++ b/libhal/libhal.c
@@ -4643,7 +4643,8 @@ libhal_device_is_locked_by_others (LibHa
  * 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
+ * @action: the action to check for
+ * @action_param: A #NULL terminated list of action parameters or #NULL if there are no parameters
  * @caller: the caller to check for
  * @error: pointer to an initialized dbus error object for returning errors
  * 
@@ -4659,12 +4660,14 @@ libhal_device_is_locked_by_others (LibHa
 char*
 libhal_device_is_caller_privileged (LibHalContext *ctx,
                                     const char *udi,
-                                    const char *privilege,
+                                    const char *action,
+                                    char **action_parameters,
                                     const char *caller,
                                     DBusError *error)
 {
 	DBusMessage *message;
 	DBusMessageIter iter;
+	DBusMessageIter iter_array;
 	DBusMessage *reply;
 	DBusMessageIter reply_iter;
         char *dbus_str;
@@ -4672,7 +4675,7 @@ libhal_device_is_caller_privileged (LibH
 
 	LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL);
 	LIBHAL_CHECK_PARAM_VALID(udi, "*udi", NULL);
-	LIBHAL_CHECK_PARAM_VALID(privilege, "*privilege", NULL);
+	LIBHAL_CHECK_PARAM_VALID(action, "*action", NULL);
 	LIBHAL_CHECK_PARAM_VALID(caller, "*caller", NULL);
 
 	message = dbus_message_new_method_call ("org.freedesktop.Hal",
@@ -4688,7 +4691,20 @@ libhal_device_is_caller_privileged (LibH
 	}
 
 	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, &action);
+	dbus_message_iter_open_container (&iter, 
+					  DBUS_TYPE_ARRAY,
+					  DBUS_TYPE_STRING_AS_STRING,
+					  &iter_array);
+
+        if (action_parameters != NULL) {
+                int n;
+                for (n = 0; action_parameters[n] != NULL; n++) {
+                        dbus_message_iter_append_basic (&iter_array, DBUS_TYPE_STRING, &(action_parameters[n]));
+                }
+        }
+
+        dbus_message_iter_close_container (&iter, &iter_array);
 	dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &caller);
 	
 	reply = dbus_connection_send_with_reply_and_block (ctx->connection,
diff --git a/libhal/libhal.h b/libhal/libhal.h
index 9df5dad..110c684 100644
--- a/libhal/libhal.h
+++ b/libhal/libhal.h
@@ -716,7 +716,8 @@ dbus_bool_t libhal_device_is_locked_by_o
 /* 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 *action,
+                                          char **action_parameters,
                                           const char *caller,
                                           DBusError *error);
 
diff --git a/policy/Makefile.am b/policy/Makefile.am
index 30497d8..1a2e7bf 100644
--- a/policy/Makefile.am
+++ b/policy/Makefile.am
@@ -5,7 +5,8 @@ polkit_privilegedir = $(sysconfdir)/Poli
 dist_polkit_privilege_DATA =    \
 	hal-storage.policy	\
 	hal-power.policy	\
-	hal-killswitch.policy
+	hal-killswitch.policy	\
+	hal-lock.policy
 
 if HAVE_ACLMGMT
 dist_polkit_privilege_DATA += hal-device-file.policy
diff --git a/policy/hal-device-file.policy b/policy/hal-device-file.policy
index 800ef2f..16e91b3 100644
--- a/policy/hal-device-file.policy
+++ b/policy/hal-device-file.policy
@@ -14,6 +14,8 @@
 # to this file are applied instantly.
 
 # Directly access sound devices
+#
+#  device-file: special device file
 [Action hal-device-file-sound]
 AllowRemoteInactive=no
 AllowRemoteActive=no
@@ -21,6 +23,8 @@ AllowLocalInactive=no
 AllowLocalActive=yes
 
 # Directly access video4linux devices
+#
+#  device-file: special device file
 [Action hal-device-file-video4linux]
 AllowRemoteInactive=no
 AllowRemoteActive=no
@@ -28,6 +32,8 @@ AllowLocalInactive=no
 AllowLocalActive=yes
 
 # Directly access optical drives
+#
+#  device-file: special device file
 [Action hal-device-file-cdrom]
 AllowRemoteInactive=no
 AllowRemoteActive=no
@@ -35,6 +41,8 @@ AllowLocalInactive=yes
 AllowLocalActive=yes
 
 # Directly access DVB devices
+#
+#  device-file: special device file
 [Action hal-device-file-dvb]
 AllowRemoteInactive=no
 AllowRemoteActive=no
@@ -42,6 +50,8 @@ AllowLocalInactive=no
 AllowLocalActive=yes
 
 # Directly access digital cameras
+#
+#  device-file: special device file
 [Action hal-device-file-camera]
 AllowRemoteInactive=no
 AllowRemoteActive=no
@@ -49,6 +59,8 @@ AllowLocalInactive=no
 AllowLocalActive=yes
 
 # Directly access scanners
+#
+#  device-file: special device file
 [Action hal-device-file-scanner]
 AllowRemoteInactive=no
 AllowRemoteActive=no
@@ -56,6 +68,8 @@ AllowLocalInactive=no
 AllowLocalActive=yes
 
 # Directly access Firewire IIDC devices
+#
+#  device-file: special device file
 [Action hal-device-file-ieee1394-iidc]
 AllowRemoteInactive=no
 AllowRemoteActive=no
@@ -63,6 +77,8 @@ AllowLocalInactive=no
 AllowLocalActive=yes
 
 # Directly access Firewire AVC devices
+#
+#  device-file: special device file
 [Action hal-device-file-ieee1394-avc]
 AllowRemoteInactive=no
 AllowRemoteActive=no
diff --git a/tools/Makefile.am b/tools/Makefile.am
index 0fca49c..f759a14 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -66,7 +66,7 @@ hal_disable_polling_LDADD = @GLIB_LIBS@ 
 
 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
+hal_is_caller_privileged_LDADD = @GLIB_LIBS@ @DBUS_LIBS@ $(top_builddir)/libhal/libhal.la
 endif
 
 libexec_PROGRAMS =                          \
diff --git a/tools/hal-acl-tool.c b/tools/hal-acl-tool.c
index d940426..8813325 100644
--- a/tools/hal-acl-tool.c
+++ b/tools/hal-acl-tool.c
@@ -654,6 +654,7 @@ acl_device_added_visitor (const char *se
                 pk_action = libpolkit_action_new();
                 priv_name = g_strdup_printf ("hal-device-file-%s", afd->type);
                 libpolkit_action_set_action_id (pk_action, priv_name);
+                libpolkit_action_set_param (pk_action, "device-file", afd->device);
                 g_free (priv_name);
 
                 /* Now ask PolicyKit if the given session should have access */
diff --git a/tools/hal-functions b/tools/hal-functions
index 347b952..9b363c7 100755
--- a/tools/hal-functions
+++ b/tools/hal-functions
@@ -5,11 +5,11 @@
 
 hal_check_priv() {
     if [ "$HAVE_POLKIT" = "1" -a -n $HAL_METHOD_INVOKED_BY_SYSTEMBUS_CONNECTION_NAME ]; then
-        local PRIVILEGE
+        local ACTION
         local PK_RESULT
         local RET
-        PRIVILEGE=$1
-        PK_RESULT=`hal-is-caller-privileged --udi $UDI --privilege $PRIVILEGE \
+        ACTION=$1
+        PK_RESULT=`hal-is-caller-privileged --udi $UDI --action $ACTION \
             --caller $HAL_METHOD_INVOKED_BY_SYSTEMBUS_CONNECTION_NAME`
         RET=$?
         if [ "$RET" != "0" ]; then
@@ -19,7 +19,7 @@ hal_check_priv() {
         fi
         if [ "$PK_RESULT" != "yes" ] ;then
             echo "org.freedesktop.Hal.Device.PermissionDeniedByPolicy" >&2
-            echo "$PRIVILEGE $PK_RESULT <-- (privilege, result)" >&2
+            echo "$ACTION $PK_RESULT <-- (action, result)" >&2
             exit 1
         fi
     fi
diff --git a/tools/hal-is-caller-privileged.c b/tools/hal-is-caller-privileged.c
index fe87571..55d68d7 100644
--- a/tools/hal-is-caller-privileged.c
+++ b/tools/hal-is-caller-privileged.c
@@ -32,6 +32,7 @@
 #include <string.h>
 #include <unistd.h>
 #include <getopt.h>
+#include <glib.h>
 
 #include <libhal.h>
 
@@ -47,19 +48,21 @@ usage (int argc, char *argv[])
 {
 	fprintf (stderr,
                  "\n"
-                 "usage : hal-is-caller-privileged --udi <udi> --privileged <interface>\n"
+                 "usage : hal-is-caller-privileged --udi <udi> --action <action>\n"
+                 "                                 [--action-param <key>=<value>]\n"
                  "                                 --caller <caller-name>\n"
                  "                                 [--help] [--version]\n");
 	fprintf (stderr,
                  "\n"
                  "        --udi            Unique Device Id\n"
-                 "        --privilege      Privilege to check for\n"
+                 "        --action         PolicyKit action to check for\n"
+                 "        --action-param   Action parameters (may occur multiple times)\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"
+                 "privileged for a given PolicyKit action 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"
@@ -80,25 +83,32 @@ int
 main (int argc, char *argv[])
 {
 	char *udi = NULL;
-	char *privilege = NULL;
+	char *action = NULL;
 	char *caller = NULL;
         dbus_bool_t is_version = FALSE;
         char *polkit_result;
 	DBusError error;
         LibHalContext *hal_ctx;
+        GPtrArray *params;
+        int n;
+        char *param_key;
+        char *param_value;
+        char **action_params;
 
 	if (argc <= 1) {
 		usage (argc, argv);
 		return 1;
 	}
 
+        params = g_ptr_array_new ();
 	while (1) {
 		int c;
 		int option_index = 0;
 		const char *opt;
 		static struct option long_options[] = {
 			{"udi", 1, NULL, 0},
-			{"privilege", 1, NULL, 0},
+			{"action", 1, NULL, 0},
+			{"action-param", 1, NULL, 0},
 			{"caller", 1, NULL, 0},
 			{"version", 0, NULL, 0},
 			{"help", 0, NULL, 0},
@@ -123,8 +133,20 @@ main (int argc, char *argv[])
 				udi = strdup (optarg);
 			} else if (strcmp (opt, "caller") == 0) {
 				caller = strdup (optarg);
-			} else if (strcmp (opt, "privilege") == 0) {
-				privilege = strdup (optarg);
+			} else if (strcmp (opt, "action") == 0) {
+				action = strdup (optarg);
+			} else if (strcmp (opt, "action-param") == 0) {
+				param_key = strdup (optarg);
+                                param_value = NULL;
+                                for (n = 0; param_key[n] != '=' && param_key[n] != '\0'; n++)
+                                        ;
+                                if (param_key[n] == '\0')
+                                        usage (argc, argv);
+                                param_key[n] = '\0';
+                                param_value = param_key + n + 1;
+                                g_ptr_array_add (params, g_strdup (param_key));
+                                g_ptr_array_add (params, g_strdup (param_value));
+                                g_free (param_key);
 			}
 			break;
 
@@ -140,7 +162,7 @@ main (int argc, char *argv[])
 		return 0;
 	}
 
-	if (udi == NULL || caller == NULL || privilege == NULL) {
+	if (udi == NULL || caller == NULL || action == NULL) {
 		usage (argc, argv);
 		return 1;
 	}
@@ -165,9 +187,17 @@ main (int argc, char *argv[])
 		return 1;
 	}
 
+        if (params->len > 0) {
+                g_ptr_array_add (params, NULL);
+                action_params = (char **) g_ptr_array_free (params, FALSE);
+        } else {
+                action_params = NULL;
+        }
+
         polkit_result = libhal_device_is_caller_privileged (hal_ctx,
                                                             udi,
-                                                            privilege,
+                                                            action,
+                                                            action_params,
                                                             caller,
                                                             &error);
         if (dbus_error_is_set (&error)) {
diff --git a/tools/hal-storage-mount.c b/tools/hal-storage-mount.c
index 2730def..a35cc2d 100644
--- a/tools/hal-storage-mount.c
+++ b/tools/hal-storage-mount.c
@@ -142,10 +142,10 @@ cannot_remount (const char *device)
 
 #ifdef HAVE_POLKIT
 static void
-permission_denied_privilege (const char *privilege, const char *result)
+permission_denied_action (const char *action, const char *result)
 {
 	fprintf (stderr, "org.freedesktop.Hal.Device.PermissionDeniedByPolicy\n");
-	fprintf (stderr, "%s %s <-- (privilege, result)\n", privilege, result);
+	fprintf (stderr, "%s %s <-- (action, result)\n", action, result);
 	exit (1);
 }
 #endif
@@ -462,7 +462,7 @@ handle_mount (LibHalContext *hal_ctx, 
 	GString *mount_option_str;
 	gboolean pol_is_fixed;
 	gboolean pol_change_uid;
-	char *privilege;
+	char *action;
 	gboolean is_remount;
 	gboolean explicit_mount_point_given;
 	const char *end;
@@ -728,39 +728,84 @@ handle_mount (LibHalContext *hal_ctx, 
 		}
 	}
 
+
+	char *mount_option_commasep = NULL;
+	char *mount_do_fstype = "auto";
+
+	/* construct arguments to mount */
+	na = 0;
+	args[na++] = MOUNT;
+	if (strlen (mount_fstype) > 0) {
+		mount_do_fstype = (char *) map_fstype (mount_fstype);
+	} else if (volume == NULL) {
+		/* non-pollable drive; force auto */
+		mount_do_fstype = "auto";
+	} else if (libhal_volume_get_fstype (volume) != NULL && strlen (libhal_volume_get_fstype (volume)) > 0) {
+		mount_do_fstype = (char *) map_fstype (libhal_volume_get_fstype (volume));
+	}
+	args[na++] = MOUNT_TYPE_OPT;
+	args[na++] = mount_do_fstype;
+
+	args[na++] = "-o";
+#ifdef HAVE_UMOUNT_HAL
+	mount_option_str = g_string_new (MOUNT_OPTIONS ",uhelper=hal");
+#else
+	mount_option_str = g_string_new (MOUNT_OPTIONS);
+#endif
+	for (i = 0; given_options[i] != NULL; i++) {
+		g_string_append (mount_option_str, ",");
+		g_string_append (mount_option_str, given_options[i]);
+	}
+	mount_option_commasep = g_string_free (mount_option_str, FALSE); /* leak! */
+	args[na++] = mount_option_commasep;
+	args[na++] = (char *) device;
+	args[na++] = mount_dir;
+	args[na++] = NULL;
+
 	if (pol_is_fixed) {
 		if (pol_change_uid) {
-			privilege = "hal-storage-mount-fixed-extra-options";
+			action = "hal-storage-mount-fixed-extra-options";
 		} else {
-			privilege = "hal-storage-mount-fixed";
+			action = "hal-storage-mount-fixed";
 		}
 	} else {
 		if (pol_change_uid) {
-			privilege = "hal-storage-mount-removable-extra-options"; /* TODO: rethink "extra-options" */
+			action = "hal-storage-mount-removable-extra-options"; /* TODO: rethink "extra-options" */
 		} else {
-			privilege = "hal-storage-mount-removable";
+			action = "hal-storage-mount-removable";
 		}
 	}
 
 #ifdef DEBUG
-	printf ("using privilege %s for uid %s, system_bus_connection %s\n", privilege, invoked_by_uid, 
+	printf ("using action %s for uid %s, system_bus_connection %s\n", action, invoked_by_uid, 
 		invoked_by_syscon_name);
 #endif
 
 #ifdef HAVE_POLKIT
         if (invoked_by_syscon_name != NULL) {
                 char *polkit_result;
+                char *action_params[] = {
+                        "fstype", "",
+                        "mount-point", "",
+                        "mount-options", "",
+                        NULL};
+
+                action_params[1] = mount_do_fstype;
+                action_params[3] = mount_dir;
+                action_params[5] = mount_option_commasep;
+
                 dbus_error_init (&error);
                 polkit_result = libhal_device_is_caller_privileged (hal_ctx,
                                                                     udi,
-                                                                    privilege,
+                                                                    action,
+                                                                    action_params,
                                                                     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);
+                        permission_denied_action (action, polkit_result);
                 }
                 libhal_free_string (polkit_result);
         }
@@ -794,38 +839,6 @@ handle_mount (LibHalContext *hal_ctx, 
 #endif
 	}
 
-	char *mount_option_commasep = NULL;
-	char *mount_do_fstype = "auto";
-
-	/* construct arguments to mount */
-	na = 0;
-	args[na++] = MOUNT;
-	if (strlen (mount_fstype) > 0) {
-		mount_do_fstype = (char *) map_fstype (mount_fstype);
-	} else if (volume == NULL) {
-		/* non-pollable drive; force auto */
-		mount_do_fstype = "auto";
-	} else if (libhal_volume_get_fstype (volume) != NULL && strlen (libhal_volume_get_fstype (volume)) > 0) {
-		mount_do_fstype = (char *) map_fstype (libhal_volume_get_fstype (volume));
-	}
-	args[na++] = MOUNT_TYPE_OPT;
-	args[na++] = mount_do_fstype;
-
-	args[na++] = "-o";
-#ifdef HAVE_UMOUNT_HAL
-	mount_option_str = g_string_new (MOUNT_OPTIONS ",uhelper=hal");
-#else
-	mount_option_str = g_string_new (MOUNT_OPTIONS);
-#endif
-	for (i = 0; given_options[i] != NULL; i++) {
-		g_string_append (mount_option_str, ",");
-		g_string_append (mount_option_str, given_options[i]);
-	}
-	mount_option_commasep = g_string_free (mount_option_str, FALSE); /* leak! */
-	args[na++] = mount_option_commasep;
-	args[na++] = (char *) device;
-	args[na++] = mount_dir;
-	args[na++] = NULL;
 
 	/* TODO FIXME XXX HACK: OK, so we should rewrite the options in /media/.hal-mtab .. 
 	 *                      but it doesn't really matter much at this point */
diff --git a/tools/hal-storage-shared.c b/tools/hal-storage-shared.c
index 2c8f3ca..64ffa15 100644
--- a/tools/hal-storage-shared.c
+++ b/tools/hal-storage-shared.c
@@ -419,21 +419,22 @@ line_found:
 	 * 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) {
-                const char *privilege = "hal-storage-unmount-others";
+                const char *action = "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,
+                                                                            action,
+                                                                            NULL, /* TODO: FIXME: */
                                                                             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);
+                                permission_denied_privilege (action, polkit_result);
                         }
                         libhal_free_string (polkit_result);
                 }
@@ -594,18 +595,19 @@ try_open_excl_again:
 #ifdef HAVE_POLKIT
         if (invoked_by_syscon_name != NULL) {
                 char *polkit_result;
-                const char *privilege = "hal-storage-eject";
+                const char *action = "hal-storage-eject";
                 dbus_error_init (&error);
                 polkit_result = libhal_device_is_caller_privileged (hal_ctx,
                                                                     udi,
-                                                                    privilege,
+                                                                    action,
+                                                                    NULL,
                                                                     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);
+                        permission_denied_privilege (action, polkit_result);
                 }
                 libhal_free_string (polkit_result);
         }


More information about the hal-commit mailing list