summaryrefslogtreecommitdiff
path: root/modules/pam_limits
diff options
context:
space:
mode:
authorSteve Langasek <steve.langasek@ubuntu.com>2019-01-03 16:26:05 -0800
committerSteve Langasek <steve.langasek@ubuntu.com>2019-01-03 17:26:38 -0800
commit9c52e721044e7501c3d4567b36d222dc7326224a (patch)
tree9011790770130c60a712a6f125ad50d60e07cc74 /modules/pam_limits
parent9727ff2a3fa0e94a42b34a579027bacf4146d571 (diff)
parent186ff16e8d12ff15d518000c17f115ccab5275a4 (diff)
New upstream version 1.0.1
Diffstat (limited to 'modules/pam_limits')
-rw-r--r--modules/pam_limits/Makefile.am38
-rw-r--r--modules/pam_limits/Makefile.in744
-rw-r--r--modules/pam_limits/README64
-rw-r--r--modules/pam_limits/README.xml39
-rw-r--r--modules/pam_limits/limits.conf50
-rw-r--r--modules/pam_limits/limits.conf.5219
-rw-r--r--modules/pam_limits/limits.conf.5.xml287
-rw-r--r--modules/pam_limits/pam_limits.8132
-rw-r--r--modules/pam_limits/pam_limits.8.xml256
-rw-r--r--modules/pam_limits/pam_limits.c777
-rwxr-xr-xmodules/pam_limits/tst-pam_limits2
11 files changed, 2608 insertions, 0 deletions
diff --git a/modules/pam_limits/Makefile.am b/modules/pam_limits/Makefile.am
new file mode 100644
index 00000000..13232ea6
--- /dev/null
+++ b/modules/pam_limits/Makefile.am
@@ -0,0 +1,38 @@
+#
+# Copyright (c) 2005, 2006 Thorsten Kukuk <kukuk@suse.de>
+#
+
+CLEANFILES = *~
+
+EXTRA_DIST = README $(MANS) $(XMLS) limits.conf tst-pam_limits
+
+man_MANS = limits.conf.5 pam_limits.8
+XMLS = README.xml limits.conf.5.xml pam_limits.8.xml
+
+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
+if HAVE_VERSIONING
+ AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+
+securelib_LTLIBRARIES = pam_limits.la
+pam_limits_la_LIBADD = -L$(top_builddir)/libpam -lpam
+
+secureconf_DATA = limits.conf
+
+if ENABLE_REGENERATE_MAN
+noinst_DATA = README
+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/modules/pam_limits/Makefile.in b/modules/pam_limits/Makefile.in
new file mode 100644
index 00000000..97f38f65
--- /dev/null
+++ b/modules/pam_limits/Makefile.in
@@ -0,0 +1,744 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2005, 2006 Thorsten Kukuk <kukuk@suse.de>
+#
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
+subdir = modules/pam_limits
+DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/gettext.m4 \
+ $(top_srcdir)/m4/iconv.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/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libprelude.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man5dir)" \
+ "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(secureconfdir)"
+securelibLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(securelib_LTLIBRARIES)
+pam_limits_la_DEPENDENCIES =
+pam_limits_la_SOURCES = pam_limits.c
+pam_limits_la_OBJECTS = pam_limits.lo
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = pam_limits.c
+DIST_SOURCES = pam_limits.c
+man5dir = $(mandir)/man5
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(man_MANS)
+secureconfDATA_INSTALL = $(INSTALL_DATA)
+DATA = $(noinst_DATA) $(secureconf_DATA)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FO2PDF = @FO2PDF@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+HAVE_KEY_MANAGEMENT = @HAVE_KEY_MANAGEMENT@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRACK = @LIBCRACK@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBNSL = @LIBNSL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PAM_READ_BOTH_CONFS = @PAM_READ_BOTH_CONFS@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PIE_CFLAGS = @PIE_CFLAGS@
+PIE_LDFLAGS = @PIE_LDFLAGS@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WITH_DEBUG = @WITH_DEBUG@
+WITH_PAMLOCKING = @WITH_PAMLOCKING@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libc_cv_fpie = @libc_cv_fpie@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_cv_ld_as_needed = @pam_cv_ld_as_needed@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+CLEANFILES = *~
+EXTRA_DIST = README $(MANS) $(XMLS) limits.conf tst-pam_limits
+man_MANS = limits.conf.5 pam_limits.8
+XMLS = README.xml limits.conf.5.xml pam_limits.8.xml
+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 $(am__append_1)
+securelib_LTLIBRARIES = pam_limits.la
+pam_limits_la_LIBADD = -L$(top_builddir)/libpam -lpam
+secureconf_DATA = limits.conf
+@ENABLE_REGENERATE_MAN_TRUE@noinst_DATA = README
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_limits/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_limits/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(securelibdir)" || $(MKDIR_P) "$(DESTDIR)$(securelibdir)"
+ @list='$(securelib_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(securelibLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(securelibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(securelibLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(securelibdir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-securelibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelib_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$p"; \
+ done
+
+clean-securelibLTLIBRARIES:
+ -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES)
+ @list='$(securelib_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+pam_limits.la: $(pam_limits_la_OBJECTS) $(pam_limits_la_DEPENDENCIES)
+ $(LINK) -rpath $(securelibdir) $(pam_limits_la_OBJECTS) $(pam_limits_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_limits.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man5: $(man5_MANS) $(man_MANS)
+ @$(NORMAL_INSTALL)
+ test -z "$(man5dir)" || $(MKDIR_P) "$(DESTDIR)$(man5dir)"
+ @list='$(man5_MANS) $(dist_man5_MANS) $(nodist_man5_MANS)'; \
+ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+ for i in $$l2; do \
+ case "$$i" in \
+ *.5*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+ else file=$$i; fi; \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ case "$$ext" in \
+ 5*) ;; \
+ *) ext='5' ;; \
+ esac; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed -e 's/^.*\///'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man5dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man5dir)/$$inst"; \
+ done
+uninstall-man5:
+ @$(NORMAL_UNINSTALL)
+ @list='$(man5_MANS) $(dist_man5_MANS) $(nodist_man5_MANS)'; \
+ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+ for i in $$l2; do \
+ case "$$i" in \
+ *.5*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ case "$$ext" in \
+ 5*) ;; \
+ *) ext='5' ;; \
+ esac; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed -e 's/^.*\///'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " rm -f '$(DESTDIR)$(man5dir)/$$inst'"; \
+ rm -f "$(DESTDIR)$(man5dir)/$$inst"; \
+ done
+install-man8: $(man8_MANS) $(man_MANS)
+ @$(NORMAL_INSTALL)
+ test -z "$(man8dir)" || $(MKDIR_P) "$(DESTDIR)$(man8dir)"
+ @list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \
+ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+ for i in $$l2; do \
+ case "$$i" in \
+ *.8*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+ else file=$$i; fi; \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ case "$$ext" in \
+ 8*) ;; \
+ *) ext='8' ;; \
+ esac; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed -e 's/^.*\///'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst"; \
+ done
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \
+ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+ for i in $$l2; do \
+ case "$$i" in \
+ *.8*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ case "$$ext" in \
+ 8*) ;; \
+ *) ext='8' ;; \
+ esac; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed -e 's/^.*\///'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " rm -f '$(DESTDIR)$(man8dir)/$$inst'"; \
+ rm -f "$(DESTDIR)$(man8dir)/$$inst"; \
+ done
+install-secureconfDATA: $(secureconf_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(secureconfdir)" || $(MKDIR_P) "$(DESTDIR)$(secureconfdir)"
+ @list='$(secureconf_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(secureconfDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(secureconfdir)/$$f'"; \
+ $(secureconfDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(secureconfdir)/$$f"; \
+ done
+
+uninstall-secureconfDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(secureconf_DATA)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(secureconfdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(secureconfdir)/$$f"; \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+check-TESTS: $(TESTS)
+ @failed=0; all=0; xfail=0; xpass=0; skip=0; ws='[ ]'; \
+ srcdir=$(srcdir); export srcdir; \
+ list=' $(TESTS) '; \
+ if test -n "$$list"; then \
+ for tst in $$list; do \
+ if test -f ./$$tst; then dir=./; \
+ elif test -f $$tst; then dir=; \
+ else dir="$(srcdir)/"; fi; \
+ if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *$$ws$$tst$$ws*) \
+ xpass=`expr $$xpass + 1`; \
+ failed=`expr $$failed + 1`; \
+ echo "XPASS: $$tst"; \
+ ;; \
+ *) \
+ echo "PASS: $$tst"; \
+ ;; \
+ esac; \
+ elif test $$? -ne 77; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *$$ws$$tst$$ws*) \
+ xfail=`expr $$xfail + 1`; \
+ echo "XFAIL: $$tst"; \
+ ;; \
+ *) \
+ failed=`expr $$failed + 1`; \
+ echo "FAIL: $$tst"; \
+ ;; \
+ esac; \
+ else \
+ skip=`expr $$skip + 1`; \
+ echo "SKIP: $$tst"; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ if test "$$xfail" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="All $$all tests behaved as expected ($$xfail expected failures)"; \
+ fi; \
+ else \
+ if test "$$xpass" -eq 0; then \
+ banner="$$failed of $$all tests failed"; \
+ else \
+ banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \
+ fi; \
+ fi; \
+ dashes="$$banner"; \
+ skipped=""; \
+ if test "$$skip" -ne 0; then \
+ skipped="($$skip tests were not run)"; \
+ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$skipped"; \
+ fi; \
+ report=""; \
+ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
+ report="Please report to $(PACKAGE_BUGREPORT)"; \
+ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$report"; \
+ fi; \
+ dashes=`echo "$$dashes" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ test -z "$$skipped" || echo "$$skipped"; \
+ test -z "$$report" || echo "$$report"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0; \
+ else :; fi
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(MANS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(secureconfdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-securelibLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-data-local install-man install-secureconfDATA \
+ install-securelibLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man: install-man5 install-man8
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man uninstall-secureconfDATA \
+ uninstall-securelibLTLIBRARIES
+
+uninstall-man: uninstall-man5 uninstall-man8
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \
+ clean-generic clean-libtool clean-securelibLTLIBRARIES ctags \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-data-local install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man install-man5 \
+ install-man8 install-pdf install-pdf-am install-ps \
+ install-ps-am install-secureconfDATA \
+ install-securelibLTLIBRARIES install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-man uninstall-man5 \
+ uninstall-man8 uninstall-secureconfDATA \
+ uninstall-securelibLTLIBRARIES
+
+@ENABLE_REGENERATE_MAN_TRUE@README: pam_limits.8.xml limits.conf.5.xml
+@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
+
+install-data-local:
+ mkdir -p $(DESTDIR)$(limits_conf_dir)
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/pam_limits/README b/modules/pam_limits/README
new file mode 100644
index 00000000..3c59052a
--- /dev/null
+++ b/modules/pam_limits/README
@@ -0,0 +1,64 @@
+pam_limits — PAM module to limit resources
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+DESCRIPTION
+
+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.
+
+If Linux PAM is compiled with audit support the module will report when it
+denies access based on limit of maximum number of concurrent login sessions.
+
+OPTIONS
+
+change_uid
+
+ 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.
+
+conf=/path/to/limits.conf
+
+ Indicate an alternative limits.conf style configuration file to override
+ the default.
+
+debug
+
+ Print debug information.
+
+utmp_early
+
+ 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.
+
+noaudit
+
+ Do not report exceeded maximum logins count to the audit subsystem.
+
+EXAMPLES
+
+These are some example lines which might be specified in /etc/security/
+limits.conf.
+
+* soft core 0
+* hard rss 10000
+@student hard nproc 20
+@faculty soft nproc 20
+@faculty hard nproc 50
+ftp hard nproc 0
+@student - maxlogins 4
+
+
diff --git a/modules/pam_limits/README.xml b/modules/pam_limits/README.xml
new file mode 100644
index 00000000..964a5a21
--- /dev/null
+++ b/modules/pam_limits/README.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+"http://www.docbook.org/xml/4.3/docbookx.dtd"
+[
+<!--
+<!ENTITY pamlimits SYSTEM "pam_limits.8.xml">
+-->
+<!--
+<!ENTITY limitsconf SYSTEM "limits.conf.5.xml">
+-->
+]>
+
+<article>
+
+ <articleinfo>
+
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_limits.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_limits-name"]/*)'/>
+ </title>
+
+ </articleinfo>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_limits.8.xml" xpointer='xpointer(//refsect1[@id = "pam_limits-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_limits.8.xml" xpointer='xpointer(//refsect1[@id = "pam_limits-options"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="limits.conf.5.xml" xpointer='xpointer(//refsect1[@id = "limits.conf-examples"]/*)'/>
+ </section>
+
+</article>
diff --git a/modules/pam_limits/limits.conf b/modules/pam_limits/limits.conf
new file mode 100644
index 00000000..5d5c3f70
--- /dev/null
+++ b/modules/pam_limits/limits.conf
@@ -0,0 +1,50 @@
+# /etc/security/limits.conf
+#
+#Each line describes a limit for a user in the form:
+#
+#<domain> <type> <item> <value>
+#
+#Where:
+#<domain> can be:
+# - an user name
+# - a group name, with @group syntax
+# - the wildcard *, for default entry
+# - the wildcard %, can be also used with %group syntax,
+# for maxlogin limit
+#
+#<type> can have the two values:
+# - "soft" for enforcing the soft limits
+# - "hard" for enforcing hard limits
+#
+#<item> can be one of the following:
+# - core - limits the core file size (KB)
+# - data - max data size (KB)
+# - fsize - maximum filesize (KB)
+# - memlock - max locked-in-memory address space (KB)
+# - nofile - max number of open files
+# - rss - max resident set size (KB)
+# - stack - max stack size (KB)
+# - cpu - max CPU time (MIN)
+# - nproc - max number of processes
+# - 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
+# - locks - max number of file locks the user can hold
+# - sigpending - max number of pending signals
+# - msgqueue - max memory used by POSIX message queues (bytes)
+# - nice - max nice priority allowed to raise to values: [-20, 19]
+# - rtprio - max realtime priority
+#
+#<domain> <type> <item> <value>
+#
+
+#* soft core 0
+#* hard rss 10000
+#@student hard nproc 20
+#@faculty soft nproc 20
+#@faculty hard nproc 50
+#ftp hard nproc 0
+#@student - maxlogins 4
+
+# End of file
diff --git a/modules/pam_limits/limits.conf.5 b/modules/pam_limits/limits.conf.5
new file mode 100644
index 00000000..0aba7137
--- /dev/null
+++ b/modules/pam_limits/limits.conf.5
@@ -0,0 +1,219 @@
+.\" Title: limits.conf
+.\" Author:
+.\" Generator: DocBook XSL Stylesheets v1.73.1 <http://docbook.sf.net/>
+.\" Date: 04/16/2008
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\"
+.TH "LIMITS\.CONF" "5" "04/16/2008" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.SH "NAME"
+limits.conf - configuration file for the pam_limits module
+.SH "DESCRIPTION"
+.PP
+The syntax of the lines is as follows:
+.PP
+
+\fI<domain>\fR
+\fI<type>\fR
+\fI<item>\fR
+\fI<value>\fR
+.PP
+The fields listed above should be filled as follows:
+.PP
+\fB<domain>\fR
+.RS 4
+.sp
+.RS 4
+\h'-04'\(bu\h'+03'a username
+.RE
+.sp
+.RS 4
+\h'-04'\(bu\h'+03'a groupname, with
+\fB@group\fR
+syntax\. This should not be confused with netgroups\.
+.RE
+.sp
+.RS 4
+\h'-04'\(bu\h'+03'the wildcard
+\fB*\fR, for default entry\.
+.RE
+.sp
+.RS 4
+\h'-04'\(bu\h'+03'the wildcard
+\fB%\fR, for maxlogins limit only, can also be used with
+\fI%group\fR
+syntax\.
+.RE
+.RE
+.PP
+\fB<type>\fR
+.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\.
+.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\-existing
+\fBhard\fR
+limits\. The values specified with this token can be thought of as
+\fIdefault\fR
+values, for normal system usage\.
+.RE
+.PP
+\fB\-\fR
+.RS 4
+for enforcing both
+\fBsoft\fR
+and
+\fBhard\fR
+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
+.RE
+.PP
+\fB<item>\fR
+.RS 4
+.PP
+\fBcore\fR
+.RS 4
+limits the core file size (KB)
+.RE
+.PP
+\fBdata\fR
+.RS 4
+maximum data size (KB)
+.RE
+.PP
+\fBfsize\fR
+.RS 4
+maximum filesize (KB)
+.RE
+.PP
+\fBmemlock\fR
+.RS 4
+maximum locked\-in\-memory address space (KB)
+.RE
+.PP
+\fBnofile\fR
+.RS 4
+maximum number of open files
+.RE
+.PP
+\fBrss\fR
+.RS 4
+maximum resident set size (KB)
+.RE
+.PP
+\fBstack\fR
+.RS 4
+maximum stack size (KB)
+.RE
+.PP
+\fBcpu\fR
+.RS 4
+maximum CPU time (minutes)
+.RE
+.PP
+\fBnproc\fR
+.RS 4
+maximum number of processes
+.RE
+.PP
+\fBas\fR
+.RS 4
+address space limit (KB)
+.RE
+.PP
+\fBmaxlogins\fR
+.RS 4
+maximum number of logins for this user except for this with
+\fIuid=0\fR
+.RE
+.PP
+\fBmaxsyslogins\fR
+.RS 4
+maximum number of logins on system
+.RE
+.PP
+\fBpriority\fR
+.RS 4
+the priority to run user process with (negative values boost process priority)
+.RE
+.PP
+\fBlocks\fR
+.RS 4
+maximum locked files (Linux 2\.4 and higher)
+.RE
+.PP
+\fBsigpending\fR
+.RS 4
+maximum number of pending signals (Linux 2\.6 and higher)
+.RE
+.PP
+\fBmsqqueue\fR
+.RS 4
+maximum memory used by POSIX message queues (bytes) (Linux 2\.6 and higher)
+.RE
+.PP
+\fBnice\fR
+.RS 4
+maximum nice priority allowed to raise to (Linux 2\.6\.12 and higher) values: [\-20,19]
+.RE
+.PP
+\fBrtprio\fR
+.RS 4
+maximum realtime priority allowed for non\-privileged processes (Linux 2\.6\.12 and higher)
+.RE
+.RE
+.PP
+In general, individual limits have priority over group limits, so if you impose no limits for
+\fIadmin\fR
+group, but one of the members in this group have a limits line, the user will have its limits set according to this line\.
+.PP
+Also, please note that all limit settings are set
+\fIper login\fR\. They are not global, nor are they permanent; existing only for the duration of the session\.
+.PP
+In the
+\fIlimits\fR
+configuration file, the \'\fB#\fR\' character introduces a comment \- after which the rest of the line is ignored\.
+.PP
+The pam_limits module does its best to report configuration problems found in its configuration file via
+\fBsyslog\fR(3)\.
+.SH "EXAMPLES"
+.PP
+These are some example lines which might be specified in
+\fI/etc/security/limits\.conf\fR\.
+.sp
+.RS 4
+.nf
+* soft core 0
+* hard rss 10000
+@student hard nproc 20
+@faculty soft nproc 20
+@faculty hard nproc 50
+ftp hard nproc 0
+@student \- maxlogins 4
+
+.fi
+.RE
+.SH "SEE ALSO"
+.PP
+
+\fBpam_limits\fR(8),
+\fBpam.d\fR(5),
+\fBpam\fR(8)
+.SH "AUTHOR"
+.PP
+pam_limits was initially written by Cristian Gafton <gafton@redhat\.com>
diff --git a/modules/pam_limits/limits.conf.5.xml b/modules/pam_limits/limits.conf.5.xml
new file mode 100644
index 00000000..fb1fad27
--- /dev/null
+++ b/modules/pam_limits/limits.conf.5.xml
@@ -0,0 +1,287 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="limits.conf">
+
+ <refmeta>
+ <refentrytitle>limits.conf</refentrytitle>
+ <manvolnum>5</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>limits.conf</refname>
+ <refpurpose>configuration file for the pam_limits module</refpurpose>
+ </refnamediv>
+
+ <refsect1 id='limits.conf-description'>
+ <title>DESCRIPTION</title>
+ <para>
+ The syntax of the lines is as follows:
+ </para>
+ <para>
+ <replaceable>&lt;domain&gt;</replaceable> <replaceable>&lt;type&gt;</replaceable>
+ <replaceable>&lt;item&gt;</replaceable> <replaceable>&lt;value&gt;</replaceable>
+ </para>
+ <para>
+ The fields listed above should be filled as follows:
+ </para>
+ <variablelist>
+ <varlistentry>
+ <term>
+ <option>&lt;domain&gt;</option>
+ </term>
+ <listitem>
+ <itemizedlist>
+ <listitem>
+ <para>
+ a username
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ a groupname, with <emphasis remap='B'>@group</emphasis> syntax.
+ This should not be confused with netgroups.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ the wildcard <emphasis remap='B'>*</emphasis>, for default entry.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ the wildcard <emphasis remap='B'>%</emphasis>, for maxlogins limit only,
+ can also be used with <emphasis remap='b'>%group</emphasis> syntax.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>&lt;type&gt;</option>
+ </term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term><option>hard</option></term>
+ <listitem>
+ <para>
+ for enforcing <emphasis remap='B'>hard</emphasis> 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.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>soft</option></term>
+ <listitem>
+ <para>
+ for enforcing <emphasis remap='B'>soft</emphasis> resource limits.
+ These limits are ones that the user can move up or down within the
+ permitted range by any pre-existing <emphasis remap='B'>hard</emphasis>
+ limits. The values specified with this token can be thought of as
+ <emphasis>default</emphasis> values, for normal system usage.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>-</option></term>
+ <listitem>
+ <para>
+ for enforcing both <emphasis remap='B'>soft</emphasis> and
+ <emphasis remap='B'>hard</emphasis> resource limits together.
+ </para>
+ <para>
+ 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. .
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>&lt;item&gt;</option>
+ </term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term><option>core</option></term>
+ <listitem>
+ <para>limits the core file size (KB)</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>data</option></term>
+ <listitem>
+ <para>maximum data size (KB)</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>fsize</option></term>
+ <listitem>
+ <para>maximum filesize (KB)</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>memlock</option></term>
+ <listitem>
+ <para>maximum locked-in-memory address space (KB)</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>nofile</option></term>
+ <listitem>
+ <para>maximum number of open files</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>rss</option></term>
+ <listitem>
+ <para>maximum resident set size (KB)</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>stack</option></term>
+ <listitem>
+ <para>maximum stack size (KB)</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>cpu</option></term>
+ <listitem>
+ <para>maximum CPU time (minutes)</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>nproc</option></term>
+ <listitem>
+ <para>maximum number of processes</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>as</option></term>
+ <listitem>
+ <para>address space limit (KB)</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>maxlogins</option></term>
+ <listitem>
+ <para>maximum number of logins for this user except
+ for this with <emphasis>uid=0</emphasis></para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>maxsyslogins</option></term>
+ <listitem>
+ <para>maximum number of logins on system</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>priority</option></term>
+ <listitem>
+ <para>the priority to run user process with (negative
+ values boost process priority)</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>locks</option></term>
+ <listitem>
+ <para>maximum locked files (Linux 2.4 and higher)</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>sigpending</option></term>
+ <listitem>
+ <para>maximum number of pending signals (Linux 2.6 and higher)</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>msqqueue</option></term>
+ <listitem>
+ <para>maximum memory used by POSIX message queues (bytes)
+ (Linux 2.6 and higher)</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>nice</option></term>
+ <listitem>
+ <para>maximum nice priority allowed to raise to (Linux 2.6.12 and higher) values: [-20,19]</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>rtprio</option></term>
+ <listitem>
+ <para>maximum realtime priority allowed for non-privileged processes
+ (Linux 2.6.12 and higher)</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ <para>
+ In general, individual limits have priority over group limits, so if
+ you impose no limits for <emphasis>admin</emphasis> group, but one of
+ the members in this group have a limits line, the user will have its
+ limits set according to this line.
+ </para>
+ <para>
+ Also, please note that all limit settings are set
+ <emphasis>per login</emphasis>. They are not global, nor are they
+ permanent; existing only for the duration of the session.
+ </para>
+ <para>
+ In the <emphasis>limits</emphasis> configuration file, the
+ '<emphasis remap='B'>#</emphasis>' character introduces a comment
+ - after which the rest of the line is ignored.
+ </para>
+ <para>
+ The pam_limits module does its best to report configuration problems
+ found in its configuration file via <citerefentry>
+ <refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
+ </para>
+ </refsect1>
+
+ <refsect1 id="limits.conf-examples">
+ <title>EXAMPLES</title>
+ <para>
+ These are some example lines which might be specified in
+ <filename>/etc/security/limits.conf</filename>.
+ </para>
+ <programlisting>
+* soft core 0
+* hard rss 10000
+@student hard nproc 20
+@faculty soft nproc 20
+@faculty hard nproc 50
+ftp hard nproc 0
+@student - maxlogins 4
+ </programlisting>
+ </refsect1>
+
+ <refsect1 id="limits.conf-see_also">
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry><refentrytitle>pam_limits</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id="limits.conf-author">
+ <title>AUTHOR</title>
+ <para>
+ pam_limits was initially written by Cristian Gafton &lt;gafton@redhat.com&gt;
+ </para>
+ </refsect1>
+</refentry>
diff --git a/modules/pam_limits/pam_limits.8 b/modules/pam_limits/pam_limits.8
new file mode 100644
index 00000000..8ffe28e4
--- /dev/null
+++ b/modules/pam_limits/pam_limits.8
@@ -0,0 +1,132 @@
+.\" Title: pam_limits
+.\" Author:
+.\" Generator: DocBook XSL Stylesheets v1.73.1 <http://docbook.sf.net/>
+.\" Date: 04/16/2008
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\"
+.TH "PAM_LIMITS" "8" "04/16/2008" "Linux-PAM Manual" "Linux-PAM Manual"
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.SH "NAME"
+pam_limits - PAM module to limit resources
+.SH "SYNOPSIS"
+.HP 14
+\fBpam_limits\.so\fR [change_uid] [conf=\fI/path/to/limits\.conf\fR] [debug] [utmp_early] [noaudit]
+.SH "DESCRIPTION"
+.PP
+The pam_limits PAM module sets limits on the system resources that can be obtained in a user\-session\. Users of
+\fIuid=0\fR
+are affected by this limits, too\.
+.PP
+By default limits are taken from the
+\fI/etc/security/limits\.conf\fR
+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\.
+.PP
+If Linux PAM is compiled with audit support the module will report when it denies access based on limit of maximum number of concurrent login sessions\.
+.SH "OPTIONS"
+.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\.
+.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\.
+.RE
+.PP
+\fBdebug\fR
+.RS 4
+Print debug information\.
+.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
+.PP
+\fBnoaudit\fR
+.RS 4
+Do not report exceeded maximum logins count to the audit subsystem\.
+.RE
+.SH "MODULE SERVICES PROVIDED"
+.PP
+Only the
+\fBsession\fR
+service is supported\.
+.SH "RETURN VALUES"
+.PP
+PAM_ABORT
+.RS 4
+Cannot get current limits\.
+.RE
+.PP
+PAM_IGNORE
+.RS 4
+No limits found for this user\.
+.RE
+.PP
+PAM_PERM_DENIED
+.RS 4
+New limits could not be set\.
+.RE
+.PP
+PAM_SERVICE_ERR
+.RS 4
+Cannot read config file\.
+.RE
+.PP
+PAM_SESSEION_ERR
+.RS 4
+Error recovering account name\.
+.RE
+.PP
+PAM_SUCCESS
+.RS 4
+Limits were changed\.
+.RE
+.PP
+PAM_USER_UNKNOWN
+.RS 4
+The user is not known to the system\.
+.RE
+.SH "FILES"
+.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 4
+.nf
+#%PAM\-1\.0
+#
+# Resource limits imposed on login sessions via pam_limits
+#
+session required pam_limits\.so
+
+.fi
+.RE
+.PP
+Replace "login" for each service you are using this module\.
+.SH "SEE ALSO"
+.PP
+
+\fBlimits.conf\fR(5),
+\fBpam.d\fR(8),
+\fBpam\fR(8)\.
+.SH "AUTHORS"
+.PP
+pam_limits was initially written by Cristian Gafton <gafton@redhat\.com>
diff --git a/modules/pam_limits/pam_limits.8.xml b/modules/pam_limits/pam_limits.8.xml
new file mode 100644
index 00000000..98afdcd4
--- /dev/null
+++ b/modules/pam_limits/pam_limits.8.xml
@@ -0,0 +1,256 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
+
+<refentry id='pam_limits'>
+
+ <refmeta>
+ <refentrytitle>pam_limits</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class='setdesc'>Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id='pam_limits-name'>
+ <refname>pam_limits</refname>
+ <refpurpose>
+ PAM module to limit resources
+ </refpurpose>
+ </refnamediv>
+
+<!-- body begins here -->
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_limits-cmdsynopsis">
+ <command>pam_limits.so</command>
+ <arg choice="opt">
+ change_uid
+ </arg>
+ <arg choice="opt">
+ conf=<replaceable>/path/to/limits.conf</replaceable>
+ </arg>
+ <arg choice="opt">
+ debug
+ </arg>
+ <arg choice="opt">
+ utmp_early
+ </arg>
+ <arg choice="opt">
+ noaudit
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+
+ <refsect1 id="pam_limits-description">
+ <title>DESCRIPTION</title>
+ <para>
+ The pam_limits PAM module sets limits on the system resources that can be
+ obtained in a user-session. Users of <emphasis>uid=0</emphasis> are affected
+ by this limits, too.
+ </para>
+ <para>
+ By default limits are taken from the <filename>/etc/security/limits.conf</filename>
+ 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>
+ <para>
+ If Linux PAM is compiled with audit support the module will report
+ when it denies access based on limit of maximum number of concurrent
+ login sessions.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_limits-options">
+ <title>OPTIONS</title>
+ <variablelist>
+ <varlistentry>
+ <term>
+ <option>change_uid</option>
+ </term>
+ <listitem>
+ <para>
+ 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.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>conf=<replaceable>/path/to/limits.conf</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ Indicate an alternative limits.conf style configuration file to
+ override the default.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>debug</option>
+ </term>
+ <listitem>
+ <para>
+ Print debug information.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>utmp_early</option>
+ </term>
+ <listitem>
+ <para>
+ 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.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>noaudit</option>
+ </term>
+ <listitem>
+ <para>
+ Do not report exceeded maximum logins count to the audit subsystem.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="pam_limits-services">
+ <title>MODULE SERVICES PROVIDED</title>
+ <para>
+ Only the <option>session</option> service is supported.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_limits-return_values">
+ <title>RETURN VALUES</title>
+ <variablelist>
+ <varlistentry>
+ <term>PAM_ABORT</term>
+ <listitem>
+ <para>
+ Cannot get current limits.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_IGNORE</term>
+ <listitem>
+ <para>
+ No limits found for this user.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_PERM_DENIED</term>
+ <listitem>
+ <para>
+ New limits could not be set.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_SERVICE_ERR</term>
+ <listitem>
+ <para>
+ Cannot read config file.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_SESSEION_ERR</term>
+ <listitem>
+ <para>
+ Error recovering account name.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_SUCCESS</term>
+ <listitem>
+ <para>
+ Limits were changed.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_USER_UNKNOWN</term>
+ <listitem>
+ <para>
+ The user is not known to the system.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="pam_limits-files">
+ <title>FILES</title>
+ <variablelist>
+ <varlistentry>
+ <term><filename>/etc/security/limits.conf</filename></term>
+ <listitem>
+ <para>Default configuration file</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id='pam_limits-examples'>
+ <title>EXAMPLES</title>
+ <para>
+ For the services you need resources limits (login for example) put a
+ the following line in <filename>/etc/pam.d/login</filename> as the last
+ line for that service (usually after the pam_unix session line):
+ </para>
+ <programlisting>
+#%PAM-1.0
+#
+# Resource limits imposed on login sessions via pam_limits
+#
+session required pam_limits.so
+ </programlisting>
+ <para>
+ Replace "login" for each service you are using this module.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_limits-see_also">
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>limits.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_limits-authors">
+ <title>AUTHORS</title>
+ <para>
+ pam_limits was initially written by Cristian Gafton &lt;gafton@redhat.com&gt;
+ </para>
+ </refsect1>
+</refentry>
diff --git a/modules/pam_limits/pam_limits.c b/modules/pam_limits/pam_limits.c
new file mode 100644
index 00000000..f1e29b85
--- /dev/null
+++ b/modules/pam_limits/pam_limits.c
@@ -0,0 +1,777 @@
+/*
+ * pam_limits - impose resource limits when opening a user session
+ *
+ * 1.6 - modified for PLD (added process priority settings)
+ * by Marcin Korzonek <mkorz@shadow.eu.org>
+ * 1.5 - Elliot Lee's "max system logins patch"
+ * 1.4 - addressed bug in configuration file parser
+ * 1.3 - modified the configuration file format
+ * 1.2 - added 'debug' and 'conf=' arguments
+ * 1.1 - added @group support
+ * 1.0 - initial release - Linux ONLY
+ *
+ * See end for Copyright information
+ */
+
+#if !defined(linux) && !defined(__linux)
+#warning THIS CODE IS KNOWN TO WORK ONLY ON LINUX !!!
+#endif
+
+#include "config.h"
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <syslog.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#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
+#endif
+
+#include <grp.h>
+#include <pwd.h>
+#include <locale.h>
+
+#ifdef HAVE_LIBAUDIT
+#include <libaudit.h>
+#endif
+
+/* Module defines */
+#define LINE_LENGTH 1024
+
+#define LIMITS_DEF_USER 0 /* limit was set by an 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 default entry */
+#define LIMITS_DEF_DEFAULT 4 /* limit was set by an default entry */
+#define LIMITS_DEF_NONE 5 /* this limit was not set yet */
+
+static const char *limits_def_names[] = {
+ "USER",
+ "GROUP",
+ "ALLGROUP",
+ "ALL",
+ "DEFAULT",
+ "NONE",
+ NULL
+};
+
+struct user_limits_struct {
+ int supported;
+ int src_soft;
+ int src_hard;
+ struct rlimit limit;
+};
+
+/* internal data */
+struct pam_limit_s {
+ int login_limit; /* the max logins limit */
+ int login_limit_def; /* which entry set the login limit */
+ 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 */
+ struct user_limits_struct limits[RLIM_NLIMITS];
+ const char *conf_file;
+ int utmp_after_pam_call;
+ char login_group[LINE_LENGTH];
+};
+
+#define LIMIT_LOGIN RLIM_NLIMITS+1
+#define LIMIT_NUMSYSLOGINS RLIM_NLIMITS+2
+
+#define LIMIT_PRI RLIM_NLIMITS+3
+
+#define LIMIT_SOFT 1
+#define LIMIT_HARD 2
+
+#define PAM_SM_SESSION
+
+#include <security/pam_modules.h>
+#include <security/_pam_macros.h>
+#include <security/pam_modutil.h>
+#include <security/pam_ext.h>
+
+/* argument parsing */
+
+#define PAM_DEBUG_ARG 0x0001
+#define PAM_DO_SETREUID 0x0002
+#define PAM_UTMP_EARLY 0x0004
+#define PAM_NO_AUDIT 0x0008
+
+/* 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)
+{
+ int ctrl=0;
+
+ /* step through arguments */
+ for (ctrl=0; argc-- > 0; ++argv) {
+
+ /* generic options */
+
+ if (!strcmp(*argv,"debug")) {
+ ctrl |= PAM_DEBUG_ARG;
+ } else if (!strncmp(*argv,"conf=",5)) {
+ pl->conf_file = *argv+5;
+ } else if (!strncmp(*argv,"change_uid",10)) {
+ ctrl |= PAM_DO_SETREUID;
+ } else if (!strcmp(*argv,"utmp_early")) {
+ ctrl |= PAM_UTMP_EARLY;
+ } else if (!strcmp(*argv,"noaudit")) {
+ ctrl |= PAM_NO_AUDIT;
+ } else {
+ pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv);
+ }
+ }
+
+ return ctrl;
+}
+
+
+#define LIMITED_OK 0 /* limit setting appeared to work */
+#define LIMIT_ERR 1 /* error setting a limit */
+#define LOGIN_ERR 2 /* too many logins err */
+
+/* Counts the number of user logins and check against the limit*/
+static int
+check_logins (pam_handle_t *pamh, const char *name, int limit, int ctrl,
+ struct pam_limit_s *pl)
+{
+ struct utmp *ut;
+ int count;
+
+ if (ctrl & PAM_DEBUG_ARG) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "checking logins for '%s' (maximum of %d)", name, limit);
+ }
+
+ if (limit < 0)
+ return 0; /* no limits imposed */
+ if (limit == 0) /* maximum 0 logins ? */ {
+ pam_syslog(pamh, LOG_WARNING, "No logins allowed for '%s'", name);
+ return LOGIN_ERR;
+ }
+
+ setutent();
+
+ /* Because there is no definition about when an application
+ actually adds a utmp entry, some applications bizarrely do the
+ utmp call before the have PAM authenticate them to the system:
+ you're logged it, sort of...? Anyway, you can use the
+ "utmp_early" module argument in your PAM config file to make
+ allowances for this sort of problem. (There should be a PAM
+ standard for this, since if a module wants to actually map a
+ username then any early utmp entry will be for the unmapped
+ name = broken.) */
+
+ if (ctrl & PAM_UTMP_EARLY) {
+ count = 0;
+ } else {
+ count = 1;
+ }
+
+ while((ut = getutent())) {
+#ifdef USER_PROCESS
+ if (ut->ut_type != USER_PROCESS) {
+ continue;
+ }
+#endif
+ if (ut->UT_USER[0] == '\0') {
+ continue;
+ }
+ if (!pl->flag_numsyslogins) {
+ if (((pl->login_limit_def == LIMITS_DEF_USER)
+ || (pl->login_limit_def == LIMITS_DEF_GROUP)
+ || (pl->login_limit_def == LIMITS_DEF_DEFAULT))
+ && strncmp(name, ut->UT_USER, sizeof(ut->UT_USER)) != 0) {
+ continue;
+ }
+ if ((pl->login_limit_def == LIMITS_DEF_ALLGROUP)
+ && !pam_modutil_user_in_group_nam_nam(pamh, ut->UT_USER, pl->login_group)) {
+ continue;
+ }
+ }
+ if (++count > limit) {
+ break;
+ }
+ }
+ endutent();
+ if (count > limit) {
+ if (name) {
+ pam_syslog(pamh, LOG_WARNING,
+ "Too many logins (max %d) for %s", limit, name);
+ } else {
+ pam_syslog(pamh, LOG_WARNING, "Too many system logins (max %d)", limit);
+ }
+ return LOGIN_ERR;
+ }
+ return 0;
+}
+
+static int init_limits(struct pam_limit_s *pl)
+{
+ int i;
+ int retval = PAM_SUCCESS;
+
+ D(("called."));
+
+ for(i = 0; i < RLIM_NLIMITS; i++) {
+ int r = getrlimit(i, &pl->limits[i].limit);
+ if (r == -1) {
+ pl->limits[i].supported = 0;
+ if (errno != EINVAL) {
+ retval = !PAM_SUCCESS;
+ }
+ } else {
+ pl->limits[i].supported = 1;
+ pl->limits[i].src_soft = LIMITS_DEF_NONE;
+ pl->limits[i].src_hard = LIMITS_DEF_NONE;
+ }
+ }
+
+ errno = 0;
+ pl->priority = getpriority (PRIO_PROCESS, 0);
+ if (pl->priority == -1 && errno != 0)
+ retval = !PAM_SUCCESS;
+ pl->login_limit = -2;
+ pl->login_limit_def = LIMITS_DEF_NONE;
+
+ 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,
+ int ctrl, struct pam_limit_s *pl)
+{
+ int limit_item;
+ int limit_type = 0;
+ int int_value = 0;
+ rlim_t rlimit_value = 0;
+ char *endptr;
+ const char *value_orig = lim_value;
+
+ if (ctrl & PAM_DEBUG_ARG)
+ pam_syslog(pamh, LOG_DEBUG, "%s: processing %s %s %s for %s",
+ __FUNCTION__, lim_type, lim_item, lim_value,
+ limits_def_names[source]);
+
+ if (strcmp(lim_item, "cpu") == 0)
+ limit_item = RLIMIT_CPU;
+ else if (strcmp(lim_item, "fsize") == 0)
+ limit_item = RLIMIT_FSIZE;
+ else if (strcmp(lim_item, "data") == 0)
+ limit_item = RLIMIT_DATA;
+ else if (strcmp(lim_item, "stack") == 0)
+ limit_item = RLIMIT_STACK;
+ else if (strcmp(lim_item, "core") == 0)
+ limit_item = RLIMIT_CORE;
+ else if (strcmp(lim_item, "rss") == 0)
+ limit_item = RLIMIT_RSS;
+ else if (strcmp(lim_item, "nproc") == 0)
+ limit_item = RLIMIT_NPROC;
+ else if (strcmp(lim_item, "nofile") == 0)
+ limit_item = RLIMIT_NOFILE;
+ else if (strcmp(lim_item, "memlock") == 0)
+ limit_item = RLIMIT_MEMLOCK;
+#ifdef RLIMIT_AS
+ else if (strcmp(lim_item, "as") == 0)
+ limit_item = RLIMIT_AS;
+#endif /*RLIMIT_AS*/
+#ifdef RLIMIT_LOCKS
+ else if (strcmp(lim_item, "locks") == 0)
+ limit_item = RLIMIT_LOCKS;
+#endif
+#ifdef RLIMIT_SIGPENDING
+ else if (strcmp(lim_item, "sigpending") == 0)
+ limit_item = RLIMIT_SIGPENDING;
+#endif
+#ifdef RLIMIT_MSGQUEUE
+ else if (strcmp(lim_item, "msgqueue") == 0)
+ limit_item = RLIMIT_MSGQUEUE;
+#endif
+#ifdef RLIMIT_NICE
+ else if (strcmp(lim_item, "nice") == 0)
+ limit_item = RLIMIT_NICE;
+#endif
+#ifdef RLIMIT_RTPRIO
+ else if (strcmp(lim_item, "rtprio") == 0)
+ limit_item = RLIMIT_RTPRIO;
+#endif
+ else if (strcmp(lim_item, "maxlogins") == 0) {
+ limit_item = LIMIT_LOGIN;
+ pl->flag_numsyslogins = 0;
+ } else if (strcmp(lim_item, "maxsyslogins") == 0) {
+ limit_item = LIMIT_NUMSYSLOGINS;
+ pl->flag_numsyslogins = 1;
+ } else if (strcmp(lim_item, "priority") == 0) {
+ limit_item = LIMIT_PRI;
+ } else {
+ pam_syslog(pamh, LOG_DEBUG, "unknown limit item '%s'", lim_item);
+ return;
+ }
+
+ if (strcmp(lim_type,"soft")==0)
+ limit_type=LIMIT_SOFT;
+ else if (strcmp(lim_type, "hard")==0)
+ 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) {
+ pam_syslog(pamh, LOG_DEBUG, "unknown limit type '%s'", lim_type);
+ return;
+ }
+ if (limit_item != LIMIT_PRI
+#ifdef RLIMIT_NICE
+ && limit_item != RLIMIT_NICE
+#endif
+ && (strcmp(lim_value, "-1") == 0
+ || strcmp(lim_value, "-") == 0 || strcmp(lim_value, "unlimited") == 0
+ || strcmp(lim_value, "infinity") == 0)) {
+ int_value = -1;
+ rlimit_value = RLIM_INFINITY;
+ } else if (limit_item == LIMIT_PRI || limit_item == LIMIT_LOGIN ||
+#ifdef RLIMIT_NICE
+ limit_item == RLIMIT_NICE ||
+#endif
+ limit_item == LIMIT_NUMSYSLOGINS) {
+ long temp;
+ temp = strtol (lim_value, &endptr, 10);
+ temp = temp < INT_MAX ? temp : INT_MAX;
+ int_value = temp > INT_MIN ? temp : INT_MIN;
+ if (int_value == 0 && value_orig == endptr) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "wrong limit value '%s' for limit type '%s'",
+ lim_value, lim_type);
+ return;
+ }
+ } else {
+#ifdef __USE_FILE_OFFSET64
+ rlimit_value = strtoull (lim_value, &endptr, 10);
+#else
+ rlimit_value = strtoul (lim_value, &endptr, 10);
+#endif
+ if (rlimit_value == 0 && value_orig == endptr) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "wrong limit value '%s' for limit type '%s'",
+ lim_value, lim_type);
+ return;
+ }
+ }
+
+ /* one more special case when limiting logins */
+ if ((source == LIMITS_DEF_ALL || source == LIMITS_DEF_ALLGROUP)
+ && (limit_item != LIMIT_LOGIN)) {
+ if (ctrl & PAM_DEBUG_ARG)
+ pam_syslog(pamh, LOG_DEBUG,
+ "'%%' domain valid for maxlogins type only");
+ return;
+ }
+
+ switch(limit_item) {
+ case RLIMIT_CPU:
+ 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:
+ case RLIMIT_STACK:
+ case RLIMIT_CORE:
+ case RLIMIT_RSS:
+ case RLIMIT_MEMLOCK:
+#ifdef RLIMIT_AS
+ case RLIMIT_AS:
+#endif
+ if (rlimit_value != RLIM_INFINITY)
+ {
+ 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;
+ if (int_value < -20)
+ int_value = -20;
+ rlimit_value = 20 - int_value;
+#endif
+ break;
+ }
+
+ if ( (limit_item != LIMIT_LOGIN)
+ && (limit_item != LIMIT_NUMSYSLOGINS)
+ && (limit_item != LIMIT_PRI) ) {
+ if (limit_type & LIMIT_SOFT) {
+ if (pl->limits[limit_item].src_soft < source) {
+ return;
+ } else {
+ pl->limits[limit_item].limit.rlim_cur = rlimit_value;
+ pl->limits[limit_item].src_soft = source;
+ }
+ }
+ if (limit_type & LIMIT_HARD) {
+ if (pl->limits[limit_item].src_hard < source) {
+ return;
+ } else {
+ pl->limits[limit_item].limit.rlim_max = rlimit_value;
+ pl->limits[limit_item].src_hard = source;
+ }
+ }
+ } else {
+ /* recent kernels support negative priority limits (=raise priority) */
+
+ if (limit_item == LIMIT_PRI) {
+ pl->priority = int_value;
+ } else {
+ if (pl->login_limit_def < source) {
+ return;
+ } else {
+ pl->login_limit = int_value;
+ pl->login_limit_def = source;
+ }
+ }
+ }
+ return;
+}
+
+static int parse_config_file(pam_handle_t *pamh, const char *uname, int ctrl,
+ struct pam_limit_s *pl)
+{
+ FILE *fil;
+ char buf[LINE_LENGTH];
+
+ /* check for the LIMITS_FILE */
+ if (ctrl & PAM_DEBUG_ARG)
+ pam_syslog(pamh, LOG_DEBUG, "reading settings from '%s'", CONF_FILE);
+ fil = fopen(CONF_FILE, "r");
+ if (fil == NULL) {
+ pam_syslog (pamh, LOG_WARNING,
+ "cannot read settings from %s: %m", CONF_FILE);
+ return PAM_SERVICE_ERR;
+ }
+
+ /* start the show */
+ while (fgets(buf, LINE_LENGTH, fil) != NULL) {
+ char domain[LINE_LENGTH];
+ char ltype[LINE_LENGTH];
+ char item[LINE_LENGTH];
+ char value[LINE_LENGTH];
+ int i;
+ size_t j;
+ char *tptr,*line;
+
+ line = buf;
+ /* skip the leading white space */
+ while (*line && isspace(*line))
+ line++;
+
+ /* Rip off the comments */
+ tptr = strchr(line,'#');
+ if (tptr)
+ *tptr = '\0';
+ /* Rip off the newline char */
+ tptr = strchr(line,'\n');
+ if (tptr)
+ *tptr = '\0';
+ /* Anything left ? */
+ if (!strlen(line))
+ continue;
+
+ domain[0] = ltype[0] = item[0] = value[0] = '\0';
+
+ i = sscanf(line,"%s%s%s%s", domain, ltype, item, value);
+ D(("scanned line[%d]: domain[%s], ltype[%s], item[%s], value[%s]",
+ i, domain, ltype, item, value));
+
+ for(j=0; j < strlen(ltype); j++)
+ ltype[j]=tolower(ltype[j]);
+
+ if (i == 4) { /* a complete line */
+ for(j=0; j < strlen(item); j++)
+ item[j]=tolower(item[j]);
+ for(j=0; j < strlen(value); j++)
+ value[j]=tolower(value[j]);
+
+ 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) {
+ 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,
+ pl);
+ } else if (domain[0]=='%') {
+ 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);
+ } 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)) {
+ 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 {
+ pam_syslog(pamh, LOG_WARNING, "invalid line '%s' - skipped", line);
+ }
+ }
+ fclose(fil);
+ return PAM_SUCCESS;
+}
+
+static int setup_limits(pam_handle_t *pamh,
+ const char *uname, uid_t uid, int ctrl,
+ struct pam_limit_s *pl)
+{
+ int i;
+ int status;
+ int retval = LIMITED_OK;
+
+ for (i=0, status=LIMITED_OK; i<RLIM_NLIMITS; i++) {
+ if (!pl->limits[i].supported) {
+ /* skip it if its not known to the system */
+ continue;
+ }
+ if (pl->limits[i].src_soft == LIMITS_DEF_NONE &&
+ pl->limits[i].src_hard == LIMITS_DEF_NONE) {
+ /* skip it if its not initialized */
+ continue;
+ }
+ if (pl->limits[i].limit.rlim_cur > pl->limits[i].limit.rlim_max)
+ pl->limits[i].limit.rlim_cur = pl->limits[i].limit.rlim_max;
+ status |= setrlimit(i, &pl->limits[i].limit);
+ }
+
+ if (status) {
+ retval = LIMIT_ERR;
+ }
+
+ status = setpriority(PRIO_PROCESS, 0, pl->priority);
+ if (status != 0) {
+ retval = LIMIT_ERR;
+ }
+
+ if (uid == 0) {
+ D(("skip login limit check for uid=0"));
+ } else if (pl->login_limit > 0) {
+ if (check_logins(pamh, uname, pl->login_limit, ctrl, pl) == LOGIN_ERR) {
+#ifdef HAVE_LIBAUDIT
+ if (!(ctrl & PAM_NO_AUDIT)) {
+ pam_modutil_audit_write(pamh, AUDIT_ANOM_LOGIN_SESSIONS,
+ "pam_limits", PAM_PERM_DENIED);
+ /* ignore return value as we fail anyway */
+ }
+#endif
+ retval |= LOGIN_ERR;
+ }
+ } else if (pl->login_limit == 0) {
+ retval |= LOGIN_ERR;
+ }
+
+ return retval;
+}
+
+/* now the session stuff */
+PAM_EXTERN int
+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 plstruct;
+ struct pam_limit_s *pl = &plstruct;
+ glob_t globbuf;
+ const char *oldlocale;
+
+ D(("called."));
+
+ memset(pl, 0, sizeof(*pl));
+ memset(&globbuf, 0, sizeof(globbuf));
+
+ 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");
+ return PAM_SESSION_ERR;
+ }
+
+ pwd = pam_modutil_getpwnam(pamh, user_name);
+ if (!pwd) {
+ if (ctrl & PAM_DEBUG_ARG)
+ pam_syslog(pamh, LOG_WARNING,
+ "open_session username '%s' does not exist", user_name);
+ return PAM_USER_UNKNOWN;
+ }
+
+ 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);
+ if (retval == PAM_IGNORE) {
+ D(("the configuration file ('%s') has an applicable '<domain> -' entry", CONF_FILE));
+ return PAM_SUCCESS;
+ }
+ 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);
+ if (retval & LOGIN_ERR)
+ pam_error(pamh, _("Too many logins for '%s'."), pwd->pw_name);
+ if (retval != LIMITED_OK) {
+ return PAM_PERM_DENIED;
+ }
+
+ return PAM_SUCCESS;
+}
+
+PAM_EXTERN int
+pam_sm_close_session (pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ /* nothing to do */
+ return PAM_SUCCESS;
+}
+
+#ifdef PAM_STATIC
+
+/* static module data */
+
+struct pam_module _pam_limits_modstruct = {
+ "pam_limits",
+ NULL,
+ NULL,
+ NULL,
+ pam_sm_open_session,
+ pam_sm_close_session,
+ NULL
+};
+#endif
+
+/*
+ * Copyright (c) Cristian Gafton, 1996-1997, <gafton@redhat.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
diff --git a/modules/pam_limits/tst-pam_limits b/modules/pam_limits/tst-pam_limits
new file mode 100755
index 00000000..f563beb7
--- /dev/null
+++ b/modules/pam_limits/tst-pam_limits
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_limits.so