Lines 37-42
Link Here
|
37 |
#include <login_cap.h> |
37 |
#include <login_cap.h> |
38 |
#include <paths.h> |
38 |
#include <paths.h> |
39 |
#include <pwd.h> |
39 |
#include <pwd.h> |
|
|
40 |
#include <stdint.h> |
40 |
#include <stdio.h> |
41 |
#include <stdio.h> |
41 |
#include <stdlib.h> |
42 |
#include <stdlib.h> |
42 |
#include <string.h> |
43 |
#include <string.h> |
Lines 379-414
setclasscontext(const char *classname, unsigned int flags)
Link Here
|
379 |
} |
380 |
} |
380 |
|
381 |
|
381 |
|
382 |
|
|
|
383 |
static const char * const inherit_enum[] = { |
384 |
"inherit", |
385 |
NULL |
386 |
}; |
387 |
|
388 |
/* |
389 |
* Private function setting umask from the login class. |
390 |
*/ |
391 |
static void |
392 |
setclassumask(login_cap_t *lc, const struct passwd *pwd) |
393 |
{ |
394 |
/* |
395 |
* Make it unlikely that someone would input our default sentinel |
396 |
* indicating no specification. |
397 |
*/ |
398 |
const rlim_t def_val = INT64_MIN + 1, err_val = INT64_MIN; |
399 |
rlim_t val; |
400 |
|
401 |
if (login_getcapenum(lc, "umask", inherit_enum) == 0) |
402 |
/* Found "inherit". */ |
403 |
return; |
404 |
|
405 |
val = login_getcapnum(lc, "umask", def_val, err_val); |
406 |
|
407 |
if (val != def_val) { |
408 |
if (val < 0 || val > UINT16_MAX) { |
409 |
/* We get here also on 'err_val'. */ |
410 |
syslog(LOG_WARNING, |
411 |
"%s%s%sLogin class '%s': " |
412 |
"Invalid umask specification: '%s'", |
413 |
pwd ? "Login '" : "", |
414 |
pwd ? pwd->pw_name : "", |
415 |
pwd ? "': " : "", |
416 |
lc->lc_class, |
417 |
login_getcapstr(lc, "umask", "", "")); |
418 |
} else { |
419 |
const mode_t mode = val; |
420 |
|
421 |
umask(mode); |
422 |
} |
423 |
} |
424 |
} |
382 |
|
425 |
|
383 |
/* |
426 |
/* |
384 |
* Private function which takes care of processing |
427 |
* Private function which takes care of processing |
385 |
*/ |
428 |
*/ |
386 |
|
429 |
|
387 |
static mode_t |
430 |
static void |
388 |
setlogincontext(login_cap_t *lc, const struct passwd *pwd, |
431 |
setlogincontext(login_cap_t *lc, const struct passwd *pwd, unsigned long flags) |
389 |
mode_t mymask, unsigned long flags) |
|
|
390 |
{ |
432 |
{ |
391 |
if (lc) { |
433 |
if (lc == NULL) |
392 |
/* Set resources */ |
434 |
return; |
393 |
if (flags & LOGIN_SETRESOURCES) |
435 |
|
394 |
setclassresources(lc); |
436 |
/* Set resources. */ |
395 |
/* See if there's a umask override */ |
437 |
if ((flags & LOGIN_SETRESOURCES) != 0) |
396 |
if (flags & LOGIN_SETUMASK) |
438 |
setclassresources(lc); |
397 |
mymask = (mode_t)login_getcapnum(lc, "umask", mymask, mymask); |
439 |
|
398 |
/* Set paths */ |
440 |
/* See if there's a umask override. */ |
399 |
if (flags & LOGIN_SETPATH) |
441 |
if ((flags & LOGIN_SETUMASK) != 0) |
400 |
setclassenvironment(lc, pwd, 1); |
442 |
setclassumask(lc, pwd); |
401 |
/* Set environment */ |
443 |
|
402 |
if (flags & LOGIN_SETENV) |
444 |
/* Set paths. */ |
403 |
setclassenvironment(lc, pwd, 0); |
445 |
if ((flags & LOGIN_SETPATH) != 0) |
404 |
/* Set cpu affinity */ |
446 |
setclassenvironment(lc, pwd, 1); |
405 |
if (flags & LOGIN_SETCPUMASK) |
447 |
|
406 |
setclasscpumask(lc); |
448 |
/* Set environment. */ |
407 |
} |
449 |
if ((flags & LOGIN_SETENV) != 0) |
408 |
return (mymask); |
450 |
setclassenvironment(lc, pwd, 0); |
|
|
451 |
|
452 |
/* Set cpu affinity. */ |
453 |
if ((flags & LOGIN_SETCPUMASK) != 0) |
454 |
setclasscpumask(lc); |
409 |
} |
455 |
} |
410 |
|
456 |
|
411 |
|
457 |
|
|
|
458 |
/* |
459 |
* Private function to set process priority. |
460 |
*/ |
461 |
static void |
462 |
setclasspriority(login_cap_t * const lc, struct passwd const * const pwd) |
463 |
{ |
464 |
const rlim_t def_val = 0, err_val = INT64_MIN; |
465 |
rlim_t p; |
466 |
int rc; |
467 |
|
468 |
if (login_getcapenum(lc, "priority", inherit_enum) == 0) |
469 |
/* Found "inherit". */ |
470 |
return; |
471 |
|
472 |
p = login_getcapnum(lc, "priority", def_val, err_val); |
473 |
|
474 |
if (p == err_val) { |
475 |
/* Invariant: 'lc' != NULL. */ |
476 |
syslog(LOG_WARNING, |
477 |
"%s%s%sLogin class '%s': " |
478 |
"Invalid priority specification: '%s'", |
479 |
pwd ? "Login '" : "", |
480 |
pwd ? pwd->pw_name : "", |
481 |
pwd ? "': " : "", |
482 |
lc->lc_class, |
483 |
login_getcapstr(lc, "priority", "", "")); |
484 |
/* Reset the priority, as if the capability was not present. */ |
485 |
p = def_val; |
486 |
} |
487 |
|
488 |
if (p > PRIO_MAX) { |
489 |
struct rtprio rtp; |
490 |
|
491 |
rtp.type = RTP_PRIO_IDLE; |
492 |
p += RTP_PRIO_MIN - (PRIO_MAX + 1); |
493 |
rtp.prio = p > RTP_PRIO_MAX ? RTP_PRIO_MAX : p; |
494 |
rc = rtprio(RTP_SET, 0, &rtp); |
495 |
} else if (p < PRIO_MIN) { |
496 |
struct rtprio rtp; |
497 |
|
498 |
rtp.type = RTP_PRIO_REALTIME; |
499 |
p += RTP_PRIO_MAX - (PRIO_MIN - 1); |
500 |
rtp.prio = p < RTP_PRIO_MIN ? RTP_PRIO_MIN : p; |
501 |
rc = rtprio(RTP_SET, 0, &rtp); |
502 |
} else |
503 |
rc = setpriority(PRIO_PROCESS, 0, (int)p); |
504 |
|
505 |
if (rc != 0) |
506 |
syslog(LOG_WARNING, |
507 |
"%s%s%sLogin class '%s': " |
508 |
"Setting priority failed: %m", |
509 |
pwd ? "Login '" : "", |
510 |
pwd ? pwd->pw_name : "", |
511 |
pwd ? "': " : "", |
512 |
lc ? lc->lc_class : "<none>"); |
513 |
} |
412 |
|
514 |
|
413 |
/* |
515 |
/* |
414 |
* setusercontext() |
516 |
* setusercontext() |
Lines 427-436
setlogincontext(login_cap_t *lc, const struct passwd *pwd,
Link Here
|
427 |
int |
529 |
int |
428 |
setusercontext(login_cap_t *lc, const struct passwd *pwd, uid_t uid, unsigned int flags) |
530 |
setusercontext(login_cap_t *lc, const struct passwd *pwd, uid_t uid, unsigned int flags) |
429 |
{ |
531 |
{ |
430 |
rlim_t p; |
|
|
431 |
mode_t mymask; |
432 |
login_cap_t *llc = NULL; |
532 |
login_cap_t *llc = NULL; |
433 |
struct rtprio rtp; |
|
|
434 |
int error; |
533 |
int error; |
435 |
|
534 |
|
436 |
if (lc == NULL) { |
535 |
if (lc == NULL) { |
Lines 446-477
setusercontext(login_cap_t *lc, const struct passwd *pwd, uid_t uid, unsigned in
Link Here
|
446 |
flags &= ~(LOGIN_SETGROUP | LOGIN_SETLOGIN | LOGIN_SETMAC); |
545 |
flags &= ~(LOGIN_SETGROUP | LOGIN_SETLOGIN | LOGIN_SETMAC); |
447 |
|
546 |
|
448 |
/* Set the process priority */ |
547 |
/* Set the process priority */ |
449 |
if (flags & LOGIN_SETPRIORITY) { |
548 |
if (flags & LOGIN_SETPRIORITY) |
450 |
p = login_getcapnum(lc, "priority", LOGIN_DEFPRI, LOGIN_DEFPRI); |
549 |
setclasspriority(lc, pwd); |
451 |
|
|
|
452 |
if (p > PRIO_MAX) { |
453 |
rtp.type = RTP_PRIO_IDLE; |
454 |
p += RTP_PRIO_MIN - (PRIO_MAX + 1); |
455 |
rtp.prio = p > RTP_PRIO_MAX ? RTP_PRIO_MAX : p; |
456 |
if (rtprio(RTP_SET, 0, &rtp)) |
457 |
syslog(LOG_WARNING, "rtprio '%s' (%s): %m", |
458 |
pwd ? pwd->pw_name : "-", |
459 |
lc ? lc->lc_class : LOGIN_DEFCLASS); |
460 |
} else if (p < PRIO_MIN) { |
461 |
rtp.type = RTP_PRIO_REALTIME; |
462 |
p += RTP_PRIO_MAX - (PRIO_MIN - 1); |
463 |
rtp.prio = p < RTP_PRIO_MIN ? RTP_PRIO_MIN : p; |
464 |
if (rtprio(RTP_SET, 0, &rtp)) |
465 |
syslog(LOG_WARNING, "rtprio '%s' (%s): %m", |
466 |
pwd ? pwd->pw_name : "-", |
467 |
lc ? lc->lc_class : LOGIN_DEFCLASS); |
468 |
} else { |
469 |
if (setpriority(PRIO_PROCESS, 0, (int)p) != 0) |
470 |
syslog(LOG_WARNING, "setpriority '%s' (%s): %m", |
471 |
pwd ? pwd->pw_name : "-", |
472 |
lc ? lc->lc_class : LOGIN_DEFCLASS); |
473 |
} |
474 |
} |
475 |
|
550 |
|
476 |
/* Setup the user's group permissions */ |
551 |
/* Setup the user's group permissions */ |
477 |
if (flags & LOGIN_SETGROUP) { |
552 |
if (flags & LOGIN_SETGROUP) { |
Lines 532-539
setusercontext(login_cap_t *lc, const struct passwd *pwd, uid_t uid, unsigned in
Link Here
|
532 |
} |
607 |
} |
533 |
} |
608 |
} |
534 |
|
609 |
|
535 |
mymask = (flags & LOGIN_SETUMASK) ? umask(LOGIN_DEFUMASK) : 0; |
610 |
setlogincontext(lc, pwd, flags); |
536 |
mymask = setlogincontext(lc, pwd, mymask, flags); |
|
|
537 |
login_close(llc); |
611 |
login_close(llc); |
538 |
|
612 |
|
539 |
/* This needs to be done after anything that needs root privs */ |
613 |
/* This needs to be done after anything that needs root privs */ |
Lines 546-558
setusercontext(login_cap_t *lc, const struct passwd *pwd, uid_t uid, unsigned in
Link Here
|
546 |
* Now, we repeat some of the above for the user's private entries |
620 |
* Now, we repeat some of the above for the user's private entries |
547 |
*/ |
621 |
*/ |
548 |
if (geteuid() == uid && (lc = login_getuserclass(pwd)) != NULL) { |
622 |
if (geteuid() == uid && (lc = login_getuserclass(pwd)) != NULL) { |
549 |
mymask = setlogincontext(lc, pwd, mymask, flags); |
623 |
setlogincontext(lc, pwd, flags); |
|
|
624 |
if (flags & LOGIN_SETPRIORITY) |
625 |
setclasspriority(lc, pwd); |
550 |
login_close(lc); |
626 |
login_close(lc); |
551 |
} |
627 |
} |
552 |
|
628 |
|
553 |
/* Finally, set any umask we've found */ |
|
|
554 |
if (flags & LOGIN_SETUMASK) |
555 |
umask(mymask); |
556 |
|
557 |
return (0); |
629 |
return (0); |
558 |
} |
630 |
} |