summaryrefslogtreecommitdiff
path: root/Linux-PAM/modules/pam_limits
diff options
context:
space:
mode:
authorSteve Langasek <steve.langasek@ubuntu.com>2019-01-03 15:43:05 -0800
committerSteve Langasek <steve.langasek@ubuntu.com>2019-01-03 15:44:43 -0800
commit9a4298687784e7812c8aeef6e0e97830febbf393 (patch)
tree45942549c91c2ae3cb6b58aa5df40b9e121f908a /Linux-PAM/modules/pam_limits
parentd5b06b67bbeeed7c05c0eb2e05d6a972ad050d1c (diff)
parent9bc383eeb9d9f5976645cb4c4850a8d36b2bd7da (diff)
New upstream version 0.99.8.1
Diffstat (limited to 'Linux-PAM/modules/pam_limits')
-rw-r--r--Linux-PAM/modules/pam_limits/Makefile.am4
-rw-r--r--Linux-PAM/modules/pam_limits/README7
-rw-r--r--Linux-PAM/modules/pam_limits/limits.conf2
-rw-r--r--Linux-PAM/modules/pam_limits/limits.conf.5120
-rw-r--r--Linux-PAM/modules/pam_limits/limits.conf.5.xml2
-rw-r--r--Linux-PAM/modules/pam_limits/pam_limits.862
-rw-r--r--Linux-PAM/modules/pam_limits/pam_limits.8.xml10
-rw-r--r--Linux-PAM/modules/pam_limits/pam_limits.c95
8 files changed, 226 insertions, 76 deletions
diff --git a/Linux-PAM/modules/pam_limits/Makefile.am b/Linux-PAM/modules/pam_limits/Makefile.am
index be2852a9..60256a7c 100644
--- a/Linux-PAM/modules/pam_limits/Makefile.am
+++ b/Linux-PAM/modules/pam_limits/Makefile.am
@@ -13,8 +13,10 @@ TESTS = tst-pam_limits
securelibdir = $(SECUREDIR)
secureconfdir = $(SCONFIGDIR)
+limits_conf_dir = $(SCONFIGDIR)/limits.d
AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ -DLIMITS_FILE_DIR=\"$(limits_conf_dir)/*.conf\" \
-DLIMITS_FILE=\"$(SCONFIGDIR)/limits.conf\"
AM_LDFLAGS = -no-undefined -avoid-version -module \
-L$(top_builddir)/libpam -lpam
@@ -32,3 +34,5 @@ README: pam_limits.8.xml limits.conf.5.xml
-include $(top_srcdir)/Make.xml.rules
endif
+install-data-local:
+ mkdir -p $(DESTDIR)$(limits_conf_dir)
diff --git a/Linux-PAM/modules/pam_limits/README b/Linux-PAM/modules/pam_limits/README
index adab19df..26336711 100644
--- a/Linux-PAM/modules/pam_limits/README
+++ b/Linux-PAM/modules/pam_limits/README
@@ -8,6 +8,13 @@ The pam_limits PAM module sets limits on the system resources that can be
obtained in a user-session. Users of uid=0 are affected by this limits, too.
By default limits are taken from the /etc/security/limits.conf config file.
+Then individual files from the /etc/security/limits.d/ directory are read. The
+files are parsed one after another in the order of "C" locale. The effect of
+the individual files is the same as if all the files were concatenated together
+in the order of parsing. If a config file is explicitely specified with a
+module option then the files in the above directory are not parsed.
+
+The module must not be called by a multithreaded application.
OPTIONS
diff --git a/Linux-PAM/modules/pam_limits/limits.conf b/Linux-PAM/modules/pam_limits/limits.conf
index c52778b1..d3463638 100644
--- a/Linux-PAM/modules/pam_limits/limits.conf
+++ b/Linux-PAM/modules/pam_limits/limits.conf
@@ -26,7 +26,7 @@
# - stack - max stack size (KB)
# - cpu - max CPU time (MIN)
# - nproc - max number of processes
-# - as - address space limit
+# - as - address space limit (KB)
# - maxlogins - max number of logins for this user
# - maxsyslogins - max number of logins on the system
# - priority - the priority to run user process with
diff --git a/Linux-PAM/modules/pam_limits/limits.conf.5 b/Linux-PAM/modules/pam_limits/limits.conf.5
index e6ba853f..3cf62f26 100644
--- a/Linux-PAM/modules/pam_limits/limits.conf.5
+++ b/Linux-PAM/modules/pam_limits/limits.conf.5
@@ -1,11 +1,11 @@
.\" Title: limits.conf
.\" Author:
-.\" Generator: DocBook XSL Stylesheets v1.70.1 <http://docbook.sf.net/>
-.\" Date: 06/22/2006
+.\" Generator: DocBook XSL Stylesheets v1.71.1 <http://docbook.sf.net/>
+.\" Date: 04/30/2007
.\" Manual: Linux\-PAM Manual
.\" Source: Linux\-PAM Manual
.\"
-.TH "LIMITS.CONF" "5" "06/22/2006" "Linux\-PAM Manual" "Linux\-PAM Manual"
+.TH "LIMITS.CONF" "5" "04/30/2007" "Linux\-PAM Manual" "Linux\-PAM Manual"
.\" disable hyphenation
.nh
.\" disable justification (adjust text to left margin only)
@@ -23,38 +23,44 @@ The syntax of the lines is as follows:
\fI<value>\fR
.PP
The fields listed above should be filled as follows:
-.TP 3n
+.PP
\fB<domain>\fR
-.RS 3n
-.TP 3n
+.RS 4
+.RS 4
+.TP 4
\(bu
a username
-.TP 3n
+.TP 4
\(bu
a groupname, with
\fB@group\fR
syntax. This should not be confused with netgroups.
-.TP 3n
+.TP 4
\(bu
the wildcard
\fB*\fR, for default entry.
-.TP 3n
+.TP 4
\(bu
the wildcard
\fB%\fR, for maxlogins limit only, can also be used with
\fI%group\fR
syntax.
.RE
-.TP 3n
+.RE
+.PP
\fB<type>\fR
-.RS 3n
-.TP 3n
+.RS 4
+.RS 4
+.PP
\fBhard\fR
+.RS 4
for enforcing
\fBhard\fR
resource limits. These limits are set by the superuser and enforced by the Kernel. The user cannot raise his requirement of system resources above such values.
-.TP 3n
+.RE
+.PP
\fBsoft\fR
+.RS 4
for enforcing
\fBsoft\fR
resource limits. These limits are ones that the user can move up or down within the permitted range by any pre\-exisiting
@@ -62,8 +68,10 @@ resource limits. These limits are ones that the user can move up or down within
limits. The values specified with this token can be thought of as
\fIdefault\fR
values, for normal system usage.
-.TP 3n
+.RE
+.PP
\fB\-\fR
+.RS 4
for enforcing both
\fBsoft\fR
and
@@ -72,64 +80,104 @@ resource limits together.
.sp
Note, if you specify a type of '\-' but neglect to supply the item and value fields then the module will never enforce any limits on the specified user/group etc. .
.RE
-.TP 3n
+.RE
+.RE
+.PP
\fB<item>\fR
-.RS 3n
-.TP 3n
+.RS 4
+.RS 4
+.PP
\fBcore\fR
+.RS 4
limits the core file size (KB)
-.TP 3n
+.RE
+.PP
\fBdata\fR
+.RS 4
maximum data size (KB)
-.TP 3n
+.RE
+.PP
\fBfsize\fR
+.RS 4
maximum filesize (KB)
-.TP 3n
+.RE
+.PP
\fBmemlock\fR
+.RS 4
maximum locked\-in\-memory address space (KB)
-.TP 3n
+.RE
+.PP
\fBnofile\fR
+.RS 4
maximum number of open files
-.TP 3n
+.RE
+.PP
\fBrss\fR
+.RS 4
maximum resident set size (KB)
-.TP 3n
+.RE
+.PP
\fBstack\fR
+.RS 4
maximum stack size (KB)
-.TP 3n
+.RE
+.PP
\fBcpu\fR
+.RS 4
maximum CPU time (minutes)
-.TP 3n
+.RE
+.PP
\fBnproc\fR
+.RS 4
maximum number of processes
-.TP 3n
+.RE
+.PP
\fBas\fR
-address space limit
-.TP 3n
+.RS 4
+address space limit (KB)
+.RE
+.PP
\fBmaxlogins\fR
+.RS 4
maximum number of logins for this user
-.TP 3n
+.RE
+.PP
\fBmaxsyslogins\fR
+.RS 4
maximum number of logins on system
-.TP 3n
+.RE
+.PP
\fBpriority\fR
+.RS 4
the priority to run user process with (negative values boost process priority)
-.TP 3n
+.RE
+.PP
\fBlocks\fR
+.RS 4
maximum locked files (Linux 2.4 and higher)
-.TP 3n
+.RE
+.PP
\fBsigpending\fR
+.RS 4
maximum number of pending signals (Linux 2.6 and higher)
-.TP 3n
+.RE
+.PP
\fBmsqqueue\fR
+.RS 4
maximum memory used by POSIX message queues (bytes) (Linux 2.6 and higher)
-.TP 3n
+.RE
+.PP
\fBnice\fR
+.RS 4
maximum nice priority allowed to raise to (Linux 2.6.12 and higher)
-.TP 3n
+.RE
+.PP
\fBrtprio\fR
+.RS 4
maximum realtime priority allowed for non\-privileged processes (Linux 2.6.12 and higher)
.RE
+.RE
+.RE
.PP
In general, individual limits have priority over group limits, so if you impose no limits for
\fIadmin\fR
@@ -149,7 +197,7 @@ The pam_limits module does its best to report configuration problems found in it
These are some example lines which might be specified in
\fI/etc/security/limits.conf\fR.
.sp
-.RS 3n
+.RS 4
.nf
* soft core 0
* hard rss 10000
diff --git a/Linux-PAM/modules/pam_limits/limits.conf.5.xml b/Linux-PAM/modules/pam_limits/limits.conf.5.xml
index 28df7381..830aa022 100644
--- a/Linux-PAM/modules/pam_limits/limits.conf.5.xml
+++ b/Linux-PAM/modules/pam_limits/limits.conf.5.xml
@@ -169,7 +169,7 @@
<varlistentry>
<term><option>as</option></term>
<listitem>
- <para>address space limit</para>
+ <para>address space limit (KB)</para>
</listitem>
</varlistentry>
<varlistentry>
diff --git a/Linux-PAM/modules/pam_limits/pam_limits.8 b/Linux-PAM/modules/pam_limits/pam_limits.8
index 9083e14d..4f01e4cf 100644
--- a/Linux-PAM/modules/pam_limits/pam_limits.8
+++ b/Linux-PAM/modules/pam_limits/pam_limits.8
@@ -1,11 +1,11 @@
.\" Title: pam_limits
.\" Author:
-.\" Generator: DocBook XSL Stylesheets v1.70.1 <http://docbook.sf.net/>
-.\" Date: 06/17/2006
+.\" Generator: DocBook XSL Stylesheets v1.71.1 <http://docbook.sf.net/>
+.\" Date: 04/30/2007
.\" Manual: Linux\-PAM Manual
.\" Source: Linux\-PAM Manual
.\"
-.TH "PAM_LIMITS" "8" "06/17/2006" "Linux\-PAM Manual" "Linux\-PAM Manual"
+.TH "PAM_LIMITS" "8" "04/30/2007" "Linux\-PAM Manual" "Linux\-PAM Manual"
.\" disable hyphenation
.nh
.\" disable justification (adjust text to left margin only)
@@ -23,58 +23,86 @@ are affected by this limits, too.
.PP
By default limits are taken from the
\fI/etc/security/limits.conf\fR
-config file.
+config file. Then individual files from the
+\fI/etc/security/limits.d/\fR
+directory are read. The files are parsed one after another in the order of "C" locale. The effect of the individual files is the same as if all the files were concatenated together in the order of parsing. If a config file is explicitely specified with a module option then the files in the above directory are not parsed.
+.PP
+The module must not be called by a multithreaded application.
.SH "OPTIONS"
-.TP 3n
+.PP
\fBchange_uid\fR
+.RS 4
Change real uid to the user for who the limits are set up. Use this option if you have problems like login not forking a shell for user who has no processes. Be warned that something else may break when you do this.
-.TP 3n
+.RE
+.PP
\fBconf=\fR\fB\fI/path/to/limits.conf\fR\fR
+.RS 4
Indicate an alternative limits.conf style configuration file to override the default.
-.TP 3n
+.RE
+.PP
\fBdebug\fR
+.RS 4
Print debug information.
-.TP 3n
+.RE
+.PP
\fButmp_early\fR
+.RS 4
Some broken applications actually allocate a utmp entry for the user before the user is admitted to the system. If some of the services you are configuring PAM for do this, you can selectively use this module argument to compensate for this behavior and at the same time maintain system\-wide consistency with a single limits.conf file.
+.RE
.SH "MODULE SERVICES PROVIDED"
.PP
Only the
\fBsession\fR
service is supported.
.SH "RETURN VALUES"
-.TP 3n
+.PP
PAM_ABORT
+.RS 4
Cannot get current limits.
-.TP 3n
+.RE
+.PP
PAM_IGNORE
+.RS 4
No limits found for this user.
-.TP 3n
+.RE
+.PP
PAM_PERM_DENIED
+.RS 4
New limits could not be set.
-.TP 3n
+.RE
+.PP
PAM_SERVICE_ERR
+.RS 4
Cannot read config file.
-.TP 3n
+.RE
+.PP
PAM_SESSEION_ERR
+.RS 4
Error recovering account name.
-.TP 3n
+.RE
+.PP
PAM_SUCCESS
+.RS 4
Limits were changed.
-.TP 3n
+.RE
+.PP
PAM_USER_UNKNOWN
+.RS 4
The user is not known to the system.
+.RE
.SH "FILES"
-.TP 3n
+.PP
\fI/etc/security/limits.conf\fR
+.RS 4
Default configuration file
+.RE
.SH "EXAMPLES"
.PP
For the services you need resources limits (login for example) put a the following line in
\fI/etc/pam.d/login\fR
as the last line for that service (usually after the pam_unix session line):
.sp
-.RS 3n
+.RS 4
.nf
#%PAM\-1.0
#
diff --git a/Linux-PAM/modules/pam_limits/pam_limits.8.xml b/Linux-PAM/modules/pam_limits/pam_limits.8.xml
index 78060a20..9f13bb68 100644
--- a/Linux-PAM/modules/pam_limits/pam_limits.8.xml
+++ b/Linux-PAM/modules/pam_limits/pam_limits.8.xml
@@ -47,7 +47,15 @@
</para>
<para>
By default limits are taken from the <filename>/etc/security/limits.conf</filename>
- config file.
+ config file. Then individual files from the <filename>/etc/security/limits.d/</filename>
+ directory are read. The files are parsed one after another in the order of "C" locale.
+ The effect of the individual files is the same as if all the files were
+ concatenated together in the order of parsing.
+ If a config file is explicitely specified with a module option then the
+ files in the above directory are not parsed.
+ </para>
+ <para>
+ The module must not be called by a multithreaded application.
</para>
</refsect1>
diff --git a/Linux-PAM/modules/pam_limits/pam_limits.c b/Linux-PAM/modules/pam_limits/pam_limits.c
index 20aa794a..a4bc727f 100644
--- a/Linux-PAM/modules/pam_limits/pam_limits.c
+++ b/Linux-PAM/modules/pam_limits/pam_limits.c
@@ -31,7 +31,7 @@
#include <sys/stat.h>
#include <sys/resource.h>
#include <limits.h>
-
+#include <glob.h>
#include <utmp.h>
#ifndef UT_USER /* some systems have ut_name instead of ut_user */
#define UT_USER ut_user
@@ -39,6 +39,7 @@
#include <grp.h>
#include <pwd.h>
+#include <locale.h>
/* Module defines */
#define LINE_LENGTH 1024
@@ -75,7 +76,7 @@ struct pam_limit_s {
specific user or to count all logins */
int priority; /* the priority to run user process with */
struct user_limits_struct limits[RLIM_NLIMITS];
- char conf_file[BUFSIZ];
+ const char *conf_file;
int utmp_after_pam_call;
char login_group[LINE_LENGTH];
};
@@ -101,6 +102,11 @@ struct pam_limit_s {
#define PAM_DO_SETREUID 0x0002
#define PAM_UTMP_EARLY 0x0004
+/* Limits from globbed files. */
+#define LIMITS_CONF_GLOB LIMITS_FILE_DIR
+
+#define CONF_FILE (pl->conf_file != NULL)?pl->conf_file:LIMITS_FILE
+
static int
_pam_parse (const pam_handle_t *pamh, int argc, const char **argv,
struct pam_limit_s *pl)
@@ -115,7 +121,7 @@ _pam_parse (const pam_handle_t *pamh, int argc, const char **argv,
if (!strcmp(*argv,"debug")) {
ctrl |= PAM_DEBUG_ARG;
} else if (!strncmp(*argv,"conf=",5)) {
- strncpy(pl->conf_file,*argv+5,sizeof(pl->conf_file)-1);
+ pl->conf_file = *argv+5;
} else if (!strncmp(*argv,"change_uid",10)) {
ctrl |= PAM_DO_SETREUID;
} else if (!strcmp(*argv,"utmp_early")) {
@@ -124,7 +130,6 @@ _pam_parse (const pam_handle_t *pamh, int argc, const char **argv,
pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv);
}
}
- pl->conf_file[sizeof(pl->conf_file) - 1] = '\0';
return ctrl;
}
@@ -370,8 +375,13 @@ process_limit (const pam_handle_t *pamh, int source, const char *lim_type,
switch(limit_item) {
case RLIMIT_CPU:
- if (rlimit_value != RLIM_INFINITY)
- rlimit_value *= 60;
+ if (rlimit_value != RLIM_INFINITY)
+ {
+ if (rlimit_value >= RLIM_INFINITY/60)
+ rlimit_value = RLIM_INFINITY;
+ else
+ rlimit_value *= 60;
+ }
break;
case RLIMIT_FSIZE:
case RLIMIT_DATA:
@@ -381,13 +391,20 @@ process_limit (const pam_handle_t *pamh, int source, const char *lim_type,
case RLIMIT_MEMLOCK:
case RLIMIT_AS:
if (rlimit_value != RLIM_INFINITY)
- rlimit_value *= 1024;
+ {
+ if (rlimit_value >= RLIM_INFINITY/1024)
+ rlimit_value = RLIM_INFINITY;
+ else
+ rlimit_value *= 1024;
+ }
break;
#ifdef RLIMIT_NICE
case RLIMIT_NICE:
if (int_value > 19)
int_value = 19;
- rlimit_value = 19 - int_value;
+ if (int_value < -20)
+ int_value = -20;
+ rlimit_value = 20 - int_value;
#endif
break;
}
@@ -434,7 +451,6 @@ static int parse_config_file(pam_handle_t *pamh, const char *uname, int ctrl,
FILE *fil;
char buf[LINE_LENGTH];
-#define CONF_FILE (pl->conf_file[0])?pl->conf_file:LIMITS_FILE
/* check for the LIMITS_FILE */
if (ctrl & PAM_DEBUG_ARG)
pam_syslog(pamh, LOG_DEBUG, "reading settings from '%s'", CONF_FILE);
@@ -444,7 +460,6 @@ static int parse_config_file(pam_handle_t *pamh, const char *uname, int ctrl,
"cannot read settings from %s: %m", CONF_FILE);
return PAM_SERVICE_ERR;
}
-#undef CONF_FILE
/* init things */
memset(buf, 0, sizeof(buf));
@@ -599,16 +614,22 @@ pam_sm_open_session (pam_handle_t *pamh, int flags UNUSED,
int argc, const char **argv)
{
int retval;
+ int i;
+ int glob_rc;
char *user_name;
struct passwd *pwd;
int ctrl;
- struct pam_limit_s pl;
+ struct pam_limit_s plstruct;
+ struct pam_limit_s *pl = &plstruct;
+ glob_t globbuf;
+ const char *oldlocale;
D(("called."));
- memset(&pl, 0, sizeof(pl));
+ memset(pl, 0, sizeof(*pl));
+ memset(&globbuf, 0, sizeof(globbuf));
- ctrl = _pam_parse(pamh, argc, argv, &pl);
+ ctrl = _pam_parse(pamh, argc, argv, pl);
retval = pam_get_item( pamh, PAM_USER, (void*) &user_name );
if ( user_name == NULL || retval != PAM_SUCCESS ) {
pam_syslog(pamh, LOG_CRIT, "open_session - error recovering username");
@@ -623,26 +644,60 @@ pam_sm_open_session (pam_handle_t *pamh, int flags UNUSED,
return PAM_USER_UNKNOWN;
}
- retval = init_limits(&pl);
+ retval = init_limits(pl);
if (retval != PAM_SUCCESS) {
pam_syslog(pamh, LOG_WARNING, "cannot initialize");
return PAM_ABORT;
}
- retval = parse_config_file(pamh, pwd->pw_name, ctrl, &pl);
+ retval = parse_config_file(pamh, pwd->pw_name, ctrl, pl);
if (retval == PAM_IGNORE) {
- D(("the configuration file has an applicable '<domain> -' entry"));
+ D(("the configuration file ('%s') has an applicable '<domain> -' entry", CONF_FILE));
return PAM_SUCCESS;
}
- if (retval != PAM_SUCCESS) {
- pam_syslog(pamh, LOG_WARNING, "error parsing the configuration file");
- return retval;
+ if (retval != PAM_SUCCESS || pl->conf_file != NULL)
+ /* skip reading limits.d if config file explicitely specified */
+ goto out;
+
+ /* Read subsequent *.conf files, if they exist. */
+
+ /* set the LC_COLLATE so the sorting order doesn't depend
+ on system locale */
+
+ oldlocale = setlocale(LC_COLLATE, "C");
+ glob_rc = glob(LIMITS_CONF_GLOB, GLOB_ERR, NULL, &globbuf);
+
+ if (oldlocale != NULL)
+ setlocale (LC_COLLATE, oldlocale);
+
+ if (!glob_rc) {
+ /* 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);
+ if (retval == PAM_IGNORE) {
+ D(("the configuration file ('%s') has an applicable '<domain> -' entry", pl->conf_file));
+ globfree(&globbuf);
+ return PAM_SUCCESS;
+ }
+ if (retval != PAM_SUCCESS)
+ goto out;
+ }
+ }
+
+out:
+ globfree(&globbuf);
+ if (retval != PAM_SUCCESS)
+ {
+ pam_syslog(pamh, LOG_WARNING, "error parsing the configuration file: '%s' ",CONF_FILE);
+ return retval;
}
if (ctrl & PAM_DO_SETREUID) {
setreuid(pwd->pw_uid, -1);
}
- retval = setup_limits(pamh, pwd->pw_name, pwd->pw_uid, ctrl, &pl);
+
+ retval = setup_limits(pamh, pwd->pw_name, pwd->pw_uid, ctrl, pl);
if (retval & LOGIN_ERR)
pam_error(pamh, _("Too many logins for '%s'."), pwd->pw_name);
if (retval != LIMITED_OK) {