* libmisc/limits.c: Parse the limits, umask, nice, maxlogin, file

limit with getlog() / getulong(). This also means, in case of
	non-PAM enabled systems, that the umask specified on the GECOS
	fields should start with a 0 if specified in octal. (it used to be
	force to octal). Do the appropriate cast and range checking.
This commit is contained in:
nekral-guest 2009-04-24 22:56:42 +00:00
parent 0c571784a3
commit 10396f9536
2 changed files with 51 additions and 34 deletions

View File

@ -1,3 +1,11 @@
2009-04-25 Nicolas François <nicolas.francois@centraliens.net>
* libmisc/limits.c: Parse the limits, umask, nice, maxlogin, file
limit with getlog() / getulong(). This also means, in case of
non-PAM enabled systems, that the umask specified on the GECOS
fields should start with a 0 if specified in octal. (it used to be
force to octal). Do the appropriate cast and range checking.
2009-04-25 Nicolas François <nicolas.francois@centraliens.net> 2009-04-25 Nicolas François <nicolas.francois@centraliens.net>
* libmisc/salt.c: In case gettimeofday() fails, get some entropy * libmisc/salt.c: In case gettimeofday() fails, get some entropy

View File

@ -65,22 +65,22 @@
* multiplier - value*multiplier is the actual limit * multiplier - value*multiplier is the actual limit
*/ */
static int static int
setrlimit_value (unsigned int rlimit, const char *value, setrlimit_value (unsigned int resource, const char *value,
unsigned int multiplier) unsigned int multiplier)
{ {
struct rlimit rlim; struct rlimit rlim;
long limit; long limit;
char **endptr = (char **) &value;
const char *value_orig = value;
limit = strtol (value, endptr, 10); if (getlong (value, &limit) == 0) {
if ((0 == limit) && (value_orig == *endptr)) { /* no chars read */
return 0; return 0;
} }
limit *= multiplier; limit *= multiplier;
rlim.rlim_cur = limit; if (limit != (rlim_t) limit) {
rlim.rlim_max = limit; return 0;
if (setrlimit (rlimit, &rlim) != 0) { }
rlim.rlim_cur = (rlim_t) limit;
rlim.rlim_max = (rlim_t) limit;
if (setrlimit (resource, &rlim) != 0) {
return LOGIN_ERROR_RLIMIT; return LOGIN_ERROR_RLIMIT;
} }
return 0; return 0;
@ -105,14 +105,14 @@ static int set_prio (const char *value)
static int set_umask (const char *value) static int set_umask (const char *value)
{ {
mode_t mask; unsigned long int mask;
char **endptr = (char **) &value;
mask = strtol (value, endptr, 8) & 0777; if ( (getulong (value, &mask) == 0)
if ((0 == mask) && (value == *endptr)) { || (mask != (mode_t) mask)) {
return 0; return 0;
} }
(void) umask (mask);
(void) umask ((mode_t) mask);
return 0; return 0;
} }
@ -125,12 +125,9 @@ static int check_logins (const char *name, const char *maxlogins)
#else #else
struct utmp *ut; struct utmp *ut;
#endif #endif
unsigned int limit, count; unsigned long limit, count;
char **endptr = (char **) &maxlogins;
const char *ml_orig = maxlogins;
limit = strtol (maxlogins, endptr, 10); if (getulong (maxlogins, &limit) == 0) {
if ((0 == limit) && (ml_orig == *endptr)) { /* no chars read */
return 0; return 0;
} }
@ -396,7 +393,7 @@ static int setup_user_limits (const char *uname)
static void setup_usergroups (const struct passwd *info) static void setup_usergroups (const struct passwd *info)
{ {
const struct group *grp; const struct group *grp;
mode_t oldmask; mode_t tmpmask;
/* /*
* if not root, and UID == GID, and username is the same as primary * if not root, and UID == GID, and username is the same as primary
@ -408,8 +405,9 @@ static void setup_usergroups (const struct passwd *info)
grp = getgrgid (info->pw_gid); grp = getgrgid (info->pw_gid);
if ( (NULL != grp) if ( (NULL != grp)
&& (strcmp (info->pw_name, grp->gr_name) == 0)) { && (strcmp (info->pw_name, grp->gr_name) == 0)) {
oldmask = umask (0777); tmpmask = umask (0777);
(void) umask ((oldmask & ~070) | ((oldmask >> 3) & 070)); tmpmask = (tmpmask & ~070) | ((tmpmask >> 3) & 070);
(void) umask (tmpmask);
} }
} }
} }
@ -421,8 +419,6 @@ static void setup_usergroups (const struct passwd *info)
void setup_limits (const struct passwd *info) void setup_limits (const struct passwd *info)
{ {
char *cp; char *cp;
int i;
long l;
if (getdef_bool ("USERGROUPS_ENAB")) { if (getdef_bool ("USERGROUPS_ENAB")) {
setup_usergroups (info); setup_usergroups (info);
@ -451,22 +447,28 @@ void setup_limits (const struct passwd *info)
} }
if (strncmp (cp, "pri=", 4) == 0) { if (strncmp (cp, "pri=", 4) == 0) {
i = atoi (cp + 4); long int inc;
if ((i >= -20) && (i <= 20)) { if ( (getlong (cp + 4, &inc) == 1)
&& (inc >= -20) && (inc <= 20)) {
errno = 0; errno = 0;
if ( (nice (i) == -1) if ( (nice ((int) inc) != -1)
&& (0 != errno)) { || (0 != errno)) {
SYSLOG ((LOG_WARN, continue;
"Can't set the nice value for user %s",
info->pw_name));
} }
} }
/* Failed to parse or failed to nice() */
SYSLOG ((LOG_WARN,
"Can't set the nice value for user %s",
info->pw_name));
continue; continue;
} }
if (strncmp (cp, "ulimit=", 7) == 0) { if (strncmp (cp, "ulimit=", 7) == 0) {
l = strtol (cp + 7, (char **) 0, 10); long int blocks;
if (set_filesize_limit (l) != 0) { if ( (getlong (cp + 7, &blocks) == 0)
|| (blocks != (int) blocks)
|| (set_filesize_limit ((int) blocks) != 0)) {
SYSLOG ((LOG_WARN, SYSLOG ((LOG_WARN,
"Can't set the ulimit for user %s", "Can't set the ulimit for user %s",
info->pw_name)); info->pw_name));
@ -474,8 +476,15 @@ void setup_limits (const struct passwd *info)
continue; continue;
} }
if (strncmp (cp, "umask=", 6) == 0) { if (strncmp (cp, "umask=", 6) == 0) {
i = strtol (cp + 6, (char **) 0, 8) & 0777; unsigned long int mask;
(void) umask (i); if ( (getulong (cp + 6, &mask) == 0)
|| (mask != (mode_t) mask)) {
SYSLOG ((LOG_WARN,
"Can't set umask value for user %s",
info->pw_name));
} else {
(void) umask ((mode_t) mask);
}
continue; continue;
} }