diff options
author | David Zeuthen <davidz@redhat.com> | 2012-04-20 09:33:08 -0400 |
---|---|---|
committer | David Zeuthen <davidz@redhat.com> | 2012-04-20 09:33:08 -0400 |
commit | 15250f35ff8770389cc579c304fbcac9beebc203 (patch) | |
tree | 7432e8ae708d6ced7da4deb3323cc08c7a82adb2 | |
parent | 25ac4346524ad0026bcfa65189e048d22ad15b32 (diff) |
Use libacl library instead of setfacl(1)
https://bugs.freedesktop.org/show_bug.cgi?id=48842
Signed-off-by: David Zeuthen <davidz@redhat.com>
-rw-r--r-- | configure.ac | 13 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/udiskslinuxfilesystem.c | 68 |
3 files changed, 55 insertions, 28 deletions
diff --git a/configure.ac b/configure.ac index 63bd396..20c2042 100644 --- a/configure.ac +++ b/configure.ac @@ -71,6 +71,19 @@ if test "x$with_systemdsystemunitdir" != "xno"; then fi AM_CONDITIONAL(HAVE_SYSTEMD, [test -n "$systemdsystemunitdir"]) +# libacl +AC_CHECK_HEADERS( + [sys/acl.h acl/libacl.h], + [ACL_CFLAGS=""], + AC_MSG_ERROR([*** ACL headers not found.])) +AC_CHECK_LIB( + [acl], + [acl_get_file], + [ACL_LIBS="-lacl"], + AC_MSG_ERROR([*** libacl not found.])) +AC_SUBST(ACL_CFLAGS) +AC_SUBST(ACL_LIBS) + # Internationalization # diff --git a/src/Makefile.am b/src/Makefile.am index 250ed48..a3a5787 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -86,6 +86,7 @@ libudisks_daemon_la_CFLAGS = \ $(GUDEV_CFLAGS) \ $(LIBATASMART_CFLAGS) \ $(POLKIT_GOBJECT_1_CFLAGS) \ + $(ACL_CFLAGS) \ $(NULL) libudisks_daemon_la_LIBADD = \ @@ -94,6 +95,7 @@ libudisks_daemon_la_LIBADD = \ $(GUDEV_LIBS) \ $(LIBATASMART_LIBS) \ $(POLKIT_GOBJECT_1_LIBS) \ + $(ACL_LIBS) \ $(top_builddir)/udisks/libudisks2.la \ $(NULL) diff --git a/src/udiskslinuxfilesystem.c b/src/udiskslinuxfilesystem.c index 7c36f53..9dde4e4 100644 --- a/src/udiskslinuxfilesystem.c +++ b/src/udiskslinuxfilesystem.c @@ -29,6 +29,8 @@ #include <stdio.h> #include <mntent.h> #include <sys/types.h> +#include <sys/acl.h> +#include <errno.h> #include <glib/gstdio.h> @@ -758,6 +760,42 @@ ensure_utf8 (const gchar *s) /* ---------------------------------------------------------------------------------------------------- */ +static gboolean +add_acl (const gchar *path, + uid_t uid, + GError **error) +{ + gboolean ret = FALSE; + acl_t acl = NULL; + acl_entry_t entry; + acl_permset_t permset; + + acl = acl_get_file(path, ACL_TYPE_ACCESS); + if (acl == NULL || + acl_create_entry (&acl, &entry) == -1 || + acl_set_tag_type (entry, ACL_USER) == -1 || + acl_set_qualifier (entry, &uid) == -1 || + acl_get_permset (entry, &permset) == -1 || + acl_add_perm (permset, ACL_READ|ACL_EXECUTE) == -1 || + acl_calc_mask (&acl) == -1 || + acl_set_file (path, ACL_TYPE_ACCESS, acl) == -1) + { + g_set_error (error, + G_IO_ERROR, + g_io_error_from_errno (errno), + "Adding read ACL for uid %d to `%s' failed: %m", + (gint) uid, path); + goto out; + } + + ret = TRUE; + + out: + if (acl != NULL) + acl_free (acl); + return ret; +} + /* * calculate_mount_point: <internal> * @block: A #UDisksBlock. @@ -803,9 +841,6 @@ calculate_mount_point (UDisksBlock *block, mount_dir = g_strdup_printf ("/run/media/%s", user_name); 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)) { @@ -828,36 +863,13 @@ calculate_mount_point (UDisksBlock *block, mount_dir); goto out; } - /* Then set the ACL such that only $USER can actually access it */ - escaped_user_name = udisks_daemon_util_escape (user_name);; - 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)) + /* Finally, add the read+execute ACL for $USER */ + if (!add_acl (mount_dir, uid, 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); } } /* otherwise fall back to mounting in /media */ |