diff options
Diffstat (limited to 'modules/pam_lastlog')
-rw-r--r-- | modules/pam_lastlog/Makefile.am | 2 | ||||
-rw-r--r-- | modules/pam_lastlog/Makefile.in | 275 | ||||
-rw-r--r-- | modules/pam_lastlog/README | 21 | ||||
-rw-r--r-- | modules/pam_lastlog/pam_lastlog.8 | 242 | ||||
-rw-r--r-- | modules/pam_lastlog/pam_lastlog.8.xml | 61 | ||||
-rw-r--r-- | modules/pam_lastlog/pam_lastlog.c | 209 |
6 files changed, 492 insertions, 318 deletions
diff --git a/modules/pam_lastlog/Makefile.am b/modules/pam_lastlog/Makefile.am index 88bab27..1c63932 100644 --- a/modules/pam_lastlog/Makefile.am +++ b/modules/pam_lastlog/Makefile.am @@ -22,7 +22,7 @@ if HAVE_VERSIONING endif securelib_LTLIBRARIES = pam_lastlog.la -pam_lastlog_la_LIBADD = -L$(top_builddir)/libpam -lpam -lutil +pam_lastlog_la_LIBADD = $(top_builddir)/libpam/libpam.la -lutil if ENABLE_REGENERATE_MAN noinst_DATA = README diff --git a/modules/pam_lastlog/Makefile.in b/modules/pam_lastlog/Makefile.in index d590ee3..30cdda0 100644 --- a/modules/pam_lastlog/Makefile.in +++ b/modules/pam_lastlog/Makefile.in @@ -1,8 +1,9 @@ -# Makefile.in generated by automake 1.10.1 from Makefile.am. +# Makefile.in generated by automake 1.11.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. +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 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. @@ -21,8 +22,9 @@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c @@ -42,7 +44,7 @@ subdir = modules/pam_lastlog 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/intlmacosx.m4 \ + $(top_srcdir)/m4/iconv.m4 \ $(top_srcdir)/m4/japhar_grep_cflags.m4 \ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \ @@ -51,29 +53,44 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/gettext.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/pkg.m4 \ - $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ - $(top_srcdir)/configure.in + $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \ + $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_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__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__installdirs = "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)" -securelibLTLIBRARIES_INSTALL = $(INSTALL) LTLIBRARIES = $(securelib_LTLIBRARIES) -pam_lastlog_la_DEPENDENCIES = +pam_lastlog_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la pam_lastlog_la_SOURCES = pam_lastlog.c pam_lastlog_la_OBJECTS = pam_lastlog.lo DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/depcomp +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__depfiles_maybe = depfiles +am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ @@ -91,6 +108,8 @@ MANS = $(man_MANS) DATA = $(noinst_DATA) ETAGS = etags CTAGS = ctags +am__tty_colors = \ +red=; grn=; lgn=; blu=; std= DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ @@ -120,7 +139,6 @@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FO2PDF = @FO2PDF@ -GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ GMSGFMT = @GMSGFMT@ GMSGFMT_015 = @GMSGFMT_015@ GREP = @GREP@ @@ -178,6 +196,7 @@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PIE_CFLAGS = @PIE_CFLAGS@ @@ -195,7 +214,6 @@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ XGETTEXT = @XGETTEXT@ XGETTEXT_015 = @XGETTEXT_015@ -XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ XMLCATALOG = @XMLCATALOG@ XMLLINT = @XMLLINT@ XML_CATALOG_FILE = @XML_CATALOG_FILE@ @@ -272,7 +290,7 @@ TESTS = tst-pam_lastlog AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include AM_LDFLAGS = -no-undefined -avoid-version -module $(am__append_1) securelib_LTLIBRARIES = pam_lastlog.la -pam_lastlog_la_LIBADD = -L$(top_builddir)/libpam -lpam -lutil +pam_lastlog_la_LIBADD = $(top_builddir)/libpam/libpam.la -lutil @ENABLE_REGENERATE_MAN_TRUE@noinst_DATA = README all: all-am @@ -282,14 +300,14 @@ $(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; \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_lastlog/Makefile'; \ - cd $(top_srcdir) && \ - $(AUTOMAKE) --gnu modules/pam_lastlog/Makefile + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_lastlog/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu modules/pam_lastlog/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ @@ -307,23 +325,28 @@ $(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 +$(am__aclocal_m4_deps): install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES) @$(NORMAL_INSTALL) test -z "$(securelibdir)" || $(MKDIR_P) "$(DESTDIR)$(securelibdir)" - @list='$(securelib_LTLIBRARIES)'; for p in $$list; do \ + @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \ + list2=; 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"; \ + list2="$$list2 $$p"; \ else :; fi; \ - done + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(securelibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(securelibdir)"; \ + } 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"; \ + @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$f"; \ done clean-securelibLTLIBRARIES: @@ -347,21 +370,21 @@ distclean-compile: .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCC_TRUE@ $(am__mv) $(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 +@am__fastdepCC_TRUE@ $(am__mv) $(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 +@am__fastdepCC_TRUE@ $(am__mv) $(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 $@ $< @@ -371,65 +394,58 @@ mostlyclean-libtool: clean-libtool: -rm -rf .libs _libs -install-man8: $(man8_MANS) $(man_MANS) +install-man8: $(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; \ + @list=''; test -n "$(man8dir)" || exit 0; \ + { for i in $$list; do echo "$$i"; done; \ + l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.8[a-z]*$$/p'; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \ + fi; \ 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 + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \ + 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 + @list=''; test -n "$(man8dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.8[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + test -z "$$files" || { \ + echo " ( cd '$(DESTDIR)$(man8dir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(man8dir)" && rm -f $$files; } 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; } \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) - tags=; \ + set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ @@ -437,37 +453,43 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ 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 \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$tags $$unique; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ 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" \ + test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$tags $$unique + $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ - && cd $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) $$here + && $(am__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='[ ]'; \ + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ srcdir=$(srcdir); export srcdir; \ list=' $(TESTS) '; \ + $(am__tty_colors); \ if test -n "$$list"; then \ for tst in $$list; do \ if test -f ./$$tst; then dir=./; \ @@ -476,49 +498,63 @@ check-TESTS: $(TESTS) if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ - *$$ws$$tst$$ws*) \ + *[\ \ ]$$tst[\ \ ]*) \ xpass=`expr $$xpass + 1`; \ failed=`expr $$failed + 1`; \ - echo "XPASS: $$tst"; \ + col=$$red; res=XPASS; \ ;; \ *) \ - echo "PASS: $$tst"; \ + col=$$grn; res=PASS; \ ;; \ esac; \ elif test $$? -ne 77; then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ - *$$ws$$tst$$ws*) \ + *[\ \ ]$$tst[\ \ ]*) \ xfail=`expr $$xfail + 1`; \ - echo "XFAIL: $$tst"; \ + col=$$lgn; res=XFAIL; \ ;; \ *) \ failed=`expr $$failed + 1`; \ - echo "FAIL: $$tst"; \ + col=$$red; res=FAIL; \ ;; \ esac; \ else \ skip=`expr $$skip + 1`; \ - echo "SKIP: $$tst"; \ + col=$$blu; res=SKIP; \ fi; \ + echo "$${col}$$res$${std}: $$tst"; \ done; \ + if test "$$all" -eq 1; then \ + tests="test"; \ + All=""; \ + else \ + tests="tests"; \ + All="All "; \ + fi; \ if test "$$failed" -eq 0; then \ if test "$$xfail" -eq 0; then \ - banner="All $$all tests passed"; \ + banner="$$All$$all $$tests passed"; \ else \ - banner="All $$all tests behaved as expected ($$xfail expected failures)"; \ + if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ + banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ fi; \ else \ if test "$$xpass" -eq 0; then \ - banner="$$failed of $$all tests failed"; \ + banner="$$failed of $$all $$tests failed"; \ else \ - banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \ + if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ + 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)"; \ + if test "$$skip" -eq 1; then \ + skipped="($$skip test was not run)"; \ + else \ + skipped="($$skip tests were not run)"; \ + fi; \ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ dashes="$$skipped"; \ fi; \ @@ -529,15 +565,32 @@ check-TESTS: $(TESTS) dashes="$$report"; \ fi; \ dashes=`echo "$$dashes" | sed s/./=/g`; \ - echo "$$dashes"; \ + if test "$$failed" -eq 0; then \ + echo "$$grn$$dashes"; \ + else \ + echo "$$red$$dashes"; \ + fi; \ echo "$$banner"; \ test -z "$$skipped" || echo "$$skipped"; \ test -z "$$report" || echo "$$report"; \ - echo "$$dashes"; \ + echo "$$dashes$$std"; \ test "$$failed" -eq 0; \ else :; fi distdir: $(DISTFILES) + @list='$(MANS)'; if test -n "$$list"; then \ + list=`for p in $$list; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \ + if test -n "$$list" && \ + grep 'ab help2man is required to generate this page' $$list >/dev/null; then \ + echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \ + grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \ + echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \ + echo " typically \`make maintainer-clean' will remove them" >&2; \ + exit 1; \ + else :; fi; \ + else :; fi @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ @@ -553,13 +606,17 @@ distdir: $(DISTFILES) 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 "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ - cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ - test -f $(distdir)/$$file \ - || cp -p $$d/$$file $(distdir)/$$file \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @@ -592,6 +649,7 @@ clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @@ -614,6 +672,8 @@ dvi-am: html: html-am +html-am: + info: info-am info-am: @@ -622,18 +682,28 @@ install-data-am: install-man install-securelibLTLIBRARIES install-dvi: install-dvi-am +install-dvi-am: + install-exec-am: install-html: install-html-am +install-html-am: + install-info: install-info-am +install-info-am: + install-man: install-man8 install-pdf: install-pdf-am +install-pdf-am: + install-ps: install-ps-am +install-ps-am: + installcheck-am: maintainer-clean: maintainer-clean-am @@ -658,7 +728,7 @@ uninstall-am: uninstall-man uninstall-securelibLTLIBRARIES uninstall-man: uninstall-man8 -.MAKE: install-am install-strip +.MAKE: check-am install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \ clean-generic clean-libtool clean-securelibLTLIBRARIES ctags \ @@ -678,6 +748,7 @@ uninstall-man: uninstall-man8 @ENABLE_REGENERATE_MAN_TRUE@README: pam_lastlog.8.xml @ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules + # 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_lastlog/README b/modules/pam_lastlog/README index c714948..38a3065 100644 --- a/modules/pam_lastlog/README +++ b/modules/pam_lastlog/README @@ -1,4 +1,5 @@ -pam_lastlog — PAM module to display date of last login +pam_lastlog — PAM module to display date of last login and perform inactive +account lock out ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ @@ -10,6 +11,10 @@ login of the user. In addition, the module maintains the /var/log/lastlog file. Some applications may perform this function themselves. In such cases, this module is not necessary. +If the module is called in the auth or account phase, the accounts that were +not used recently enough will be disallowed to log in. The check is not +performed for the root account so the root is never locked out. + OPTIONS debug @@ -52,6 +57,12 @@ showfailed Display number of failed login attempts and the date of the last failed attempt from btmp. The date is not displayed when nodate is specified. +inactive=<days> + + This option is specific for the auth or account phase. It specifies the + number of days after the last login of the user when the user will be + locked out by the module. The default value is 90. + EXAMPLES Add the following line to /etc/pam.d/login to display the last login time of an @@ -60,7 +71,15 @@ user: session required pam_lastlog.so nowtmp +To reject the user if he did not login during the previous 50 days the +following line can be used: + + auth required pam_lastlog.so inactive=50 + + AUTHOR pam_lastlog was written by Andrew G. Morgan <morgan@kernel.org>. +Inactive account lock out added by Tomáš Mráz <tm@t8m.info>. + diff --git a/modules/pam_lastlog/pam_lastlog.8 b/modules/pam_lastlog/pam_lastlog.8 index c70421f..d037595 100644 --- a/modules/pam_lastlog/pam_lastlog.8 +++ b/modules/pam_lastlog/pam_lastlog.8 @@ -1,161 +1,22 @@ +'\" t .\" Title: pam_lastlog .\" Author: [see the "AUTHOR" section] -.\" Generator: DocBook XSL Stylesheets v1.74.0 <http://docbook.sf.net/> -.\" Date: 06/21/2011 +.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/> +.\" Date: 09/19/2013 .\" Manual: Linux-PAM Manual .\" Source: Linux-PAM Manual .\" Language: English .\" -.TH "PAM_LASTLOG" "8" "06/21/2011" "Linux-PAM Manual" "Linux\-PAM Manual" +.TH "PAM_LASTLOG" "8" "09/19/2013" "Linux-PAM Manual" "Linux\-PAM Manual" .\" ----------------------------------------------------------------- -.\" * (re)Define some macros +.\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" toupper - uppercase a string (locale-aware) +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.de toupper -.tr aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ -\\$* -.tr aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz -.. -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" SH-xref - format a cross-reference to an SH section -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.de SH-xref -.ie n \{\ -.\} -.toupper \\$* -.el \{\ -\\$* -.\} -.. -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" SH - level-one heading that works better for non-TTY output -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.de1 SH -.\" put an extra blank line of space above the head in non-TTY output -.if t \{\ -.sp 1 -.\} -.sp \\n[PD]u -.nr an-level 1 -.set-an-margin -.nr an-prevailing-indent \\n[IN] -.fi -.in \\n[an-margin]u -.ti 0 -.HTML-TAG ".NH \\n[an-level]" -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -\." make the size of the head bigger -.ps +3 -.ft B -.ne (2v + 1u) -.ie n \{\ -.\" if n (TTY output), use uppercase -.toupper \\$* -.\} -.el \{\ -.nr an-break-flag 0 -.\" if not n (not TTY), use normal case (not uppercase) -\\$1 -.in \\n[an-margin]u -.ti 0 -.\" if not n (not TTY), put a border/line under subheading -.sp -.6 -\l'\n(.lu' -.\} -.. -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" SS - level-two heading that works better for non-TTY output -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.de1 SS -.sp \\n[PD]u -.nr an-level 1 -.set-an-margin -.nr an-prevailing-indent \\n[IN] -.fi -.in \\n[IN]u -.ti \\n[SN]u -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.ps \\n[PS-SS]u -\." make the size of the head bigger -.ps +2 -.ft B -.ne (2v + 1u) -.if \\n[.$] \&\\$* -.. -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" BB/BE - put background/screen (filled box) around block of text -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.de BB -.if t \{\ -.sp -.5 -.br -.in +2n -.ll -2n -.gcolor red -.di BX -.\} -.. -.de EB -.if t \{\ -.if "\\$2"adjust-for-leading-newline" \{\ -.sp -1 -.\} -.br -.di -.in -.ll -.gcolor -.nr BW \\n(.lu-\\n(.i -.nr BH \\n(dn+.5v -.ne \\n(BHu+.5v -.ie "\\$2"adjust-for-leading-newline" \{\ -\M[\\$1]\h'1n'\v'+.5v'\D'P \\n(BWu 0 0 \\n(BHu -\\n(BWu 0 0 -\\n(BHu'\M[] -.\} -.el \{\ -\M[\\$1]\h'1n'\v'-.5v'\D'P \\n(BWu 0 0 \\n(BHu -\\n(BWu 0 0 -\\n(BHu'\M[] -.\} -.in 0 -.sp -.5v -.nf -.BX -.in -.sp .5v -.fi -.\} -.. -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" BM/EM - put colored marker in margin next to block of text -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.de BM -.if t \{\ -.br -.ll -2n -.gcolor red -.di BX -.\} -.. -.de EM -.if t \{\ -.br -.di -.ll -.gcolor -.nr BH \\n(dn -.ne \\n(BHu -\M[\\$1]\D'P -.75n 0 0 \\n(BHu -(\\n[.i]u - \\n(INu - .75n) 0 0 -\\n(BHu'\M[] -.in 0 -.nf -.BX -.in -.fi -.\} -.. +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- @@ -166,20 +27,20 @@ .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- -.SH "Name" -pam_lastlog \- PAM module to display date of last login -.SH "Synopsis" -.fam C +.SH "NAME" +pam_lastlog \- PAM module to display date of last login and perform inactive account lock out +.SH "SYNOPSIS" .HP \w'\fBpam_lastlog\&.so\fR\ 'u -\fBpam_lastlog\&.so\fR [debug] [silent] [never] [nodate] [nohost] [noterm] [nowtmp] [noupdate] [showfailed] -.fam +\fBpam_lastlog\&.so\fR [debug] [silent] [never] [nodate] [nohost] [noterm] [nowtmp] [noupdate] [showfailed] [inactive=<days>] .SH "DESCRIPTION" .PP pam_lastlog is a PAM module to display a line of information about the last login of the user\&. In addition, the module maintains the -\FC/var/log/lastlog\F[] +/var/log/lastlog file\&. .PP Some applications may perform this function themselves\&. In such cases, this module is not necessary\&. +.PP +If the module is called in the auth or account phase, the accounts that were not used recently enough will be disallowed to log in\&. The check is not performed for the root account so the root is never locked out\&. .SH "OPTIONS" .PP \fBdebug\fR @@ -189,41 +50,41 @@ Print debug information\&. .PP \fBsilent\fR .RS 4 -Don\'t inform the user about any previous login, just update the -\FC/var/log/lastlog\F[] +Don\*(Aqt inform the user about any previous login, just update the +/var/log/lastlog file\&. .RE .PP \fBnever\fR .RS 4 If the -\FC/var/log/lastlog\F[] +/var/log/lastlog file does not contain any old entries for the user, indicate that the user has never previously logged in with a welcome message\&. .RE .PP \fBnodate\fR .RS 4 -Don\'t display the date of the last login\&. +Don\*(Aqt display the date of the last login\&. .RE .PP \fBnoterm\fR .RS 4 -Don\'t display the terminal name on which the last login was attempted\&. +Don\*(Aqt display the terminal name on which the last login was attempted\&. .RE .PP \fBnohost\fR .RS 4 -Don\'t indicate from which host the last login was attempted\&. +Don\*(Aqt indicate from which host the last login was attempted\&. .RE .PP \fBnowtmp\fR .RS 4 -Don\'t update the wtmp entry\&. +Don\*(Aqt update the wtmp entry\&. .RE .PP \fBnoupdate\fR .RS 4 -Don\'t update any file\&. +Don\*(Aqt update any file\&. .RE .PP \fBshowfailed\fR @@ -232,11 +93,20 @@ Display number of failed login attempts and the date of the last failed attempt \fBnodate\fR is specified\&. .RE +.PP +\fBinactive=<days>\fR +.RS 4 +This option is specific for the auth or account phase\&. It specifies the number of days after the last login of the user when the user will be locked out by the module\&. The default value is 90\&. +.RE .SH "MODULE TYPES PROVIDED" .PP -Only the +The +\fBauth\fR +and +\fBaccount\fR +module type allows to lock out users which did not login recently enough\&. The \fBsession\fR -module type is provided\&. +module type is provided for displaying the information about the last login and/or updating the lastlog and wtmp files\&. .SH "RETURN VALUES" .PP .PP @@ -254,48 +124,58 @@ PAM_USER_UNKNOWN .RS 4 User not known\&. .RE +.PP +PAM_AUTH_ERR +.RS 4 +User locked out in the auth or account phase due to inactivity\&. +.RE +.PP +PAM_IGNORE +.RS 4 +There was an error during reading the lastlog file in the auth or account phase and thus inactivity of the user cannot be determined\&. +.RE .SH "EXAMPLES" .PP Add the following line to -\FC/etc/pam\&.d/login\F[] +/etc/pam\&.d/login to display the last login time of an user: .sp .if n \{\ .RS 4 .\} -.fam C -.ps -1 .nf -.if t \{\ -.sp -1 -.\} -.BB lightgray adjust-for-leading-newline -.sp -1 - session required pam_lastlog\&.so nowtmp -.EB lightgray adjust-for-leading-newline -.if t \{\ -.sp 1 +.fi +.if n \{\ +.RE +.\} +.PP +To reject the user if he did not login during the previous 50 days the following line can be used: +.sp +.if n \{\ +.RS 4 .\} +.nf + auth required pam_lastlog\&.so inactive=50 + .fi -.fam -.ps +1 .if n \{\ .RE .\} .SH "FILES" .PP -\FC/var/log/lastlog\F[] +/var/log/lastlog .RS 4 Lastlog logging file .RE .SH "SEE ALSO" .PP - \fBpam.conf\fR(5), \fBpam.d\fR(5), \fBpam\fR(8) .SH "AUTHOR" .PP pam_lastlog was written by Andrew G\&. Morgan <morgan@kernel\&.org>\&. +.PP +Inactive account lock out added by Tomáš Mráz <tm@t8m\&.info>\&. diff --git a/modules/pam_lastlog/pam_lastlog.8.xml b/modules/pam_lastlog/pam_lastlog.8.xml index 2a6794a..77da9db 100644 --- a/modules/pam_lastlog/pam_lastlog.8.xml +++ b/modules/pam_lastlog/pam_lastlog.8.xml @@ -12,7 +12,7 @@ <refnamediv id="pam_lastlog-name"> <refname>pam_lastlog</refname> - <refpurpose>PAM module to display date of last login</refpurpose> + <refpurpose>PAM module to display date of last login and perform inactive account lock out</refpurpose> </refnamediv> <refsynopsisdiv> @@ -45,6 +45,9 @@ <arg choice="opt"> showfailed </arg> + <arg choice="opt"> + inactive=<days> + </arg> </cmdsynopsis> </refsynopsisdiv> @@ -61,6 +64,12 @@ Some applications may perform this function themselves. In such cases, this module is not necessary. </para> + <para> + If the module is called in the auth or account phase, the accounts that + were not used recently enough will be disallowed to log in. The + check is not performed for the root account so the root is never + locked out. + </para> </refsect1> <refsect1 id="pam_lastlog-options"> @@ -165,13 +174,30 @@ </para> </listitem> </varlistentry> + <varlistentry> + <term> + <option>inactive=<days></option> + </term> + <listitem> + <para> + This option is specific for the auth or account phase. It + specifies the number of days after the last login of the user + when the user will be locked out by the module. The default + value is 90. + </para> + </listitem> + </varlistentry> </variablelist> </refsect1> <refsect1 id="pam_lastlog-types"> <title>MODULE TYPES PROVIDED</title> <para> - Only the <option>session</option> module type is provided. + The <option>auth</option> and <option>account</option> module type + allows to lock out users which did not login recently enough. + The <option>session</option> module type is provided for displaying + the information about the last login and/or updating the lastlog and + wtmp files. </para> </refsect1> @@ -207,6 +233,27 @@ </listitem> </varlistentry> + <varlistentry> + <term>PAM_AUTH_ERR</term> + <listitem> + <para> + User locked out in the auth or account phase due to + inactivity. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>PAM_IGNORE</term> + <listitem> + <para> + There was an error during reading the lastlog file + in the auth or account phase and thus inactivity + of the user cannot be determined. + </para> + </listitem> + </varlistentry> + </variablelist> </para> </refsect1> @@ -220,6 +267,13 @@ <programlisting> session required pam_lastlog.so nowtmp </programlisting> + <para> + To reject the user if he did not login during the previous 50 days + the following line can be used: + </para> + <programlisting> + auth required pam_lastlog.so inactive=50 + </programlisting> </refsect1> <refsect1 id="pam_lastlog-files"> @@ -254,6 +308,9 @@ <para> pam_lastlog was written by Andrew G. Morgan <morgan@kernel.org>. </para> + <para> + Inactive account lock out added by Tomáš Mráz <tm@t8m.info>. + </para> </refsect1> </refentry> diff --git a/modules/pam_lastlog/pam_lastlog.c b/modules/pam_lastlog/pam_lastlog.c index 9e8da7d..bd454ff 100644 --- a/modules/pam_lastlog/pam_lastlog.c +++ b/modules/pam_lastlog/pam_lastlog.c @@ -56,6 +56,9 @@ struct lastlog { #define DEFAULT_HOST "" /* "[no.where]" */ #define DEFAULT_TERM "" /* "tt???" */ +#define DEFAULT_INACTIVE_DAYS 90 +#define MAX_INACTIVE_DAYS 100000 + /* * here, we make a definition for the externally accessible function * in this file (this definition is required for static a module @@ -64,6 +67,8 @@ struct lastlog { */ #define PAM_SM_SESSION +#define PAM_SM_AUTH +#define PAM_SM_ACCOUNT #include <security/pam_modules.h> #include <security/_pam_macros.h> @@ -83,7 +88,45 @@ struct lastlog { #define LASTLOG_UPDATE 0400 /* update the lastlog and wtmp files (default) */ static int -_pam_parse(pam_handle_t *pamh, int flags, int argc, const char **argv) +_pam_auth_parse(pam_handle_t *pamh, int flags, int argc, const char **argv, + time_t *inactive) +{ + int ctrl = 0; + + *inactive = DEFAULT_INACTIVE_DAYS; + + /* does the appliction require quiet? */ + if (flags & PAM_SILENT) { + ctrl |= LASTLOG_QUIET; + } + + /* step through arguments */ + for (; argc-- > 0; ++argv) { + char *ep = NULL; + long l; + + if (!strcmp(*argv,"debug")) { + ctrl |= LASTLOG_DEBUG; + } else if (!strcmp(*argv,"silent")) { + ctrl |= LASTLOG_QUIET; + } else if (!strncmp(*argv,"inactive=", 9)) { + l = strtol(*argv+9, &ep, 10); + if (ep != *argv+9 && l > 0 && l < MAX_INACTIVE_DAYS) + *inactive = l; + else { + pam_syslog(pamh, LOG_ERR, "bad option value: %s", *argv); + } + } else { + pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv); + } + } + + D(("ctrl = %o", ctrl)); + return ctrl; +} + +static int +_pam_session_parse(pam_handle_t *pamh, int flags, int argc, const char **argv) { int ctrl=(LASTLOG_DATE|LASTLOG_HOST|LASTLOG_LINE|LASTLOG_WTMP|LASTLOG_UPDATE); @@ -145,6 +188,44 @@ get_tty(pam_handle_t *pamh) } static int +last_login_open(pam_handle_t *pamh, int announce, uid_t uid) +{ + int last_fd; + + /* obtain the last login date and all the relevant info */ + last_fd = open(_PATH_LASTLOG, announce&LASTLOG_UPDATE ? O_RDWR : O_RDONLY); + if (last_fd < 0) { + if (errno == ENOENT && (announce & LASTLOG_UPDATE)) { + last_fd = open(_PATH_LASTLOG, O_RDWR|O_CREAT, + S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); + if (last_fd < 0) { + pam_syslog(pamh, LOG_ERR, + "unable to create %s: %m", _PATH_LASTLOG); + D(("unable to create %s file", _PATH_LASTLOG)); + return -1; + } + pam_syslog(pamh, LOG_WARNING, + "file %s created", _PATH_LASTLOG); + D(("file %s created", _PATH_LASTLOG)); + } else { + pam_syslog(pamh, LOG_ERR, "unable to open %s: %m", _PATH_LASTLOG); + D(("unable to open %s file", _PATH_LASTLOG)); + return -1; + } + } + + if (lseek(last_fd, sizeof(struct lastlog) * (off_t) uid, SEEK_SET) < 0) { + pam_syslog(pamh, LOG_ERR, "failed to lseek %s: %m", _PATH_LASTLOG); + D(("unable to lseek %s file", _PATH_LASTLOG)); + close(last_fd); + return -1; + } + + return last_fd; +} + + +static int last_login_read(pam_handle_t *pamh, int announce, int last_fd, uid_t uid, time_t *lltime) { struct flock last_lock; @@ -338,31 +419,9 @@ last_login_date(pam_handle_t *pamh, int announce, uid_t uid, const char *user, t int last_fd; /* obtain the last login date and all the relevant info */ - last_fd = open(_PATH_LASTLOG, announce&LASTLOG_UPDATE ? O_RDWR : O_RDONLY); + last_fd = last_login_open(pamh, announce, uid); if (last_fd < 0) { - if (errno == ENOENT) { - last_fd = open(_PATH_LASTLOG, O_RDWR|O_CREAT, - S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); - if (last_fd < 0) { - pam_syslog(pamh, LOG_ERR, - "unable to create %s: %m", _PATH_LASTLOG); - D(("unable to create %s file", _PATH_LASTLOG)); - return PAM_SERVICE_ERR; - } - pam_syslog(pamh, LOG_WARNING, - "file %s created", _PATH_LASTLOG); - D(("file %s created", _PATH_LASTLOG)); - } else { - pam_syslog(pamh, LOG_ERR, "unable to open %s: %m", _PATH_LASTLOG); - D(("unable to open %s file", _PATH_LASTLOG)); - return PAM_SERVICE_ERR; - } - } - - if (lseek(last_fd, sizeof(struct lastlog) * (off_t) uid, SEEK_SET) < 0) { - pam_syslog(pamh, LOG_ERR, "failed to lseek %s: %m", _PATH_LASTLOG); - D(("unable to lseek %s file", _PATH_LASTLOG)); - return PAM_SERVICE_ERR; + return PAM_SERVICE_ERR; } retval = last_login_read(pamh, announce, last_fd, uid, lltime); @@ -420,6 +479,10 @@ last_login_failed(pam_handle_t *pamh, int announce, const char *user, time_t llt } } + if (retval != 0) + pam_syslog(pamh, LOG_WARNING, "corruption detected in %s", _PATH_BTMP); + retval = PAM_SUCCESS; + if (failed) { /* we want the date? */ if (announce & LASTLOG_DATE) { @@ -502,7 +565,91 @@ cleanup: return retval; } -/* --- authentication management functions (only) --- */ +/* --- authentication (locking out inactive users) functions --- */ +PAM_EXTERN int +pam_sm_authenticate(pam_handle_t *pamh, int flags, + int argc, const char **argv) +{ + int retval, ctrl; + const char *user = NULL; + const struct passwd *pwd; + uid_t uid; + time_t lltime = 0; + time_t inactive_days = 0; + int last_fd; + + /* + * Lock out the user if he did not login recently enough. + */ + + ctrl = _pam_auth_parse(pamh, flags, argc, argv, &inactive_days); + + /* which user? */ + + if (pam_get_user(pamh, &user, NULL) != PAM_SUCCESS || user == NULL + || *user == '\0') { + pam_syslog(pamh, LOG_ERR, "cannot determine the user's name"); + return PAM_USER_UNKNOWN; + } + + /* what uid? */ + + pwd = pam_modutil_getpwnam (pamh, user); + if (pwd == NULL) { + pam_syslog(pamh, LOG_ERR, "user unknown"); + return PAM_USER_UNKNOWN; + } + uid = pwd->pw_uid; + pwd = NULL; /* tidy up */ + + if (uid == 0) + return PAM_SUCCESS; + + /* obtain the last login date and all the relevant info */ + last_fd = last_login_open(pamh, ctrl, uid); + if (last_fd < 0) { + return PAM_IGNORE; + } + + retval = last_login_read(pamh, ctrl|LASTLOG_QUIET, last_fd, uid, &lltime); + close(last_fd); + + if (retval != PAM_SUCCESS) { + D(("error while reading lastlog file")); + return PAM_IGNORE; + } + + if (lltime == 0) { /* user never logged in before */ + if (ctrl & LASTLOG_DEBUG) + pam_syslog(pamh, LOG_DEBUG, "user never logged in - pass"); + return PAM_SUCCESS; + } + + lltime = (time(NULL) - lltime) / (24*60*60); + + if (lltime > inactive_days) { + pam_syslog(pamh, LOG_INFO, "user %s inactive for %d days - denied", user, lltime); + return PAM_AUTH_ERR; + } + + return PAM_SUCCESS; +} + +PAM_EXTERN int +pam_sm_setcred(pam_handle_t *pamh UNUSED, int flags UNUSED, + int argc UNUSED, const char **argv UNUSED) +{ + return PAM_SUCCESS; +} + +PAM_EXTERN int +pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, + int argc, const char **argv) +{ + return pam_sm_authenticate(pamh, flags, argc, argv); +} + +/* --- session management functions --- */ PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags, @@ -519,7 +666,7 @@ pam_sm_open_session(pam_handle_t *pamh, int flags, * last login info and then updates the lastlog for that user. */ - ctrl = _pam_parse(pamh, flags, argc, argv); + ctrl = _pam_session_parse(pamh, flags, argc, argv); /* which user? */ @@ -560,7 +707,7 @@ pam_sm_close_session (pam_handle_t *pamh, int flags, { const char *terminal_line; - if (!(_pam_parse(pamh, flags, argc, argv) & LASTLOG_WTMP)) + if (!(_pam_session_parse(pamh, flags, argc, argv) & LASTLOG_WTMP)) return PAM_SUCCESS; terminal_line = get_tty(pamh); @@ -577,9 +724,9 @@ pam_sm_close_session (pam_handle_t *pamh, int flags, struct pam_module _pam_lastlog_modstruct = { "pam_lastlog", - NULL, - NULL, - NULL, + pam_sm_authenticate, + pam_sm_setcred, + pam_sm_acct_mgmt, pam_sm_open_session, pam_sm_close_session, NULL, |