diff options
Diffstat (limited to 'openbsd-compat/port-solaris.c')
-rw-r--r-- | openbsd-compat/port-solaris.c | 114 |
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 | |||
236 | void | ||
237 | solaris_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 | |||
292 | void | ||
293 | solaris_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 | |||
317 | void | ||
318 | solaris_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 | ||