\fB\-U\fR, \fB\-\-user\fR[=\fIfile\fR]
Enter the user namespace. If no file is specified, enter the user namespace of
the target process. If file is specified, enter the user namespace specified by
-file.
+file. See also \fB\-\-setuid\fR and \fB\-\-setgid\fR options.
+.TP
+\fB\-G\fR, \fB\-\-setgid\fR \fIgid\fR
+Set group ID which will be used in the entered user namespace.
+.TP
+\fB\-S\fR, \fB\-\-setuid\fR \fIuid\fR
+Set user ID which will be used in the entered user namespace.
.TP
\fB\-r\fR, \fB\-\-root\fR[=\fIdirectory\fR]
Set the root directory. If no directory is specified, set the root directory to
fputs(_(" -n, --net [=<file>] enter network namespace\n"), out);
fputs(_(" -p, --pid [=<file>] enter pid namespace\n"), out);
fputs(_(" -U, --user [=<file>] enter user namespace\n"), out);
+ fputs(_(" -S, --setuid <uid> set uid in user namespace\n"), out);
+ fputs(_(" -G, --setgid <gid> set gid in user namespace\n"), out);
fputs(_(" -r, --root [=<dir>] set the root directory\n"), out);
fputs(_(" -w, --wd [=<dir>] set the working directory\n"), out);
fputs(_(" -F, --no-fork do not fork before exec'ing <program>\n"), out);
{ "net", optional_argument, NULL, 'n' },
{ "pid", optional_argument, NULL, 'p' },
{ "user", optional_argument, NULL, 'U' },
+ { "setuid", required_argument, NULL, 'S' },
+ { "setgid", required_argument, NULL, 'G' },
{ "root", optional_argument, NULL, 'r' },
{ "wd", optional_argument, NULL, 'w' },
{ "no-fork", no_argument, NULL, 'F' },
int c, namespaces = 0;
bool do_rd = false, do_wd = false;
int do_fork = -1; /* unknown yet */
+ uid_t uid = 0;
+ gid_t gid = 0;
setlocale(LC_MESSAGES, "");
bindtextdomain(PACKAGE, LOCALEDIR);
atexit(close_stdout);
while ((c =
- getopt_long(argc, argv, "hVt:m::u::i::n::p::U::r::w::F",
+ getopt_long(argc, argv, "hVt:m::u::i::n::p::U::S:G:r::w::F",
longopts, NULL)) != -1) {
switch (c) {
case 'h':
else
namespaces |= CLONE_NEWUSER;
break;
+ case 'S':
+ uid = strtoul_or_err(optarg, _("failed to parse uid"));
+ break;
+ case 'G':
+ gid = strtoul_or_err(optarg, _("failed to parse gid"));
+ break;
case 'F':
do_fork = 0;
break;
if (do_fork == 1)
continue_as_child();
+ if (namespaces & CLONE_NEWUSER) {
+ if (setuid(uid) < 0)
+ err(EXIT_FAILURE, _("setuid failed"));
+ if (setgid(gid) < 0)
+ err(EXIT_FAILURE, _("setgid failed"));
+ }
+
if (optind < argc) {
execvp(argv[optind], argv + optind);
err(EXIT_FAILURE, _("failed to execute %s"), argv[optind]);