diff options
author | Steve Langasek <steve.langasek@canonical.com> | 2022-08-16 22:06:15 -0700 |
---|---|---|
committer | Steve Langasek <steve.langasek@canonical.com> | 2022-08-16 22:06:15 -0700 |
commit | 99d0d1c5c4f07332daa86e73981267a761bc966e (patch) | |
tree | a56fe41110023676d7082028cbaa47ca4b6e6164 /libpam | |
parent | f6d08ed47a3da3c08345bce2ca366e961c52ad7c (diff) | |
parent | 40f7d85f3736d058c26de1dafa4fed46de7d75ef (diff) |
New upstream version 1.5.2
Diffstat (limited to 'libpam')
-rw-r--r-- | libpam/Makefile.am | 5 | ||||
-rw-r--r-- | libpam/Makefile.in | 100 | ||||
-rw-r--r-- | libpam/include/pam_inline.h | 51 | ||||
-rw-r--r-- | libpam/include/security/pam_modutil.h | 5 | ||||
-rw-r--r-- | libpam/libpam.map | 5 | ||||
-rw-r--r-- | libpam/pam.pc.in | 9 | ||||
-rw-r--r-- | libpam/pam_dispatch.c | 1 | ||||
-rw-r--r-- | libpam/pam_end.c | 3 | ||||
-rw-r--r-- | libpam/pam_modutil_check_user.c | 92 | ||||
-rw-r--r-- | libpam/pam_modutil_priv.c | 17 | ||||
-rw-r--r-- | libpam/pam_modutil_sanitize.c | 73 | ||||
-rw-r--r-- | libpam/pam_start.c | 3 |
12 files changed, 270 insertions, 94 deletions
diff --git a/libpam/Makefile.am b/libpam/Makefile.am index 9252a837..55222afc 100644 --- a/libpam/Makefile.am +++ b/libpam/Makefile.am @@ -35,7 +35,12 @@ libpam_la_SOURCES = pam_account.c pam_auth.c pam_data.c pam_delay.c \ pam_misc.c pam_password.c pam_prelude.c \ pam_session.c pam_start.c pam_strerror.c \ pam_vprompt.c pam_syslog.c pam_dynamic.c pam_audit.c \ + pam_modutil_check_user.c \ pam_modutil_cleanup.c pam_modutil_getpwnam.c pam_modutil_ioloop.c \ pam_modutil_getgrgid.c pam_modutil_getpwuid.c pam_modutil_getgrnam.c \ pam_modutil_getspnam.c pam_modutil_getlogin.c pam_modutil_ingroup.c \ pam_modutil_priv.c pam_modutil_sanitize.c pam_modutil_searchkey.c + +# Pkg-config script. +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = pam.pc diff --git a/libpam/Makefile.in b/libpam/Makefile.in index a1939ccf..0c2333c0 100644 --- a/libpam/Makefile.in +++ b/libpam/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, @@ -19,6 +19,7 @@ # + VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ @@ -96,25 +97,28 @@ host_triplet = @host@ @HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/libpam.map subdir = libpam 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 $(include_HEADERS) \ $(noinst_HEADERS) $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = +CONFIG_CLEAN_FILES = pam.pc CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ @@ -143,7 +147,8 @@ am__uninstall_files_from_dir = { \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } -am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)" +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)" \ + "$(DESTDIR)$(includedir)" LTLIBRARIES = $(lib_LTLIBRARIES) am__DEPENDENCIES_1 = libpam_la_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) @@ -152,12 +157,13 @@ am_libpam_la_OBJECTS = pam_account.lo pam_auth.lo pam_data.lo \ pam_get_authtok.lo pam_handlers.lo pam_item.lo pam_misc.lo \ pam_password.lo pam_prelude.lo pam_session.lo pam_start.lo \ pam_strerror.lo pam_vprompt.lo pam_syslog.lo pam_dynamic.lo \ - pam_audit.lo pam_modutil_cleanup.lo pam_modutil_getpwnam.lo \ - pam_modutil_ioloop.lo pam_modutil_getgrgid.lo \ - pam_modutil_getpwuid.lo pam_modutil_getgrnam.lo \ - pam_modutil_getspnam.lo pam_modutil_getlogin.lo \ - pam_modutil_ingroup.lo pam_modutil_priv.lo \ - pam_modutil_sanitize.lo pam_modutil_searchkey.lo + pam_audit.lo pam_modutil_check_user.lo pam_modutil_cleanup.lo \ + pam_modutil_getpwnam.lo pam_modutil_ioloop.lo \ + pam_modutil_getgrgid.lo pam_modutil_getpwuid.lo \ + pam_modutil_getgrnam.lo pam_modutil_getspnam.lo \ + pam_modutil_getlogin.lo pam_modutil_ingroup.lo \ + pam_modutil_priv.lo pam_modutil_sanitize.lo \ + pam_modutil_searchkey.lo libpam_la_OBJECTS = $(am_libpam_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -188,6 +194,7 @@ am__depfiles_remade = ./$(DEPDIR)/pam_account.Plo \ ./$(DEPDIR)/pam_end.Plo ./$(DEPDIR)/pam_env.Plo \ ./$(DEPDIR)/pam_get_authtok.Plo ./$(DEPDIR)/pam_handlers.Plo \ ./$(DEPDIR)/pam_item.Plo ./$(DEPDIR)/pam_misc.Plo \ + ./$(DEPDIR)/pam_modutil_check_user.Plo \ ./$(DEPDIR)/pam_modutil_cleanup.Plo \ ./$(DEPDIR)/pam_modutil_getgrgid.Plo \ ./$(DEPDIR)/pam_modutil_getgrnam.Plo \ @@ -230,6 +237,7 @@ am__can_run_installinfo = \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac +DATA = $(pkgconfig_DATA) HEADERS = $(include_HEADERS) $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, @@ -250,7 +258,7 @@ am__define_uniq_tagged_files = \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags -am__DIST_COMMON = $(srcdir)/Makefile.in \ +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/pam.pc.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ @@ -271,6 +279,9 @@ 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@ @@ -284,6 +295,8 @@ ECONF_CFLAGS = @ECONF_CFLAGS@ ECONF_LIBS = @ECONF_LIBS@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ +EXE_CFLAGS = @EXE_CFLAGS@ +EXE_LDFLAGS = @EXE_LDFLAGS@ FGREP = @FGREP@ FO2PDF = @FO2PDF@ GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ @@ -303,7 +316,6 @@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBAUDIT = @LIBAUDIT@ -LIBCRACK = @LIBCRACK@ LIBCRYPT = @LIBCRYPT@ LIBDB = @LIBDB@ LIBDL = @LIBDL@ @@ -350,8 +362,6 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ -PIE_CFLAGS = @PIE_CFLAGS@ -PIE_LDFLAGS = @PIE_LDFLAGS@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -362,6 +372,7 @@ SECUREDIR = @SECUREDIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ +STRINGPARAM_HMAC = @STRINGPARAM_HMAC@ STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@ STRIP = @STRIP@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ @@ -411,7 +422,6 @@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ -libc_cv_fpie = @libc_cv_fpie@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ @@ -419,9 +429,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@ @@ -431,6 +438,7 @@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ +systemdunitdir = @systemdunitdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ @@ -461,11 +469,16 @@ libpam_la_SOURCES = pam_account.c pam_auth.c pam_data.c pam_delay.c \ pam_misc.c pam_password.c pam_prelude.c \ pam_session.c pam_start.c pam_strerror.c \ pam_vprompt.c pam_syslog.c pam_dynamic.c pam_audit.c \ + pam_modutil_check_user.c \ pam_modutil_cleanup.c pam_modutil_getpwnam.c pam_modutil_ioloop.c \ pam_modutil_getgrgid.c pam_modutil_getpwuid.c pam_modutil_getgrnam.c \ pam_modutil_getspnam.c pam_modutil_getlogin.c pam_modutil_ingroup.c \ pam_modutil_priv.c pam_modutil_sanitize.c pam_modutil_searchkey.c + +# Pkg-config script. +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = pam.pc all: all-am .SUFFIXES: @@ -499,6 +512,8 @@ $(top_srcdir)/configure: $(am__configure_deps) $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): +pam.pc: $(top_builddir)/config.status $(srcdir)/pam.pc.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) @@ -557,6 +572,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_handlers.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_item.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_misc.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_modutil_check_user.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_modutil_cleanup.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_modutil_getgrgid.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_modutil_getgrnam.Plo@am__quote@ # am--include-marker @@ -609,6 +625,27 @@ mostlyclean-libtool: clean-libtool: -rm -rf .libs _libs +install-pkgconfigDATA: $(pkgconfig_DATA) + @$(NORMAL_INSTALL) + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ + done + +uninstall-pkgconfigDATA: + @$(NORMAL_UNINSTALL) + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) install-includeHEADERS: $(include_HEADERS) @$(NORMAL_INSTALL) @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ @@ -718,9 +755,9 @@ distdir-am: $(DISTFILES) done check-am: all-am check: check-am -all-am: Makefile $(LTLIBRARIES) $(HEADERS) +all-am: Makefile $(LTLIBRARIES) $(DATA) $(HEADERS) installdirs: - for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"; do \ + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(includedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am @@ -773,6 +810,7 @@ distclean: distclean-am -rm -f ./$(DEPDIR)/pam_handlers.Plo -rm -f ./$(DEPDIR)/pam_item.Plo -rm -f ./$(DEPDIR)/pam_misc.Plo + -rm -f ./$(DEPDIR)/pam_modutil_check_user.Plo -rm -f ./$(DEPDIR)/pam_modutil_cleanup.Plo -rm -f ./$(DEPDIR)/pam_modutil_getgrgid.Plo -rm -f ./$(DEPDIR)/pam_modutil_getgrnam.Plo @@ -808,7 +846,7 @@ info: info-am info-am: -install-data-am: install-includeHEADERS +install-data-am: install-includeHEADERS install-pkgconfigDATA install-dvi: install-dvi-am @@ -850,6 +888,7 @@ maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/pam_handlers.Plo -rm -f ./$(DEPDIR)/pam_item.Plo -rm -f ./$(DEPDIR)/pam_misc.Plo + -rm -f ./$(DEPDIR)/pam_modutil_check_user.Plo -rm -f ./$(DEPDIR)/pam_modutil_cleanup.Plo -rm -f ./$(DEPDIR)/pam_modutil_getgrgid.Plo -rm -f ./$(DEPDIR)/pam_modutil_getgrnam.Plo @@ -885,7 +924,8 @@ ps: ps-am ps-am: -uninstall-am: uninstall-includeHEADERS uninstall-libLTLIBRARIES +uninstall-am: uninstall-includeHEADERS uninstall-libLTLIBRARIES \ + uninstall-pkgconfigDATA .MAKE: install-am install-strip @@ -898,12 +938,12 @@ uninstall-am: uninstall-includeHEADERS uninstall-libLTLIBRARIES install-exec-am install-html install-html-am \ install-includeHEADERS install-info install-info-am \ install-libLTLIBRARIES install-man install-pdf install-pdf-am \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs maintainer-clean \ + install-pkgconfigDATA install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-includeHEADERS \ - uninstall-libLTLIBRARIES + uninstall-libLTLIBRARIES uninstall-pkgconfigDATA .PRECIOUS: Makefile diff --git a/libpam/include/pam_inline.h b/libpam/include/pam_inline.h index ec05fe43..ec2f3bf0 100644 --- a/libpam/include/pam_inline.h +++ b/libpam/include/pam_inline.h @@ -10,6 +10,8 @@ #include "pam_cc_compat.h" #include <string.h> +#include <unistd.h> +#include <errno.h> /* * Evaluates to @@ -64,4 +66,53 @@ pam_str_skip_icase_prefix_len(const char *str, const char *prefix, size_t prefix #define pam_str_skip_icase_prefix(str_, prefix_) \ pam_str_skip_icase_prefix_len((str_), (prefix_), sizeof(prefix_) - 1 + PAM_MUST_BE_ARRAY(prefix_)) +static inline int +pam_read_passwords(int fd, int npass, char **passwords) +{ + /* + * The passwords array must contain npass preallocated + * buffers of length PAM_MAX_RESP_SIZE + 1. + */ + int rbytes = 0; + int offset = 0; + int i = 0; + char *pptr; + while (npass > 0) { + rbytes = read(fd, passwords[i]+offset, PAM_MAX_RESP_SIZE+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) { + ++pptr; /* skip the '\0' */ + rbytes -= pptr - (passwords[i] + offset); + i++; + offset = 0; + npass--; + if (rbytes > 0) { + if (npass > 0) { + memcpy(passwords[i], pptr, rbytes); + } + memset(pptr, '\0', rbytes); + } + } + offset += rbytes; + } + + /* clear up */ + if (offset > 0 && npass > 0) { + memset(passwords[i], '\0', offset); + } + + return i; +} + #endif /* PAM_INLINE_H */ diff --git a/libpam/include/security/pam_modutil.h b/libpam/include/security/pam_modutil.h index 3a6aec6a..33f87b90 100644 --- a/libpam/include/security/pam_modutil.h +++ b/libpam/include/security/pam_modutil.h @@ -58,6 +58,11 @@ extern "C" { #include <security/_pam_types.h> +extern int PAM_NONNULL((1,2)) +pam_modutil_check_user_in_passwd(pam_handle_t *pamh, + const char *user_name, + const char *file_name); + extern struct passwd * PAM_NONNULL((1,2)) pam_modutil_getpwnam(pam_handle_t *pamh, const char *user); diff --git a/libpam/libpam.map b/libpam/libpam.map index c9690a91..3cc7ef35 100644 --- a/libpam/libpam.map +++ b/libpam/libpam.map @@ -82,3 +82,8 @@ LIBPAM_1.4 { global: pam_start_confdir; } LIBPAM_1.0; + +LIBPAM_MODUTIL_1.4.1 { + global: + pam_modutil_check_user_in_passwd; +} LIBPAM_MODUTIL_1.3.2; diff --git a/libpam/pam.pc.in b/libpam/pam.pc.in new file mode 100644 index 00000000..a7cf852d --- /dev/null +++ b/libpam/pam.pc.in @@ -0,0 +1,9 @@ +libdir=@libdir@ +includedir=@includedir@ + +Name: PAM +Description: The primary Linux-PAM library. It is used by PAM modules and PAM-aware applications. +URL: http://www.linux-pam.org/ +Version: @VERSION@ +Cflags: -I${includedir} +Libs: -L${libdir} -lpam diff --git a/libpam/pam_dispatch.c b/libpam/pam_dispatch.c index cf632e8e..974104a2 100644 --- a/libpam/pam_dispatch.c +++ b/libpam/pam_dispatch.c @@ -424,7 +424,6 @@ int _pam_dispatch(pam_handle_t *pamh, int flags, int choice) /* call the list of module functions */ pamh->choice = choice; retval = _pam_dispatch_aux(pamh, flags, h, resumed, use_cached_chain); - resumed = PAM_FALSE; __PAM_TO_APP(pamh); diff --git a/libpam/pam_end.c b/libpam/pam_end.c index 942253d8..406b1478 100644 --- a/libpam/pam_end.c +++ b/libpam/pam_end.c @@ -56,6 +56,9 @@ int pam_end(pam_handle_t *pamh, int pam_status) _pam_overwrite(pamh->user); _pam_drop(pamh->user); + _pam_overwrite(pamh->confdir); + _pam_drop(pamh->confdir); + _pam_overwrite(pamh->prompt); _pam_drop(pamh->prompt); /* prompt for pam_get_user() */ diff --git a/libpam/pam_modutil_check_user.c b/libpam/pam_modutil_check_user.c new file mode 100644 index 00000000..cf1bd1b5 --- /dev/null +++ b/libpam/pam_modutil_check_user.c @@ -0,0 +1,92 @@ +#include "pam_modutil_private.h" +#include <security/pam_ext.h> + +#include <stdio.h> +#include <string.h> +#include <syslog.h> + +int +pam_modutil_check_user_in_passwd(pam_handle_t *pamh, + const char *user_name, + const char *file_name) +{ + int rc; + size_t user_len; + FILE *fp; + char line[BUFSIZ]; + + /* Validate the user name. */ + if ((user_len = strlen(user_name)) == 0) { + pam_syslog(pamh, LOG_NOTICE, "user name is not valid"); + return PAM_SERVICE_ERR; + } + + if (user_len > sizeof(line) - sizeof(":")) { + pam_syslog(pamh, LOG_NOTICE, "user name is too long"); + return PAM_SERVICE_ERR; + } + + if (strchr(user_name, ':') != NULL) { + /* + * "root:x" is not a local user name even if the passwd file + * contains a line starting with "root:x:". + */ + return PAM_PERM_DENIED; + } + + /* Open the passwd file. */ + if (file_name == NULL) { + file_name = "/etc/passwd"; + } + if ((fp = fopen(file_name, "r")) == NULL) { + pam_syslog(pamh, LOG_ERR, "error opening %s: %m", file_name); + return PAM_SERVICE_ERR; + } + + /* + * Scan the file using fgets() instead of fgetpwent_r() because + * the latter is not flexible enough in handling long lines + * in passwd files. + */ + rc = PAM_PERM_DENIED; + while (fgets(line, sizeof(line), fp) != NULL) { + size_t line_len; + const char *str; + + /* + * Does this line start with the user name + * followed by a colon? + */ + if (strncmp(user_name, line, user_len) == 0 && + line[user_len] == ':') { + rc = PAM_SUCCESS; + /* + * Continue reading the file to avoid timing attacks. + */ + } + /* Has a newline been read? */ + line_len = strlen(line); + if (line_len < sizeof(line) - 1 || + line[line_len - 1] == '\n') { + /* Yes, continue with the next line. */ + continue; + } + + /* No, read till the end of this line first. */ + while ((str = fgets(line, sizeof(line), fp)) != NULL) { + line_len = strlen(line); + if (line_len == 0 || + line[line_len - 1] == '\n') { + break; + } + } + if (str == NULL) { + /* fgets returned NULL, we are done. */ + break; + } + /* Continue with the next line. */ + } + + fclose(fp); + return rc; +} diff --git a/libpam/pam_modutil_priv.c b/libpam/pam_modutil_priv.c index e22fab1a..a463e06a 100644 --- a/libpam/pam_modutil_priv.c +++ b/libpam/pam_modutil_priv.c @@ -107,11 +107,20 @@ int pam_modutil_drop_priv(pam_handle_t *pamh, * We should care to leave process credentials in consistent state. * That is, e.g. if change_gid() succeeded but change_uid() failed, * we should try to restore old gid. + * + * We try to add the supplementary groups on a best-effort + * basis. If it fails, it's not fatal: we fall back to using an + * empty list. */ - if (setgroups(0, NULL)) { - pam_syslog(pamh, LOG_ERR, - "pam_modutil_drop_priv: setgroups failed: %m"); - return cleanup(p); + if (initgroups(pw->pw_name, pw->pw_gid)) { + pam_syslog(pamh, LOG_WARNING, + "pam_modutil_drop_priv: initgroups failed: %m"); + + if (setgroups(0, NULL)) { + pam_syslog(pamh, LOG_ERR, + "pam_modutil_drop_priv: setgroups failed: %m"); + return cleanup(p); + } } if (change_gid(pw->pw_gid, &p->old_gid)) { pam_syslog(pamh, LOG_ERR, diff --git a/libpam/pam_modutil_sanitize.c b/libpam/pam_modutil_sanitize.c index 58b9537c..f26e8ec0 100644 --- a/libpam/pam_modutil_sanitize.c +++ b/libpam/pam_modutil_sanitize.c @@ -10,13 +10,6 @@ #include <fcntl.h> #include <syslog.h> #include <sys/resource.h> -#include <dirent.h> -#ifdef HAVE_SYS_VFS_H -#include <sys/vfs.h> -#endif -#ifdef HAVE_LINUX_MAGIC_H -#include <linux/magic.h> -#endif /* * Creates a pipe, closes its write end, redirects fd to its read end. @@ -91,69 +84,31 @@ redirect_out(pam_handle_t *pamh, enum pam_modutil_redirect_fd mode, return fd; } -/* Check if path is in a procfs. */ -static int -is_in_procfs(int fd) -{ -#if defined HAVE_SYS_VFS_H && defined PROC_SUPER_MAGIC - struct statfs stfs; - - if (fstatfs(fd, &stfs) == 0) { - if (stfs.f_type == PROC_SUPER_MAGIC) - return 1; - } else { - return 0; - } -#endif /* HAVE_SYS_VFS_H && PROC_SUPER_MAGIC */ - - return -1; -} - /* Closes all descriptors after stderr. */ static void close_fds(void) { - DIR *dir = NULL; - struct dirent *dent; - int dfd = -1; - int fd; - struct rlimit rlim; - /* * An arbitrary upper limit for the maximum file descriptor number * returned by RLIMIT_NOFILE. */ - const unsigned int MAX_FD_NO = 65535; + const int MAX_FD_NO = 65535; /* The lower limit is the same as for _POSIX_OPEN_MAX. */ - const unsigned int MIN_FD_NO = 20; - - /* If /proc is mounted, we can optimize which fd can be closed. */ - if ((dir = opendir("/proc/self/fd")) != NULL) { - if ((dfd = dirfd(dir)) >= 0 && is_in_procfs(dfd) > 0) { - while ((dent = readdir(dir)) != NULL) { - fd = atoi(dent->d_name); - if (fd > STDERR_FILENO && fd != dfd) - close(fd); - } - } else { - dfd = -1; - } - closedir(dir); - } + const int MIN_FD_NO = 20; - /* If /proc isn't available, fallback to the previous behavior. */ - if (dfd < 0) { - if (getrlimit(RLIMIT_NOFILE, &rlim) || rlim.rlim_max > MAX_FD_NO) - fd = MAX_FD_NO; - else if (rlim.rlim_max < MIN_FD_NO) - fd = MIN_FD_NO; - else - fd = rlim.rlim_max - 1; - - for (; fd > STDERR_FILENO; --fd) - close(fd); - } + int fd; + struct rlimit rlim; + + if (getrlimit(RLIMIT_NOFILE, &rlim) || rlim.rlim_max > (rlim_t)MAX_FD_NO) + fd = MAX_FD_NO; + else if (rlim.rlim_max < (rlim_t)MIN_FD_NO) + fd = MIN_FD_NO; + else + fd = (int)rlim.rlim_max - 1; + + for (; fd > STDERR_FILENO; --fd) + close(fd); } int diff --git a/libpam/pam_start.c b/libpam/pam_start.c index 59d06224..99dd0389 100644 --- a/libpam/pam_start.c +++ b/libpam/pam_start.c @@ -115,6 +115,7 @@ static int _pam_start_internal ( pam_syslog(*pamh, LOG_CRIT, "pam_start: malloc failed for pam_conv"); _pam_drop((*pamh)->service_name); _pam_drop((*pamh)->user); + _pam_drop((*pamh)->confdir); _pam_drop(*pamh); return (PAM_BUF_ERR); } else { @@ -128,6 +129,7 @@ static int _pam_start_internal ( _pam_drop((*pamh)->pam_conversation); _pam_drop((*pamh)->service_name); _pam_drop((*pamh)->user); + _pam_drop((*pamh)->confdir); _pam_drop(*pamh); return PAM_ABORT; } @@ -145,6 +147,7 @@ static int _pam_start_internal ( _pam_drop((*pamh)->pam_conversation); _pam_drop((*pamh)->service_name); _pam_drop((*pamh)->user); + _pam_drop((*pamh)->confdir); _pam_drop(*pamh); return PAM_ABORT; } |