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:
parent
b5a5c0828b
commit
ea389504ed
@ -2,6 +2,8 @@
|
||||
|
||||
PROG= jail
|
||||
MAN= jail.8
|
||||
DPADD= ${LIBUTIL}
|
||||
LDADD= -lutil
|
||||
|
||||
WARNS?= 2
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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 ...");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user