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:
Maxim Konovalov 2004-05-29 18:39:27 +00:00
parent 23465eaec2
commit 927b481001
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=129848
2 changed files with 40 additions and 19 deletions

View File

@ -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

View File

@ -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);
}