1 /* |
1 /* |
2 * ProFTPD - FTP server daemon |
2 * ProFTPD - FTP server daemon |
3 * Copyright (c) 1997, 1998 Public Flood Software |
3 * Copyright (c) 1997, 1998 Public Flood Software |
4 * Copyright (c) 2003-2010 The ProFTPD Project team |
4 * Copyright (c) 2003-2010 The ProFTPD Project team |
5 * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. |
5 * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. |
6 * |
6 * |
7 * This program is free software; you can redistribute it and/or modify |
7 * This program is free software; you can redistribute it and/or modify |
8 * it under the terms of the GNU General Public License as published by |
8 * it under the terms of the GNU General Public License as published by |
9 * the Free Software Foundation; either version 2 of the License, or |
9 * the Free Software Foundation; either version 2 of the License, or |
10 * (at your option) any later version. |
10 * (at your option) any later version. |
142 /* The POST_CMD handler for "PASS" is only called after PASS has |
142 /* The POST_CMD handler for "PASS" is only called after PASS has |
143 * successfully completed, which means authentication is successful, |
143 * successfully completed, which means authentication is successful, |
144 * so we can "tweak" our root access down to almost nothing. |
144 * so we can "tweak" our root access down to almost nothing. |
145 */ |
145 */ |
146 MODRET solaris_priv_post_pass(cmd_rec *cmd) { |
146 MODRET solaris_priv_post_pass(cmd_rec *cmd) { |
147 int res = 0; |
147 int res = -1; |
148 priv_set_t *p, *i; |
148 priv_set_t *p = NULL; |
|
149 priv_set_t *i = NULL; |
149 |
150 |
150 if (!use_privs) |
151 if (!use_privs) |
151 return PR_DECLINED(cmd); |
152 return PR_DECLINED(cmd); |
152 |
153 |
153 pr_signals_block(); |
154 pr_signals_block(); |
160 * We also remove the basic Solaris privileges we know we will |
161 * We also remove the basic Solaris privileges we know we will |
161 * never need. |
162 * never need. |
162 */ |
163 */ |
163 |
164 |
164 i = priv_allocset(); |
165 i = priv_allocset(); |
|
166 if (i == NULL) |
|
167 goto out; |
165 priv_basicset(i); |
168 priv_basicset(i); |
166 priv_delset(i, PRIV_PROC_EXEC); |
169 priv_delset(i, PRIV_PROC_EXEC); |
167 priv_delset(i, PRIV_PROC_FORK); |
170 priv_delset(i, PRIV_PROC_FORK); |
168 priv_delset(i, PRIV_PROC_INFO); |
171 priv_delset(i, PRIV_PROC_INFO); |
169 priv_delset(i, PRIV_PROC_SESSION); |
172 priv_delset(i, PRIV_PROC_SESSION); |
170 setppriv(PRIV_SET, PRIV_INHERITABLE, i); |
173 setppriv(PRIV_SET, PRIV_INHERITABLE, i); |
171 |
174 |
172 p = priv_allocset(); |
175 p = priv_allocset(); |
|
176 if (p == NULL) |
|
177 goto out; |
173 priv_basicset(p); |
178 priv_basicset(p); |
174 |
179 |
175 priv_addset(p, PRIV_NET_PRIVADDR); |
180 priv_addset(p, PRIV_NET_PRIVADDR); |
176 priv_addset(p, PRIV_PROC_AUDIT); |
181 priv_addset(p, PRIV_PROC_AUDIT); |
177 |
182 |
209 res = setppriv(PRIV_SET, PRIV_EFFECTIVE, p); |
214 res = setppriv(PRIV_SET, PRIV_EFFECTIVE, p); |
210 |
215 |
211 if (setreuid(session.uid, session.uid) == -1) { |
216 if (setreuid(session.uid, session.uid) == -1) { |
212 pr_log_pri(PR_LOG_ERR, MOD_SOLARIS_PRIV_VERSION ": setreuid: %s", |
217 pr_log_pri(PR_LOG_ERR, MOD_SOLARIS_PRIV_VERSION ": setreuid: %s", |
213 strerror(errno)); |
218 strerror(errno)); |
|
219 priv_freeset(i); |
|
220 priv_freeset(p); |
214 pr_signals_unblock(); |
221 pr_signals_unblock(); |
215 end_login(1); |
222 end_login(1); |
216 } |
223 } |
|
224 |
|
225 out: |
|
226 if (i != NULL) |
|
227 priv_freeset(i); |
|
228 if (p != NULL) |
|
229 priv_freeset(p); |
|
230 |
217 pr_signals_unblock(); |
231 pr_signals_unblock(); |
218 |
232 |
219 if (res != -1) { |
233 if (res != -1) { |
220 /* That's it! Disable all further id switching */ |
234 /* That's it! Disable all further id switching */ |
221 session.disable_id_switching = TRUE; |
235 session.disable_id_switching = TRUE; |
222 |
236 |
223 } else { |
237 } else { |
224 pr_log_pri(PR_LOG_NOTICE, MOD_SOLARIS_PRIV_VERSION ": attempt to configure " |
238 pr_log_pri(PR_LOG_NOTICE, MOD_SOLARIS_PRIV_VERSION ": attempt to configure " |
225 "privileges failed, reverting to normal operation"); |
239 "privileges failed, reverting to normal operation"); |
226 } |
240 } |
|
241 |
|
242 return PR_DECLINED(cmd); |
|
243 } |
|
244 |
|
245 static void log_err_permitted(const char* fn) { |
|
246 pr_log_pri(PR_LOG_ERR, MOD_SOLARIS_PRIV_VERSION ": %s(%s): %s", |
|
247 fn, "permitted", strerror(errno)); |
|
248 } |
|
249 |
|
250 static void log_err_effective(const char* fn) { |
|
251 pr_log_pri(PR_LOG_ERR, MOD_SOLARIS_PRIV_VERSION ": %s(%s): %s", |
|
252 fn, "effective", strerror(errno)); |
|
253 } |
|
254 |
|
255 MODRET solaris_priv_post_fail(cmd_rec *cmd) { |
|
256 priv_set_t* permitted_set = NULL; |
|
257 priv_set_t* effective_set = NULL; |
|
258 |
|
259 if ((permitted_set = priv_allocset()) == NULL) { |
|
260 log_err_permitted("priv_allocset"); |
|
261 goto out; |
|
262 } |
|
263 if ((effective_set = priv_allocset()) == NULL) { |
|
264 log_err_effective("priv_allocset"); |
|
265 goto out; |
|
266 } |
|
267 |
|
268 if (getppriv(PRIV_PERMITTED, permitted_set) != 0) { |
|
269 log_err_permitted("getppriv"); |
|
270 goto out; |
|
271 } |
|
272 if (getppriv(PRIV_EFFECTIVE, effective_set) != 0) { |
|
273 log_err_effective("getppriv"); |
|
274 goto out; |
|
275 } |
|
276 |
|
277 if (priv_addset(permitted_set, PRIV_PROC_AUDIT) != 0) { |
|
278 log_err_permitted("priv_addset"); |
|
279 goto out; |
|
280 } |
|
281 if (priv_addset(effective_set, PRIV_PROC_AUDIT) != 0) { |
|
282 log_err_effective("priv_addset"); |
|
283 goto out; |
|
284 } |
|
285 |
|
286 if (setppriv(PRIV_SET, PRIV_PERMITTED, permitted_set) != 0) { |
|
287 log_err_permitted("setppriv"); |
|
288 goto out; |
|
289 } |
|
290 if (setppriv(PRIV_SET, PRIV_EFFECTIVE, effective_set) != 0) { |
|
291 log_err_effective("setppriv"); |
|
292 goto out; |
|
293 } |
|
294 |
|
295 out: |
|
296 if (permitted_set != NULL) |
|
297 priv_freeset(permitted_set); |
|
298 if (effective_set != NULL) |
|
299 priv_freeset(effective_set); |
227 |
300 |
228 return PR_DECLINED(cmd); |
301 return PR_DECLINED(cmd); |
229 } |
302 } |
230 |
303 |
231 /* Initialization routines |
304 /* Initialization routines |
348 { NULL, NULL, NULL } |
421 { NULL, NULL, NULL } |
349 }; |
422 }; |
350 |
423 |
351 static cmdtable solaris_priv_cmdtab[] = { |
424 static cmdtable solaris_priv_cmdtab[] = { |
352 { POST_CMD, C_PASS, G_NONE, solaris_priv_post_pass, FALSE, FALSE }, |
425 { POST_CMD, C_PASS, G_NONE, solaris_priv_post_pass, FALSE, FALSE }, |
|
426 { POST_CMD_ERR, C_PASS, G_NONE, solaris_priv_post_fail, FALSE, FALSE }, |
353 { 0, NULL } |
427 { 0, NULL } |
354 }; |
428 }; |
355 |
429 |
356 module solaris_priv_module = { |
430 module solaris_priv_module = { |
357 NULL, NULL, |
431 NULL, NULL, |