diff options
Diffstat (limited to 'openbsd-compat/port-solaris.c')
-rw-r--r-- | openbsd-compat/port-solaris.c | 136 |
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 | |||
236 | priv_set_t * | ||
237 | solaris_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 | |||
256 | void | ||
257 | solaris_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 | |||
313 | void | ||
314 | solaris_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 | |||
338 | void | ||
339 | solaris_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 | ||