diff options
Diffstat (limited to 'modules/pam_unix')
25 files changed, 440 insertions, 460 deletions
diff --git a/modules/pam_unix/Makefile.am b/modules/pam_unix/Makefile.am index 6463872a..a1dfe44e 100644 --- a/modules/pam_unix/Makefile.am +++ b/modules/pam_unix/Makefile.am @@ -5,7 +5,7 @@ CLEANFILES = *~ MAINTAINERCLEANFILES = $(MANS) README -EXTRA_DIST = md5.c md5_crypt.c lckpwdf.-c $(XMLS) CHANGELOG +EXTRA_DIST = md5.c md5_crypt.c lckpwdf.-c yppasswd_xdr.c $(XMLS) CHANGELOG if HAVE_DOC dist_man_MANS = pam_unix.8 unix_chkpwd.8 unix_update.8 @@ -15,7 +15,11 @@ dist_check_SCRIPTS = tst-pam_unix TESTS = $(dist_check_SCRIPTS) securelibdir = $(SECUREDIR) +if HAVE_VENDORDIR +secureconfdir = $(VENDOR_SCONFIGDIR) +else secureconfdir = $(SCONFIGDIR) +endif AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \ -DCHKPWD_HELPER=\"$(sbindir)/unix_chkpwd\" \ @@ -39,7 +43,10 @@ noinst_PROGRAMS = bigcrypt pam_unix_la_SOURCES = bigcrypt.c pam_unix_acct.c \ pam_unix_auth.c pam_unix_passwd.c pam_unix_sess.c support.c \ - passverify.c yppasswd_xdr.c md5_good.c md5_broken.c + passverify.c md5_good.c md5_broken.c +if HAVE_NIS + pam_unix_la_SOURCES += yppasswd_xdr.c +endif bigcrypt_SOURCES = bigcrypt.c bigcrypt_main.c bigcrypt_CFLAGS = $(AM_CFLAGS) @@ -47,14 +54,14 @@ bigcrypt_LDADD = @LIBCRYPT@ unix_chkpwd_SOURCES = unix_chkpwd.c md5_good.c md5_broken.c bigcrypt.c \ passverify.c -unix_chkpwd_CFLAGS = $(AM_CFLAGS) @PIE_CFLAGS@ -DHELPER_COMPILE=\"unix_chkpwd\" -unix_chkpwd_LDFLAGS = @PIE_LDFLAGS@ +unix_chkpwd_CFLAGS = $(AM_CFLAGS) @EXE_CFLAGS@ -DHELPER_COMPILE=\"unix_chkpwd\" +unix_chkpwd_LDFLAGS = @EXE_LDFLAGS@ unix_chkpwd_LDADD = @LIBCRYPT@ @LIBSELINUX@ @LIBAUDIT@ unix_update_SOURCES = unix_update.c md5_good.c md5_broken.c bigcrypt.c \ passverify.c -unix_update_CFLAGS = $(AM_CFLAGS) @PIE_CFLAGS@ -DHELPER_COMPILE=\"unix_update\" -unix_update_LDFLAGS = @PIE_LDFLAGS@ +unix_update_CFLAGS = $(AM_CFLAGS) @EXE_CFLAGS@ -DHELPER_COMPILE=\"unix_update\" +unix_update_LDFLAGS = @EXE_LDFLAGS@ unix_update_LDADD = @LIBCRYPT@ @LIBSELINUX@ if ENABLE_REGENERATE_MAN diff --git a/modules/pam_unix/Makefile.in b/modules/pam_unix/Makefile.in index bfc1a252..1de5b72b 100644 --- a/modules/pam_unix/Makefile.in +++ b/modules/pam_unix/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -98,20 +98,24 @@ host_triplet = @host@ @HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map sbin_PROGRAMS = unix_chkpwd$(EXEEXT) unix_update$(EXEEXT) noinst_PROGRAMS = bigcrypt$(EXEEXT) +@HAVE_NIS_TRUE@am__append_2 = yppasswd_xdr.c subdir = modules/pam_unix ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/gettext.m4 \ - $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \ - $(top_srcdir)/m4/japhar_grep_cflags.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \ + $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/intlmacosx.m4 \ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \ - $(top_srcdir)/m4/ld-no-undefined.m4 $(top_srcdir)/m4/lib-ld.m4 \ + $(top_srcdir)/m4/ld-no-undefined.m4 \ + $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \ - $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/configure.ac + $(top_srcdir)/m4/progtest.m4 \ + $(top_srcdir)/m4/warn_lang_flags.m4 \ + $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \ @@ -153,9 +157,13 @@ am__uninstall_files_from_dir = { \ } LTLIBRARIES = $(securelib_LTLIBRARIES) pam_unix_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la +am__pam_unix_la_SOURCES_DIST = bigcrypt.c pam_unix_acct.c \ + pam_unix_auth.c pam_unix_passwd.c pam_unix_sess.c support.c \ + passverify.c md5_good.c md5_broken.c yppasswd_xdr.c +@HAVE_NIS_TRUE@am__objects_1 = yppasswd_xdr.lo am_pam_unix_la_OBJECTS = bigcrypt.lo pam_unix_acct.lo pam_unix_auth.lo \ pam_unix_passwd.lo pam_unix_sess.lo support.lo passverify.lo \ - yppasswd_xdr.lo md5_good.lo md5_broken.lo + md5_good.lo md5_broken.lo $(am__objects_1) pam_unix_la_OBJECTS = $(am_pam_unix_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -244,7 +252,7 @@ am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(pam_unix_la_SOURCES) $(bigcrypt_SOURCES) \ $(unix_chkpwd_SOURCES) $(unix_update_SOURCES) -DIST_SOURCES = $(pam_unix_la_SOURCES) $(bigcrypt_SOURCES) \ +DIST_SOURCES = $(am__pam_unix_la_SOURCES_DIST) $(bigcrypt_SOURCES) \ $(unix_chkpwd_SOURCES) $(unix_update_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ @@ -431,6 +439,7 @@ am__set_TESTS_bases = \ bases='$(TEST_LOGS)'; \ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ bases=`echo $$bases` +AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)' RECHECK_LOGS = $(TEST_LOGS) AM_RECURSIVE_TARGETS = check recheck TEST_SUITE_LOG = test-suite.log @@ -475,10 +484,14 @@ CC_FOR_BUILD = @CC_FOR_BUILD@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ +CRYPTO_LIBS = @CRYPTO_LIBS@ +CRYPT_CFLAGS = @CRYPT_CFLAGS@ +CRYPT_LIBS = @CRYPT_LIBS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ +DOCBOOK_RNG = @DOCBOOK_RNG@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ @@ -488,12 +501,16 @@ ECONF_CFLAGS = @ECONF_CFLAGS@ ECONF_LIBS = @ECONF_LIBS@ EGREP = @EGREP@ 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@ @@ -507,7 +524,6 @@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAUDIT = @LIBAUDIT@ -LIBCRACK = @LIBCRACK@ LIBCRYPT = @LIBCRYPT@ LIBDB = @LIBDB@ LIBDL = @LIBDL@ @@ -526,12 +542,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@ @@ -554,8 +572,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ -PIE_CFLAGS = @PIE_CFLAGS@ -PIE_LDFLAGS = @PIE_LDFLAGS@ +PDF_STYLESHEET = @PDF_STYLESHEET@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -566,11 +583,16 @@ SECUREDIR = @SECUREDIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ +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@ @@ -615,7 +637,6 @@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ -libc_cv_fpie = @libc_cv_fpie@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ @@ -623,9 +644,6 @@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ -pam_cv_ld_O1 = @pam_cv_ld_O1@ -pam_cv_ld_as_needed = @pam_cv_ld_as_needed@ -pam_cv_ld_no_undefined = @pam_cv_ld_no_undefined@ pam_xauth_path = @pam_xauth_path@ pdfdir = @pdfdir@ prefix = @prefix@ @@ -635,19 +653,21 @@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ +systemdunitdir = @systemdunitdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ CLEANFILES = *~ MAINTAINERCLEANFILES = $(MANS) README -EXTRA_DIST = md5.c md5_crypt.c lckpwdf.-c $(XMLS) CHANGELOG +EXTRA_DIST = md5.c md5_crypt.c lckpwdf.-c yppasswd_xdr.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 dist_check_SCRIPTS = tst-pam_unix TESTS = $(dist_check_SCRIPTS) 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 \ -DCHKPWD_HELPER=\"$(sbindir)/unix_chkpwd\" \ -DUPDATE_HELPER=\"$(sbindir)/unix_update\" \ @@ -660,24 +680,23 @@ pam_unix_la_LIBADD = $(top_builddir)/libpam/libpam.la \ securelib_LTLIBRARIES = pam_unix.la noinst_HEADERS = md5.h support.h yppasswd.h bigcrypt.h passverify.h -pam_unix_la_SOURCES = bigcrypt.c pam_unix_acct.c \ - pam_unix_auth.c pam_unix_passwd.c pam_unix_sess.c support.c \ - passverify.c yppasswd_xdr.c md5_good.c md5_broken.c - +pam_unix_la_SOURCES = bigcrypt.c pam_unix_acct.c pam_unix_auth.c \ + pam_unix_passwd.c pam_unix_sess.c support.c passverify.c \ + md5_good.c md5_broken.c $(am__append_2) bigcrypt_SOURCES = bigcrypt.c bigcrypt_main.c bigcrypt_CFLAGS = $(AM_CFLAGS) bigcrypt_LDADD = @LIBCRYPT@ unix_chkpwd_SOURCES = unix_chkpwd.c md5_good.c md5_broken.c bigcrypt.c \ passverify.c -unix_chkpwd_CFLAGS = $(AM_CFLAGS) @PIE_CFLAGS@ -DHELPER_COMPILE=\"unix_chkpwd\" -unix_chkpwd_LDFLAGS = @PIE_LDFLAGS@ +unix_chkpwd_CFLAGS = $(AM_CFLAGS) @EXE_CFLAGS@ -DHELPER_COMPILE=\"unix_chkpwd\" +unix_chkpwd_LDFLAGS = @EXE_LDFLAGS@ unix_chkpwd_LDADD = @LIBCRYPT@ @LIBSELINUX@ @LIBAUDIT@ unix_update_SOURCES = unix_update.c md5_good.c md5_broken.c bigcrypt.c \ passverify.c -unix_update_CFLAGS = $(AM_CFLAGS) @PIE_CFLAGS@ -DHELPER_COMPILE=\"unix_update\" -unix_update_LDFLAGS = @PIE_LDFLAGS@ +unix_update_CFLAGS = $(AM_CFLAGS) @EXE_CFLAGS@ -DHELPER_COMPILE=\"unix_update\" +unix_update_LDFLAGS = @EXE_LDFLAGS@ unix_update_LDADD = @LIBCRYPT@ @LIBSELINUX@ @ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README all: all-am @@ -1254,7 +1273,7 @@ $(TEST_SUITE_LOG): $(TEST_LOGS) test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ fi; \ echo "$${col}$$br$${std}"; \ - echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ + echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \ echo "$${col}$$br$${std}"; \ create_testsuite_report --maybe-color; \ echo "$$col$$br$$std"; \ diff --git a/modules/pam_unix/README b/modules/pam_unix/README index a87f34a5..67a2d215 100644 --- a/modules/pam_unix/README +++ b/modules/pam_unix/README @@ -99,7 +99,7 @@ use_authtok When password changing enforce the module to set the new password to the one provided by a previously stacked password module (this is used in the - example of the stacking of the pam_cracklib module documented below). + example of the stacking of the pam_passwdqc module documented below). authtok_type=type @@ -194,8 +194,8 @@ auth required pam_unix.so # Ensure users account and password are still active 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 +# with pam_passwdqc(8) +password required pam_passwdqc.so config=/etc/passwdqc.conf password required pam_unix.so use_authtok nullok yescrypt session required pam_unix.so diff --git a/modules/pam_unix/README.xml b/modules/pam_unix/README.xml index 7fd340b3..49a65946 100644 --- a/modules/pam_unix/README.xml +++ b/modules/pam_unix/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_unix.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_unix.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_unix-name"]/*)'/> + <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_unix.8.xml" xpointer='xpointer(id("pam_unix-name")/*)'/> </title> - </articleinfo> + </info> <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_unix.8.xml" xpointer='xpointer(//refsect1[@id = "pam_unix-description"]/*)'/> + <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_unix.8.xml" xpointer='xpointer(id("pam_unix-description")/*)'/> </section> <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_unix.8.xml" xpointer='xpointer(//refsect1[@id = "pam_unix-options"]/*)'/> + <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_unix.8.xml" xpointer='xpointer(id("pam_unix-options")/*)'/> </section> <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_unix.8.xml" xpointer='xpointer(//refsect1[@id = "pam_unix-examples"]/*)'/> + <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_unix.8.xml" xpointer='xpointer(id("pam_unix-examples")/*)'/> </section> <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_unix.8.xml" xpointer='xpointer(//refsect1[@id = "pam_unix-author"]/*)'/> + <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_unix.8.xml" xpointer='xpointer(id("pam_unix-author")/*)'/> </section> -</article> +</article>
\ No newline at end of file diff --git a/modules/pam_unix/bigcrypt.c b/modules/pam_unix/bigcrypt.c index e08e4098..c1028668 100644 --- a/modules/pam_unix/bigcrypt.c +++ b/modules/pam_unix/bigcrypt.c @@ -29,9 +29,8 @@ #include <string.h> #include <stdlib.h> #include <security/_pam_macros.h> -#ifdef HAVE_LIBXCRYPT -#include <xcrypt.h> -#elif defined(HAVE_CRYPT_H) +#include "pam_inline.h" +#ifdef HAVE_CRYPT_H #include <crypt.h> #endif @@ -58,12 +57,12 @@ char *bigcrypt(const char *key, const char *salt) #endif unsigned long int keylen, n_seg, j; char *cipher_ptr, *plaintext_ptr, *tmp_ptr, *salt_ptr; - char keybuf[KEYBUF_SIZE + 1]; + char keybuf[KEYBUF_SIZE + 1] = {}; D(("called with key='%s', salt='%s'.", key, salt)); /* reset arrays */ - dec_c2_cryptbuf = malloc(CBUF_SIZE); + dec_c2_cryptbuf = calloc(1, CBUF_SIZE); if (!dec_c2_cryptbuf) { return NULL; } @@ -75,8 +74,6 @@ char *bigcrypt(const char *key, const char *salt) } cdata->initialized = 0; #endif - memset(keybuf, 0, KEYBUF_SIZE + 1); - memset(dec_c2_cryptbuf, 0, CBUF_SIZE); /* fill KEYBUF_SIZE with key */ strncpy(keybuf, key, KEYBUF_SIZE); @@ -111,10 +108,14 @@ char *bigcrypt(const char *key, const char *salt) #endif if (tmp_ptr == NULL) { free(dec_c2_cryptbuf); +#ifdef HAVE_CRYPT_R + free(cdata); +#endif return NULL; } /* and place in the static area */ strncpy(cipher_ptr, tmp_ptr, 13); + pam_overwrite_string(tmp_ptr); cipher_ptr += ESEGMENT_SIZE + SALT_SIZE; plaintext_ptr += SEGMENT_SIZE; /* first block of SEGMENT_SIZE */ @@ -135,13 +136,18 @@ char *bigcrypt(const char *key, const char *salt) tmp_ptr = crypt(plaintext_ptr, salt_ptr); #endif if (tmp_ptr == NULL) { - _pam_overwrite(dec_c2_cryptbuf); + pam_overwrite_string(dec_c2_cryptbuf); free(dec_c2_cryptbuf); +#ifdef HAVE_CRYPT_R + pam_overwrite_object(cdata); + free(cdata); +#endif return NULL; } /* skip the salt for seg!=0 */ strncpy(cipher_ptr, (tmp_ptr + SALT_SIZE), ESEGMENT_SIZE); + pam_overwrite_string(tmp_ptr); cipher_ptr += ESEGMENT_SIZE; plaintext_ptr += SEGMENT_SIZE; @@ -151,6 +157,7 @@ char *bigcrypt(const char *key, const char *salt) D(("key=|%s|, salt=|%s|\nbuf=|%s|\n", key, salt, dec_c2_cryptbuf)); #ifdef HAVE_CRYPT_R + pam_overwrite_object(cdata); free(cdata); #endif diff --git a/modules/pam_unix/lckpwdf.-c b/modules/pam_unix/lckpwdf.-c index 7145617e..c3e63155 100644 --- a/modules/pam_unix/lckpwdf.-c +++ b/modules/pam_unix/lckpwdf.-c @@ -73,17 +73,17 @@ static int lckpwdf(void) lockfd = open(LOCKFILE, O_WRONLY); if(lockfd == -1 && errno == ENOENT) { - security_context_t create_context; + char *create_context_raw; int rc; - if(getfilecon("/etc/passwd", &create_context)) + if(getfilecon_raw("/etc/passwd", &create_context_raw)) return -1; - rc = setfscreatecon(create_context); - freecon(create_context); + rc = setfscreatecon_raw(create_context_raw); + freecon(create_context_raw); if(rc) return -1; lockfd = open(LOCKFILE, O_CREAT | O_WRONLY, 0600); - if(setfscreatecon(NULL)) + if(setfscreatecon_raw(NULL)) return -1; } } diff --git a/modules/pam_unix/md5.c b/modules/pam_unix/md5.c index 9954536f..95b8de4c 100644 --- a/modules/pam_unix/md5.c +++ b/modules/pam_unix/md5.c @@ -21,26 +21,27 @@ #include <string.h> #include "md5.h" +#include "pam_inline.h" + #ifndef HIGHFIRST #define byteReverse(buf, len) /* Nothing */ #else -typedef unsigned char PAM_ATTRIBUTE_ALIGNED(4) uint8_aligned; - -static void byteReverse(uint8_aligned *buf, unsigned longs); +static void byteReverse(uint32 *buf, unsigned longs); #ifndef ASM_MD5 /* * Note: this code is harmless on little-endian machines. */ -static void byteReverse(uint8_aligned *buf, unsigned longs) +static void byteReverse(uint32 *buf, unsigned longs) { uint32 t; do { - t = (uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 | - ((unsigned) buf[1] << 8 | buf[0]); - *(uint32 *) buf = t; - buf += 4; + unsigned char *p = (unsigned char *) buf; + t = (uint32) ((unsigned) p[3] << 8 | p[2]) << 16 | + ((unsigned) p[1] << 8 | p[0]); + *buf = t; + ++buf; } while (--longs); } #endif @@ -52,10 +53,10 @@ static void byteReverse(uint8_aligned *buf, unsigned longs) */ void MD5Name(MD5Init)(struct MD5Context *ctx) { - ctx->buf[0] = 0x67452301U; - ctx->buf[1] = 0xefcdab89U; - ctx->buf[2] = 0x98badcfeU; - ctx->buf[3] = 0x10325476U; + ctx->buf.i[0] = 0x67452301U; + ctx->buf.i[1] = 0xefcdab89U; + ctx->buf.i[2] = 0x98badcfeU; + ctx->buf.i[3] = 0x10325476U; ctx->bits[0] = 0; ctx->bits[1] = 0; @@ -81,7 +82,7 @@ void MD5Name(MD5Update)(struct MD5Context *ctx, unsigned const char *buf, unsign /* Handle any leading odd-sized chunks */ if (t) { - unsigned char *p = (unsigned char *) ctx->in + t; + unsigned char *p = ctx->in.c + t; t = 64 - t; if (len < t) { @@ -89,24 +90,24 @@ void MD5Name(MD5Update)(struct MD5Context *ctx, unsigned const char *buf, unsign return; } memcpy(p, buf, t); - byteReverse(ctx->in, 16); - MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in); + byteReverse(ctx->in.i, 16); + MD5Name(MD5Transform)(ctx->buf.i, ctx->in.i); buf += t; len -= t; } /* Process data in 64-byte chunks */ while (len >= 64) { - memcpy(ctx->in, buf, 64); - byteReverse(ctx->in, 16); - MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in); + memcpy(ctx->in.c, buf, 64); + byteReverse(ctx->in.i, 16); + MD5Name(MD5Transform)(ctx->buf.i, ctx->in.i); buf += 64; len -= 64; } /* Handle any remaining bytes of data. */ - memcpy(ctx->in, buf, len); + memcpy(ctx->in.c, buf, len); } /* @@ -123,7 +124,7 @@ void MD5Name(MD5Final)(unsigned char digest[16], struct MD5Context *ctx) /* Set the first char of padding to 0x80. This is safe since there is always at least one byte free */ - p = ctx->in + count; + p = ctx->in.c + count; *p++ = 0x80; /* Bytes of padding needed to make 64 bytes */ @@ -133,24 +134,24 @@ void MD5Name(MD5Final)(unsigned char digest[16], struct MD5Context *ctx) if (count < 8) { /* Two lots of padding: Pad the first block to 64 bytes */ memset(p, 0, count); - byteReverse(ctx->in, 16); - MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in); + byteReverse(ctx->in.i, 16); + MD5Name(MD5Transform)(ctx->buf.i, ctx->in.i); /* Now fill the next block with 56 bytes */ - memset(ctx->in, 0, 56); + memset(ctx->in.c, 0, 56); } else { /* Pad block to 56 bytes */ memset(p, 0, count - 8); } - byteReverse(ctx->in, 14); + byteReverse(ctx->in.i, 14); /* Append length in bits and transform */ - memcpy((uint32 *)ctx->in + 14, ctx->bits, 2*sizeof(uint32)); + memcpy(ctx->in.i + 14, ctx->bits, 2*sizeof(uint32)); - MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in); - byteReverse((unsigned char *) ctx->buf, 4); - memcpy(digest, ctx->buf, 16); - memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */ + MD5Name(MD5Transform)(ctx->buf.i, ctx->in.i); + byteReverse(ctx->buf.i, 4); + memcpy(digest, ctx->buf.c, 16); + pam_overwrite_object(ctx); /* In case it's sensitive */ } #ifndef ASM_MD5 diff --git a/modules/pam_unix/md5.h b/modules/pam_unix/md5.h index d9186b7f..3dc54bd2 100644 --- a/modules/pam_unix/md5.h +++ b/modules/pam_unix/md5.h @@ -7,9 +7,15 @@ typedef unsigned int uint32; struct MD5Context { - uint32 buf[4]; + union { + uint32 i[4]; + unsigned char c[16] PAM_ATTRIBUTE_ALIGNED(4); + } buf; uint32 bits[2]; - unsigned char in[64] PAM_ATTRIBUTE_ALIGNED(4); + union { + uint32 i[16]; + unsigned char c[64] PAM_ATTRIBUTE_ALIGNED(4); + } in; }; void GoodMD5Init(struct MD5Context *); diff --git a/modules/pam_unix/md5_crypt.c b/modules/pam_unix/md5_crypt.c index 94f7b434..ed5ecda4 100644 --- a/modules/pam_unix/md5_crypt.c +++ b/modules/pam_unix/md5_crypt.c @@ -87,7 +87,7 @@ char *MD5Name(crypt_md5)(const char *pw, const char *salt) MD5Name(MD5Update)(&ctx,(unsigned const char *)final,pl>16 ? 16 : pl); /* Don't leave anything around in vm they could use. */ - memset(final, 0, sizeof final); + pam_overwrite_array(final); /* Then something really weird... */ for (j = 0, i = strlen(pw); i; i >>= 1) @@ -151,7 +151,7 @@ char *MD5Name(crypt_md5)(const char *pw, const char *salt) *p = '\0'; /* Don't leave anything around in vm they could use. */ - memset(final, 0, sizeof final); + pam_overwrite_array(final); return passwd; } diff --git a/modules/pam_unix/pam_unix.8 b/modules/pam_unix/pam_unix.8 index b396b66c..438717f9 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.79.1 <http://docbook.sf.net/> -.\" Date: 06/08/2020 +.\" 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_UNIX" "8" "06/08/2020" "Linux-PAM Manual" "Linux\-PAM Manual" +.TH "PAM_UNIX" "8" "05/07/2023" "Linux\-PAM" "Linux\-PAM Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -71,31 +71,31 @@ Remaining arguments, supported by others functions of this module, are silently \fBsyslog\fR(3)\&. .SH "OPTIONS" .PP -\fBdebug\fR +debug .RS 4 Turns on debugging via \fBsyslog\fR(3)\&. .RE .PP -\fBaudit\fR +audit .RS 4 A little more extreme than debug\&. .RE .PP -\fBquiet\fR +quiet .RS 4 Turns off informational messages namely messages about session open and close via \fBsyslog\fR(3)\&. .RE .PP -\fBnullok\fR +nullok .RS 4 The default action of this module is to not permit the user access to a service if their official password is blank\&. The \fBnullok\fR argument overrides this default\&. .RE .PP -\fBnullresetok\fR +nullresetok .RS 4 Allow users to authenticate with blank password if password reset is enforced even if \fBnullok\fR @@ -104,43 +104,43 @@ is not set\&. If password reset is not required and is not set the authentication with blank password will be denied\&. .RE .PP -\fBtry_first_pass\fR +try_first_pass .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\&. .RE .PP -\fBuse_first_pass\fR +use_first_pass .RS 4 The argument \fBuse_first_pass\fR forces the module to use a previous stacked modules password and will never prompt the user \- if no password is available or the password is not appropriate, the user will be denied access\&. .RE .PP -\fBnodelay\fR +nodelay .RS 4 This argument can be used to discourage the authentication component from requesting a delay should the authentication as a whole fail\&. The default action is for the module to request a delay\-on\-failure of the order of two second\&. .RE .PP -\fBuse_authtok\fR +use_authtok .RS 4 When password changing enforce the module to set the new password to the one provided by a previously stacked \fBpassword\fR module (this is used in the example of the stacking of the -\fBpam_cracklib\fR +\fBpam_passwdqc\fR module documented below)\&. .RE .PP -\fBauthtok_type=\fR\fB\fItype\fR\fR +authtok_type=type .RS 4 This argument can be used to modify the password prompt when changing passwords to include the type of the password\&. Empty by default\&. .RE .PP -\fBnis\fR +nis .RS 4 NIS RPC is used for setting new passwords\&. .RE .PP -\fBremember=\fR\fB\fIn\fR\fR +remember=n .RS 4 The last \fIn\fR @@ -151,75 +151,75 @@ in order to force password change history and keep the user from alternating bet module should be used\&. .RE .PP -\fBshadow\fR +shadow .RS 4 Try to maintain a shadow based system\&. .RE .PP -\fBmd5\fR +md5 .RS 4 When a user changes their password next, encrypt it with the MD5 algorithm\&. .RE .PP -\fBbigcrypt\fR +bigcrypt .RS 4 When a user changes their password next, encrypt it with the DEC C2 algorithm\&. .RE .PP -\fBsha256\fR +sha256 .RS 4 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\&. .RE .PP -\fBsha512\fR +sha512 .RS 4 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\&. .RE .PP -\fBblowfish\fR +blowfish .RS 4 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 +gost_yescrypt .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 +yescrypt .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\&. .RE .PP -\fBrounds=\fR\fB\fIn\fR\fR +rounds=n .RS 4 Set the optional number of rounds of the SHA256, SHA512, blowfish, gost\-yescrypt, and yescrypt password hashing algorithms to \fIn\fR\&. .RE .PP -\fBbroken_shadow\fR +broken_shadow .RS 4 Ignore errors reading shadow information for users in the account management module\&. .RE .PP -\fBminlen=\fR\fB\fIn\fR\fR +minlen=n .RS 4 Set a minimum password length of \fIn\fR characters\&. The max\&. for DES crypt based passwords are 8 characters\&. .RE .PP -\fBno_pass_expiry\fR +no_pass_expiry .RS 4 When set ignore password expiration as defined by the \fIshadow\fR @@ -264,8 +264,8 @@ auth required pam_unix\&.so # Ensure users account and password are still active 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 +# with pam_passwdqc(8) +password required pam_passwdqc\&.so config=/etc/passwdqc\&.conf password required pam_unix\&.so use_authtok nullok yescrypt session required pam_unix\&.so diff --git a/modules/pam_unix/pam_unix.8.xml b/modules/pam_unix/pam_unix.8.xml index fa02c3a6..dfc04274 100644 --- a/modules/pam_unix/pam_unix.8.xml +++ b/modules/pam_unix/pam_unix.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="pam_unix"> +<refentry xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="pam_unix"> <refmeta> <refentrytitle>pam_unix</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_unix-name"> + <refnamediv xml:id="pam_unix-name"> <refname>pam_unix</refname> <refpurpose>Module for traditional password authentication</refpurpose> </refnamediv> <refsynopsisdiv> - <cmdsynopsis id="pam_unix-cmdsynopsis"> + <cmdsynopsis xml:id="pam_unix-cmdsynopsis" sepchar=" "> <command>pam_unix.so</command> - <arg choice="opt"> + <arg choice="opt" rep="norepeat"> ... </arg> </cmdsynopsis> </refsynopsisdiv> - <refsect1 id="pam_unix-description"> + <refsect1 xml:id="pam_unix-description"> <title>DESCRIPTION</title> @@ -42,7 +39,7 @@ <emphasis>shadow</emphasis> elements: expire, last_change, max_change, min_change, warn_change. In the case of the latter, it may offer advice to the user on changing their password or, through the - <emphasis remap='B'>PAM_AUTHTOKEN_REQD</emphasis> return, delay + <emphasis remap="B">PAM_AUTHTOKEN_REQD</emphasis> return, delay giving service to the user until they have established a new password. The entries listed above are documented in the <citerefentry> <refentrytitle>shadow</refentrytitle><manvolnum>5</manvolnum> @@ -89,7 +86,7 @@ <para> The password component of this module performs the task of updating the user's password. The default encryption hash is taken from the - <emphasis remap='B'>ENCRYPT_METHOD</emphasis> variable from + <emphasis remap="B">ENCRYPT_METHOD</emphasis> variable from <emphasis>/etc/login.defs</emphasis> </para> @@ -107,13 +104,13 @@ </para> </refsect1> - <refsect1 id="pam_unix-options"> + <refsect1 xml:id="pam_unix-options"> <title>OPTIONS</title> <variablelist> <varlistentry> <term> - <option>debug</option> + debug </term> <listitem> <para> @@ -127,7 +124,7 @@ <varlistentry> <term> - <option>audit</option> + audit </term> <listitem> <para> @@ -138,7 +135,7 @@ <varlistentry> <term> - <option>quiet</option> + quiet </term> <listitem> <para> @@ -153,7 +150,7 @@ <varlistentry> <term> - <option>nullok</option> + nullok </term> <listitem> <para> @@ -165,7 +162,7 @@ </varlistentry> <varlistentry> <term> - <option>nullresetok</option> + nullresetok </term> <listitem> <para> @@ -178,7 +175,7 @@ </varlistentry> <varlistentry> <term> - <option>try_first_pass</option> + try_first_pass </term> <listitem> <para> @@ -190,7 +187,7 @@ </varlistentry> <varlistentry> <term> - <option>use_first_pass</option> + use_first_pass </term> <listitem> <para> @@ -203,7 +200,7 @@ </varlistentry> <varlistentry> <term> - <option>nodelay</option> + nodelay </term> <listitem> <para> @@ -216,21 +213,21 @@ </varlistentry> <varlistentry> <term> - <option>use_authtok</option> + use_authtok </term> <listitem> <para> When password changing enforce the module to set the new password to the one provided by a previously stacked <option>password</option> module (this is used in the - example of the stacking of the <command>pam_cracklib</command> + example of the stacking of the <command>pam_passwdqc</command> module documented below). </para> </listitem> </varlistentry> <varlistentry> <term> - <option>authtok_type=<replaceable>type</replaceable></option> + authtok_type=type </term> <listitem> <para> @@ -242,7 +239,7 @@ </varlistentry> <varlistentry> <term> - <option>nis</option> + nis </term> <listitem> <para> @@ -252,7 +249,7 @@ </varlistentry> <varlistentry> <term> - <option>remember=<replaceable>n</replaceable></option> + remember=n </term> <listitem> <para> @@ -269,7 +266,7 @@ </varlistentry> <varlistentry> <term> - <option>shadow</option> + shadow </term> <listitem> <para> @@ -279,7 +276,7 @@ </varlistentry> <varlistentry> <term> - <option>md5</option> + md5 </term> <listitem> <para> @@ -290,7 +287,7 @@ </varlistentry> <varlistentry> <term> - <option>bigcrypt</option> + bigcrypt </term> <listitem> <para> @@ -301,7 +298,7 @@ </varlistentry> <varlistentry> <term> - <option>sha256</option> + sha256 </term> <listitem> <para> @@ -315,7 +312,7 @@ </varlistentry> <varlistentry> <term> - <option>sha512</option> + sha512 </term> <listitem> <para> @@ -329,7 +326,7 @@ </varlistentry> <varlistentry> <term> - <option>blowfish</option> + blowfish </term> <listitem> <para> @@ -343,7 +340,7 @@ </varlistentry> <varlistentry> <term> - <option>gost_yescrypt</option> + gost_yescrypt </term> <listitem> <para> @@ -357,7 +354,7 @@ </varlistentry> <varlistentry> <term> - <option>yescrypt</option> + yescrypt </term> <listitem> <para> @@ -371,7 +368,7 @@ </varlistentry> <varlistentry> <term> - <option>rounds=<replaceable>n</replaceable></option> + rounds=n </term> <listitem> <para> @@ -384,7 +381,7 @@ </varlistentry> <varlistentry> <term> - <option>broken_shadow</option> + broken_shadow </term> <listitem> <para> @@ -395,7 +392,7 @@ </varlistentry> <varlistentry> <term> - <option>minlen=<replaceable>n</replaceable></option> + minlen=n </term> <listitem> <para> @@ -407,7 +404,7 @@ </varlistentry> <varlistentry> <term> - <option>no_pass_expiry</option> + no_pass_expiry </term> <listitem> <para> @@ -418,9 +415,9 @@ meaning that other authentication source or method succeeded. The example can be public key authentication in <emphasis>sshd</emphasis>. The module will return - <emphasis remap='B'>PAM_SUCCESS</emphasis> instead of eventual - <emphasis remap='B'>PAM_NEW_AUTHTOK_REQD</emphasis> or - <emphasis remap='B'>PAM_AUTHTOK_EXPIRED</emphasis>. + <emphasis remap="B">PAM_SUCCESS</emphasis> instead of eventual + <emphasis remap="B">PAM_NEW_AUTHTOK_REQD</emphasis> or + <emphasis remap="B">PAM_AUTHTOK_EXPIRED</emphasis>. </para> </listitem> </varlistentry> @@ -432,7 +429,7 @@ </para> </refsect1> - <refsect1 id="pam_unix-types"> + <refsect1 xml:id="pam_unix-types"> <title>MODULE TYPES PROVIDED</title> <para> All module types (<option>account</option>, <option>auth</option>, @@ -440,7 +437,7 @@ </para> </refsect1> - <refsect1 id='pam_unix-return_values'> + <refsect1 xml:id="pam_unix-return_values"> <title>RETURN VALUES</title> <variablelist> <varlistentry> @@ -454,7 +451,7 @@ </variablelist> </refsect1> - <refsect1 id='pam_unix-examples'> + <refsect1 xml:id="pam_unix-examples"> <title>EXAMPLES</title> <para> An example usage for <filename>/etc/pam.d/login</filename> @@ -465,15 +462,15 @@ auth required pam_unix.so # Ensure users account and password are still active 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 +# with pam_passwdqc(8) +password required pam_passwdqc.so config=/etc/passwdqc.conf password required pam_unix.so use_authtok nullok yescrypt session required pam_unix.so </programlisting> </para> </refsect1> - <refsect1 id='pam_unix-see_also'> + <refsect1 xml:id="pam_unix-see_also"> <title>SEE ALSO</title> <para> <citerefentry> @@ -491,11 +488,11 @@ session required pam_unix.so </para> </refsect1> - <refsect1 id='pam_unix-author'> + <refsect1 xml:id="pam_unix-author"> <title>AUTHOR</title> <para> pam_unix was written by various people. </para> </refsect1> -</refentry> +</refentry>
\ No newline at end of file diff --git a/modules/pam_unix/pam_unix_acct.c b/modules/pam_unix/pam_unix_acct.c index de8d65c1..8f5ed3e0 100644 --- a/modules/pam_unix/pam_unix_acct.c +++ b/modules/pam_unix/pam_unix_acct.c @@ -189,7 +189,7 @@ pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv) unsigned long long ctrl; const void *void_uname; const char *uname; - int retval, daysleft; + int retval, daysleft = -1; char buf[256]; D(("called.")); @@ -252,6 +252,10 @@ pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv) _("Your account has expired; please contact your system administrator.")); break; case PAM_AUTHTOK_ERR: + /* + * We ignore "password changed too early" error + * as it is relevant only for password change. + */ retval = PAM_SUCCESS; /* fallthrough */ case PAM_SUCCESS: diff --git a/modules/pam_unix/pam_unix_passwd.c b/modules/pam_unix/pam_unix_passwd.c index e988b2e3..c3417413 100644 --- a/modules/pam_unix/pam_unix_passwd.c +++ b/modules/pam_unix/pam_unix_passwd.c @@ -66,30 +66,21 @@ #include <security/pam_ext.h> #include <security/pam_modutil.h> +#include "pam_inline.h" #include "pam_cc_compat.h" #include "md5.h" #include "support.h" #include "passverify.h" #include "bigcrypt.h" -#if (HAVE_YP_GET_DEFAULT_DOMAIN || HAVE_GETDOMAINNAME) && HAVE_YP_MASTER -# define HAVE_NIS -#endif - #ifdef HAVE_NIS # include <rpc/rpc.h> - -# if HAVE_RPCSVC_YP_PROT_H -# include <rpcsvc/yp_prot.h> -# endif - -# if HAVE_RPCSVC_YPCLNT_H -# include <rpcsvc/ypclnt.h> -# endif +# include <rpcsvc/yp_prot.h> +# include <rpcsvc/ypclnt.h> # include "yppasswd.h" -# if !HAVE_DECL_GETRPCPORT &&!HAVE_RPCB_GETADDR +# if !defined(HAVE_DECL_GETRPCPORT) &&!defined(HAVE_RPCB_GETADDR) extern int getrpcport(const char *host, unsigned long prognum, unsigned long versnum, unsigned int proto); # endif /* GNU libc 2.1 */ @@ -577,7 +568,7 @@ static int _pam_unix_approve_pass(pam_handle_t * pamh } } - if (strlen(pass_new) > MAXPASS) { + if (strlen(pass_new) > PAM_MAX_RESP_SIZE) { remark = _("You must choose a shorter password."); D(("length exceeded [%s]", remark)); } else if (off(UNIX__IAMROOT, ctrl)) { diff --git a/modules/pam_unix/passverify.c b/modules/pam_unix/passverify.c index a571b4f7..81b10d88 100644 --- a/modules/pam_unix/passverify.c +++ b/modules/pam_unix/passverify.c @@ -19,9 +19,7 @@ #include <sys/time.h> #include <sys/stat.h> #include <fcntl.h> -#ifdef HAVE_LIBXCRYPT -#include <xcrypt.h> -#elif defined(HAVE_CRYPT_H) +#ifdef HAVE_CRYPT_H #include <crypt.h> #endif @@ -98,7 +96,7 @@ PAMH_ARG_DECL(int verify_pwd_hash, } else if (*hash != '$' && hash_len >= 13) { pp = bigcrypt(p, hash); if (pp && hash_len == 13 && strlen(pp) > hash_len) { - _pam_overwrite(pp + hash_len); + pam_overwrite_string(pp + hash_len); } } else { /* @@ -149,7 +147,7 @@ PAMH_ARG_DECL(int verify_pwd_hash, if (cdata != NULL) { cdata->initialized = 0; pp = x_strdup(crypt_r(p, hash, cdata)); - memset(cdata, '\0', sizeof(*cdata)); + pam_overwrite_object(cdata); free(cdata); } #else @@ -243,12 +241,15 @@ PAMH_ARG_DECL(int get_account_info, * ...and shadow password file entry for this user, * if shadowing is enabled */ + *spwdent = pam_modutil_getspnam(pamh, name); + if (*spwdent == NULL) { #ifndef HELPER_COMPILE - if (geteuid() || SELINUX_ENABLED) + /* still a chance the user can authenticate */ return PAM_UNIX_RUN_HELPER; #endif - *spwdent = pam_modutil_getspnam(pamh, name); - if (*spwdent == NULL || (*spwdent)->sp_pwdp == NULL) + return PAM_AUTHINFO_UNAVAIL; + } + if ((*spwdent)->sp_pwdp == NULL) return PAM_AUTHINFO_UNAVAIL; } } else { @@ -289,13 +290,7 @@ 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; @@ -339,7 +334,7 @@ PAMH_ARG_DECL(int check_shadow_expiry, #define PW_TMPFILE "/etc/npasswd" #define SH_TMPFILE "/etc/nshadow" -#define OPW_TMPFILE "/etc/security/nopasswd" +#define OPW_TMPFILE SCONFIGDIR "/nopasswd" /* * i64c - convert an integer to a radix 64 character @@ -432,7 +427,7 @@ PAMH_ARG_DECL(char * create_password_hash, #else char salt[64]; /* contains rounds number + max 16 bytes of salt + algo id */ #endif - char *sp; + char *sp, *ret; #ifdef HAVE_CRYPT_R struct crypt_data *cdata = NULL; #endif @@ -452,7 +447,7 @@ PAMH_ARG_DECL(char * create_password_hash, algoid = "$6$"; } else { /* must be crypt/bigcrypt */ char tmppass[9]; - char *crypted; + char *hashed; crypt_make_salt(salt, 2); if (off(UNIX_BIGCRYPT, ctrl) && strlen(password) > 8) { @@ -460,10 +455,10 @@ PAMH_ARG_DECL(char * create_password_hash, tmppass[sizeof(tmppass)-1] = '\0'; password = tmppass; } - crypted = bigcrypt(password, salt); - memset(tmppass, '\0', sizeof(tmppass)); + hashed = bigcrypt(password, salt); + pam_overwrite_array(tmppass); password = NULL; - return crypted; + return hashed; } #if defined(CRYPT_GENSALT_IMPLEMENTS_AUTO_ENTROPY) && CRYPT_GENSALT_IMPLEMENTS_AUTO_ENTROPY @@ -473,23 +468,11 @@ PAMH_ARG_DECL(char * create_password_hash, */ 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]; - crypt_make_salt(entropy, sizeof(entropy) - 1); - sp = crypt_gensalt_r (algoid, rounds, - entropy, sizeof(entropy), - salt, sizeof(salt)); - } else { -#endif - sp = stpcpy(salt, algoid); - if (on(UNIX_ALGO_ROUNDS, ctrl)) { - sp += snprintf(sp, sizeof(salt) - (16 + 1 + (sp - salt)), "rounds=%u$", rounds); - } - crypt_make_salt(sp, 16); -#ifdef HAVE_CRYPT_GENSALT_R + sp = stpcpy(salt, algoid); + if (on(UNIX_ALGO_ROUNDS, ctrl)) { + sp += snprintf(sp, sizeof(salt) - (16 + 1 + (sp - salt)), "rounds=%u$", rounds); } -#endif + crypt_make_salt(sp, 16); #endif /* CRYPT_GENSALT_IMPLEMENTS_AUTO_ENTROPY */ #ifdef HAVE_CRYPT_R sp = NULL; @@ -511,18 +494,21 @@ PAMH_ARG_DECL(char * create_password_hash, on(UNIX_SHA256_PASS, ctrl) ? "sha256" : on(UNIX_SHA512_PASS, ctrl) ? "sha512" : algoid); if(sp) { - memset(sp, '\0', strlen(sp)); + pam_overwrite_string(sp); } #ifdef HAVE_CRYPT_R + pam_overwrite_object(cdata); free(cdata); #endif return NULL; } - sp = x_strdup(sp); + ret = strdup(sp); + pam_overwrite_string(sp); #ifdef HAVE_CRYPT_R + pam_overwrite_object(cdata); free(cdata); #endif - return sp; + return ret; } #ifdef WITH_SELINUX @@ -650,7 +636,7 @@ save_old_password(pam_handle_t *pamh, const char *forwho, const char *oldpass, struct stat st; size_t len = strlen(forwho); #ifdef WITH_SELINUX - security_context_t prev_context=NULL; + char *prev_context_raw = NULL; #endif if (howmany < 0) { @@ -665,20 +651,20 @@ save_old_password(pam_handle_t *pamh, const char *forwho, const char *oldpass, #ifdef WITH_SELINUX if (SELINUX_ENABLED) { - security_context_t passwd_context=NULL; - if (getfilecon("/etc/passwd",&passwd_context)<0) { + char *passwd_context_raw = NULL; + if (getfilecon_raw("/etc/passwd",&passwd_context_raw)<0) { return PAM_AUTHTOK_ERR; }; - if (getfscreatecon(&prev_context)<0) { - freecon(passwd_context); + if (getfscreatecon_raw(&prev_context_raw)<0) { + freecon(passwd_context_raw); return PAM_AUTHTOK_ERR; } - if (setfscreatecon(passwd_context)) { - freecon(passwd_context); - freecon(prev_context); + if (setfscreatecon_raw(passwd_context_raw)) { + freecon(passwd_context_raw); + freecon(prev_context_raw); return PAM_AUTHTOK_ERR; } - freecon(passwd_context); + freecon(passwd_context_raw); } #endif pwfile = fopen(OPW_TMPFILE, "w"); @@ -796,12 +782,12 @@ done: } #ifdef WITH_SELINUX if (SELINUX_ENABLED) { - if (setfscreatecon(prev_context)) { + if (setfscreatecon_raw(prev_context_raw)) { err = 1; } - if (prev_context) - freecon(prev_context); - prev_context=NULL; + if (prev_context_raw) + freecon(prev_context_raw); + prev_context_raw = NULL; } #endif if (!err) { @@ -821,26 +807,26 @@ PAMH_ARG_DECL(int unix_update_passwd, int err = 1; int oldmask; #ifdef WITH_SELINUX - security_context_t prev_context=NULL; + char *prev_context_raw = NULL; #endif oldmask = umask(077); #ifdef WITH_SELINUX if (SELINUX_ENABLED) { - security_context_t passwd_context=NULL; - if (getfilecon("/etc/passwd",&passwd_context)<0) { + char *passwd_context_raw = NULL; + if (getfilecon_raw("/etc/passwd",&passwd_context_raw)<0) { return PAM_AUTHTOK_ERR; }; - if (getfscreatecon(&prev_context)<0) { - freecon(passwd_context); + if (getfscreatecon_raw(&prev_context_raw)<0) { + freecon(passwd_context_raw); return PAM_AUTHTOK_ERR; } - if (setfscreatecon(passwd_context)) { - freecon(passwd_context); - freecon(prev_context); + if (setfscreatecon_raw(passwd_context_raw)) { + freecon(passwd_context_raw); + freecon(prev_context_raw); return PAM_AUTHTOK_ERR; } - freecon(passwd_context); + freecon(passwd_context_raw); } #endif pwfile = fopen(PW_TMPFILE, "w"); @@ -919,12 +905,12 @@ done: } #ifdef WITH_SELINUX if (SELINUX_ENABLED) { - if (setfscreatecon(prev_context)) { + if (setfscreatecon_raw(prev_context_raw)) { err = 1; } - if (prev_context) - freecon(prev_context); - prev_context=NULL; + if (prev_context_raw) + freecon(prev_context_raw); + prev_context_raw = NULL; } #endif if (!err) { @@ -945,27 +931,27 @@ PAMH_ARG_DECL(int unix_update_shadow, int oldmask; int wroteentry = 0; #ifdef WITH_SELINUX - security_context_t prev_context=NULL; + char *prev_context_raw = NULL; #endif oldmask = umask(077); #ifdef WITH_SELINUX if (SELINUX_ENABLED) { - security_context_t shadow_context=NULL; - if (getfilecon("/etc/shadow",&shadow_context)<0) { + char *shadow_context_raw = NULL; + if (getfilecon_raw("/etc/shadow",&shadow_context_raw)<0) { return PAM_AUTHTOK_ERR; }; - if (getfscreatecon(&prev_context)<0) { - freecon(shadow_context); + if (getfscreatecon_raw(&prev_context_raw)<0) { + freecon(shadow_context_raw); return PAM_AUTHTOK_ERR; } - if (setfscreatecon(shadow_context)) { - freecon(shadow_context); - freecon(prev_context); + if (setfscreatecon_raw(shadow_context_raw)) { + freecon(shadow_context_raw); + freecon(prev_context_raw); return PAM_AUTHTOK_ERR; } - freecon(shadow_context); + freecon(shadow_context_raw); } #endif pwfile = fopen(SH_TMPFILE, "w"); @@ -1065,12 +1051,12 @@ PAMH_ARG_DECL(int unix_update_shadow, #ifdef WITH_SELINUX if (SELINUX_ENABLED) { - if (setfscreatecon(prev_context)) { + if (setfscreatecon_raw(prev_context_raw)) { err = 1; } - if (prev_context) - freecon(prev_context); - prev_context=NULL; + if (prev_context_raw) + freecon(prev_context_raw); + prev_context_raw = NULL; } #endif @@ -1096,12 +1082,18 @@ helper_verify_password(const char *name, const char *p, int nullok) if (pwd == NULL || hash == NULL) { helper_log_err(LOG_NOTICE, "check pass; user unknown"); retval = PAM_USER_UNKNOWN; + } else if (p[0] == '\0' && nullok) { + if (hash[0] == '\0') { + retval = PAM_SUCCESS; + } else { + retval = PAM_AUTH_ERR; + } } else { retval = verify_pwd_hash(p, hash, nullok); } if (hash) { - _pam_overwrite(hash); + pam_overwrite_string(hash); _pam_drop(hash); } @@ -1111,6 +1103,7 @@ helper_verify_password(const char *name, const char *p, int nullok) } void +PAM_FORMAT((printf, 2, 3)) helper_log_err(int err, const char *format, ...) { va_list args; @@ -1180,49 +1173,6 @@ getuidname(uid_t uid) return username; } -int -read_passwords(int fd, int npass, char **passwords) -{ - /* The passwords array must contain npass preallocated - * buffers of length MAXPASS + 1 - */ - int rbytes = 0; - int offset = 0; - int i = 0; - char *pptr; - while (npass > 0) { - rbytes = read(fd, passwords[i]+offset, MAXPASS+1-offset); - - if (rbytes < 0) { - if (errno == EINTR) continue; - break; - } - if (rbytes == 0) - break; - - while (npass > 0 && (pptr=memchr(passwords[i]+offset, '\0', rbytes)) - != NULL) { - rbytes -= pptr - (passwords[i]+offset) + 1; - i++; - offset = 0; - npass--; - if (rbytes > 0) { - if (npass > 0) - memcpy(passwords[i], pptr+1, rbytes); - memset(pptr+1, '\0', rbytes); - } - } - offset += rbytes; - } - - /* clear up */ - if (offset > 0 && npass > 0) { - memset(passwords[i], '\0', offset); - } - - return i; -} - #endif /* ****************************************************************** * * Copyright (c) Jan Rękorajski 1999. diff --git a/modules/pam_unix/passverify.h b/modules/pam_unix/passverify.h index e9a88fbf..463ef185 100644 --- a/modules/pam_unix/passverify.h +++ b/modules/pam_unix/passverify.h @@ -8,9 +8,7 @@ #define PAM_UNIX_RUN_HELPER PAM_CRED_INSUFFICIENT -#define MAXPASS PAM_MAX_RESP_SIZE /* the maximum length of a password */ - -#define OLD_PASSWORDS_FILE "/etc/security/opasswd" +#define OLD_PASSWORDS_FILE SCONFIGDIR "/opasswd" int is_pwd_shadowed(const struct passwd *pwd); @@ -50,8 +48,6 @@ setup_signals(void); char * getuidname(uid_t uid); -int -read_passwords(int fd, int npass, char **passwords); #endif #ifdef HELPER_COMPILE diff --git a/modules/pam_unix/support.c b/modules/pam_unix/support.c index 41db1f04..043273d2 100644 --- a/modules/pam_unix/support.c +++ b/modules/pam_unix/support.c @@ -19,7 +19,7 @@ #include <ctype.h> #include <syslog.h> #include <sys/resource.h> -#ifdef HAVE_RPCSVC_YPCLNT_H +#ifdef HAVE_NIS #include <rpcsvc/ypclnt.h> #endif @@ -601,6 +601,9 @@ _unix_blankpasswd (pam_handle_t *pamh, unsigned long long ctrl, const char *name char *salt = NULL; int daysleft; int retval; + int blank = 0; + int execloop; + int nonexistent_check = 1; D(("called")); @@ -624,32 +627,35 @@ _unix_blankpasswd (pam_handle_t *pamh, unsigned long long ctrl, const char *name /* UNIX passwords area */ - retval = get_pwd_hash(pamh, name, &pwd, &salt); - - if (retval == PAM_UNIX_RUN_HELPER) { - /* salt will not be set here so we can return immediately */ - if (_unix_run_helper_binary(pamh, NULL, ctrl, name) == PAM_SUCCESS) - return 1; - else - return 0; - } + /* + * Execute this loop twice: one checking the password hash of an existing + * user and another one for a non-existing user. This way the runtimes + * are equal, making it more difficult to differentiate existing from + * non-existing users. + */ + for (execloop = 0; execloop < 2; ++execloop) { + retval = get_pwd_hash(pamh, name, &pwd, &salt); - /* Does this user have a password? */ - if (salt == NULL) { - retval = 0; - } else { - if (strlen(salt) == 0) - retval = 1; - else - retval = 0; + if (retval == PAM_UNIX_RUN_HELPER) { + if (_unix_run_helper_binary(pamh, NULL, ctrl, name) == PAM_SUCCESS) + blank = nonexistent_check; + } else if (retval == PAM_USER_UNKNOWN) { + name = "root"; + nonexistent_check = 0; + continue; + } else if (salt != NULL) { + if (strlen(salt) == 0) + blank = nonexistent_check; + } + name = "pam_unix_non_existent:"; + /* non-existent user check will not affect the blank value */ } /* tidy up */ - if (salt) _pam_delete(salt); - return retval; + return blank; } int _unix_verify_password(pam_handle_t * pamh, const char *name @@ -658,7 +664,7 @@ int _unix_verify_password(pam_handle_t * pamh, const char *name struct passwd *pwd = NULL; char *salt = NULL; char *data_name; - char pw[MAXPASS + 1]; + char pw[PAM_MAX_RESP_SIZE + 1]; int retval; @@ -685,7 +691,7 @@ 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) { + if (p != NULL && strlen(p) > PAM_MAX_RESP_SIZE) { memset(pw, 0, sizeof(pw)); p = strncpy(pw, p, sizeof(pw) - 1); } @@ -799,7 +805,7 @@ int _unix_verify_password(pam_handle_t * pamh, const char *name } cleanup: - memset(pw, 0, sizeof(pw)); /* clear memory of the password */ + pam_overwrite_array(pw); /* clear memory of the password */ if (data_name) _pam_delete(data_name); if (salt) diff --git a/modules/pam_unix/support.h b/modules/pam_unix/support.h index 19754dc1..81054002 100644 --- a/modules/pam_unix/support.h +++ b/modules/pam_unix/support.h @@ -151,10 +151,10 @@ static const UNIX_Ctrls unix_args[UNIX_CTRLS_] = /* use this to free strings. ESPECIALLY password strings */ -#define _pam_delete(xx) \ -{ \ - _pam_overwrite(xx); \ - _pam_drop(xx); \ +#define _pam_delete(xx) \ +{ \ + pam_overwrite_string(xx); \ + _pam_drop(xx); \ } extern int _make_remark(pam_handle_t * pamh, unsigned long long ctrl, diff --git a/modules/pam_unix/unix_chkpwd.8 b/modules/pam_unix/unix_chkpwd.8 index e5d40ad3..7c1963b3 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.79.1 <http://docbook.sf.net/> -.\" Date: 06/08/2020 +.\" 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 "UNIX_CHKPWD" "8" "06/08/2020" "Linux-PAM Manual" "Linux\-PAM Manual" +.TH "UNIX_CHKPWD" "8" "05/07/2023" "Linux\-PAM" "Linux\-PAM Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/modules/pam_unix/unix_chkpwd.8.xml b/modules/pam_unix/unix_chkpwd.8.xml index a10dbe33..ca0fa109 100644 --- a/modules/pam_unix/unix_chkpwd.8.xml +++ b/modules/pam_unix/unix_chkpwd.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="unix_chkpwd"> +<refentry xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="unix_chkpwd"> <refmeta> <refentrytitle>unix_chkpwd</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="unix_chkpwd-name"> + <refnamediv xml:id="unix_chkpwd-name"> <refname>unix_chkpwd</refname> <refpurpose>Helper binary that verifies the password of the current user</refpurpose> </refnamediv> <refsynopsisdiv> - <cmdsynopsis id="unix_chkpwd-cmdsynopsis"> + <cmdsynopsis xml:id="unix_chkpwd-cmdsynopsis" sepchar=" "> <command>unix_chkpwd</command> - <arg choice="opt"> + <arg choice="opt" rep="norepeat"> ... </arg> </cmdsynopsis> </refsynopsisdiv> - <refsect1 id="unix_chkpwd-description"> + <refsect1 xml:id="unix_chkpwd-description"> <title>DESCRIPTION</title> @@ -48,7 +45,7 @@ </para> </refsect1> - <refsect1 id='unix_chkpwd-see_also'> + <refsect1 xml:id="unix_chkpwd-see_also"> <title>SEE ALSO</title> <para> <citerefentry> @@ -57,11 +54,11 @@ </para> </refsect1> - <refsect1 id='unix_chkpwd-author'> + <refsect1 xml:id="unix_chkpwd-author"> <title>AUTHOR</title> <para> Written by Andrew Morgan and other various people. </para> </refsect1> -</refentry> +</refentry>
\ No newline at end of file diff --git a/modules/pam_unix/unix_chkpwd.c b/modules/pam_unix/unix_chkpwd.c index 88647e58..556a2e2c 100644 --- a/modules/pam_unix/unix_chkpwd.c +++ b/modules/pam_unix/unix_chkpwd.c @@ -33,6 +33,7 @@ #include <security/_pam_macros.h> #include "passverify.h" +#include "pam_inline.h" static int _check_expiry(const char *uname) { @@ -89,7 +90,7 @@ static int _audit_log(int type, const char *uname, int rc) int main(int argc, char *argv[]) { - char pass[MAXPASS + 1]; + char pass[PAM_MAX_RESP_SIZE + 1]; char *option; int npass, nullok; int blankpass = 0; @@ -136,7 +137,7 @@ int main(int argc, char *argv[]) user = getuidname(getuid()); /* if the caller specifies the username, verify that user matches it */ - if (strcmp(user, argv[1])) { + if (user == NULL || strcmp(user, argv[1])) { user = argv[1]; /* no match -> permanently change to the real user and proceed */ if (setuid(getuid()) != 0) @@ -162,7 +163,7 @@ int main(int argc, char *argv[]) } /* read the password from stdin (a pipe from the pam_unix module) */ - npass = read_passwords(STDIN_FILENO, 1, passwords); + npass = pam_read_passwords(STDIN_FILENO, 1, passwords); if (npass != 1) { /* is it a valid password? */ helper_log_err(LOG_DEBUG, "no password supplied"); @@ -175,7 +176,7 @@ int main(int argc, char *argv[]) retval = helper_verify_password(user, pass, nullok); - memset(pass, '\0', MAXPASS); /* clear memory of the password */ + pam_overwrite_array(pass); /* clear memory of the password */ /* return pass or fail */ diff --git a/modules/pam_unix/unix_update.8 b/modules/pam_unix/unix_update.8 index 4a7a3d1b..b3b7a28f 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.79.1 <http://docbook.sf.net/> -.\" Date: 06/08/2020 +.\" 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 "UNIX_UPDATE" "8" "06/08/2020" "Linux-PAM Manual" "Linux\-PAM Manual" +.TH "UNIX_UPDATE" "8" "05/07/2023" "Linux\-PAM" "Linux\-PAM Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/modules/pam_unix/unix_update.8.xml b/modules/pam_unix/unix_update.8.xml index 6c7467b9..1a968652 100644 --- a/modules/pam_unix/unix_update.8.xml +++ b/modules/pam_unix/unix_update.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="unix_update"> +<refentry xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="unix_update"> <refmeta> <refentrytitle>unix_update</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="unix_update-name"> + <refnamediv xml:id="unix_update-name"> <refname>unix_update</refname> <refpurpose>Helper binary that updates the password of a given user</refpurpose> </refnamediv> <refsynopsisdiv> - <cmdsynopsis id="unix_update-cmdsynopsis"> + <cmdsynopsis xml:id="unix_update-cmdsynopsis" sepchar=" "> <command>unix_update</command> - <arg choice="opt"> + <arg choice="opt" rep="norepeat"> ... </arg> </cmdsynopsis> </refsynopsisdiv> - <refsect1 id="unix_update-description"> + <refsect1 xml:id="unix_update-description"> <title>DESCRIPTION</title> @@ -48,7 +45,7 @@ </para> </refsect1> - <refsect1 id='unix_update-see_also'> + <refsect1 xml:id="unix_update-see_also"> <title>SEE ALSO</title> <para> <citerefentry> @@ -57,11 +54,11 @@ </para> </refsect1> - <refsect1 id='unix_update-author'> + <refsect1 xml:id="unix_update-author"> <title>AUTHOR</title> <para> Written by Tomas Mraz and other various people. </para> </refsect1> -</refentry> +</refentry>
\ No newline at end of file diff --git a/modules/pam_unix/unix_update.c b/modules/pam_unix/unix_update.c index 6ea7ea51..49a70ff3 100644 --- a/modules/pam_unix/unix_update.c +++ b/modules/pam_unix/unix_update.c @@ -32,14 +32,15 @@ #include <security/_pam_macros.h> #include "passverify.h" +#include "pam_inline.h" static int set_password(const char *forwho, const char *shadow, const char *remember) { struct passwd *pwd = NULL; int retval; - char pass[MAXPASS + 1]; - char towhat[MAXPASS + 1]; + char pass[PAM_MAX_RESP_SIZE + 1]; + char towhat[PAM_MAX_RESP_SIZE + 1]; int npass = 0; /* we don't care about number format errors because the helper should be called internally only */ @@ -49,20 +50,23 @@ set_password(const char *forwho, const char *shadow, const char *remember) /* read the password from stdin (a pipe from the pam_unix module) */ - npass = read_passwords(STDIN_FILENO, 2, passwords); + npass = pam_read_passwords(STDIN_FILENO, 2, passwords); if (npass != 2) { /* is it a valid password? */ if (npass == 1) { helper_log_err(LOG_DEBUG, "no new password supplied"); - memset(pass, '\0', MAXPASS); + pam_overwrite_array(pass); } else { helper_log_err(LOG_DEBUG, "no valid passwords supplied"); } return PAM_AUTHTOK_ERR; } - if (lock_pwdf() != PAM_SUCCESS) + if (lock_pwdf() != PAM_SUCCESS) { + pam_overwrite_array(pass); + pam_overwrite_array(towhat); return PAM_AUTHTOK_LOCK_BUSY; + } pwd = getpwnam(forwho); @@ -97,8 +101,8 @@ set_password(const char *forwho, const char *shadow, const char *remember) } done: - memset(pass, '\0', MAXPASS); - memset(towhat, '\0', MAXPASS); + pam_overwrite_array(pass); + pam_overwrite_array(towhat); unlock_pwdf(); diff --git a/modules/pam_unix/yppasswd.h b/modules/pam_unix/yppasswd.h index 5f947071..dc686cd7 100644 --- a/modules/pam_unix/yppasswd.h +++ b/modules/pam_unix/yppasswd.h @@ -1,28 +1,20 @@ /* - * yppasswdd - * Copyright 1994, 1995, 1996 Olaf Kirch, <okir@lst.de> - * - * This program is covered by the GNU General Public License, version 2 - * or later. It is provided in the hope that it is useful. However, the author - * disclaims ALL WARRANTIES, expressed or implied. See the GPL for details. - * - * This file was generated automatically by rpcgen from yppasswd.x, and - * editied manually. + * Please do not edit this file. + * It was generated using rpcgen. */ -#ifndef _YPPASSWD_H_ -#define _YPPASSWD_H_ +#ifndef _YPPASSWD_H_RPCGEN +#define _YPPASSWD_H_RPCGEN -#define YPPASSWDPROG ((u_long)100009) -#define YPPASSWDVERS ((u_long)1) -#define YPPASSWDPROC_UPDATE ((u_long)1) +#include <rpc/rpc.h> -/* - * The password struct passed by the update call. I renamed it to - * xpasswd to avoid a type clash with the one defined in <pwd.h>. - */ -#ifndef __sgi -typedef struct xpasswd { + +#ifdef __cplusplus +extern "C" { +#endif + + +struct xpasswd { char *pw_name; char *pw_passwd; int pw_uid; @@ -30,22 +22,45 @@ typedef struct xpasswd { char *pw_gecos; char *pw_dir; char *pw_shell; -} xpasswd; - -#else -#include <pwd.h> +}; typedef struct xpasswd xpasswd; -#endif -/* The updated password information, plus the old password. - */ -typedef struct yppasswd { +struct yppasswd { char *oldpass; xpasswd newpw; -} yppasswd; +}; +typedef struct yppasswd yppasswd; -/* XDR encoding/decoding routines */ -bool_t xdr_xpasswd(XDR * xdrs, xpasswd * objp); -bool_t xdr_yppasswd(XDR * xdrs, yppasswd * objp); +#define YPPASSWDPROG 100009 +#define YPPASSWDVERS 1 + +#if defined(__STDC__) || defined(__cplusplus) +#define YPPASSWDPROC_UPDATE 1 +extern int * yppasswdproc_update_1(yppasswd *, CLIENT *); +extern int * yppasswdproc_update_1_svc(yppasswd *, struct svc_req *); +extern int yppasswdprog_1_freeresult (SVCXPRT *, xdrproc_t, caddr_t); + +#else /* K&R C */ +#define YPPASSWDPROC_UPDATE 1 +extern int * yppasswdproc_update_1(); +extern int * yppasswdproc_update_1_svc(); +extern int yppasswdprog_1_freeresult (); +#endif /* K&R C */ + +/* the xdr functions */ + +#if defined(__STDC__) || defined(__cplusplus) +extern bool_t xdr_passwd (XDR *, xpasswd*); +extern bool_t xdr_yppasswd (XDR *, yppasswd*); + +#else /* K&R C */ +extern bool_t xdr_passwd (); +extern bool_t xdr_yppasswd (); + +#endif /* K&R C */ + +#ifdef __cplusplus +} +#endif -#endif /* _YPPASSWD_H_ */ +#endif /* !_YPPASSWD_H_RPCGEN */ diff --git a/modules/pam_unix/yppasswd_xdr.c b/modules/pam_unix/yppasswd_xdr.c index f2b86a56..0523d523 100644 --- a/modules/pam_unix/yppasswd_xdr.c +++ b/modules/pam_unix/yppasswd_xdr.c @@ -1,40 +1,36 @@ /* - * yppasswdd - * Copyright 1994, 1995, 1996 Olaf Kirch, <okir@lst.de> - * - * This program is covered by the GNU General Public License, version 2 - * or later. It is provided in the hope that it is useful. However, the author - * disclaims ALL WARRANTIES, expressed or implied. See the GPL for details. - * - * This file was generated automatically by rpcgen from yppasswd.x, and - * editied manually. + * Please do not edit this file. + * It was generated using rpcgen. */ -#include "config.h" - -#ifdef HAVE_RPC_RPC_H - -#include <rpc/rpc.h> #include "yppasswd.h" bool_t -xdr_xpasswd(XDR * xdrs, xpasswd * objp) +xdr_passwd (XDR *xdrs, xpasswd *objp) { - return xdr_string(xdrs, &objp->pw_name, ~0) - && xdr_string(xdrs, &objp->pw_passwd, ~0) - && xdr_int(xdrs, &objp->pw_uid) - && xdr_int(xdrs, &objp->pw_gid) - && xdr_string(xdrs, &objp->pw_gecos, ~0) - && xdr_string(xdrs, &objp->pw_dir, ~0) - && xdr_string(xdrs, &objp->pw_shell, ~0); + if (!xdr_string (xdrs, &objp->pw_name, ~0)) + return FALSE; + if (!xdr_string (xdrs, &objp->pw_passwd, ~0)) + return FALSE; + if (!xdr_int (xdrs, &objp->pw_uid)) + return FALSE; + if (!xdr_int (xdrs, &objp->pw_gid)) + return FALSE; + if (!xdr_string (xdrs, &objp->pw_gecos, ~0)) + return FALSE; + if (!xdr_string (xdrs, &objp->pw_dir, ~0)) + return FALSE; + if (!xdr_string (xdrs, &objp->pw_shell, ~0)) + return FALSE; + return TRUE; } - bool_t -xdr_yppasswd(XDR * xdrs, yppasswd * objp) +xdr_yppasswd (XDR *xdrs, yppasswd *objp) { - return xdr_string(xdrs, &objp->oldpass, ~0) - && xdr_xpasswd(xdrs, &objp->newpw); + if (!xdr_string (xdrs, &objp->oldpass, ~0)) + return FALSE; + if (!xdr_passwd (xdrs, &objp->newpw)) + return FALSE; + return TRUE; } - -#endif |