o Add -u <username> flag to jail(8): set user context before exec.

PR:		bin/44320
Submitted by:	Mike Matsnev <mike@po.cs.msu.su>
Reviewed by:	-current
MFC after:	6 weeks
This commit is contained in:
maxim 2003-03-27 12:16:58 +00:00
parent b5a5c0828b
commit ea389504ed
3 changed files with 84 additions and 12 deletions

View File

@ -2,6 +2,8 @@
PROG= jail
MAN= jail.8
DPADD= ${LIBUTIL}
LDADD= -lutil
WARNS?= 2

View File

@ -41,12 +41,29 @@
.Nd "imprison process and its descendants"
.Sh SYNOPSIS
.Nm
.Op Fl u Ar username
.Ar path hostname ip-number command ...
.Sh DESCRIPTION
The
.Nm
utility imprisons a process and all future descendants.
.Pp
The options are as follows:
.Bl -tag -width ".Fl u Ar username"
.It Fl u Ar username
The user name as whom the
.Ar command
should run.
.It Ar path
Directory which is to be the root of the prison.
.It Ar hostname
Hostname of the prison.
.It Ar ip-number
IP number assigned to the prison.
.It Ar command
Pathname of the program which is to be executed.
.El
.Pp
Please see the
.Xr jail 2
man page for further details.

View File

@ -10,44 +10,97 @@
*
*/
#include <sys/types.h>
#include <sys/param.h>
#include <sys/jail.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <err.h>
#include <grp.h>
#include <login_cap.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
static void usage(void);
int
main(int argc, char **argv)
{
login_cap_t *lcap;
struct jail j;
int i;
struct passwd *pwd;
struct in_addr in;
int ch, groups[NGROUPS], i, ngroups;
char *username;
if (argc < 5)
errx(1, "usage: %s path hostname ip-number command ...\n",
argv[0]);
i = chdir(argv[1]);
username = NULL;
while ((ch = getopt(argc, argv, "u:")) != -1)
switch (ch) {
case 'u':
username = optarg;
break;
default:
usage();
break;
}
argc -= optind;
argv += optind;
if (argc < 4)
usage();
if (username != NULL) {
pwd = getpwnam(username);
if (pwd == NULL)
err(1, "getpwnam %s", username);
lcap = login_getpwclass(pwd);
if (lcap == NULL)
err(1, "getpwclass failed", username);
ngroups = NGROUPS;
i = getgrouplist(username, pwd->pw_gid, groups, &ngroups);
if (i)
err(1, "getgrouplist %s", username);
}
i = chdir(argv[0]);
if (i)
err(1, "chdir %s", argv[1]);
err(1, "chdir %s", argv[0]);
memset(&j, 0, sizeof(j));
j.version = 0;
j.path = argv[1];
j.hostname = argv[2];
i = inet_aton(argv[3], &in);
j.path = argv[0];
j.hostname = argv[1];
i = inet_aton(argv[2], &in);
if (!i)
errx(1, "Couldn't make sense of ip-number\n");
j.ip_number = ntohl(in.s_addr);
i = jail(&j);
if (i)
err(1, "Imprisonment failed");
i = execv(argv[4], argv + 4);
if (username != NULL) {
i = setgroups(ngroups, groups);
if (i)
err(1, "setgroups failed");
i = setgid(pwd->pw_gid);
if (i)
err(1, "setgid failed");
i = setusercontext(lcap, pwd, pwd->pw_uid,
LOGIN_SETALL & ~LOGIN_SETGROUP);
if (i)
err(1, "setusercontext failed");
}
i = execv(argv[3], argv + 3);
if (i)
err(1, "execv(%s)", argv[4]);
err(1, "execv(%s)", argv[3]);
exit (0);
}
static void
usage(void)
{
errx(1,
"Usage: jail [-u username] path hostname ip-number command ...");
}