]> xenbits.xensource.com Git - libvirt.git/commitdiff
virt-login-shell: change way we request a login shell
authorDaniel P. Berrange <berrange@redhat.com>
Tue, 12 Apr 2016 14:45:48 +0000 (15:45 +0100)
committerDaniel P. Berrange <berrange@redhat.com>
Fri, 10 Jun 2016 10:03:01 +0000 (11:03 +0100)
Currently we request a login shell by passing the -l argument
to the shell. This is either hardcoded, or required to be
specified by the user in the virt-login-shell.conf file.

The standard way for login programs to request a shell run
as a login shell is to modify the argv passed to execve()
so that argv[0] contains the relative shell filename
prefixed with a zero. eg instead of doing

  const char **shellargs = ["/bin/bash", "-l", NULL];
  execve(shellargs[0], shellargs, env);

We should be doing

  const char **shellargs = ["-bash", NULL];
  execve("/bin/bash", shellargs, env);

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 116fa73eb60853d605f9c7ce08fe643d5aa29251..51175f74db1923e9bd71351fd78dc76c75f859de 100644 (file)
@@ -111,7 +111,7 @@ static int virLoginShellGetShellArgv(virConfPtr conf,
 
     p = virConfGetValue(conf, "shell");
     if (!p) {
-        len = 2; /* /bin/sh -l */
+        len = 1; /* /bin/sh */
     } else if (p->type == VIR_CONF_LIST) {
         /* Calc length and check items */
         for (len = 0, pp = p->list; pp; len++, pp = pp->next) {
@@ -136,8 +136,6 @@ static int virLoginShellGetShellArgv(virConfPtr conf,
     if (!p) {
         if (VIR_STRDUP(shargv[i++], "/bin/sh") < 0)
             goto error;
-        if (VIR_STRDUP(shargv[i++], "-l") < 0)
-            goto error;
     } else if (p->type == VIR_CONF_LIST) {
         for (pp = p->list; pp; pp = pp->next) {
             if (VIR_STRDUP(shargv[i++], pp->str) < 0)
@@ -201,6 +199,7 @@ main(int argc, char **argv)
     char *name = NULL;
     char **shargv = NULL;
     size_t shargvlen = 0;
+    char *shcmd = NULL;
     virSecurityModelPtr secmodel = NULL;
     virSecurityLabelPtr seclabel = NULL;
     virDomainPtr dom = NULL;
@@ -215,6 +214,7 @@ main(int argc, char **argv)
     int openmax;
     size_t i;
     const char *cmdstr = NULL;
+    char *tmp;
 
     struct option opt[] = {
         {"help", no_argument, NULL, 'h'},
@@ -347,6 +347,22 @@ main(int argc, char **argv)
         shargv[shargvlen] = NULL;
     }
 
+    /* We need to modify the first elementin shargv
+     * so that it has the relative filename and has
+     * a leading '-' to indicate it is a login shell
+     */
+    shcmd = shargv[0];
+    if (shcmd[0] != '/') {
+        virReportSystemError(errno,
+                             _("Shell '%s' should have absolute path"),
+                             shcmd);
+        goto cleanup;
+    }
+    tmp = strrchr(shcmd, '/');
+    if (VIR_STRDUP(shargv[0], tmp) < 0)
+        goto cleanup;
+    shargv[0][0] = '-';
+
     /* A fork is required to create new process in correct pid namespace.  */
     if ((cpid = virFork()) < 0)
         goto cleanup;
@@ -358,9 +374,9 @@ main(int argc, char **argv)
             tmpfd = i;
             VIR_MASS_CLOSE(tmpfd);
         }
-        if (execv(shargv[0], (char *const*) shargv) < 0) {
+        if (execv(shcmd, (char *const*) shargv) < 0) {
             virReportSystemError(errno, _("Unable to exec shell %s"),
-                                 shargv[0]);
+                                 shcmd);
             virDispatchError(NULL);
             return errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE;
         }
@@ -379,6 +395,7 @@ main(int argc, char **argv)
     if (conn)
         virConnectClose(conn);
     virStringFreeList(shargv);
+    VIR_FREE(shcmd);
     VIR_FREE(name);
     VIR_FREE(homedir);
     VIR_FREE(seclabel);
index 835fd3fecd912ac55b3f40013fc1f7a2a3c2db95..67ca1cc8d9ef8b4c7c089c7353fb815d959a76e4 100644 (file)
@@ -8,7 +8,11 @@
 # container.  Shell commands must be a list of commands/options separated by
 # comma and delimited by square brackets. Defaults to: /bin/sh -l.
 # Modify and uncomment the following to modify the login shell.
-# shell = [ "/bin/sh",  "-l" ]
+#
+# shell = [ "/bin/bash" ]
+#
+# Note there is no need to pass a '--login' / '-l' argument since
+# virt-login-shell will always request a login shell
 
 # 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
index c41c2ad22691ead1819ffbb7bcf543fca8858bd5..37619193dfc7619c031417ec6b4eba4680c7b10b 100644 (file)
@@ -44,7 +44,7 @@ By default, virt-login-shell will execute the /bin/sh program for the user.
 You can modify this behaviour by defining the shell variable in
 /etc/libvirt/virt-login-shell.conf.
 
-eg.  shell = [ "/bin/ksh", "--login"]
+eg.  shell = [ "/bin/bash" ]
 
 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