]> xenbits.xensource.com Git - libvirt.git/commitdiff
virt-login-shell: add ability to auto-detect shell from container
authorDaniel P. Berrange <berrange@redhat.com>
Tue, 12 Apr 2016 16:01:39 +0000 (17:01 +0100)
committerDaniel P. Berrange <berrange@redhat.com>
Fri, 10 Jun 2016 10:03:02 +0000 (11:03 +0100)
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 <berrange@redhat.com>
tools/virt-login-shell.c
tools/virt-login-shell.conf
tools/virt-login-shell.pod

index 784008bc569db82103b127f7aa1eaf646902cb91..dc3d3e371b15394765e5223676bf0a30234a604d 100644 (file)
@@ -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;
index e29d22206c37b71e961f5e29268d2aa2b9679638..4a504b37c5ddfc609b50d2339865f05f251e6cc4 100644 (file)
 # 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.
index 37619193dfc7619c031417ec6b4eba4680c7b10b..9d61115417a306fe18b3019ffaf2014cddd84c50 100644 (file)
@@ -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.