summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--man/systemd-mount.xml8
-rw-r--r--src/mount/mount-tool.c55
2 files changed, 60 insertions, 3 deletions
diff --git a/man/systemd-mount.xml b/man/systemd-mount.xml
index 87bc2b36eb..76ea0550d7 100644
--- a/man/systemd-mount.xml
+++ b/man/systemd-mount.xml
@@ -160,6 +160,14 @@
</varlistentry>
<varlistentry>
+ <term><option>--owner=<replaceable>USER</replaceable></option></term>
+
+ <listitem><para>Let the specified user <replaceable>USER</replaceable> own the mounted file system.
+ This is done by appending <option>uid=</option> and <option>gid=</option> options to the list
+ of mount options. Only certain file systems support this option.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><option>--fsck=</option></term>
<listitem><para>Takes a boolean argument, defaults to on. Controls whether to run a file system check
diff --git a/src/mount/mount-tool.c b/src/mount/mount-tool.c
index da3647e7e2..f82e9dac44 100644
--- a/src/mount/mount-tool.c
+++ b/src/mount/mount-tool.c
@@ -41,6 +41,7 @@
#include "strv.h"
#include "udev-util.h"
#include "unit-name.h"
+#include "user-util.h"
#include "terminal-util.h"
enum {
@@ -69,6 +70,8 @@ static usec_t arg_timeout_idle = USEC_INFINITY;
static bool arg_timeout_idle_set = false;
static char **arg_automount_property = NULL;
static int arg_bind_device = -1;
+static uid_t arg_uid = UID_INVALID;
+static gid_t arg_gid = GID_INVALID;
static bool arg_fsck = true;
static bool arg_aggressive_gc = false;
@@ -89,6 +92,7 @@ static void help(void) {
" --discover Discover mount device metadata\n"
" -t --type=TYPE File system type\n"
" -o --options=OPTIONS Mount options\n"
+ " --owner=USER Add uid= and gid= options for USER\n"
" --fsck=no Don't run file system check before mount\n"
" --description=TEXT Description for unit\n"
" -p --property=NAME=VALUE Set mount unit property\n"
@@ -116,6 +120,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_DISCOVER,
ARG_MOUNT_TYPE,
ARG_MOUNT_OPTIONS,
+ ARG_OWNER,
ARG_FSCK,
ARG_DESCRIPTION,
ARG_TIMEOUT_IDLE,
@@ -139,6 +144,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "discover", no_argument, NULL, ARG_DISCOVER },
{ "type", required_argument, NULL, 't' },
{ "options", required_argument, NULL, 'o' },
+ { "owner", required_argument, NULL, ARG_OWNER },
{ "fsck", required_argument, NULL, ARG_FSCK },
{ "description", required_argument, NULL, ARG_DESCRIPTION },
{ "property", required_argument, NULL, 'p' },
@@ -220,6 +226,18 @@ static int parse_argv(int argc, char *argv[]) {
return log_oom();
break;
+ case ARG_OWNER: {
+ const char *user = optarg;
+
+ r = get_user_creds(&user, &arg_uid, &arg_gid, NULL, NULL);
+ if (r < 0)
+ return log_error_errno(r,
+ r == -EBADMSG ? "UID or GID of user %s are invalid."
+ : "Cannot use \"%s\" as owner: %m",
+ optarg);
+ break;
+ }
+
case ARG_FSCK:
r = parse_boolean(optarg);
if (r < 0)
@@ -422,6 +440,7 @@ static int transient_unit_set_properties(sd_bus_message *m, char **properties) {
}
static int transient_mount_set_properties(sd_bus_message *m) {
+ _cleanup_free_ char *options = NULL;
int r;
assert(m);
@@ -442,12 +461,25 @@ static int transient_mount_set_properties(sd_bus_message *m) {
return r;
}
- if (arg_mount_options) {
- r = sd_bus_message_append(m, "(sv)", "Options", "s", arg_mount_options);
+ /* Prepend uid=…,gid=… if arg_uid is set */
+ if (arg_uid != UID_INVALID) {
+ r = asprintf(&options,
+ "uid=" UID_FMT ",gid=" GID_FMT "%s%s",
+ arg_uid, arg_gid,
+ arg_mount_options ? "," : "", arg_mount_options);
if (r < 0)
- return r;
+ return -ENOMEM;
}
+ if (options || arg_mount_options) {
+ log_debug("Using mount options: %s", options ?: arg_mount_options);
+
+ r = sd_bus_message_append(m, "(sv)", "Options", "s", options ?: arg_mount_options);
+ if (r < 0)
+ return r;
+ } else
+ log_debug("Not using any mount options");
+
if (arg_fsck) {
_cleanup_free_ char *fsck = NULL;
@@ -1604,6 +1636,23 @@ int main(int argc, char* argv[]) {
}
}
+ /* The kernel (properly) refuses mounting file systems with unknown uid=,gid= options,
+ * but not for all filesystem types. Let's try to catch the cases where the option
+ * would be used if the file system does not support it. It is also possible to
+ * autodetect the file system, but that's only possible with disk-based file systems
+ * which incidentally seem to be implemented more carefully and reject unknown options,
+ * so it's probably OK that we do the check only when the type is specified.
+ */
+ if (arg_mount_type &&
+ !streq(arg_mount_type, "auto") &&
+ arg_uid != UID_INVALID &&
+ !fstype_can_uid_gid(arg_mount_type)) {
+ log_error("File system type %s is not known to support uid=/gid=, refusing.",
+ arg_mount_type);
+ r = -EOPNOTSUPP;
+ goto finish;
+ }
+
switch (arg_action) {
case ACTION_MOUNT: