* libmisc/limits.c: Add brackets and parenthesis.
* libmisc/limits.c: Avoid implicit conversion of pointers / integers to booleans. * libmisc/limits.c: Ignore the return value of umask(). We will never return to the original umask. * libmisc/limits.c: Avoid multi-statements lines. * libmisc/limits.c: Added default to a switch(). Report invalid limit strings to syslog. * libmisc/limits.c: Ignore the return value of fclose(). /etc/limits is open read-only. * libmisc/limits.c: Ignore the return value of fputs() and sleep(). * libmisc/limits.c: Check the return value of nice() and set_filesize_limit(), and report errors to syslog. * libmisc/ulimit.c, lib/prototypes.h: Return failures of set_filesize_limit(). Change the prototype to return an int instead of void.
This commit is contained in:
parent
dcd480ffd9
commit
abb95d5aab
23
ChangeLog
23
ChangeLog
@ -1,3 +1,26 @@
|
|||||||
|
2008-06-15 Nicolas François <nicolas.francois@centraliens.net>
|
||||||
|
|
||||||
|
* libmisc/limits.c: Add brackets and parenthesis.
|
||||||
|
* libmisc/limits.c: Avoid implicit conversion of pointers /
|
||||||
|
integers to booleans.
|
||||||
|
* libmisc/limits.c: Ignore the return value of umask(). We will
|
||||||
|
never return to the original umask.
|
||||||
|
* libmisc/limits.c: Avoid multi-statements lines.
|
||||||
|
* libmisc/limits.c: Added default to a switch(). Report invalid
|
||||||
|
limit strings to syslog.
|
||||||
|
* libmisc/limits.c: Ignore the return value of fclose().
|
||||||
|
/etc/limits is open read-only.
|
||||||
|
* libmisc/limits.c: Ignore the return value of fputs() and
|
||||||
|
sleep().
|
||||||
|
* libmisc/limits.c: Check the return value of nice() and
|
||||||
|
set_filesize_limit(), and report errors to syslog.
|
||||||
|
|
||||||
|
2008-06-15 Nicolas François <nicolas.francois@centraliens.net>
|
||||||
|
|
||||||
|
* libmisc/ulimit.c, lib/prototypes.h: Return failures of
|
||||||
|
set_filesize_limit(). Change the prototype to return an int
|
||||||
|
instead of void.
|
||||||
|
|
||||||
2008-06-15 Nicolas François <nicolas.francois@centraliens.net>
|
2008-06-15 Nicolas François <nicolas.francois@centraliens.net>
|
||||||
|
|
||||||
* libmisc/failure.c: Try to close the open file if a failure
|
* libmisc/failure.c: Try to close the open file if a failure
|
||||||
|
@ -258,7 +258,7 @@ extern void ttytype (const char *);
|
|||||||
extern char *tz (const char *);
|
extern char *tz (const char *);
|
||||||
|
|
||||||
/* ulimit.c */
|
/* ulimit.c */
|
||||||
extern void set_filesize_limit (int);
|
extern int set_filesize_limit (int blocks);
|
||||||
|
|
||||||
/* utmp.c */
|
/* utmp.c */
|
||||||
extern void checkutmp (bool picky);
|
extern void checkutmp (bool picky);
|
||||||
|
@ -74,13 +74,15 @@ setrlimit_value (unsigned int rlimit, const char *value,
|
|||||||
const char *value_orig = value;
|
const char *value_orig = value;
|
||||||
|
|
||||||
limit = strtol (value, endptr, 10);
|
limit = strtol (value, endptr, 10);
|
||||||
if (limit == 0 && value_orig == *endptr) /* no chars read */
|
if ((0 == limit) && (value_orig == *endptr)) { /* no chars read */
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
limit *= multiplier;
|
limit *= multiplier;
|
||||||
rlim.rlim_cur = limit;
|
rlim.rlim_cur = limit;
|
||||||
rlim.rlim_max = limit;
|
rlim.rlim_max = limit;
|
||||||
if (setrlimit (rlimit, &rlim))
|
if (setrlimit (rlimit, &rlim) != 0) {
|
||||||
return LOGIN_ERROR_RLIMIT;
|
return LOGIN_ERROR_RLIMIT;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,10 +93,12 @@ static int set_prio (const char *value)
|
|||||||
char **endptr = (char **) &value;
|
char **endptr = (char **) &value;
|
||||||
|
|
||||||
prio = strtol (value, endptr, 10);
|
prio = strtol (value, endptr, 10);
|
||||||
if ((prio == 0) && (value == *endptr))
|
if ((0 == prio) && (value == *endptr)) {
|
||||||
return 0;
|
return 0;
|
||||||
if (setpriority (PRIO_PROCESS, 0, prio))
|
}
|
||||||
|
if (setpriority (PRIO_PROCESS, 0, prio) != 0) {
|
||||||
return LOGIN_ERROR_RLIMIT;
|
return LOGIN_ERROR_RLIMIT;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,9 +109,10 @@ static int set_umask (const char *value)
|
|||||||
char **endptr = (char **) &value;
|
char **endptr = (char **) &value;
|
||||||
|
|
||||||
mask = strtol (value, endptr, 8) & 0777;
|
mask = strtol (value, endptr, 8) & 0777;
|
||||||
if ((mask == 0) && (value == *endptr))
|
if ((0 == mask) && (value == *endptr)) {
|
||||||
return 0;
|
return 0;
|
||||||
umask (mask);
|
}
|
||||||
|
(void) umask (mask);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,10 +130,11 @@ static int check_logins (const char *name, const char *maxlogins)
|
|||||||
const char *ml_orig = maxlogins;
|
const char *ml_orig = maxlogins;
|
||||||
|
|
||||||
limit = strtol (maxlogins, endptr, 10);
|
limit = strtol (maxlogins, endptr, 10);
|
||||||
if (limit == 0 && ml_orig == *endptr) /* no chars read */
|
if ((0 == limit) && (ml_orig == *endptr)) { /* no chars read */
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (limit == 0) { /* maximum 0 logins ? */
|
if (0 == limit) { /* maximum 0 logins ? */
|
||||||
SYSLOG ((LOG_WARN, "No logins allowed for `%s'\n", name));
|
SYSLOG ((LOG_WARN, "No logins allowed for `%s'\n", name));
|
||||||
return LOGIN_ERROR_LOGIN;
|
return LOGIN_ERROR_LOGIN;
|
||||||
}
|
}
|
||||||
@ -141,15 +147,20 @@ static int check_logins (const char *name, const char *maxlogins)
|
|||||||
setutent ();
|
setutent ();
|
||||||
while ((ut = getutent ())) {
|
while ((ut = getutent ())) {
|
||||||
#endif
|
#endif
|
||||||
if (ut->ut_type != USER_PROCESS)
|
if (USER_PROCESS != ut->ut_type) {
|
||||||
continue;
|
continue;
|
||||||
if (ut->ut_user[0] == '\0')
|
}
|
||||||
|
if ('\0' == ut->ut_user[0]) {
|
||||||
continue;
|
continue;
|
||||||
if (strncmp (name, ut->ut_user, sizeof (ut->ut_user)) != 0)
|
}
|
||||||
|
if (strncmp (name, ut->ut_user, sizeof (ut->ut_user)) != 0) {
|
||||||
continue;
|
continue;
|
||||||
if (++count > limit)
|
}
|
||||||
|
count++;
|
||||||
|
if (count > limit) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#if HAVE_UTMPX_H
|
#if HAVE_UTMPX_H
|
||||||
endutxent ();
|
endutxent ();
|
||||||
#else
|
#else
|
||||||
@ -203,10 +214,11 @@ static int do_user_limits (const char *buf, const char *name)
|
|||||||
{
|
{
|
||||||
const char *pp;
|
const char *pp;
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
|
bool reported = false;
|
||||||
|
|
||||||
pp = buf;
|
pp = buf;
|
||||||
|
|
||||||
while (*pp != '\0')
|
while ('\0' != *pp) {
|
||||||
switch (*pp++) {
|
switch (*pp++) {
|
||||||
#ifdef RLIMIT_AS
|
#ifdef RLIMIT_AS
|
||||||
case 'a':
|
case 'a':
|
||||||
@ -298,13 +310,23 @@ static int do_user_limits (const char *buf, const char *name)
|
|||||||
break;
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
case 'L':
|
case 'L':
|
||||||
/* LIMIT the number of concurent logins */
|
/* LIMIT the number of concurrent logins */
|
||||||
retval |= check_logins (name, pp);
|
retval |= check_logins (name, pp);
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
case 'P':
|
case 'P':
|
||||||
retval |= set_prio (pp);
|
retval |= set_prio (pp);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
/* Only report invalid strings once */
|
||||||
|
if (!reported) {
|
||||||
|
SYSLOG ((LOG_WARN,
|
||||||
|
"Invalid limit string: '%s'",
|
||||||
|
pp-1));
|
||||||
|
reported = true;
|
||||||
|
retval |= LOGIN_ERROR_RLIMIT;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
@ -336,8 +358,9 @@ static int setup_user_limits (const char *uname)
|
|||||||
* - username must start on first column
|
* - username must start on first column
|
||||||
* A better (smarter) checking should be done --cristiang */
|
* A better (smarter) checking should be done --cristiang */
|
||||||
while (fgets (buf, 1024, fil) != NULL) {
|
while (fgets (buf, 1024, fil) != NULL) {
|
||||||
if (buf[0] == '#' || buf[0] == '\n')
|
if (('#' == buf[0]) || ('\n' == buf[0])) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
memzero (tempbuf, sizeof (tempbuf));
|
memzero (tempbuf, sizeof (tempbuf));
|
||||||
/* a valid line should have a username, then spaces,
|
/* a valid line should have a username, then spaces,
|
||||||
* then limits
|
* then limits
|
||||||
@ -357,11 +380,12 @@ static int setup_user_limits (const char *uname)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose (fil);
|
(void) fclose (fil);
|
||||||
if (limits[0] == '\0') {
|
if (limits[0] == '\0') {
|
||||||
/* no user specific limits */
|
/* no user specific limits */
|
||||||
if (deflimits[0] == '\0') /* no default limits */
|
if (deflimits[0] == '\0') { /* no default limits */
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
strcpy (limits, deflimits); /* use the default limits */
|
strcpy (limits, deflimits); /* use the default limits */
|
||||||
}
|
}
|
||||||
return do_user_limits (limits, uname);
|
return do_user_limits (limits, uname);
|
||||||
@ -379,12 +403,13 @@ static void setup_usergroups (const struct passwd *info)
|
|||||||
* group name, set umask group bits to be the same as owner bits
|
* group name, set umask group bits to be the same as owner bits
|
||||||
* (examples: 022 -> 002, 077 -> 007).
|
* (examples: 022 -> 002, 077 -> 007).
|
||||||
*/
|
*/
|
||||||
if (info->pw_uid != 0 && info->pw_uid == info->pw_gid) {
|
if ((0 != info->pw_uid) && (info->pw_uid == info->pw_gid)) {
|
||||||
/* local, no need for xgetgrgid */
|
/* local, no need for xgetgrgid */
|
||||||
grp = getgrgid (info->pw_gid);
|
grp = getgrgid (info->pw_gid);
|
||||||
if (grp && (strcmp (info->pw_name, grp->gr_name) == 0)) {
|
if ( (NULL != grp)
|
||||||
|
&& (strcmp (info->pw_name, grp->gr_name) == 0)) {
|
||||||
oldmask = umask (0777);
|
oldmask = umask (0777);
|
||||||
umask ((oldmask & ~070) | ((oldmask >> 3) & 070));
|
(void) umask ((oldmask & ~070) | ((oldmask >> 3) & 070));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -399,8 +424,9 @@ void setup_limits (const struct passwd *info)
|
|||||||
int i;
|
int i;
|
||||||
long l;
|
long l;
|
||||||
|
|
||||||
if (getdef_bool ("USERGROUPS_ENAB"))
|
if (getdef_bool ("USERGROUPS_ENAB")) {
|
||||||
setup_usergroups (info);
|
setup_usergroups (info);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* See if the GECOS field contains values for NICE, UMASK or ULIMIT.
|
* See if the GECOS field contains values for NICE, UMASK or ULIMIT.
|
||||||
@ -410,28 +436,41 @@ void setup_limits (const struct passwd *info)
|
|||||||
|
|
||||||
if (getdef_bool ("QUOTAS_ENAB")) {
|
if (getdef_bool ("QUOTAS_ENAB")) {
|
||||||
#ifdef LIMITS
|
#ifdef LIMITS
|
||||||
if (info->pw_uid != 0)
|
if (info->pw_uid != 0) {
|
||||||
if (setup_user_limits (info->pw_name) &
|
if (setup_user_limits (info->pw_name) &
|
||||||
LOGIN_ERROR_LOGIN) {
|
LOGIN_ERROR_LOGIN) {
|
||||||
fputs (_("Too many logins.\n"), stderr);
|
(void) fputs (_("Too many logins.\n"), stderr);
|
||||||
sleep (2);
|
(void) sleep (2); /* XXX: Should be FAIL_DELAY */
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
for (cp = info->pw_gecos; cp != NULL; cp = strchr (cp, ',')) {
|
for (cp = info->pw_gecos; cp != NULL; cp = strchr (cp, ',')) {
|
||||||
if (*cp == ',')
|
if (',' == *cp) {
|
||||||
cp++;
|
cp++;
|
||||||
|
}
|
||||||
|
|
||||||
if (strncmp (cp, "pri=", 4) == 0) {
|
if (strncmp (cp, "pri=", 4) == 0) {
|
||||||
i = atoi (cp + 4);
|
i = atoi (cp + 4);
|
||||||
if (i >= -20 && i <= 20)
|
if ((i >= -20) && (i <= 20)) {
|
||||||
(void) nice (i);
|
errno = 0;
|
||||||
|
if ( (nice (i) == -1)
|
||||||
|
&& (0 != errno)) {
|
||||||
|
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);
|
l = strtol (cp + 7, (char **) 0, 10);
|
||||||
set_filesize_limit (l);
|
if (set_filesize_limit (l) != 0) {
|
||||||
|
SYSLOG ((LOG_WARN,
|
||||||
|
"Can't set the ulimit for user %s",
|
||||||
|
info->pw_name));
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (strncmp (cp, "umask=", 6) == 0) {
|
if (strncmp (cp, "umask=", 6) == 0) {
|
||||||
|
@ -50,14 +50,21 @@
|
|||||||
#endif
|
#endif
|
||||||
#include "prototypes.h"
|
#include "prototypes.h"
|
||||||
|
|
||||||
void set_filesize_limit (int blocks)
|
int set_filesize_limit (int blocks)
|
||||||
{
|
{
|
||||||
|
int ret = -1;
|
||||||
#if HAVE_ULIMIT_H
|
#if HAVE_ULIMIT_H
|
||||||
ulimit (UL_SETFSIZE, blocks);
|
if (ulimit (UL_SETFSIZE, blocks) != -1) {
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
#elif defined(RLIMIT_FSIZE)
|
#elif defined(RLIMIT_FSIZE)
|
||||||
struct rlimit rlimit_fsize;
|
struct rlimit rlimit_fsize;
|
||||||
|
|
||||||
rlimit_fsize.rlim_cur = rlimit_fsize.rlim_max = 512L * blocks;
|
rlimit_fsize.rlim_cur = 512L * blocks;
|
||||||
setrlimit (RLIMIT_FSIZE, &rlimit_fsize);
|
rlimit_fsize.rlim_max = rlimit_fsize.rlim_cur;
|
||||||
|
ret = setrlimit (RLIMIT_FSIZE, &rlimit_fsize);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user