summaryrefslogtreecommitdiff
path: root/openbsd-compat/port-solaris.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2016-01-08 14:24:56 +1100
committerDamien Miller <djm@mindrot.org>2016-01-08 14:29:12 +1100
commit4626cbaf78767fc8e9c86dd04785386c59ae0839 (patch)
tree449a777d8781a7f88724cbec9a4717f5b3fe4ec6 /openbsd-compat/port-solaris.c
parent422d1b3ee977ff4c724b597fb2e437d38fc8de9d (diff)
Support Illumos/Solaris fine-grained privileges
Includes a pre-auth privsep sandbox and several pledge() emulations. bz#2511, patch by Alex Wilson. ok dtucker@
Diffstat (limited to 'openbsd-compat/port-solaris.c')
-rw-r--r--openbsd-compat/port-solaris.c114
1 files changed, 114 insertions, 0 deletions
diff --git a/openbsd-compat/port-solaris.c b/openbsd-compat/port-solaris.c
index 25382f1c9..962cd1685 100644
--- a/openbsd-compat/port-solaris.c
+++ b/openbsd-compat/port-solaris.c
@@ -227,3 +227,117 @@ solaris_set_default_project(struct passwd *pw)
227 } 227 }
228} 228}
229#endif /* USE_SOLARIS_PROJECTS */ 229#endif /* USE_SOLARIS_PROJECTS */
230
231#ifdef USE_SOLARIS_PRIVS
232# ifdef HAVE_PRIV_H
233# include <priv.h>
234# endif
235
236void
237solaris_drop_privs_pinfo_net_fork_exec(void)
238{
239 priv_set_t *pset = NULL, *npset = NULL;
240
241 /*
242 * Note: this variant avoids dropping DAC filesystem rights, in case
243 * the process calling it is running as root and should have the
244 * ability to read/write/chown any file on the system.
245 *
246 * We start with the basic set, then *add* the DAC rights to it while
247 * taking away other parts of BASIC we don't need. Then we intersect
248 * this with our existing PERMITTED set. In this way we keep any
249 * DAC rights we had before, while otherwise reducing ourselves to
250 * the minimum set of privileges we need to proceed.
251 *
252 * This also means we drop any other parts of "root" that we don't
253 * need (e.g. the ability to kill any process, create new device nodes
254 * etc etc).
255 */
256
257 if ((pset = priv_allocset()) == NULL ||
258 (npset = priv_allocset()) == NULL)
259 fatal("priv_allocset: %s", strerror(errno));
260
261 priv_basicset(npset);
262
263 if (priv_addset(npset, PRIV_FILE_CHOWN) != 0 ||
264 priv_addset(npset, PRIV_FILE_DAC_READ) != 0 ||
265 priv_addset(npset, PRIV_FILE_DAC_SEARCH) != 0 ||
266 priv_addset(npset, PRIV_FILE_DAC_WRITE) != 0 ||
267 priv_addset(npset, PRIV_FILE_OWNER) != 0)
268 fatal("priv_addset: %s", strerror(errno));
269
270 if (priv_delset(npset, PRIV_FILE_LINK_ANY) != 0 ||
271 priv_delset(npset, PRIV_NET_ACCESS) != 0 ||
272 priv_delset(npset, PRIV_PROC_EXEC) != 0 ||
273 priv_delset(npset, PRIV_PROC_FORK) != 0 ||
274 priv_delset(npset, PRIV_PROC_INFO) != 0 ||
275 priv_delset(npset, PRIV_PROC_SESSION) != 0)
276 fatal("priv_delset: %s", strerror(errno));
277
278 if (getppriv(PRIV_PERMITTED, pset) != 0)
279 fatal("getppriv: %s", strerror(errno));
280
281 priv_intersect(pset, npset);
282
283 if (setppriv(PRIV_SET, PRIV_PERMITTED, npset) != 0 ||
284 setppriv(PRIV_SET, PRIV_LIMIT, npset) != 0 ||
285 setppriv(PRIV_SET, PRIV_INHERITABLE, npset) != 0)
286 fatal("setppriv: %s", strerror(errno));
287
288 priv_freeset(pset);
289 priv_freeset(npset);
290}
291
292void
293solaris_drop_privs_root_pinfo_net(void)
294{
295 priv_set_t *pset = NULL;
296
297 if ((pset = priv_allocset()) == NULL)
298 fatal("priv_allocset: %s", strerror(errno));
299
300 /* Start with "basic" and drop everything we don't need. */
301 priv_basicset(pset);
302
303 if (priv_delset(pset, PRIV_FILE_LINK_ANY) != 0 ||
304 priv_delset(pset, PRIV_NET_ACCESS) != 0 ||
305 priv_delset(pset, PRIV_PROC_INFO) != 0 ||
306 priv_delset(pset, PRIV_PROC_SESSION) != 0)
307 fatal("priv_delset: %s", strerror(errno));
308
309 if (setppriv(PRIV_SET, PRIV_PERMITTED, pset) != 0 ||
310 setppriv(PRIV_SET, PRIV_LIMIT, pset) != 0 ||
311 setppriv(PRIV_SET, PRIV_INHERITABLE, pset) != 0)
312 fatal("setppriv: %s", strerror(errno));
313
314 priv_freeset(pset);
315}
316
317void
318solaris_drop_privs_root_pinfo_net_exec(void)
319{
320 priv_set_t *pset = NULL;
321
322 if ((pset = priv_allocset()) == NULL)
323 fatal("priv_allocset: %s", strerror(errno));
324
325 /* Start with "basic" and drop everything we don't need. */
326 priv_basicset(pset);
327
328 if (priv_delset(pset, PRIV_FILE_LINK_ANY) != 0 ||
329 priv_delset(pset, PRIV_NET_ACCESS) != 0 ||
330 priv_delset(pset, PRIV_PROC_EXEC) != 0 ||
331 priv_delset(pset, PRIV_PROC_INFO) != 0 ||
332 priv_delset(pset, PRIV_PROC_SESSION) != 0)
333 fatal("priv_delset: %s", strerror(errno));
334
335 if (setppriv(PRIV_SET, PRIV_PERMITTED, pset) != 0 ||
336 setppriv(PRIV_SET, PRIV_LIMIT, pset) != 0 ||
337 setppriv(PRIV_SET, PRIV_INHERITABLE, pset) != 0)
338 fatal("setppriv: %s", strerror(errno));
339
340 priv_freeset(pset);
341}
342
343#endif