fputs(_(" -C, --cgroup[=<file>] enter cgroup namespace\n"), out);
fputs(_(" -U, --user[=<file>] enter user namespace\n"), out);
fputs(_(" -T, --time[=<file>] enter time namespace\n"), out);
- fputs(_(" -S, --setuid <uid> set uid in entered namespace\n"), out);
- fputs(_(" -G, --setgid <gid> set gid in entered namespace\n"), out);
- fputs(_(" -S, --setuid=[<uid>] set uid in entered namespace\n"), out);
- fputs(_(" -G, --setgid=[<gid>] set gid in entered namespace\n"), out);
++ fputs(_(" -S, --setuid[=<uid>] set uid in entered namespace\n"), out);
++ fputs(_(" -G, --setgid[=<gid>] set gid in entered namespace\n"), out);
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);
static pid_t namespace_target_pid = 0;
static int root_fd = -1;
static int wd_fd = -1;
+static int env_fd = -1;
+ static int uid_gid_fd = -1;
static void open_target_fd(int *fd, const char *type, const char *path)
{
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, do_env = false;
- bool do_rd = false, do_wd = false, do_uid = false, force_uid = false, do_gid = false, force_gid = false;
-- bool do_all = false;
++ bool do_rd = false, do_wd = false, do_uid = false, force_uid = false,
++ do_gid = false, force_gid = false, do_env = false, do_all = false;
int do_fork = -1; /* unknown yet */
char *wdns = NULL;
uid_t uid = 0;
close_stdout_atexit();
while ((c =
- getopt_long(argc, argv, "+ahVt:m::u::i::n::p::C::U::T::S:G:r::w::W::eFZ",
- 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);
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);
+ if (do_uid || do_gid)
+ open_target_fd(&uid_gid_fd, "", 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 (uid_gid_fd >= 0) {
+ struct stat st;
+
+ if (fstat(uid_gid_fd, &st) > 0)
+ err(EXIT_FAILURE, _("can not get process stat"));
+
+ close(uid_gid_fd);
+ uid_gid_fd = -1;
+
+ if (do_uid)
+ uid = st.st_uid;
+ if (do_gid)
+ gid = st.st_gid;
+ }
+
if (do_fork == 1)
continue_as_child();