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