From 18a10ddc1681f3d7ab58470f5c6e2e335767a60f Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Tue, 12 Apr 2016 17:01:39 +0100 Subject: [PATCH] virt-login-shell: add ability to auto-detect shell from container Currently the shell must be looked up from the config setting in /etc/libvirt/virt-login-shell.conf. This is inflexible if there are containers where different users need different shells. Add add a new 'auto-shell' config parameter which instructs us to query the containers' /etc/passwd for the shell to be exec'd. Signed-off-by: Daniel P. Berrange --- tools/virt-login-shell.c | 37 +++++++++++++++++++++++++++++++++++++ tools/virt-login-shell.conf | 14 ++++++++++++++ tools/virt-login-shell.pod | 7 +++++++ 3 files changed, 58 insertions(+) diff --git a/tools/virt-login-shell.c b/tools/virt-login-shell.c index 784008bc56..dc3d3e371b 100644 --- a/tools/virt-login-shell.c +++ b/tools/virt-login-shell.c @@ -100,6 +100,25 @@ static int virLoginShellAllowedUser(virConfPtr conf, return ret; } +static int virLoginShellGetAutoShell(virConfPtr conf, + bool *autoshell) +{ + virConfValuePtr p; + + p = virConfGetValue(conf, "auto_shell"); + if (!p) { + *autoshell = false; + } else if (p->type == VIR_CONF_LONG || + p->type == VIR_CONF_ULONG) { + *autoshell = (p->l != 0); + } else { + virReportSystemError(EINVAL, "%s", + _("auto_shell must be a boolean value")); + return -1; + } + return 0; +} + static int virLoginShellGetShellArgv(virConfPtr conf, char ***retshargv, size_t *retshargvlen) @@ -222,6 +241,7 @@ main(int argc, char **argv) char *tmp; char *term = NULL; virErrorPtr saved_err = NULL; + bool autoshell = false; struct option opt[] = { {"help", no_argument, NULL, 'h'}, @@ -292,6 +312,9 @@ main(int argc, char **argv) if (virLoginShellGetShellArgv(conf, &shargv, &shargvlen) < 0) goto cleanup; + if (virLoginShellGetAutoShell(conf, &autoshell) < 0) + goto cleanup; + conn = virConnectOpen("lxc:///"); if (!conn) goto cleanup; @@ -342,6 +365,20 @@ main(int argc, char **argv) goto cleanup; } + if (autoshell) { + tmp = virGetUserShell(uid); + if (tmp) { + virStringFreeList(shargv); + shargvlen = 1; + if (VIR_ALLOC_N(shargv[0], shargvlen + 1) < 0) { + VIR_FREE(tmp); + goto cleanup; + } + shargv[0] = tmp; + shargv[1] = NULL; + } + } + if (cmdstr) { if (VIR_REALLOC_N(shargv, shargvlen + 3) < 0) goto cleanup; diff --git a/tools/virt-login-shell.conf b/tools/virt-login-shell.conf index e29d22206c..4a504b37c5 100644 --- a/tools/virt-login-shell.conf +++ b/tools/virt-login-shell.conf @@ -18,6 +18,20 @@ # Note there is no need to pass a '--login' / '-l' argument since # virt-login-shell will always request a login shell +# Normally virt-login-shell will always use the shell identified +# by the 'shell' configuration setting above. If the container +# is running a full OS, it might be desirable to allow the choice +# of shell to be delegated to the owner of the shell, by querying +# the /etc/passwd file inside the container +# +# To allow for that, uncomment the following: +# auto_shell = 1 +# +# NB, this should /not/ be used if any container is sharing the +# host filesystem /etc, as this would cause virt-login-shell to +# look at the host's /etc/passwd finding itself as the listed +# shell. Hilarious recursion would then ensue. + # allowed_users specifies the user names of all users that are allowed to # execute virt-login-shell. You can specify the users as a comma # separated list of usernames or user groups. diff --git a/tools/virt-login-shell.pod b/tools/virt-login-shell.pod index 37619193df..9d61115417 100644 --- a/tools/virt-login-shell.pod +++ b/tools/virt-login-shell.pod @@ -46,6 +46,13 @@ You can modify this behaviour by defining the shell variable in eg. shell = [ "/bin/bash" ] +If the 'auto_shell' config option is set then it will attempt to automatically +detect the shell from /etc/password inside the container. This should only be +done if the container has a separate /etc directory from the host, otherwise +it will end up recursively invoking virt-login-shell. + +eg. auto_shell = 1 + By default no users are allowed to use virt-login-shell, if you want to allow certain users to use virt-login-shell, you need to modify the allowed_users variable in /etc/libvirt/virt-login-shell.conf.