diff options
-rw-r--r-- | man/machinectl.xml | 11 | ||||
-rw-r--r-- | 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 @@ <varlistentry> <term><option>--uid=</option></term> - <listitem><para>When used with the <command>shell</command> - command, chooses the user ID to open the interactive shell - session as. If this switch is not specified, defaults to - <literal>root</literal>. Note that this switch is not - supported for the <command>login</command> command (see - below).</para></listitem> + <listitem><para>When used with the <command>shell</command> command, chooses the user ID to + open the interactive shell session as. If the argument to the <command>shell</command> + command also specifies an user name, this option is ignored. If the name is not specified + in either way, <literal>root</literal> will be used by default. Note that this switch is + not supported for the <command>login</command> command (see below).</para></listitem> </varlistentry> <varlistentry> 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'," |