diff options
author | David Zeuthen <davidz@redhat.com> | 2007-04-09 15:22:00 -0400 |
---|---|---|
committer | David Zeuthen <davidz@redhat.com> | 2007-04-09 15:22:00 -0400 |
commit | e4b6fcb25a2a954ca201781246cfae7acfb80214 (patch) | |
tree | 52ebce4d3d8ad74dcf4c76b25c6e7d4991e0dfe8 | |
parent | c994c40ad21a3a956690757eb0193e73fdc8bf72 (diff) |
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
-rw-r--r-- | hald/access-check.c | 42 | ||||
-rw-r--r-- | hald/access-check.h | 3 | ||||
-rw-r--r-- | hald/ci-tracker.c | 94 | ||||
-rwxr-xr-x | hald/debug-hald.sh | 3 | ||||
-rw-r--r-- | hald/hald_dbus.c | 62 | ||||
-rw-r--r-- | hald/linux/addons/addon-cpufreq.c | 3 | ||||
-rw-r--r-- | hald/linux/addons/addon-dell-backlight.cpp | 11 | ||||
-rw-r--r-- | hald/linux/addons/addon-macbookpro-backlight.c | 27 | ||||
-rwxr-xr-x | hald/run-hald.sh | 3 | ||||
-rwxr-xr-x | hald/valgrind-hald.sh | 2 | ||||
-rw-r--r-- | libhal/libhal.c | 24 | ||||
-rw-r--r-- | libhal/libhal.h | 3 | ||||
-rw-r--r-- | policy/Makefile.am | 3 | ||||
-rw-r--r-- | policy/hal-device-file.policy | 16 | ||||
-rw-r--r-- | tools/Makefile.am | 2 | ||||
-rw-r--r-- | tools/hal-acl-tool.c | 1 | ||||
-rwxr-xr-x | tools/hal-functions | 8 | ||||
-rw-r--r-- | tools/hal-is-caller-privileged.c | 48 | ||||
-rw-r--r-- | tools/hal-storage-mount.c | 97 | ||||
-rw-r--r-- | tools/hal-storage-shared.c | 14 |
20 files changed, 339 insertions, 127 deletions
diff --git a/hald/access-check.c b/hald/access-check.c index 7a97845d..2051b76b 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_device (CITracker *cit, /* 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_device (CITracker *cit, } #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_device (CITracker *cit, 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 (CITracker *cit, 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 (CITracker *cit, 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 (CITracker *cit, * 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 *cit, 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 *cit, 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 2f3c34a9..2b9a896e 100644 --- a/hald/access-check.h +++ b/hald/access-check.h @@ -35,7 +35,8 @@ gboolean access_check_message_caller_is_root_or_hal (CITracker *cit, 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 e1d31eb5..085e0d8b 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, const char *system_bus_unique_name) 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 6a378ba2..7d81989b 100755 --- a/hald/debug-hald.sh +++ b/hald/debug-hald.sh @@ -17,8 +17,7 @@ if [ "$1" = "--skip-fdi-install" ] ; then 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 9e19bf6b..3db89e03 100644 --- a/hald/hald_dbus.c +++ b/hald/hald_dbus.c @@ -2052,14 +2052,13 @@ device_acquire_interface_lock (DBusConnection *connection, DBusMessage *message, } 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 (DBusConnection *connection, DBusMessage *message, d 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 (DBusConnection *connection, DBusMessage *message, d 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, ¶m); + 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 (DBusConnection *connection, DBusMessage *message, d 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 (DBusConnection *connection, DBusMessage *message, d 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 (DBusConnection *connection, DBusMessage *message, d 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 *connection, " <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 *store, 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 bf6fba6d..7ace00cf 100644 --- a/hald/linux/addons/addon-cpufreq.c +++ b/hald/linux/addons/addon-cpufreq.c @@ -933,6 +933,7 @@ dbus_is_privileged (DBusConnection *connection, DBusMessage *message, DBusError 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 *connection, DBusMessage *message, DBusError 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 20658aa2..b3282b5b 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, dbus_bool_t onAC) } 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, DBusMessage *message, const char *udi, c 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, DBusMessage *message, const char *udi, c 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 f6da1989..d6366613 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, DBusMessage *message, const char *udi, c 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, DBusMessage *message, const char *udi, c 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 *connection, DBusMessage *message, void *userdat "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 *connection, DBusMessage *message, void *userdat "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 *connection, DBusMessage *message, void *userdat "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 *connection, DBusMessage *message, void *userdat "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 *connection, DBusMessage *message, void *userdat "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 ca574249..07ebfe6e 100755 --- a/hald/run-hald.sh +++ b/hald/run-hald.sh @@ -17,8 +17,7 @@ if [ "$1" = "--skip-fdi-install" ] ; then 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 0246702a..32eab927 100755 --- a/hald/valgrind-hald.sh +++ b/hald/valgrind-hald.sh @@ -16,7 +16,9 @@ if [ "$1" = "--skip-fdi-install" ] ; then 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 013d8c10..9bc8a425 100644 --- a/libhal/libhal.c +++ b/libhal/libhal.c @@ -4643,7 +4643,8 @@ libhal_device_is_locked_by_others (LibHalContext *ctx, * 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 (LibHalContext *ctx, 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 (LibHalContext *ctx, 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 (LibHalContext *ctx, } 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 9df5dad8..110c6848 100644 --- a/libhal/libhal.h +++ b/libhal/libhal.h @@ -716,7 +716,8 @@ dbus_bool_t libhal_device_is_locked_by_others (LibHalContext *ctx, /* 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 30497d86..1a2e7bfd 100644 --- a/policy/Makefile.am +++ b/policy/Makefile.am @@ -5,7 +5,8 @@ polkit_privilegedir = $(sysconfdir)/PolicyKit/policy 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 800ef2f2..16e91b30 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 0fca49c4..f759a14b 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -66,7 +66,7 @@ hal_disable_polling_LDADD = @GLIB_LIBS@ @DBUS_LIBS@ $(top_builddir)/libhal/libha 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 d9404263..88133250 100644 --- a/tools/hal-acl-tool.c +++ b/tools/hal-acl-tool.c @@ -654,6 +654,7 @@ acl_device_added_visitor (const char *seat_id, 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 347b9528..9b363c7f 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 fe875711..55d68d77 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 2730def3..a35cc2de 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 2c8f3ca2..64ffa15a 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); } |