summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek2013-02-14 03:05:48 +0100
committerKarel Zak2013-02-14 14:42:35 +0100
commit57580694269be36cc52138b0f82e72f09338e192 (patch)
tree1b4f0a31421327529afc83c9d2b16750f465fe49
parentlibblkid: read whole buffer for iso_volume_descriptor (diff)
downloadkernel-qcow2-util-linux-57580694269be36cc52138b0f82e72f09338e192.tar.gz
kernel-qcow2-util-linux-57580694269be36cc52138b0f82e72f09338e192.tar.xz
kernel-qcow2-util-linux-57580694269be36cc52138b0f82e72f09338e192.zip
unshare,nsenter: spawn shell by default
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>
-rw-r--r--include/exec_shell.h1
-rw-r--r--lib/Makemodule.am3
-rw-r--r--lib/exec_shell.c27
-rw-r--r--sys-utils/Makemodule.am1
-rw-r--r--sys-utils/nsenter.15
-rw-r--r--sys-utils/nsenter.c16
-rw-r--r--sys-utils/unshare.c12
7 files changed, 49 insertions, 16 deletions
diff --git a/include/exec_shell.h b/include/exec_shell.h
new file mode 100644
index 000000000..a2aa757de
--- /dev/null
+++ b/include/exec_shell.h
@@ -0,0 +1 @@
+extern void __attribute__((__noreturn__)) exec_shell(void);
diff --git a/lib/Makemodule.am b/lib/Makemodule.am
index 81e20b106..74b6bc1fa 100644
--- a/lib/Makemodule.am
+++ b/lib/Makemodule.am
@@ -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
index 000000000..95620cd4d
--- /dev/null
+++ b/lib/exec_shell.c
@@ -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);
+}
diff --git a/sys-utils/Makemodule.am b/sys-utils/Makemodule.am
index 86c529eae..c214b927e 100644
--- a/sys-utils/Makemodule.am
+++ b/sys-utils/Makemodule.am
@@ -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
diff --git a/sys-utils/nsenter.1 b/sys-utils/nsenter.1
index ea3c1b066..719f23224 100644
--- a/sys-utils/nsenter.1
+++ b/sys-utils/nsenter.1
@@ -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.
diff --git a/sys-utils/nsenter.c b/sys-utils/nsenter.c
index 3df433812..106349c7e 100644
--- a/sys-utils/nsenter.c
+++ b/sys-utils/nsenter.c
@@ -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>
@@ -28,12 +26,15 @@
#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();
}
diff --git a/sys-utils/unshare.c b/sys-utils/unshare.c
index 62d2fcbbf..2eea165b8 100644
--- a/sys-utils/unshare.c
+++ b/sys-utils/unshare.c
@@ -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();
}