From bc3bb330b8543a31d4a1f488cb782b6ff3519d6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 26 Sep 2016 11:45:31 -0400 Subject: [PATCH] machinectl: prefer user@ to --uid=user for shell (#4006) It seems to me that the explicit positional argument should have higher priority than "an option". --- man/machinectl.xml | 11 ++++---- src/machine/machinectl.c | 57 ++++++++++++++++++++++++++++------------ 2 files changed, 45 insertions(+), 23 deletions(-) diff --git a/man/machinectl.xml b/man/machinectl.xml index 7056fd4204..eaa247714b 100644 --- a/man/machinectl.xml +++ b/man/machinectl.xml @@ -186,12 +186,11 @@ - When used with the shell - command, chooses the user ID to open the interactive shell - session as. If this switch is not specified, defaults to - root. Note that this switch is not - supported for the login command (see - below). + When used with the shell command, chooses the user ID to + open the interactive shell session as. If the argument to the shell + command also specifies an user name, this option is ignored. If the name is not specified + in either way, root will be used by default. Note that this switch is + not supported for the login command (see below). diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c index d2ca2ef342..e9de31e184 100644 --- a/src/machine/machinectl.c +++ b/src/machine/machinectl.c @@ -1368,6 +1368,41 @@ static int process_forward(sd_event *event, PTYForward **forward, int master, PT return ret; } +static int parse_machine_uid(const char *spec, const char **machine, char **uid) { + /* + * Whatever is specified in the spec takes priority over global arguments. + */ + char *_uid = NULL; + const char *_machine = NULL; + + if (spec) { + const char *at; + + at = strchr(spec, '@'); + if (at) { + if (at == spec) + /* Do the same as ssh and refuse "@host". */ + return -EINVAL; + + _machine = at + 1; + _uid = strndup(spec, at - spec); + if (!_uid) + return -ENOMEM; + } else + _machine = spec; + }; + + if (arg_uid && !_uid) { + _uid = strdup(arg_uid); + if (!_uid) + return -ENOMEM; + } + + *uid = _uid; + *machine = isempty(_machine) ? ".host" : _machine; + return 0; +} + static int login_machine(int argc, char *argv[], void *userdata) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; @@ -1443,7 +1478,8 @@ static int shell_machine(int argc, char *argv[], void *userdata) { _cleanup_(sd_event_unrefp) sd_event *event = NULL; int master = -1, r; sd_bus *bus = userdata; - const char *pty, *match, *machine, *path, *uid = NULL; + const char *pty, *match, *machine, *path; + _cleanup_free_ char *uid = NULL; assert(bus); @@ -1474,22 +1510,9 @@ static int shell_machine(int argc, char *argv[], void *userdata) { if (r < 0) return log_error_errno(r, "Failed to attach bus to event loop: %m"); - machine = argc < 2 || isempty(argv[1]) ? NULL : argv[1]; - - if (arg_uid) - uid = arg_uid; - else if (machine) { - const char *at; - - at = strchr(machine, '@'); - if (at) { - uid = strndupa(machine, at - machine); - machine = at + 1; - } - } - - if (isempty(machine)) - machine = ".host"; + r = parse_machine_uid(argc >= 2 ? argv[1] : NULL, &machine, &uid); + if (r < 0) + return log_error_errno(r, "Failed to parse machine specification: %m"); match = strjoina("type='signal'," "sender='org.freedesktop.machine1',"