diff options
author | Steve Langasek <steve.langasek@canonical.com> | 2020-08-11 14:54:35 -0700 |
---|---|---|
committer | Steve Langasek <steve.langasek@canonical.com> | 2020-08-11 15:00:33 -0700 |
commit | 239d9c3181694bda5a0531ac579612c46c3b4e6d (patch) | |
tree | 43c04725cde922627215f4c32665ea832dd456d1 /modules/pam_unix | |
parent | aa2142277bf5fb4a884c6119180e41258817705b (diff) | |
parent | f6d08ed47a3da3c08345bce2ca366e961c52ad7c (diff) | |
download | pam-239d9c3181694bda5a0531ac579612c46c3b4e6d.tar.gz pam-239d9c3181694bda5a0531ac579612c46c3b4e6d.tar.bz2 pam-239d9c3181694bda5a0531ac579612c46c3b4e6d.zip |
Merge upstream version 1.4.0
Diffstat (limited to 'modules/pam_unix')
-rw-r--r-- | modules/pam_unix/CHANGELOG | 18 | ||||
-rw-r--r-- | modules/pam_unix/Makefile.am | 20 | ||||
-rw-r--r-- | modules/pam_unix/Makefile.in | 300 | ||||
-rw-r--r-- | modules/pam_unix/README | 34 | ||||
-rw-r--r-- | modules/pam_unix/bigcrypt.c | 2 | ||||
-rw-r--r-- | modules/pam_unix/md5.c | 7 | ||||
-rw-r--r-- | modules/pam_unix/md5.h | 4 | ||||
-rw-r--r-- | modules/pam_unix/md5_crypt.c | 5 | ||||
-rw-r--r-- | modules/pam_unix/pam_unix.8 | 45 | ||||
-rw-r--r-- | modules/pam_unix/pam_unix.8.xml | 69 | ||||
-rw-r--r-- | modules/pam_unix/pam_unix_acct.c | 57 | ||||
-rw-r--r-- | modules/pam_unix/pam_unix_auth.c | 26 | ||||
-rw-r--r-- | modules/pam_unix/pam_unix_passwd.c | 62 | ||||
-rw-r--r-- | modules/pam_unix/pam_unix_sess.c | 43 | ||||
-rw-r--r-- | modules/pam_unix/passverify.c | 133 | ||||
-rw-r--r-- | modules/pam_unix/passverify.h | 8 | ||||
-rw-r--r-- | modules/pam_unix/support.c | 200 | ||||
-rw-r--r-- | modules/pam_unix/support.h | 113 | ||||
-rw-r--r-- | modules/pam_unix/unix_chkpwd.8 | 6 | ||||
-rw-r--r-- | modules/pam_unix/unix_chkpwd.c | 11 | ||||
-rw-r--r-- | modules/pam_unix/unix_update.8 | 6 |
21 files changed, 694 insertions, 475 deletions
diff --git a/modules/pam_unix/CHANGELOG b/modules/pam_unix/CHANGELOG index c18acc27..f8f70f59 100644 --- a/modules/pam_unix/CHANGELOG +++ b/modules/pam_unix/CHANGELOG @@ -1,6 +1,6 @@ $Id$ -* Mon Aug 16 1999 Jan Rêkorajski <baggins@pld.org.pl> +* Mon Aug 16 1999 Jan RÄ™korajski <baggins@pld.org.pl> - fixed reentrancy problems * Sun Jul 4 21:03:42 PDT 1999 @@ -15,7 +15,7 @@ $Id$ * Sun Jun 27 1999 Steve Langasek <vorlon@netexpress.net> - fix to uid-handling code for NIS+ -* Sat Jun 26 1999 Jan Rêkorajski <baggins@mimuw.edu.pl> +* Sat Jun 26 1999 Jan RÄ™korajski <baggins@mimuw.edu.pl> - merged MD5 fix and early failure syslog by Andrey Vladimirovich Savochkin <saw@msu.ru> - minor fixes @@ -24,31 +24,31 @@ $Id$ * Fri Jun 25 1999 Stephen Langasek <vorlon@netexpress.net> - reorganized the code to let it build as separate C files -* Sun Jun 20 1999 Jan Rêkorajski <baggins@mimuw.edu.pl> +* Sun Jun 20 1999 Jan RÄ™korajski <baggins@mimuw.edu.pl> - fixes in pam_unix_auth, it incorrectly saved and restored return value when likeauth option was used -* Tue Jun 15 1999 Jan Rêkorajski <baggins@mimuw.edu.pl> +* Tue Jun 15 1999 Jan RÄ™korajski <baggins@mimuw.edu.pl> - added NIS+ support -* Mon Jun 14 1999 Jan Rêkorajski <baggins@mimuw.edu.pl> +* Mon Jun 14 1999 Jan RÄ™korajski <baggins@mimuw.edu.pl> - total rewrite based on pam_pwdb module, now there is ONE pam_unix.so module, it accepts the same options as pam_pwdb - all of them correctly ;) (pam_pwdb dosn't understand what DISALLOW_NULL_AUTHTOK means) -* Tue Apr 20 1999 Jan Rêkorajski <baggins@mimuw.edu.pl> +* Tue Apr 20 1999 Jan RÄ™korajski <baggins@mimuw.edu.pl> - Arghhh, pam_unix_passwd was not updating /etc/shadow when used with pam_cracklib. -* Mon Apr 19 1999 Jan Rêkorajski <baggins@mimuw.edu.pl> +* Mon Apr 19 1999 Jan RÄ™korajski <baggins@mimuw.edu.pl> - added "remember=XXX" option that means 'remember XXX old passwords' Old passwords are stored in /etc/security/opasswd, there can be maximum of 400 passwords per user. -* Sat Mar 27 1999 Jan Rêkorajski <baggins@mimuw.edu.pl> +* Sat Mar 27 1999 Jan RÄ™korajski <baggins@mimuw.edu.pl> - added crypt16 to pam_unix_auth and pam_unix_passwd (check only, this algorithm is too lame to use it in real life) -* Sun Mar 21 1999 Jan Rêkorajski <baggins@mimuw.edu.pl> +* Sun Mar 21 1999 Jan RÄ™korajski <baggins@mimuw.edu.pl> - pam_unix_auth now correctly behave when user has NULL AUTHTOK - pam_unix_auth returns PAM_PERM_DENIED when seteuid fails diff --git a/modules/pam_unix/Makefile.am b/modules/pam_unix/Makefile.am index 56df1782..6463872a 100644 --- a/modules/pam_unix/Makefile.am +++ b/modules/pam_unix/Makefile.am @@ -5,13 +5,14 @@ CLEANFILES = *~ MAINTAINERCLEANFILES = $(MANS) README -EXTRA_DIST = README md5.c md5_crypt.c lckpwdf.-c $(MANS) CHANGELOG \ - tst-pam_unix $(XMLS) +EXTRA_DIST = md5.c md5_crypt.c lckpwdf.-c $(XMLS) CHANGELOG -man_MANS = pam_unix.8 unix_chkpwd.8 unix_update.8 +if HAVE_DOC +dist_man_MANS = pam_unix.8 unix_chkpwd.8 unix_update.8 +endif XMLS = README.xml pam_unix.8.xml unix_chkpwd.8.xml unix_update.8.xml - -TESTS = tst-pam_unix +dist_check_SCRIPTS = tst-pam_unix +TESTS = $(dist_check_SCRIPTS) securelibdir = $(SECUREDIR) secureconfdir = $(SCONFIGDIR) @@ -19,11 +20,7 @@ secureconfdir = $(SCONFIGDIR) AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \ -DCHKPWD_HELPER=\"$(sbindir)/unix_chkpwd\" \ -DUPDATE_HELPER=\"$(sbindir)/unix_update\" \ - @TIRPC_CFLAGS@ @NSL_CFLAGS@ - -if HAVE_LIBSELINUX - AM_CFLAGS += -D"WITH_SELINUX" -endif + @TIRPC_CFLAGS@ @NSL_CFLAGS@ $(WARN_CFLAGS) pam_unix_la_LDFLAGS = -no-undefined -avoid-version -module if HAVE_VERSIONING @@ -61,7 +58,6 @@ unix_update_LDFLAGS = @PIE_LDFLAGS@ unix_update_LDADD = @LIBCRYPT@ @LIBSELINUX@ if ENABLE_REGENERATE_MAN -noinst_DATA = README -README: pam_unix.8.xml +dist_noinst_DATA = README -include $(top_srcdir)/Make.xml.rules endif diff --git a/modules/pam_unix/Makefile.in b/modules/pam_unix/Makefile.in index 806f04c8..bfc1a252 100644 --- a/modules/pam_unix/Makefile.in +++ b/modules/pam_unix/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. +# Makefile.in generated by automake 1.16.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2018 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -22,7 +22,17 @@ VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -85,14 +95,10 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -@HAVE_LIBSELINUX_TRUE@am__append_1 = -D"WITH_SELINUX" -@HAVE_VERSIONING_TRUE@am__append_2 = -Wl,--version-script=$(srcdir)/../modules.map +@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map sbin_PROGRAMS = unix_chkpwd$(EXEEXT) unix_update$(EXEEXT) noinst_PROGRAMS = bigcrypt$(EXEEXT) subdir = modules/pam_unix -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ - $(top_srcdir)/build-aux/depcomp $(noinst_HEADERS) \ - $(top_srcdir)/build-aux/test-driver README 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 \ @@ -108,10 +114,16 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/configure.ac 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) 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)" +PROGRAMS = $(noinst_PROGRAMS) $(sbin_PROGRAMS) am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ @@ -139,8 +151,6 @@ am__uninstall_files_from_dir = { \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } -am__installdirs = "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(sbindir)" \ - "$(DESTDIR)$(man8dir)" LTLIBRARIES = $(securelib_LTLIBRARIES) pam_unix_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la am_pam_unix_la_OBJECTS = bigcrypt.lo pam_unix_acct.lo pam_unix_auth.lo \ @@ -154,7 +164,6 @@ am__v_lt_1 = pam_unix_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(pam_unix_la_LDFLAGS) $(LDFLAGS) -o $@ -PROGRAMS = $(noinst_PROGRAMS) $(sbin_PROGRAMS) am_bigcrypt_OBJECTS = bigcrypt-bigcrypt.$(OBJEXT) \ bigcrypt-bigcrypt_main.$(OBJEXT) bigcrypt_OBJECTS = $(am_bigcrypt_OBJECTS) @@ -196,7 +205,24 @@ am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp -am__depfiles_maybe = depfiles +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/bigcrypt-bigcrypt.Po \ + ./$(DEPDIR)/bigcrypt-bigcrypt_main.Po ./$(DEPDIR)/bigcrypt.Plo \ + ./$(DEPDIR)/md5_broken.Plo ./$(DEPDIR)/md5_good.Plo \ + ./$(DEPDIR)/pam_unix_acct.Plo ./$(DEPDIR)/pam_unix_auth.Plo \ + ./$(DEPDIR)/pam_unix_passwd.Plo ./$(DEPDIR)/pam_unix_sess.Plo \ + ./$(DEPDIR)/passverify.Plo ./$(DEPDIR)/support.Plo \ + ./$(DEPDIR)/unix_chkpwd-bigcrypt.Po \ + ./$(DEPDIR)/unix_chkpwd-md5_broken.Po \ + ./$(DEPDIR)/unix_chkpwd-md5_good.Po \ + ./$(DEPDIR)/unix_chkpwd-passverify.Po \ + ./$(DEPDIR)/unix_chkpwd-unix_chkpwd.Po \ + ./$(DEPDIR)/unix_update-bigcrypt.Po \ + ./$(DEPDIR)/unix_update-md5_broken.Po \ + ./$(DEPDIR)/unix_update-md5_good.Po \ + ./$(DEPDIR)/unix_update-passverify.Po \ + ./$(DEPDIR)/unix_update-unix_update.Po \ + ./$(DEPDIR)/yppasswd_xdr.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) @@ -227,8 +253,9 @@ am__can_run_installinfo = \ esac man8dir = $(mandir)/man8 NROFF = nroff -MANS = $(man_MANS) -DATA = $(noinst_DATA) +MANS = $(dist_man_MANS) +am__dist_noinst_DATA_DIST = README +DATA = $(dist_noinst_DATA) HEADERS = $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, @@ -426,6 +453,9 @@ TEST_LOGS = $(am__test_logs2:.test.log=.log) TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ $(TEST_LOG_FLAGS) +am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \ + $(top_srcdir)/build-aux/depcomp \ + $(top_srcdir)/build-aux/test-driver DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ @@ -454,6 +484,8 @@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ +ECONF_CFLAGS = @ECONF_CFLAGS@ +ECONF_LIBS = @ECONF_LIBS@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ @@ -462,7 +494,6 @@ GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ GMSGFMT = @GMSGFMT@ GMSGFMT_015 = @GMSGFMT_015@ GREP = @GREP@ -HAVE_KEY_MANAGEMENT = @HAVE_KEY_MANAGEMENT@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ @@ -498,6 +529,7 @@ LN_S = @LN_S@ LTLIBICONV = @LTLIBICONV@ LTLIBINTL = @LTLIBINTL@ LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ @@ -534,11 +566,13 @@ SECUREDIR = @SECUREDIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ +STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@ STRIP = @STRIP@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ XGETTEXT = @XGETTEXT@ XGETTEXT_015 = @XGETTEXT_015@ XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ @@ -607,21 +641,20 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ CLEANFILES = *~ MAINTAINERCLEANFILES = $(MANS) README -EXTRA_DIST = README md5.c md5_crypt.c lckpwdf.-c $(MANS) CHANGELOG \ - tst-pam_unix $(XMLS) - -man_MANS = pam_unix.8 unix_chkpwd.8 unix_update.8 +EXTRA_DIST = md5.c md5_crypt.c lckpwdf.-c $(XMLS) CHANGELOG +@HAVE_DOC_TRUE@dist_man_MANS = pam_unix.8 unix_chkpwd.8 unix_update.8 XMLS = README.xml pam_unix.8.xml unix_chkpwd.8.xml unix_update.8.xml -TESTS = tst-pam_unix +dist_check_SCRIPTS = tst-pam_unix +TESTS = $(dist_check_SCRIPTS) securelibdir = $(SECUREDIR) secureconfdir = $(SCONFIGDIR) -AM_CFLAGS = -I$(top_srcdir)/libpam/include \ - -I$(top_srcdir)/libpamc/include \ +AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \ -DCHKPWD_HELPER=\"$(sbindir)/unix_chkpwd\" \ - -DUPDATE_HELPER=\"$(sbindir)/unix_update\" @TIRPC_CFLAGS@ \ - @NSL_CFLAGS@ $(am__append_1) + -DUPDATE_HELPER=\"$(sbindir)/unix_update\" \ + @TIRPC_CFLAGS@ @NSL_CFLAGS@ $(WARN_CFLAGS) + pam_unix_la_LDFLAGS = -no-undefined -avoid-version -module \ - $(am__append_2) + $(am__append_1) pam_unix_la_LIBADD = $(top_builddir)/libpam/libpam.la \ @LIBCRYPT@ @LIBSELINUX@ @TIRPC_LIBS@ @NSL_LIBS@ @@ -646,7 +679,7 @@ unix_update_SOURCES = unix_update.c md5_good.c md5_broken.c bigcrypt.c \ unix_update_CFLAGS = $(AM_CFLAGS) @PIE_CFLAGS@ -DHELPER_COMPILE=\"unix_update\" unix_update_LDFLAGS = @PIE_LDFLAGS@ unix_update_LDADD = @LIBCRYPT@ @LIBSELINUX@ -@ENABLE_REGENERATE_MAN_TRUE@noinst_DATA = README +@ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README all: all-am .SUFFIXES: @@ -663,14 +696,13 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_unix/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu modules/pam_unix/Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) @@ -682,44 +714,6 @@ $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): -install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES) - @$(NORMAL_INSTALL) - @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \ - list2=; for p in $$list; do \ - if test -f $$p; then \ - list2="$$list2 $$p"; \ - else :; fi; \ - done; \ - test -z "$$list2" || { \ - echo " $(MKDIR_P) '$(DESTDIR)$(securelibdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(securelibdir)" || exit 1; \ - 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)'; 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: - -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES) - @list='$(securelib_LTLIBRARIES)'; \ - locs=`for p in $$list; do echo $$p; done | \ - sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ - sort -u`; \ - test -z "$$locs" || { \ - echo rm -f $${locs}; \ - rm -f $${locs}; \ - } - -pam_unix.la: $(pam_unix_la_OBJECTS) $(pam_unix_la_DEPENDENCIES) $(EXTRA_pam_unix_la_DEPENDENCIES) - $(AM_V_CCLD)$(pam_unix_la_LINK) -rpath $(securelibdir) $(pam_unix_la_OBJECTS) $(pam_unix_la_LIBADD) $(LIBS) - clean-noinstPROGRAMS: @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ @@ -778,6 +772,44 @@ clean-sbinPROGRAMS: echo " rm -f" $$list; \ rm -f $$list +install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(securelibdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(securelibdir)" || exit 1; \ + 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)'; 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: + -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES) + @list='$(securelib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +pam_unix.la: $(pam_unix_la_OBJECTS) $(pam_unix_la_DEPENDENCIES) $(EXTRA_pam_unix_la_DEPENDENCIES) + $(AM_V_CCLD)$(pam_unix_la_LINK) -rpath $(securelibdir) $(pam_unix_la_OBJECTS) $(pam_unix_la_LIBADD) $(LIBS) + bigcrypt$(EXEEXT): $(bigcrypt_OBJECTS) $(bigcrypt_DEPENDENCIES) $(EXTRA_bigcrypt_DEPENDENCIES) @rm -f bigcrypt$(EXEEXT) $(AM_V_CCLD)$(bigcrypt_LINK) $(bigcrypt_OBJECTS) $(bigcrypt_LDADD) $(LIBS) @@ -796,42 +828,48 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bigcrypt-bigcrypt.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bigcrypt-bigcrypt_main.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bigcrypt.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5_broken.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5_good.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_unix_acct.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_unix_auth.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_unix_passwd.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_unix_sess.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/passverify.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/support.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unix_chkpwd-bigcrypt.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unix_chkpwd-md5_broken.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unix_chkpwd-md5_good.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unix_chkpwd-passverify.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unix_chkpwd-unix_chkpwd.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unix_update-bigcrypt.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unix_update-md5_broken.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unix_update-md5_good.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unix_update-passverify.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unix_update-unix_update.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/yppasswd_xdr.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bigcrypt-bigcrypt.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bigcrypt-bigcrypt_main.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bigcrypt.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5_broken.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5_good.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_unix_acct.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_unix_auth.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_unix_passwd.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_unix_sess.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/passverify.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/support.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unix_chkpwd-bigcrypt.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unix_chkpwd-md5_broken.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unix_chkpwd-md5_good.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unix_chkpwd-passverify.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unix_chkpwd-unix_chkpwd.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unix_update-bigcrypt.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unix_update-md5_broken.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unix_update-md5_good.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unix_update-passverify.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unix_update-unix_update.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/yppasswd_xdr.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -1013,10 +1051,10 @@ mostlyclean-libtool: clean-libtool: -rm -rf .libs _libs -install-man8: $(man_MANS) +install-man8: $(dist_man_MANS) @$(NORMAL_INSTALL) @list1=''; \ - list2='$(man_MANS)'; \ + list2='$(dist_man_MANS)'; \ test -n "$(man8dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ @@ -1051,7 +1089,7 @@ uninstall-man8: @$(NORMAL_UNINSTALL) @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 | \ + l2='$(dist_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,.,'`; \ @@ -1139,7 +1177,7 @@ $(TEST_SUITE_LOG): $(TEST_LOGS) if test -n "$$am__remaking_logs"; then \ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ "recursion detected" >&2; \ - else \ + elif test -n "$$redo_logs"; then \ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ fi; \ if $(am__make_dryrun); then :; else \ @@ -1229,7 +1267,7 @@ $(TEST_SUITE_LOG): $(TEST_LOGS) fi; \ $$success || exit 1 -check-TESTS: +check-TESTS: $(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) @@ -1239,7 +1277,7 @@ check-TESTS: log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ exit $$?; -recheck: all +recheck: all $(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 \ @@ -1272,7 +1310,10 @@ tst-pam_unix.log: tst-pam_unix @am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ @am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) -distdir: $(DISTFILES) +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ @@ -1303,11 +1344,12 @@ distdir: $(DISTFILES) fi; \ done check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(dist_check_SCRIPTS) $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am -all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(MANS) $(DATA) $(HEADERS) +all-am: Makefile $(PROGRAMS) $(LTLIBRARIES) $(MANS) $(DATA) $(HEADERS) installdirs: - for dir in "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)"; do \ + for dir in "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am @@ -1351,7 +1393,28 @@ clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ clean-sbinPROGRAMS clean-securelibLTLIBRARIES mostlyclean-am distclean: distclean-am - -rm -rf ./$(DEPDIR) + -rm -f ./$(DEPDIR)/bigcrypt-bigcrypt.Po + -rm -f ./$(DEPDIR)/bigcrypt-bigcrypt_main.Po + -rm -f ./$(DEPDIR)/bigcrypt.Plo + -rm -f ./$(DEPDIR)/md5_broken.Plo + -rm -f ./$(DEPDIR)/md5_good.Plo + -rm -f ./$(DEPDIR)/pam_unix_acct.Plo + -rm -f ./$(DEPDIR)/pam_unix_auth.Plo + -rm -f ./$(DEPDIR)/pam_unix_passwd.Plo + -rm -f ./$(DEPDIR)/pam_unix_sess.Plo + -rm -f ./$(DEPDIR)/passverify.Plo + -rm -f ./$(DEPDIR)/support.Plo + -rm -f ./$(DEPDIR)/unix_chkpwd-bigcrypt.Po + -rm -f ./$(DEPDIR)/unix_chkpwd-md5_broken.Po + -rm -f ./$(DEPDIR)/unix_chkpwd-md5_good.Po + -rm -f ./$(DEPDIR)/unix_chkpwd-passverify.Po + -rm -f ./$(DEPDIR)/unix_chkpwd-unix_chkpwd.Po + -rm -f ./$(DEPDIR)/unix_update-bigcrypt.Po + -rm -f ./$(DEPDIR)/unix_update-md5_broken.Po + -rm -f ./$(DEPDIR)/unix_update-md5_good.Po + -rm -f ./$(DEPDIR)/unix_update-passverify.Po + -rm -f ./$(DEPDIR)/unix_update-unix_update.Po + -rm -f ./$(DEPDIR)/yppasswd_xdr.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -1397,7 +1460,28 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) + -rm -f ./$(DEPDIR)/bigcrypt-bigcrypt.Po + -rm -f ./$(DEPDIR)/bigcrypt-bigcrypt_main.Po + -rm -f ./$(DEPDIR)/bigcrypt.Plo + -rm -f ./$(DEPDIR)/md5_broken.Plo + -rm -f ./$(DEPDIR)/md5_good.Plo + -rm -f ./$(DEPDIR)/pam_unix_acct.Plo + -rm -f ./$(DEPDIR)/pam_unix_auth.Plo + -rm -f ./$(DEPDIR)/pam_unix_passwd.Plo + -rm -f ./$(DEPDIR)/pam_unix_sess.Plo + -rm -f ./$(DEPDIR)/passverify.Plo + -rm -f ./$(DEPDIR)/support.Plo + -rm -f ./$(DEPDIR)/unix_chkpwd-bigcrypt.Po + -rm -f ./$(DEPDIR)/unix_chkpwd-md5_broken.Po + -rm -f ./$(DEPDIR)/unix_chkpwd-md5_good.Po + -rm -f ./$(DEPDIR)/unix_chkpwd-passverify.Po + -rm -f ./$(DEPDIR)/unix_chkpwd-unix_chkpwd.Po + -rm -f ./$(DEPDIR)/unix_update-bigcrypt.Po + -rm -f ./$(DEPDIR)/unix_update-md5_broken.Po + -rm -f ./$(DEPDIR)/unix_update-md5_good.Po + -rm -f ./$(DEPDIR)/unix_update-passverify.Po + -rm -f ./$(DEPDIR)/unix_update-unix_update.Po + -rm -f ./$(DEPDIR)/yppasswd_xdr.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -1421,10 +1505,11 @@ uninstall-man: uninstall-man8 .MAKE: check-am install-am install-strip -.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \ - clean-generic clean-libtool clean-noinstPROGRAMS \ - clean-sbinPROGRAMS clean-securelibLTLIBRARIES cscopelist-am \ - ctags ctags-am distclean distclean-compile distclean-generic \ +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \ + check-am clean clean-generic clean-libtool \ + clean-noinstPROGRAMS 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 \ @@ -1439,7 +1524,8 @@ uninstall-man: uninstall-man8 uninstall-man8 uninstall-sbinPROGRAMS \ uninstall-securelibLTLIBRARIES -@ENABLE_REGENERATE_MAN_TRUE@README: pam_unix.8.xml +.PRECIOUS: Makefile + @ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/modules/pam_unix/README b/modules/pam_unix/README index 651ed9c8..a87f34a5 100644 --- a/modules/pam_unix/README +++ b/modules/pam_unix/README @@ -69,6 +69,12 @@ nullok service if their official password is blank. The nullok argument overrides this default. +nullresetok + + Allow users to authenticate with blank password if password reset is + enforced even if nullok is not set. If password reset is not required and + nullok is not set the authentication with blank password will be denied. + try_first_pass Before prompting the user for their password, the module first tries the @@ -128,25 +134,35 @@ bigcrypt sha256 When a user changes their password next, encrypt it with the SHA256 - algorithm. If the SHA256 algorithm is not known to the crypt(3) function, - fall back to MD5. + algorithm. The SHA256 algorithm must be supported by the crypt(3) function. sha512 When a user changes their password next, encrypt it with the SHA512 - algorithm. If the SHA512 algorithm is not known to the crypt(3) function, - fall back to MD5. + algorithm. The SHA512 algorithm must be supported by the crypt(3) function. blowfish When a user changes their password next, encrypt it with the blowfish - algorithm. If the blowfish algorithm is not known to the crypt(3) function, - fall back to MD5. + algorithm. The blowfish algorithm must be supported by the crypt(3) + function. + +gost_yescrypt + + When a user changes their password next, encrypt it with the gost-yescrypt + algorithm. The gost-yescrypt algorithm must be supported by the crypt(3) + function. + +yescrypt + + When a user changes their password next, encrypt it with the yescrypt + algorithm. The yescrypt algorithm must be supported by the crypt(3) + function. rounds=n - Set the optional number of rounds of the SHA256, SHA512 and blowfish - password hashing algorithms to n. + Set the optional number of rounds of the SHA256, SHA512, blowfish, + gost-yescrypt, and yescrypt password hashing algorithms to n. broken_shadow @@ -180,7 +196,7 @@ account required pam_unix.so # Change the user's password, but at first check the strength # with pam_cracklib(8) password required pam_cracklib.so retry=3 minlen=6 difok=3 -password required pam_unix.so use_authtok nullok md5 +password required pam_unix.so use_authtok nullok yescrypt session required pam_unix.so diff --git a/modules/pam_unix/bigcrypt.c b/modules/pam_unix/bigcrypt.c index e1d57a07..e08e4098 100644 --- a/modules/pam_unix/bigcrypt.c +++ b/modules/pam_unix/bigcrypt.c @@ -13,7 +13,7 @@ * Description: The cleartext is divided into blocks of SEGMENT_SIZE=8 * characters or less. Each block is encrypted using the standard UNIX * libc crypt function. The result of the encryption for one block - * provides the salt for the suceeding block. + * provides the salt for the succeeding block. * * Restrictions: The buffer used to hold the encrypted result is * statically allocated. (see MAX_PASS_LEN below). This is necessary, diff --git a/modules/pam_unix/md5.c b/modules/pam_unix/md5.c index 94f0485b..9954536f 100644 --- a/modules/pam_unix/md5.c +++ b/modules/pam_unix/md5.c @@ -24,13 +24,16 @@ #ifndef HIGHFIRST #define byteReverse(buf, len) /* Nothing */ #else -static void byteReverse(unsigned char *buf, unsigned longs); + +typedef unsigned char PAM_ATTRIBUTE_ALIGNED(4) uint8_aligned; + +static void byteReverse(uint8_aligned *buf, unsigned longs); #ifndef ASM_MD5 /* * Note: this code is harmless on little-endian machines. */ -static void byteReverse(unsigned char *buf, unsigned longs) +static void byteReverse(uint8_aligned *buf, unsigned longs) { uint32 t; do { diff --git a/modules/pam_unix/md5.h b/modules/pam_unix/md5.h index 103f168a..d9186b7f 100644 --- a/modules/pam_unix/md5.h +++ b/modules/pam_unix/md5.h @@ -2,12 +2,14 @@ #ifndef MD5_H #define MD5_H +#include "pam_cc_compat.h" + typedef unsigned int uint32; struct MD5Context { uint32 buf[4]; uint32 bits[2]; - unsigned char in[64]; + unsigned char in[64] PAM_ATTRIBUTE_ALIGNED(4); }; void GoodMD5Init(struct MD5Context *); diff --git a/modules/pam_unix/md5_crypt.c b/modules/pam_unix/md5_crypt.c index 4ab9ec84..94f7b434 100644 --- a/modules/pam_unix/md5_crypt.c +++ b/modules/pam_unix/md5_crypt.c @@ -15,6 +15,7 @@ #include <string.h> #include <stdlib.h> #include "md5.h" +#include "pam_inline.h" static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */ "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; @@ -55,8 +56,8 @@ char *MD5Name(crypt_md5)(const char *pw, const char *salt) return NULL; /* If it starts with the magic string, then skip that */ - if (!strncmp(sp, magic, strlen(magic))) - sp += strlen(magic); + if ((ep = pam_str_skip_prefix_len(sp, magic, strlen(magic))) != NULL) + sp = ep; /* It stops at the first '$', max 8 chars */ for (ep = sp; *ep && *ep != '$' && ep < (sp + 8); ep++) diff --git a/modules/pam_unix/pam_unix.8 b/modules/pam_unix/pam_unix.8 index b3808f1a..b396b66c 100644 --- a/modules/pam_unix/pam_unix.8 +++ b/modules/pam_unix/pam_unix.8 @@ -1,13 +1,13 @@ '\" t .\" Title: pam_unix .\" Author: [see the "AUTHOR" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/> -.\" Date: 05/18/2017 +.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/> +.\" Date: 06/08/2020 .\" Manual: Linux-PAM Manual .\" Source: Linux-PAM Manual .\" Language: English .\" -.TH "PAM_UNIX" "8" "05/18/2017" "Linux-PAM Manual" "Linux\-PAM Manual" +.TH "PAM_UNIX" "8" "06/08/2020" "Linux-PAM Manual" "Linux\-PAM Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -95,6 +95,15 @@ The default action of this module is to not permit the user access to a service argument overrides this default\&. .RE .PP +\fBnullresetok\fR +.RS 4 +Allow users to authenticate with blank password if password reset is enforced even if +\fBnullok\fR +is not set\&. If password reset is not required and +\fBnullok\fR +is not set the authentication with blank password will be denied\&. +.RE +.PP \fBtry_first_pass\fR .RS 4 Before prompting the user for their password, the module first tries the previous stacked module\*(Aqs password in case that satisfies this module as well\&. @@ -159,28 +168,42 @@ When a user changes their password next, encrypt it with the DEC C2 algorithm\&. .PP \fBsha256\fR .RS 4 -When a user changes their password next, encrypt it with the SHA256 algorithm\&. If the SHA256 algorithm is not known to the +When a user changes their password next, encrypt it with the SHA256 algorithm\&. The SHA256 algorithm must be supported by the \fBcrypt\fR(3) -function, fall back to MD5\&. +function\&. .RE .PP \fBsha512\fR .RS 4 -When a user changes their password next, encrypt it with the SHA512 algorithm\&. If the SHA512 algorithm is not known to the +When a user changes their password next, encrypt it with the SHA512 algorithm\&. The SHA512 algorithm must be supported by the \fBcrypt\fR(3) -function, fall back to MD5\&. +function\&. .RE .PP \fBblowfish\fR .RS 4 -When a user changes their password next, encrypt it with the blowfish algorithm\&. If the blowfish algorithm is not known to the +When a user changes their password next, encrypt it with the blowfish algorithm\&. The blowfish algorithm must be supported by the +\fBcrypt\fR(3) +function\&. +.RE +.PP +\fBgost_yescrypt\fR +.RS 4 +When a user changes their password next, encrypt it with the gost\-yescrypt algorithm\&. The gost\-yescrypt algorithm must be supported by the +\fBcrypt\fR(3) +function\&. +.RE +.PP +\fByescrypt\fR +.RS 4 +When a user changes their password next, encrypt it with the yescrypt algorithm\&. The yescrypt algorithm must be supported by the \fBcrypt\fR(3) -function, fall back to MD5\&. +function\&. .RE .PP \fBrounds=\fR\fB\fIn\fR\fR .RS 4 -Set the optional number of rounds of the SHA256, SHA512 and blowfish password hashing algorithms to +Set the optional number of rounds of the SHA256, SHA512, blowfish, gost\-yescrypt, and yescrypt password hashing algorithms to \fIn\fR\&. .RE .PP @@ -243,7 +266,7 @@ account required pam_unix\&.so # Change the user\*(Aqs password, but at first check the strength # with pam_cracklib(8) password required pam_cracklib\&.so retry=3 minlen=6 difok=3 -password required pam_unix\&.so use_authtok nullok md5 +password required pam_unix\&.so use_authtok nullok yescrypt session required pam_unix\&.so .fi diff --git a/modules/pam_unix/pam_unix.8.xml b/modules/pam_unix/pam_unix.8.xml index 1b318f11..fa02c3a6 100644 --- a/modules/pam_unix/pam_unix.8.xml +++ b/modules/pam_unix/pam_unix.8.xml @@ -165,6 +165,19 @@ </varlistentry> <varlistentry> <term> + <option>nullresetok</option> + </term> + <listitem> + <para> + Allow users to authenticate with blank password if password reset + is enforced even if <option>nullok</option> is not set. If password + reset is not required and <option>nullok</option> is not set the + authentication with blank password will be denied. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> <option>try_first_pass</option> </term> <listitem> @@ -293,11 +306,10 @@ <listitem> <para> When a user changes their password next, - encrypt it with the SHA256 algorithm. If the - SHA256 algorithm is not known to the <citerefentry> + encrypt it with the SHA256 algorithm. The + SHA256 algorithm must be supported by the <citerefentry> <refentrytitle>crypt</refentrytitle><manvolnum>3</manvolnum> - </citerefentry> function, - fall back to MD5. + </citerefentry> function. </para> </listitem> </varlistentry> @@ -308,11 +320,10 @@ <listitem> <para> When a user changes their password next, - encrypt it with the SHA512 algorithm. If the - SHA512 algorithm is not known to the <citerefentry> + encrypt it with the SHA512 algorithm. The + SHA512 algorithm must be supported by the <citerefentry> <refentrytitle>crypt</refentrytitle><manvolnum>3</manvolnum> - </citerefentry> function, - fall back to MD5. + </citerefentry> function. </para> </listitem> </varlistentry> @@ -323,11 +334,38 @@ <listitem> <para> When a user changes their password next, - encrypt it with the blowfish algorithm. If the - blowfish algorithm is not known to the <citerefentry> + encrypt it with the blowfish algorithm. The + blowfish algorithm must be supported by the <citerefentry> + <refentrytitle>crypt</refentrytitle><manvolnum>3</manvolnum> + </citerefentry> function. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <option>gost_yescrypt</option> + </term> + <listitem> + <para> + When a user changes their password next, + encrypt it with the gost-yescrypt algorithm. The + gost-yescrypt algorithm must be supported by the <citerefentry> + <refentrytitle>crypt</refentrytitle><manvolnum>3</manvolnum> + </citerefentry> function. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <option>yescrypt</option> + </term> + <listitem> + <para> + When a user changes their password next, + encrypt it with the yescrypt algorithm. The + yescrypt algorithm must be supported by the <citerefentry> <refentrytitle>crypt</refentrytitle><manvolnum>3</manvolnum> - </citerefentry> function, - fall back to MD5. + </citerefentry> function. </para> </listitem> </varlistentry> @@ -337,8 +375,9 @@ </term> <listitem> <para> - Set the optional number of rounds of the SHA256, SHA512 - and blowfish password hashing algorithms to + Set the optional number of rounds of the SHA256, SHA512, + blowfish, gost-yescrypt, and yescrypt password hashing + algorithms to <replaceable>n</replaceable>. </para> </listitem> @@ -428,7 +467,7 @@ account required pam_unix.so # Change the user's password, but at first check the strength # with pam_cracklib(8) password required pam_cracklib.so retry=3 minlen=6 difok=3 -password required pam_unix.so use_authtok nullok md5 +password required pam_unix.so use_authtok nullok yescrypt session required pam_unix.so </programlisting> </para> diff --git a/modules/pam_unix/pam_unix_acct.c b/modules/pam_unix/pam_unix_acct.c index 88331149..de8d65c1 100644 --- a/modules/pam_unix/pam_unix_acct.c +++ b/modules/pam_unix/pam_unix_acct.c @@ -1,6 +1,8 @@ /* + * pam_unix account management + * * Copyright Elliot Lee, 1996. All rights reserved. - * Copyright Jan Rêkorajski, 1999. All rights reserved. + * Copyright Jan RÄ™korajski, 1999. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -51,18 +53,15 @@ #include <security/_pam_macros.h> -/* indicate that the following groups are defined */ - -#define PAM_SM_ACCOUNT - #include <security/pam_modules.h> #include <security/pam_ext.h> #include <security/pam_modutil.h> +#include "pam_cc_compat.h" #include "support.h" #include "passverify.h" -int _unix_run_verify_binary(pam_handle_t *pamh, unsigned int ctrl, +int _unix_run_verify_binary(pam_handle_t *pamh, unsigned long long ctrl, const char *user, int *daysleft) { int retval=0, child, fds[2]; @@ -127,7 +126,9 @@ int _unix_run_verify_binary(pam_handle_t *pamh, unsigned int ctrl, args[1] = user; args[2] = "chkexpiry"; + DIAG_PUSH_IGNORE_CAST_QUAL; execve(CHKPWD_HELPER, (char *const *) args, envp); + DIAG_POP_IGNORE_CAST_QUAL; pam_syslog(pamh, LOG_ERR, "helper binary execve failed: %m"); /* should not get here: exit with error */ @@ -185,12 +186,10 @@ int _unix_run_verify_binary(pam_handle_t *pamh, unsigned int ctrl, int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv) { - unsigned int ctrl; + unsigned long long ctrl; const void *void_uname; const char *uname; int retval, daysleft; - struct spwd *spent; - struct passwd *pwent; char buf[256]; D(("called.")); @@ -207,29 +206,7 @@ pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv) return PAM_USER_UNKNOWN; } - retval = get_account_info(pamh, uname, &pwent, &spent); - if (retval == PAM_USER_UNKNOWN) { - pam_syslog(pamh, LOG_ERR, - "could not identify user (from getpwnam(%s))", - uname); - return retval; - } - - if (retval == PAM_SUCCESS && spent == NULL) - return PAM_SUCCESS; - - if (retval == PAM_UNIX_RUN_HELPER) { - retval = _unix_run_verify_binary(pamh, ctrl, uname, &daysleft); - if (retval == PAM_AUTHINFO_UNAVAIL && - on(UNIX_BROKEN_SHADOW, ctrl)) - return PAM_SUCCESS; - } else if (retval != PAM_SUCCESS) { - if (on(UNIX_BROKEN_SHADOW,ctrl)) - return PAM_SUCCESS; - else - return retval; - } else - retval = check_shadow_expiry(pamh, spent, &daysleft); + retval = _unix_verify_user(pamh, ctrl, uname, &daysleft); if (on(UNIX_NO_PASS_EXPIRY, ctrl)) { const void *pretval = NULL; @@ -250,7 +227,7 @@ pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv) "account %s has expired (account expired)", uname); _make_remark(pamh, ctrl, PAM_ERROR_MSG, - _("Your account has expired; please contact your system administrator")); + _("Your account has expired; please contact your system administrator.")); break; case PAM_NEW_AUTHTOK_REQD: if (daysleft == 0) { @@ -258,13 +235,13 @@ pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv) "expired password for user %s (root enforced)", uname); _make_remark(pamh, ctrl, PAM_ERROR_MSG, - _("You are required to change your password immediately (administrator enforced)")); + _("You are required to change your password immediately (administrator enforced).")); } else { pam_syslog(pamh, LOG_DEBUG, "expired password for user %s (password aged)", uname); _make_remark(pamh, ctrl, PAM_ERROR_MSG, - _("You are required to change your password immediately (password expired)")); + _("You are required to change your password immediately (password expired).")); } break; case PAM_AUTHTOK_EXPIRED: @@ -272,7 +249,7 @@ pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv) "account %s has expired (failed to change password)", uname); _make_remark(pamh, ctrl, PAM_ERROR_MSG, - _("Your account has expired; please contact your system administrator")); + _("Your account has expired; please contact your system administrator.")); break; case PAM_AUTHTOK_ERR: retval = PAM_SUCCESS; @@ -285,19 +262,19 @@ pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv) #if defined HAVE_DNGETTEXT && defined ENABLE_NLS snprintf (buf, sizeof (buf), dngettext(PACKAGE, - "Warning: your password will expire in %d day", - "Warning: your password will expire in %d days", + "Warning: your password will expire in %d day.", + "Warning: your password will expire in %d days.", daysleft), daysleft); #else if (daysleft == 1) snprintf(buf, sizeof (buf), - _("Warning: your password will expire in %d day"), + _("Warning: your password will expire in %d day."), daysleft); else snprintf(buf, sizeof (buf), /* TRANSLATORS: only used if dngettext is not supported */ - _("Warning: your password will expire in %d days"), + _("Warning: your password will expire in %d days."), daysleft); #endif _make_remark(pamh, ctrl, PAM_TEXT_INFO, buf); diff --git a/modules/pam_unix/pam_unix_auth.c b/modules/pam_unix/pam_unix_auth.c index fce6bce1..4eccff8e 100644 --- a/modules/pam_unix/pam_unix_auth.c +++ b/modules/pam_unix/pam_unix_auth.c @@ -1,7 +1,9 @@ /* + * pam_unix authentication management + * * Copyright Alexander O. Yuriev, 1996. All rights reserved. * NIS+ support by Thorsten Kukuk <kukuk@weber.uni-paderborn.de> - * Copyright Jan Rêkorajski, 1999. All rights reserved. + * Copyright Jan RÄ™korajski, 1999. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -48,11 +50,6 @@ #include <sys/stat.h> #include <syslog.h> -/* indicate the following groups are defined */ - -#define PAM_SM_AUTH - -#define _PAM_EXTERN_FUNCTIONS #include <security/_pam_macros.h> #include <security/pam_modules.h> #include <security/pam_ext.h> @@ -74,8 +71,6 @@ * onto a normal UNIX authentication */ -#define _UNIX_AUTHTOK "-UN*X-PASS" - #define AUTH_RETURN \ do { \ D(("recording return code for next time [%d]", \ @@ -98,7 +93,7 @@ setcred_free (pam_handle_t *pamh UNUSED, void *ptr, int err UNUSED) int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) { - unsigned int ctrl; + unsigned long long ctrl; int retval, *ret_data = NULL; const char *name; const char *p; @@ -126,21 +121,22 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) * '+' or '-' as the first character of a user name. Don't * allow this characters here. */ - if (name == NULL || name[0] == '-' || name[0] == '+') { - pam_syslog(pamh, LOG_ERR, "bad username [%s]", name); + if (name[0] == '-' || name[0] == '+') { + pam_syslog(pamh, LOG_NOTICE, "bad username [%s]", name); retval = PAM_USER_UNKNOWN; AUTH_RETURN; } if (on(UNIX_DEBUG, ctrl)) - D(("username [%s] obtained", name)); + pam_syslog(pamh, LOG_DEBUG, "username [%s] obtained", name); } else { - D(("trouble reading username")); if (retval == PAM_CONV_AGAIN) { D(("pam_get_user/conv() function is not ready yet")); /* it is safe to resume this function so we translate this * retval to the value that indicates we're happy to resume. */ retval = PAM_INCOMPLETE; + } else if (on(UNIX_DEBUG, ctrl)) { + pam_syslog(pamh, LOG_DEBUG, "could not obtain username"); } AUTH_RETURN; } @@ -148,7 +144,7 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) /* if this user does not have a password... */ if (_unix_blankpasswd(pamh, ctrl, name)) { - D(("user '%s' has blank passwd", name)); + pam_syslog(pamh, LOG_DEBUG, "user [%s] has blank password; authenticated without it", name); name = NULL; retval = PAM_SUCCESS; AUTH_RETURN; @@ -196,7 +192,7 @@ pam_sm_setcred (pam_handle_t *pamh, int flags, { int retval; const void *pretval = NULL; - unsigned int ctrl; + unsigned long long ctrl; D(("called.")); diff --git a/modules/pam_unix/pam_unix_passwd.c b/modules/pam_unix/pam_unix_passwd.c index 9fdebefb..e988b2e3 100644 --- a/modules/pam_unix/pam_unix_passwd.c +++ b/modules/pam_unix/pam_unix_passwd.c @@ -1,7 +1,9 @@ /* + * pam_unix password management + * * Main coding by Elliot Lee <sopwith@redhat.com>, Red Hat Software. * Copyright (C) 1996. - * Copyright (c) Jan Rêkorajski, 1999. + * Copyright (c) Jan RÄ™korajski, 1999. * Copyright (c) Red Hat, Inc., 2007, 2008. * * Redistribution and use in source and binary forms, with or without @@ -56,20 +58,15 @@ #include <sys/stat.h> #include <signal.h> -#include <errno.h> #include <sys/wait.h> #include <sys/resource.h> #include <security/_pam_macros.h> - -/* indicate the following groups are defined */ - -#define PAM_SM_PASSWORD - #include <security/pam_modules.h> #include <security/pam_ext.h> #include <security/pam_modutil.h> +#include "pam_cc_compat.h" #include "md5.h" #include "support.h" #include "passverify.h" @@ -106,11 +103,6 @@ extern int getrpcport(const char *host, unsigned long prognum, Sets it. */ -/* data tokens */ - -#define _UNIX_OLD_AUTHTOK "-UN*X-OLD-PASS" -#define _UNIX_NEW_AUTHTOK "-UN*X-NEW-PASS" - #define MAX_PASSWD_TRIES 3 #ifdef HAVE_NIS @@ -143,7 +135,7 @@ __taddr2port (const struct netconfig *nconf, const struct netbuf *nbuf) } #endif -static char *getNISserver(pam_handle_t *pamh, unsigned int ctrl) +static char *getNISserver(pam_handle_t *pamh, unsigned long long ctrl) { char *master; char *domainname; @@ -238,7 +230,7 @@ static char *getNISserver(pam_handle_t *pamh, unsigned int ctrl) #ifdef WITH_SELINUX -static int _unix_run_update_binary(pam_handle_t *pamh, unsigned int ctrl, const char *user, +static int _unix_run_update_binary(pam_handle_t *pamh, unsigned long long ctrl, const char *user, const char *fromwhat, const char *towhat, int remember) { int retval, child, fds[2]; @@ -298,7 +290,9 @@ static int _unix_run_update_binary(pam_handle_t *pamh, unsigned int ctrl, const snprintf(buffer, sizeof(buffer), "%d", remember); args[4] = buffer; + DIAG_PUSH_IGNORE_CAST_QUAL; execve(UPDATE_HELPER, (char *const *) args, envp); + DIAG_POP_IGNORE_CAST_QUAL; /* should not get here: exit with error */ D(("helper binary is not available")); @@ -355,7 +349,7 @@ static int _unix_run_update_binary(pam_handle_t *pamh, unsigned int ctrl, const static int check_old_password(const char *forwho, const char *newpass) { static char buf[16384]; - char *s_luser, *s_uid, *s_npas, *s_pas; + char *s_pas; int retval = PAM_SUCCESS; FILE *opwfile; size_t len = strlen(forwho); @@ -369,9 +363,9 @@ static int check_old_password(const char *forwho, const char *newpass) buf[len] == ',')) { char *sptr; buf[strlen(buf) - 1] = '\0'; - s_luser = strtok_r(buf, ":,", &sptr); - s_uid = strtok_r(NULL, ":,", &sptr); - s_npas = strtok_r(NULL, ":,", &sptr); + /* s_luser = */ strtok_r(buf, ":,", &sptr); + /* s_uid = */ strtok_r(NULL, ":,", &sptr); + /* s_npas = */ strtok_r(NULL, ":,", &sptr); s_pas = strtok_r(NULL, ":,", &sptr); while (s_pas != NULL) { char *md5pass = Goodcrypt_md5(newpass, s_pas); @@ -393,12 +387,11 @@ static int check_old_password(const char *forwho, const char *newpass) static int _do_setpass(pam_handle_t* pamh, const char *forwho, const char *fromwhat, - char *towhat, unsigned int ctrl, int remember) + char *towhat, unsigned long long ctrl, int remember) { struct passwd *pwd = NULL; int retval = 0; int unlocked = 0; - char *master = NULL; D(("called")); @@ -411,6 +404,8 @@ static int _do_setpass(pam_handle_t* pamh, const char *forwho, if (on(UNIX_NIS, ctrl) && _unix_comesfromsource(pamh, forwho, 0, 1)) { #ifdef HAVE_NIS + char *master; + if ((master=getNISserver(pamh, ctrl)) != NULL) { struct timeval timeout; struct yppasswd yppwd; @@ -517,7 +512,7 @@ done: return retval; } -static int _unix_verify_shadow(pam_handle_t *pamh, const char *user, unsigned int ctrl) +static int _unix_verify_shadow(pam_handle_t *pamh, const char *user, unsigned long long ctrl) { struct passwd *pwent = NULL; /* Password and shadow password */ struct spwd *spent = NULL; /* file entries for the user */ @@ -547,7 +542,7 @@ static int _unix_verify_shadow(pam_handle_t *pamh, const char *user, unsigned in } static int _pam_unix_approve_pass(pam_handle_t * pamh - ,unsigned int ctrl + ,unsigned long long ctrl ,const char *pass_old ,const char *pass_new, int pass_min_len) @@ -565,7 +560,8 @@ static int _pam_unix_approve_pass(pam_handle_t * pamh pam_syslog(pamh, LOG_DEBUG, "bad authentication token"); } _make_remark(pamh, ctrl, PAM_ERROR_MSG, pass_new == NULL ? - _("No password supplied") : _("Password unchanged")); + _("No password has been supplied.") : + _("The password has not been changed.")); return PAM_AUTHTOK_ERR; } /* @@ -580,9 +576,13 @@ static int _pam_unix_approve_pass(pam_handle_t * pamh return PAM_AUTHTOK_ERR; } } - if (off(UNIX__IAMROOT, ctrl)) { - if (strlen(pass_new) < pass_min_len) - remark = _("You must choose a longer password"); + + if (strlen(pass_new) > MAXPASS) { + remark = _("You must choose a shorter password."); + D(("length exceeded [%s]", remark)); + } else if (off(UNIX__IAMROOT, ctrl)) { + if ((int)strlen(pass_new) < pass_min_len) + remark = _("You must choose a longer password."); D(("length check [%s]", remark)); if (on(UNIX_REMEMBER_PASSWD, ctrl)) { if ((retval = check_old_password(user, pass_new)) == PAM_AUTHTOK_ERR) @@ -604,10 +604,10 @@ static int _pam_unix_approve_pass(pam_handle_t * pamh int pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv) { - unsigned int ctrl, lctrl; + unsigned long long ctrl, lctrl; int retval; int remember = -1; - int rounds = -1; + int rounds = 0; int pass_min_len = 0; /* <DO NOT free() THESE> */ @@ -631,8 +631,8 @@ pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv) * '+' or '-' as the first character of a user name. Don't * allow them. */ - if (user == NULL || user[0] == '-' || user[0] == '+') { - pam_syslog(pamh, LOG_ERR, "bad username [%s]", user); + if (user[0] == '-' || user[0] == '+') { + pam_syslog(pamh, LOG_NOTICE, "bad username [%s]", user); return PAM_USER_UNKNOWN; } if (retval == PAM_SUCCESS && on(UNIX_DEBUG, ctrl)) @@ -719,7 +719,7 @@ pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv) if (retval == PAM_AUTHTOK_ERR) { if (off(UNIX__IAMROOT, ctrl)) _make_remark(pamh, ctrl, PAM_ERROR_MSG, - _("You must wait longer to change your password")); + _("You must wait longer to change your password.")); else retval = PAM_SUCCESS; } diff --git a/modules/pam_unix/pam_unix_sess.c b/modules/pam_unix/pam_unix_sess.c index 03e7dcd9..3f6a8fb3 100644 --- a/modules/pam_unix/pam_unix_sess.c +++ b/modules/pam_unix/pam_unix_sess.c @@ -1,8 +1,8 @@ /* - * $Id$ + * pam_unix session management * * Copyright Alexander O. Yuriev, 1996. All rights reserved. - * Copyright Jan Rêkorajski, 1999. All rights reserved. + * Copyright Jan RÄ™korajski, 1999. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -47,10 +47,6 @@ #include <sys/types.h> #include <sys/stat.h> -/* indicate the following groups are defined */ - -#define PAM_SM_SESSION - #include <security/_pam_macros.h> #include <security/pam_modules.h> #include <security/pam_ext.h> @@ -67,9 +63,9 @@ int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv) { char *user_name, *service; - unsigned int ctrl; + unsigned long long ctrl; int retval; - const char *login_name; + const char *login_name; D(("called.")); @@ -78,24 +74,31 @@ pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv) retval = pam_get_item(pamh, PAM_USER, (void *) &user_name); if (user_name == NULL || *user_name == '\0' || retval != PAM_SUCCESS) { pam_syslog(pamh, LOG_ERR, - "open_session - error recovering username"); + "open_session - error recovering username"); return PAM_SESSION_ERR; /* How did we get authenticated with no username?! */ } retval = pam_get_item(pamh, PAM_SERVICE, (void *) &service); if (service == NULL || *service == '\0' || retval != PAM_SUCCESS) { pam_syslog(pamh, LOG_CRIT, - "open_session - error recovering service"); + "open_session - error recovering service"); return PAM_SESSION_ERR; } login_name = pam_modutil_getlogin(pamh); if (login_name == NULL) { - login_name = ""; + login_name = ""; + } + if (off (UNIX_QUIET, ctrl)) { + char uid[32]; + struct passwd *pwd = pam_modutil_getpwnam (pamh, user_name); + if (pwd == NULL) { + snprintf (uid, 32, "getpwnam error"); + } + else { + snprintf (uid, 32, "%u", pwd->pw_uid); + } + pam_syslog(pamh, LOG_INFO, "session opened for user %s(uid=%s) by %s(uid=%lu)", user_name, uid, login_name, (unsigned long)getuid()); } - if (off (UNIX_QUIET, ctrl)) - pam_syslog(pamh, LOG_INFO, "session opened for user %s by %s(uid=%lu)", - user_name, login_name, (unsigned long)getuid()); - return PAM_SUCCESS; } @@ -103,7 +106,7 @@ int pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, const char **argv) { char *user_name, *service; - unsigned int ctrl; + unsigned long long ctrl; int retval; D(("called.")); @@ -113,19 +116,19 @@ pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, const char **argv) retval = pam_get_item(pamh, PAM_USER, (void *) &user_name); if (user_name == NULL || *user_name == '\0' || retval != PAM_SUCCESS) { pam_syslog(pamh, LOG_ERR, - "close_session - error recovering username"); + "close_session - error recovering username"); return PAM_SESSION_ERR; /* How did we get authenticated with no username?! */ } retval = pam_get_item(pamh, PAM_SERVICE, (void *) &service); if (service == NULL || *service == '\0' || retval != PAM_SUCCESS) { pam_syslog(pamh, LOG_CRIT, - "close_session - error recovering service"); + "close_session - error recovering service"); return PAM_SESSION_ERR; } if (off (UNIX_QUIET, ctrl)) - pam_syslog(pamh, LOG_INFO, "session closed for user %s", - user_name); + pam_syslog(pamh, LOG_INFO, "session closed for user %s", + user_name); return PAM_SUCCESS; } diff --git a/modules/pam_unix/passverify.c b/modules/pam_unix/passverify.c index 9c1771e2..a571b4f7 100644 --- a/modules/pam_unix/passverify.c +++ b/modules/pam_unix/passverify.c @@ -25,6 +25,8 @@ #include <crypt.h> #endif +#include "pam_cc_compat.h" +#include "pam_inline.h" #include "md5.h" #include "bigcrypt.h" #include "passverify.h" @@ -65,8 +67,8 @@ strip_hpux_aging(char *hash) } } -int -verify_pwd_hash(const char *p, char *hash, unsigned int nullok) +PAMH_ARG_DECL(int verify_pwd_hash, + const char *p, char *hash, unsigned int nullok) { size_t hash_len; char *pp = NULL; @@ -87,7 +89,7 @@ verify_pwd_hash(const char *p, char *hash, unsigned int nullok) } else if (!p || *hash == '*' || *hash == '!') { retval = PAM_AUTH_ERR; } else { - if (!strncmp(hash, "$1$", 3)) { + if (pam_str_skip_prefix(hash, "$1$") != NULL) { pp = Goodcrypt_md5(p, hash); if (pp && strcmp(pp, hash) != 0) { _pam_delete(pp); @@ -103,6 +105,44 @@ verify_pwd_hash(const char *p, char *hash, unsigned int nullok) * Ok, we don't know the crypt algorithm, but maybe * libcrypt knows about it? We should try it. */ +#if defined(CRYPT_CHECKSALT_AVAILABLE) && CRYPT_CHECKSALT_AVAILABLE + /* Get the status of the hash from checksalt */ + int retval_checksalt = crypt_checksalt(hash); + + /* + * Check for hashing methods that are disabled by + * libcrypt configuration and/or system preset. + */ + if (retval_checksalt == CRYPT_SALT_METHOD_DISABLED) { + /* + * pam_syslog() needs a pam handle, + * but that's not available here. + */ + pam_syslog(pamh, LOG_ERR, + "The support for password hash \"%.6s\" " + "has been disabled in libcrypt " + "configuration.", + hash); + } + /* + * Check for malformed hashes, like descrypt hashes + * starting with "$2...", which might have been + * generated by unsafe base64 encoding functions + * as used in glibc <= 2.16. + * Such hashes are likely to be rejected by many + * recent implementations of libcrypt. + */ + if (retval_checksalt == CRYPT_SALT_INVALID) { + pam_syslog(pamh, LOG_ERR, + "The password hash \"%.6s\" is unknown to " + "libcrypt.", + hash); + } +#else +#ifndef HELPER_COMPILE + (void)pamh; +#endif +#endif #ifdef HAVE_CRYPT_R struct crypt_data *cdata; cdata = malloc(sizeof(*cdata)); @@ -166,25 +206,30 @@ PAMH_ARG_DECL(int get_account_info, save_euid = geteuid(); save_uid = getuid(); - if (save_uid == (*pwd)->pw_uid) - setreuid(save_euid, save_uid); - else { - setreuid(0, -1); - if (setreuid(-1, (*pwd)->pw_uid) == -1) { - setreuid(-1, 0); - setreuid(0, -1); - if(setreuid(-1, (*pwd)->pw_uid) == -1) + if (save_uid == (*pwd)->pw_uid) { + if (setreuid(save_euid, save_uid)) + return PAM_CRED_INSUFFICIENT; + } else { + if (setreuid(0, -1)) + return PAM_CRED_INSUFFICIENT; + if (setreuid(-1, (*pwd)->pw_uid)) { + if (setreuid(-1, 0) + || setreuid(0, -1) + || setreuid(-1, (*pwd)->pw_uid)) { return PAM_CRED_INSUFFICIENT; + } } } *spwdent = pam_modutil_getspnam(pamh, name); - if (save_uid == (*pwd)->pw_uid) - setreuid(save_uid, save_euid); - else { - setreuid(-1, 0); - setreuid(save_uid, -1); - setreuid(-1, save_euid); + if (save_uid == (*pwd)->pw_uid) { + if (setreuid(save_uid, save_euid)) + return PAM_CRED_INSUFFICIENT; + } else { + if (setreuid(-1, 0) + || setreuid(save_uid, -1) + || setreuid(-1, save_euid)) + return PAM_CRED_INSUFFICIENT; } if (*spwdent == NULL || (*spwdent)->sp_pwdp == NULL) @@ -244,7 +289,13 @@ PAMH_ARG_DECL(int check_shadow_expiry, D(("account expired")); return PAM_ACCT_EXPIRED; } +#if defined(CRYPT_CHECKSALT_AVAILABLE) && CRYPT_CHECKSALT_AVAILABLE + if (spent->sp_lstchg == 0 || + crypt_checksalt(spent->sp_pwdp) == CRYPT_SALT_METHOD_LEGACY || + crypt_checksalt(spent->sp_pwdp) == CRYPT_SALT_TOO_CHEAP) { +#else if (spent->sp_lstchg == 0) { +#endif D(("need a new password")); *daysleft = 0; return PAM_NEW_AUTHTOK_REQD; @@ -372,10 +423,15 @@ crypt_md5_wrapper(const char *pass_new) } PAMH_ARG_DECL(char * create_password_hash, - const char *password, unsigned int ctrl, int rounds) + const char *password, unsigned long long ctrl, int rounds) { const char *algoid; +#if defined(CRYPT_GENSALT_OUTPUT_SIZE) && CRYPT_GENSALT_OUTPUT_SIZE > 64 + /* Strings returned by crypt_gensalt_rn will be no longer than this. */ + char salt[CRYPT_GENSALT_OUTPUT_SIZE]; +#else char salt[64]; /* contains rounds number + max 16 bytes of salt + algo id */ +#endif char *sp; #ifdef HAVE_CRYPT_R struct crypt_data *cdata = NULL; @@ -384,8 +440,12 @@ PAMH_ARG_DECL(char * create_password_hash, if (on(UNIX_MD5_PASS, ctrl)) { /* algoid = "$1" */ return crypt_md5_wrapper(password); + } else if (on(UNIX_YESCRYPT_PASS, ctrl)) { + algoid = "$y$"; + } else if (on(UNIX_GOST_YESCRYPT_PASS, ctrl)) { + algoid = "$gy$"; } else if (on(UNIX_BLOWFISH_PASS, ctrl)) { - algoid = "$2a$"; + algoid = "$2b$"; } else if (on(UNIX_SHA256_PASS, ctrl)) { algoid = "$5$"; } else if (on(UNIX_SHA512_PASS, ctrl)) { @@ -406,6 +466,13 @@ PAMH_ARG_DECL(char * create_password_hash, return crypted; } +#if defined(CRYPT_GENSALT_IMPLEMENTS_AUTO_ENTROPY) && CRYPT_GENSALT_IMPLEMENTS_AUTO_ENTROPY + /* + * Any version of libcrypt supporting auto entropy is + * guaranteed to have crypt_gensalt_rn(). + */ + sp = crypt_gensalt_rn(algoid, rounds, NULL, 0, salt, sizeof(salt)); +#else #ifdef HAVE_CRYPT_GENSALT_R if (on(UNIX_BLOWFISH_PASS, ctrl)) { char entropy[17]; @@ -423,6 +490,7 @@ PAMH_ARG_DECL(char * create_password_hash, #ifdef HAVE_CRYPT_GENSALT_R } #endif +#endif /* CRYPT_GENSALT_IMPLEMENTS_AUTO_ENTROPY */ #ifdef HAVE_CRYPT_R sp = NULL; cdata = malloc(sizeof(*cdata)); @@ -434,10 +502,11 @@ PAMH_ARG_DECL(char * create_password_hash, sp = crypt(password, salt); #endif if (!sp || strncmp(algoid, sp, strlen(algoid)) != 0) { - /* libxcrypt/libc doesn't know the algorithm, use MD5 */ + /* libxcrypt/libc doesn't know the algorithm, error out */ pam_syslog(pamh, LOG_ERR, - "Algo %s not supported by the crypto backend, " - "falling back to MD5\n", + "Algo %s not supported by the crypto backend.\n", + on(UNIX_YESCRYPT_PASS, ctrl) ? "yescrypt" : + on(UNIX_GOST_YESCRYPT_PASS, ctrl) ? "gost_yescrypt" : on(UNIX_BLOWFISH_PASS, ctrl) ? "blowfish" : on(UNIX_SHA256_PASS, ctrl) ? "sha256" : on(UNIX_SHA512_PASS, ctrl) ? "sha512" : algoid); @@ -447,7 +516,7 @@ PAMH_ARG_DECL(char * create_password_hash, #ifdef HAVE_CRYPT_R free(cdata); #endif - return crypt_md5_wrapper(password); + return NULL; } sp = x_strdup(sp); #ifdef HAVE_CRYPT_R @@ -958,7 +1027,9 @@ PAMH_ARG_DECL(int unix_update_shadow, fclose(opwfile); if (!wroteentry && !err) { + DIAG_PUSH_IGNORE_CAST_QUAL; spwdent.sp_namp = (char *)forwho; + DIAG_POP_IGNORE_CAST_QUAL; spwdent.sp_pwdp = towhat; spwdent.sp_lstchg = time(NULL) / (60 * 60 * 24); if (spwdent.sp_lstchg == 0) @@ -1017,21 +1088,21 @@ int helper_verify_password(const char *name, const char *p, int nullok) { struct passwd *pwd = NULL; - char *salt = NULL; + char *hash = NULL; int retval; - retval = get_pwd_hash(name, &pwd, &salt); + retval = get_pwd_hash(name, &pwd, &hash); - if (pwd == NULL || salt == NULL) { + if (pwd == NULL || hash == NULL) { helper_log_err(LOG_NOTICE, "check pass; user unknown"); retval = PAM_USER_UNKNOWN; } else { - retval = verify_pwd_hash(p, salt, nullok); + retval = verify_pwd_hash(p, hash, nullok); } - if (salt) { - _pam_overwrite(salt); - _pam_drop(salt); + if (hash) { + _pam_overwrite(hash); + _pam_drop(hash); } p = NULL; /* no longer needed here */ @@ -1154,7 +1225,7 @@ read_passwords(int fd, int npass, char **passwords) #endif /* ****************************************************************** * - * Copyright (c) Jan Rêkorajski 1999. + * Copyright (c) Jan RÄ™korajski 1999. * Copyright (c) Andrew G. Morgan 1996-8. * Copyright (c) Alex O. Yuriev, 1996. * Copyright (c) Cristian Gafton 1996. diff --git a/modules/pam_unix/passverify.h b/modules/pam_unix/passverify.h index caf7ae8a..e9a88fbf 100644 --- a/modules/pam_unix/passverify.h +++ b/modules/pam_unix/passverify.h @@ -13,9 +13,6 @@ #define OLD_PASSWORDS_FILE "/etc/security/opasswd" int -verify_pwd_hash(const char *p, char *hash, unsigned int nullok); - -int is_pwd_shadowed(const struct passwd *pwd); char * @@ -65,8 +62,11 @@ read_passwords(int fd, int npass, char **passwords); #define PAMH_ARG(...) pamh, __VA_ARGS__ #endif +PAMH_ARG_DECL(int verify_pwd_hash, + const char *p, char *hash, unsigned int nullok); + PAMH_ARG_DECL(char * create_password_hash, - const char *password, unsigned int ctrl, int rounds); + const char *password, unsigned long long ctrl, int rounds); PAMH_ARG_DECL(int get_account_info, const char *name, struct passwd **pwd, struct spwd **spwdent); diff --git a/modules/pam_unix/support.c b/modules/pam_unix/support.c index f2e28d35..41db1f04 100644 --- a/modules/pam_unix/support.c +++ b/modules/pam_unix/support.c @@ -28,86 +28,14 @@ #include <security/pam_ext.h> #include <security/pam_modutil.h> +#include "pam_cc_compat.h" +#include "pam_inline.h" #include "support.h" #include "passverify.h" -static char * -search_key (const char *key, const char *filename) -{ - FILE *fp; - char *buf = NULL; - size_t buflen = 0; - char *retval = NULL; - - fp = fopen (filename, "r"); - if (NULL == fp) - return NULL; - - while (!feof (fp)) - { - char *tmp, *cp; -#if defined(HAVE_GETLINE) - ssize_t n = getline (&buf, &buflen, fp); -#elif defined (HAVE_GETDELIM) - ssize_t n = getdelim (&buf, &buflen, '\n', fp); -#else - ssize_t n; - - if (buf == NULL) - { - buflen = BUF_SIZE; - buf = malloc (buflen); - if (buf == NULL) { - fclose (fp); - return NULL; - } - } - buf[0] = '\0'; - if (fgets (buf, buflen - 1, fp) == NULL) - break; - else if (buf != NULL) - n = strlen (buf); - else - n = 0; -#endif /* HAVE_GETLINE / HAVE_GETDELIM */ - cp = buf; - - if (n < 1) - break; - - tmp = strchr (cp, '#'); /* remove comments */ - if (tmp) - *tmp = '\0'; - while (isspace ((int)*cp)) /* remove spaces and tabs */ - ++cp; - if (*cp == '\0') /* ignore empty lines */ - continue; - - if (cp[strlen (cp) - 1] == '\n') - cp[strlen (cp) - 1] = '\0'; - - tmp = strsep (&cp, " \t="); - if (cp != NULL) - while (isspace ((int)*cp) || *cp == '=') - ++cp; - - if (strcasecmp (tmp, key) == 0) - { - retval = strdup (cp); - break; - } - } - fclose (fp); - - free (buf); - - return retval; -} - - /* this is a front-end for module-application conversations */ -int _make_remark(pam_handle_t * pamh, unsigned int ctrl, +int _make_remark(pam_handle_t * pamh, unsigned long long ctrl, int type, const char *text) { int retval = PAM_SUCCESS; @@ -122,10 +50,11 @@ int _make_remark(pam_handle_t * pamh, unsigned int ctrl, * set the control flags for the UNIX module. */ -int _set_ctrl(pam_handle_t *pamh, int flags, int *remember, int *rounds, - int *pass_min_len, int argc, const char **argv) +unsigned long long _set_ctrl(pam_handle_t *pamh, int flags, int *remember, + int *rounds, int *pass_min_len, int argc, + const char **argv) { - unsigned int ctrl; + unsigned long long ctrl; char *val; int j; @@ -153,7 +82,7 @@ int _set_ctrl(pam_handle_t *pamh, int flags, int *remember, int *rounds, } /* preset encryption method with value from /etc/login.defs */ - val = search_key ("ENCRYPT_METHOD", LOGIN_DEFS); + val = pam_modutil_search_key(pamh, LOGIN_DEFS, "ENCRYPT_METHOD"); if (val) { for (j = 0; j < UNIX_CTRLS_; ++j) { if (unix_args[j].token && unix_args[j].is_hash_algo @@ -171,10 +100,11 @@ int _set_ctrl(pam_handle_t *pamh, int flags, int *remember, int *rounds, /* read number of rounds for crypt algo */ if (rounds && (on(UNIX_SHA256_PASS, ctrl) || on(UNIX_SHA512_PASS, ctrl))) { - val=search_key ("SHA_CRYPT_MAX_ROUNDS", LOGIN_DEFS); + val = pam_modutil_search_key(pamh, LOGIN_DEFS, "SHA_CRYPT_MAX_ROUNDS"); if (val) { *rounds = strtol(val, NULL, 10); + set(UNIX_ALGO_ROUNDS, ctrl); free (val); } } @@ -183,17 +113,20 @@ int _set_ctrl(pam_handle_t *pamh, int flags, int *remember, int *rounds, /* now parse the arguments to this module */ for (; argc-- > 0; ++argv) { + const char *str = NULL; D(("pam_unix arg: %s", *argv)); for (j = 0; j < UNIX_CTRLS_; ++j) { if (unix_args[j].token - && !strncmp(*argv, unix_args[j].token, strlen(unix_args[j].token))) { + && (str = pam_str_skip_prefix_len(*argv, + unix_args[j].token, + strlen(unix_args[j].token))) != NULL) { break; } } - if (j >= UNIX_CTRLS_) { + if (str == NULL) { pam_syslog(pamh, LOG_ERR, "unrecognized option [%s]", *argv); } else { @@ -204,7 +137,7 @@ int _set_ctrl(pam_handle_t *pamh, int flags, int *remember, int *rounds, "option remember not allowed for this module type"); continue; } - *remember = strtol(*argv + 9, NULL, 10); + *remember = strtol(str, NULL, 10); if ((*remember == INT_MIN) || (*remember == INT_MAX)) *remember = -1; if (*remember > 400) @@ -215,14 +148,14 @@ int _set_ctrl(pam_handle_t *pamh, int flags, int *remember, int *rounds, "option minlen not allowed for this module type"); continue; } - *pass_min_len = atoi(*argv + 7); + *pass_min_len = atoi(str); } else if (j == UNIX_ALGO_ROUNDS) { if (rounds == NULL) { pam_syslog(pamh, LOG_ERR, "option rounds not allowed for this module type"); continue; } - *rounds = strtol(*argv + 7, NULL, 10); + *rounds = strtol(str, NULL, 10); } ctrl &= unix_args[j].mask; /* for turning things off */ @@ -242,23 +175,33 @@ int _set_ctrl(pam_handle_t *pamh, int flags, int *remember, int *rounds, set(UNIX__NONULL, ctrl); } - /* Set default rounds for blowfish */ - if (on(UNIX_BLOWFISH_PASS, ctrl) && off(UNIX_ALGO_ROUNDS, ctrl) && rounds != NULL) { - *rounds = 5; - set(UNIX_ALGO_ROUNDS, ctrl); + /* Set default rounds for blowfish, gost-yescrypt and yescrypt */ + if (off(UNIX_ALGO_ROUNDS, ctrl) && rounds != NULL) { + if (on(UNIX_BLOWFISH_PASS, ctrl) || + on(UNIX_GOST_YESCRYPT_PASS, ctrl) || + on(UNIX_YESCRYPT_PASS, ctrl)) { + *rounds = 5; + set(UNIX_ALGO_ROUNDS, ctrl); + } } /* Enforce sane "rounds" values */ if (on(UNIX_ALGO_ROUNDS, ctrl)) { - if (on(UNIX_BLOWFISH_PASS, ctrl)) { + if (on(UNIX_GOST_YESCRYPT_PASS, ctrl) || + on(UNIX_YESCRYPT_PASS, ctrl)) { + if (*rounds < 3 || *rounds > 11) + *rounds = 5; + } else if (on(UNIX_BLOWFISH_PASS, ctrl)) { if (*rounds < 4 || *rounds > 31) *rounds = 5; } else if (on(UNIX_SHA256_PASS, ctrl) || on(UNIX_SHA512_PASS, ctrl)) { - if ((*rounds < 1000) || (*rounds == INT_MAX)) + if ((*rounds < 1000) || (*rounds == INT_MAX)) { /* don't care about bogus values */ + *rounds = 0; unset(UNIX_ALGO_ROUNDS, ctrl); - if (*rounds >= 10000000) + } else if (*rounds >= 10000000) { *rounds = 9999999; + } } } @@ -273,11 +216,6 @@ int _set_ctrl(pam_handle_t *pamh, int flags, int *remember, int *rounds, return ctrl; } -static void _cleanup(pam_handle_t * pamh UNUSED, void *x, int error_status UNUSED) -{ - _pam_delete(x); -} - /* ************************************************************** * * Useful non-trivial functions * * ************************************************************** */ @@ -417,7 +355,7 @@ int _unix_getpwnam(pam_handle_t *pamh, const char *name, } #else /* we don't have NIS support, make compiler happy. */ - nis = 0; + (void) nis; #endif if (matched && (ret != NULL)) { @@ -529,7 +467,7 @@ int _unix_comesfromsource(pam_handle_t *pamh, #include <sys/wait.h> static int _unix_run_helper_binary(pam_handle_t *pamh, const char *passwd, - unsigned int ctrl, const char *user) + unsigned long long ctrl, const char *user) { int retval, child, fds[2]; struct sigaction newsa, oldsa; @@ -593,7 +531,9 @@ static int _unix_run_helper_binary(pam_handle_t *pamh, const char *passwd, args[2]="nonull"; } + DIAG_PUSH_IGNORE_CAST_QUAL; execve(CHKPWD_HELPER, (char *const *) args, envp); + DIAG_POP_IGNORE_CAST_QUAL; /* should not get here: exit with error */ D(("helper binary is not available")); @@ -655,10 +595,11 @@ static int _unix_run_helper_binary(pam_handle_t *pamh, const char *passwd, */ int -_unix_blankpasswd (pam_handle_t *pamh, unsigned int ctrl, const char *name) +_unix_blankpasswd (pam_handle_t *pamh, unsigned long long ctrl, const char *name) { struct passwd *pwd = NULL; char *salt = NULL; + int daysleft; int retval; D(("called")); @@ -669,6 +610,15 @@ _unix_blankpasswd (pam_handle_t *pamh, unsigned int ctrl, const char *name) * else (CG) */ + if (on(UNIX_NULLRESETOK, ctrl)) { + retval = _unix_verify_user(pamh, ctrl, name, &daysleft); + if (retval == PAM_NEW_AUTHTOK_REQD) { + /* password reset is enforced, allow authentication with empty password */ + pam_syslog(pamh, LOG_DEBUG, "user [%s] has expired blank password, enabling nullok", name); + set(UNIX__NULLOK, ctrl); + } + } + if (on(UNIX__NONULL, ctrl)) return 0; /* will fail but don't let on yet */ @@ -703,11 +653,12 @@ _unix_blankpasswd (pam_handle_t *pamh, unsigned int ctrl, const char *name) } int _unix_verify_password(pam_handle_t * pamh, const char *name - ,const char *p, unsigned int ctrl) + ,const char *p, unsigned long long ctrl) { struct passwd *pwd = NULL; char *salt = NULL; char *data_name; + char pw[MAXPASS + 1]; int retval; @@ -734,6 +685,11 @@ int _unix_verify_password(pam_handle_t * pamh, const char *name strcpy(data_name + sizeof(FAIL_PREFIX) - 1, name); } + if (p != NULL && strlen(p) > MAXPASS) { + memset(pw, 0, sizeof(pw)); + p = strncpy(pw, p, sizeof(pw) - 1); + } + if (retval != PAM_SUCCESS) { if (retval == PAM_UNIX_RUN_HELPER) { D(("running helper binary")); @@ -758,7 +714,7 @@ int _unix_verify_password(pam_handle_t * pamh, const char *name } } } else { - retval = verify_pwd_hash(p, salt, off(UNIX__NONULL, ctrl)); + retval = verify_pwd_hash(pamh, p, salt, off(UNIX__NONULL, ctrl)); } if (retval == PAM_SUCCESS) { @@ -843,6 +799,7 @@ int _unix_verify_password(pam_handle_t * pamh, const char *name } cleanup: + memset(pw, 0, sizeof(pw)); /* clear memory of the password */ if (data_name) _pam_delete(data_name); if (salt) @@ -853,8 +810,45 @@ cleanup: return retval; } +int +_unix_verify_user(pam_handle_t *pamh, + unsigned long long ctrl, + const char *name, + int *daysleft) +{ + int retval; + struct spwd *spent; + struct passwd *pwent; + + retval = get_account_info(pamh, name, &pwent, &spent); + if (retval == PAM_USER_UNKNOWN) { + pam_syslog(pamh, LOG_ERR, + "could not identify user (from getpwnam(%s))", + name); + return retval; + } + + if (retval == PAM_SUCCESS && spent == NULL) + return PAM_SUCCESS; + + if (retval == PAM_UNIX_RUN_HELPER) { + retval = _unix_run_verify_binary(pamh, ctrl, name, daysleft); + if (retval == PAM_AUTHINFO_UNAVAIL && + on(UNIX_BROKEN_SHADOW, ctrl)) + return PAM_SUCCESS; + } else if (retval != PAM_SUCCESS) { + if (on(UNIX_BROKEN_SHADOW,ctrl)) + return PAM_SUCCESS; + else + return retval; + } else + retval = check_shadow_expiry(pamh, spent, daysleft); + + return retval; +} + /* ****************************************************************** * - * Copyright (c) Jan Rêkorajski 1999. + * Copyright (c) Jan RÄ™korajski 1999. * Copyright (c) Andrew G. Morgan 1996-8. * Copyright (c) Alex O. Yuriev, 1996. * Copyright (c) Cristian Gafton 1996. diff --git a/modules/pam_unix/support.h b/modules/pam_unix/support.h index b4c279c3..19754dc1 100644 --- a/modules/pam_unix/support.h +++ b/modules/pam_unix/support.h @@ -22,8 +22,8 @@ typedef struct { const char *token; - unsigned int mask; /* shall assume 32 bits of flags */ - unsigned int flag; + unsigned long long mask; /* shall assume 64 bits of flags */ + unsigned long long flag; unsigned int is_hash_algo; } UNIX_Ctrls; @@ -48,7 +48,7 @@ typedef struct { /* the generic mask */ -#define _ALL_ON_ (~0U) +#define _ALL_ON_ (~0ULL) /* end of macro definitions definitions for the control flags */ @@ -98,47 +98,53 @@ typedef struct { #define UNIX_QUIET 28 /* Don't print informational messages */ #define UNIX_NO_PASS_EXPIRY 29 /* Don't check for password expiration if not used for authentication */ #define UNIX_DES 30 /* DES, default */ +#define UNIX_GOST_YESCRYPT_PASS 31 /* new password hashes will use gost-yescrypt */ +#define UNIX_YESCRYPT_PASS 32 /* new password hashes will use yescrypt */ +#define UNIX_NULLRESETOK 33 /* allow empty password if password reset is enforced */ /* -------------- */ -#define UNIX_CTRLS_ 31 /* number of ctrl arguments defined */ +#define UNIX_CTRLS_ 34 /* number of ctrl arguments defined */ -#define UNIX_DES_CRYPT(ctrl) (off(UNIX_MD5_PASS,ctrl)&&off(UNIX_BIGCRYPT,ctrl)&&off(UNIX_SHA256_PASS,ctrl)&&off(UNIX_SHA512_PASS,ctrl)&&off(UNIX_BLOWFISH_PASS,ctrl)) +#define UNIX_DES_CRYPT(ctrl) (off(UNIX_MD5_PASS,ctrl)&&off(UNIX_BIGCRYPT,ctrl)&&off(UNIX_SHA256_PASS,ctrl)&&off(UNIX_SHA512_PASS,ctrl)&&off(UNIX_BLOWFISH_PASS,ctrl)&&off(UNIX_GOST_YESCRYPT_PASS,ctrl)&&off(UNIX_YESCRYPT_PASS,ctrl)) static const UNIX_Ctrls unix_args[UNIX_CTRLS_] = { -/* symbol token name ctrl mask ctrl * - * ----------------------- ------------------- --------------------- -------- */ - -/* UNIX__OLD_PASSWD */ {NULL, _ALL_ON_, 01, 0}, -/* UNIX__VERIFY_PASSWD */ {NULL, _ALL_ON_, 02, 0}, -/* UNIX__IAMROOT */ {NULL, _ALL_ON_, 04, 0}, -/* UNIX_AUDIT */ {"audit", _ALL_ON_, 010, 0}, -/* UNIX_USE_FIRST_PASS */ {"use_first_pass", _ALL_ON_^(060), 020, 0}, -/* UNIX_TRY_FIRST_PASS */ {"try_first_pass", _ALL_ON_^(060), 040, 0}, -/* UNIX_AUTHTOK_TYPE */ {"authtok_type=", _ALL_ON_, 0100, 0}, -/* UNIX__PRELIM */ {NULL, _ALL_ON_^(0600), 0200, 0}, -/* UNIX__UPDATE */ {NULL, _ALL_ON_^(0600), 0400, 0}, -/* UNIX__NONULL */ {NULL, _ALL_ON_, 01000, 0}, -/* UNIX__QUIET */ {NULL, _ALL_ON_, 02000, 0}, -/* UNIX_USE_AUTHTOK */ {"use_authtok", _ALL_ON_, 04000, 0}, -/* UNIX_SHADOW */ {"shadow", _ALL_ON_, 010000, 0}, -/* UNIX_MD5_PASS */ {"md5", _ALL_ON_^(0260420000), 020000, 1}, -/* UNIX__NULLOK */ {"nullok", _ALL_ON_^(01000), 0, 0}, -/* UNIX_DEBUG */ {"debug", _ALL_ON_, 040000, 0}, -/* UNIX_NODELAY */ {"nodelay", _ALL_ON_, 0100000, 0}, -/* UNIX_NIS */ {"nis", _ALL_ON_, 0200000, 0}, -/* UNIX_BIGCRYPT */ {"bigcrypt", _ALL_ON_^(0260420000), 0400000, 1}, -/* UNIX_LIKE_AUTH */ {"likeauth", _ALL_ON_, 01000000, 0}, -/* UNIX_REMEMBER_PASSWD */ {"remember=", _ALL_ON_, 02000000, 0}, -/* UNIX_NOREAP */ {"noreap", _ALL_ON_, 04000000, 0}, -/* UNIX_BROKEN_SHADOW */ {"broken_shadow", _ALL_ON_, 010000000, 0}, -/* UNIX_SHA256_PASS */ {"sha256", _ALL_ON_^(0260420000), 020000000, 1}, -/* UNIX_SHA512_PASS */ {"sha512", _ALL_ON_^(0260420000), 040000000, 1}, -/* UNIX_ALGO_ROUNDS */ {"rounds=", _ALL_ON_, 0100000000, 0}, -/* UNIX_BLOWFISH_PASS */ {"blowfish", _ALL_ON_^(0260420000), 0200000000, 1}, -/* UNIX_MIN_PASS_LEN */ {"minlen=", _ALL_ON_, 0400000000, 0}, -/* UNIX_QUIET */ {"quiet", _ALL_ON_, 01000000000, 0}, -/* UNIX_NO_PASS_EXPIRY */ {"no_pass_expiry", _ALL_ON_, 02000000000, 0}, -/* UNIX_DES */ {"des", _ALL_ON_^(0260420000), 0, 1}, +/* symbol token name ctrl mask ctrl * + * --------------------------- -------------------- ------------------------- ---------------- */ + +/* UNIX__OLD_PASSWD */ {NULL, _ALL_ON_, 01, 0}, +/* UNIX__VERIFY_PASSWD */ {NULL, _ALL_ON_, 02, 0}, +/* UNIX__IAMROOT */ {NULL, _ALL_ON_, 04, 0}, +/* UNIX_AUDIT */ {"audit", _ALL_ON_, 010, 0}, +/* UNIX_USE_FIRST_PASS */ {"use_first_pass", _ALL_ON_^(060ULL), 020, 0}, +/* UNIX_TRY_FIRST_PASS */ {"try_first_pass", _ALL_ON_^(060ULL), 040, 0}, +/* UNIX_AUTHTOK_TYPE */ {"authtok_type=", _ALL_ON_, 0100, 0}, +/* UNIX__PRELIM */ {NULL, _ALL_ON_^(0600ULL), 0200, 0}, +/* UNIX__UPDATE */ {NULL, _ALL_ON_^(0600ULL), 0400, 0}, +/* UNIX__NONULL */ {NULL, _ALL_ON_, 01000, 0}, +/* UNIX__QUIET */ {NULL, _ALL_ON_, 02000, 0}, +/* UNIX_USE_AUTHTOK */ {"use_authtok", _ALL_ON_, 04000, 0}, +/* UNIX_SHADOW */ {"shadow", _ALL_ON_, 010000, 0}, +/* UNIX_MD5_PASS */ {"md5", _ALL_ON_^(015660420000ULL), 020000, 1}, +/* UNIX__NULLOK */ {"nullok", _ALL_ON_^(01000ULL), 0, 0}, +/* UNIX_DEBUG */ {"debug", _ALL_ON_, 040000, 0}, +/* UNIX_NODELAY */ {"nodelay", _ALL_ON_, 0100000, 0}, +/* UNIX_NIS */ {"nis", _ALL_ON_, 0200000, 0}, +/* UNIX_BIGCRYPT */ {"bigcrypt", _ALL_ON_^(015660420000ULL), 0400000, 1}, +/* UNIX_LIKE_AUTH */ {"likeauth", _ALL_ON_, 01000000, 0}, +/* UNIX_REMEMBER_PASSWD */ {"remember=", _ALL_ON_, 02000000, 0}, +/* UNIX_NOREAP */ {"noreap", _ALL_ON_, 04000000, 0}, +/* UNIX_BROKEN_SHADOW */ {"broken_shadow", _ALL_ON_, 010000000, 0}, +/* UNIX_SHA256_PASS */ {"sha256", _ALL_ON_^(015660420000ULL), 020000000, 1}, +/* UNIX_SHA512_PASS */ {"sha512", _ALL_ON_^(015660420000ULL), 040000000, 1}, +/* UNIX_ALGO_ROUNDS */ {"rounds=", _ALL_ON_, 0100000000, 0}, +/* UNIX_BLOWFISH_PASS */ {"blowfish", _ALL_ON_^(015660420000ULL), 0200000000, 1}, +/* UNIX_MIN_PASS_LEN */ {"minlen=", _ALL_ON_, 0400000000, 0}, +/* UNIX_QUIET */ {"quiet", _ALL_ON_, 01000000000, 0}, +/* UNIX_NO_PASS_EXPIRY */ {"no_pass_expiry", _ALL_ON_, 02000000000, 0}, +/* UNIX_DES */ {"des", _ALL_ON_^(015660420000ULL), 0, 1}, +/* UNIX_GOST_YESCRYPT_PASS */ {"gost_yescrypt", _ALL_ON_^(015660420000ULL), 04000000000, 1}, +/* UNIX_YESCRYPT_PASS */ {"yescrypt", _ALL_ON_^(015660420000ULL), 010000000000, 1}, +/* UNIX_NULLRESETOK */ {"nullresetok", _ALL_ON_, 020000000000, 0}, }; #define UNIX_DEFAULTS (unix_args[UNIX__NONULL].flag) @@ -151,27 +157,26 @@ static const UNIX_Ctrls unix_args[UNIX_CTRLS_] = _pam_drop(xx); \ } -extern int _make_remark(pam_handle_t * pamh, unsigned int ctrl - ,int type, const char *text); -extern int _set_ctrl(pam_handle_t * pamh, int flags, int *remember, int *rounds, - int *pass_min_len, int argc, const char **argv); +extern int _make_remark(pam_handle_t * pamh, unsigned long long ctrl, + int type, const char *text); +extern unsigned long long _set_ctrl(pam_handle_t * pamh, int flags, + int *remember, int *rounds, + int *pass_min_len, + int argc, const char **argv); extern int _unix_getpwnam (pam_handle_t *pamh, const char *name, int files, int nis, struct passwd **ret); extern int _unix_comesfromsource (pam_handle_t *pamh, const char *name, int files, int nis); -extern int _unix_blankpasswd(pam_handle_t *pamh,unsigned int ctrl, +extern int _unix_blankpasswd(pam_handle_t *pamh, unsigned long long ctrl, const char *name); -extern int _unix_verify_password(pam_handle_t * pamh, const char *name - ,const char *p, unsigned int ctrl); -extern int _unix_read_password(pam_handle_t * pamh - ,unsigned int ctrl - ,const char *comment - ,const char *prompt1 - ,const char *prompt2 - ,const char *data_name - ,const void **pass); +extern int _unix_verify_password(pam_handle_t * pamh, const char *name, + const char *p, unsigned long long ctrl); + +extern int _unix_verify_user(pam_handle_t *pamh, unsigned long long ctrl, + const char *name, int *daysleft); extern int _unix_run_verify_binary(pam_handle_t *pamh, - unsigned int ctrl, const char *user, int *daysleft); + unsigned long long ctrl, + const char *user, int *daysleft); #endif /* _PAM_UNIX_SUPPORT_H */ diff --git a/modules/pam_unix/unix_chkpwd.8 b/modules/pam_unix/unix_chkpwd.8 index 46048995..e5d40ad3 100644 --- a/modules/pam_unix/unix_chkpwd.8 +++ b/modules/pam_unix/unix_chkpwd.8 @@ -1,13 +1,13 @@ '\" t .\" Title: unix_chkpwd .\" Author: [see the "AUTHOR" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/> -.\" Date: 05/18/2017 +.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/> +.\" Date: 06/08/2020 .\" Manual: Linux-PAM Manual .\" Source: Linux-PAM Manual .\" Language: English .\" -.TH "UNIX_CHKPWD" "8" "05/18/2017" "Linux-PAM Manual" "Linux\-PAM Manual" +.TH "UNIX_CHKPWD" "8" "06/08/2020" "Linux-PAM Manual" "Linux\-PAM Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/modules/pam_unix/unix_chkpwd.c b/modules/pam_unix/unix_chkpwd.c index 39c84dbf..88647e58 100644 --- a/modules/pam_unix/unix_chkpwd.c +++ b/modules/pam_unix/unix_chkpwd.c @@ -2,7 +2,7 @@ * This program is designed to run setuid(root) or with sufficient * privilege to read all of the unix password databases. It is designed * to provide a mechanism for the current user (defined by this - * process' uid) to verify their own password. + * process's uid) to verify their own password. * * The password is read from the standard input. The exit status of * this program indicates whether the user is authenticated or not. @@ -188,7 +188,14 @@ int main(int argc, char *argv[]) #endif helper_log_err(LOG_NOTICE, "password check failed for user (%s)", user); } - return PAM_AUTH_ERR; + /* if helper_verify_password() returned PAM_USER_UNKNOWN, the + most appropriate error to propagate to + _unix_verify_password() is PAM_AUTHINFO_UNAVAIL; otherwise + return general failure */ + if (retval == PAM_USER_UNKNOWN) + return PAM_AUTHINFO_UNAVAIL; + else + return PAM_AUTH_ERR; } else { if (getuid() != 0) { #ifdef HAVE_LIBAUDIT diff --git a/modules/pam_unix/unix_update.8 b/modules/pam_unix/unix_update.8 index c5eab08c..4a7a3d1b 100644 --- a/modules/pam_unix/unix_update.8 +++ b/modules/pam_unix/unix_update.8 @@ -1,13 +1,13 @@ '\" t .\" Title: unix_update .\" Author: [see the "AUTHOR" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/> -.\" Date: 05/18/2017 +.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/> +.\" Date: 06/08/2020 .\" Manual: Linux-PAM Manual .\" Source: Linux-PAM Manual .\" Language: English .\" -.TH "UNIX_UPDATE" "8" "05/18/2017" "Linux-PAM Manual" "Linux\-PAM Manual" +.TH "UNIX_UPDATE" "8" "06/08/2020" "Linux-PAM Manual" "Linux\-PAM Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- |