|
Lines 40-88
Link Here
|
| 40 |
#include <jail.h> |
40 |
#include <jail.h> |
| 41 |
#include <limits.h> |
41 |
#include <limits.h> |
| 42 |
#include <login_cap.h> |
42 |
#include <login_cap.h> |
|
|
43 |
#include <paths.h> |
| 44 |
#include <pwd.h> |
| 43 |
#include <stdio.h> |
45 |
#include <stdio.h> |
| 44 |
#include <stdlib.h> |
46 |
#include <stdlib.h> |
| 45 |
#include <string.h> |
47 |
#include <string.h> |
| 46 |
#include <pwd.h> |
|
|
| 47 |
#include <unistd.h> |
48 |
#include <unistd.h> |
| 48 |
|
49 |
|
|
|
50 |
extern char **environ; |
| 51 |
|
| 52 |
static void get_user_info(const char *username, const struct passwd **pwdp, |
| 53 |
login_cap_t **lcapp); |
| 49 |
static void usage(void); |
54 |
static void usage(void); |
| 50 |
|
55 |
|
| 51 |
#define GET_USER_INFO do { \ |
|
|
| 52 |
pwd = getpwnam(username); \ |
| 53 |
if (pwd == NULL) { \ |
| 54 |
if (errno) \ |
| 55 |
err(1, "getpwnam: %s", username); \ |
| 56 |
else \ |
| 57 |
errx(1, "%s: no such user", username); \ |
| 58 |
} \ |
| 59 |
lcap = login_getpwclass(pwd); \ |
| 60 |
if (lcap == NULL) \ |
| 61 |
err(1, "getpwclass: %s", username); \ |
| 62 |
ngroups = ngroups_max; \ |
| 63 |
if (getgrouplist(username, pwd->pw_gid, groups, &ngroups) != 0) \ |
| 64 |
err(1, "getgrouplist: %s", username); \ |
| 65 |
} while (0) |
| 66 |
|
| 67 |
int |
56 |
int |
| 68 |
main(int argc, char *argv[]) |
57 |
main(int argc, char *argv[]) |
| 69 |
{ |
58 |
{ |
| 70 |
int jid; |
59 |
int jid; |
| 71 |
login_cap_t *lcap = NULL; |
60 |
login_cap_t *lcap = NULL; |
| 72 |
struct passwd *pwd = NULL; |
61 |
int ch, clean, uflag, Uflag; |
| 73 |
gid_t *groups = NULL; |
62 |
char *cleanenv; |
| 74 |
int ch, ngroups, uflag, Uflag; |
63 |
const struct passwd *pwd = NULL; |
| 75 |
long ngroups_max; |
64 |
const char *username, *shell, *term; |
| 76 |
char *username; |
|
|
| 77 |
|
65 |
|
| 78 |
ch = uflag = Uflag = 0; |
66 |
ch = clean = uflag = Uflag = 0; |
| 79 |
username = NULL; |
67 |
username = NULL; |
| 80 |
ngroups_max = sysconf(_SC_NGROUPS_MAX) + 1; |
|
|
| 81 |
if ((groups = malloc(sizeof(gid_t) * ngroups_max)) == NULL) |
| 82 |
err(1, "malloc"); |
| 83 |
|
68 |
|
| 84 |
while ((ch = getopt(argc, argv, "nu:U:")) != -1) { |
69 |
while ((ch = getopt(argc, argv, "lnu:U:")) != -1) { |
| 85 |
switch (ch) { |
70 |
switch (ch) { |
|
|
71 |
case 'l': |
| 72 |
clean = 1; |
| 73 |
break; |
| 86 |
case 'n': |
74 |
case 'n': |
| 87 |
/* Specified name, now unused */ |
75 |
/* Specified name, now unused */ |
| 88 |
break; |
76 |
break; |
|
Lines 100-111
Link Here
|
| 100 |
} |
88 |
} |
| 101 |
argc -= optind; |
89 |
argc -= optind; |
| 102 |
argv += optind; |
90 |
argv += optind; |
| 103 |
if (argc < 2) |
91 |
if (argc < 1) |
| 104 |
usage(); |
92 |
usage(); |
| 105 |
if (uflag && Uflag) |
93 |
if (uflag && Uflag) |
| 106 |
usage(); |
94 |
usage(); |
| 107 |
if (uflag) |
95 |
if (uflag || (clean && !Uflag)) |
| 108 |
GET_USER_INFO; |
96 |
/* User info from the home environment */ |
|
|
97 |
get_user_info(username, &pwd, &lcap); |
| 98 |
|
| 99 |
/* Attach to the jail */ |
| 109 |
jid = jail_getid(argv[0]); |
100 |
jid = jail_getid(argv[0]); |
| 110 |
if (jid < 0) |
101 |
if (jid < 0) |
| 111 |
errx(1, "%s", jail_errmsg); |
102 |
errx(1, "%s", jail_errmsg); |
|
Lines 113-140
Link Here
|
| 113 |
err(1, "jail_attach(%d)", jid); |
104 |
err(1, "jail_attach(%d)", jid); |
| 114 |
if (chdir("/") == -1) |
105 |
if (chdir("/") == -1) |
| 115 |
err(1, "chdir(): /"); |
106 |
err(1, "chdir(): /"); |
| 116 |
if (username != NULL) { |
107 |
|
|
|
108 |
/* Set up user environment */ |
| 109 |
if (clean || username != NULL) { |
| 117 |
if (Uflag) |
110 |
if (Uflag) |
| 118 |
GET_USER_INFO; |
111 |
/* User info from the jail environment */ |
| 119 |
if (setgroups(ngroups, groups) != 0) |
112 |
get_user_info(username, &pwd, &lcap); |
| 120 |
err(1, "setgroups"); |
113 |
if (clean) { |
|
|
114 |
term = getenv("TERM"); |
| 115 |
cleanenv = NULL; |
| 116 |
environ = &cleanenv; |
| 117 |
setenv("PATH", "/bin:/usr/bin", 1); |
| 118 |
if (term != NULL) |
| 119 |
setenv("TERM", term, 1); |
| 120 |
} |
| 121 |
if (setgid(pwd->pw_gid) != 0) |
121 |
if (setgid(pwd->pw_gid) != 0) |
| 122 |
err(1, "setgid"); |
122 |
err(1, "setgid"); |
| 123 |
if (setusercontext(lcap, pwd, pwd->pw_uid, |
123 |
if (setusercontext(lcap, pwd, pwd->pw_uid, username |
| 124 |
LOGIN_SETALL & ~LOGIN_SETGROUP & ~LOGIN_SETLOGIN) != 0) |
124 |
? LOGIN_SETALL & ~LOGIN_SETGROUP & ~LOGIN_SETLOGIN |
|
|
125 |
: LOGIN_SETPATH | LOGIN_SETENV) != 0) |
| 125 |
err(1, "setusercontext"); |
126 |
err(1, "setusercontext"); |
| 126 |
login_close(lcap); |
127 |
login_close(lcap); |
|
|
128 |
setenv("USER", pwd->pw_name, 1); |
| 129 |
setenv("HOME", pwd->pw_dir, 1); |
| 130 |
setenv("SHELL", |
| 131 |
*pwd->pw_shell ? pwd->pw_shell : _PATH_BSHELL, 1); |
| 132 |
if (clean && chdir(pwd->pw_dir) < 0) |
| 133 |
err(1, "chdir: %s", pwd->pw_dir); |
| 134 |
endpwent(); |
| 127 |
} |
135 |
} |
| 128 |
if (execvp(argv[1], argv + 1) == -1) |
136 |
|
| 129 |
err(1, "execvp(): %s", argv[1]); |
137 |
/* Run the specified command, or the shell */ |
|
|
138 |
if (argc > 1) { |
| 139 |
if (execvp(argv[1], argv + 1) < 0) |
| 140 |
err(1, "execvp: %s", argv[1]); |
| 141 |
} else { |
| 142 |
if (!(shell = getenv("SHELL"))) |
| 143 |
shell = _PATH_BSHELL; |
| 144 |
if (execlp(shell, shell, "-i", NULL) < 0) |
| 145 |
err(1, "execlp: %s", shell); |
| 146 |
} |
| 130 |
exit(0); |
147 |
exit(0); |
| 131 |
} |
148 |
} |
| 132 |
|
149 |
|
| 133 |
static void |
150 |
static void |
|
|
151 |
get_user_info(const char *username, const struct passwd **pwdp, |
| 152 |
login_cap_t **lcapp) |
| 153 |
{ |
| 154 |
uid_t uid; |
| 155 |
const struct passwd *pwd; |
| 156 |
|
| 157 |
errno = 0; |
| 158 |
if (username) { |
| 159 |
pwd = getpwnam(username); |
| 160 |
if (pwd == NULL) { |
| 161 |
if (errno) |
| 162 |
err(1, "getpwnam: %s", username); |
| 163 |
else |
| 164 |
errx(1, "%s: no such user", username); |
| 165 |
} |
| 166 |
} else { |
| 167 |
uid = getuid(); |
| 168 |
pwd = getpwuid(uid); |
| 169 |
if (pwd == NULL) { |
| 170 |
if (errno) |
| 171 |
err(1, "getpwuid: %d", uid); |
| 172 |
else |
| 173 |
errx(1, "unknown uid: %d", uid); |
| 174 |
} |
| 175 |
} |
| 176 |
*pwdp = pwd; |
| 177 |
*lcapp = login_getpwclass(pwd); |
| 178 |
if (*lcapp == NULL) |
| 179 |
err(1, "getpwclass: %s", pwd->pw_name); |
| 180 |
if (initgroups(pwd->pw_name, pwd->pw_gid) < 0) |
| 181 |
err(1, "initgroups: %s", pwd->pw_name); |
| 182 |
} |
| 183 |
|
| 184 |
static void |
| 134 |
usage(void) |
185 |
usage(void) |
| 135 |
{ |
186 |
{ |
| 136 |
|
187 |
|
| 137 |
fprintf(stderr, "%s\n", |
188 |
fprintf(stderr, "%s\n", |
| 138 |
"usage: jexec [-u username | -U username] jail command ..."); |
189 |
"usage: jexec [-l] [-u username | -U username] jail [command ...]"); |
| 139 |
exit(1); |
190 |
exit(1); |
| 140 |
} |
191 |
} |