From: David Zeuthen Date: Sun, 13 Mar 2011 19:56:44 +0000 (-0400) Subject: Add FilesystemSetLabel method X-Git-Tag: upstream/2.1.2~480^2~119 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d01676ca5aa6668f70896dd9d9046bd1c5713de1;p=platform%2Fupstream%2Fudisks2.git Add FilesystemSetLabel method Signed-off-by: David Zeuthen --- diff --git a/data/org.freedesktop.UDisks2.xml b/data/org.freedesktop.UDisks2.xml index 0efa6b2..5f31596 100644 --- a/data/org.freedesktop.UDisks2.xml +++ b/data/org.freedesktop.UDisks2.xml @@ -136,6 +136,10 @@ + + + + diff --git a/policy/org.freedesktop.udisks2.policy.in b/policy/org.freedesktop.udisks2.policy.in index 30ab0e4..3930aff 100644 --- a/policy/org.freedesktop.udisks2.policy.in +++ b/policy/org.freedesktop.udisks2.policy.in @@ -19,4 +19,14 @@ + + <_description>Modify a device + <_message>Authentication is required to modify a device + + auth_admin + auth_admin + auth_admin_keep + + + diff --git a/src/udiskslinuxblock.c b/src/udiskslinuxblock.c index 5a24a75..6453077 100644 --- a/src/udiskslinuxblock.c +++ b/src/udiskslinuxblock.c @@ -373,6 +373,12 @@ handle_unmount (UDisksBlockDevice *block, GDBusMethodInvocation *invocation, const gchar* const *options); +static gboolean +handle_set_label (UDisksBlockDevice *block, + GDBusMethodInvocation *invocation, + const gchar *label, + const gchar* const *options); + static void block_device_connect (UDisksLinuxBlock *block) { @@ -384,6 +390,10 @@ block_device_connect (UDisksLinuxBlock *block) "handle-filesystem-unmount", G_CALLBACK (handle_unmount), NULL); + g_signal_connect (block->iface_block_device, + "handle-filesystem-set-label", + G_CALLBACK (handle_set_label), + NULL); } static gchar * @@ -1946,3 +1956,182 @@ handle_unmount (UDisksBlockDevice *block, g_object_unref (object); return TRUE; } + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +on_set_label_job_completed (UDisksJob *job, + gboolean success, + const gchar *message, + gpointer user_data) +{ + GDBusMethodInvocation *invocation = G_DBUS_METHOD_INVOCATION (user_data); + UDisksBlockDevice *block; + + block = UDISKS_BLOCK_DEVICE (g_dbus_method_invocation_get_user_data (invocation)); + + if (success) + udisks_block_device_complete_filesystem_set_label (block, invocation); + else + g_dbus_method_invocation_return_error (invocation, + UDISKS_ERROR, + UDISKS_ERROR_FAILED, + "Error setting filesystem label: %s", + message); +} + +/* runs in thread dedicated to handling method call */ +static gboolean +handle_set_label (UDisksBlockDevice *block, + GDBusMethodInvocation *invocation, + const gchar *label, + const gchar* const *requested_options) +{ + GDBusObject *object; + UDisksDaemon *daemon; + const gchar *probed_fs_usage; + const gchar *probed_fs_type; + GError *error; + PolkitSubject *auth_subject; + const gchar *auth_action_id; + PolkitDetails *auth_details; + gboolean auth_no_user_interaction; + PolkitCheckAuthorizationFlags auth_flags; + PolkitAuthorizationResult *auth_result; + gboolean supports_online; + guint n; + UDisksBaseJob *job; + gchar *escaped_label; + + object = NULL; + daemon = NULL; + auth_subject = NULL; + auth_details = NULL; + auth_result = NULL; + auth_no_user_interaction = FALSE; + supports_online = FALSE; + escaped_label = NULL; + + object = g_dbus_interface_get_object (G_DBUS_INTERFACE (block)); + daemon = udisks_linux_block_get_daemon (UDISKS_LINUX_BLOCK (object)); + + probed_fs_usage = udisks_block_device_get_id_usage (block); + probed_fs_type = udisks_block_device_get_id_type (block); + + /* TODO: add support for other fstypes */ + if (!(g_strcmp0 (probed_fs_usage, "filesystem") == 0 && + (g_strcmp0 (probed_fs_type, "ext2") == 0 || + g_strcmp0 (probed_fs_type, "ext3") == 0 || + g_strcmp0 (probed_fs_type, "ext4") == 0))) + { + g_dbus_method_invocation_return_error (invocation, + UDISKS_ERROR, + UDISKS_ERROR_NOT_SUPPORTED, + "Don't know how to change label on device of type %s:%s", + probed_fs_usage, + probed_fs_type); + goto out; + } + supports_online = FALSE; + + /* Fail if the device is already mounted and the tools/drivers doesn't + * support changing the label in that case + */ + if (!supports_online) + { + const gchar * const *existing_mount_points; + existing_mount_points = udisks_block_device_get_filesystem_mount_points (block); + if (existing_mount_points != NULL && g_strv_length ((gchar **) existing_mount_points) > 0) + { + g_dbus_method_invocation_return_error (invocation, + UDISKS_ERROR, + UDISKS_ERROR_NOT_SUPPORTED, + "Cannot change label on mounted device of type %s:%s.\n", + probed_fs_usage, + probed_fs_type); + goto out; + } + } + + for (n = 0; requested_options != NULL && requested_options[n] != NULL; n++) + { + const gchar *option = requested_options[n]; + if (g_strcmp0 (option, "auth_no_user_interaction") == 0) + { + auth_no_user_interaction = TRUE; + continue; + } + + g_dbus_method_invocation_return_error (invocation, + UDISKS_ERROR, + UDISKS_ERROR_OPTION_NOT_PERMITTED, + "Option `%s' is not allowed", + option); + goto out; + } + + /* now check that the user is actually authorized to change the filesystem label + * + * (TODO: fill in details and pick the right action_id) + */ + auth_action_id = "org.freedesktop.udisks2.modify", + auth_subject = polkit_system_bus_name_new (g_dbus_method_invocation_get_sender (invocation)); + auth_flags = POLKIT_CHECK_AUTHORIZATION_FLAGS_NONE; + if (!auth_no_user_interaction) + auth_flags = POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION; + error = NULL; + auth_result = polkit_authority_check_authorization_sync (udisks_daemon_get_authority (daemon), + auth_subject, + auth_action_id, + auth_details, + auth_flags, + NULL, /* GCancellable* */ + &error); + if (auth_result == NULL) + { + g_dbus_method_invocation_return_error (invocation, + UDISKS_ERROR, + UDISKS_ERROR_FAILED, + "Error checking authorization: %s (%s, %d)", + error->message, + g_quark_to_string (error->domain), + error->code); + g_error_free (error); + goto out; + } + if (!polkit_authorization_result_get_is_authorized (auth_result)) + { + g_dbus_method_invocation_return_error_literal (invocation, + UDISKS_ERROR, + polkit_authorization_result_get_is_challenge (auth_result) ? + UDISKS_ERROR_NOT_AUTHORIZED_CAN_OBTAIN : + UDISKS_ERROR_NOT_AUTHORIZED, + "Not authorized to perform operation"); + goto out; + } + + escaped_label = g_shell_quote (label); + job = udisks_daemon_launch_spawned_job (daemon, + NULL, /* cancellable */ + NULL, /* input_string */ + "e2label %s %s", + udisks_block_device_get_device (block), + escaped_label); + g_signal_connect (job, + "completed", + G_CALLBACK (on_set_label_job_completed), + invocation); + + out: + g_free (escaped_label); + if (auth_subject != NULL) + g_object_unref (auth_subject); + if (auth_details != NULL) + g_object_unref (auth_details); + if (auth_result != NULL) + g_object_unref (auth_result); + if (object != NULL) + g_object_unref (object); + + return TRUE; /* returning TRUE means that we handled the method invocation */ +} diff --git a/udisks/udisksenums.h b/udisks/udisksenums.h index f2a5e8d..e0cb524 100644 --- a/udisks/udisksenums.h +++ b/udisks/udisksenums.h @@ -41,6 +41,7 @@ G_BEGIN_DECLS * @UDISKS_ERROR_OPTION_NOT_PERMITTED: Not permitted to use the requested option. * @UDISKS_ERROR_MOUNTED_BY_OTHER_USER: The device is mounted by another user. * @UDISKS_ERROR_ALREADY_UNMOUNTING: The device is already unmounting. + * @UDISKS_ERROR_NOT_SUPPORTED: The operation is not supported due to missing driver/tool support. * * Error codes for the #UDISKS_ERROR error domain and the * corresponding D-Bus error names. @@ -56,10 +57,11 @@ typedef enum UDISKS_ERROR_NOT_MOUNTED, /* org.freedesktop.UDisks.Error.NotMounted */ UDISKS_ERROR_OPTION_NOT_PERMITTED, /* org.freedesktop.UDisks.Error.OptionNotPermitted */ UDISKS_ERROR_MOUNTED_BY_OTHER_USER, /* org.freedesktop.UDisks.Error.MountedByOtherUser */ - UDISKS_ERROR_ALREADY_UNMOUNTING /* org.freedesktop.UDisks.Error.AlreadyUnmounting */ + UDISKS_ERROR_ALREADY_UNMOUNTING, /* org.freedesktop.UDisks.Error.AlreadyUnmounting */ + UDISKS_ERROR_NOT_SUPPORTED /* org.freedesktop.UDisks.Error.NotSupported */ } UDisksError; -#define UDISKS_ERROR_NUM_ENTRIES (UDISKS_ERROR_ALREADY_UNMOUNTING + 1) +#define UDISKS_ERROR_NUM_ENTRIES (UDISKS_ERROR_NOT_SUPPORTED + 1) G_END_DECLS diff --git a/udisks/udiskserror.c b/udisks/udiskserror.c index adb4109..0ce803d 100644 --- a/udisks/udiskserror.c +++ b/udisks/udiskserror.c @@ -41,7 +41,8 @@ static const GDBusErrorEntry dbus_error_entries[] = {UDISKS_ERROR_NOT_MOUNTED, "org.freedesktop.UDisks.Error.NotMounted"}, {UDISKS_ERROR_OPTION_NOT_PERMITTED, "org.freedesktop.UDisks.Error.OptionNotPermitted"}, {UDISKS_ERROR_MOUNTED_BY_OTHER_USER, "org.freedesktop.UDisks.Error.MountedByOtherUser"}, - {UDISKS_ERROR_ALREADY_UNMOUNTING, "org.freedesktop.UDisks.Error.AlreadyUnmounting"} + {UDISKS_ERROR_ALREADY_UNMOUNTING, "org.freedesktop.UDisks.Error.AlreadyUnmounting"}, + {UDISKS_ERROR_NOT_SUPPORTED, "org.freedesktop.UDisks.Error.NotSupported"} }; GQuark