# Author: Vlad Glagolev # # Changes in this patch: # * groups and comments support # * bugfix for not found user or empty file # * bugfix for unlimited values # * bugfix for tab separators --- src/ulimits.c.orig 2013-01-28 14:39:13.000000000 +0400 +++ src/ulimits.c 2014-10-02 21:39:49.318495483 +0400 @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -95,6 +96,47 @@ #define PLIMIT_PRIORITY RLIMIT_NLIMITS + 3 /** + * Check if user is in the group + * + * @param uname A pointer to a username + * @param gname A pointer to a groupname + * @return 0 if a user belongs to group, -1 otherwise + */ +static int user_in_group(const *uname, const char *gname) +{ + struct group *groupdata; + char *const *list; + + if (uname == NULL || gname == NULL) { + return -1; + } + + if (*gname == '@') { + gname++; + } else { + return -1; + } + + groupdata = getgrnam(gname); + + if (groupdata == NULL) { + return -1; + } + + list = groupdata->gr_mem; + + while (*list != NULL) { + if (strcmp(*list, uname) == 0) { + return 0; + } + + list++; + } + + return -1; +} + +/** * Parses a single limit specification. * This function parses a single limit specification (that is, a single * letter followed by a numerical value) and fills the provided @@ -109,7 +151,7 @@ parse_limit_value(char **s, struct rlimit_setting *rlimit) { char *c, *p; - int value; + int value, inf; if ( s == NULL || *s == NULL || rlimit == NULL ) { errno = EINVAL; @@ -123,7 +165,16 @@ /* Get the numerical value for the limit. */ errno = 0; - value = strtol(c + 1, &p, 10); + + /* A single dash means no limits. */ + if (*(c+1) == '-') { + p = c+2; + inf = 1; + } else { + value = strtol(c + 1, &p, 10); + inf = 0; + } + if ( errno || p == c + 1 ) return -1; @@ -132,7 +183,7 @@ #define ULIMIT(symbol, letter, unused1, factor, unused2) \ case letter: \ rlimit->resource = symbol; \ - rlimit->limit = value * factor; \ + rlimit->limit = inf == 1 ? RLIM_INFINITY : value * factor; \ break; #include "ulimits.h" #undef ULIMIT @@ -174,15 +225,6 @@ while ( *s == ' ' || *s == '\t' ) s += 1; - /* A single dash means no limits. */ - if ( *s == '-' && *(s + 1) == '\0' ) { - for ( ; n < RLIMIT_NLIMITS && n < len - 1 ; n++ ) { - rlimits[n].resource = n; - rlimits[n].limit = RLIM_INFINITY; - } - s += 1; - } - while ( *s != '\0' && n < len - 1 ) { if ( parse_limit_value(&s, &(rlimits[n])) < 0 ) return -1; @@ -280,9 +322,11 @@ while ( ! found && ! feof(f) ) { c = fgetc(f); - if ( isgraph(c) && n < len - 1 ) + if (c == '#') + discard_line(f); + else if ( isgraph(c) && n < len - 1 ) buffer[n++] = (char)c; - else if ( c == ' ' && n > 0 ) + else if ( (c == ' ' || c == '\t') && n > 0 ) found = 1; else { n = 0; @@ -357,18 +401,21 @@ if ( strcmp(nbuf, "*") == 0 ) default_found = get_line(f, lbuf, sizeof(lbuf)) != -1; - else if ( strcmp(nbuf, user) == 0 ) + else if ( strcmp(nbuf, user) == 0 || user_in_group(user, nbuf) == 0 ) user_found = get_line(f, lbuf, sizeof(lbuf)) != -1; else discard_line(f); } fclose(f); - if ( user_found || default_found ) + if ( user_found || default_found ) { if ( (n = parse_limit_string(lbuf, rlimits, len)) == -1 ) errno = EBADMSG; - return n; + return n; + } + + return -1; } static int .