diff options
Diffstat (limited to 'extra/source/pam/patches/pam-1.1.3-limits-range.patch')
-rw-r--r-- | extra/source/pam/patches/pam-1.1.3-limits-range.patch | 351 |
1 files changed, 351 insertions, 0 deletions
diff --git a/extra/source/pam/patches/pam-1.1.3-limits-range.patch b/extra/source/pam/patches/pam-1.1.3-limits-range.patch new file mode 100644 index 00000000..c357eb28 --- /dev/null +++ b/extra/source/pam/patches/pam-1.1.3-limits-range.patch @@ -0,0 +1,351 @@ +Index: modules/pam_limits/limits.conf.5.xml +=================================================================== +RCS file: /cvsroot/pam/Linux-PAM/modules/pam_limits/limits.conf.5.xml,v +retrieving revision 1.9 +retrieving revision 1.11 +diff -u -p -r1.9 -r1.11 +--- modules/pam_limits/limits.conf.5.xml 20 Feb 2009 13:27:14 -0000 1.9 ++++ modules/pam_limits/limits.conf.5.xml 14 Dec 2010 08:40:40 -0000 1.11 +@@ -53,7 +53,38 @@ + <listitem> + <para> + the wildcard <emphasis remap='B'>%</emphasis>, for maxlogins limit only, +- can also be used with <emphasis remap='b'>%group</emphasis> syntax. ++ can also be used with <emphasis remap='B'>%group</emphasis> syntax. If the ++ <emphasis remap='B'>%</emphasis> wildcard is used alone it is identical ++ to using <emphasis remap='B'>*</emphasis> with maxsyslogins limit. With ++ a group specified after <emphasis remap='B'>%</emphasis> it limits the total ++ number of logins of all users that are member of the group. ++ </para> ++ </listitem> ++ <listitem> ++ <para> ++ an uid range specified as <replaceable><min_uid></replaceable><emphasis ++ remap='B'>:</emphasis><replaceable><max_uid></replaceable>. If min_uid ++ is omitted, the match is exact for the max_uid. If max_uid is omitted, all ++ uids greater than or equal min_uid match. ++ </para> ++ </listitem> ++ <listitem> ++ <para> ++ a gid range specified as <emphasis ++ remap='B'>@</emphasis><replaceable><min_gid></replaceable><emphasis ++ remap='B'>:</emphasis><replaceable><max_gid></replaceable>. If min_gid ++ is omitted, the match is exact for the max_gid. If max_gid is omitted, all ++ gids greater than or equal min_gid match. For the exact match all groups including ++ the user's supplementary groups are examined. For the range matches only ++ the user's primary group is examined. ++ </para> ++ </listitem> ++ <listitem> ++ <para> ++ a gid specified as <emphasis ++ remap='B'>%:</emphasis><replaceable><gid></replaceable> applicable ++ to maxlogins limit only. It limits the total number of logins of all users ++ that are member of the group with the specified gid. + </para> + </listitem> + </itemizedlist> +@@ -182,7 +213,7 @@ + <varlistentry> + <term><option>maxsyslogins</option></term> + <listitem> +- <para>maximum number of logins on system</para> ++ <para>maximum number of all logins on system</para> + </listitem> + </varlistentry> + <varlistentry> +@@ -272,12 +303,15 @@ + </para> + <programlisting> + * soft core 0 +-* hard rss 10000 ++* hard nofile 512 + @student hard nproc 20 + @faculty soft nproc 20 + @faculty hard nproc 50 + ftp hard nproc 0 + @student - maxlogins 4 ++:123 hard cpu 5000 ++@500: soft cpu 10000 ++600:700 hard locks 10 + </programlisting> + </refsect1> + +Index: modules/pam_limits/pam_limits.c +=================================================================== +RCS file: /cvsroot/pam/Linux-PAM/modules/pam_limits/pam_limits.c,v +retrieving revision 1.48 +retrieving revision 1.49 +diff -u -p -r1.48 -r1.49 +--- modules/pam_limits/pam_limits.c 18 Nov 2010 09:37:32 -0000 1.48 ++++ modules/pam_limits/pam_limits.c 14 Dec 2010 08:40:40 -0000 1.49 +@@ -55,6 +55,12 @@ + #define LIMITS_DEF_DEFAULT 4 /* limit was set by an default entry */ + #define LIMITS_DEF_NONE 5 /* this limit was not set yet */ + ++#define LIMIT_RANGE_ERR -1 /* error in specified uid/gid range */ ++#define LIMIT_RANGE_NONE 0 /* no range specified */ ++#define LIMIT_RANGE_ONE 1 /* exact uid/gid specified (:max_uid)*/ ++#define LIMIT_RANGE_MIN 2 /* only minimum uid/gid specified (min_uid:) */ ++#define LIMIT_RANGE_MM 3 /* both min and max uid/gid specified (min_uid:max_uid) */ ++ + static const char *limits_def_names[] = { + "USER", + "GROUP", +@@ -520,8 +526,57 @@ process_limit (const pam_handle_t *pamh, + return; + } + +-static int parse_config_file(pam_handle_t *pamh, const char *uname, int ctrl, +- struct pam_limit_s *pl) ++static int ++parse_uid_range(pam_handle_t *pamh, const char *domain, ++ uid_t *min_uid, uid_t *max_uid) ++{ ++ const char *range = domain; ++ char *pmax; ++ char *endptr; ++ int rv = LIMIT_RANGE_MM; ++ ++ if ((pmax=strchr(range, ':')) == NULL) ++ return LIMIT_RANGE_NONE; ++ ++pmax; ++ ++ if (range[0] == '@' || range[0] == '%') ++ ++range; ++ ++ if (range[0] == ':') ++ rv = LIMIT_RANGE_ONE; ++ else { ++ errno = 0; ++ *min_uid = strtoul (range, &endptr, 10); ++ if (errno != 0 || (range == endptr) || *endptr != ':') { ++ pam_syslog(pamh, LOG_DEBUG, ++ "wrong min_uid/gid value in '%s'", domain); ++ return LIMIT_RANGE_ERR; ++ } ++ } ++ ++ if (*pmax == '\0') { ++ if (rv == LIMIT_RANGE_ONE) ++ return LIMIT_RANGE_ERR; ++ else ++ return LIMIT_RANGE_MIN; ++ } ++ ++ errno = 0; ++ *max_uid = strtoul (pmax, &endptr, 10); ++ if (errno != 0 || (pmax == endptr) || *endptr != '\0') { ++ pam_syslog(pamh, LOG_DEBUG, ++ "wrong max_uid/gid value in '%s'", domain); ++ return LIMIT_RANGE_ERR; ++ } ++ ++ if (rv == LIMIT_RANGE_ONE) ++ *min_uid = *max_uid; ++ return rv; ++} ++ ++static int ++parse_config_file(pam_handle_t *pamh, const char *uname, uid_t uid, gid_t gid, ++ int ctrl, struct pam_limit_s *pl) + { + FILE *fil; + char buf[LINE_LENGTH]; +@@ -543,8 +598,10 @@ static int parse_config_file(pam_handle_ + char item[LINE_LENGTH]; + char value[LINE_LENGTH]; + int i; ++ int rngtype; + size_t j; + char *tptr,*line; ++ uid_t min_uid = (uid_t)-1, max_uid = (uid_t)-1; + + line = buf; + /* skip the leading white space */ +@@ -572,6 +629,11 @@ static int parse_config_file(pam_handle_ + for(j=0; j < strlen(ltype); j++) + ltype[j]=tolower(ltype[j]); + ++ if ((rngtype=parse_uid_range(pamh, domain, &min_uid, &max_uid)) < 0) { ++ pam_syslog(pamh, LOG_WARNING, "invalid uid range '%s' - skipped", domain); ++ continue; ++ } ++ + if (i == 4) { /* a complete line */ + for(j=0; j < strlen(item); j++) + item[j]=tolower(item[j]); +@@ -581,47 +643,133 @@ static int parse_config_file(pam_handle_ + if (strcmp(uname, domain) == 0) /* this user have a limit */ + process_limit(pamh, LIMITS_DEF_USER, ltype, item, value, ctrl, pl); + else if (domain[0]=='@') { +- if (ctrl & PAM_DEBUG_ARG) { ++ if (ctrl & PAM_DEBUG_ARG) { + pam_syslog(pamh, LOG_DEBUG, + "checking if %s is in group %s", + uname, domain + 1); +- } +- if (pam_modutil_user_in_group_nam_nam(pamh, uname, domain+1)) +- process_limit(pamh, LIMITS_DEF_GROUP, ltype, item, value, ctrl, ++ } ++ switch(rngtype) { ++ case LIMIT_RANGE_NONE: ++ if (pam_modutil_user_in_group_nam_nam(pamh, uname, domain+1)) ++ process_limit(pamh, LIMITS_DEF_GROUP, ltype, item, value, ctrl, ++ pl); ++ break; ++ case LIMIT_RANGE_ONE: ++ if (pam_modutil_user_in_group_nam_gid(pamh, uname, (gid_t)max_uid)) ++ process_limit(pamh, LIMITS_DEF_GROUP, ltype, item, value, ctrl, + pl); ++ break; ++ case LIMIT_RANGE_MM: ++ if (gid > (gid_t)max_uid) ++ break; ++ /* fallthrough */ ++ case LIMIT_RANGE_MIN: ++ if (gid >= (gid_t)min_uid) ++ process_limit(pamh, LIMITS_DEF_GROUP, ltype, item, value, ctrl, ++ pl); ++ } + } else if (domain[0]=='%') { +- if (ctrl & PAM_DEBUG_ARG) { ++ if (ctrl & PAM_DEBUG_ARG) { + pam_syslog(pamh, LOG_DEBUG, + "checking if %s is in group %s", + uname, domain + 1); +- } +- if (strcmp(domain,"%") == 0) +- process_limit(pamh, LIMITS_DEF_ALL, ltype, item, value, ctrl, +- pl); +- else if (pam_modutil_user_in_group_nam_nam(pamh, uname, domain+1)) { +- strcpy(pl->login_group, domain+1); +- process_limit(pamh, LIMITS_DEF_ALLGROUP, ltype, item, value, ctrl, +- pl); + } +- } else if (strcmp(domain, "*") == 0) +- process_limit(pamh, LIMITS_DEF_DEFAULT, ltype, item, value, ctrl, +- pl); ++ switch(rngtype) { ++ case LIMIT_RANGE_NONE: ++ if (strcmp(domain,"%") == 0) ++ process_limit(pamh, LIMITS_DEF_ALL, ltype, item, value, ctrl, ++ pl); ++ else if (pam_modutil_user_in_group_nam_nam(pamh, uname, domain+1)) { ++ strcpy(pl->login_group, domain+1); ++ process_limit(pamh, LIMITS_DEF_ALLGROUP, ltype, item, value, ctrl, ++ pl); ++ } ++ break; ++ case LIMIT_RANGE_ONE: ++ if (pam_modutil_user_in_group_nam_gid(pamh, uname, (gid_t)max_uid)) { ++ struct group *grp; ++ grp = pam_modutil_getgrgid(pamh, (gid_t)max_uid); ++ strncpy(pl->login_group, grp->gr_name, sizeof(pl->login_group)); ++ pl->login_group[sizeof(pl->login_group)-1] = '\0'; ++ process_limit(pamh, LIMITS_DEF_ALLGROUP, ltype, item, value, ctrl, ++ pl); ++ } ++ break; ++ case LIMIT_RANGE_MIN: ++ case LIMIT_RANGE_MM: ++ pam_syslog(pamh, LOG_WARNING, "range unsupported for %%group matching - ignored"); ++ } ++ } else { ++ switch(rngtype) { ++ case LIMIT_RANGE_NONE: ++ if (strcmp(domain, "*") == 0) ++ process_limit(pamh, LIMITS_DEF_DEFAULT, ltype, item, value, ctrl, ++ pl); ++ break; ++ case LIMIT_RANGE_ONE: ++ if (uid != max_uid) ++ break; ++ /* fallthrough */ ++ case LIMIT_RANGE_MM: ++ if (uid > max_uid) ++ break; ++ /* fallthrough */ ++ case LIMIT_RANGE_MIN: ++ if (uid >= min_uid) ++ process_limit(pamh, LIMITS_DEF_USER, ltype, item, value, ctrl, pl); ++ } ++ } + } else if (i == 2 && ltype[0] == '-') { /* Probably a no-limit line */ + if (strcmp(uname, domain) == 0) { + if (ctrl & PAM_DEBUG_ARG) { + pam_syslog(pamh, LOG_DEBUG, "no limits for '%s'", uname); + } +- fclose(fil); +- return PAM_IGNORE; +- } else if (domain[0] == '@' && pam_modutil_user_in_group_nam_nam(pamh, uname, domain+1)) { ++ } else if (domain[0] == '@') { ++ switch(rngtype) { ++ case LIMIT_RANGE_NONE: ++ if (!pam_modutil_user_in_group_nam_nam(pamh, uname, domain+1)) ++ continue; /* next line */ ++ break; ++ case LIMIT_RANGE_ONE: ++ if (!pam_modutil_user_in_group_nam_gid(pamh, uname, (gid_t)max_uid)) ++ continue; /* next line */ ++ break; ++ case LIMIT_RANGE_MM: ++ if (gid > (gid_t)max_uid) ++ continue; /* next line */ ++ /* fallthrough */ ++ case LIMIT_RANGE_MIN: ++ if (gid < (gid_t)min_uid) ++ continue; /* next line */ ++ } + if (ctrl & PAM_DEBUG_ARG) { + pam_syslog(pamh, LOG_DEBUG, + "no limits for '%s' in group '%s'", + uname, domain+1); + } +- fclose(fil); +- return PAM_IGNORE; ++ } else { ++ switch(rngtype) { ++ case LIMIT_RANGE_NONE: ++ continue; /* next line */ ++ case LIMIT_RANGE_ONE: ++ if (uid != max_uid) ++ continue; /* next line */ ++ break; ++ case LIMIT_RANGE_MM: ++ if (uid > max_uid) ++ continue; /* next line */ ++ /* fallthrough */ ++ case LIMIT_RANGE_MIN: ++ if (uid >= min_uid) ++ break; ++ continue; /* next line */ ++ } ++ if (ctrl & PAM_DEBUG_ARG) { ++ pam_syslog(pamh, LOG_DEBUG, "no limits for '%s'", uname); ++ } + } ++ fclose(fil); ++ return PAM_IGNORE; + } else { + pam_syslog(pamh, LOG_WARNING, "invalid line '%s' - skipped", line); + } +@@ -731,7 +879,7 @@ pam_sm_open_session (pam_handle_t *pamh, + return PAM_ABORT; + } + +- retval = parse_config_file(pamh, pwd->pw_name, ctrl, pl); ++ retval = parse_config_file(pamh, pwd->pw_name, pwd->pw_uid, pwd->pw_gid, ctrl, pl); + if (retval == PAM_IGNORE) { + D(("the configuration file ('%s') has an applicable '<domain> -' entry", CONF_FILE)); + return PAM_SUCCESS; +@@ -755,7 +903,7 @@ pam_sm_open_session (pam_handle_t *pamh, + /* Parse the *.conf files. */ + for (i = 0; globbuf.gl_pathv[i] != NULL; i++) { + pl->conf_file = globbuf.gl_pathv[i]; +- retval = parse_config_file(pamh, pwd->pw_name, ctrl, pl); ++ retval = parse_config_file(pamh, pwd->pw_name, pwd->pw_uid, pwd->pw_gid, ctrl, pl); + if (retval == PAM_IGNORE) { + D(("the configuration file ('%s') has an applicable '<domain> -' entry", pl->conf_file)); + globfree(&globbuf); |