o Add -l option to jail(8) similar to su(1): before running jail'ed

program under specific user's credentials, clean the environment and
set only a few variables.

PR:		bin/70024
Submitted by:	demon
MFC after:	1 month
This commit is contained in:
maxim 2004-08-15 08:21:50 +00:00
parent aa8e92f2fd
commit 4aa5a376e3
2 changed files with 50 additions and 6 deletions

View File

@ -42,7 +42,7 @@
.Sh SYNOPSIS
.Nm
.Op Fl i
.Op Fl u Ar username | Fl U Ar username
.Op Fl l Fl u Ar username | Fl U Ar username
.Ar path hostname ip-number command ...
.Sh DESCRIPTION
The
@ -53,6 +53,24 @@ The options are as follows:
.Bl -tag -width ".Fl u Ar username"
.It Fl i
Output the jail identifier of the newly created jail.
.It Fl l
Run program in the clean environment.
The environment is discarded except for
.Ev HOME ,
.Ev SHELL ,
.Ev TERM
and
.Ev USER .
.Ev HOME
and
.Ev SHELL
are set to the target login's default values.
.Ev USER
is set to the target login.
.Ev TERM
is imported from your current environment.
The environment variables from the login class capability database for the
target login are also set.
.It Fl u Ar username
The user name from host environment as whom the
.Ar command

View File

@ -20,6 +20,7 @@ __FBSDID("$FreeBSD$");
#include <errno.h>
#include <grp.h>
#include <login_cap.h>
#include <paths.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
@ -27,6 +28,7 @@ __FBSDID("$FreeBSD$");
#include <unistd.h>
static void usage(void);
extern char **environ;
#define GET_USER_INFO do { \
pwd = getpwnam(username); \
@ -51,13 +53,15 @@ main(int argc, char **argv)
struct jail j;
struct passwd *pwd;
struct in_addr in;
int ch, groups[NGROUPS], i, iflag, ngroups, uflag, Uflag;
int ch, groups[NGROUPS], i, iflag, lflag, ngroups, uflag, Uflag;
char path[PATH_MAX], *username;
static char *cleanenv;
const char *shell, *p;
iflag = uflag = Uflag = 0;
username = NULL;
iflag = lflag = uflag = Uflag = 0;
username = cleanenv = NULL;
while ((ch = getopt(argc, argv, "iu:U:")) != -1) {
while ((ch = getopt(argc, argv, "ilu:U:")) != -1) {
switch (ch) {
case 'i':
iflag = 1;
@ -70,6 +74,9 @@ main(int argc, char **argv)
username = optarg;
Uflag = 1;
break;
case 'l':
lflag = 1;
break;
default:
usage();
}
@ -80,6 +87,8 @@ main(int argc, char **argv)
usage();
if (uflag && Uflag)
usage();
if (lflag && username == NULL)
usage();
if (uflag)
GET_USER_INFO;
if (realpath(argv[0], path) == NULL)
@ -103,6 +112,10 @@ main(int argc, char **argv)
if (username != NULL) {
if (Uflag)
GET_USER_INFO;
if (lflag) {
p = getenv("TERM");
environ = &cleanenv;
}
if (setgroups(ngroups, groups) != 0)
err(1, "setgroups");
if (setgid(pwd->pw_gid) != 0)
@ -112,6 +125,19 @@ main(int argc, char **argv)
err(1, "setusercontext");
login_close(lcap);
}
if (lflag) {
if (*pwd->pw_shell)
shell = pwd->pw_shell;
else
shell = _PATH_BSHELL;
if (chdir(pwd->pw_dir) < 0)
errx(1, "no home directory");
setenv("HOME", pwd->pw_dir, 1);
setenv("SHELL", shell, 1);
setenv("USER", pwd->pw_name, 1);
if (p)
setenv("TERM", p, 1);
}
if (execv(argv[3], argv + 3) != 0)
err(1, "execv: %s", argv[3]);
exit(0);
@ -122,7 +148,7 @@ usage(void)
{
(void)fprintf(stderr, "%s%s\n",
"usage: jail [-i] [-u username | -U username]",
"usage: jail [-i] [-l -u username | -U username]",
" path hostname ip-number command ...");
exit(1);
}