diff options
author | delphij <delphij@FreeBSD.org> | 2006-04-19 10:12:10 +0000 |
---|---|---|
committer | delphij <delphij@FreeBSD.org> | 2006-04-19 10:12:10 +0000 |
commit | fe5c8255df598de68e545aabeb2b1c272e548b9a (patch) | |
tree | 4a17bb5881e69532ada738ff53e9ae0c192ec0ee /usr.sbin/jexec/jexec.c | |
parent | 51d1ca0f6e57fd46aed0662d117beda3ff711169 (diff) | |
download | FreeBSD-src-fe5c8255df598de68e545aabeb2b1c272e548b9a.zip FreeBSD-src-fe5c8255df598de68e545aabeb2b1c272e548b9a.tar.gz |
Add -u and -U which functions like the jail(8) that allow
commands to be executed under a different credential.
PR: bin/95777
Submitted by: clsung
Diffstat (limited to 'usr.sbin/jexec/jexec.c')
-rw-r--r-- | usr.sbin/jexec/jexec.c | 70 |
1 files changed, 65 insertions, 5 deletions
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); } |