diff --git a/lib/libutil/login_cap.h b/lib/libutil/login_cap.h --- a/lib/libutil/login_cap.h +++ b/lib/libutil/login_cap.h @@ -33,7 +33,6 @@ #define LOGIN_MECLASS "me" #define LOGIN_DEFSTYLE "passwd" #define LOGIN_DEFSERVICE "login" -#define LOGIN_DEFPRI 0 #define _PATH_LOGIN_CONF "/etc/login.conf" #define _FILE_LOGIN_CONF ".login_conf" #define _PATH_AUTHPROG "/usr/libexec/login_" diff --git a/lib/libutil/login_class.c b/lib/libutil/login_class.c --- a/lib/libutil/login_class.c +++ b/lib/libutil/login_class.c @@ -456,9 +456,7 @@ int setusercontext(login_cap_t *lc, const struct passwd *pwd, uid_t uid, unsigned int flags) { - rlim_t p; login_cap_t *llc = NULL; - struct rtprio rtp; int error; if (lc == NULL) { @@ -475,29 +473,50 @@ /* Set the process priority */ if (flags & LOGIN_SETPRIORITY) { - p = login_getcapnum(lc, "priority", LOGIN_DEFPRI, LOGIN_DEFPRI); + /* + * Make it unlikely that someone would input our default sentinel + * (which indicates no specification). + */ + rlim_t const def_val = INT64_MIN + 1, err_val = INT64_MIN; + rlim_t p = login_getcapnum(lc, "priority", def_val, err_val); + int rc; - if (p > PRIO_MAX) { - rtp.type = RTP_PRIO_IDLE; - p += RTP_PRIO_MIN - (PRIO_MAX + 1); - rtp.prio = p > RTP_PRIO_MAX ? RTP_PRIO_MAX : p; - if (rtprio(RTP_SET, 0, &rtp)) - syslog(LOG_WARNING, "rtprio '%s' (%s): %m", - pwd ? pwd->pw_name : "-", - lc ? lc->lc_class : LOGIN_DEFCLASS); - } else if (p < PRIO_MIN) { - rtp.type = RTP_PRIO_REALTIME; - p += RTP_PRIO_MAX - (PRIO_MIN - 1); - rtp.prio = p < RTP_PRIO_MIN ? RTP_PRIO_MIN : p; - if (rtprio(RTP_SET, 0, &rtp)) - syslog(LOG_WARNING, "rtprio '%s' (%s): %m", - pwd ? pwd->pw_name : "-", - lc ? lc->lc_class : LOGIN_DEFCLASS); - } else { - if (setpriority(PRIO_PROCESS, 0, (int)p) != 0) - syslog(LOG_WARNING, "setpriority '%s' (%s): %m", - pwd ? pwd->pw_name : "-", - lc ? lc->lc_class : LOGIN_DEFCLASS); + if (p != def_val) { + /* Invariant: 'lc' != NULL from here. */ + if (p == err_val) { + syslog(LOG_WARNING, + "%s%s%sLogin class '%s': " + "Invalid priority specification: '%s'", + pwd ? "Login '" : "", + pwd ? pwd->pw_name : "", + pwd ? "': " : "", + lc->lc_class, + login_getcapstr(lc, "priority", "", "")); + } else { + if (p > PRIO_MAX) { + struct rtprio rtp; + rtp.type = RTP_PRIO_IDLE; + p += RTP_PRIO_MIN - (PRIO_MAX + 1); + rtp.prio = p > RTP_PRIO_MAX ? RTP_PRIO_MAX : p; + rc = rtprio(RTP_SET, 0, &rtp); + } else if (p < PRIO_MIN) { + struct rtprio rtp; + rtp.type = RTP_PRIO_REALTIME; + p += RTP_PRIO_MAX - (PRIO_MIN - 1); + rtp.prio = p < RTP_PRIO_MIN ? RTP_PRIO_MIN : p; + rc = rtprio(RTP_SET, 0, &rtp); + } else + rc = setpriority(PRIO_PROCESS, 0, (int)p); + + if (rc != 0) + syslog(LOG_WARNING, + "%s%s%sLogin class '%s': " + "Setting priority failed: %m", + pwd ? "Login '" : "", + pwd ? pwd->pw_name : "", + pwd ? "': " : "", + lc->lc_class); + } } }