summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Zeuthen <davidz@redhat.com>2012-04-20 09:33:08 -0400
committerDavid Zeuthen <davidz@redhat.com>2012-04-20 09:33:08 -0400
commit15250f35ff8770389cc579c304fbcac9beebc203 (patch)
tree7432e8ae708d6ced7da4deb3323cc08c7a82adb2
parent25ac4346524ad0026bcfa65189e048d22ad15b32 (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.ac13
-rw-r--r--src/Makefile.am2
-rw-r--r--src/udiskslinuxfilesystem.c68
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 */