summaryrefslogtreecommitdiffstats
path: root/libmisc/limits.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--lib/limits.c (renamed from libmisc/limits.c)138
1 files changed, 43 insertions, 95 deletions
diff --git a/libmisc/limits.c b/lib/limits.c
index fea85fe..813c082 100644
--- a/libmisc/limits.c
+++ b/lib/limits.c
@@ -28,11 +28,12 @@
#include <pwd.h>
#include "getdef.h"
#include "shadowlog.h"
-#ifdef HAVE_SYS_RESOURCE_H
#include <sys/resource.h>
-#define LIMITS
-#endif
-#ifdef LIMITS
+
+#include "atoi/str2i.h"
+#include "memzero.h"
+
+
#ifndef LIMITS_FILE
#define LIMITS_FILE "/etc/limits"
#endif
@@ -48,8 +49,10 @@ static int setrlimit_value (unsigned int resource,
const char *value,
unsigned int multiplier)
{
- struct rlimit rlim;
- rlim_t limit;
+ char *end;
+ long l;
+ rlim_t limit;
+ struct rlimit rlim;
/* The "-" is special, not belonging to a strange negative limit.
* It is infinity, in a controlled way.
@@ -58,23 +61,18 @@ static int setrlimit_value (unsigned int resource,
limit = RLIM_INFINITY;
}
else {
- /* We cannot use getlong here because it fails when there
+ /* We cannot use str2sl() here because it fails when there
* is more to the value than just this number!
* Also, we are limited to base 10 here (hex numbers will not
* work with the limit string parser as is anyway)
*/
- char *endptr;
- long longlimit = strtol (value, &endptr, 10);
- if ((0 == longlimit) && (value == endptr)) {
- /* No argument at all. No-op.
- * FIXME: We could instead throw an error, though.
- */
- return 0;
- }
- longlimit *= multiplier;
- limit = (rlim_t)longlimit;
- if (longlimit != limit)
- {
+ errno = 0;
+ l = strtol(value, &end, 10);
+
+ if (value == end || errno != 0)
+ return 0; // FIXME: We could instead throw an error, though.
+
+ if (__builtin_mul_overflow(l, multiplier, &limit)) {
/* FIXME: Again, silent error handling...
* Wouldn't screaming make more sense?
*/
@@ -95,11 +93,11 @@ static int set_prio (const char *value)
{
long prio;
- if ( (getlong (value, &prio) == 0)
+ if ( (str2sl(&prio, value) == -1)
|| (prio != (int) prio)) {
return 0;
}
- if (setpriority (PRIO_PROCESS, 0, (int) prio) != 0) {
+ if (setpriority (PRIO_PROCESS, 0, prio) != 0) {
return LOGIN_ERROR_RLIMIT;
}
return 0;
@@ -108,14 +106,14 @@ static int set_prio (const char *value)
static int set_umask (const char *value)
{
- unsigned long int mask;
+ unsigned long mask;
- if ( (getulong (value, &mask) == 0)
+ if ( (str2ul(&mask, value) == -1)
|| (mask != (mode_t) mask)) {
return 0;
}
- (void) umask ((mode_t) mask);
+ (void) umask (mask);
return 0;
}
@@ -123,14 +121,9 @@ static int set_umask (const char *value)
/* Counts the number of user logins and check against the limit */
static int check_logins (const char *name, const char *maxlogins)
{
-#ifdef USE_UTMPX
- struct utmpx *ut;
-#else /* !USE_UTMPX */
- struct utmp *ut;
-#endif /* !USE_UTMPX */
unsigned long limit, count;
- if (getulong (maxlogins, &limit) == 0) {
+ if (str2ul(&limit, maxlogins) == -1) {
return 0;
}
@@ -139,38 +132,8 @@ static int check_logins (const char *name, const char *maxlogins)
return LOGIN_ERROR_LOGIN;
}
- count = 0;
-#ifdef USE_UTMPX
- setutxent ();
- while ((ut = getutxent ()))
-#else /* !USE_UTMPX */
- setutent ();
- while ((ut = getutent ()))
-#endif /* !USE_UTMPX */
- {
- if (USER_PROCESS != ut->ut_type) {
- continue;
- }
- if ('\0' == ut->ut_user[0]) {
- continue;
- }
- if (strncmp (name, ut->ut_user, sizeof (ut->ut_user)) != 0) {
- continue;
- }
- count++;
- if (count > limit) {
- break;
- }
- }
-#ifdef USE_UTMPX
- endutxent ();
-#else /* !USE_UTMPX */
- endutent ();
-#endif /* !USE_UTMPX */
- /*
- * This is called after setutmp(), so the number of logins counted
- * includes the user who is currently trying to log in.
- */
+ count = active_sessions_count(name, limit);
+
if (count > limit) {
SYSLOG ((LOG_WARN,
"Too many logins (max %lu) for %s\n",
@@ -243,34 +206,26 @@ static int do_user_limits (const char *buf, const char *name)
while ('\0' != *pp) {
switch (*pp++) {
-#ifdef RLIMIT_AS
case 'a':
case 'A':
/* RLIMIT_AS - max address space (KB) */
retval |= setrlimit_value (RLIMIT_AS, pp, 1024);
break;
-#endif
-#ifdef RLIMIT_CORE
case 'c':
case 'C':
/* RLIMIT_CORE - max core file size (KB) */
retval |= setrlimit_value (RLIMIT_CORE, pp, 1024);
break;
-#endif
-#ifdef RLIMIT_DATA
case 'd':
case 'D':
/* RLIMIT_DATA - max data size (KB) */
retval |= setrlimit_value (RLIMIT_DATA, pp, 1024);
break;
-#endif
-#ifdef RLIMIT_FSIZE
case 'f':
case 'F':
/* RLIMIT_FSIZE - Maximum filesize (KB) */
retval |= setrlimit_value (RLIMIT_FSIZE, pp, 1024);
break;
-#endif
#ifdef RLIMIT_NICE
case 'i':
case 'I':
@@ -294,13 +249,11 @@ static int do_user_limits (const char *buf, const char *name)
retval |= setrlimit_value (RLIMIT_MEMLOCK, pp, 1024);
break;
#endif
-#ifdef RLIMIT_NOFILE
case 'n':
case 'N':
/* RLIMIT_NOFILE - max number of open files */
retval |= setrlimit_value (RLIMIT_NOFILE, pp, 1);
break;
-#endif
#ifdef RLIMIT_RTPRIO
case 'o':
case 'O':
@@ -319,20 +272,16 @@ static int do_user_limits (const char *buf, const char *name)
retval |= setrlimit_value (RLIMIT_RSS, pp, 1024);
break;
#endif
-#ifdef RLIMIT_STACK
case 's':
case 'S':
/* RLIMIT_STACK - max stack size (KB) */
retval |= setrlimit_value (RLIMIT_STACK, pp, 1024);
break;
-#endif
-#ifdef RLIMIT_CPU
case 't':
case 'T':
/* RLIMIT_CPU - max CPU time (MIN) */
retval |= setrlimit_value (RLIMIT_CPU, pp, 60);
break;
-#endif
#ifdef RLIMIT_NPROC
case 'u':
case 'U':
@@ -409,11 +358,11 @@ static int setup_user_limits (const char *uname)
char tempbuf[1024];
/* init things */
- memzero (buf, sizeof (buf));
- memzero (name, sizeof (name));
- memzero (limits, sizeof (limits));
- memzero (deflimits, sizeof (deflimits));
- memzero (tempbuf, sizeof (tempbuf));
+ MEMZERO(buf);
+ MEMZERO(name);
+ MEMZERO(limits);
+ MEMZERO(deflimits);
+ MEMZERO(tempbuf);
/* start the checks */
fil = fopen (LIMITS_FILE, "r");
@@ -430,7 +379,7 @@ static int setup_user_limits (const char *uname)
if (('#' == buf[0]) || ('\n' == buf[0])) {
continue;
}
- memzero (tempbuf, sizeof (tempbuf));
+ MEMZERO(tempbuf);
/* a valid line should have a username, then spaces,
* then limits
* we allow the format:
@@ -479,7 +428,6 @@ static int setup_user_limits (const char *uname)
}
return do_user_limits (limits, uname);
}
-#endif /* LIMITS */
static void setup_usergroups (const struct passwd *info)
@@ -523,7 +471,6 @@ void setup_limits (const struct passwd *info)
*/
if (getdef_bool ("QUOTAS_ENAB")) {
-#ifdef LIMITS
if (info->pw_uid != 0) {
if ((setup_user_limits (info->pw_name) & LOGIN_ERROR_LOGIN) != 0) {
(void) fputs (_("Too many logins.\n"), log_get_logfd());
@@ -531,18 +478,18 @@ void setup_limits (const struct passwd *info)
exit (EXIT_FAILURE);
}
}
-#endif
for (cp = info->pw_gecos; cp != NULL; cp = strchr (cp, ',')) {
if (',' == *cp) {
cp++;
}
if (strncmp (cp, "pri=", 4) == 0) {
- long int inc;
- if ( (getlong (cp + 4, &inc) == 1)
+ long inc;
+
+ if ( (str2sl(&inc, cp + 4) == 0)
&& (inc >= -20) && (inc <= 20)) {
errno = 0;
- if ( (nice ((int) inc) != -1)
+ if ( (nice (inc) != -1)
|| (0 != errno)) {
continue;
}
@@ -556,10 +503,10 @@ void setup_limits (const struct passwd *info)
continue;
}
if (strncmp (cp, "ulimit=", 7) == 0) {
- long int blocks;
- if ( (getlong (cp + 7, &blocks) == 0)
+ long blocks;
+ if ( (str2sl(&blocks, cp + 7) == -1)
|| (blocks != (int) blocks)
- || (set_filesize_limit ((int) blocks) != 0)) {
+ || (set_filesize_limit (blocks) != 0)) {
SYSLOG ((LOG_WARN,
"Can't set the ulimit for user %s",
info->pw_name));
@@ -567,14 +514,15 @@ void setup_limits (const struct passwd *info)
continue;
}
if (strncmp (cp, "umask=", 6) == 0) {
- unsigned long int mask;
- if ( (getulong (cp + 6, &mask) == 0)
+ unsigned long mask;
+
+ if ( (str2ul(&mask, cp + 6) == -1)
|| (mask != (mode_t) mask)) {
SYSLOG ((LOG_WARN,
"Can't set umask value for user %s",
info->pw_name));
} else {
- (void) umask ((mode_t) mask);
+ (void) umask (mask);
}
continue;
@@ -584,6 +532,6 @@ void setup_limits (const struct passwd *info)
}
#else /* !USE_PAM */
-extern int errno; /* warning: ANSI C forbids an empty source file */
+extern int ISO_C_forbids_an_empty_translation_unit;
#endif /* !USE_PAM */