#include "namespace.h"
#include "exec_shell.h"
#include "optutils.h"
+#include "xalloc.h"
+#include "all-io.h"
+#include "env.h"
static struct namespace_file {
int nstype;
fputs(_(" --preserve-credentials do not touch uids or gids\n"), out);
fputs(_(" -r, --root[=<dir>] set the root directory\n"), out);
fputs(_(" -w, --wd[=<dir>] set the working directory\n"), out);
- fputs(_(" -W. --wdns <dir> set the working directory in namespace\n"), out);
+ fputs(_(" -W, --wdns <dir> set the working directory in namespace\n"), out);
+ fputs(_(" -e, --env inherit environment variables from target process\n"), out);
fputs(_(" -F, --no-fork do not fork before exec'ing <program>\n"), out);
#ifdef HAVE_LIBSELINUX
fputs(_(" -Z, --follow-context set SELinux context according to --target PID\n"), out);
static pid_t namespace_target_pid = 0;
static int root_fd = -1;
static int wd_fd = -1;
+static int env_fd = -1;
static void open_target_fd(int *fd, const char *type, const char *path)
{
{ "root", optional_argument, NULL, 'r' },
{ "wd", optional_argument, NULL, 'w' },
{ "wdns", optional_argument, NULL, 'W' },
+ { "env", no_argument, NULL, 'e' },
{ "no-fork", no_argument, NULL, 'F' },
{ "preserve-credentials", no_argument, NULL, OPT_PRESERVE_CRED },
#ifdef HAVE_LIBSELINUX
struct namespace_file *nsfile;
int c, pass, namespaces = 0, setgroups_nerrs = 0, preserve_cred = 0;
- bool do_rd = false, do_wd = false, force_uid = false, force_gid = false;
+ bool do_rd = false, do_wd = false, force_uid = false, force_gid = false, do_env = false;
bool do_all = false;
int do_fork = -1; /* unknown yet */
char *wdns = NULL;
uid_t uid = 0;
gid_t gid = 0;
+ struct ul_env_list *envls;
#ifdef HAVE_LIBSELINUX
bool selinux = 0;
#endif
close_stdout_atexit();
while ((c =
- getopt_long(argc, argv, "+ahVt:m::u::i::n::p::C::U::T::S:G:r::w::W:FZ",
+ getopt_long(argc, argv, "+ahVt:m::u::i::n::p::C::U::T::S:G:r::w::W::eFZ",
longopts, NULL)) != -1) {
err_exclusive_options(c, longopts, excl, excl_st);
case 'W':
wdns = optarg;
break;
+ case 'e':
+ do_env = true;
+ break;
case OPT_PRESERVE_CRED:
preserve_cred = 1;
break;
open_target_fd(&root_fd, "root", NULL);
if (do_wd)
open_target_fd(&wd_fd, "cwd", NULL);
+ if (do_env)
+ open_target_fd(&env_fd, "environ", NULL);
/*
* Update namespaces variable to contain all requested namespaces
wd_fd = -1;
}
+ /* Pass environment variables of the target process to the spawned process */
+ if (env_fd >= 0) {
+ if ((envls = env_from_fd(env_fd)) == NULL)
+ err(EXIT_FAILURE, _("failed to get environment variables"));
+ clearenv();
+ if (env_list_setenv(envls) < 0)
+ err(EXIT_FAILURE, _("failed to set environment variables"));
+ env_list_free(envls);
+ close(env_fd);
+ }
+
if (do_fork == 1)
continue_as_child();