o Implement -U flag: run command as user which exists only in jail.
o getpwnam(3) returns NULL and does not set errno when the user does not exist. Bail out with "no such user" instead of "Unknown error: 0". PR: bin/67262 Submitted by: demon (-U flag) MFC after: 3 weeks
This commit is contained in:
parent
23465eaec2
commit
927b481001
@ -42,7 +42,7 @@
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl i
|
||||
.Op Fl u Ar username
|
||||
.Op Fl u Ar username | Fl U Ar username
|
||||
.Ar path hostname ip-number command ...
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
@ -54,7 +54,11 @@ The options are as follows:
|
||||
.It Fl i
|
||||
Output the jail identifier of the newly created jail.
|
||||
.It Fl u Ar username
|
||||
The user name as whom the
|
||||
The user name from host environment as whom the
|
||||
.Ar command
|
||||
should run.
|
||||
.It Fl U Ar username
|
||||
The user name from jailed environment as whom the
|
||||
.Ar command
|
||||
should run.
|
||||
.It Ar path
|
||||
|
@ -17,6 +17,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <grp.h>
|
||||
#include <login_cap.h>
|
||||
#include <pwd.h>
|
||||
@ -27,6 +28,22 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
static void usage(void);
|
||||
|
||||
#define GET_USER_INFO do { \
|
||||
pwd = getpwnam(username); \
|
||||
if (pwd == NULL) { \
|
||||
if (errno) \
|
||||
err(1, "getpwnam: %s", username); \
|
||||
else \
|
||||
errx(1, "%s: no such user", username); \
|
||||
} \
|
||||
lcap = login_getpwclass(pwd); \
|
||||
if (lcap == NULL) \
|
||||
err(1, "getpwclass: %s", username); \
|
||||
ngroups = NGROUPS; \
|
||||
if (getgrouplist(username, pwd->pw_gid, groups, &ngroups) != 0) \
|
||||
err(1, "getgrouplist: %s", username); \
|
||||
} while (0)
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
@ -34,19 +51,24 @@ main(int argc, char **argv)
|
||||
struct jail j;
|
||||
struct passwd *pwd;
|
||||
struct in_addr in;
|
||||
int ch, groups[NGROUPS], i, iflag, ngroups;
|
||||
int ch, groups[NGROUPS], i, iflag, ngroups, uflag, Uflag;
|
||||
char *username;
|
||||
|
||||
iflag = 0;
|
||||
iflag = uflag = Uflag = 0;
|
||||
username = NULL;
|
||||
|
||||
while ((ch = getopt(argc, argv, "iu:")) != -1) {
|
||||
while ((ch = getopt(argc, argv, "iu:U:")) != -1) {
|
||||
switch (ch) {
|
||||
case 'i':
|
||||
iflag = 1;
|
||||
break;
|
||||
case 'u':
|
||||
username = optarg;
|
||||
uflag = 1;
|
||||
break;
|
||||
case 'U':
|
||||
username = optarg;
|
||||
Uflag = 1;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
@ -56,18 +78,10 @@ main(int argc, char **argv)
|
||||
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: %s", username);
|
||||
ngroups = NGROUPS;
|
||||
if (getgrouplist(username, pwd->pw_gid, groups, &ngroups) != 0)
|
||||
err(1, "getgrouplist: %s", username);
|
||||
}
|
||||
if (uflag && Uflag)
|
||||
usage();
|
||||
if (uflag)
|
||||
GET_USER_INFO;
|
||||
if (chdir(argv[0]) != 0)
|
||||
err(1, "chdir: %s", argv[0]);
|
||||
memset(&j, 0, sizeof(j));
|
||||
@ -85,6 +99,8 @@ main(int argc, char **argv)
|
||||
fflush(stdout);
|
||||
}
|
||||
if (username != NULL) {
|
||||
if (Uflag)
|
||||
GET_USER_INFO;
|
||||
if (setgroups(ngroups, groups) != 0)
|
||||
err(1, "setgroups");
|
||||
if (setgid(pwd->pw_gid) != 0)
|
||||
@ -103,7 +119,8 @@ static void
|
||||
usage(void)
|
||||
{
|
||||
|
||||
(void)fprintf(stderr,
|
||||
"usage: jail [-i] [-u username] path hostname ip-number command ...\n");
|
||||
(void)fprintf(stderr, "%s%s\n",
|
||||
"usage: jail [-i] [-u username | -U username]",
|
||||
" path hostname ip-number command ...");
|
||||
exit(1);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user