diff options
-rw-r--r-- | usr.sbin/jexec/Makefile | 2 | ||||
-rw-r--r-- | usr.sbin/jexec/jexec.8 | 14 | ||||
-rw-r--r-- | usr.sbin/jexec/jexec.c | 70 |
3 files changed, 80 insertions, 6 deletions
diff --git a/usr.sbin/jexec/Makefile b/usr.sbin/jexec/Makefile index 87e9926..2bf817c 100644 --- a/usr.sbin/jexec/Makefile +++ b/usr.sbin/jexec/Makefile @@ -2,6 +2,8 @@ PROG= jexec MAN= jexec.8 +DPADD= ${LIBUTIL} +LDADD= -lutil WARNS?= 6 .include <bsd.prog.mk> diff --git a/usr.sbin/jexec/jexec.8 b/usr.sbin/jexec/jexec.8 index a5749c1..0677ff0 100644 --- a/usr.sbin/jexec/jexec.8 +++ b/usr.sbin/jexec/jexec.8 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd April 8, 2003 +.Dd April 19, 2006 .Dt JEXEC 8 .Os .Sh NAME @@ -33,6 +33,7 @@ .Nd "execute a command inside an existing jail" .Sh SYNOPSIS .Nm +.Op Fl u Ar username | Fl U Ar username .Ar jid command ... .Sh DESCRIPTION The @@ -41,6 +42,17 @@ utility executes .Ar command inside the jail identified by .Ar jid . +.Pp +The following options are available: +.Bl -tag -width indent +.It Fl u Ar username +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. .Sh SEE ALSO .Xr jail_attach 2 , .Xr jail 8 , diff --git a/usr.sbin/jexec/jexec.c b/usr.sbin/jexec/jexec.c index 089a896..f35b1ec 100644 --- a/usr.sbin/jexec/jexec.c +++ b/usr.sbin/jexec/jexec.c @@ -30,26 +30,84 @@ #include <sys/jail.h> #include <err.h> +#include <errno.h> +#include <login_cap.h> #include <stdio.h> #include <stdlib.h> +#include <pwd.h> #include <unistd.h> 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[]) { int jid; + login_cap_t *lcap = NULL; + struct passwd *pwd = NULL; + gid_t groups[NGROUPS]; + int ch, ngroups, uflag, Uflag; + char *username; + ch = uflag = Uflag = 0; + username = NULL; - if (argc < 3) + while ((ch = getopt(argc, argv, "u:U:")) != -1) { + switch (ch) { + case 'u': + username = optarg; + uflag = 1; + break; + case 'U': + username = optarg; + Uflag = 1; + break; + default: + usage(); + } + } + argc -= optind; + argv += optind; + if (argc < 2) + usage(); + if (uflag && Uflag) usage(); - jid = (int)strtol(argv[1], NULL, 10); + if (uflag) + GET_USER_INFO; + jid = (int)strtol(argv[0], NULL, 10); if (jail_attach(jid) == -1) err(1, "jail_attach(): %d", jid); if (chdir("/") == -1) err(1, "chdir(): /"); - if (execvp(argv[2], argv + 2) == -1) - err(1, "execvp(): %s", argv[2]); + if (username != NULL) { + if (Uflag) + GET_USER_INFO; + if (setgroups(ngroups, groups) != 0) + err(1, "setgroups"); + if (setgid(pwd->pw_gid) != 0) + err(1, "setgid"); + if (setusercontext(lcap, pwd, pwd->pw_uid, + LOGIN_SETALL & ~LOGIN_SETGROUP & ~LOGIN_SETLOGIN) != 0) + err(1, "setusercontext"); + login_close(lcap); + } + if (execvp(argv[1], argv + 1) == -1) + err(1, "execvp(): %s", argv[1]); exit(0); } @@ -57,6 +115,8 @@ static void usage(void) { - fprintf(stderr, "usage: jexec jid command [...]\n"); + fprintf(stderr, "%s%s\n", + "usage: jexec [-u username | -U username]", + " jid command [...]"); exit(1); } |