diff options
Diffstat (limited to 'modules/pam_limits')
-rw-r--r-- | modules/pam_limits/Makefile.in | 34 | ||||
-rw-r--r-- | modules/pam_limits/README | 1 | ||||
-rw-r--r-- | modules/pam_limits/limits.conf | 11 | ||||
-rw-r--r-- | modules/pam_limits/limits.conf.5 | 18 | ||||
-rw-r--r-- | modules/pam_limits/limits.conf.5.xml | 13 | ||||
-rw-r--r-- | modules/pam_limits/pam_limits.8 | 4 | ||||
-rw-r--r-- | modules/pam_limits/pam_limits.c | 98 |
7 files changed, 145 insertions, 34 deletions
diff --git a/modules/pam_limits/Makefile.in b/modules/pam_limits/Makefile.in index ac06d6c0..ac265081 100644 --- a/modules/pam_limits/Makefile.in +++ b/modules/pam_limits/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -96,18 +96,21 @@ host_triplet = @host@ @HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map subdir = modules/pam_limits ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/gettext.m4 \ - $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \ - $(top_srcdir)/m4/japhar_grep_cflags.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ + $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/intlmacosx.m4 \ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \ - $(top_srcdir)/m4/ld-no-undefined.m4 $(top_srcdir)/m4/lib-ld.m4 \ + $(top_srcdir)/m4/ld-no-undefined.m4 \ + $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \ - $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/configure.ac + $(top_srcdir)/m4/progtest.m4 \ + $(top_srcdir)/m4/warn_lang_flags.m4 \ + $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \ @@ -376,6 +379,7 @@ am__set_TESTS_bases = \ bases='$(TEST_LOGS)'; \ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ bases=`echo $$bases` +AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)' RECHECK_LOGS = $(TEST_LOGS) AM_RECURSIVE_TARGETS = check recheck TEST_SUITE_LOG = test-suite.log @@ -420,6 +424,9 @@ CC_FOR_BUILD = @CC_FOR_BUILD@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ +CRYPTO_LIBS = @CRYPTO_LIBS@ +CRYPT_CFLAGS = @CRYPT_CFLAGS@ +CRYPT_LIBS = @CRYPT_LIBS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ @@ -433,6 +440,8 @@ ECONF_CFLAGS = @ECONF_CFLAGS@ ECONF_LIBS = @ECONF_LIBS@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ +EXE_CFLAGS = @EXE_CFLAGS@ +EXE_LDFLAGS = @EXE_LDFLAGS@ FGREP = @FGREP@ FO2PDF = @FO2PDF@ GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ @@ -452,7 +461,6 @@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAUDIT = @LIBAUDIT@ -LIBCRACK = @LIBCRACK@ LIBCRYPT = @LIBCRYPT@ LIBDB = @LIBDB@ LIBDL = @LIBDL@ @@ -499,8 +507,6 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ -PIE_CFLAGS = @PIE_CFLAGS@ -PIE_LDFLAGS = @PIE_LDFLAGS@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -511,6 +517,7 @@ SECUREDIR = @SECUREDIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ +STRINGPARAM_HMAC = @STRINGPARAM_HMAC@ STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@ STRIP = @STRIP@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ @@ -560,7 +567,6 @@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ -libc_cv_fpie = @libc_cv_fpie@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ @@ -568,9 +574,6 @@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ -pam_cv_ld_O1 = @pam_cv_ld_O1@ -pam_cv_ld_as_needed = @pam_cv_ld_as_needed@ -pam_cv_ld_no_undefined = @pam_cv_ld_no_undefined@ pam_xauth_path = @pam_xauth_path@ pdfdir = @pdfdir@ prefix = @prefix@ @@ -580,6 +583,7 @@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ +systemdunitdir = @systemdunitdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ @@ -982,7 +986,7 @@ $(TEST_SUITE_LOG): $(TEST_LOGS) test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ fi; \ echo "$${col}$$br$${std}"; \ - echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ + echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \ echo "$${col}$$br$${std}"; \ create_testsuite_report --maybe-color; \ echo "$$col$$br$$std"; \ diff --git a/modules/pam_limits/README b/modules/pam_limits/README index 6aabd54f..ed104d62 100644 --- a/modules/pam_limits/README +++ b/modules/pam_limits/README @@ -62,6 +62,7 @@ limits.conf. @faculty hard nproc 50 ftp hard nproc 0 @student - maxlogins 4 +@student - nonewprivs 1 :123 hard cpu 5000 @500: soft cpu 10000 600:700 hard locks 10 diff --git a/modules/pam_limits/limits.conf b/modules/pam_limits/limits.conf index be621a7c..e8a746cc 100644 --- a/modules/pam_limits/limits.conf +++ b/modules/pam_limits/limits.conf @@ -1,5 +1,16 @@ # /etc/security/limits.conf # +#This file sets the resource limits for the users logged in via PAM. +#It does not affect resource limits of the system services. +# +#Also note that configuration files in /etc/security/limits.d directory, +#which are read in alphabetical order, override the settings in this +#file in case the domain is the same or more specific. +#That means, for example, that setting a limit for wildcard domain here +#can be overridden with a wildcard setting in a config file in the +#subdirectory, but a user specific setting here can be overridden only +#with a user specific setting in the subdirectory. +# #Each line describes a limit for a user in the form: # #<domain> <type> <item> <value> diff --git a/modules/pam_limits/limits.conf.5 b/modules/pam_limits/limits.conf.5 index f527fec8..a4a0ed31 100644 --- a/modules/pam_limits/limits.conf.5 +++ b/modules/pam_limits/limits.conf.5 @@ -2,12 +2,12 @@ .\" Title: limits.conf .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/> -.\" Date: 06/08/2020 +.\" Date: 09/03/2021 .\" Manual: Linux-PAM Manual .\" Source: Linux-PAM Manual .\" Language: English .\" -.TH "LIMITS\&.CONF" "5" "06/08/2020" "Linux-PAM Manual" "Linux\-PAM Manual" +.TH "LIMITS\&.CONF" "5" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -245,6 +245,11 @@ maximum number of all logins on system; user is not allowed to log\-in if total \fIuid=0\fR) .RE .PP +\fBnonewprivs\fR +.RS 4 +value of 0 or 1; if set to 1 disables acquiring new privileges by invoking prctl(PR_SET_NO_NEW_PRIVS) +.RE +.PP \fBpriority\fR .RS 4 the priority to run user process with (negative values boost process priority) @@ -282,9 +287,11 @@ All items support the values or \fIinfinity\fR indicating no limit, except for -\fBpriority\fR -and -\fBnice\fR\&. +\fBpriority\fR, +\fBnice\fR, and +\fBnonewprivs\fR\&. If +\fBnofile\fR +is to be set to one of these values, it will be set to the contents of /proc/sys/fs/nr_open instead (see setrlimit(3))\&. .PP If a hard limit or soft limit of a resource is set to a valid value, but outside of the supported range of the local system, the system may reject the new limit or unexpected behavior may occur\&. If the control value \fIrequired\fR @@ -321,6 +328,7 @@ These are some example lines which might be specified in @faculty hard nproc 50 ftp hard nproc 0 @student \- maxlogins 4 +@student \- nonewprivs 1 :123 hard cpu 5000 @500: soft cpu 10000 600:700 hard locks 10 diff --git a/modules/pam_limits/limits.conf.5.xml b/modules/pam_limits/limits.conf.5.xml index 380a1399..c5bd6768 100644 --- a/modules/pam_limits/limits.conf.5.xml +++ b/modules/pam_limits/limits.conf.5.xml @@ -228,6 +228,13 @@ </listitem> </varlistentry> <varlistentry> + <term><option>nonewprivs</option></term> + <listitem> + <para>value of 0 or 1; if set to 1 disables acquiring new + privileges by invoking prctl(PR_SET_NO_NEW_PRIVS)</para> + </listitem> + </varlistentry> + <varlistentry> <term><option>priority</option></term> <listitem> <para>the priority to run user process with (negative @@ -274,7 +281,10 @@ <para> All items support the values <emphasis>-1</emphasis>, <emphasis>unlimited</emphasis> or <emphasis>infinity</emphasis> indicating no limit, - except for <emphasis remap='B'>priority</emphasis> and <emphasis remap='B'>nice</emphasis>. + except for <emphasis remap='B'>priority</emphasis>, <emphasis remap='B'>nice</emphasis>, + and <emphasis remap='B'>nonewprivs</emphasis>. + If <emphasis remap='B'>nofile</emphasis> is to be set to one of these values, + it will be set to the contents of /proc/sys/fs/nr_open instead (see setrlimit(3)). </para> <para> If a hard limit or soft limit of a resource is set to a valid value, @@ -323,6 +333,7 @@ @faculty hard nproc 50 ftp hard nproc 0 @student - maxlogins 4 +@student - nonewprivs 1 :123 hard cpu 5000 @500: soft cpu 10000 600:700 hard locks 10 diff --git a/modules/pam_limits/pam_limits.8 b/modules/pam_limits/pam_limits.8 index fbbacc66..50e9a100 100644 --- a/modules/pam_limits/pam_limits.8 +++ b/modules/pam_limits/pam_limits.8 @@ -2,12 +2,12 @@ .\" Title: pam_limits .\" Author: [see the "AUTHORS" section] .\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/> -.\" Date: 06/08/2020 +.\" Date: 09/03/2021 .\" Manual: Linux-PAM Manual .\" Source: Linux-PAM Manual .\" Language: English .\" -.TH "PAM_LIMITS" "8" "06/08/2020" "Linux-PAM Manual" "Linux-PAM Manual" +.TH "PAM_LIMITS" "8" "09/03/2021" "Linux-PAM Manual" "Linux-PAM Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/modules/pam_limits/pam_limits.c b/modules/pam_limits/pam_limits.c index b791cdce..7cc45d77 100644 --- a/modules/pam_limits/pam_limits.c +++ b/modules/pam_limits/pam_limits.c @@ -28,6 +28,7 @@ #include <syslog.h> #include <stdarg.h> #include <signal.h> +#include <sys/prctl.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/resource.h> @@ -49,7 +50,7 @@ /* Module defines */ #define LINE_LENGTH 1024 -#define LIMITS_DEF_USER 0 /* limit was set by an user entry */ +#define LIMITS_DEF_USER 0 /* limit was set by a user entry */ #define LIMITS_DEF_GROUP 1 /* limit was set by a group entry */ #define LIMITS_DEF_ALLGROUP 2 /* limit was set by a group entry */ #define LIMITS_DEF_ALL 3 /* limit was set by an all entry */ @@ -88,6 +89,7 @@ struct pam_limit_s { int flag_numsyslogins; /* whether to limit logins only for a specific user or to count all logins */ int priority; /* the priority to run user process with */ + int nonewprivs; /* whether to prctl(PR_SET_NO_NEW_PRIVS) */ struct user_limits_struct limits[RLIM_NLIMITS]; const char *conf_file; int utmp_after_pam_call; @@ -98,6 +100,7 @@ struct pam_limit_s { #define LIMIT_NUMSYSLOGINS RLIM_NLIMITS+2 #define LIMIT_PRI RLIM_NLIMITS+3 +#define LIMIT_NONEWPRIVS RLIM_NLIMITS+4 #define LIMIT_SOFT 1 #define LIMIT_HARD 2 @@ -484,6 +487,41 @@ static int init_limits(pam_handle_t *pamh, struct pam_limit_s *pl, int ctrl) return retval; } +/* + * Read the contents of <pathname> and return it in *valuep + * return 1 if conversion succeeds, result is in *valuep + * return 0 if conversion fails, *valuep is untouched. + */ +static int +value_from_file(const char *pathname, rlim_t *valuep) +{ + char buf[128]; + FILE *fp; + int retval; + + retval = 0; + + if ((fp = fopen(pathname, "r")) != NULL) { + if (fgets(buf, sizeof(buf), fp) != NULL) { + char *endptr; + unsigned long long value; + + errno = 0; + value = strtoull(buf, &endptr, 10); + if (endptr != buf && + (value != ULLONG_MAX || errno == 0) && + (unsigned long long) (rlim_t) value == value) { + *valuep = (rlim_t) value; + retval = 1; + } + } + + fclose(fp); + } + + return retval; +} + static void process_limit (const pam_handle_t *pamh, int source, const char *lim_type, const char *lim_item, const char *lim_value, @@ -551,6 +589,8 @@ process_limit (const pam_handle_t *pamh, int source, const char *lim_type, pl->flag_numsyslogins = 1; } else if (strcmp(lim_item, "priority") == 0) { limit_item = LIMIT_PRI; + } else if (strcmp(lim_item, "nonewprivs") == 0) { + limit_item = LIMIT_NONEWPRIVS; } else { pam_syslog(pamh, LOG_DEBUG, "unknown limit item '%s'", lim_item); return; @@ -562,11 +602,23 @@ process_limit (const pam_handle_t *pamh, int source, const char *lim_type, limit_type=LIMIT_HARD; else if (strcmp(lim_type,"-")==0) limit_type=LIMIT_SOFT | LIMIT_HARD; - else if (limit_item != LIMIT_LOGIN && limit_item != LIMIT_NUMSYSLOGINS) { + else if (limit_item != LIMIT_LOGIN && limit_item != LIMIT_NUMSYSLOGINS + && limit_item != LIMIT_NONEWPRIVS) { pam_syslog(pamh, LOG_DEBUG, "unknown limit type '%s'", lim_type); return; } - if (limit_item != LIMIT_PRI + if (limit_item == LIMIT_NONEWPRIVS) { + /* just require a bool-style 0 or 1 */ + if (strcmp(lim_value, "0") == 0) { + int_value = 0; + } else if (strcmp(lim_value, "1") == 0) { + int_value = 1; + } else { + pam_syslog(pamh, LOG_DEBUG, + "wrong limit value '%s' for limit type '%s'", + lim_value, lim_type); + } + } else if (limit_item != LIMIT_PRI #ifdef RLIMIT_NICE && limit_item != RLIMIT_NICE #endif @@ -649,11 +701,26 @@ process_limit (const pam_handle_t *pamh, int source, const char *lim_type, rlimit_value = 20 - int_value; break; #endif + case RLIMIT_NOFILE: + /* + * If nofile is to be set to "unlimited", try to set it to + * the value in /proc/sys/fs/nr_open instead. + */ + if (rlimit_value == RLIM_INFINITY) { + if (!value_from_file("/proc/sys/fs/nr_open", &rlimit_value)) + pam_syslog(pamh, LOG_WARNING, + "Cannot set \"nofile\" to a sensible value"); + else if (ctrl & PAM_DEBUG_ARG) + pam_syslog(pamh, LOG_DEBUG, "Setting \"nofile\" limit to %llu", + (unsigned long long) rlimit_value); + } + break; } if ( (limit_item != LIMIT_LOGIN) && (limit_item != LIMIT_NUMSYSLOGINS) - && (limit_item != LIMIT_PRI) ) { + && (limit_item != LIMIT_PRI) + && (limit_item != LIMIT_NONEWPRIVS) ) { if (limit_type & LIMIT_SOFT) { if (pl->limits[limit_item].src_soft < source) { return; @@ -674,14 +741,16 @@ process_limit (const pam_handle_t *pamh, int source, const char *lim_type, /* recent kernels support negative priority limits (=raise priority) */ if (limit_item == LIMIT_PRI) { - pl->priority = int_value; + pl->priority = int_value; + } else if (limit_item == LIMIT_NONEWPRIVS) { + pl->nonewprivs = int_value; } else { - if (pl->login_limit_def < source) { - return; - } else { - pl->login_limit = int_value; - pl->login_limit_def = source; - } + if (pl->login_limit_def < source) { + return; + } else { + pl->login_limit = int_value; + pl->login_limit_def = source; + } } } return; @@ -995,6 +1064,13 @@ static int setup_limits(pam_handle_t *pamh, retval |= LOGIN_ERR; } + if (pl->nonewprivs) { + if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) { + pam_syslog(pamh, LOG_ERR, "Could not set prctl(PR_SET_NO_NEW_PRIVS): %m"); + retval |= LIMIT_ERR; + } + } + return retval; } |