aboutsummaryrefslogtreecommitdiff
path: root/modules/pam_pwhistory
diff options
context:
space:
mode:
Diffstat (limited to 'modules/pam_pwhistory')
-rw-r--r--modules/pam_pwhistory/Makefile.am20
-rw-r--r--modules/pam_pwhistory/Makefile.in196
-rw-r--r--modules/pam_pwhistory/README20
-rw-r--r--modules/pam_pwhistory/README.xml32
-rw-r--r--modules/pam_pwhistory/opasswd.c78
-rw-r--r--modules/pam_pwhistory/opasswd.h8
-rw-r--r--modules/pam_pwhistory/pam_pwhistory.851
-rw-r--r--modules/pam_pwhistory/pam_pwhistory.8.xml117
-rw-r--r--modules/pam_pwhistory/pam_pwhistory.c45
-rw-r--r--modules/pam_pwhistory/pwhistory.conf21
-rw-r--r--modules/pam_pwhistory/pwhistory.conf.5118
-rw-r--r--modules/pam_pwhistory/pwhistory.conf.5.xml152
-rw-r--r--modules/pam_pwhistory/pwhistory_config.c131
-rw-r--r--modules/pam_pwhistory/pwhistory_config.h54
-rw-r--r--modules/pam_pwhistory/pwhistory_helper.88
-rw-r--r--modules/pam_pwhistory/pwhistory_helper.8.xml23
-rw-r--r--modules/pam_pwhistory/pwhistory_helper.c22
-rw-r--r--modules/pam_pwhistory/tst-pam_pwhistory-retval.c60
18 files changed, 966 insertions, 190 deletions
diff --git a/modules/pam_pwhistory/Makefile.am b/modules/pam_pwhistory/Makefile.am
index 8a4dbcb2..6cd5ffd3 100644
--- a/modules/pam_pwhistory/Makefile.am
+++ b/modules/pam_pwhistory/Makefile.am
@@ -9,14 +9,19 @@ MAINTAINERCLEANFILES = $(MANS) README
EXTRA_DIST = $(XMLS)
if HAVE_DOC
-dist_man_MANS = pam_pwhistory.8 pwhistory_helper.8
+dist_man_MANS = pam_pwhistory.8 pwhistory_helper.8 pwhistory.conf.5
endif
-XMLS = README.xml pam_pwhistory.8.xml pwhistory_helper.8.xml
+XMLS = README.xml pam_pwhistory.8.xml pwhistory_helper.8.xml \
+ pwhistory.conf.5.xml
dist_check_SCRIPTS = tst-pam_pwhistory
-TESTS = $(dist_check_SCRIPTS)
+TESTS = $(dist_check_SCRIPTS) $(check_PROGRAMS)
securelibdir = $(SECUREDIR)
+if HAVE_VENDORDIR
+secureconfdir = $(VENDOR_SCONFIGDIR)
+else
secureconfdir = $(SCONFIGDIR)
+endif
AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
$(WARN_CFLAGS) -DPWHISTORY_HELPER=\"$(sbindir)/pwhistory_helper\"
@@ -26,12 +31,14 @@ if HAVE_VERSIONING
pam_pwhistory_la_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
endif
-noinst_HEADERS = opasswd.h
+noinst_HEADERS = opasswd.h pwhistory_config.h
+
+dist_secureconf_DATA = pwhistory.conf
securelib_LTLIBRARIES = pam_pwhistory.la
pam_pwhistory_la_CFLAGS = $(AM_CFLAGS)
pam_pwhistory_la_LIBADD = $(top_builddir)/libpam/libpam.la @LIBCRYPT@ @LIBSELINUX@
-pam_pwhistory_la_SOURCES = pam_pwhistory.c opasswd.c
+pam_pwhistory_la_SOURCES = pam_pwhistory.c opasswd.c pwhistory_config.c
sbin_PROGRAMS = pwhistory_helper
pwhistory_helper_CFLAGS = $(AM_CFLAGS) -DHELPER_COMPILE=\"pwhistory_helper\" @EXE_CFLAGS@
@@ -39,6 +46,9 @@ pwhistory_helper_SOURCES = pwhistory_helper.c opasswd.c
pwhistory_helper_LDFLAGS = @EXE_LDFLAGS@
pwhistory_helper_LDADD = $(top_builddir)/libpam/libpam.la @LIBCRYPT@
+check_PROGRAMS = tst-pam_pwhistory-retval
+tst_pam_pwhistory_retval_LDADD = $(top_builddir)/libpam/libpam.la
+
if ENABLE_REGENERATE_MAN
dist_noinst_DATA = README
-include $(top_srcdir)/Make.xml.rules
diff --git a/modules/pam_pwhistory/Makefile.in b/modules/pam_pwhistory/Makefile.in
index cf1082b0..dcb969ac 100644
--- a/modules/pam_pwhistory/Makefile.in
+++ b/modules/pam_pwhistory/Makefile.in
@@ -98,6 +98,7 @@ build_triplet = @build@
host_triplet = @host@
@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
sbin_PROGRAMS = pwhistory_helper$(EXEEXT)
+check_PROGRAMS = tst-pam_pwhistory-retval$(EXEEXT)
subdir = modules/pam_pwhistory
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
@@ -118,14 +119,15 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \
- $(am__dist_noinst_DATA_DIST) $(noinst_HEADERS) \
- $(am__DIST_COMMON)
+ $(am__dist_noinst_DATA_DIST) $(dist_secureconf_DATA) \
+ $(noinst_HEADERS) $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am__installdirs = "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(securelibdir)" \
- "$(DESTDIR)$(man8dir)"
+ "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man8dir)" \
+ "$(DESTDIR)$(secureconfdir)"
PROGRAMS = $(sbin_PROGRAMS)
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
@@ -157,7 +159,8 @@ am__uninstall_files_from_dir = { \
LTLIBRARIES = $(securelib_LTLIBRARIES)
pam_pwhistory_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
am_pam_pwhistory_la_OBJECTS = pam_pwhistory_la-pam_pwhistory.lo \
- pam_pwhistory_la-opasswd.lo
+ pam_pwhistory_la-opasswd.lo \
+ pam_pwhistory_la-pwhistory_config.lo
pam_pwhistory_la_OBJECTS = $(am_pam_pwhistory_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@@ -176,6 +179,10 @@ pwhistory_helper_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
$(pwhistory_helper_CFLAGS) $(CFLAGS) \
$(pwhistory_helper_LDFLAGS) $(LDFLAGS) -o $@
+tst_pam_pwhistory_retval_SOURCES = tst-pam_pwhistory-retval.c
+tst_pam_pwhistory_retval_OBJECTS = tst-pam_pwhistory-retval.$(OBJEXT)
+tst_pam_pwhistory_retval_DEPENDENCIES = \
+ $(top_builddir)/libpam/libpam.la
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
@@ -193,8 +200,10 @@ depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
am__maybe_remake_depfiles = depfiles
am__depfiles_remade = ./$(DEPDIR)/pam_pwhistory_la-opasswd.Plo \
./$(DEPDIR)/pam_pwhistory_la-pam_pwhistory.Plo \
+ ./$(DEPDIR)/pam_pwhistory_la-pwhistory_config.Plo \
./$(DEPDIR)/pwhistory_helper-opasswd.Po \
- ./$(DEPDIR)/pwhistory_helper-pwhistory_helper.Po
+ ./$(DEPDIR)/pwhistory_helper-pwhistory_helper.Po \
+ ./$(DEPDIR)/tst-pam_pwhistory-retval.Po
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
@@ -214,18 +223,21 @@ AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
-SOURCES = $(pam_pwhistory_la_SOURCES) $(pwhistory_helper_SOURCES)
-DIST_SOURCES = $(pam_pwhistory_la_SOURCES) $(pwhistory_helper_SOURCES)
+SOURCES = $(pam_pwhistory_la_SOURCES) $(pwhistory_helper_SOURCES) \
+ tst-pam_pwhistory-retval.c
+DIST_SOURCES = $(pam_pwhistory_la_SOURCES) $(pwhistory_helper_SOURCES) \
+ tst-pam_pwhistory-retval.c
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
+man5dir = $(mandir)/man5
man8dir = $(mandir)/man8
NROFF = nroff
MANS = $(dist_man_MANS)
am__dist_noinst_DATA_DIST = README
-DATA = $(dist_noinst_DATA)
+DATA = $(dist_noinst_DATA) $(dist_secureconf_DATA)
HEADERS = $(noinst_HEADERS)
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
@@ -453,6 +465,7 @@ CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
+DOCBOOK_RNG = @DOCBOOK_RNG@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -465,11 +478,13 @@ EXEEXT = @EXEEXT@
EXE_CFLAGS = @EXE_CFLAGS@
EXE_LDFLAGS = @EXE_LDFLAGS@
FGREP = @FGREP@
+FILECMD = @FILECMD@
FO2PDF = @FO2PDF@
GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
GMSGFMT = @GMSGFMT@
GMSGFMT_015 = @GMSGFMT_015@
GREP = @GREP@
+HTML_STYLESHEET = @HTML_STYLESHEET@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
@@ -501,12 +516,14 @@ LIBSELINUX = @LIBSELINUX@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
+LOGIND_CFLAGS = @LOGIND_CFLAGS@
LTLIBICONV = @LTLIBICONV@
LTLIBINTL = @LTLIBINTL@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
+MAN_STYLESHEET = @MAN_STYLESHEET@
MKDIR_P = @MKDIR_P@
MSGFMT = @MSGFMT@
MSGFMT_015 = @MSGFMT_015@
@@ -529,6 +546,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
+PDF_STYLESHEET = @PDF_STYLESHEET@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
@@ -539,12 +557,16 @@ SECUREDIR = @SECUREDIR@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
-STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_PROFILECONDITIONS = @STRINGPARAM_PROFILECONDITIONS@
STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
STRIP = @STRIP@
+SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@
+SYSTEMD_LIBS = @SYSTEMD_LIBS@
TIRPC_CFLAGS = @TIRPC_CFLAGS@
TIRPC_LIBS = @TIRPC_LIBS@
+TXT_STYLESHEET = @TXT_STYLESHEET@
USE_NLS = @USE_NLS@
+VENDOR_SCONFIGDIR = @VENDOR_SCONFIGDIR@
VERSION = @VERSION@
WARN_CFLAGS = @WARN_CFLAGS@
XGETTEXT = @XGETTEXT@
@@ -613,26 +635,31 @@ top_srcdir = @top_srcdir@
CLEANFILES = *~
MAINTAINERCLEANFILES = $(MANS) README
EXTRA_DIST = $(XMLS)
-@HAVE_DOC_TRUE@dist_man_MANS = pam_pwhistory.8 pwhistory_helper.8
-XMLS = README.xml pam_pwhistory.8.xml pwhistory_helper.8.xml
+@HAVE_DOC_TRUE@dist_man_MANS = pam_pwhistory.8 pwhistory_helper.8 pwhistory.conf.5
+XMLS = README.xml pam_pwhistory.8.xml pwhistory_helper.8.xml \
+ pwhistory.conf.5.xml
+
dist_check_SCRIPTS = tst-pam_pwhistory
-TESTS = $(dist_check_SCRIPTS)
+TESTS = $(dist_check_SCRIPTS) $(check_PROGRAMS)
securelibdir = $(SECUREDIR)
-secureconfdir = $(SCONFIGDIR)
+@HAVE_VENDORDIR_FALSE@secureconfdir = $(SCONFIGDIR)
+@HAVE_VENDORDIR_TRUE@secureconfdir = $(VENDOR_SCONFIGDIR)
AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
$(WARN_CFLAGS) -DPWHISTORY_HELPER=\"$(sbindir)/pwhistory_helper\"
pam_pwhistory_la_LDFLAGS = -no-undefined -avoid-version -module \
$(am__append_1)
-noinst_HEADERS = opasswd.h
+noinst_HEADERS = opasswd.h pwhistory_config.h
+dist_secureconf_DATA = pwhistory.conf
securelib_LTLIBRARIES = pam_pwhistory.la
pam_pwhistory_la_CFLAGS = $(AM_CFLAGS)
pam_pwhistory_la_LIBADD = $(top_builddir)/libpam/libpam.la @LIBCRYPT@ @LIBSELINUX@
-pam_pwhistory_la_SOURCES = pam_pwhistory.c opasswd.c
+pam_pwhistory_la_SOURCES = pam_pwhistory.c opasswd.c pwhistory_config.c
pwhistory_helper_CFLAGS = $(AM_CFLAGS) -DHELPER_COMPILE=\"pwhistory_helper\" @EXE_CFLAGS@
pwhistory_helper_SOURCES = pwhistory_helper.c opasswd.c
pwhistory_helper_LDFLAGS = @EXE_LDFLAGS@
pwhistory_helper_LDADD = $(top_builddir)/libpam/libpam.la @LIBCRYPT@
+tst_pam_pwhistory_retval_LDADD = $(top_builddir)/libpam/libpam.la
@ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README
all: all-am
@@ -667,6 +694,15 @@ $(top_srcdir)/configure: $(am__configure_deps)
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
+
+clean-checkPROGRAMS:
+ @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
install-sbinPROGRAMS: $(sbin_PROGRAMS)
@$(NORMAL_INSTALL)
@list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
@@ -759,6 +795,10 @@ pwhistory_helper$(EXEEXT): $(pwhistory_helper_OBJECTS) $(pwhistory_helper_DEPEND
@rm -f pwhistory_helper$(EXEEXT)
$(AM_V_CCLD)$(pwhistory_helper_LINK) $(pwhistory_helper_OBJECTS) $(pwhistory_helper_LDADD) $(LIBS)
+tst-pam_pwhistory-retval$(EXEEXT): $(tst_pam_pwhistory_retval_OBJECTS) $(tst_pam_pwhistory_retval_DEPENDENCIES) $(EXTRA_tst_pam_pwhistory_retval_DEPENDENCIES)
+ @rm -f tst-pam_pwhistory-retval$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(tst_pam_pwhistory_retval_OBJECTS) $(tst_pam_pwhistory_retval_LDADD) $(LIBS)
+
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@@ -767,8 +807,10 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_pwhistory_la-opasswd.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_pwhistory_la-pam_pwhistory.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_pwhistory_la-pwhistory_config.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pwhistory_helper-opasswd.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pwhistory_helper-pwhistory_helper.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-pam_pwhistory-retval.Po@am__quote@ # am--include-marker
$(am__depfiles_remade):
@$(MKDIR_P) $(@D)
@@ -811,6 +853,13 @@ pam_pwhistory_la-opasswd.lo: opasswd.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_pwhistory_la_CFLAGS) $(CFLAGS) -c -o pam_pwhistory_la-opasswd.lo `test -f 'opasswd.c' || echo '$(srcdir)/'`opasswd.c
+pam_pwhistory_la-pwhistory_config.lo: pwhistory_config.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_pwhistory_la_CFLAGS) $(CFLAGS) -MT pam_pwhistory_la-pwhistory_config.lo -MD -MP -MF $(DEPDIR)/pam_pwhistory_la-pwhistory_config.Tpo -c -o pam_pwhistory_la-pwhistory_config.lo `test -f 'pwhistory_config.c' || echo '$(srcdir)/'`pwhistory_config.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pam_pwhistory_la-pwhistory_config.Tpo $(DEPDIR)/pam_pwhistory_la-pwhistory_config.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pwhistory_config.c' object='pam_pwhistory_la-pwhistory_config.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_pwhistory_la_CFLAGS) $(CFLAGS) -c -o pam_pwhistory_la-pwhistory_config.lo `test -f 'pwhistory_config.c' || echo '$(srcdir)/'`pwhistory_config.c
+
pwhistory_helper-pwhistory_helper.o: pwhistory_helper.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pwhistory_helper_CFLAGS) $(CFLAGS) -MT pwhistory_helper-pwhistory_helper.o -MD -MP -MF $(DEPDIR)/pwhistory_helper-pwhistory_helper.Tpo -c -o pwhistory_helper-pwhistory_helper.o `test -f 'pwhistory_helper.c' || echo '$(srcdir)/'`pwhistory_helper.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pwhistory_helper-pwhistory_helper.Tpo $(DEPDIR)/pwhistory_helper-pwhistory_helper.Po
@@ -844,6 +893,49 @@ mostlyclean-libtool:
clean-libtool:
-rm -rf .libs _libs
+install-man5: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man5dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man5dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man5dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.5[a-z]*$$/p'; \
+ fi; \
+ } | 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,^[^5][0-9a-z]*$$,5,;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)$(man5dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man5dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man5dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man5dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man5:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man5dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.5[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man5dir)'; $(am__uninstall_files_from_dir)
install-man8: $(dist_man_MANS)
@$(NORMAL_INSTALL)
@list1=''; \
@@ -887,6 +979,27 @@ uninstall-man8:
} | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
-e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+install-dist_secureconfDATA: $(dist_secureconf_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(dist_secureconf_DATA)'; test -n "$(secureconfdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(secureconfdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(secureconfdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(secureconfdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(secureconfdir)" || exit $$?; \
+ done
+
+uninstall-dist_secureconfDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(dist_secureconf_DATA)'; test -n "$(secureconfdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(secureconfdir)'; $(am__uninstall_files_from_dir)
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
@@ -1060,7 +1173,7 @@ $(TEST_SUITE_LOG): $(TEST_LOGS)
fi; \
$$success || exit 1
-check-TESTS: $(dist_check_SCRIPTS)
+check-TESTS: $(check_PROGRAMS) $(dist_check_SCRIPTS)
@list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
@list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
@@ -1070,7 +1183,7 @@ check-TESTS: $(dist_check_SCRIPTS)
log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
exit $$?;
-recheck: all $(dist_check_SCRIPTS)
+recheck: all $(check_PROGRAMS) $(dist_check_SCRIPTS)
@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
@set +e; $(am__set_TESTS_bases); \
bases=`for i in $$bases; do echo $$i; done \
@@ -1088,6 +1201,13 @@ tst-pam_pwhistory.log: tst-pam_pwhistory
--log-file $$b.log --trs-file $$b.trs \
$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
"$$tst" $(AM_TESTS_FD_REDIRECT)
+tst-pam_pwhistory-retval.log: tst-pam_pwhistory-retval$(EXEEXT)
+ @p='tst-pam_pwhistory-retval$(EXEEXT)'; \
+ b='tst-pam_pwhistory-retval'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
.test.log:
@p='$<'; \
$(am__set_b); \
@@ -1137,12 +1257,13 @@ distdir-am: $(DISTFILES)
fi; \
done
check-am: all-am
- $(MAKE) $(AM_MAKEFLAGS) $(dist_check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) \
+ $(dist_check_SCRIPTS)
$(MAKE) $(AM_MAKEFLAGS) check-TESTS
check: check-am
all-am: Makefile $(PROGRAMS) $(LTLIBRARIES) $(MANS) $(DATA) $(HEADERS)
installdirs:
- for dir in "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"; do \
+ for dir in "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(secureconfdir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
@@ -1182,14 +1303,16 @@ maintainer-clean-generic:
-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
clean: clean-am
-clean-am: clean-generic clean-libtool clean-sbinPROGRAMS \
- clean-securelibLTLIBRARIES mostlyclean-am
+clean-am: clean-checkPROGRAMS clean-generic clean-libtool \
+ clean-sbinPROGRAMS clean-securelibLTLIBRARIES mostlyclean-am
distclean: distclean-am
-rm -f ./$(DEPDIR)/pam_pwhistory_la-opasswd.Plo
-rm -f ./$(DEPDIR)/pam_pwhistory_la-pam_pwhistory.Plo
+ -rm -f ./$(DEPDIR)/pam_pwhistory_la-pwhistory_config.Plo
-rm -f ./$(DEPDIR)/pwhistory_helper-opasswd.Po
-rm -f ./$(DEPDIR)/pwhistory_helper-pwhistory_helper.Po
+ -rm -f ./$(DEPDIR)/tst-pam_pwhistory-retval.Po
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
@@ -1206,7 +1329,8 @@ info: info-am
info-am:
-install-data-am: install-man install-securelibLTLIBRARIES
+install-data-am: install-dist_secureconfDATA install-man \
+ install-securelibLTLIBRARIES
install-dvi: install-dvi-am
@@ -1222,7 +1346,7 @@ install-info: install-info-am
install-info-am:
-install-man: install-man8
+install-man: install-man5 install-man8
install-pdf: install-pdf-am
@@ -1237,8 +1361,10 @@ installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/pam_pwhistory_la-opasswd.Plo
-rm -f ./$(DEPDIR)/pam_pwhistory_la-pam_pwhistory.Plo
+ -rm -f ./$(DEPDIR)/pam_pwhistory_la-pwhistory_config.Plo
-rm -f ./$(DEPDIR)/pwhistory_helper-opasswd.Po
-rm -f ./$(DEPDIR)/pwhistory_helper-pwhistory_helper.Po
+ -rm -f ./$(DEPDIR)/tst-pam_pwhistory-retval.Po
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
@@ -1255,28 +1381,30 @@ ps: ps-am
ps-am:
-uninstall-am: uninstall-man uninstall-sbinPROGRAMS \
- uninstall-securelibLTLIBRARIES
+uninstall-am: uninstall-dist_secureconfDATA uninstall-man \
+ uninstall-sbinPROGRAMS uninstall-securelibLTLIBRARIES
-uninstall-man: uninstall-man8
+uninstall-man: uninstall-man5 uninstall-man8
.MAKE: check-am install-am install-strip
.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
- check-am clean clean-generic clean-libtool clean-sbinPROGRAMS \
- clean-securelibLTLIBRARIES cscopelist-am ctags ctags-am \
- distclean distclean-compile distclean-generic \
+ check-am clean clean-checkPROGRAMS clean-generic clean-libtool \
+ clean-sbinPROGRAMS clean-securelibLTLIBRARIES cscopelist-am \
+ ctags ctags-am 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-dvi install-dvi-am install-exec \
- install-exec-am install-html install-html-am install-info \
- install-info-am install-man install-man8 install-pdf \
- install-pdf-am install-ps install-ps-am install-sbinPROGRAMS \
+ install-data-am install-dist_secureconfDATA 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-sbinPROGRAMS \
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 \
- recheck tags tags-am uninstall uninstall-am uninstall-man \
+ recheck tags tags-am uninstall uninstall-am \
+ uninstall-dist_secureconfDATA uninstall-man uninstall-man5 \
uninstall-man8 uninstall-sbinPROGRAMS \
uninstall-securelibLTLIBRARIES
diff --git a/modules/pam_pwhistory/README b/modules/pam_pwhistory/README
index 161bebc7..b4868767 100644
--- a/modules/pam_pwhistory/README
+++ b/modules/pam_pwhistory/README
@@ -31,9 +31,9 @@ enforce_for_root
remember=N
- The last N passwords for each user are saved in /etc/security/opasswd. The
- default is 10. Value of 0 makes the module to keep the existing contents of
- the opasswd file unchanged.
+ The last N passwords for each user are saved. The default is 10. Value of 0
+ makes the module to keep the existing contents of the opasswd file
+ unchanged.
retry=N
@@ -43,6 +43,20 @@ authtok_type=STRING
See pam_get_authtok(3) for more details.
+file=/path/filename
+
+ Store password history in file /path/filename rather than the default
+ location. The default location is /etc/security/opasswd.
+
+conf=/path/to/config-file
+
+ Use another configuration file instead of the default /etc/security/
+ pwhistory.conf.
+
+The options for configuring the module behavior are described in the
+pwhistory.conf(5) manual page. The options specified on the module command line
+override the values from the configuration file.
+
EXAMPLES
An example password section would be:
diff --git a/modules/pam_pwhistory/README.xml b/modules/pam_pwhistory/README.xml
index f048e321..194edbc7 100644
--- a/modules/pam_pwhistory/README.xml
+++ b/modules/pam_pwhistory/README.xml
@@ -1,41 +1,27 @@
-<?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 pamaccess SYSTEM "pam_pwhistory.8.xml">
--->
-]>
+<article xmlns="http://docbook.org/ns/docbook" version="5.0">
-<article>
-
- <articleinfo>
+ <info>
<title>
- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
- href="pam_pwhistory.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_pwhistory-name"]/*)'/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_pwhistory.8.xml" xpointer='xpointer(id("pam_pwhistory-name")/*)'/>
</title>
- </articleinfo>
+ </info>
<section>
- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
- href="pam_pwhistory.8.xml" xpointer='xpointer(//refsect1[@id = "pam_pwhistory-description"]/*)'/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_pwhistory.8.xml" xpointer='xpointer(id("pam_pwhistory-description")/*)'/>
</section>
<section>
- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
- href="pam_pwhistory.8.xml" xpointer='xpointer(//refsect1[@id = "pam_pwhistory-options"]/*)'/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_pwhistory.8.xml" xpointer='xpointer(id("pam_pwhistory-options")/*)'/>
</section>
<section>
- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
- href="pam_pwhistory.8.xml" xpointer='xpointer(//refsect1[@id = "pam_pwhistory-examples"]/*)'/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_pwhistory.8.xml" xpointer='xpointer(id("pam_pwhistory-examples")/*)'/>
</section>
<section>
- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
- href="pam_pwhistory.8.xml" xpointer='xpointer(//refsect1[@id = "pam_pwhistory-author"]/*)'/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_pwhistory.8.xml" xpointer='xpointer(id("pam_pwhistory-author")/*)'/>
</section>
-</article>
+</article> \ No newline at end of file
diff --git a/modules/pam_pwhistory/opasswd.c b/modules/pam_pwhistory/opasswd.c
index a6cd3d2a..859b3da4 100644
--- a/modules/pam_pwhistory/opasswd.c
+++ b/modules/pam_pwhistory/opasswd.c
@@ -44,6 +44,7 @@
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
+#include <limits.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
@@ -67,6 +68,7 @@
#include <security/pam_ext.h>
#endif
#include <security/pam_modules.h>
+#include "pam_inline.h"
#include "opasswd.h"
@@ -74,8 +76,7 @@
#define RANDOM_DEVICE "/dev/urandom"
#endif
-#define OLD_PASSWORDS_FILE "/etc/security/opasswd"
-#define TMP_PASSWORDS_FILE OLD_PASSWORDS_FILE".tmpXXXXXX"
+#define DEFAULT_OLD_PASSWORDS_FILE SCONFIGDIR "/opasswd"
#define DEFAULT_BUFLEN 4096
@@ -129,6 +130,7 @@ compare_password(const char *newpass, const char *oldpass)
char *outval;
#ifdef HAVE_CRYPT_R
struct crypt_data output;
+ int retval;
output.initialized = 0;
@@ -137,12 +139,14 @@ compare_password(const char *newpass, const char *oldpass)
outval = crypt (newpass, oldpass);
#endif
- return outval != NULL && strcmp(outval, oldpass) == 0;
+ retval = outval != NULL && strcmp(outval, oldpass) == 0;
+ pam_overwrite_string(outval);
+ return retval;
}
/* Check, if the new password is already in the opasswd file. */
PAMH_ARG_DECL(int
-check_old_pass, const char *user, const char *newpass, int debug)
+check_old_pass, const char *user, const char *newpass, const char *filename, int debug)
{
int retval = PAM_SUCCESS;
FILE *oldpf;
@@ -156,10 +160,13 @@ check_old_pass, const char *user, const char *newpass, int debug)
return PAM_PWHISTORY_RUN_HELPER;
#endif
- if ((oldpf = fopen (OLD_PASSWORDS_FILE, "r")) == NULL)
+ const char *opasswd_file =
+ (filename != NULL ? filename : DEFAULT_OLD_PASSWORDS_FILE);
+
+ if ((oldpf = fopen (opasswd_file, "r")) == NULL)
{
if (errno != ENOENT)
- pam_syslog (pamh, LOG_ERR, "Cannot open %s: %m", OLD_PASSWORDS_FILE);
+ pam_syslog (pamh, LOG_ERR, "Cannot open %s: %m", opasswd_file);
return PAM_SUCCESS;
}
@@ -235,16 +242,15 @@ check_old_pass, const char *user, const char *newpass, int debug)
} while (oldpass != NULL);
}
- if (buf)
- free (buf);
+ pam_overwrite_n(buf, buflen);
+ free (buf);
return retval;
}
PAMH_ARG_DECL(int
-save_old_pass, const char *user, int howmany, int debug UNUSED)
+save_old_pass, const char *user, int howmany, const char *filename, int debug UNUSED)
{
- char opasswd_tmp[] = TMP_PASSWORDS_FILE;
struct stat opasswd_stat;
FILE *oldpf, *newpf;
int newpf_fd;
@@ -256,6 +262,15 @@ save_old_pass, const char *user, int howmany, int debug UNUSED)
struct passwd *pwd;
const char *oldpass;
+ /* Define opasswd file and temp file for opasswd */
+ const char *opasswd_file =
+ (filename != NULL ? filename : DEFAULT_OLD_PASSWORDS_FILE);
+ char opasswd_tmp[PATH_MAX];
+
+ if ((size_t) snprintf (opasswd_tmp, sizeof (opasswd_tmp), "%s.tmpXXXXXX",
+ opasswd_file) >= sizeof (opasswd_tmp))
+ return PAM_BUF_ERR;
+
pwd = pam_modutil_getpwnam (pamh, user);
if (pwd == NULL)
return PAM_USER_UNKNOWN;
@@ -285,24 +300,22 @@ save_old_pass, const char *user, int howmany, int debug UNUSED)
if (oldpass == NULL || *oldpass == '\0')
return PAM_SUCCESS;
- if ((oldpf = fopen (OLD_PASSWORDS_FILE, "r")) == NULL)
+ if ((oldpf = fopen (opasswd_file, "r")) == NULL)
{
if (errno == ENOENT)
{
- pam_syslog (pamh, LOG_NOTICE, "Creating %s",
- OLD_PASSWORDS_FILE);
+ pam_syslog (pamh, LOG_NOTICE, "Creating %s", opasswd_file);
do_create = 1;
}
else
{
- pam_syslog (pamh, LOG_ERR, "Cannot open %s: %m",
- OLD_PASSWORDS_FILE);
+ pam_syslog (pamh, LOG_ERR, "Cannot open %s: %m", opasswd_file);
return PAM_AUTHTOK_ERR;
}
}
else if (fstat (fileno (oldpf), &opasswd_stat) < 0)
{
- pam_syslog (pamh, LOG_ERR, "Cannot stat %s: %m", OLD_PASSWORDS_FILE);
+ pam_syslog (pamh, LOG_ERR, "Cannot stat %s: %m", opasswd_file);
fclose (oldpf);
return PAM_AUTHTOK_ERR;
}
@@ -312,7 +325,7 @@ save_old_pass, const char *user, int howmany, int debug UNUSED)
if (newpf_fd == -1)
{
pam_syslog (pamh, LOG_ERR, "Cannot create %s temp file: %m",
- OLD_PASSWORDS_FILE);
+ opasswd_file);
if (oldpf)
fclose (oldpf);
return PAM_AUTHTOK_ERR;
@@ -321,23 +334,19 @@ save_old_pass, const char *user, int howmany, int debug UNUSED)
{
if (fchmod (newpf_fd, S_IRUSR|S_IWUSR) != 0)
pam_syslog (pamh, LOG_ERR,
- "Cannot set permissions of %s temp file: %m",
- OLD_PASSWORDS_FILE);
+ "Cannot set permissions of %s temp file: %m", opasswd_file);
if (fchown (newpf_fd, 0, 0) != 0)
pam_syslog (pamh, LOG_ERR,
- "Cannot set owner/group of %s temp file: %m",
- OLD_PASSWORDS_FILE);
+ "Cannot set owner/group of %s temp file: %m", opasswd_file);
}
else
{
if (fchmod (newpf_fd, opasswd_stat.st_mode) != 0)
pam_syslog (pamh, LOG_ERR,
- "Cannot set permissions of %s temp file: %m",
- OLD_PASSWORDS_FILE);
+ "Cannot set permissions of %s temp file: %m", opasswd_file);
if (fchown (newpf_fd, opasswd_stat.st_uid, opasswd_stat.st_gid) != 0)
pam_syslog (pamh, LOG_ERR,
- "Cannot set owner/group of %s temp file: %m",
- OLD_PASSWORDS_FILE);
+ "Cannot set owner/group of %s temp file: %m", opasswd_file);
}
newpf = fdopen (newpf_fd, "w+");
if (newpf == NULL)
@@ -514,6 +523,7 @@ save_old_pass, const char *user, int howmany, int debug UNUSED)
}
if (fputs (out, newpf) < 0)
{
+ pam_overwrite_string(out);
free (out);
retval = PAM_AUTHTOK_ERR;
if (oldpf)
@@ -521,6 +531,7 @@ save_old_pass, const char *user, int howmany, int debug UNUSED)
fclose (newpf);
goto error_opasswd;
}
+ pam_overwrite_string(out);
free (out);
}
@@ -550,14 +561,23 @@ save_old_pass, const char *user, int howmany, int debug UNUSED)
goto error_opasswd;
}
- unlink (OLD_PASSWORDS_FILE".old");
- if (link (OLD_PASSWORDS_FILE, OLD_PASSWORDS_FILE".old") != 0 &&
+ char opasswd_backup[PATH_MAX];
+ if ((size_t) snprintf (opasswd_backup, sizeof (opasswd_backup), "%s.old",
+ opasswd_file) >= sizeof (opasswd_backup))
+ {
+ retval = PAM_BUF_ERR;
+ goto error_opasswd;
+ }
+
+ unlink (opasswd_backup);
+ if (link (opasswd_file, opasswd_backup) != 0 &&
errno != ENOENT)
pam_syslog (pamh, LOG_ERR, "Cannot create backup file of %s: %m",
- OLD_PASSWORDS_FILE);
- rename (opasswd_tmp, OLD_PASSWORDS_FILE);
+ opasswd_file);
+ rename (opasswd_tmp, opasswd_file);
error_opasswd:
unlink (opasswd_tmp);
+ pam_overwrite_n(buf, buflen);
free (buf);
return retval;
diff --git a/modules/pam_pwhistory/opasswd.h b/modules/pam_pwhistory/opasswd.h
index 3f257288..19a4062c 100644
--- a/modules/pam_pwhistory/opasswd.h
+++ b/modules/pam_pwhistory/opasswd.h
@@ -57,10 +57,10 @@ void
helper_log_err(int err, const char *format, ...);
#endif
-PAMH_ARG_DECL(int
-check_old_pass, const char *user, const char *newpass, int debug);
+PAMH_ARG_DECL(int check_old_pass, const char *user, const char *newpass,
+ const char *filename, int debug);
-PAMH_ARG_DECL(int
-save_old_pass, const char *user, int howmany, int debug);
+PAMH_ARG_DECL(int save_old_pass, const char *user, int howmany,
+ const char *filename, int debug);
#endif /* __OPASSWD_H__ */
diff --git a/modules/pam_pwhistory/pam_pwhistory.8 b/modules/pam_pwhistory/pam_pwhistory.8
index bdbd6c8d..df95ee37 100644
--- a/modules/pam_pwhistory/pam_pwhistory.8
+++ b/modules/pam_pwhistory/pam_pwhistory.8
@@ -1,13 +1,13 @@
'\" t
.\" Title: pam_pwhistory
.\" Author: [see the "AUTHOR" section]
-.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
-.\" Date: 09/03/2021
+.\" Generator: DocBook XSL Stylesheets v1.79.2 <http://docbook.sf.net/>
+.\" Date: 05/07/2023
.\" Manual: Linux-PAM Manual
-.\" Source: Linux-PAM Manual
+.\" Source: Linux-PAM
.\" Language: English
.\"
-.TH "PAM_PWHISTORY" "8" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.TH "PAM_PWHISTORY" "8" "05/07/2023" "Linux\-PAM" "Linux\-PAM Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -31,7 +31,7 @@
pam_pwhistory \- PAM module to remember last passwords
.SH "SYNOPSIS"
.HP \w'\fBpam_pwhistory\&.so\fR\ 'u
-\fBpam_pwhistory\&.so\fR [debug] [use_authtok] [enforce_for_root] [remember=\fIN\fR] [retry=\fIN\fR] [authtok_type=\fISTRING\fR]
+\fBpam_pwhistory\&.so\fR [debug] [use_authtok] [enforce_for_root] [remember=\fIN\fR] [retry=\fIN\fR] [authtok_type=\fISTRING\fR] [file=\fI/path/filename\fR] [conf=\fI/path/to/config\-file\fR]
.SH "DESCRIPTION"
.PP
This module saves the last passwords for each user in order to force password change history and keep the user from alternating between the same password too frequently\&.
@@ -39,13 +39,13 @@ This module saves the last passwords for each user in order to force password ch
This module does not work together with kerberos\&. In general, it does not make much sense to use this module in conjunction with NIS or LDAP, since the old passwords are stored on the local machine and are not available on another machine for password history checking\&.
.SH "OPTIONS"
.PP
-\fBdebug\fR
+debug
.RS 4
Turns on debugging via
\fBsyslog\fR(3)\&.
.RE
.PP
-\fBuse_authtok\fR
+use_authtok
.RS 4
When password changing enforce the module to use the new password provided by a previously stacked
\fBpassword\fR
@@ -54,17 +54,16 @@ module (this is used in the example of the stacking of the
module documented below)\&.
.RE
.PP
-\fBenforce_for_root\fR
+enforce_for_root
.RS 4
If this option is set, the check is enforced for root, too\&.
.RE
.PP
-\fBremember=\fR\fB\fIN\fR\fR
+remember=N
.RS 4
The last
\fIN\fR
-passwords for each user are saved in
-/etc/security/opasswd\&. The default is
+passwords for each user are saved\&. The default is
\fI10\fR\&. Value of
\fI0\fR
makes the module to keep the existing contents of the
@@ -72,7 +71,7 @@ opasswd
file unchanged\&.
.RE
.PP
-\fBretry=\fR\fB\fIN\fR\fR
+retry=N
.RS 4
Prompt user at most
\fIN\fR
@@ -80,12 +79,30 @@ times before returning with error\&. The default is
\fI1\fR\&.
.RE
.PP
-\fBauthtok_type=\fR\fB\fISTRING\fR\fR
+authtok_type=STRING
.RS 4
See
\fBpam_get_authtok\fR(3)
for more details\&.
.RE
+.PP
+file=/path/filename
+.RS 4
+Store password history in file
+/path/filename
+rather than the default location\&. The default location is
+/etc/security/opasswd\&.
+.RE
+.PP
+conf=/path/to/config\-file
+.RS 4
+Use another configuration file instead of the default
+/etc/security/pwhistory\&.conf\&.
+.RE
+.PP
+The options for configuring the module behavior are described in the
+\fBpwhistory.conf\fR(5)
+manual page\&. The options specified on the module command line override the values from the configuration file\&.
.SH "MODULE TYPES PROVIDED"
.PP
Only the
@@ -150,10 +167,16 @@ password required pam_unix\&.so use_authtok
.PP
/etc/security/opasswd
.RS 4
-File with password history
+Default file with password history
+.RE
+.PP
+/etc/security/pwhistory\&.conf
+.RS 4
+Config file for pam_pwhistory options
.RE
.SH "SEE ALSO"
.PP
+\fBpwhistory.conf\fR(5),
\fBpam.conf\fR(5),
\fBpam.d\fR(5),
\fBpam\fR(8)
diff --git a/modules/pam_pwhistory/pam_pwhistory.8.xml b/modules/pam_pwhistory/pam_pwhistory.8.xml
index d88115c2..d83d8d97 100644
--- a/modules/pam_pwhistory/pam_pwhistory.8.xml
+++ b/modules/pam_pwhistory/pam_pwhistory.8.xml
@@ -1,46 +1,49 @@
-<?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="pam_pwhistory">
+<refentry xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="pam_pwhistory">
<refmeta>
<refentrytitle>pam_pwhistory</refentrytitle>
<manvolnum>8</manvolnum>
- <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ <refmiscinfo class="source">Linux-PAM</refmiscinfo>
+ <refmiscinfo class="manual">Linux-PAM Manual</refmiscinfo>
</refmeta>
- <refnamediv id="pam_pwhistory-name">
+ <refnamediv xml:id="pam_pwhistory-name">
<refname>pam_pwhistory</refname>
<refpurpose>PAM module to remember last passwords</refpurpose>
</refnamediv>
<refsynopsisdiv>
- <cmdsynopsis id="pam_pwhistory-cmdsynopsis">
+ <cmdsynopsis xml:id="pam_pwhistory-cmdsynopsis" sepchar=" ">
<command>pam_pwhistory.so</command>
- <arg choice="opt">
+ <arg choice="opt" rep="norepeat">
debug
</arg>
- <arg choice="opt">
+ <arg choice="opt" rep="norepeat">
use_authtok
</arg>
- <arg choice="opt">
+ <arg choice="opt" rep="norepeat">
enforce_for_root
</arg>
- <arg choice="opt">
+ <arg choice="opt" rep="norepeat">
remember=<replaceable>N</replaceable>
</arg>
- <arg choice="opt">
+ <arg choice="opt" rep="norepeat">
retry=<replaceable>N</replaceable>
</arg>
- <arg choice="opt">
+ <arg choice="opt" rep="norepeat">
authtok_type=<replaceable>STRING</replaceable>
</arg>
+ <arg choice="opt" rep="norepeat">
+ file=<replaceable>/path/filename</replaceable>
+ </arg>
+ <arg choice="opt" rep="norepeat">
+ conf=<replaceable>/path/to/config-file</replaceable>
+ </arg>
</cmdsynopsis>
</refsynopsisdiv>
- <refsect1 id="pam_pwhistory-description">
+ <refsect1 xml:id="pam_pwhistory-description">
<title>DESCRIPTION</title>
@@ -58,12 +61,12 @@
</para>
</refsect1>
- <refsect1 id="pam_pwhistory-options">
+ <refsect1 xml:id="pam_pwhistory-options">
<title>OPTIONS</title>
<variablelist>
<varlistentry>
<term>
- <option>debug</option>
+ debug
</term>
<listitem>
<para>
@@ -76,7 +79,7 @@
</varlistentry>
<varlistentry>
<term>
- <option>use_authtok</option>
+ use_authtok
</term>
<listitem>
<para>
@@ -89,7 +92,7 @@
</varlistentry>
<varlistentry>
<term>
- <option>enforce_for_root</option>
+ enforce_for_root
</term>
<listitem>
<para>
@@ -99,12 +102,12 @@
</varlistentry>
<varlistentry>
<term>
- <option>remember=<replaceable>N</replaceable></option>
+ remember=N
</term>
<listitem>
<para>
The last <replaceable>N</replaceable> passwords for each
- user are saved in <filename>/etc/security/opasswd</filename>.
+ user are saved.
The default is <emphasis>10</emphasis>. Value of
<emphasis>0</emphasis> makes the module to keep the existing
contents of the <filename>opasswd</filename> file unchanged.
@@ -113,7 +116,7 @@
</varlistentry>
<varlistentry>
<term>
- <option>retry=<replaceable>N</replaceable></option>
+ retry=N
</term>
<listitem>
<para>
@@ -126,7 +129,7 @@
<varlistentry>
<term>
- <option>authtok_type=<replaceable>STRING</replaceable></option>
+ authtok_type=STRING
</term>
<listitem>
<para>
@@ -137,17 +140,49 @@
</listitem>
</varlistentry>
+ <varlistentry>
+ <term>
+ file=/path/filename
+ </term>
+ <listitem>
+ <para>
+ Store password history in file <filename>/path/filename</filename>
+ rather than the default location. The default location is
+ <filename>/etc/security/opasswd</filename>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ conf=/path/to/config-file
+ </term>
+ <listitem>
+ <para>
+ Use another configuration file instead of the default
+ <filename>/etc/security/pwhistory.conf</filename>.
+ </para>
+ </listitem>
+ </varlistentry>
+
</variablelist>
+ <para>
+ The options for configuring the module behavior are described in the
+ <citerefentry><refentrytitle>pwhistory.conf</refentrytitle>
+ <manvolnum>5</manvolnum></citerefentry> manual page. The options
+ specified on the module command line override the values from the
+ configuration file.
+ </para>
</refsect1>
- <refsect1 id="pam_pwhistory-types">
+ <refsect1 xml:id="pam_pwhistory-types">
<title>MODULE TYPES PROVIDED</title>
<para>
Only the <option>password</option> module type is provided.
</para>
</refsect1>
- <refsect1 id='pam_pwhistory-return_values'>
+ <refsect1 xml:id="pam_pwhistory-return_values">
<title>RETURN VALUES</title>
<variablelist>
<varlistentry>
@@ -186,7 +221,7 @@
</variablelist>
</refsect1>
- <refsect1 id='pam_pwhistory-examples'>
+ <refsect1 xml:id="pam_pwhistory-examples">
<title>EXAMPLES</title>
<para>
An example password section would be:
@@ -207,22 +242,40 @@ password required pam_unix.so use_authtok
</para>
</refsect1>
- <refsect1 id="pam_pwhistory-files">
+ <refsect1 xml:id="pam_pwhistory-files">
<title>FILES</title>
<variablelist>
<varlistentry>
- <term><filename>/etc/security/opasswd</filename></term>
+ <term>/etc/security/opasswd</term>
<listitem>
- <para>File with password history</para>
+ <para>Default file with password history</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><filename>/etc/security/pwhistory.conf</filename></term>
+ <listitem>
+ <para>Config file for pam_pwhistory options</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry condition="with_vendordir">
+ <term><filename>%vendordir%/security/pwhistory.conf</filename></term>
+ <listitem>
+ <para>
+ Config file for pam_pwhistory options. It will be used if
+ <filename>/etc/security/pwhistory.conf</filename> does not exist.
+ </para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
- <refsect1 id='pam_pwhistory-see_also'>
+ <refsect1 xml:id="pam_pwhistory-see_also">
<title>SEE ALSO</title>
<para>
<citerefentry>
+ <refentrytitle>pwhistory.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
<refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
</citerefentry>,
<citerefentry>
@@ -237,11 +290,11 @@ password required pam_unix.so use_authtok
</para>
</refsect1>
- <refsect1 id='pam_pwhistory-author'>
+ <refsect1 xml:id="pam_pwhistory-author">
<title>AUTHOR</title>
<para>
pam_pwhistory was written by Thorsten Kukuk &lt;kukuk@thkukuk.de&gt;
</para>
</refsect1>
-</refentry>
+</refentry> \ No newline at end of file
diff --git a/modules/pam_pwhistory/pam_pwhistory.c b/modules/pam_pwhistory/pam_pwhistory.c
index ce2c21f5..5a7fb811 100644
--- a/modules/pam_pwhistory/pam_pwhistory.c
+++ b/modules/pam_pwhistory/pam_pwhistory.c
@@ -63,14 +63,8 @@
#include "opasswd.h"
#include "pam_inline.h"
+#include "pwhistory_config.h"
-struct options_t {
- int debug;
- int enforce_for_root;
- int remember;
- int tries;
-};
-typedef struct options_t options_t;
static void
@@ -104,13 +98,23 @@ parse_option (pam_handle_t *pamh, const char *argv, options_t *options)
options->enforce_for_root = 1;
else if (pam_str_skip_icase_prefix(argv, "authtok_type=") != NULL)
{ /* ignore, for pam_get_authtok */; }
+ else if ((str = pam_str_skip_icase_prefix(argv, "file=")) != NULL)
+ {
+ if (*str != '/')
+ {
+ pam_syslog (pamh, LOG_ERR,
+ "pam_pwhistory: file path should be absolute: %s", argv);
+ }
+ else
+ options->filename = str;
+ }
else
pam_syslog (pamh, LOG_ERR, "pam_pwhistory: unknown option: %s", argv);
}
static int
run_save_helper(pam_handle_t *pamh, const char *user,
- int howmany, int debug)
+ int howmany, const char *filename, int debug)
{
int retval, child;
struct sigaction newsa, oldsa;
@@ -123,7 +127,7 @@ run_save_helper(pam_handle_t *pamh, const char *user,
if (child == 0)
{
static char *envp[] = { NULL };
- char *args[] = { NULL, NULL, NULL, NULL, NULL, NULL };
+ char *args[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL };
if (pam_modutil_sanitize_helper_fds(pamh, PAM_MODUTIL_PIPE_FD,
PAM_MODUTIL_PIPE_FD,
@@ -137,9 +141,10 @@ run_save_helper(pam_handle_t *pamh, const char *user,
args[0] = (char *)PWHISTORY_HELPER;
args[1] = (char *)"save";
args[2] = (char *)user;
+ args[3] = (char *)filename;
DIAG_POP_IGNORE_CAST_QUAL;
- if (asprintf(&args[3], "%d", howmany) < 0 ||
- asprintf(&args[4], "%d", debug) < 0)
+ if (asprintf(&args[4], "%d", howmany) < 0 ||
+ asprintf(&args[5], "%d", debug) < 0)
{
pam_syslog(pamh, LOG_ERR, "asprintf: %m");
_exit(PAM_SYSTEM_ERR);
@@ -185,7 +190,7 @@ run_save_helper(pam_handle_t *pamh, const char *user,
static int
run_check_helper(pam_handle_t *pamh, const char *user,
- const char *newpass, int debug)
+ const char *newpass, const char *filename, int debug)
{
int retval, child, fds[2];
struct sigaction newsa, oldsa;
@@ -202,7 +207,7 @@ run_check_helper(pam_handle_t *pamh, const char *user,
if (child == 0)
{
static char *envp[] = { NULL };
- char *args[] = { NULL, NULL, NULL, NULL, NULL };
+ char *args[] = { NULL, NULL, NULL, NULL, NULL, NULL };
/* reopen stdin as pipe */
if (dup2(fds[0], STDIN_FILENO) != STDIN_FILENO)
@@ -223,8 +228,9 @@ run_check_helper(pam_handle_t *pamh, const char *user,
args[0] = (char *)PWHISTORY_HELPER;
args[1] = (char *)"check";
args[2] = (char *)user;
+ args[3] = (char *)filename;
DIAG_POP_IGNORE_CAST_QUAL;
- if (asprintf(&args[3], "%d", debug) < 0)
+ if (asprintf(&args[4], "%d", debug) < 0)
{
pam_syslog(pamh, LOG_ERR, "asprintf: %m");
_exit(PAM_SYSTEM_ERR);
@@ -299,6 +305,8 @@ pam_sm_chauthtok (pam_handle_t *pamh, int flags, int argc, const char **argv)
options.remember = 10;
options.tries = 1;
+ parse_config_file(pamh, argc, argv, &options);
+
/* Parse parameters for module */
for ( ; argc-- > 0; argv++)
parse_option (pamh, *argv, &options);
@@ -306,7 +314,6 @@ pam_sm_chauthtok (pam_handle_t *pamh, int flags, int argc, const char **argv)
if (options.debug)
pam_syslog (pamh, LOG_DEBUG, "pam_sm_chauthtok entered");
-
if (options.remember == 0)
return PAM_IGNORE;
@@ -323,10 +330,10 @@ pam_sm_chauthtok (pam_handle_t *pamh, int flags, int argc, const char **argv)
return PAM_SUCCESS;
}
- retval = save_old_pass (pamh, user, options.remember, options.debug);
+ retval = save_old_pass (pamh, user, options.remember, options.filename, options.debug);
if (retval == PAM_PWHISTORY_RUN_HELPER)
- retval = run_save_helper(pamh, user, options.remember, options.debug);
+ retval = run_save_helper(pamh, user, options.remember, options.filename, options.debug);
if (retval != PAM_SUCCESS)
return retval;
@@ -358,9 +365,9 @@ pam_sm_chauthtok (pam_handle_t *pamh, int flags, int argc, const char **argv)
if (options.debug)
pam_syslog (pamh, LOG_DEBUG, "check against old password file");
- retval = check_old_pass (pamh, user, newpass, options.debug);
+ retval = check_old_pass (pamh, user, newpass, options.filename, options.debug);
if (retval == PAM_PWHISTORY_RUN_HELPER)
- retval = run_check_helper(pamh, user, newpass, options.debug);
+ retval = run_check_helper(pamh, user, newpass, options.filename, options.debug);
if (retval != PAM_SUCCESS)
{
diff --git a/modules/pam_pwhistory/pwhistory.conf b/modules/pam_pwhistory/pwhistory.conf
new file mode 100644
index 00000000..070b7197
--- /dev/null
+++ b/modules/pam_pwhistory/pwhistory.conf
@@ -0,0 +1,21 @@
+# Configuration for remembering the last passwords used by a user.
+#
+# Enable the debugging logs.
+# Enabled if option is present.
+# debug
+#
+# root account's passwords are also remembered.
+# Enabled if option is present.
+# enforce_for_root
+#
+# Number of passwords to remember.
+# The default is 10.
+# remember = 10
+#
+# Number of times to prompt for the password.
+# The default is 1.
+# retry = 1
+#
+# The directory where the last passwords are kept.
+# The default is /etc/security/opasswd.
+# file = /etc/security/opasswd
diff --git a/modules/pam_pwhistory/pwhistory.conf.5 b/modules/pam_pwhistory/pwhistory.conf.5
new file mode 100644
index 00000000..ae57798f
--- /dev/null
+++ b/modules/pam_pwhistory/pwhistory.conf.5
@@ -0,0 +1,118 @@
+'\" t
+.\" Title: pwhistory.conf
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.2 <http://docbook.sf.net/>
+.\" Date: 05/07/2023
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM
+.\" Language: English
+.\"
+.TH "PWHISTORY\&.CONF" "5" "05/07/2023" "Linux\-PAM" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pwhistory.conf \- pam_pwhistory configuration file
+.SH "DESCRIPTION"
+.PP
+\fBpwhistory\&.conf\fR
+provides a way to configure the default settings for saving the last passwords for each user\&. This file is read by the
+\fIpam_pwhistory\fR
+module and is the preferred method over configuring
+\fIpam_pwhistory\fR
+directly\&.
+.PP
+The file has a very simple
+\fIname = value\fR
+format with possible comments starting with
+\fI#\fR
+character\&. The whitespace at the beginning of line, end of line, and around the
+\fI=\fR
+sign is ignored\&.
+.SH "OPTIONS"
+.PP
+debug
+.RS 4
+Turns on debugging via
+\fBsyslog\fR(3)\&.
+.RE
+.PP
+enforce_for_root
+.RS 4
+If this option is set, the check is enforced for root, too\&.
+.RE
+.PP
+remember=N
+.RS 4
+The last
+\fIN\fR
+passwords for each user are saved\&. The default is
+\fI10\fR\&. Value of
+\fI0\fR
+makes the module to keep the existing contents of the
+opasswd
+file unchanged\&.
+.RE
+.PP
+retry=N
+.RS 4
+Prompt user at most
+\fIN\fR
+times before returning with error\&. The default is 1\&.
+.RE
+.PP
+file=/path/filename
+.RS 4
+Store password history in file
+\fI/path/filename\fR
+rather than the default location\&. The default location is
+/etc/security/opasswd\&.
+.RE
+.SH "EXAMPLES"
+.PP
+/etc/security/pwhistory\&.conf file example:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+debug
+remember=5
+file=/tmp/opasswd
+
+.fi
+.if n \{\
+.RE
+.\}
+.SH "FILES"
+.PP
+/etc/security/pwhistory\&.conf
+.RS 4
+the config file for custom options
+.RE
+.SH "SEE ALSO"
+.PP
+\fBpwhistory\fR(8),
+\fBpam_pwhistory\fR(8),
+\fBpam.conf\fR(5),
+\fBpam.d\fR(5),
+\fBpam\fR(8)
+.SH "AUTHOR"
+.PP
+pam_pwhistory was written by Thorsten Kukuk\&. The support for pwhistory\&.conf was written by Iker Pedrosa\&.
diff --git a/modules/pam_pwhistory/pwhistory.conf.5.xml b/modules/pam_pwhistory/pwhistory.conf.5.xml
new file mode 100644
index 00000000..2a2dfd3a
--- /dev/null
+++ b/modules/pam_pwhistory/pwhistory.conf.5.xml
@@ -0,0 +1,152 @@
+<refentry xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="pwhistory.conf">
+
+ <refmeta>
+ <refentrytitle>pwhistory.conf</refentrytitle>
+ <manvolnum>5</manvolnum>
+ <refmiscinfo class="source">Linux-PAM</refmiscinfo>
+ <refmiscinfo class="manual">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv xml:id="pwhistory.conf-name">
+ <refname>pwhistory.conf</refname>
+ <refpurpose>pam_pwhistory configuration file</refpurpose>
+ </refnamediv>
+
+ <refsect1 xml:id="pwhistory.conf-description">
+
+ <title>DESCRIPTION</title>
+ <para>
+ <emphasis remap="B">pwhistory.conf</emphasis> provides a way to configure the
+ default settings for saving the last passwords for each user.
+ This file is read by the <emphasis>pam_pwhistory</emphasis> module and is the
+ preferred method over configuring <emphasis>pam_pwhistory</emphasis> directly.
+ </para>
+ <para>
+ The file has a very simple <emphasis>name = value</emphasis> format with possible comments
+ starting with <emphasis>#</emphasis> character. The whitespace at the beginning of line, end
+ of line, and around the <emphasis>=</emphasis> sign is ignored.
+ </para>
+ </refsect1>
+
+ <refsect1 xml:id="pwhistory.conf-options">
+
+ <title>OPTIONS</title>
+ <variablelist>
+ <varlistentry>
+ <term>
+ debug
+ </term>
+ <listitem>
+ <para>
+ Turns on debugging via
+ <citerefentry>
+ <refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ enforce_for_root
+ </term>
+ <listitem>
+ <para>
+ If this option is set, the check is enforced for root, too.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ remember=N
+ </term>
+ <listitem>
+ <para>
+ The last <replaceable>N</replaceable> passwords for each
+ user are saved.
+ The default is <emphasis>10</emphasis>. Value of
+ <emphasis>0</emphasis> makes the module to keep the existing
+ contents of the <filename>opasswd</filename> file unchanged.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ retry=N
+ </term>
+ <listitem>
+ <para>
+ Prompt user at most <replaceable>N</replaceable> times
+ before returning with error. The default is 1.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ file=/path/filename
+ </term>
+ <listitem>
+ <para>
+ Store password history in file
+ <replaceable>/path/filename</replaceable> rather than the default
+ location. The default location is
+ <filename>/etc/security/opasswd</filename>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 xml:id="pwhistory.conf-examples">
+ <title>EXAMPLES</title>
+ <para>
+ /etc/security/pwhistory.conf file example:
+ </para>
+ <programlisting>
+debug
+remember=5
+file=/tmp/opasswd
+ </programlisting>
+ </refsect1>
+
+ <refsect1 xml:id="pwhistory.conf-files">
+ <title>FILES</title>
+ <variablelist>
+ <varlistentry>
+ <term>/etc/security/pwhistory.conf</term>
+ <listitem>
+ <para>the config file for custom options</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 xml:id="pwhistory.conf-see_also">
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>pwhistory</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam_pwhistory</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 xml:id="pwhistory.conf-author">
+ <title>AUTHOR</title>
+ <para>
+ pam_pwhistory was written by Thorsten Kukuk. The support for
+ pwhistory.conf was written by Iker Pedrosa.
+ </para>
+ </refsect1>
+
+</refentry> \ No newline at end of file
diff --git a/modules/pam_pwhistory/pwhistory_config.c b/modules/pam_pwhistory/pwhistory_config.c
new file mode 100644
index 00000000..692cf80e
--- /dev/null
+++ b/modules/pam_pwhistory/pwhistory_config.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2022 Iker Pedrosa <ipedrosa@redhat.com>
+ *
+ * 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.
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <sys/stat.h>
+
+#include <security/pam_modutil.h>
+
+#include "pam_inline.h"
+#include "pwhistory_config.h"
+
+#define PWHISTORY_DEFAULT_CONF SCONFIGDIR "/pwhistory.conf"
+
+#ifdef VENDOR_SCONFIGDIR
+#define VENDOR_PWHISTORY_DEFAULT_CONF (VENDOR_SCONFIGDIR "/pwhistory.conf")
+#endif
+
+void
+parse_config_file(pam_handle_t *pamh, int argc, const char **argv,
+ struct options_t *options)
+{
+ const char *fname = NULL;
+ int i;
+ char *val;
+
+ for (i = 0; i < argc; ++i) {
+ const char *str = pam_str_skip_prefix(argv[i], "conf=");
+
+ if (str != NULL) {
+ fname = str;
+ }
+ }
+
+ if (fname == NULL) {
+ fname = PWHISTORY_DEFAULT_CONF;
+
+#ifdef VENDOR_PWHISTORY_DEFAULT_CONF
+ /*
+ * Check whether PWHISTORY_DEFAULT_CONF file is available.
+ * If it does not exist, fall back to VENDOR_PWHISTORY_DEFAULT_CONF file.
+ */
+ struct stat buffer;
+ if (stat(fname, &buffer) != 0 && errno == ENOENT) {
+ fname = VENDOR_PWHISTORY_DEFAULT_CONF;
+ }
+#endif
+ }
+
+ val = pam_modutil_search_key (pamh, fname, "debug");
+ if (val != NULL) {
+ options->debug = 1;
+ free(val);
+ }
+
+ val = pam_modutil_search_key (pamh, fname, "enforce_for_root");
+ if (val != NULL) {
+ options->enforce_for_root = 1;
+ free(val);
+ }
+
+ val = pam_modutil_search_key (pamh, fname, "remember");
+ if (val != NULL) {
+ unsigned int temp;
+ if (sscanf(val, "%u", &temp) != 1) {
+ pam_syslog(pamh, LOG_ERR,
+ "Bad number supplied for remember argument");
+ } else {
+ options->remember = temp;
+ }
+ free(val);
+ }
+
+ val = pam_modutil_search_key (pamh, fname, "retry");
+ if (val != NULL) {
+ unsigned int temp;
+ if (sscanf(val, "%u", &temp) != 1) {
+ pam_syslog(pamh, LOG_ERR,
+ "Bad number supplied for retry argument");
+ } else {
+ options->tries = temp;
+ }
+ free(val);
+ }
+
+ val = pam_modutil_search_key (pamh, fname, "file");
+ if (val != NULL) {
+ if (*val != '/') {
+ pam_syslog (pamh, LOG_ERR,
+ "File path should be absolute: %s", val);
+ } else {
+ options->filename = val;
+ }
+ }
+}
diff --git a/modules/pam_pwhistory/pwhistory_config.h b/modules/pam_pwhistory/pwhistory_config.h
new file mode 100644
index 00000000..e2b3bc83
--- /dev/null
+++ b/modules/pam_pwhistory/pwhistory_config.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2022 Iker Pedrosa <ipedrosa@redhat.com>
+ *
+ * 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.
+ */
+
+#ifndef _PWHISTORY_CONFIG_H
+#define _PWHISTORY_CONFIG_H
+
+#include <security/pam_ext.h>
+
+struct options_t {
+ int debug;
+ int enforce_for_root;
+ int remember;
+ int tries;
+ const char *filename;
+};
+typedef struct options_t options_t;
+
+void
+parse_config_file(pam_handle_t *pamh, int argc, const char **argv,
+ struct options_t *options);
+
+#endif /* _PWHISTORY_CONFIG_H */
diff --git a/modules/pam_pwhistory/pwhistory_helper.8 b/modules/pam_pwhistory/pwhistory_helper.8
index 684b5b02..0b837d32 100644
--- a/modules/pam_pwhistory/pwhistory_helper.8
+++ b/modules/pam_pwhistory/pwhistory_helper.8
@@ -1,13 +1,13 @@
'\" t
.\" Title: pwhistory_helper
.\" Author: [see the "AUTHOR" section]
-.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
-.\" Date: 09/03/2021
+.\" Generator: DocBook XSL Stylesheets v1.79.2 <http://docbook.sf.net/>
+.\" Date: 05/07/2023
.\" Manual: Linux-PAM Manual
-.\" Source: Linux-PAM Manual
+.\" Source: Linux-PAM
.\" Language: English
.\"
-.TH "PWHISTORY_HELPER" "8" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.TH "PWHISTORY_HELPER" "8" "05/07/2023" "Linux\-PAM" "Linux\-PAM Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff --git a/modules/pam_pwhistory/pwhistory_helper.8.xml b/modules/pam_pwhistory/pwhistory_helper.8.xml
index a0301764..8370a485 100644
--- a/modules/pam_pwhistory/pwhistory_helper.8.xml
+++ b/modules/pam_pwhistory/pwhistory_helper.8.xml
@@ -1,30 +1,27 @@
-<?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="pwhistory_helper">
+<refentry xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="pwhistory_helper">
<refmeta>
<refentrytitle>pwhistory_helper</refentrytitle>
<manvolnum>8</manvolnum>
- <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ <refmiscinfo class="source">Linux-PAM</refmiscinfo>
+ <refmiscinfo class="manual">Linux-PAM Manual</refmiscinfo>
</refmeta>
- <refnamediv id="pwhistory_helper-name">
+ <refnamediv xml:id="pwhistory_helper-name">
<refname>pwhistory_helper</refname>
<refpurpose>Helper binary that transfers password hashes from passwd or shadow to opasswd</refpurpose>
</refnamediv>
<refsynopsisdiv>
- <cmdsynopsis id="pwhistory_helper-cmdsynopsis">
+ <cmdsynopsis xml:id="pwhistory_helper-cmdsynopsis" sepchar=" ">
<command>pwhistory_helper</command>
- <arg choice="opt">
+ <arg choice="opt" rep="norepeat">
...
</arg>
</cmdsynopsis>
</refsynopsisdiv>
- <refsect1 id="pwhistory_helper-description">
+ <refsect1 xml:id="pwhistory_helper-description">
<title>DESCRIPTION</title>
@@ -48,7 +45,7 @@
</para>
</refsect1>
- <refsect1 id='pwhistory_helper-see_also'>
+ <refsect1 xml:id="pwhistory_helper-see_also">
<title>SEE ALSO</title>
<para>
<citerefentry>
@@ -57,7 +54,7 @@
</para>
</refsect1>
- <refsect1 id='pwhistory_helper-author'>
+ <refsect1 xml:id="pwhistory_helper-author">
<title>AUTHOR</title>
<para>
Written by Tomas Mraz based on the code originally in
@@ -65,4 +62,4 @@
</para>
</refsect1>
-</refentry>
+</refentry> \ No newline at end of file
diff --git a/modules/pam_pwhistory/pwhistory_helper.c b/modules/pam_pwhistory/pwhistory_helper.c
index b08a14a7..469d95fa 100644
--- a/modules/pam_pwhistory/pwhistory_helper.c
+++ b/modules/pam_pwhistory/pwhistory_helper.c
@@ -51,7 +51,7 @@
static int
-check_history(const char *user, const char *debug)
+check_history(const char *user, const char *filename, const char *debug)
{
char pass[PAM_MAX_RESP_SIZE + 1];
char *passwords[] = { pass };
@@ -68,21 +68,21 @@ check_history(const char *user, const char *debug)
return PAM_AUTHTOK_ERR;
}
- retval = check_old_pass(user, pass, dbg);
+ retval = check_old_pass(user, pass, filename, dbg);
- memset(pass, '\0', PAM_MAX_RESP_SIZE); /* clear memory of the password */
+ pam_overwrite_array(pass); /* clear memory of the password */
return retval;
}
static int
-save_history(const char *user, const char *howmany, const char *debug)
+save_history(const char *user, const char *filename, const char *howmany, const char *debug)
{
int num = atoi(howmany);
int dbg = atoi(debug); /* no need to be too fancy here */
int retval;
- retval = save_old_pass(user, num, dbg);
+ retval = save_old_pass(user, num, filename, dbg);
return retval;
}
@@ -92,13 +92,14 @@ main(int argc, char *argv[])
{
const char *option;
const char *user;
+ const char *filename;
/*
* we establish that this program is running with non-tty stdin.
* this is to discourage casual use.
*/
- if (isatty(STDIN_FILENO) || argc < 4)
+ if (isatty(STDIN_FILENO) || argc < 5)
{
fprintf(stderr,
"This binary is not designed for running in this way.\n");
@@ -107,11 +108,12 @@ main(int argc, char *argv[])
option = argv[1];
user = argv[2];
+ filename = argv[3];
- if (strcmp(option, "check") == 0 && argc == 4)
- return check_history(user, argv[3]);
- else if (strcmp(option, "save") == 0 && argc == 5)
- return save_history(user, argv[3], argv[4]);
+ if (strcmp(option, "check") == 0 && argc == 5)
+ return check_history(user, filename, argv[4]);
+ else if (strcmp(option, "save") == 0 && argc == 6)
+ return save_history(user, filename, argv[4], argv[5]);
fprintf(stderr, "This binary is not designed for running in this way.\n");
diff --git a/modules/pam_pwhistory/tst-pam_pwhistory-retval.c b/modules/pam_pwhistory/tst-pam_pwhistory-retval.c
new file mode 100644
index 00000000..9c9a62b4
--- /dev/null
+++ b/modules/pam_pwhistory/tst-pam_pwhistory-retval.c
@@ -0,0 +1,60 @@
+/*
+ * Check pam_pwhistory return values.
+ *
+ * Copyright (c) 2023 Stefan Schubert <schubi@suse.de>
+ */
+
+#include "test_assert.h"
+
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <security/pam_appl.h>
+
+#define MODULE_NAME "pam_pwhistory"
+#define TEST_NAME "tst-" MODULE_NAME "-retval"
+
+static const char service_file[] = TEST_NAME ".service";
+static struct pam_conv conv;
+
+int
+main(void)
+{
+ pam_handle_t *pamh = NULL;
+ FILE *fp;
+ char cwd[PATH_MAX];
+
+ ASSERT_NE(NULL, getcwd(cwd, sizeof(cwd)));
+
+ /* PAM_USER_UNKNOWN */
+ ASSERT_NE(NULL, fp = fopen(service_file, "w"));
+ ASSERT_LT(0,
+ fprintf(fp, "#%%PAM-1.0\n"
+ "auth required %s/.libs/%s.so\n"
+ "account required %s/.libs/%s.so\n"
+ "password required %s/.libs/%s.so\n"
+ "session required %s/.libs/%s.so\n",
+ cwd, MODULE_NAME,
+ cwd, MODULE_NAME,
+ cwd, MODULE_NAME,
+ cwd, MODULE_NAME));
+ ASSERT_EQ(0, fclose(fp));
+
+ ASSERT_EQ(PAM_SUCCESS,
+ pam_start_confdir(service_file, "", &conv, ".", &pamh));
+ ASSERT_NE(NULL, pamh);
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_authenticate(pamh, 0));
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_setcred(pamh, 0));
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_acct_mgmt(pamh, 0));
+ ASSERT_EQ(PAM_USER_UNKNOWN, pam_chauthtok(pamh, 0));
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_open_session(pamh, 0));
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_close_session(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
+ pamh = NULL;
+
+ /* cleanup */
+ ASSERT_EQ(0, unlink(service_file));
+
+ return 0;
+}