summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Zeuthen <davidz@redhat.com>2012-02-22 16:52:48 -0500
committerDavid Zeuthen <davidz@redhat.com>2012-02-22 16:52:48 -0500
commitaa02e5fc53efdeaf66047d2ad437ed543178965b (patch)
treee3a34d972811c670a7611794f452a57d5fc5ad61
parent06009a62608fb3cc4b0783054f645e8784ab13c0 (diff)
Use /run/media/$USER for mounting
Also use ACLs on the $USER sub-directory so only $USER (and not any other user) can access the mounted filesystem. Signed-off-by: David Zeuthen <davidz@redhat.com>
-rw-r--r--data/org.freedesktop.UDisks2.xml3
-rw-r--r--src/udiskslinuxfilesystem.c83
2 files changed, 61 insertions, 25 deletions
diff --git a/data/org.freedesktop.UDisks2.xml b/data/org.freedesktop.UDisks2.xml
index 6aec563..4e4cb4f 100644
--- a/data/org.freedesktop.UDisks2.xml
+++ b/data/org.freedesktop.UDisks2.xml
@@ -1097,7 +1097,8 @@
looking at data related to the device (such the filesystem
UUID and label) and will be created automatically. It is
returned in @mount_path and is normally a sub-directory of
- <filename class='directory'>/media</filename>.
+ <filename class='directory'>/run/media/$USER</filename> but
+ note that any path may be returned.
The filesystem should be unmounted using the
org.freedesktop.UDisks2.Filesystem.Unmount() method.
diff --git a/src/udiskslinuxfilesystem.c b/src/udiskslinuxfilesystem.c
index 4852357..99ae1f5 100644
--- a/src/udiskslinuxfilesystem.c
+++ b/src/udiskslinuxfilesystem.c
@@ -28,6 +28,8 @@
#include <stdlib.h>
#include <stdio.h>
#include <mntent.h>
+#include <sys/types.h>
+#include <sys/acl.h>
#include <glib/gstdio.h>
@@ -635,10 +637,11 @@ calculate_mount_point (UDisksBlock *block,
const gchar *fs_type,
GError **error)
{
- const gchar *label;
- const gchar *uuid;
+ const gchar *label = NULL;
+ const gchar *uuid = NULL;
+ gchar *escaped_user_name = NULL;
gchar *mount_dir = NULL;
- gchar *mount_point;
+ gchar *mount_point = NULL;
gchar *orig_mount_point;
GString *str;
gchar *s;
@@ -652,40 +655,71 @@ calculate_mount_point (UDisksBlock *block,
uuid = udisks_block_get_id_uuid (block);
}
-#if 0 /* $XDG_RUNTIME_DIR/media turned off for now, may have security issues */
- /* try mounting in user's $XDG_RUNTIME_DIR/media first - have to create it on demand... */
+ /* If we know the user-name, mount in /run/media/$USER */
if (user_name != NULL)
{
- s = g_strdup_printf ("/run/user/%s", user_name);
- if (g_file_test (s, G_FILE_TEST_EXISTS))
+ escaped_user_name = g_strescape (user_name, NULL);;
+
+ mount_dir = g_strdup_printf ("/run/media/%s", escaped_user_name);
+ if (!g_file_test (mount_dir, G_FILE_TEST_EXISTS))
{
- mount_dir = g_strdup_printf ("%s/media", s);
- if (!g_file_test (mount_dir, G_FILE_TEST_EXISTS))
+ gchar *stderr_txt;
+ gint exit_status;
+
+ /* First ensure that /run/media exists */
+ if (!g_file_test ("/run/media", G_FILE_TEST_EXISTS))
{
- if (g_mkdir (mount_dir, 0777) != 0)
- {
- g_set_error (error,
- UDISKS_ERROR,
- UDISKS_ERROR_FAILED,
- "Error creating directory `%s': %m",
- mount_dir);
- goto out;
- }
- if (chown (mount_dir, uid, gid) != 0)
+ if (g_mkdir ("/run/media", 0755) != 0)
{
g_set_error (error,
UDISKS_ERROR,
UDISKS_ERROR_FAILED,
- "Error chowning`%s' to uid=%d, gid=%d: %m",
- mount_dir, (gint) uid, (gint) gid);
+ "Error creating directory /run/media: %m");
goto out;
}
}
+ /* Then create the per-user /run/media/$USER */
+ if (g_mkdir (mount_dir, 0700) != 0)
+ {
+ g_set_error (error,
+ UDISKS_ERROR,
+ UDISKS_ERROR_FAILED,
+ "Error creating directory `%s': %m",
+ mount_dir);
+ goto out;
+ }
+ /* Then set the ACL such that only $USER can actually access it */
+ s = g_strdup_printf ("setfacl -m \"u:%s:rx\" \"%s\"",
+ escaped_user_name,
+ mount_dir);
+ if (!g_spawn_command_line_sync (s,
+ NULL, /* stdout_txt */
+ &stderr_txt,
+ &exit_status,
+ error))
+ {
+ g_free (s);
+ if (rmdir (mount_dir) != 0)
+ udisks_warning ("Error calling rmdir() on %s: %m", mount_dir);
+ goto out;
+ }
+ if (!(WIFEXITED (exit_status) && WEXITSTATUS (exit_status) == 0))
+ {
+ g_set_error (error,
+ UDISKS_ERROR,
+ UDISKS_ERROR_FAILED,
+ "Command-line `%s' didn't exit normally: %s", s, stderr_txt);
+ g_free (stderr_txt);
+ g_free (s);
+ if (rmdir (mount_dir) != 0)
+ udisks_warning ("Error calling rmdir() on %s: %m", mount_dir);
+ goto out;
+ }
+ g_free (stderr_txt);
+ g_free (s);
}
- g_free (s);
}
-#endif
- /* fall back to mounting in /media */
+ /* otherwise fall back to mounting in /media */
if (mount_dir == NULL)
mount_dir = g_strdup ("/media");
@@ -750,6 +784,7 @@ calculate_mount_point (UDisksBlock *block,
g_free (mount_dir);
out:
+ g_free (escaped_user_name);
return mount_point;
}