summaryrefslogtreecommitdiff
path: root/openbsd-compat/port-solaris.c
diff options
context:
space:
mode:
Diffstat (limited to 'openbsd-compat/port-solaris.c')
-rw-r--r--openbsd-compat/port-solaris.c136
1 files changed, 136 insertions, 0 deletions
diff --git a/openbsd-compat/port-solaris.c b/openbsd-compat/port-solaris.c
index 25382f1c9..e36e412d7 100644
--- a/openbsd-compat/port-solaris.c
+++ b/openbsd-compat/port-solaris.c
@@ -227,3 +227,139 @@ 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
236priv_set_t *
237solaris_basic_privset(void)
238{
239 priv_set_t *pset;
240
241#ifdef HAVE_PRIV_BASICSET
242 if ((pset = priv_allocset()) == NULL) {
243 error("priv_allocset: %s", strerror(errno));
244 return NULL;
245 }
246 priv_basicset(pset);
247#else
248 if ((pset = priv_str_to_set("basic", ",", NULL)) == NULL) {
249 error("priv_str_to_set: %s", strerror(errno));
250 return NULL;
251 }
252#endif
253 return pset;
254}
255
256void
257solaris_drop_privs_pinfo_net_fork_exec(void)
258{
259 priv_set_t *pset = NULL, *npset = NULL;
260
261 /*
262 * Note: this variant avoids dropping DAC filesystem rights, in case
263 * the process calling it is running as root and should have the
264 * ability to read/write/chown any file on the system.
265 *
266 * We start with the basic set, then *add* the DAC rights to it while
267 * taking away other parts of BASIC we don't need. Then we intersect
268 * this with our existing PERMITTED set. In this way we keep any
269 * DAC rights we had before, while otherwise reducing ourselves to
270 * the minimum set of privileges we need to proceed.
271 *
272 * This also means we drop any other parts of "root" that we don't
273 * need (e.g. the ability to kill any process, create new device nodes
274 * etc etc).
275 */
276
277 if ((pset = priv_allocset()) == NULL)
278 fatal("priv_allocset: %s", strerror(errno));
279 if ((npset = solaris_basic_privset()) == NULL)
280 fatal("solaris_basic_privset: %s", strerror(errno));
281
282 if (priv_addset(npset, PRIV_FILE_CHOWN) != 0 ||
283 priv_addset(npset, PRIV_FILE_DAC_READ) != 0 ||
284 priv_addset(npset, PRIV_FILE_DAC_SEARCH) != 0 ||
285 priv_addset(npset, PRIV_FILE_DAC_WRITE) != 0 ||
286 priv_addset(npset, PRIV_FILE_OWNER) != 0)
287 fatal("priv_addset: %s", strerror(errno));
288
289 if (priv_delset(npset, PRIV_FILE_LINK_ANY) != 0 ||
290#ifdef PRIV_NET_ACCESS
291 priv_delset(npset, PRIV_NET_ACCESS) != 0 ||
292#endif
293 priv_delset(npset, PRIV_PROC_EXEC) != 0 ||
294 priv_delset(npset, PRIV_PROC_FORK) != 0 ||
295 priv_delset(npset, PRIV_PROC_INFO) != 0 ||
296 priv_delset(npset, PRIV_PROC_SESSION) != 0)
297 fatal("priv_delset: %s", strerror(errno));
298
299 if (getppriv(PRIV_PERMITTED, pset) != 0)
300 fatal("getppriv: %s", strerror(errno));
301
302 priv_intersect(pset, npset);
303
304 if (setppriv(PRIV_SET, PRIV_PERMITTED, npset) != 0 ||
305 setppriv(PRIV_SET, PRIV_LIMIT, npset) != 0 ||
306 setppriv(PRIV_SET, PRIV_INHERITABLE, npset) != 0)
307 fatal("setppriv: %s", strerror(errno));
308
309 priv_freeset(pset);
310 priv_freeset(npset);
311}
312
313void
314solaris_drop_privs_root_pinfo_net(void)
315{
316 priv_set_t *pset = NULL;
317
318 /* Start with "basic" and drop everything we don't need. */
319 if ((pset = solaris_basic_privset()) == NULL)
320 fatal("solaris_basic_privset: %s", strerror(errno));
321
322 if (priv_delset(pset, PRIV_FILE_LINK_ANY) != 0 ||
323#ifdef PRIV_NET_ACCESS
324 priv_delset(pset, PRIV_NET_ACCESS) != 0 ||
325#endif
326 priv_delset(pset, PRIV_PROC_INFO) != 0 ||
327 priv_delset(pset, PRIV_PROC_SESSION) != 0)
328 fatal("priv_delset: %s", strerror(errno));
329
330 if (setppriv(PRIV_SET, PRIV_PERMITTED, pset) != 0 ||
331 setppriv(PRIV_SET, PRIV_LIMIT, pset) != 0 ||
332 setppriv(PRIV_SET, PRIV_INHERITABLE, pset) != 0)
333 fatal("setppriv: %s", strerror(errno));
334
335 priv_freeset(pset);
336}
337
338void
339solaris_drop_privs_root_pinfo_net_exec(void)
340{
341 priv_set_t *pset = NULL;
342
343
344 /* Start with "basic" and drop everything we don't need. */
345 if ((pset = solaris_basic_privset()) == NULL)
346 fatal("solaris_basic_privset: %s", strerror(errno));
347
348 if (priv_delset(pset, PRIV_FILE_LINK_ANY) != 0 ||
349#ifdef PRIV_NET_ACCESS
350 priv_delset(pset, PRIV_NET_ACCESS) != 0 ||
351#endif
352 priv_delset(pset, PRIV_PROC_EXEC) != 0 ||
353 priv_delset(pset, PRIV_PROC_INFO) != 0 ||
354 priv_delset(pset, PRIV_PROC_SESSION) != 0)
355 fatal("priv_delset: %s", strerror(errno));
356
357 if (setppriv(PRIV_SET, PRIV_PERMITTED, pset) != 0 ||
358 setppriv(PRIV_SET, PRIV_LIMIT, pset) != 0 ||
359 setppriv(PRIV_SET, PRIV_INHERITABLE, pset) != 0)
360 fatal("setppriv: %s", strerror(errno));
361
362 priv_freeset(pset);
363}
364
365#endif