]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
unshare,nsenter: spawn shell by default
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 14 Feb 2013 02:05:48 +0000 (21:05 -0500)
committerKarel Zak <kzak@redhat.com>
Thu, 14 Feb 2013 13:42:35 +0000 (14:42 +0100)
The behaviour mimics chroot.

Possibly it would have been nicer to to query the password database in
the new namepace and run the shell of the user there, but it's hard to
do correctly. getpwuid() might need to load nss plugins, and the arch
in the new namespace might be different (in case of NEWNS mounts), or
the hostname might be different, etc. So in general it's not possible
to do it reliably.

Signed-off-by: Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
include/exec_shell.h [new file with mode: 0644]
lib/Makemodule.am
lib/exec_shell.c [new file with mode: 0644]
sys-utils/Makemodule.am
sys-utils/nsenter.1
sys-utils/nsenter.c
sys-utils/unshare.c

diff --git a/include/exec_shell.h b/include/exec_shell.h
new file mode 100644 (file)
index 0000000..a2aa757
--- /dev/null
@@ -0,0 +1 @@
+extern void __attribute__((__noreturn__)) exec_shell(void);
index 81e20b106b92a16c15c2a6cdf4aa75b9d1c4c1b6..74b6bc1fa9bb9a7a26ea49df3843d6872e42e0d8 100644 (file)
@@ -24,7 +24,8 @@ libcommon_la_SOURCES = \
        lib/tt.c \
        lib/wholedisk.c \
        lib/ttyutils.c \
-       lib/xgetpass.c
+       lib/xgetpass.c \
+       lib/exec_shell.c
 
 if LINUX
 libcommon_la_SOURCES += \
diff --git a/lib/exec_shell.c b/lib/exec_shell.c
new file mode 100644 (file)
index 0000000..95620cd
--- /dev/null
@@ -0,0 +1,27 @@
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+#include "nls.h"
+#include "c.h"
+#include "xalloc.h"
+
+#include "exec_shell.h"
+
+#define DEFAULT_SHELL "/bin/sh"
+
+void __attribute__((__noreturn__)) exec_shell(void) {
+       const char *shell = getenv("SHELL"), *shell_basename;
+       char *arg0;
+       if (!shell)
+               shell = DEFAULT_SHELL;
+
+       shell_basename = basename(shell);
+       arg0 = xmalloc(strlen(shell_basename) + 2);
+       arg0[0] = '-';
+       strcpy(arg0 + 1, shell_basename);
+
+       execl(shell, arg0, NULL);
+       err(EXIT_FAILURE, _("failed to execute %s"), shell);
+}
index 86c529eae070fe6672eafc83d9f0cd4cc84a19bb..c214b927e4607dc395358b5b7f1cc56b781745f1 100644 (file)
@@ -287,6 +287,7 @@ if BUILD_UNSHARE
 usrbin_exec_PROGRAMS += unshare
 dist_man_MANS += sys-utils/unshare.1
 unshare_SOURCES = sys-utils/unshare.c
+unshare_LDADD = $(LDADD) libcommon.la
 endif
 
 if BUILD_NSENTER
index ea3c1b066855e500338f1caff80ab641a1a96dee..719f23224f83783d0260be0b6f0c9252309d4ffc 100644 (file)
@@ -4,7 +4,7 @@ nsenter \- run program with namespaces of other processes
 .SH SYNOPSIS
 .B nsenter
 .RI [ options ]
-program
+.RI [ program ]
 .RI [ arguments ]
 .SH DESCRIPTION
 Enters the contexts of one or more other processes and then executes specified
@@ -50,6 +50,9 @@ flag).
 See the
 .BR clone (2)
 for exact semantics of the flags.
+.TP
+If program is not given, run ``${SHELL}'' (default: /bin\:/sh).
+
 .SH OPTIONS
 Argument with square brakets, such as [\fIfile\fR], means optional argument.
 Command line syntax to specify optional argument \-\-mount=/path\:/to\:/file.
index 3df433812c567aeeaa36287c8038c49446d9993e..106349c7ea4888148977f5ba27b0abad57ca9200 100644 (file)
@@ -17,8 +17,6 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-#include <sys/types.h>
-#include <sys/wait.h>
 #include <dirent.h>
 #include <errno.h>
 #include <getopt.h>
 #include <stdbool.h>
 #include <unistd.h>
 #include <assert.h>
+#include <sys/types.h>
+#include <sys/wait.h>
 
 #include "strutils.h"
 #include "nls.h"
 #include "c.h"
 #include "closestream.h"
 #include "namespace.h"
+#include "exec_shell.h"
 
 static struct namespace_file {
        int nstype;
@@ -253,9 +254,6 @@ int main(int argc, char *argv[])
                }
        }
 
-       if (optind >= argc)
-               usage(EXIT_FAILURE);
-
        /*
         * Open remaining namespace and directory descriptors.
         */
@@ -317,7 +315,9 @@ int main(int argc, char *argv[])
        if (do_fork == 1)
                continue_as_child();
 
-       execvp(argv[optind], argv + optind);
-
-       err(EXIT_FAILURE, _("failed to execute %s"), argv[optind]);
+       if (optind < argc) {
+               execvp(argv[optind], argv + optind);
+               err(EXIT_FAILURE, _("failed to execute %s"), argv[optind]);
+       }
+       exec_shell();
 }
index 62d2fcbbfb976df7fcdbe0808779da3c8b879991..2eea165b84c75c750c551d886c09093804aaa71f 100644 (file)
@@ -29,6 +29,7 @@
 #include "c.h"
 #include "closestream.h"
 #include "namespace.h"
+#include "exec_shell.h"
 
 static void usage(int status)
 {
@@ -107,13 +108,12 @@ int main(int argc, char *argv[])
                }
        }
 
-       if(optind >= argc)
-               usage(EXIT_FAILURE);
-
        if(-1 == unshare(unshare_flags))
                err(EXIT_FAILURE, _("unshare failed"));
 
-       execvp(argv[optind], argv + optind);
-
-       err(EXIT_FAILURE, _("failed to execute %s"), argv[optind]);
+       if (optind < argc) {
+               execvp(argv[optind], argv + optind);
+               err(EXIT_FAILURE, _("failed to execute %s"), argv[optind]);
+       }
+       exec_shell();
 }