diff options
author | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2017-12-09 10:18:48 +0100 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2017-12-15 14:57:07 +0100 |
commit | e09fc88440f399766f7f4fbe8e56b68ba18a131d (patch) | |
tree | a68728824cb2f1348d10673386ef1ad6eced930b /src | |
parent | 8426bfd397d5aba61c9b5ec79c12864ccf4cfd58 (diff) | |
download | systemd-e09fc88440f399766f7f4fbe8e56b68ba18a131d.tar.gz systemd-e09fc88440f399766f7f4fbe8e56b68ba18a131d.tar.bz2 systemd-e09fc88440f399766f7f4fbe8e56b68ba18a131d.zip |
mount: add option to specify uid= and gid=
The kernel needs two numbers, but for the user it's most convenient to provide the
user name and have that resolved to uid and gid.
Right now the primary group of the specified user is always used. That's the most
common case anyway. In the future we can extend the --owner option to allow a group
after a colon.
[I added this before realizing that this will not be enough to be used for user
runtime directory. But this seems useful on its own, so I'm keeping this commit.]
Diffstat (limited to 'src')
-rw-r--r-- | src/mount/mount-tool.c | 55 |
1 files changed, 52 insertions, 3 deletions
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: |