Rebased to release 1.4.0

Rebased to pam-redhat-1.1.3
Removed pam_cracklib as it has been deprecated
This commit is contained in:
ipedrosa 2020-06-24 16:28:29 +02:00
parent aea1c2fa66
commit aad6db4b92
36 changed files with 478 additions and 4020 deletions

2
.gitignore vendored
View File

@ -2,3 +2,5 @@
*.tar.bz2
/Linux-PAM-1.3.1.tar.xz
/Linux-PAM-1.3.1.tar.xz.asc
/Linux-PAM-1.4.0.tar.xz
/Linux-PAM-1.4.0.tar.xz.asc

View File

@ -1,27 +0,0 @@
diff -up pam/modules/pam_env/pam_env.c.nouserenv pam/modules/pam_env/pam_env.c
--- pam/modules/pam_env/pam_env.c.nouserenv 2010-10-20 09:59:30.000000000 +0200
+++ pam/modules/pam_env/pam_env.c 2010-11-01 14:42:01.000000000 +0100
@@ -10,7 +10,7 @@
#define DEFAULT_READ_ENVFILE 1
#define DEFAULT_USER_ENVFILE ".pam_environment"
-#define DEFAULT_USER_READ_ENVFILE 1
+#define DEFAULT_USER_READ_ENVFILE 0
#include "config.h"
diff -up pam/modules/pam_env/pam_env.8.xml.nouserenv pam/modules/pam_env/pam_env.8.xml
--- pam/modules/pam_env/pam_env.8.xml.nouserenv 2010-10-20 09:59:30.000000000 +0200
+++ pam/modules/pam_env/pam_env.8.xml 2010-11-01 14:42:01.000000000 +0100
@@ -147,7 +147,10 @@
<listitem>
<para>
Turns on or off the reading of the user specific environment
- file. 0 is off, 1 is on. By default this option is on.
+ file. 0 is off, 1 is on. By default this option is off as user
+ supplied environment variables in the PAM environment could affect
+ behavior of subsequent modules in the stack without the consent
+ of the system administrator.
</para>
</listitem>
</varlistentry>

View File

@ -1,126 +0,0 @@
From 0fa5f9d4184928c28689b673fb06bb8b4d88a0c2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Thu, 6 Feb 2020 12:41:15 +0100
Subject: [PATCH] pam_usertype: remove dependency on pam_modutil_search_key
This is needed to correctly backport the patch to this version.
---
modules/pam_usertype/pam_usertype.c | 88 ++++++++++++++++++++++++++++-
1 file changed, 87 insertions(+), 1 deletion(-)
diff --git a/modules/pam_usertype/pam_usertype.c b/modules/pam_usertype/pam_usertype.c
index d3629c137d98545871d24ff26c06d8377068141f..741956b05809d8d6247fe2eba82ae14427cfeae4 100644
--- a/modules/pam_usertype/pam_usertype.c
+++ b/modules/pam_usertype/pam_usertype.c
@@ -40,6 +40,7 @@
#include "config.h"
#include <sys/types.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
@@ -72,6 +73,91 @@ struct pam_usertype_opts {
int audit;
};
+/* taken from pam_umask.c and reformatted */
+static char *
+search_key (const char *filename,
+ const char *key)
+{
+ 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;
+}
+
static int
pam_usertype_parse_args(struct pam_usertype_opts *opts,
pam_handle_t *pamh,
@@ -170,7 +256,7 @@ pam_usertype_get_id(pam_handle_t *pamh,
char *ep;
uid_t uid;
- value = pam_modutil_search_key(pamh, LOGIN_DEFS, key);
+ value = search_key(LOGIN_DEFS, key);
if (value == NULL) {
return default_value;
}
--
2.24.1

View File

@ -1,684 +0,0 @@
From 88df4b5383b776b7b8ee9eb4c33231d54185b1e2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Fri, 10 Jan 2020 15:53:35 +0100
Subject: [PATCH] pam_usertype: new module to tell if uid is in login.defs
ranges
This module will check if the user account type is system or regular based
on its uid. To evaluate the condition it will use 0-99 reserved range
together with `SYS_UID_MIN` and `SYS_UID_MAX` values from `/etc/login.defs`.
If these values are not set, it uses configure-time defaults
`--with-sys-uid-min` and `--with-uid-min` (according to `login.defs` man page
`SYS_UID_MAX` defaults to `UID_MIN - 1`.
This information can be used to skip specific module in pam stack
based on the account type. `pam_succeed_if uid < 1000` is used at the moment
however it does not reflect changes to `login.defs`.
---
configure.ac | 22 ++
modules/Makefile.am | 2 +-
modules/pam_usertype/Makefile.am | 34 +++
modules/pam_usertype/README.xml | 41 +++
modules/pam_usertype/pam_usertype.8.xml | 170 +++++++++++++
modules/pam_usertype/pam_usertype.c | 319 ++++++++++++++++++++++++
modules/pam_usertype/tst-pam_usertype | 2 +
7 files changed, 589 insertions(+), 1 deletion(-)
create mode 100644 modules/pam_usertype/Makefile.am
create mode 100644 modules/pam_usertype/README.xml
create mode 100644 modules/pam_usertype/pam_usertype.8.xml
create mode 100644 modules/pam_usertype/pam_usertype.c
create mode 100755 modules/pam_usertype/tst-pam_usertype
diff --git a/configure.ac b/configure.ac
index 0267202d2f56cbb641ce74d283bc4ba2a4b3d0d9..f10a09e14c10639b91c356d6ef883da4a0a87a66 100644
--- a/configure.ac
+++ b/configure.ac
@@ -606,6 +606,27 @@ AC_SUBST([HAVE_KEY_MANAGEMENT], $HAVE_KEY_MANAGEMENT)
AM_CONDITIONAL([HAVE_KEY_MANAGEMENT], [test "$have_key_syscalls" = 1])
+dnl
+dnl Get values for default uid ranges in login.defs used in pam_usertype
+dnl
+AC_ARG_WITH([uidmin], AS_HELP_STRING([--with-uidmin=<number>],[default value for regular user min uid (1000)]), opt_uidmin=$withval)
+if test x"$opt_uidmin" == x; then
+ opt_uidmin=1000
+fi
+AC_DEFINE_UNQUOTED(PAM_USERTYPE_UIDMIN, $opt_uidmin, [Minimum regular user uid.])
+
+AC_ARG_WITH([sysuidmin], AS_HELP_STRING([--with-sysuidmin=<number>],[default value for system user min uid (101)]), opt_sysuidmin=$withval)
+if test x"$opt_sysuidmin" == x; then
+ opt_sysuidmin=101
+fi
+AC_DEFINE_UNQUOTED(PAM_USERTYPE_SYSUIDMIN, $opt_sysuidmin, [Minimum system user uid.])
+
+AC_ARG_WITH([kerneloverflowuid], AS_HELP_STRING([--with-kernel-overflow-uid=<number>],[kernel overflow uid, default (uint16_t)-2=65534]), opt_kerneloverflowuid=$withval)
+if test x"$opt_kerneloverflowuid" == x; then
+ opt_kerneloverflowuid=65534
+fi
+AC_DEFINE_UNQUOTED(PAM_USERTYPE_OVERFLOW_UID, $opt_kerneloverflowuid, [Kernel overflow uid.])
+
dnl Files to be created from when we run configure
AC_CONFIG_FILES([Makefile libpam/Makefile libpamc/Makefile libpamc/test/Makefile \
libpam_misc/Makefile conf/Makefile conf/pam_conv1/Makefile \
@@ -636,6 +657,7 @@ AC_CONFIG_FILES([Makefile libpam/Makefile libpamc/Makefile libpamc/test/Makefile
modules/pam_timestamp/Makefile modules/pam_tty_audit/Makefile \
modules/pam_umask/Makefile \
modules/pam_unix/Makefile modules/pam_userdb/Makefile \
+ modules/pam_usertype/Makefile \
modules/pam_warn/Makefile modules/pam_wheel/Makefile \
modules/pam_xauth/Makefile doc/Makefile doc/specs/Makefile \
doc/man/Makefile doc/sag/Makefile doc/adg/Makefile \
diff --git a/modules/Makefile.am b/modules/Makefile.am
index 5149181e2d1aeefbab8876433e8a54848ec56fc6..c1b5c5611c79e666bbd2f94fa0712a2b78bd2f5f 100644
--- a/modules/Makefile.am
+++ b/modules/Makefile.am
@@ -12,7 +12,7 @@ SUBDIRS = pam_access pam_cracklib pam_debug pam_deny pam_echo \
pam_selinux pam_sepermit pam_shells pam_stress \
pam_succeed_if pam_time pam_timestamp \
pam_tty_audit pam_umask \
- pam_unix pam_userdb pam_warn pam_wheel pam_xauth
+ pam_unix pam_userdb pam_usertype pam_warn pam_wheel pam_xauth
CLEANFILES = *~
diff --git a/modules/pam_usertype/Makefile.am b/modules/pam_usertype/Makefile.am
new file mode 100644
index 0000000000000000000000000000000000000000..1646bc34f2fbc44032af5a5b38d160614b247b72
--- /dev/null
+++ b/modules/pam_usertype/Makefile.am
@@ -0,0 +1,34 @@
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+# Copyright (c) 2020 Red Hat, Inc.
+#
+
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+
+EXTRA_DIST = README ${MANS} ${XMLS} tst-pam_usertype
+
+TESTS = tst-pam_usertype
+
+man_MANS = pam_usertype.8
+
+XMLS = README.xml pam_usertype.8.xml
+
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+AM_LDFLAGS = -no-undefined -avoid-version -module
+if HAVE_VERSIONING
+ AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+
+securelib_LTLIBRARIES = pam_usertype.la
+pam_usertype_la_LIBADD = $(top_builddir)/libpam/libpam.la
+
+if ENABLE_REGENERATE_MAN
+noinst_DATA = README
+README: pam_usertype.8.xml
+-include $(top_srcdir)/Make.xml.rules
+endif
diff --git a/modules/pam_usertype/README.xml b/modules/pam_usertype/README.xml
new file mode 100644
index 0000000000000000000000000000000000000000..58550465459222ace5e346c32b54cf6776eeeec5
--- /dev/null
+++ b/modules/pam_usertype/README.xml
@@ -0,0 +1,41 @@
+<?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_usertype.8.xml">
+-->
+]>
+
+<article>
+
+ <articleinfo>
+
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_usertype.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_usertype-name"]/*)'/>
+ </title>
+
+ </articleinfo>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_usertype.8.xml" xpointer='xpointer(//refsect1[@id = "pam_usertype-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_usertype.8.xml" xpointer='xpointer(//refsect1[@id = "pam_usertype-options"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_usertype.8.xml" xpointer='xpointer(//refsect1[@id = "pam_usertype-examples"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_usertype.8.xml" xpointer='xpointer(//refsect1[@id = "pam_usertype-author"]/*)'/>
+ </section>
+
+</article>
diff --git a/modules/pam_usertype/pam_usertype.8.xml b/modules/pam_usertype/pam_usertype.8.xml
new file mode 100644
index 0000000000000000000000000000000000000000..1ba4ee71dcd4faee1bf5293c718d1bdf823689f0
--- /dev/null
+++ b/modules/pam_usertype/pam_usertype.8.xml
@@ -0,0 +1,170 @@
+<?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_usertype'>
+ <refmeta>
+ <refentrytitle>pam_usertype</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class='sectdesc'>Linux-PAM</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id='pam_usertype-name'>
+ <refname>pam_usertype</refname>
+ <refpurpose>check if the authenticated user is a system or regular account</refpurpose>
+ </refnamediv>
+
+
+ <refsynopsisdiv>
+ <cmdsynopsis id='pam_usertype-cmdsynopsis'>
+ <command>pam_usertype.so</command>
+ <arg choice='opt' rep='repeat'><replaceable>flag</replaceable></arg>
+ <arg choice='req'><replaceable>condition</replaceable></arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+
+ <refsect1 id='pam_usertype-description'>
+ <title>DESCRIPTION</title>
+ <para>
+ pam_usertype.so is designed to succeed or fail authentication
+ based on type of the account of the authenticated user.
+ The type of the account is decided with help of
+ <emphasis>SYS_UID_MIN</emphasis> and <emphasis>SYS_UID_MAX</emphasis>
+ settings in <emphasis>/etc/login.defs</emphasis>. One use is to select
+ whether to load other modules based on this test.
+ </para>
+
+ <para>
+ The module should be given only one condition as module argument.
+ Authentication will succeed only if the condition is met.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_usertype-options">
+ <title>OPTIONS</title>
+ <para>
+ The following <emphasis>flag</emphasis>s are supported:
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term><option>use_uid</option></term>
+ <listitem>
+ <para>
+ Evaluate conditions using the account of the user whose UID
+ the application is running under instead of the user being
+ authenticated.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>audit</option></term>
+ <listitem>
+ <para>
+ Log unknown users to the system log.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ Available <emphasis>condition</emphasis>s are:
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term><option>issystem</option></term>
+ <listitem>
+ <para>Succeed if the user is a system user.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>isregular</option></term>
+ <listitem>
+ <para>Succeed if the user is a regular user.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="pam_usertype-types">
+ <title>MODULE TYPES PROVIDED</title>
+ <para>
+ All module types (<option>account</option>, <option>auth</option>,
+ <option>password</option> and <option>session</option>) are provided.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_usertype-return_values'>
+ <title>RETURN VALUES</title>
+ <variablelist>
+
+ <varlistentry>
+ <term>PAM_SUCCESS</term>
+ <listitem>
+ <para>
+ The condition was true.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_AUTH_ERR</term>
+ <listitem>
+ <para>
+ The condition was false.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_SERVICE_ERR</term>
+ <listitem>
+ <para>
+ A service error occurred or the arguments can't be
+ parsed correctly.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_USER_UNKNOWN</term>
+ <listitem>
+ <para>
+ User was not found.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+
+ <refsect1 id='pam_usertype-examples'>
+ <title>EXAMPLES</title>
+ <para>
+ Skip remaining modules if the user is a system user:
+ </para>
+ <programlisting>
+account sufficient pam_usertype.so issystem
+ </programlisting>
+ </refsect1>
+
+ <refsect1 id='pam_usertype-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>login.defs</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_usertype-author'>
+ <title>AUTHOR</title>
+ <para>Pavel Březina &lt;pbrezina@redhat.com&gt;</para>
+ </refsect1>
+</refentry>
diff --git a/modules/pam_usertype/pam_usertype.c b/modules/pam_usertype/pam_usertype.c
new file mode 100644
index 0000000000000000000000000000000000000000..d3629c137d98545871d24ff26c06d8377068141f
--- /dev/null
+++ b/modules/pam_usertype/pam_usertype.c
@@ -0,0 +1,319 @@
+/******************************************************************************
+ * Check user type based on login.defs.
+ *
+ * Copyright (c) 2020 Red Hat, Inc.
+ * Written by Pavel Březina <pbrezina@redhat.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <ctype.h>
+#include <errno.h>
+
+#define PAM_SM_AUTH
+#define PAM_SM_ACCOUNT
+#define PAM_SM_SESSION
+#define PAM_SM_PASSWORD
+
+#include <security/pam_modules.h>
+#include <security/pam_modutil.h>
+#include <security/pam_ext.h>
+
+#define LOGIN_DEFS "/etc/login.defs"
+
+enum pam_usertype_op {
+ OP_IS_SYSTEM,
+ OP_IS_REGULAR,
+
+ OP_SENTINEL
+};
+
+struct pam_usertype_opts {
+ enum pam_usertype_op op;
+ int use_uid;
+ int audit;
+};
+
+static int
+pam_usertype_parse_args(struct pam_usertype_opts *opts,
+ pam_handle_t *pamh,
+ int argc,
+ const char **argv)
+{
+ int i;
+
+ memset(opts, 0, sizeof(struct pam_usertype_opts));
+ opts->op = OP_SENTINEL;
+
+ for (i = 0; i < argc; i++) {
+ if (strcmp(argv[i], "use_uid") == 0) {
+ opts->use_uid = 1;
+ } else if (strcmp(argv[i], "audit") == 0) {
+ opts->audit = 1;
+ } else if (strcmp(argv[i], "issystem") == 0) {
+ opts->op = OP_IS_SYSTEM;
+ } else if (strcmp(argv[i], "isregular") == 0) {
+ opts->op = OP_IS_REGULAR;
+ } else {
+ pam_syslog(pamh, LOG_WARNING, "Unknown argument: %s", argv[i]);
+ /* Just continue. */
+ }
+ }
+
+ if (opts->op == OP_SENTINEL) {
+ pam_syslog(pamh, LOG_ERR, "Operation not specified");
+ return PAM_SERVICE_ERR;
+ }
+
+ return PAM_SUCCESS;
+}
+
+static int
+pam_usertype_get_uid(struct pam_usertype_opts *opts,
+ pam_handle_t *pamh,
+ uid_t *_uid)
+{
+ struct passwd *pwd;
+ const void *prompt;
+ const char *username;
+ int ret;
+
+ /* Get uid of user that runs the application. */
+ if (opts->use_uid) {
+ pwd = pam_modutil_getpwuid(pamh, getuid());
+ if (pwd == NULL) {
+ pam_syslog(pamh, LOG_ERR,
+ "error retrieving information about user %lu",
+ (unsigned long)getuid());
+ return PAM_USER_UNKNOWN;
+ }
+
+ *_uid = pwd->pw_uid;
+ return PAM_SUCCESS;
+ }
+
+ /* Get uid of user that is being authenticated. */
+ ret = pam_get_item(pamh, PAM_USER_PROMPT, &prompt);
+ if (ret != PAM_SUCCESS || prompt == NULL || strlen(prompt) == 0) {
+ prompt = "login: ";
+ }
+
+ ret = pam_get_user(pamh, &username, prompt);
+ if (ret != PAM_SUCCESS || username == NULL) {
+ pam_syslog(pamh, LOG_ERR, "error retrieving user name: %s",
+ pam_strerror(pamh, ret));
+ return ret;
+ }
+
+ pwd = pam_modutil_getpwnam(pamh, username);
+ if (pwd == NULL) {
+ if (opts->audit) {
+ pam_syslog(pamh, LOG_NOTICE,
+ "error retrieving information about user %s", username);
+ }
+
+ return PAM_USER_UNKNOWN;
+ }
+
+ *_uid = pwd->pw_uid;
+
+ return PAM_SUCCESS;
+}
+
+#define MAX_UID_VALUE 0xFFFFFFFFUL
+
+static uid_t
+pam_usertype_get_id(pam_handle_t *pamh,
+ const char *key,
+ uid_t default_value)
+{
+ unsigned long ul;
+ char *value;
+ char *ep;
+ uid_t uid;
+
+ value = pam_modutil_search_key(pamh, LOGIN_DEFS, key);
+ if (value == NULL) {
+ return default_value;
+ }
+
+ /* taken from get_lastlog_uid_max() */
+ ep = value + strlen(value);
+ while (ep > value && isspace(*(--ep))) {
+ *ep = '\0';
+ }
+
+ errno = 0;
+ ul = strtoul(value, &ep, 10);
+ if (!(ul >= MAX_UID_VALUE
+ || (uid_t)ul >= MAX_UID_VALUE
+ || (errno != 0 && ul == 0)
+ || value == ep
+ || *ep != '\0')) {
+ uid = (uid_t)ul;
+ } else {
+ uid = default_value;
+ }
+
+ free(value);
+
+ return uid;
+}
+
+static int
+pam_usertype_is_system(pam_handle_t *pamh, uid_t uid)
+{
+ uid_t uid_min;
+ uid_t sys_min;
+ uid_t sys_max;
+
+ if (uid == (uid_t)-1) {
+ pam_syslog(pamh, LOG_WARNING, "invalid uid");
+ return PAM_USER_UNKNOWN;
+ }
+
+ if (uid <= 99) {
+ /* Reserved. */
+ return PAM_SUCCESS;
+ }
+
+ if (uid == PAM_USERTYPE_OVERFLOW_UID) {
+ /* nobody */
+ return PAM_SUCCESS;
+ }
+
+ uid_min = pam_usertype_get_id(pamh, "UID_MIN", PAM_USERTYPE_UIDMIN);
+ sys_min = pam_usertype_get_id(pamh, "SYS_UID_MIN", PAM_USERTYPE_SYSUIDMIN);
+ sys_max = pam_usertype_get_id(pamh, "SYS_UID_MAX", uid_min - 1);
+
+ return uid >= sys_min && uid <= sys_max ? PAM_SUCCESS : PAM_AUTH_ERR;
+}
+
+static int
+pam_usertype_is_regular(pam_handle_t *pamh, uid_t uid)
+{
+ int ret;
+
+ ret = pam_usertype_is_system(pamh, uid);
+ switch (ret) {
+ case PAM_SUCCESS:
+ return PAM_AUTH_ERR;
+ case PAM_USER_UNKNOWN:
+ return PAM_USER_UNKNOWN;
+ default:
+ return PAM_SUCCESS;
+ }
+}
+
+static int
+pam_usertype_evaluate(struct pam_usertype_opts *opts,
+ pam_handle_t *pamh,
+ uid_t uid)
+{
+ switch (opts->op) {
+ case OP_IS_SYSTEM:
+ return pam_usertype_is_system(pamh, uid);
+ case OP_IS_REGULAR:
+ return pam_usertype_is_regular(pamh, uid);
+ default:
+ pam_syslog(pamh, LOG_ERR, "Unknown operation: %d", opts->op);
+ return PAM_SERVICE_ERR;
+ }
+}
+
+/**
+ * Arguments:
+ * - issystem: uid in <SYS_UID_MIN, SYS_UID_MAX>
+ * - isregular: not issystem
+ * - use_uid: use user that runs application not that is being authenticate (same as in pam_succeed_if)
+ * - audit: log unknown users to syslog
+ */
+int
+pam_sm_authenticate(pam_handle_t *pamh, int flags UNUSED,
+ int argc, const char **argv)
+{
+ struct pam_usertype_opts opts;
+ uid_t uid;
+ int ret;
+
+ ret = pam_usertype_parse_args(&opts, pamh, argc, argv);
+ if (ret != PAM_SUCCESS) {
+ return ret;
+ }
+
+ ret = pam_usertype_get_uid(&opts, pamh, &uid);
+ if (ret != PAM_SUCCESS) {
+ return ret;
+ }
+
+ return pam_usertype_evaluate(&opts, pamh, uid);
+}
+
+int
+pam_sm_setcred(pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ return PAM_IGNORE;
+}
+
+int
+pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ return pam_sm_authenticate(pamh, flags, argc, argv);
+}
+
+int
+pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ return pam_sm_authenticate(pamh, flags, argc, argv);
+}
+
+int
+pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ return pam_sm_authenticate(pamh, flags, argc, argv);
+}
+
+int
+pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ return pam_sm_authenticate(pamh, flags, argc, argv);
+}
diff --git a/modules/pam_usertype/tst-pam_usertype b/modules/pam_usertype/tst-pam_usertype
new file mode 100755
index 0000000000000000000000000000000000000000..a21f8fe7cef3daf6a842bc35972976ee189d3570
--- /dev/null
+++ b/modules/pam_usertype/tst-pam_usertype
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_usertype.so
--
2.24.1

View File

@ -1,35 +0,0 @@
From b429ea18b1c9c8953df5169c6a453b4255a6f23d Mon Sep 17 00:00:00 2001
From: Iker Pedrosa <ikerpedrosam@gmail.com>
Date: Thu, 27 Feb 2020 11:48:47 +0100
Subject: [PATCH] pam_tty_audit: if kernel audit is disabled return PAM_IGNORE
If kernel audit is disabled the socket open will return
EPROTONOSUPPORT.
Return PAM_IGNORE from pam_tty_audit and log a warning
in this situation so login is not blocked by the module.
---
modules/pam_tty_audit/pam_tty_audit.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/modules/pam_tty_audit/pam_tty_audit.c b/modules/pam_tty_audit/pam_tty_audit.c
index 7dbcada2..589c60a2 100644
--- a/modules/pam_tty_audit/pam_tty_audit.c
+++ b/modules/pam_tty_audit/pam_tty_audit.c
@@ -351,6 +351,14 @@ pam_sm_open_session (pam_handle_t *pamh, int flags, int argc, const char **argv)
fd = nl_open ();
if (fd == -1
+ && errno == EPROTONOSUPPORT)
+ {
+ pam_syslog (pamh, LOG_WARNING, "unable to open audit socket, audit not "
+ "supported; tty_audit skipped");
+ free (old_status);
+ return PAM_IGNORE;
+ }
+ else if (fd == -1
|| nl_send (fd, AUDIT_TTY_GET, 0, NULL, 0) != 0
|| nl_recv (fd, AUDIT_TTY_GET, old_status, sizeof (*old_status)) != 0)
{
--
2.25.2

View File

@ -1,88 +0,0 @@
From 27d04a849fd9f9cfd4b35eb80d687817830183df Mon Sep 17 00:00:00 2001
From: Tomas Mraz <tmraz@fedoraproject.org>
Date: Wed, 7 Aug 2019 12:22:55 +0200
Subject: [PATCH] pam_get_authtok_verify: Avoid duplicate password verification
If password was already verified by previous modules in the stack
it does not need to be verified by pam_get_authtok_verify either.
* libpam/pam_get_authtok.c (pam_get_authtok_internal): Set the authtok_verified
appropriately.
(pam_get_authtok_verify): Do not prompt if authtok_verified is set and
set it when the password is verified.
* libpam/pam_private.h: Add authtok_verified to the pam handle struct.
* libpam/pam_start.c (pam_start): Initialize authtok_verified.
---
libpam/pam_get_authtok.c | 10 ++++++++++
libpam/pam_private.h | 1 +
libpam/pam_start.c | 1 +
3 files changed, 12 insertions(+)
diff --git a/libpam/pam_get_authtok.c b/libpam/pam_get_authtok.c
index 800c6e5..99eb25f 100644
--- a/libpam/pam_get_authtok.c
+++ b/libpam/pam_get_authtok.c
@@ -140,6 +140,8 @@ pam_get_authtok_internal (pam_handle_t *pamh, int item,
}
else if (chpass)
{
+ pamh->authtok_verified = 0;
+
retval = pam_prompt (pamh, PAM_PROMPT_ECHO_OFF, &resp[0],
PROMPT1, authtok_type,
strlen (authtok_type) > 0?" ":"");
@@ -184,6 +186,9 @@ pam_get_authtok_internal (pam_handle_t *pamh, int item,
if (retval != PAM_SUCCESS)
return retval;
+ if (chpass > 1)
+ pamh->authtok_verified = 1;
+
return pam_get_item(pamh, item, (const void **)authtok);
}
@@ -214,6 +219,9 @@ pam_get_authtok_verify (pam_handle_t *pamh, const char **authtok,
if (authtok == NULL || pamh->choice != PAM_CHAUTHTOK)
return PAM_SYSTEM_ERR;
+ if (pamh->authtok_verified)
+ return pam_get_item (pamh, PAM_AUTHTOK, (const void **)authtok);
+
if (prompt != NULL)
{
retval = pam_prompt (pamh, PAM_PROMPT_ECHO_OFF, &resp,
@@ -252,5 +260,7 @@ pam_get_authtok_verify (pam_handle_t *pamh, const char **authtok,
if (retval != PAM_SUCCESS)
return retval;
+ pamh->authtok_verified = 1;
+
return pam_get_item(pamh, PAM_AUTHTOK, (const void **)authtok);
}
diff --git a/libpam/pam_private.h b/libpam/pam_private.h
index 7ff9f75..58a26f5 100644
--- a/libpam/pam_private.h
+++ b/libpam/pam_private.h
@@ -172,6 +172,7 @@ struct pam_handle {
#ifdef HAVE_LIBAUDIT
int audit_state; /* keep track of reported audit messages */
#endif
+ int authtok_verified;
};
/* Values for select arg to _pam_dispatch() */
diff --git a/libpam/pam_start.c b/libpam/pam_start.c
index 328416d..e27c64b 100644
--- a/libpam/pam_start.c
+++ b/libpam/pam_start.c
@@ -94,6 +94,7 @@ int pam_start (
#endif
(*pamh)->xdisplay = NULL;
(*pamh)->authtok_type = NULL;
+ (*pamh)->authtok_verified = 0;
memset (&((*pamh)->xauth), 0, sizeof ((*pamh)->xauth));
if (((*pamh)->pam_conversation = (struct pam_conv *)
--
2.20.1

View File

@ -1,185 +0,0 @@
diff --git a/libpam/pam_handlers.c b/libpam/pam_handlers.c
index 106ef7c..b2e94c7 100644
--- a/libpam/pam_handlers.c
+++ b/libpam/pam_handlers.c
@@ -282,7 +282,6 @@ _pam_open_config_file(pam_handle_t *pamh
{
char *p;
FILE *f;
- int err = 0;
/* Absolute path */
if (service[0] == '/') {
diff --git a/libpam_misc/misc_conv.c b/libpam_misc/misc_conv.c
index be53f34..07dce36 100644
--- a/libpam_misc/misc_conv.c
+++ b/libpam_misc/misc_conv.c
@@ -211,7 +211,7 @@ static int read_string(int echo, const char *prompt, char **retstr)
line[nc] = '\0';
}
*retstr = strdup(line);
- _pam_overwrite(line);
+ _pam_overwrite_n(line, sizeof(line));
if (!*retstr) {
D(("no memory for response string"));
nc = -1;
@@ -244,7 +244,7 @@ static int read_string(int echo, const char *prompt, char **retstr)
D(("the timer appears to have expired"));
*retstr = NULL;
- _pam_overwrite(line);
+ _pam_overwrite_n(line, sizeof(line));
cleanexit:
diff --git a/modules/pam_access/pam_access.c b/modules/pam_access/pam_access.c
index 80d885d..3801862 100644
--- a/modules/pam_access/pam_access.c
+++ b/modules/pam_access/pam_access.c
@@ -806,7 +806,7 @@ pam_sm_authenticate (pam_handle_t *pamh, int flags UNUSED,
const char *user=NULL;
const void *void_from=NULL;
const char *from;
- const char const *default_config = PAM_ACCESS_CONFIG;
+ const char * const default_config = PAM_ACCESS_CONFIG;
struct passwd *user_pw;
char hostname[MAXHOSTNAMELEN + 1];
int rv;
diff --git a/modules/pam_limits/pam_limits.c b/modules/pam_limits/pam_limits.c
index 4bc4ae7..f8476b4 100644
--- a/modules/pam_limits/pam_limits.c
+++ b/modules/pam_limits/pam_limits.c
@@ -342,7 +342,7 @@ static const char *lnames[RLIM_NLIMITS] = {
#endif
};
-static int str2rlimit(char *name) {
+static int str2rlimit(const char *name) {
int i;
if (!name || *name == '\0')
return -1;
@@ -352,7 +352,7 @@ static int str2rlimit(char *name) {
return -1;
}
-static rlim_t str2rlim_t(char *value) {
+static rlim_t str2rlim_t(const char *value) {
unsigned long long rlimit = 0;
if (!value) return (rlim_t)rlimit;
@@ -384,7 +384,7 @@ static void parse_kernel_limits(pam_handle_t *pamh, struct pam_limit_s *pl, int
FILE *limitsfile;
const char *proclimits = "/proc/1/limits";
char line[256];
- char *units, *hard, *soft, *name;
+ const char *units, *hard, *soft, *name;
if (!(limitsfile = fopen(proclimits, "r"))) {
pam_syslog(pamh, LOG_WARNING, "Could not read %s (%s), using PAM defaults", proclimits, strerror(errno));
diff --git a/modules/pam_loginuid/pam_loginuid.c b/modules/pam_loginuid/pam_loginuid.c
index 96bfd98..66d202c 100644
--- a/modules/pam_loginuid/pam_loginuid.c
+++ b/modules/pam_loginuid/pam_loginuid.c
@@ -64,7 +64,7 @@ static int set_loginuid(pam_handle_t *pamh, uid_t uid)
fd = open("/proc/self/uid_map", O_RDONLY);
if (fd >= 0) {
count = pam_modutil_read(fd, uid_map, sizeof(uid_map));
- if (strncmp(uid_map, host_uid_map, count) != 0)
+ if (count <= 0 || strncmp(uid_map, host_uid_map, count) != 0)
rc = PAM_IGNORE;
close(fd);
}
diff --git a/modules/pam_mkhomedir/mkhomedir_helper.c b/modules/pam_mkhomedir/mkhomedir_helper.c
index 9e204c1..4b8d6b7 100644
--- a/modules/pam_mkhomedir/mkhomedir_helper.c
+++ b/modules/pam_mkhomedir/mkhomedir_helper.c
@@ -232,6 +232,8 @@ create_homedir(const struct passwd *pwd,
{
pam_syslog(NULL, LOG_DEBUG,
"unable to open or stat src file %s: %m", newsource);
+ if (srcfd >= 0)
+ close(srcfd);
closedir(d);
#ifndef PATH_MAX
diff --git a/modules/pam_namespace/pam_namespace.c b/modules/pam_namespace/pam_namespace.c
index f541f89..85f5efa 100644
--- a/modules/pam_namespace/pam_namespace.c
+++ b/modules/pam_namespace/pam_namespace.c
@@ -1418,6 +1418,7 @@ static int create_instance(struct polydir_s *polyptr, char *ipath, struct stat *
if (fstat(fd, &newstatbuf) < 0) {
pam_syslog(idata->pamh, LOG_ERR, "Error stating %s, %m",
ipath);
+ close(fd);
rmdir(ipath);
return PAM_SESSION_ERR;
}
diff --git a/modules/pam_pwhistory/opasswd.c b/modules/pam_pwhistory/opasswd.c
index e6cf346..813f579 100644
--- a/modules/pam_pwhistory/opasswd.c
+++ b/modules/pam_pwhistory/opasswd.c
@@ -326,6 +326,9 @@ save_old_pass (pam_handle_t *pamh, const char *user, uid_t uid,
n = strlen (buf);
#endif /* HAVE_GETLINE / HAVE_GETDELIM */
+ if (n < 1)
+ break;
+
cp = buf;
save = strdup (buf); /* Copy to write the original data back. */
if (save == NULL)
@@ -336,9 +339,6 @@ save_old_pass (pam_handle_t *pamh, const char *user, uid_t uid,
goto error_opasswd;
}
- if (n < 1)
- break;
-
tmp = strchr (cp, '#'); /* remove comments */
if (tmp)
*tmp = '\0';
diff --git a/modules/pam_rootok/pam_rootok.c b/modules/pam_rootok/pam_rootok.c
index 17baabe..a9d9140 100644
--- a/modules/pam_rootok/pam_rootok.c
+++ b/modules/pam_rootok/pam_rootok.c
@@ -66,14 +66,17 @@ log_callback (int type, const char *fmt, ...)
int audit_fd;
va_list ap;
- va_start(ap, fmt);
#ifdef HAVE_LIBAUDIT
audit_fd = audit_open();
if (audit_fd >= 0) {
char *buf;
+ int ret;
- if (vasprintf (&buf, fmt, ap) < 0)
+ va_start(ap, fmt);
+ ret = vasprintf (&buf, fmt, ap);
+ va_end(ap);
+ if (ret < 0)
return 0;
audit_log_user_avc_message(audit_fd, AUDIT_USER_AVC, buf, NULL, NULL,
NULL, 0);
@@ -83,6 +86,7 @@ log_callback (int type, const char *fmt, ...)
}
#endif
+ va_start(ap, fmt);
vsyslog (LOG_USER | LOG_INFO, fmt, ap);
va_end(ap);
return 0;
diff --git a/modules/pam_sepermit/pam_sepermit.c b/modules/pam_sepermit/pam_sepermit.c
index c653290..f37af0f 100644
--- a/modules/pam_sepermit/pam_sepermit.c
+++ b/modules/pam_sepermit/pam_sepermit.c
@@ -353,7 +353,7 @@ sepermit_match(pam_handle_t *pamh, const char *cfgfile, const char *user,
if (*sense == PAM_SUCCESS) {
if (ignore)
*sense = PAM_IGNORE;
- if (geteuid() == 0 && exclusive && get_loginuid(pamh) == -1)
+ if (geteuid() == 0 && exclusive && get_loginuid(pamh) == (uid_t)-1)
if (sepermit_lock(pamh, user, debug) < 0)
*sense = PAM_AUTH_ERR;
}

View File

@ -1,82 +0,0 @@
diff -up Linux-PAM-1.3.1/modules/pam_unix/passverify.c.determinine-user-exists Linux-PAM-1.3.1/modules/pam_unix/passverify.c
--- Linux-PAM-1.3.1/modules/pam_unix/passverify.c.determinine-user-exists 2020-06-17 15:34:08.089162532 +0200
+++ Linux-PAM-1.3.1/modules/pam_unix/passverify.c 2020-06-17 15:36:13.233294407 +0200
@@ -1087,6 +1087,12 @@ helper_verify_password(const char *name,
if (pwd == NULL || salt == NULL) {
helper_log_err(LOG_NOTICE, "check pass; user unknown");
retval = PAM_USER_UNKNOWN;
+ } else if (p[0] == '\0' && nullok) {
+ if (salt[0] == '\0') {
+ retval = PAM_SUCCESS;
+ } else {
+ retval = PAM_AUTH_ERR;
+ }
} else {
retval = verify_pwd_hash(p, salt, nullok);
}
diff -up Linux-PAM-1.3.1/modules/pam_unix/support.c.determinine-user-exists Linux-PAM-1.3.1/modules/pam_unix/support.c
--- Linux-PAM-1.3.1/modules/pam_unix/support.c.determinine-user-exists 2020-06-17 15:34:08.090162549 +0200
+++ Linux-PAM-1.3.1/modules/pam_unix/support.c 2020-06-17 15:34:08.101162736 +0200
@@ -672,6 +672,8 @@ _unix_blankpasswd (pam_handle_t *pamh, u
struct passwd *pwd = NULL;
char *salt = NULL;
int retval;
+ int execloop = 1;
+ int nonexistent = 1;
D(("called"));
@@ -686,14 +688,31 @@ _unix_blankpasswd (pam_handle_t *pamh, u
/* UNIX passwords area */
- retval = get_pwd_hash(pamh, name, &pwd, &salt);
+ /*
+ * 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.
+ */
+ while (execloop) {
+ 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;
+ if (retval == PAM_UNIX_RUN_HELPER) {
+ execloop = 0;
+ if(nonexistent) {
+ get_pwd_hash(pamh, "pam_unix_non_existent:", &pwd, &salt);
+ }
+ /* 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;
+ } else if (retval == PAM_USER_UNKNOWN) {
+ name = "root";
+ nonexistent = 0;
+ } else {
+ execloop = 0;
+ }
}
/* Does this user have a password? */
diff -up Linux-PAM-1.3.1/modules/pam_usertype/pam_usertype.c.determinine-user-exists Linux-PAM-1.3.1/modules/pam_usertype/pam_usertype.c
--- Linux-PAM-1.3.1/modules/pam_usertype/pam_usertype.c.determinine-user-exists 2020-06-17 15:34:08.098162685 +0200
+++ Linux-PAM-1.3.1/modules/pam_usertype/pam_usertype.c 2020-06-17 15:34:08.101162736 +0200
@@ -236,8 +236,11 @@ pam_usertype_get_uid(struct pam_usertype
"error retrieving information about user %s", username);
}
+ pam_modutil_getpwnam(pamh, "root");
+
return PAM_USER_UNKNOWN;
}
+ pam_modutil_getpwnam(pamh, "pam_usertype_non_existent:");
*_uid = pwd->pw_uid;

View File

@ -1,70 +0,0 @@
diff -up Linux-PAM-1.3.1/libpam/pam_modutil_sanitize.c.fds-closing Linux-PAM-1.3.1/libpam/pam_modutil_sanitize.c
--- Linux-PAM-1.3.1/libpam/pam_modutil_sanitize.c.fds-closing 2017-02-10 11:10:15.000000000 +0100
+++ Linux-PAM-1.3.1/libpam/pam_modutil_sanitize.c 2019-10-16 16:07:31.259021159 +0200
@@ -10,6 +10,7 @@
#include <fcntl.h>
#include <syslog.h>
#include <sys/resource.h>
+#include <dirent.h>
/*
* Creates a pipe, closes its write end, redirects fd to its read end.
@@ -116,27 +117,45 @@ redirect_out(pam_handle_t *pamh, enum pa
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 int MAX_FD_NO = 65535;
+ const unsigned int MAX_FD_NO = 65535;
/* The lower limit is the same as for _POSIX_OPEN_MAX. */
- const int MIN_FD_NO = 20;
+ const unsigned int MIN_FD_NO = 20;
- int fd;
- struct rlimit rlim;
-
- 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;
+ /* If /proc is mounted, we can optimize which fd can be closed. */
+ if ((dir = opendir("/proc/self/fd")) != NULL) {
+ if ((dfd = dirfd(dir)) >= 0) {
+ while ((dent = readdir(dir)) != NULL) {
+ fd = atoi(dent->d_name);
+ if (fd > STDERR_FILENO && fd != dfd)
+ close(fd);
+ }
+ }
+ closedir(dir);
+ }
+
+ /* 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);
+ for (; fd > STDERR_FILENO; --fd)
+ close(fd);
+ }
}
int

View File

@ -1,82 +0,0 @@
From c426914fa166ffb0482b6f6ad659ddf17d5dfaa1 Mon Sep 17 00:00:00 2001
From: Nir Soffer <nsoffer@redhat.com>
Date: Wed, 9 Jan 2019 23:41:16 +0200
Subject: [PATCH] pam_lastlog: Improve silent option documentation
The silent option explicitly silents only the last login message and not
bad logins. Add a note to the manual to make this clear.
* modules/pam_lastlog/pam_lastlog.8.xml: Clearify "silent showfailed"
---
modules/pam_lastlog/pam_lastlog.8.xml | 1 +
1 file changed, 1 insertion(+)
diff --git a/modules/pam_lastlog/pam_lastlog.8.xml b/modules/pam_lastlog/pam_lastlog.8.xml
index c8f247e..bc2e1be 100644
--- a/modules/pam_lastlog/pam_lastlog.8.xml
+++ b/modules/pam_lastlog/pam_lastlog.8.xml
@@ -102,6 +102,7 @@
<para>
Don't inform the user about any previous login,
just update the <filename>/var/log/lastlog</filename> file.
+ This option does not affect display of bad login attempts.
</para>
</listitem>
</varlistentry>
--
2.20.1
From 7d036249a9772c546ede1f38ad68b3f1575216d6 Mon Sep 17 00:00:00 2001
From: Nir Soffer <nsoffer@redhat.com>
Date: Sun, 6 Jan 2019 00:36:27 +0200
Subject: [PATCH] pam_lastlog: Respect PAM_SILENT flag
pam_lastlog module will not log info about failed login if the session
was opened with PAM_SILENT flag.
Example use case enabled by this change:
sudo --non-interactive program
If this command is run by another program expecting specific output from
the command run by sudo, the unexpected info about failed logins will
break this program.
* modules/pam_lastlog/pam_lastlog.c: Respect silent option.
(_pam_session_parse): Unset LASTLOG_BTMP if PAM_SILENT is set.
---
modules/pam_lastlog/pam_lastlog.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/modules/pam_lastlog/pam_lastlog.c b/modules/pam_lastlog/pam_lastlog.c
index 18bf7be..e980c04 100644
--- a/modules/pam_lastlog/pam_lastlog.c
+++ b/modules/pam_lastlog/pam_lastlog.c
@@ -135,11 +135,6 @@ _pam_session_parse(pam_handle_t *pamh, int flags, int argc, const char **argv)
{
int ctrl=(LASTLOG_DATE|LASTLOG_HOST|LASTLOG_LINE|LASTLOG_WTMP|LASTLOG_UPDATE);
- /* does the appliction require quiet? */
- if (flags & PAM_SILENT) {
- ctrl |= LASTLOG_QUIET;
- }
-
/* step through arguments */
for (; argc-- > 0; ++argv) {
@@ -168,6 +163,12 @@ _pam_session_parse(pam_handle_t *pamh, int flags, int argc, const char **argv)
}
}
+ /* does the appliction require quiet? */
+ if (flags & PAM_SILENT) {
+ ctrl |= LASTLOG_QUIET;
+ ctrl &= ~LASTLOG_BTMP;
+ }
+
D(("ctrl = %o", ctrl));
return ctrl;
}
--
2.20.1

View File

@ -1,227 +0,0 @@
From 3a3e70739834cd5cbd17469907ef718c81ae40c0 Mon Sep 17 00:00:00 2001
From: Carlos Santos <casantos@redhat.com>
Date: Wed, 11 Sep 2019 11:50:28 -0300
Subject: [PATCH] pam_lastlog: document the 'unlimited' option
Signed-off-by: Carlos Santos <casantos@redhat.com>
---
modules/pam_lastlog/pam_lastlog.8.xml | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/modules/pam_lastlog/pam_lastlog.8.xml b/modules/pam_lastlog/pam_lastlog.8.xml
index bc2e1be..f10e94a 100644
--- a/modules/pam_lastlog/pam_lastlog.8.xml
+++ b/modules/pam_lastlog/pam_lastlog.8.xml
@@ -48,6 +48,9 @@
<arg choice="opt">
inactive=&lt;days&gt;
</arg>
+ <arg choice="opt">
+ unlimited
+ </arg>
</cmdsynopsis>
</refsynopsisdiv>
@@ -196,6 +199,18 @@
</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term>
+ <option>unlimited</option>
+ </term>
+ <listitem>
+ <para>
+ If the <emphasis>fsize</emphasis> limit is set, this option can be
+ used to override it, preventing failures on systems with large UID
+ values that lead lastlog to become a huge sparse file.
+ </para>
+ </listitem>
+ </varlistentry>
</variablelist>
</refsect1>
@@ -300,6 +315,9 @@
<refsect1 id='pam_lastlog-see_also'>
<title>SEE ALSO</title>
<para>
+ <citerefentry>
+ <refentrytitle>limits.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
<citerefentry>
<refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
</citerefentry>,
--
2.20.1
From 9349333a9ae958205294cd25e97fd6b4805bd82b Mon Sep 17 00:00:00 2001
From: Carlos Santos <casantos@redhat.com>
Date: Tue, 10 Sep 2019 23:08:30 -0300
Subject: [PATCH] pam_lastlog: prevent crash due to reduced 'fsize' limit
It a reduced fsize limit is set in /etc/security/limits.conf and
pam_limits is in use pam_lastlog may cause a crash, e.g.
----- begin /etc/pam.d/su ----
auth sufficient pam_rootok.so
auth required pam_wheel.so use_uid
auth required pam_env.so
auth required pam_unix.so nullok
account required pam_unix.so
password required pam_unix.so nullok
session required pam_limits.so
session required pam_env.so
session required pam_unix.so
session optional pam_lastlog.so
----- end /etc/pam.d/su -----
----- begin /etc/security/limits.d/fsize.conf -----
* soft fsize 1710
* hard fsize 1710
----- end /etc/security/limits.d/fsize.conf -----
# id user1
uid=1000(user1) gid=1000(user1) groups=1000(user1)
# su - user1
Last login: Wed Sep 11 01:52:44 UTC 2019 on console
$ exit
# id user2
uid=60000(user2) gid=60000(user2) groups=60000(user2)
# su - user2
File size limit exceeded
This happens because pam_limits sets RLIMIT_FSIZE before pam_lastlog
attempts to write /var/log/lastlog, leading to a SIGXFSZ signal.
In order to fix this, and an 'unlimited' option, which leads to saving
the 'fsize' limit and set it to unlimited before writing lastlog. After
that, restore the saved value. If 'fsize' is already unlimited nothing
is done.
Failing to set the 'fsize' limit is not a fatal error. With luck the
configured limit will suffice, so we try to write lastlog anyway, even
under the risk of dying due to a SIGXFSZ.
Failing to restore the 'fsize' limit is a fatal error, since we don't
want to keep it unlimited.
Signed-off-by: Carlos Santos <casantos@redhat.com>
---
modules/pam_lastlog/pam_lastlog.c | 66 ++++++++++++++++++++++++++-----
1 file changed, 57 insertions(+), 9 deletions(-)
diff --git a/modules/pam_lastlog/pam_lastlog.c b/modules/pam_lastlog/pam_lastlog.c
index e980c04..a135c9f 100644
--- a/modules/pam_lastlog/pam_lastlog.c
+++ b/modules/pam_lastlog/pam_lastlog.c
@@ -25,6 +25,8 @@
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/resource.h>
#include <syslog.h>
#include <unistd.h>
@@ -82,15 +84,16 @@ struct lastlog {
/* argument parsing */
-#define LASTLOG_DATE 01 /* display the date of the last login */
-#define LASTLOG_HOST 02 /* display the last host used (if set) */
-#define LASTLOG_LINE 04 /* display the last terminal used */
-#define LASTLOG_NEVER 010 /* display a welcome message for first login */
-#define LASTLOG_DEBUG 020 /* send info to syslog(3) */
-#define LASTLOG_QUIET 040 /* keep quiet about things */
-#define LASTLOG_WTMP 0100 /* log to wtmp as well as lastlog */
-#define LASTLOG_BTMP 0200 /* display failed login info from btmp */
-#define LASTLOG_UPDATE 0400 /* update the lastlog and wtmp files (default) */
+#define LASTLOG_DATE 01 /* display the date of the last login */
+#define LASTLOG_HOST 02 /* display the last host used (if set) */
+#define LASTLOG_LINE 04 /* display the last terminal used */
+#define LASTLOG_NEVER 010 /* display a welcome message for first login */
+#define LASTLOG_DEBUG 020 /* send info to syslog(3) */
+#define LASTLOG_QUIET 040 /* keep quiet about things */
+#define LASTLOG_WTMP 0100 /* log to wtmp as well as lastlog */
+#define LASTLOG_BTMP 0200 /* display failed login info from btmp */
+#define LASTLOG_UPDATE 0400 /* update the lastlog and wtmp files (default) */
+#define LASTLOG_UNLIMITED 01000 /* unlimited file size (ignore 'fsize' limit) */
static int
_pam_auth_parse(pam_handle_t *pamh, int flags, int argc, const char **argv,
@@ -158,6 +161,8 @@ _pam_session_parse(pam_handle_t *pamh, int flags, int argc, const char **argv)
ctrl &= ~(LASTLOG_WTMP|LASTLOG_UPDATE);
} else if (!strcmp(*argv,"showfailed")) {
ctrl |= LASTLOG_BTMP;
+ } else if (!strcmp(*argv,"unlimited")) {
+ ctrl |= LASTLOG_UNLIMITED;
} else {
pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv);
}
@@ -373,6 +378,12 @@ static int
last_login_write(pam_handle_t *pamh, int announce, int last_fd,
uid_t uid, const char *user)
{
+ static struct rlimit no_limit = {
+ RLIM_INFINITY,
+ RLIM_INFINITY
+ };
+ struct rlimit old_limit;
+ int setrlimit_res;
struct flock last_lock;
struct lastlog last_login;
time_t ll_time;
@@ -427,6 +438,31 @@ last_login_write(pam_handle_t *pamh, int announce, int last_fd,
sleep(LASTLOG_IGNORE_LOCK_TIME);
}
+ /*
+ * Failing to set the 'fsize' limit is not a fatal error. We try to write
+ * lastlog anyway, under the risk of dying due to a SIGXFSZ.
+ */
+ D(("setting limit for 'fsize'"));
+
+ if ((announce & LASTLOG_UNLIMITED) == 0) { /* don't set to unlimted */
+ setrlimit_res = -1;
+ } else if (getrlimit(RLIMIT_FSIZE, &old_limit) == 0) {
+ if (old_limit.rlim_cur == RLIM_INFINITY) { /* already unlimited */
+ setrlimit_res = -1;
+ } else {
+ setrlimit_res = setrlimit(RLIMIT_FSIZE, &no_limit);
+ if (setrlimit_res != 0)
+ pam_syslog(pamh, LOG_WARNING, "Could not set limit for 'fsize': %m");
+ }
+ } else {
+ setrlimit_res = -1;
+ if (errno == EINVAL) {
+ pam_syslog(pamh, LOG_INFO, "Limit for 'fsize' not supported: %m");
+ } else {
+ pam_syslog(pamh, LOG_WARNING, "Could not get limit for 'fsize': %m");
+ }
+ }
+
D(("writing to the lastlog file"));
if (pam_modutil_write (last_fd, (char *) &last_login,
sizeof (last_login)) != sizeof(last_login)) {
@@ -434,6 +470,18 @@ last_login_write(pam_handle_t *pamh, int announce, int last_fd,
retval = PAM_SERVICE_ERR;
}
+ /*
+ * Failing to restore the 'fsize' limit is a fatal error.
+ */
+ D(("restoring limit for 'fsize'"));
+ if (setrlimit_res == 0) {
+ setrlimit_res = setrlimit(RLIMIT_FSIZE, &old_limit);
+ if (setrlimit_res != 0) {
+ pam_syslog(pamh, LOG_ERR, "Could not restore limit for 'fsize': %m");
+ retval = PAM_SERVICE_ERR;
+ }
+ }
+
last_lock.l_type = F_UNLCK;
(void) fcntl(last_fd, F_SETLK, &last_lock); /* unlock */
D(("unlocked"));
--
2.20.1

View File

@ -1,755 +0,0 @@
diff --git a/modules/pam_motd/pam_motd.8.xml b/modules/pam_motd/pam_motd.8.xml
index 906c4ed..4e2110c 100644
--- a/modules/pam_motd/pam_motd.8.xml
+++ b/modules/pam_motd/pam_motd.8.xml
@@ -21,6 +21,9 @@
<arg choice="opt">
motd=<replaceable>/path/filename</replaceable>
</arg>
+ <arg choice="opt">
+ motd_dir=<replaceable>/path/dirname.d</replaceable>
+ </arg>
</cmdsynopsis>
</refsynopsisdiv>
@@ -31,10 +34,49 @@
<para>
pam_motd is a PAM module that can be used to display
arbitrary motd (message of the day) files after a successful
- login. By default the <filename>/etc/motd</filename> file is
- shown. The message size is limited to 64KB.
+ login. By default, pam_motd shows files in the
+ following locations:
+ </para>
+ <para>
+ <simplelist type='vert'>
+ <member><filename>/etc/motd</filename></member>
+ <member><filename>/run/motd</filename></member>
+ <member><filename>/usr/lib/motd</filename></member>
+ <member><filename>/etc/motd.d/</filename></member>
+ <member><filename>/run/motd.d/</filename></member>
+ <member><filename>/usr/lib/motd.d/</filename></member>
+ </simplelist>
+ </para>
+ <para>
+ Each message size is limited to 64KB.
+ </para>
+ <para>
+ If <filename>/etc/motd</filename> does not exist,
+ then <filename>/run/motd</filename> is shown. If
+ <filename>/run/motd</filename> does not exist, then
+ <filename>/usr/lib/motd</filename> is shown.
+ </para>
+ <para>
+ Similar overriding behavior applies to the directories.
+ Files in <filename>/etc/motd.d/</filename> override files
+ with the same name in <filename>/run/motd.d/</filename> and
+ <filename>/usr/lib/motd.d/</filename>. Files in <filename>/run/motd.d/</filename>
+ override files with the same name in <filename>/usr/lib/motd.d/</filename>.
+ </para>
+ <para>
+ Files the in the directories listed above are displayed in
+ lexicographic order by name.
+ </para>
+ <para>
+ To silence a message,
+ a symbolic link with target <filename>/dev/null</filename>
+ may be placed in <filename>/etc/motd.d</filename> with
+ the same filename as the message to be silenced. Example:
+ Creating a symbolic link as follows silences <filename>/usr/lib/motd.d/my_motd</filename>.
+ </para>
+ <para>
+ <command>ln -s /dev/null /etc/motd.d/my_motd</command>
</para>
-
</refsect1>
<refsect1 id="pam_motd-options">
@@ -47,8 +89,10 @@
</term>
<listitem>
<para>
- The <filename>/path/filename</filename> file is displayed
- as message of the day.
+ The <filename>/path/filename</filename> file is displayed
+ as message of the day. Multiple paths to try can be
+ specified as a colon-separated list. By default this option
+ is set to <filename>/etc/motd:/run/motd:/usr/lib/motd</filename>.
</para>
</listitem>
</varlistentry>
@@ -59,16 +103,17 @@
<listitem>
<para>
The <filename>/path/dirname.d</filename> directory is scanned
- and each file contained inside of it is displayed.
+ and each file contained inside of it is displayed. Multiple
+ directories to scan can be specified as a colon-separated list.
+ By default this option is set to <filename>/etc/motd.d:/run/motd.d:/usr/lib/motd.d</filename>.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
- When no options are given, the default is to display both
- <filename>/etc/motd</filename> and the contents of
- <filename>/etc/motd.d</filename>. Specifying either option (or both)
- will disable this default behavior.
+ When no options are given, the default behavior applies for both
+ options. Specifying either option (or both) will disable the
+ default behavior for both options.
</para>
</refsect1>
diff --git a/modules/pam_motd/pam_motd.c b/modules/pam_motd/pam_motd.c
index cc828d7..ec3ebd5 100644
--- a/modules/pam_motd/pam_motd.c
+++ b/modules/pam_motd/pam_motd.c
@@ -33,8 +33,8 @@
*/
#define PAM_SM_SESSION
-#define DEFAULT_MOTD "/etc/motd"
-#define DEFAULT_MOTD_D "/etc/motd.d"
+#define DEFAULT_MOTD "/etc/motd:/run/motd:/usr/lib/motd"
+#define DEFAULT_MOTD_D "/etc/motd.d:/run/motd.d:/usr/lib/motd.d"
#include <security/pam_modules.h>
#include <security/pam_modutil.h>
@@ -97,12 +97,234 @@ static void try_to_display_directory(pam_handle_t *pamh, const char *dirname)
}
}
+/*
+ * Split a DELIM-separated string ARG into an array.
+ * Outputs a newly allocated array of strings OUT_ARG_SPLIT
+ * and the number of strings OUT_NUM_STRS.
+ * Returns 0 in case of error, 1 in case of success.
+ */
+static int pam_split_string(const pam_handle_t *pamh, char *arg, char delim,
+ char ***out_arg_split, uint *out_num_strs)
+{
+ char *arg_extracted = NULL;
+ const char *arg_ptr = arg;
+ char **arg_split = NULL;
+ char delim_str[2];
+ int i = 0;
+ uint num_strs = 0;
+ int retval = 0;
+
+ delim_str[0] = delim;
+ delim_str[1] = '\0';
+
+ if (arg == NULL) {
+ goto out;
+ }
+
+ while (arg_ptr != NULL) {
+ num_strs++;
+ arg_ptr = strchr(arg_ptr + sizeof(const char), delim);
+ }
+
+ arg_split = (char **)calloc(num_strs, sizeof(char *));
+ if (arg_split == NULL) {
+ pam_syslog(pamh, LOG_CRIT, "pam_motd: failed to allocate string array");
+ goto out;
+ }
+
+ arg_extracted = strtok_r(arg, delim_str, &arg);
+ while (arg_extracted != NULL && i < num_strs) {
+ arg_split[i++] = arg_extracted;
+ arg_extracted = strtok_r(NULL, delim_str, &arg);
+ }
+
+ retval = 1;
+
+ out:
+ *out_num_strs = num_strs;
+ *out_arg_split = arg_split;
+
+ return retval;
+}
+
+/* Join A_STR and B_STR, inserting a "/" between them if one is not already trailing
+ * in A_STR or beginning B_STR. A pointer to a newly allocated string holding the
+ * joined string is returned in STRP_OUT.
+ * Returns -1 in case of error, or the number of bytes in the joined string in
+ * case of success. */
+static int join_dir_strings(char **strp_out, const char *a_str, const char *b_str)
+{
+ int has_sep = 0;
+ int retval = -1;
+ char *join_strp = NULL;
+
+ if (strp_out == NULL || a_str == NULL || b_str == NULL) {
+ goto out;
+ }
+ if (strlen(a_str) == 0) {
+ goto out;
+ }
+
+ has_sep = (a_str[strlen(a_str) - 1] == '/') || (b_str[0] == '/');
+
+ retval = asprintf(&join_strp, "%s%s%s", a_str,
+ (has_sep == 1) ? "" : "/", b_str);
+
+ if (retval < 0) {
+ goto out;
+ }
+
+ *strp_out = join_strp;
+
+ out:
+ return retval;
+}
+
+static int compare_strings(const void * a, const void * b)
+{
+ const char *a_str = *(char **)a;
+ const char *b_str = *(char **)b;
+
+ if (a_str == NULL && b_str == NULL) {
+ return 0;
+ }
+ else if (a_str == NULL) {
+ return -1;
+ }
+ else if (b_str == NULL) {
+ return 1;
+ }
+ else {
+ return strcmp(a_str, b_str);
+ }
+}
+
+static int filter_dirents(const struct dirent *d)
+{
+ return (d->d_type == DT_REG || d->d_type == DT_LNK);
+}
+
+static void try_to_display_directories_with_overrides(pam_handle_t *pamh,
+ char **motd_dir_path_split, int num_motd_dirs)
+{
+ struct dirent ***dirscans = NULL;
+ int *dirscans_sizes = NULL;
+ int dirscans_size_total = 0;
+ char **dirnames_all = NULL;
+ int i;
+ int i_dirnames = 0;
+
+ if (pamh == NULL || motd_dir_path_split == NULL) {
+ goto out;
+ }
+ if (num_motd_dirs < 1) {
+ goto out;
+ }
+
+ if ((dirscans = (struct dirent ***)calloc(num_motd_dirs,
+ sizeof(struct dirent **))) == NULL) {
+ pam_syslog(pamh, LOG_CRIT, "pam_motd: failed to allocate dirent arrays");
+ goto out;
+ }
+ if ((dirscans_sizes = (int *)calloc(num_motd_dirs, sizeof(int))) == NULL) {
+ pam_syslog(pamh, LOG_CRIT, "pam_motd: failed to allocate dirent array sizes");
+ goto out;
+ }
+
+ for (i = 0; i < num_motd_dirs; i++) {
+ dirscans_sizes[i] = scandir(motd_dir_path_split[i], &(dirscans[i]),
+ filter_dirents, alphasort);
+ if (dirscans_sizes[i] < 0) {
+ pam_syslog(pamh, LOG_ERR, "pam_motd: error scanning directory %s", motd_dir_path_split[i]);
+ dirscans_sizes[i] = 0;
+ }
+ dirscans_size_total += dirscans_sizes[i];
+ }
+
+ /* Allocate space for all file names found in the directories, including duplicates. */
+ if ((dirnames_all = (char **)calloc(dirscans_size_total,
+ sizeof(char *))) == NULL) {
+ pam_syslog(pamh, LOG_CRIT, "pam_motd: failed to allocate dirname array");
+ goto out;
+ }
+
+ for (i = 0; i < dirscans_size_total; i++) {
+ dirnames_all[i] = NULL;
+ }
+
+ for (i = 0; i < num_motd_dirs; i++) {
+ int j;
+
+ for (j = 0; j < dirscans_sizes[i]; j++) {
+ dirnames_all[i_dirnames] = dirscans[i][j]->d_name;
+ i_dirnames++;
+ }
+ }
+
+ qsort(dirnames_all, dirscans_size_total,
+ sizeof(const char *), compare_strings);
+
+ for (i = 0; i < dirscans_size_total; i++) {
+ int j;
+
+ if (dirnames_all[i] == NULL) {
+ continue;
+ }
+
+ /* Skip duplicate file names. */
+ if (i > 0 && strcmp(dirnames_all[i], dirnames_all[i - 1]) == 0) {
+ continue;
+ }
+
+ for (j = 0; j < num_motd_dirs; j++) {
+ char *abs_path = NULL;
+
+ if (join_dir_strings(&abs_path, motd_dir_path_split[j],
+ dirnames_all[i]) < 0) {
+ continue;
+ }
+
+ if (abs_path != NULL) {
+ int fd = open(abs_path, O_RDONLY, 0);
+ if (fd >= 0) {
+ try_to_display_fd(pamh, fd);
+ close(fd);
+
+ /* We displayed a file, skip to the next file name. */
+ break;
+ }
+ }
+ _pam_drop(abs_path);
+ }
+ }
+
+ out:
+ _pam_drop(dirnames_all);
+ for (i = 0; i < num_motd_dirs; i++) {
+ int j;
+ for (j = 0; j < dirscans_sizes[i]; j++) {
+ _pam_drop(dirscans[i][j]);
+ }
+ _pam_drop(dirscans[i]);
+ }
+ _pam_drop(dirscans_sizes);
+ _pam_drop(dirscans);
+
+ return;
+}
+
int pam_sm_open_session(pam_handle_t *pamh, int flags,
int argc, const char **argv)
{
int retval = PAM_IGNORE;
const char *motd_path = NULL;
+ char *motd_path_copy = NULL;
+ int num_motd_paths = 0;
+ char **motd_path_split = NULL;
const char *motd_dir_path = NULL;
+ char *motd_dir_path_copy = NULL;
+ int num_motd_dir_paths = 0;
+ char **motd_dir_path_split = NULL;
if (flags & PAM_SILENT) {
return retval;
@@ -141,16 +363,52 @@ int pam_sm_open_session(pam_handle_t *pamh, int flags,
}
if (motd_path != NULL) {
- int fd = open(motd_path, O_RDONLY, 0);
+ motd_path_copy = strdup(motd_path);
+ }
+
+ if (motd_path_copy != NULL) {
+ if (pam_split_string(pamh, motd_path_copy, ':',
+ &motd_path_split, &num_motd_paths) == 0) {
+ goto out;
+ }
+ }
+
+ if (motd_dir_path != NULL) {
+ motd_dir_path_copy = strdup(motd_dir_path);
+ }
- if (fd >= 0) {
- try_to_display_fd(pamh, fd);
- close(fd);
+ if (motd_dir_path_copy != NULL) {
+ if (pam_split_string(pamh, motd_dir_path_copy, ':',
+ &motd_dir_path_split, &num_motd_dir_paths) == 0) {
+ goto out;
}
}
- if (motd_dir_path != NULL)
- try_to_display_directory(pamh, motd_dir_path);
+ if (motd_path_split != NULL) {
+ int i;
+
+ for (i = 0; i < num_motd_paths; i++) {
+ int fd = open(motd_path_split[i], O_RDONLY, 0);
+
+ if (fd >= 0) {
+ try_to_display_fd(pamh, fd);
+ close(fd);
+
+ /* We found and displayed a file, move onto next filename. */
+ break;
+ }
+ }
+ }
+
+ if (motd_dir_path_split != NULL)
+ try_to_display_directories_with_overrides(pamh, motd_dir_path_split,
+ num_motd_dir_paths);
+
+ out:
+ _pam_drop(motd_path_copy);
+ _pam_drop(motd_path_split);
+ _pam_drop(motd_dir_path_copy);
+ _pam_drop(motd_dir_path_split);
return retval;
}
diff --git a/xtests/Makefile.am b/xtests/Makefile.am
index a6d6f8d..4d5aba3 100644
--- a/xtests/Makefile.am
+++ b/xtests/Makefile.am
@@ -32,7 +32,10 @@ EXTRA_DIST = run-xtests.sh tst-pam_dispatch1.pamd tst-pam_dispatch2.pamd \
tst-pam_substack5.pamd tst-pam_substack5a.pamd tst-pam_substack5.sh \
tst-pam_assemble_line1.pamd tst-pam_assemble_line1.sh \
tst-pam_pwhistory1.pamd tst-pam_pwhistory1.sh \
- tst-pam_time1.pamd time.conf
+ tst-pam_time1.pamd time.conf \
+ tst-pam_motd.sh tst-pam_motd1.sh tst-pam_motd2.sh \
+ tst-pam_motd3.sh tst-pam_motd4.sh tst-pam_motd1.pamd \
+ tst-pam_motd2.pamd tst-pam_motd3.pamd tst-pam_motd4.pamd
XTESTS = tst-pam_dispatch1 tst-pam_dispatch2 tst-pam_dispatch3 \
tst-pam_dispatch4 tst-pam_dispatch5 \
@@ -41,7 +44,7 @@ XTESTS = tst-pam_dispatch1 tst-pam_dispatch2 tst-pam_dispatch3 \
tst-pam_access1 tst-pam_access2 tst-pam_access3 \
tst-pam_access4 tst-pam_limits1 tst-pam_succeed_if1 \
tst-pam_group1 tst-pam_authfail tst-pam_authsucceed \
- tst-pam_pwhistory1 tst-pam_time1
+ tst-pam_pwhistory1 tst-pam_time1 tst-pam_motd
NOSRCTESTS = tst-pam_substack1 tst-pam_substack2 tst-pam_substack3 \
tst-pam_substack4 tst-pam_substack5 tst-pam_assemble_line1
diff --git a/xtests/tst-pam_motd.c b/xtests/tst-pam_motd.c
new file mode 100644
index 0000000..bba2f9d
--- /dev/null
+++ b/xtests/tst-pam_motd.c
@@ -0,0 +1,69 @@
+/*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <security/pam_appl.h>
+#include <security/pam_misc.h>
+
+static struct pam_conv conv = {
+ misc_conv,
+ NULL
+};
+
+int main(int argc, char *argv[])
+{
+ pam_handle_t *pamh=NULL;
+ char *tst_arg = NULL;
+ int retval;
+
+ if (argc > 1)
+ tst_arg = argv[1];
+
+ retval = pam_start(tst_arg, NULL, &conv, &pamh);
+
+ retval = pam_open_session(pamh, 0);
+
+ retval = pam_close_session(pamh, 0);
+
+ if (pam_end(pamh,retval) != PAM_SUCCESS) { /* close Linux-PAM */
+ pamh = NULL;
+ exit(1);
+ }
+
+ return ( retval == PAM_SUCCESS ? 0:1 ); /* indicate success */
+}
diff --git a/xtests/tst-pam_motd.sh b/xtests/tst-pam_motd.sh
new file mode 100755
index 0000000..9080128
--- /dev/null
+++ b/xtests/tst-pam_motd.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+set -e
+
+./tst-pam_motd1.sh
+./tst-pam_motd2.sh
+./tst-pam_motd3.sh
+./tst-pam_motd4.sh
diff --git a/xtests/tst-pam_motd1.pamd b/xtests/tst-pam_motd1.pamd
new file mode 100644
index 0000000..ddea82c
--- /dev/null
+++ b/xtests/tst-pam_motd1.pamd
@@ -0,0 +1,3 @@
+#%PAM-1.0
+session required pam_permit.so
+session optional pam_motd.so motd=tst-pam_motd1.d/etc/motd motd_dir=tst-pam_motd1.d/etc/motd.d
diff --git a/xtests/tst-pam_motd1.sh b/xtests/tst-pam_motd1.sh
new file mode 100755
index 0000000..cc88854
--- /dev/null
+++ b/xtests/tst-pam_motd1.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+
+TST_DIR="tst-pam_motd1.d"
+
+function tst_cleanup() {
+ rm -rf "${TST_DIR}"
+ rm -f tst-pam_motd1.out
+}
+
+mkdir -p ${TST_DIR}
+mkdir -p ${TST_DIR}/etc/motd.d
+
+# Verify the case of single motd and motd.d directory works
+echo "motd: /etc/motd" > ${TST_DIR}/etc/motd
+echo "motd: /etc/motd.d/test" > ${TST_DIR}/etc/motd.d/test
+
+./tst-pam_motd tst-pam_motd1 > tst-pam_motd1.out
+
+RET=$?
+
+motd_to_show_output=$(cat tst-pam_motd1.out | grep "motd: /etc/motd")
+if [ -z "${motd_to_show_output}" ];
+then
+ tst_cleanup
+ exit 1
+fi
+
+motd_dir_to_show_output=$(cat tst-pam_motd1.out | grep "motd: /etc/motd.d/test")
+if [ -z "${motd_dir_to_show_output}" ];
+then
+ tst_cleanup
+ exit 1
+fi
+
+tst_cleanup
+exit $RET
diff --git a/xtests/tst-pam_motd2.pamd b/xtests/tst-pam_motd2.pamd
new file mode 100644
index 0000000..8200191
--- /dev/null
+++ b/xtests/tst-pam_motd2.pamd
@@ -0,0 +1,3 @@
+#%PAM-1.0
+session required pam_permit.so
+session optional pam_motd.so motd=tst-pam_motd2.d/etc/motd:tst-pam_motd2.d/run/motd:tst-pam_motd2.d/usr/lib/motd motd_dir=tst-pam_motd2.d/etc/motd.d:tst-pam_motd2.d/run/motd.d:tst-pam_motd2.d/usr/lib/motd.d
diff --git a/xtests/tst-pam_motd2.sh b/xtests/tst-pam_motd2.sh
new file mode 100755
index 0000000..d26ea92
--- /dev/null
+++ b/xtests/tst-pam_motd2.sh
@@ -0,0 +1,53 @@
+#!/bin/bash
+
+TST_DIR="tst-pam_motd2.d"
+
+function tst_cleanup() {
+ rm -rf "${TST_DIR}"
+ rm -f tst-pam_motd2.out
+}
+
+mkdir -p ${TST_DIR}
+mkdir -p ${TST_DIR}/etc/motd.d
+mkdir -p ${TST_DIR}/run/motd.d
+mkdir -p ${TST_DIR}/usr/lib/motd.d
+
+echo "motd: /etc/motd" > ${TST_DIR}/etc/motd
+echo "motd: /run/motd" > ${TST_DIR}/run/motd
+echo "motd: /usr/lib/motd" > ${TST_DIR}/usr/lib/motd
+
+# Drop a motd file in test directories such that every overriding
+# condition (for 3 directories in this case) will be seen.
+echo "motd: e0r0u1 in usr/lib - will show" > ${TST_DIR}/usr/lib/motd.d/e0r0u1.motd
+echo "motd: e0r1u0 in run - will show" > ${TST_DIR}/run/motd.d/e0r1u0.motd
+echo "motd: e0r1u1 in usr/lib - not show" > ${TST_DIR}/usr/lib/motd.d/e0r1u1.motd
+echo "motd: e0r1u1 in run - will show" > ${TST_DIR}/run/motd.d/e0r1u1.motd
+echo "motd: e1r0u0 in etc - will show" > ${TST_DIR}/etc/motd.d/e1r0u0.motd
+echo "motd: e1r0u1 in usr/lib - not show" > ${TST_DIR}/usr/lib/motd.d/e1r0u1.motd
+echo "motd: e1r0u1 in etc - will show" > ${TST_DIR}/etc/motd.d/e1r0u1.motd
+echo "motd: e1r1u0 in run - not show" > ${TST_DIR}/run/motd.d/e1r1u0.motd
+echo "motd: e1r1u0 in etc - will show" > ${TST_DIR}/etc/motd.d/e1r1u0.motd
+echo "motd: e1r1u1 in usr/lib - not show" > ${TST_DIR}/usr/lib/motd.d/e1r1u1.motd
+echo "motd: e1r1u1 in run - not show" > ${TST_DIR}/run/motd.d/e1r1u1.motd
+echo "motd: e1r1u1 in etc - will show" > ${TST_DIR}/etc/motd.d/e1r1u1.motd
+
+./tst-pam_motd tst-pam_motd2 > tst-pam_motd2.out
+
+RET=$?
+
+motd_to_show_output=$(cat tst-pam_motd2.out | grep "motd: /etc/motd")
+if [ -z "${motd_to_show_output}" ];
+then
+ tst_cleanup
+ exit 1
+fi
+
+motd_dir_not_show_output=$(cat tst-pam_motd2.out | grep "not show")
+if [ -n "${motd_dir_not_show_output}" ];
+then
+ tst_cleanup
+ exit 1
+fi
+
+tst_cleanup
+exit $RET
diff --git a/xtests/tst-pam_motd3.pamd b/xtests/tst-pam_motd3.pamd
new file mode 100644
index 0000000..a8b8cbf
--- /dev/null
+++ b/xtests/tst-pam_motd3.pamd
@@ -0,0 +1,3 @@
+#%PAM-1.0
+session required pam_permit.so
+session optional pam_motd.so motd=tst-pam_motd3.d/etc/motd:tst-pam_motd3.d/run/motd:tst-pam_motd3.d/usr/lib/motd motd_dir=tst-pam_motd3.d/etc/motd.d:tst-pam_motd3.d/run/motd.d:tst-pam_motd3.d/usr/lib/motd.d
diff --git a/xtests/tst-pam_motd3.sh b/xtests/tst-pam_motd3.sh
new file mode 100755
index 0000000..e18856b
--- /dev/null
+++ b/xtests/tst-pam_motd3.sh
@@ -0,0 +1,53 @@
+#!/bin/bash
+
+TST_DIR="tst-pam_motd3.d"
+
+function tst_cleanup() {
+ rm -rf "${TST_DIR}"
+ rm -f tst-pam_motd3.out
+}
+
+mkdir -p ${TST_DIR}
+mkdir -p ${TST_DIR}/etc/motd.d
+mkdir -p ${TST_DIR}/run/motd.d
+mkdir -p ${TST_DIR}/usr/lib/motd.d
+
+# Verify motd is still displayed when not overridden
+echo "motd: test-show in run - show" > ${TST_DIR}/run/motd.d/test-show.motd
+
+# Test overridden by a symlink to a file that isn't /dev/null; symlink target should show
+echo "motd: hidden-by-symlink in usr/lib - not show" > ${TST_DIR}/usr/lib/motd.d/hidden-by-symlink.motd
+echo "motd: test-from-symlink - show" > ${TST_DIR}/test-from-symlink.motd
+ln -sr ${TST_DIR}/test-from-symlink.motd ${TST_DIR}/run/motd.d/hidden-by-symlink.motd
+
+# Test hidden by a null symlink
+echo "motd: hidden-by-null-symlink in run - not show" > ${TST_DIR}/run/motd.d/hidden-by-null-symlink.motd
+ln -s /dev/null ${TST_DIR}/etc/motd.d/hidden-by-null-symlink.motd
+
+./tst-pam_motd tst-pam_motd3 > tst-pam_motd3.out
+
+RET=$?
+
+motd_dir_not_show_output=$(cat tst-pam_motd3.out | grep "not show")
+if [ -n "${motd_dir_not_show_output}" ];
+then
+ tst_cleanup
+ exit 1
+fi
+
+motd_test_show_output=$(cat tst-pam_motd3.out | grep "test-show.*- show")
+if [ -z "${motd_test_show_output}" ];
+then
+ tst_cleanup
+ exit 1
+fi
+
+motd_general_symlink_show_output=$(cat tst-pam_motd3.out | grep "test-from-symlink.*- show")
+if [ -z "${motd_general_symlink_show_output}" ];
+then
+ tst_cleanup
+ exit 1
+fi
+
+tst_cleanup
+exit $RET
diff --git a/xtests/tst-pam_motd4.pamd b/xtests/tst-pam_motd4.pamd
new file mode 100644
index 0000000..9dc311a
--- /dev/null
+++ b/xtests/tst-pam_motd4.pamd
@@ -0,0 +1,3 @@
+#%PAM-1.0
+session required pam_permit.so
+session optional pam_motd.so motd=tst-pam_motd4.d/etc/motd
diff --git a/xtests/tst-pam_motd4.sh b/xtests/tst-pam_motd4.sh
new file mode 100755
index 0000000..6022177
--- /dev/null
+++ b/xtests/tst-pam_motd4.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+
+TST_DIR="tst-pam_motd4.d"
+
+function tst_cleanup() {
+ rm -rf "${TST_DIR}"
+ rm -f tst-pam_motd4.out
+}
+
+mkdir -p ${TST_DIR}/etc
+
+# Verify the case of single motd with no motd_dir given in tst-pam_motd4.pamd
+echo "motd: /etc/motd" > ${TST_DIR}/etc/motd
+
+./tst-pam_motd tst-pam_motd4 > tst-pam_motd4.out
+
+RET=$?
+
+motd_to_show_output=$(cat tst-pam_motd4.out | grep "motd: /etc/motd")
+if [ -z "${motd_to_show_output}" ];
+then
+ tst_cleanup
+ exit 1
+fi
+
+tst_cleanup
+exit $RET

View File

@ -1,131 +0,0 @@
diff --git a/modules/pam_namespace/namespace.conf.5.xml b/modules/pam_namespace/namespace.conf.5.xml
index c7698cb..a94b49e 100644
--- a/modules/pam_namespace/namespace.conf.5.xml
+++ b/modules/pam_namespace/namespace.conf.5.xml
@@ -122,9 +122,14 @@
<para><emphasis>mntopts</emphasis>=<replaceable>value</replaceable>
- value of this flag is passed to the mount call when the tmpfs mount is
done. It allows for example the specification of the maximum size of the
- tmpfs instance that is created by the mount call. See <citerefentry>
- <refentrytitle>mount</refentrytitle><manvolnum>8</manvolnum>
- </citerefentry> for details.
+ tmpfs instance that is created by the mount call. In addition to
+ options specified in the <citerefentry>
+ <refentrytitle>tmpfs</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry> manual the <emphasis>nosuid</emphasis>,
+ <emphasis>noexec</emphasis>, and <emphasis>nodev</emphasis> flags
+ can be used to respectively disable setuid bit effect, disable running
+ executables, and disable devices to be interpreted on the mounted
+ tmpfs filesystem.
</para>
<para>
diff --git a/modules/pam_namespace/pam_namespace.c b/modules/pam_namespace/pam_namespace.c
index f541f89..660c7a1 100644
--- a/modules/pam_namespace/pam_namespace.c
+++ b/modules/pam_namespace/pam_namespace.c
@@ -230,6 +230,73 @@ static int parse_iscript_params(char *params, struct polydir_s *poly)
return 0;
}
+struct mntflag {
+ const char *name;
+ size_t len;
+ unsigned long flag;
+};
+
+#define LITERAL_AND_LEN(x) x, sizeof(x) - 1
+
+static const struct mntflag mntflags[] = {
+ { LITERAL_AND_LEN("noexec"), MS_NOEXEC },
+ { LITERAL_AND_LEN("nosuid"), MS_NOSUID },
+ { LITERAL_AND_LEN("nodev"), MS_NODEV }
+ };
+
+static int filter_mntopts(const char *opts, char **filtered,
+ unsigned long *mountflags)
+{
+ size_t origlen = strlen(opts);
+ const char *end;
+ char *dest;
+
+ dest = *filtered = NULL;
+ *mountflags = 0;
+
+ if (origlen == 0)
+ return 0;
+
+ do {
+ size_t len;
+ int i;
+
+ end = strchr(opts, ',');
+ if (end == NULL) {
+ len = strlen(opts);
+ } else {
+ len = end - opts;
+ }
+
+ for (i = 0; i < (int)(sizeof(mntflags)/sizeof(mntflags[0])); i++) {
+ if (mntflags[i].len != len)
+ continue;
+ if (memcmp(mntflags[i].name, opts, len) == 0) {
+ *mountflags |= mntflags[i].flag;
+ opts = end;
+ break;
+ }
+ }
+
+ if (opts != end) {
+ if (dest != NULL) {
+ *dest = ',';
+ ++dest;
+ } else {
+ dest = *filtered = calloc(1, origlen + 1);
+ if (dest == NULL)
+ return -1;
+ }
+ memcpy(dest, opts, len);
+ dest += len;
+ }
+
+ opts = end + 1;
+ } while (end != NULL);
+
+ return 0;
+}
+
static int parse_method(char *method, struct polydir_s *poly,
struct instance_data *idata)
{
@@ -289,7 +356,8 @@ static int parse_method(char *method, struct polydir_s *poly,
break;
}
free(poly->mount_opts); /* if duplicate mntopts specified */
- if ((poly->mount_opts = strdup(flag+namelen+1)) == NULL) {
+ poly->mount_opts = NULL;
+ if (filter_mntopts(flag+namelen+1, &poly->mount_opts, &poly->mount_flags) != 0) {
pam_syslog(idata->pamh, LOG_CRIT, "Memory allocation error");
return -1;
}
@@ -1484,7 +1552,7 @@ static int ns_setup(struct polydir_s *polyptr,
}
if (polyptr->method == TMPFS) {
- if (mount("tmpfs", polyptr->dir, "tmpfs", 0, polyptr->mount_opts) < 0) {
+ if (mount("tmpfs", polyptr->dir, "tmpfs", polyptr->mount_flags, polyptr->mount_opts) < 0) {
pam_syslog(idata->pamh, LOG_ERR, "Error mounting tmpfs on %s, %m",
polyptr->dir);
return PAM_SESSION_ERR;
diff --git a/modules/pam_namespace/pam_namespace.h b/modules/pam_namespace/pam_namespace.h
index 47ebcc3..1522386 100644
--- a/modules/pam_namespace/pam_namespace.h
+++ b/modules/pam_namespace/pam_namespace.h
@@ -166,6 +166,7 @@ struct polydir_s {
unsigned int flags; /* polydir flags */
char *init_script; /* path to init script */
char *mount_opts; /* mount options for tmpfs mount */
+ unsigned long mount_flags; /* mount flags for tmpfs mount */
uid_t owner; /* user which should own the polydir */
gid_t group; /* group which should own the polydir */
mode_t mode; /* mode of the polydir */

View File

@ -1,24 +0,0 @@
diff -up Linux-PAM-1.3.1/doc/Makefile.am.noflex Linux-PAM-1.3.1/doc/Makefile.am
--- Linux-PAM-1.3.1/doc/Makefile.am.noflex 2017-02-10 11:10:15.000000000 +0100
+++ Linux-PAM-1.3.1/doc/Makefile.am 2018-05-18 14:53:50.300997606 +0200
@@ -2,7 +2,7 @@
# Copyright (c) 2005, 2006 Thorsten Kukuk <kukuk@suse.de>
#
-SUBDIRS = man specs sag adg mwg
+SUBDIRS = man sag adg mwg
CLEANFILES = *~
diff -up Linux-PAM-1.3.1/Makefile.am.noflex Linux-PAM-1.3.1/Makefile.am
--- Linux-PAM-1.3.1/Makefile.am.noflex 2018-05-18 14:53:50.301997629 +0200
+++ Linux-PAM-1.3.1/Makefile.am 2018-05-18 14:55:31.576353800 +0200
@@ -4,7 +4,7 @@
AUTOMAKE_OPTIONS = 1.9 gnu dist-bzip2 dist-xz check-news
-SUBDIRS = libpam tests libpamc libpam_misc modules po conf doc examples xtests
+SUBDIRS = libpam tests libpamc libpam_misc modules po doc examples xtests
CLEANFILES = *~

View File

@ -1,74 +0,0 @@
From b6f73810a2e7afd02a231e2dfa14b05752c83db7 Mon Sep 17 00:00:00 2001
From: "Dmitry V. Levin" <ldv@altlinux.org>
Date: Wed, 26 Feb 2020 19:20:58 +0000
Subject: [PATCH] pam_modutil_sanitize_helper_fds: fix SIGPIPE effect of
PAM_MODUTIL_PIPE_FD
When pam_modutil_sanitize_helper_fds() is invoked with
PAM_MODUTIL_PIPE_FD to provide a dummy pipe descriptor for stdout
or stderr, it closes the read end of the newly created dummy pipe.
The negative side effect of this approach is that any write to such
descriptor triggers a SIGPIPE. Avoid this by closing the write end of
the dummy pipe and using its read end as a dummy pipe descriptor for
output. Any read from such descriptor returns 0, and any write just
fails with EBADF, which should work better with unprepared writers.
* libpam/pam_modutil_sanitize.c (redirect_out_pipe): Remove.
(redirect_out): Call redirect_in_pipe instead of redirect_out_pipe.
Fixes: b0ec5d1e ("Introduce pam_modutil_sanitize_helper_fds")
---
libpam/pam_modutil_sanitize.c | 30 +-----------------------------
1 file changed, 1 insertion(+), 29 deletions(-)
diff --git a/libpam/pam_modutil_sanitize.c b/libpam/pam_modutil_sanitize.c
index 605c859d..58b9537c 100644
--- a/libpam/pam_modutil_sanitize.c
+++ b/libpam/pam_modutil_sanitize.c
@@ -46,34 +46,6 @@ redirect_in_pipe(pam_handle_t *pamh, int fd, const char *name)
return fd;
}
-/*
- * Creates a pipe, closes its read end, redirects fd to its write end.
- * Returns fd on success, -1 otherwise.
- */
-static int
-redirect_out_pipe(pam_handle_t *pamh, int fd, const char *name)
-{
- int out[2];
-
- if (pipe(out) < 0) {
- pam_syslog(pamh, LOG_ERR, "Could not create pipe: %m");
- return -1;
- }
-
- close(out[0]);
-
- if (out[1] == fd)
- return fd;
-
- if (dup2(out[1], fd) != fd) {
- pam_syslog(pamh, LOG_ERR, "dup2 of %s failed: %m", name);
- fd = -1;
- }
-
- close(out[1]);
- return fd;
-}
-
/*
* Opens /dev/null for writing, redirects fd there.
* Returns fd on success, -1 otherwise.
@@ -106,7 +78,7 @@ redirect_out(pam_handle_t *pamh, enum pam_modutil_redirect_fd mode,
{
switch (mode) {
case PAM_MODUTIL_PIPE_FD:
- if (redirect_out_pipe(pamh, fd, name) < 0)
+ if (redirect_in_pipe(pamh, fd, name) < 0)
return -1;
break;
case PAM_MODUTIL_NULL_FD:
--
2.25.3

View File

@ -1,96 +0,0 @@
From c6c51832af8e7724cfbd454daa65a6644f5b45c2 Mon Sep 17 00:00:00 2001
From: ikerexxe <ipedrosa@redhat.com>
Date: Fri, 6 Mar 2020 15:04:09 +0100
Subject: [PATCH] pam_selinux: check unknown object classes or permissions in
current policy
Explanation: check whether unknown object classes or permissions are allowed or denied in the current policy
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1680961
---
modules/pam_selinux/pam_selinux.c | 50 +++++--------------------------
1 file changed, 8 insertions(+), 42 deletions(-)
diff --git a/modules/pam_selinux/pam_selinux.c b/modules/pam_selinux/pam_selinux.c
index 96f9c831..827f5942 100644
--- a/modules/pam_selinux/pam_selinux.c
+++ b/modules/pam_selinux/pam_selinux.c
@@ -157,42 +157,6 @@ query_response (pam_handle_t *pamh, const char *text, const char *def,
return rc;
}
-static int mls_range_allowed(pam_handle_t *pamh, security_context_t src, security_context_t dst, int debug)
-{
- struct av_decision avd;
- int retval;
- security_class_t class;
- access_vector_t bit;
- context_t src_context;
- context_t dst_context;
-
- class = string_to_security_class("context");
- if (!class) {
- pam_syslog(pamh, LOG_ERR, "Failed to translate security class context. %m");
- return 0;
- }
-
- bit = string_to_av_perm(class, "contains");
- if (!bit) {
- pam_syslog(pamh, LOG_ERR, "Failed to translate av perm contains. %m");
- return 0;
- }
-
- src_context = context_new (src);
- dst_context = context_new (dst);
- context_range_set(dst_context, context_range_get(src_context));
- if (debug)
- pam_syslog(pamh, LOG_NOTICE, "Checking if %s mls range valid for %s", dst, context_str(dst_context));
-
- retval = security_compute_av(context_str(dst_context), dst, class, bit, &avd);
- context_free(src_context);
- context_free(dst_context);
- if (retval || ((bit & avd.allowed) != bit))
- return 0;
-
- return 1;
-}
-
static security_context_t
config_context (pam_handle_t *pamh, security_context_t defaultcon, int use_current_range, int debug)
{
@@ -274,16 +238,17 @@ config_context (pam_handle_t *pamh, security_context_t defaultcon, int use_curre
goto fail_set;
context_free(new_context);
- /* we have to check that this user is allowed to go into the
- range they have specified ... role is tied to an seuser, so that'll
- be checked at setexeccon time */
- if (mls_enabled && !mls_range_allowed(pamh, defaultcon, newcon, debug)) {
+ /* we have to check that this user is allowed to go into the
+ range they have specified ... role is tied to an seuser, so that'll
+ be checked at setexeccon time */
+ if (mls_enabled &&
+ selinux_check_access(defaultcon, newcon, "context", "contains", NULL) != 0) {
pam_syslog(pamh, LOG_NOTICE, "Security context %s is not allowed for %s", defaultcon, newcon);
send_audit_message(pamh, 0, defaultcon, newcon);
free(newcon);
- goto fail_range;
+ goto fail_range;
}
return newcon;
}
@@ -385,7 +350,8 @@ context_from_env (pam_handle_t *pamh, security_context_t defaultcon, int env_par
/* we have to check that this user is allowed to go into the
range they have specified ... role is tied to an seuser, so that'll
be checked at setexeccon time */
- if (mls_enabled && !mls_range_allowed(pamh, defaultcon, newcon, debug)) {
+ if (mls_enabled &&
+ selinux_check_access(defaultcon, newcon, "context", "contains", NULL) != 0) {
pam_syslog(pamh, LOG_NOTICE, "Security context %s is not allowed for %s", defaultcon, newcon);
goto fail_set;
--
2.24.1

View File

@ -1,78 +0,0 @@
diff -up Linux-PAM-1.3.1/configure.ac.redhat-modules Linux-PAM-1.3.1/configure.ac
--- Linux-PAM-1.3.1/configure.ac.redhat-modules 2018-05-18 12:57:57.000000000 +0200
+++ Linux-PAM-1.3.1/configure.ac 2018-11-26 12:58:14.623545121 +0100
@@ -611,10 +611,12 @@ AC_CONFIG_FILES([Makefile libpam/Makefil
libpam_misc/Makefile conf/Makefile conf/pam_conv1/Makefile \
po/Makefile.in \
modules/Makefile \
+ modules/pam_chroot/Makefile modules/pam_console/Makefile \
+ modules/pam_postgresok/Makefile \
modules/pam_access/Makefile modules/pam_cracklib/Makefile \
modules/pam_debug/Makefile modules/pam_deny/Makefile \
modules/pam_echo/Makefile modules/pam_env/Makefile \
- modules/pam_faildelay/Makefile \
+ modules/pam_faildelay/Makefile modules/pam_faillock/Makefile \
modules/pam_filter/Makefile modules/pam_filter/upperLOWER/Makefile \
modules/pam_ftp/Makefile modules/pam_group/Makefile \
modules/pam_issue/Makefile modules/pam_keyinit/Makefile \
diff -up Linux-PAM-1.3.1/doc/sag/pam_faillock.xml.redhat-modules Linux-PAM-1.3.1/doc/sag/pam_faillock.xml
--- Linux-PAM-1.3.1/doc/sag/pam_faillock.xml.redhat-modules 2018-11-26 12:58:14.623545121 +0100
+++ Linux-PAM-1.3.1/doc/sag/pam_faillock.xml 2018-11-26 12:58:14.623545121 +0100
@@ -0,0 +1,38 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
+ "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
+<section id='sag-pam_faillock'>
+ <title>pam_faillock - temporarily locking access based on failed authentication attempts during an interval</title>
+ <cmdsynopsis>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="../../modules/pam_faillock/pam_faillock.8.xml" xpointer='xpointer(//cmdsynopsis[@id = "pam_faillock-cmdsynopsisauth"]/*)'/>
+ </cmdsynopsis>
+ <cmdsynopsis>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="../../modules/pam_faillock/pam_faillock.8.xml" xpointer='xpointer(//cmdsynopsis[@id = "pam_faillock-cmdsynopsisacct"]/*)'/>
+ </cmdsynopsis>
+ <section id='sag-pam_faillock-description'>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="../../modules/pam_faillock/pam_faillock.8.xml" xpointer='xpointer(//refsect1[@id = "pam_faillock-description"]/*)'/>
+ </section>
+ <section id='sag-pam_faillock-options'>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="../../modules/pam_faillock/pam_faillock.8.xml" xpointer='xpointer(//refsect1[@id = "pam_faillock-options"]/*)'/>
+ </section>
+ <section id='sag-pam_faillock-types'>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="../../modules/pam_faillock/pam_faillock.8.xml" xpointer='xpointer(//refsect1[@id = "pam_faillock-types"]/*)'/>
+ </section>
+ <section id='sag-pam_faillock-return_values'>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="../../modules/pam_faillock/pam_faillock.8.xml" xpointer='xpointer(//refsect1[@id = "pam_faillock-return_values"]/*)'/>
+ </section>
+ <section id='sag-pam_faillock-examples'>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="../../modules/pam_faillock/pam_faillock.8.xml" xpointer='xpointer(//refsect1[@id = "pam_faillock-examples"]/*)'/>
+ </section>
+ <section id='sag-pam_faillock-author'>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="../../modules/pam_faillock/pam_faillock.8.xml" xpointer='xpointer(//refsect1[@id = "pam_faillock-author"]/*)'/>
+ </section>
+</section>
diff -up Linux-PAM-1.3.1/modules/Makefile.am.redhat-modules Linux-PAM-1.3.1/modules/Makefile.am
--- Linux-PAM-1.3.1/modules/Makefile.am.redhat-modules 2017-02-10 11:10:15.000000000 +0100
+++ Linux-PAM-1.3.1/modules/Makefile.am 2018-11-26 12:58:14.623545121 +0100
@@ -3,13 +3,14 @@
#
SUBDIRS = pam_access pam_cracklib pam_debug pam_deny pam_echo \
+ pam_chroot pam_console pam_postgresok pam_faillock \
pam_env pam_exec pam_faildelay pam_filter pam_ftp \
pam_group pam_issue pam_keyinit pam_lastlog pam_limits \
pam_listfile pam_localuser pam_loginuid pam_mail \
pam_mkhomedir pam_motd pam_namespace pam_nologin \
pam_permit pam_pwhistory pam_rhosts pam_rootok pam_securetty \
pam_selinux pam_sepermit pam_shells pam_stress \
- pam_succeed_if pam_tally pam_tally2 pam_time pam_timestamp \
+ pam_succeed_if pam_time pam_timestamp \
pam_tty_audit pam_umask \
pam_unix pam_userdb pam_warn pam_wheel pam_xauth

View File

@ -1,33 +0,0 @@
From e31dd6c7d0faa7a06d3ebd50a0b6957b9f822d15 Mon Sep 17 00:00:00 2001
From: Tomas Mraz <tmraz@fedoraproject.org>
Date: Wed, 7 Aug 2019 18:13:57 +0200
Subject: [PATCH] pam_tty_audit: Manual page clarification about password
logging
* modules/pam_tty_audit/pam_tty_audit.8.xml: Explanation why passwords
can be sometimes logged even when the option is not set.
---
modules/pam_tty_audit/pam_tty_audit.8.xml | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/modules/pam_tty_audit/pam_tty_audit.8.xml b/modules/pam_tty_audit/pam_tty_audit.8.xml
index 59a3406..e346c68 100644
--- a/modules/pam_tty_audit/pam_tty_audit.8.xml
+++ b/modules/pam_tty_audit/pam_tty_audit.8.xml
@@ -149,6 +149,13 @@
greater than or equal to <replaceable>min_uid</replaceable> will be
matched.
</para>
+ <para>
+ Please note that passwords in some circumstances may be logged by TTY auditing
+ even if the <option>log_passwd</option> is not used. For example, all input to
+ an ssh session will be logged - even if there is a password being typed into
+ some software running at the remote host because only the local TTY state
+ affects the local TTY auditing.
+ </para>
</refsect1>
<refsect1 id='pam_tty_audit-examples'>
--
2.20.1

View File

@ -1,34 +0,0 @@
From f7abb8c1ef3aa31e6c2564a8aaf69683a77c2016 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= <besser82@fedoraproject.org>
Date: Thu, 15 Nov 2018 15:01:57 +0100
Subject: [PATCH] pam_unix: Use bcrypt b-variant for computing new hashes.
Bcrypt hashes used the "$2a$" prefix since 1997.
However, in 2011 an implementation bug was discovered in bcrypt
affecting the handling of characters in passphrases with the 8th
bit set.
Besides fixing the bug, OpenBSD 5.5 introduced the "$2b$" prefix
for a behavior that exactly matches crypt_blowfish's "$2y$", and
the crypt_blowfish implementation supports it as well since v1.1.
That said new computed bcrypt hashes should use the "$2b$" prefix.
* modules/pam_unix/passverify.c: Use bcrypt b-variant.
---
modules/pam_unix/passverify.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/pam_unix/passverify.c b/modules/pam_unix/passverify.c
index 9c1771e2..1f433b3a 100644
--- a/modules/pam_unix/passverify.c
+++ b/modules/pam_unix/passverify.c
@@ -385,7 +385,7 @@ PAMH_ARG_DECL(char * create_password_hash,
/* algoid = "$1" */
return crypt_md5_wrapper(password);
} 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)) {

View File

@ -1,73 +0,0 @@
From 86eed7ca01864b9fd17099e57f10f2b9b6b568a1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= <besser82@fedoraproject.org>
Date: Mon, 26 Nov 2018 22:33:17 +0100
Subject: [PATCH] pam_unix: Report unusable hashes found by checksalt to
syslog.
libxcrypt can be build-time configured to support (or not support)
various hashing methods. Future versions will also have support for
runtime configuration by the system's vendor and/or administrator.
For that reason adminstrator should be notified by pam if users cannot
log into their account anymore because of such a change in the system's
configuration of libxcrypt.
Also 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.
* modules/pam_unix/passverify.c (verify_pwd_hash): Report unusable
hashes found by checksalt to syslog.
---
modules/pam_unix/passverify.c | 36 +++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/modules/pam_unix/passverify.c b/modules/pam_unix/passverify.c
index eb2444bb..2c808eb5 100644
--- a/modules/pam_unix/passverify.c
+++ b/modules/pam_unix/passverify.c
@@ -103,6 +103,42 @@ 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.
+ */
+ helper_log_err(LOG_ERR,
+ "pam_unix(verify_pwd_hash): The method "
+ "for computing the hash \"%.6s\" has been "
+ "disabled in libcrypt by the preset from "
+ "the system's vendor and/or administrator.",
+ 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) {
+ helper_log_err(LOG_ERR,
+ "pam_unix(verify_pwd_hash): The hash \"%.6s\""
+ "does not use a method known by the version "
+ "of libcrypt this system is supplied with.",
+ hash);
+ }
+#endif
#ifdef HAVE_CRYPT_R
struct crypt_data *cdata;
cdata = malloc(sizeof(*cdata));

View File

@ -1,40 +0,0 @@
From 62425bf2a0c72d0e23139d0b285547a7add26251 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= <besser82@fedoraproject.org>
Date: Thu, 15 Nov 2018 19:49:44 +0100
Subject: [PATCH] pam_unix: Add support for crypt_checksalt, if libcrypt
supports it.
libxcrypt v4.3 has added the crypt_checksalt function to whether
the prefix at the begining of a given hash string refers to a
supported hashing method.
Future revisions of this function will add support to check whether
the hashing method, the prefix refers to, was disabled or considered
deprecated by the system's factory presets or system administrator.
Furthermore it will be able to detect whether the parameters, which
are used by the corresponding hashing method, being encoded in the
hash string are not considered to be strong enough anymore.
*modules/pam_unix/passverify.c: Add support for crypt_checksalt.
---
modules/pam_unix/passverify.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/modules/pam_unix/passverify.c b/modules/pam_unix/passverify.c
index 1f433b3a..6132130a 100644
--- a/modules/pam_unix/passverify.c
+++ b/modules/pam_unix/passverify.c
@@ -244,7 +244,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;

View File

@ -1,104 +0,0 @@
From d8d11db2cef65da5d2afa7acf21aa9c8cd88abed Mon Sep 17 00:00:00 2001
From: Tomas Mraz <tmraz@fedoraproject.org>
Date: Tue, 27 Nov 2018 16:11:03 +0100
Subject: [PATCH] pam_unix: Use pam_syslog instead of helper_log_err.
* modules/pam_unix/passverify.c (verify_pwd_hash): Add pamh argument via
PAMH_ARG_DECL. Call pam_syslog() instead of helper_log_err().
* modules/pam_unix/passverify.h: Adjust the declaration of verify_pwd_hash().
* modules/pam_unix/support.c (_unix_verify_password): Add the pamh argument
to verify_pwd_hash() call.
---
modules/pam_unix/passverify.c | 24 +++++++++++++-----------
modules/pam_unix/passverify.h | 6 +++---
modules/pam_unix/support.c | 2 +-
3 files changed, 17 insertions(+), 15 deletions(-)
diff --git a/modules/pam_unix/passverify.c b/modules/pam_unix/passverify.c
index 2c808eb5..80e32767 100644
--- a/modules/pam_unix/passverify.c
+++ b/modules/pam_unix/passverify.c
@@ -65,8 +65,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;
@@ -116,11 +116,10 @@ verify_pwd_hash(const char *p, char *hash, unsigned int nullok)
* pam_syslog() needs a pam handle,
* but that's not available here.
*/
- helper_log_err(LOG_ERR,
- "pam_unix(verify_pwd_hash): The method "
- "for computing the hash \"%.6s\" has been "
- "disabled in libcrypt by the preset from "
- "the system's vendor and/or administrator.",
+ pam_syslog(pamh, LOG_ERR,
+ "The support for password hash \"%.6s\" "
+ "has been disabled in libcrypt "
+ "configuration.",
hash);
}
/*
@@ -132,12 +131,15 @@ verify_pwd_hash(const char *p, char *hash, unsigned int nullok)
* recent implementations of libcrypt.
*/
if (retval_checksalt == CRYPT_SALT_INVALID) {
- helper_log_err(LOG_ERR,
- "pam_unix(verify_pwd_hash): The hash \"%.6s\""
- "does not use a method known by the version "
- "of libcrypt this system is supplied with.",
+ 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;
diff --git a/modules/pam_unix/passverify.h b/modules/pam_unix/passverify.h
index 086c28ac..e9a88fbf 100644
--- a/modules/pam_unix/passverify.h
+++ b/modules/pam_unix/passverify.h
@@ -12,9 +12,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);
@@ -65,6 +62,9 @@ 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 long long ctrl, int rounds);
diff --git a/modules/pam_unix/support.c b/modules/pam_unix/support.c
index 6894288d..ea5594d2 100644
--- a/modules/pam_unix/support.c
+++ b/modules/pam_unix/support.c
@@ -770,7 +770,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) {

View File

@ -1,95 +0,0 @@
From 05aa693b7db6b818d31e41f0cab1d5fb4f49600e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= <besser82@fedoraproject.org>
Date: Thu, 15 Nov 2018 15:58:56 +0100
Subject: [PATCH] pam_unix: Prefer a gensalt function, that supports auto
entropy.
* modules/pam_unix/pam_unix_passwd.c: Initialize rounds parameter to 0.
* modules/pam_unix/passverify.c: Prefer gensalt with auto entropy.
* modules/pam_unix/support.c: Fix sanitizing of rounds parameter.
---
modules/pam_unix/pam_unix_passwd.c | 2 +-
modules/pam_unix/passverify.c | 13 +++++++++++++
modules/pam_unix/support.c | 7 +++++--
3 files changed, 19 insertions(+), 3 deletions(-)
Index: Linux-PAM-1.3.1/modules/pam_unix/pam_unix_passwd.c
===================================================================
--- Linux-PAM-1.3.1.orig/modules/pam_unix/pam_unix_passwd.c
+++ Linux-PAM-1.3.1/modules/pam_unix/pam_unix_passwd.c
@@ -607,7 +607,7 @@ pam_sm_chauthtok(pam_handle_t *pamh, int
unsigned int ctrl, lctrl;
int retval;
int remember = -1;
- int rounds = -1;
+ int rounds = 0;
int pass_min_len = 0;
/* <DO NOT free() THESE> */
Index: Linux-PAM-1.3.1/modules/pam_unix/passverify.c
===================================================================
--- Linux-PAM-1.3.1.orig/modules/pam_unix/passverify.c
+++ Linux-PAM-1.3.1/modules/pam_unix/passverify.c
@@ -375,7 +375,12 @@ PAMH_ARG_DECL(char * create_password_has
const char *password, unsigned int 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;
@@ -406,6 +411,13 @@ PAMH_ARG_DECL(char * create_password_has
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 +435,7 @@ PAMH_ARG_DECL(char * create_password_has
#ifdef HAVE_CRYPT_GENSALT_R
}
#endif
+#endif /* CRYPT_GENSALT_IMPLEMENTS_AUTO_ENTROPY */
#ifdef HAVE_CRYPT_R
sp = NULL;
cdata = malloc(sizeof(*cdata));
Index: Linux-PAM-1.3.1/modules/pam_unix/support.c
===================================================================
--- Linux-PAM-1.3.1.orig/modules/pam_unix/support.c
+++ Linux-PAM-1.3.1/modules/pam_unix/support.c
@@ -175,6 +175,7 @@ int _set_ctrl(pam_handle_t *pamh, int fl
if (val) {
*rounds = strtol(val, NULL, 10);
+ set(UNIX_ALGO_ROUNDS, ctrl);
free (val);
}
}
@@ -254,11 +255,13 @@ int _set_ctrl(pam_handle_t *pamh, int fl
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;
+ }
}
}

View File

@ -1,57 +0,0 @@
From a6845905869ccabb5eb802be37241eabec085dc7 Mon Sep 17 00:00:00 2001
From: Tomas Mraz <tmraz@fedoraproject.org>
Date: Mon, 14 Oct 2019 16:52:46 +0200
Subject: [PATCH] pam_unix: Add logging useful for debugging problems
Two messages added about obtaining the username are guarded
by the debug option as these should not be normally
logged - they can be useful for debugging but they do not
indicate any special condition.
The message about authenticating user with blank password is
still just LOG_DEBUG priority but it is logged unconditionally
because it is somewhat extraordinary condition to have an user
with blank password.
* modules/pam_unix/pam_unix_auth.c (pam_sm_authenticate): Replace
D() macro calls which are not enabled on production builds with
regular pam_syslog() calls.
---
modules/pam_unix/pam_unix_auth.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/modules/pam_unix/pam_unix_auth.c b/modules/pam_unix/pam_unix_auth.c
index 681e49d..3fca945 100644
--- a/modules/pam_unix/pam_unix_auth.c
+++ b/modules/pam_unix/pam_unix_auth.c
@@ -130,15 +130,16 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv)
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;
}
@@ -146,7 +147,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;
--
2.20.1

View File

@ -1,105 +0,0 @@
Index: Linux-PAM-1.3.1/modules/pam_unix/pam_unix.8.xml
===================================================================
--- Linux-PAM-1.3.1.orig/modules/pam_unix/pam_unix.8.xml
+++ Linux-PAM-1.3.1/modules/pam_unix/pam_unix.8.xml
@@ -293,11 +293,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 +307,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 +321,10 @@
<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,
- fall back to MD5.
+ </citerefentry> function.
</para>
</listitem>
</varlistentry>
@@ -338,11 +335,10 @@
<listitem>
<para>
When a user changes their password next,
- encrypt it with the gost-yescrypt algorithm. If the
- gost-yescrypt algorithm is not known to the <citerefentry>
+ 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,
- fall back to MD5.
+ </citerefentry> function.
</para>
</listitem>
</varlistentry>
@@ -353,11 +349,10 @@
<listitem>
<para>
When a user changes their password next,
- encrypt it with the yescrypt algorithm. If the
- yescrypt algorithm is not known to the <citerefentry>
+ 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>
Index: Linux-PAM-1.3.1/modules/pam_unix/passverify.c
===================================================================
--- Linux-PAM-1.3.1.orig/modules/pam_unix/passverify.c
+++ Linux-PAM-1.3.1/modules/pam_unix/passverify.c
@@ -466,10 +466,9 @@ PAMH_ARG_DECL(char * create_password_has
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" :
@@ -481,7 +480,7 @@ PAMH_ARG_DECL(char * create_password_has
#ifdef HAVE_CRYPT_R
free(cdata);
#endif
- return crypt_md5_wrapper(password);
+ return NULL;
}
sp = x_strdup(sp);
#ifdef HAVE_CRYPT_R

View File

@ -1,34 +0,0 @@
From a2b72aeb86f297d349bc9e6a8f059fedf97a499a Mon Sep 17 00:00:00 2001
From: "Dmitry V. Levin" <ldv@altlinux.org>
Date: Thu, 31 May 2018 00:20:18 +0000
Subject: [PATCH] pam_unix: remove obsolete _unix_read_password prototype
The function was removed by commit Linux-PAM-1.3.0~5
so the function prototype should go as well.
* modules/pam_unix/support.h (_unix_read_password): Remove.
Complements: 7e09188c5dc4 ("pam_unix: Use pam_get_authtok() instead of
direct pam_prompt() calls.")
---
modules/pam_unix/support.h | 7 -------
1 file changed, 7 deletions(-)
diff --git a/modules/pam_unix/support.h b/modules/pam_unix/support.h
index b4c279c3..543e9b9f 100644
--- a/modules/pam_unix/support.h
+++ b/modules/pam_unix/support.h
@@ -164,13 +164,6 @@ extern int _unix_blankpasswd(pam_handle_t *pamh,unsigned int 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_run_verify_binary(pam_handle_t *pamh,
unsigned int ctrl, const char *user, int *daysleft);

View File

@ -1,479 +0,0 @@
From 16bd523f85ede9fa9115f80e826f2d803d7e61d4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= <besser82@fedoraproject.org>
Date: Thu, 15 Nov 2018 16:38:05 +0100
Subject: [PATCH] pam_unix: Add support for (gost-)yescrypt hashing methods.
libxcrypt (v4.2 and later) has added support for the yescrypt
hashing method; gost-yescrypt has been added in v4.3.
* modules/pam_unix/pam_unix.8.xml: Documentation for (gost-)yescrypt.
* modules/pam_unix/pam_unix_acct.c: Use 64 bit type for control flags.
* modules/pam_unix/pam_unix_auth.c: Likewise.
* modules/pam_unix/pam_unix_passwd.c: Likewise.
* modules/pam_unix/pam_unix_sess.c: Likewise.
* modules/pam_unix/passverify.c: Add support for (gost-)yescrypt.
* modules/pam_unix/passverify.h: Use 64 bit type for control flags.
* modules/pam_unix/support.c: Set sane rounds for (gost-)yescrypt.
* modules/pam_unix/support.h: Add support for (gost-)yescrypt.
---
modules/pam_unix/pam_unix.8.xml | 35 +++++++++-
modules/pam_unix/pam_unix_acct.c | 4 +-
modules/pam_unix/pam_unix_auth.c | 4 +-
modules/pam_unix/pam_unix_passwd.c | 12 ++--
modules/pam_unix/pam_unix_sess.c | 4 +-
modules/pam_unix/passverify.c | 8 ++-
modules/pam_unix/passverify.h | 2 +-
modules/pam_unix/support.c | 33 ++++++----
modules/pam_unix/support.h | 101 +++++++++++++++--------------
9 files changed, 128 insertions(+), 75 deletions(-)
diff --git a/modules/pam_unix/pam_unix.8.xml b/modules/pam_unix/pam_unix.8.xml
index 1b318f11..cae2aeaa 100644
--- a/modules/pam_unix/pam_unix.8.xml
+++ b/modules/pam_unix/pam_unix.8.xml
@@ -331,14 +331,45 @@
</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. If the
+ gost-yescrypt algorithm is not known to the <citerefentry>
+ <refentrytitle>crypt</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry> function,
+ fall back to MD5.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>yescrypt</option>
+ </term>
+ <listitem>
+ <para>
+ When a user changes their password next,
+ encrypt it with the yescrypt algorithm. If the
+ yescrypt algorithm is not known to the <citerefentry>
+ <refentrytitle>crypt</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry> function,
+ fall back to MD5.
+ </para>
+ </listitem>
+ </varlistentry>
<varlistentry>
<term>
<option>rounds=<replaceable>n</replaceable></option>
</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>
diff --git a/modules/pam_unix/pam_unix_acct.c b/modules/pam_unix/pam_unix_acct.c
index fbc84e2f..d8d084ac 100644
--- a/modules/pam_unix/pam_unix_acct.c
+++ b/modules/pam_unix/pam_unix_acct.c
@@ -62,7 +62,7 @@
#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];
@@ -185,7 +185,7 @@ 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;
diff --git a/modules/pam_unix/pam_unix_auth.c b/modules/pam_unix/pam_unix_auth.c
index 9d9f709d..905fc66c 100644
--- a/modules/pam_unix/pam_unix_auth.c
+++ b/modules/pam_unix/pam_unix_auth.c
@@ -96,7 +96,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;
@@ -194,7 +194,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 f2c42513..df4c1233 100644
--- a/modules/pam_unix/pam_unix_passwd.c
+++ b/modules/pam_unix/pam_unix_passwd.c
@@ -138,7 +138,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;
@@ -233,7 +233,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];
@@ -388,7 +388,7 @@ 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;
@@ -512,7 +512,7 @@ static int _do_setpass(pam_handle_t* pamh, const char *forwho,
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 */
@@ -542,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)
@@ -600,7 +600,7 @@ 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 = 0;
diff --git a/modules/pam_unix/pam_unix_sess.c b/modules/pam_unix/pam_unix_sess.c
index 03e7dcd9..4b8af530 100644
--- a/modules/pam_unix/pam_unix_sess.c
+++ b/modules/pam_unix/pam_unix_sess.c
@@ -67,7 +67,7 @@ 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;
@@ -103,7 +103,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."));
diff --git a/modules/pam_unix/passverify.c b/modules/pam_unix/passverify.c
index 95dfe528..39e2bfac 100644
--- a/modules/pam_unix/passverify.c
+++ b/modules/pam_unix/passverify.c
@@ -387,7 +387,7 @@ 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
@@ -404,6 +404,10 @@ 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 = "$2b$";
} else if (on(UNIX_SHA256_PASS, ctrl)) {
@@ -466,6 +470,8 @@ PAMH_ARG_DECL(char * create_password_hash,
pam_syslog(pamh, LOG_ERR,
"Algo %s not supported by the crypto backend, "
"falling back to MD5\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);
diff --git a/modules/pam_unix/passverify.h b/modules/pam_unix/passverify.h
index caf7ae8a..086c28ac 100644
--- a/modules/pam_unix/passverify.h
+++ b/modules/pam_unix/passverify.h
@@ -66,7 +66,7 @@ read_passwords(int fd, int npass, char **passwords);
#endif
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 8cbc4217..6894288d 100644
--- a/modules/pam_unix/support.c
+++ b/modules/pam_unix/support.c
@@ -107,7 +107,7 @@ search_key (const char *key, const char *filename)
/* 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 +122,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;
@@ -243,15 +244,23 @@ 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)) {
@@ -532,7 +541,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;
@@ -658,7 +667,7 @@ 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;
@@ -706,7 +715,7 @@ _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;
diff --git a/modules/pam_unix/support.h b/modules/pam_unix/support.h
index 543e9b9f..e02c05e0 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,51 @@ 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_CTRLS_ 31 /* number of ctrl arguments defined */
+#define UNIX_CTRLS_ 33 /* 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},
};
#define UNIX_DEFAULTS (unix_args[UNIX__NONULL].flag)
@@ -151,20 +155,23 @@ 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_verify_password(pam_handle_t * pamh, const char *name,
+ const char *p, unsigned long long ctrl);
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 */

131
pam-1.4.0-coverity.patch Normal file
View File

@ -0,0 +1,131 @@
diff -up Linux-PAM-1.4.0/libpam_misc/misc_conv.c.coverity Linux-PAM-1.4.0/libpam_misc/misc_conv.c
--- Linux-PAM-1.4.0/libpam_misc/misc_conv.c.coverity 2020-06-08 12:17:27.000000000 +0200
+++ Linux-PAM-1.4.0/libpam_misc/misc_conv.c 2020-06-23 10:19:32.999827223 +0200
@@ -211,7 +211,7 @@ static int read_string(int echo, const c
line[nc] = '\0';
}
*retstr = strdup(line);
- _pam_overwrite(line);
+ _pam_overwrite_n(line, sizeof(line));
if (!*retstr) {
D(("no memory for response string"));
nc = -1;
@@ -244,7 +244,7 @@ static int read_string(int echo, const c
D(("the timer appears to have expired"));
*retstr = NULL;
- _pam_overwrite(line);
+ _pam_overwrite_n(line, sizeof(line));
cleanexit:
diff -up Linux-PAM-1.4.0/libpam/pam_handlers.c.coverity Linux-PAM-1.4.0/libpam/pam_handlers.c
diff -up Linux-PAM-1.4.0/modules/pam_access/pam_access.c.coverity Linux-PAM-1.4.0/modules/pam_access/pam_access.c
--- Linux-PAM-1.4.0/modules/pam_access/pam_access.c.coverity 2020-06-23 10:19:32.999827223 +0200
+++ Linux-PAM-1.4.0/modules/pam_access/pam_access.c 2020-06-23 10:21:17.113398827 +0200
@@ -811,7 +811,7 @@ pam_sm_authenticate (pam_handle_t *pamh,
const char *user=NULL;
const void *void_from=NULL;
const char *from;
- const char *default_config = PAM_ACCESS_CONFIG;
+ const char * const default_config = PAM_ACCESS_CONFIG;
struct passwd *user_pw;
char hostname[MAXHOSTNAMELEN + 1];
int rv;
diff -up Linux-PAM-1.4.0/modules/pam_limits/pam_limits.c.coverity Linux-PAM-1.4.0/modules/pam_limits/pam_limits.c
--- Linux-PAM-1.4.0/modules/pam_limits/pam_limits.c.coverity 2020-06-08 12:17:27.000000000 +0200
+++ Linux-PAM-1.4.0/modules/pam_limits/pam_limits.c 2020-06-23 10:22:40.357855843 +0200
@@ -342,7 +342,7 @@ static const char *lnames[RLIM_NLIMITS]
#endif
};
-static int str2rlimit(char *name) {
+static int str2rlimit(const char *name) {
int i;
if (!name || *name == '\0')
return -1;
@@ -352,7 +352,7 @@ static int str2rlimit(char *name) {
return -1;
}
-static rlim_t str2rlim_t(char *value) {
+static rlim_t str2rlim_t(const char *value) {
unsigned long long rlimit = 0;
if (!value) return (rlim_t)rlimit;
@@ -384,7 +384,7 @@ static void parse_kernel_limits(pam_hand
FILE *limitsfile;
const char *proclimits = "/proc/1/limits";
char line[256];
- char *hard, *soft, *name;
+ const char *hard, *soft, *name;
if (!(limitsfile = fopen(proclimits, "r"))) {
pam_syslog(pamh, LOG_WARNING, "Could not read %s (%s), using PAM defaults", proclimits, strerror(errno));
diff -up Linux-PAM-1.4.0/modules/pam_loginuid/pam_loginuid.c.coverity Linux-PAM-1.4.0/modules/pam_loginuid/pam_loginuid.c
--- Linux-PAM-1.4.0/modules/pam_loginuid/pam_loginuid.c.coverity 2020-06-08 12:17:27.000000000 +0200
+++ Linux-PAM-1.4.0/modules/pam_loginuid/pam_loginuid.c 2020-06-23 10:19:32.999827223 +0200
@@ -65,7 +65,7 @@ static int set_loginuid(pam_handle_t *pa
fd = open("/proc/self/uid_map", O_RDONLY);
if (fd >= 0) {
count = pam_modutil_read(fd, uid_map, sizeof(uid_map));
- if (strncmp(uid_map, host_uid_map, count) != 0)
+ if (count <= 0 || strncmp(uid_map, host_uid_map, count) != 0)
rc = PAM_IGNORE;
close(fd);
}
diff -up Linux-PAM-1.4.0/modules/pam_mkhomedir/mkhomedir_helper.c.coverity Linux-PAM-1.4.0/modules/pam_mkhomedir/mkhomedir_helper.c
--- Linux-PAM-1.4.0/modules/pam_mkhomedir/mkhomedir_helper.c.coverity 2020-06-08 12:17:27.000000000 +0200
+++ Linux-PAM-1.4.0/modules/pam_mkhomedir/mkhomedir_helper.c 2020-06-23 10:19:33.000827228 +0200
@@ -232,6 +232,8 @@ create_homedir(const struct passwd *pwd,
{
pam_syslog(NULL, LOG_DEBUG,
"unable to open or stat src file %s: %m", newsource);
+ if (srcfd >= 0)
+ close(srcfd);
closedir(d);
#ifndef PATH_MAX
diff -up Linux-PAM-1.4.0/modules/pam_namespace/pam_namespace.c.coverity Linux-PAM-1.4.0/modules/pam_namespace/pam_namespace.c
--- Linux-PAM-1.4.0/modules/pam_namespace/pam_namespace.c.coverity 2020-06-08 12:17:27.000000000 +0200
+++ Linux-PAM-1.4.0/modules/pam_namespace/pam_namespace.c 2020-06-23 10:19:33.000827228 +0200
@@ -1488,6 +1488,7 @@ static int create_instance(struct polydi
if (fstat(fd, &newstatbuf) < 0) {
pam_syslog(idata->pamh, LOG_ERR, "Error stating %s, %m",
ipath);
+ close(fd);
rmdir(ipath);
return PAM_SESSION_ERR;
}
diff -up Linux-PAM-1.4.0/modules/pam_rootok/pam_rootok.c.coverity Linux-PAM-1.4.0/modules/pam_rootok/pam_rootok.c
--- Linux-PAM-1.4.0/modules/pam_rootok/pam_rootok.c.coverity 2020-06-08 12:17:27.000000000 +0200
+++ Linux-PAM-1.4.0/modules/pam_rootok/pam_rootok.c 2020-06-23 10:26:21.405069413 +0200
@@ -55,15 +55,17 @@ log_callback (int type UNUSED, const cha
int audit_fd;
va_list ap;
- va_start(ap, fmt);
#ifdef HAVE_LIBAUDIT
audit_fd = audit_open();
if (audit_fd >= 0) {
char *buf;
+ int ret;
- if (vasprintf (&buf, fmt, ap) < 0) {
- va_end(ap);
+ va_start(ap, fmt);
+ ret = vasprintf (&buf, fmt, ap);
+ va_end(ap);
+ if (ret < 0) {
return 0;
}
audit_log_user_avc_message(audit_fd, AUDIT_USER_AVC, buf, NULL, NULL,
@@ -75,6 +77,7 @@ log_callback (int type UNUSED, const cha
}
#endif
+ va_start(ap, fmt);
vsyslog (LOG_USER | LOG_INFO, fmt, ap);
va_end(ap);
return 0;

View File

@ -0,0 +1,123 @@
From af0faf666c5008e54dfe43684f210e3581ff1bca Mon Sep 17 00:00:00 2001
From: ikerexxe <ipedrosa@redhat.com>
Date: Tue, 16 Jun 2020 14:32:36 +0200
Subject: [PATCH 1/2] pam_unix: avoid determining if user exists
Taking a look at the time for the password prompt to appear it was
possible to determine if a user existed in a system. Solved it by
matching the runtime until the password prompt was shown by always
checking the password hash for an existing and a non-existing user.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1629598
---
modules/pam_unix/passverify.c | 6 ++++++
modules/pam_unix/support.c | 33 ++++++++++++++++++++++++++-------
2 files changed, 32 insertions(+), 7 deletions(-)
diff --git a/modules/pam_unix/passverify.c b/modules/pam_unix/passverify.c
index a571b4f7..7455eae6 100644
--- a/modules/pam_unix/passverify.c
+++ b/modules/pam_unix/passverify.c
@@ -1096,6 +1096,12 @@ 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);
}
diff --git a/modules/pam_unix/support.c b/modules/pam_unix/support.c
index 41db1f04..dc67238c 100644
--- a/modules/pam_unix/support.c
+++ b/modules/pam_unix/support.c
@@ -601,6 +601,8 @@ _unix_blankpasswd (pam_handle_t *pamh, unsigned long long ctrl, const char *name
char *salt = NULL;
int daysleft;
int retval;
+ int execloop = 1;
+ int nonexistent = 1;
D(("called"));
@@ -624,14 +626,31 @@ _unix_blankpasswd (pam_handle_t *pamh, unsigned long long ctrl, const char *name
/* UNIX passwords area */
- retval = get_pwd_hash(pamh, name, &pwd, &salt);
+ /*
+ * 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.
+ */
+ while (execloop) {
+ 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;
+ if (retval == PAM_UNIX_RUN_HELPER) {
+ execloop = 0;
+ if(nonexistent) {
+ get_pwd_hash(pamh, "pam_unix_non_existent:", &pwd, &salt);
+ }
+ /* 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;
+ } else if (retval == PAM_USER_UNKNOWN) {
+ name = "root";
+ nonexistent = 0;
+ } else {
+ execloop = 0;
+ }
}
/* Does this user have a password? */
--
2.26.2
From 0e9b286afe1224b91ff00936058b084ad4b776e4 Mon Sep 17 00:00:00 2001
From: ikerexxe <ipedrosa@redhat.com>
Date: Tue, 16 Jun 2020 14:44:04 +0200
Subject: [PATCH 2/2] pam_usertype: avoid determining if user exists
Taking a look at the time for the password prompt to appear it was
possible to determine if a user existed in a system. Solved it by
matching the runtime until the password prompt was shown by always
checking the password hash for an existing and a non-existing user.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1629598
---
modules/pam_usertype/pam_usertype.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/modules/pam_usertype/pam_usertype.c b/modules/pam_usertype/pam_usertype.c
index 2807c306..d03b73b5 100644
--- a/modules/pam_usertype/pam_usertype.c
+++ b/modules/pam_usertype/pam_usertype.c
@@ -139,8 +139,11 @@ pam_usertype_get_uid(struct pam_usertype_opts *opts,
"error retrieving information about user %s", username);
}
+ pam_modutil_getpwnam(pamh, "root");
+
return PAM_USER_UNKNOWN;
}
+ pam_modutil_getpwnam(pamh, "pam_usertype_non_existent:");
*_uid = pwd->pw_uid;
--
2.26.2

View File

@ -1,19 +1,19 @@
diff -up Linux-PAM-1.1.8/modules/pam_filter/upperLOWER/Makefile.am.relro Linux-PAM-1.1.8/modules/pam_filter/upperLOWER/Makefile.am
--- Linux-PAM-1.1.8/modules/pam_filter/upperLOWER/Makefile.am.relro 2014-09-10 17:17:20.273401344 +0200
+++ Linux-PAM-1.1.8/modules/pam_filter/upperLOWER/Makefile.am 2014-09-10 17:17:07.857115369 +0200
diff -up Linux-PAM-1.4.0/modules/pam_filter/upperLOWER/Makefile.am.relro Linux-PAM-1.4.0/modules/pam_filter/upperLOWER/Makefile.am
--- Linux-PAM-1.4.0/modules/pam_filter/upperLOWER/Makefile.am.relro 2020-06-22 13:06:45.397887922 +0200
+++ Linux-PAM-1.4.0/modules/pam_filter/upperLOWER/Makefile.am 2020-06-22 13:11:50.898150263 +0200
@@ -9,7 +9,7 @@ securelibfilterdir = $(SECUREDIR)/pam_fi
AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
-I$(srcdir)/.. @PIE_CFLAGS@
-I$(srcdir)/.. @PIE_CFLAGS@ $(WARN_CFLAGS)
-AM_LDFLAGS = @PIE_LDFLAGS@
+AM_LDFLAGS = -Wl,-z,now @PIE_LDFLAGS@
LDADD = $(top_builddir)/libpam/libpam.la
securelibfilter_PROGRAMS = upperLOWER
diff -up Linux-PAM-1.1.8/modules/pam_mkhomedir/Makefile.am.relro Linux-PAM-1.1.8/modules/pam_mkhomedir/Makefile.am
--- Linux-PAM-1.1.8/modules/pam_mkhomedir/Makefile.am.relro 2013-06-18 16:11:21.000000000 +0200
+++ Linux-PAM-1.1.8/modules/pam_mkhomedir/Makefile.am 2014-09-10 17:18:42.922304935 +0200
@@ -30,6 +30,8 @@ endif
diff -up Linux-PAM-1.4.0/modules/pam_mkhomedir/Makefile.am.relro Linux-PAM-1.4.0/modules/pam_mkhomedir/Makefile.am
--- Linux-PAM-1.4.0/modules/pam_mkhomedir/Makefile.am.relro 2020-06-22 13:06:45.397887922 +0200
+++ Linux-PAM-1.4.0/modules/pam_mkhomedir/Makefile.am 2020-06-22 13:11:57.015235608 +0200
@@ -31,6 +31,8 @@ endif
sbin_PROGRAMS = mkhomedir_helper
mkhomedir_helper_SOURCES = mkhomedir_helper.c
@ -21,11 +21,11 @@ diff -up Linux-PAM-1.1.8/modules/pam_mkhomedir/Makefile.am.relro Linux-PAM-1.1.8
+mkhomedir_helper_LDFLAGS = -Wl,-z,now @PIE_LDFLAGS@
mkhomedir_helper_LDADD = $(top_builddir)/libpam/libpam.la
if ENABLE_REGENERATE_MAN
diff -up Linux-PAM-1.1.8/modules/pam_tally2/Makefile.am.relro Linux-PAM-1.1.8/modules/pam_tally2/Makefile.am
--- Linux-PAM-1.1.8/modules/pam_tally2/Makefile.am.relro 2013-06-18 16:11:21.000000000 +0200
+++ Linux-PAM-1.1.8/modules/pam_tally2/Makefile.am 2014-09-10 17:22:04.339944040 +0200
@@ -26,6 +26,8 @@ if HAVE_VERSIONING
check_PROGRAMS = tst-pam_mkhomedir-retval
diff -up Linux-PAM-1.4.0/modules/pam_tally2/Makefile.am.relro Linux-PAM-1.4.0/modules/pam_tally2/Makefile.am
--- Linux-PAM-1.4.0/modules/pam_tally2/Makefile.am.relro 2020-06-08 12:17:27.000000000 +0200
+++ Linux-PAM-1.4.0/modules/pam_tally2/Makefile.am 2020-06-22 13:06:45.398887936 +0200
@@ -29,6 +29,8 @@ if HAVE_VERSIONING
pam_tally2_la_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
endif
@ -34,10 +34,10 @@ diff -up Linux-PAM-1.1.8/modules/pam_tally2/Makefile.am.relro Linux-PAM-1.1.8/mo
pam_tally2_LDADD = $(top_builddir)/libpam/libpam.la $(LIBAUDIT)
securelib_LTLIBRARIES = pam_tally2.la
diff -up Linux-PAM-1.1.8/modules/pam_timestamp/Makefile.am.relro Linux-PAM-1.1.8/modules/pam_timestamp/Makefile.am
--- Linux-PAM-1.1.8/modules/pam_timestamp/Makefile.am.relro 2013-06-18 16:11:21.000000000 +0200
+++ Linux-PAM-1.1.8/modules/pam_timestamp/Makefile.am 2014-08-13 16:02:49.906688139 +0200
@@ -36,7 +36,7 @@ pam_timestamp_la_CFLAGS = $(AM_CFLAGS)
diff -up Linux-PAM-1.4.0/modules/pam_timestamp/Makefile.am.relro Linux-PAM-1.4.0/modules/pam_timestamp/Makefile.am
--- Linux-PAM-1.4.0/modules/pam_timestamp/Makefile.am.relro 2020-06-08 12:17:27.000000000 +0200
+++ Linux-PAM-1.4.0/modules/pam_timestamp/Makefile.am 2020-06-22 13:06:45.398887936 +0200
@@ -38,7 +38,7 @@ pam_timestamp_la_CFLAGS = $(AM_CFLAGS)
pam_timestamp_check_SOURCES = pam_timestamp_check.c
pam_timestamp_check_CFLAGS = $(AM_CFLAGS) @PIE_CFLAGS@
pam_timestamp_check_LDADD = $(top_builddir)/libpam/libpam.la
@ -46,10 +46,10 @@ diff -up Linux-PAM-1.1.8/modules/pam_timestamp/Makefile.am.relro Linux-PAM-1.1.8
hmacfile_SOURCES = hmacfile.c hmacsha1.c sha1.c
hmacfile_LDADD = $(top_builddir)/libpam/libpam.la
diff -up Linux-PAM-1.1.8/modules/pam_unix/Makefile.am.relro Linux-PAM-1.1.8/modules/pam_unix/Makefile.am
--- Linux-PAM-1.1.8/modules/pam_unix/Makefile.am.relro 2013-06-18 16:11:21.000000000 +0200
+++ Linux-PAM-1.1.8/modules/pam_unix/Makefile.am 2014-08-13 16:02:49.906688139 +0200
@@ -55,13 +55,13 @@ bigcrypt_LDADD = @LIBCRYPT@
diff -up Linux-PAM-1.4.0/modules/pam_unix/Makefile.am.relro Linux-PAM-1.4.0/modules/pam_unix/Makefile.am
--- Linux-PAM-1.4.0/modules/pam_unix/Makefile.am.relro 2020-06-08 12:17:27.000000000 +0200
+++ Linux-PAM-1.4.0/modules/pam_unix/Makefile.am 2020-06-22 13:06:45.398887936 +0200
@@ -48,13 +48,13 @@ 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\"

24
pam-1.4.0-noflex.patch Normal file
View File

@ -0,0 +1,24 @@
diff -up Linux-PAM-1.4.0/doc/Makefile.am.noflex Linux-PAM-1.4.0/doc/Makefile.am
--- Linux-PAM-1.4.0/doc/Makefile.am.noflex 2020-06-08 12:17:27.000000000 +0200
+++ Linux-PAM-1.4.0/doc/Makefile.am 2020-06-22 12:32:01.994741087 +0200
@@ -2,7 +2,7 @@
# Copyright (c) 2005, 2006 Thorsten Kukuk <kukuk@suse.de>
#
-SUBDIRS = man specs sag adg mwg
+SUBDIRS = man sag adg mwg
CLEANFILES = *~
diff -up Linux-PAM-1.4.0/Makefile.am.noflex Linux-PAM-1.4.0/Makefile.am
--- Linux-PAM-1.4.0/Makefile.am.noflex 2020-06-22 12:32:01.994741087 +0200
+++ Linux-PAM-1.4.0/Makefile.am 2020-06-22 12:39:36.932129391 +0200
@@ -4,7 +4,7 @@
AUTOMAKE_OPTIONS = 1.9 gnu dist-bzip2 dist-xz check-news
-SUBDIRS = libpam tests libpamc libpam_misc modules po conf examples xtests
+SUBDIRS = libpam tests libpamc libpam_misc modules po doc examples xtests
if HAVE_DOC
SUBDIRS += doc

15
pam-1.4.0-nouserenv.patch Normal file
View File

@ -0,0 +1,15 @@
diff -up Linux-PAM-1.4.0/modules/pam_env/pam_env.8.xml.nouserenv Linux-PAM-1.4.0/modules/pam_env/pam_env.8.xml
--- Linux-PAM-1.4.0/modules/pam_env/pam_env.8.xml.nouserenv 2020-06-22 13:00:37.480755648 +0200
+++ Linux-PAM-1.4.0/modules/pam_env/pam_env.8.xml 2020-06-22 13:05:06.038501660 +0200
@@ -158,7 +158,10 @@
<listitem>
<para>
Turns on or off the reading of the user specific environment
- file. 0 is off, 1 is on. By default this option is off.
+ file. 0 is off, 1 is on. By default this option is off as user
+ supplied environment variables in the PAM environment could affect
+ behavior of subsequent modules in the stack without the consent
+ of the system administrator.
</para>
</listitem>
</varlistentry>

View File

@ -1,6 +1,6 @@
diff -up Linux-PAM-1.3.0/modules/pam_pwhistory/Makefile.am.pwhhelper Linux-PAM-1.3.0/modules/pam_pwhistory/Makefile.am
--- Linux-PAM-1.3.0/modules/pam_pwhistory/Makefile.am.pwhhelper 2016-03-24 12:45:42.000000000 +0100
+++ Linux-PAM-1.3.0/modules/pam_pwhistory/Makefile.am 2016-05-06 15:18:42.307637933 +0200
diff -up Linux-PAM-1.4.0/modules/pam_pwhistory/Makefile.am.pwhhelper Linux-PAM-1.4.0/modules/pam_pwhistory/Makefile.am
--- Linux-PAM-1.4.0/modules/pam_pwhistory/Makefile.am.pwhhelper 2020-06-08 12:17:27.000000000 +0200
+++ Linux-PAM-1.4.0/modules/pam_pwhistory/Makefile.am 2020-06-22 13:22:13.740840867 +0200
@@ -1,5 +1,6 @@
#
# Copyright (c) 2008, 2009 Thorsten Kukuk <kukuk@suse.de>
@ -8,23 +8,25 @@ diff -up Linux-PAM-1.3.0/modules/pam_pwhistory/Makefile.am.pwhhelper Linux-PAM-1
#
CLEANFILES = *~
@@ -9,25 +10,34 @@ EXTRA_DIST = README $(MANS) $(XMLS) tst-
TESTS = tst-pam_pwhistory
-man_MANS = pam_pwhistory.8
+man_MANS = pam_pwhistory.8 pwhistory_helper.8
@@ -8,9 +9,9 @@ MAINTAINERCLEANFILES = $(MANS) README
EXTRA_DIST = $(XMLS)
if HAVE_DOC
-dist_man_MANS = pam_pwhistory.8
+dist_man_MANS = pam_pwhistory.8 pwhistory_helper.8
endif
-XMLS = README.xml pam_pwhistory.8.xml
+XMLS = README.xml pam_pwhistory.8.xml pwhistory_helper.8.xml
dist_check_SCRIPTS = tst-pam_pwhistory
TESTS = $(dist_check_SCRIPTS)
securelibdir = $(SECUREDIR)
@@ -18,18 +19,26 @@ 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 \
- $(WARN_CFLAGS)
-AM_LDFLAGS = -no-undefined -avoid-version -module
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ -DPWHISTORY_HELPER=\"$(sbindir)/pwhistory_helper\"
+ $(WARN_CFLAGS) -DPWHISTORY_HELPER=\"$(sbindir)/pwhistory_helper\"
+
+pam_pwhistory_la_LDFLAGS = -no-undefined -avoid-version -module
if HAVE_VERSIONING
@ -47,11 +49,11 @@ diff -up Linux-PAM-1.3.0/modules/pam_pwhistory/Makefile.am.pwhhelper Linux-PAM-1
+pwhistory_helper_LDADD = $(top_builddir)/libpam/libpam.la @LIBCRYPT@
+
if ENABLE_REGENERATE_MAN
noinst_DATA = README
README: pam_pwhistory.8.xml
diff -up Linux-PAM-1.3.0/modules/pam_pwhistory/opasswd.c.pwhhelper Linux-PAM-1.3.0/modules/pam_pwhistory/opasswd.c
--- Linux-PAM-1.3.0/modules/pam_pwhistory/opasswd.c.pwhhelper 2016-03-24 12:45:42.000000000 +0100
+++ Linux-PAM-1.3.0/modules/pam_pwhistory/opasswd.c 2016-05-06 15:18:42.307637933 +0200
dist_noinst_DATA = README
-include $(top_srcdir)/Make.xml.rules
diff -up Linux-PAM-1.4.0/modules/pam_pwhistory/opasswd.c.pwhhelper Linux-PAM-1.4.0/modules/pam_pwhistory/opasswd.c
--- Linux-PAM-1.4.0/modules/pam_pwhistory/opasswd.c.pwhhelper 2020-06-08 12:17:27.000000000 +0200
+++ Linux-PAM-1.4.0/modules/pam_pwhistory/opasswd.c 2020-06-22 13:24:02.424365617 +0200
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2008 Thorsten Kukuk <kukuk@suse.de>
@ -74,7 +76,7 @@ diff -up Linux-PAM-1.3.0/modules/pam_pwhistory/opasswd.c.pwhhelper Linux-PAM-1.3
+#include <stdarg.h>
#include <sys/stat.h>
#if defined (HAVE_XCRYPT_H)
#if defined HAVE_LIBXCRYPT
@@ -55,7 +58,14 @@
#include <crypt.h>
#endif
@ -191,9 +193,9 @@ diff -up Linux-PAM-1.3.0/modules/pam_pwhistory/opasswd.c.pwhhelper Linux-PAM-1.3
{
retval = PAM_AUTHTOK_ERR;
if (oldpf)
diff -up Linux-PAM-1.3.0/modules/pam_pwhistory/opasswd.h.pwhhelper Linux-PAM-1.3.0/modules/pam_pwhistory/opasswd.h
--- Linux-PAM-1.3.0/modules/pam_pwhistory/opasswd.h.pwhhelper 2016-03-24 12:45:42.000000000 +0100
+++ Linux-PAM-1.3.0/modules/pam_pwhistory/opasswd.h 2016-05-06 15:18:42.307637933 +0200
diff -up Linux-PAM-1.4.0/modules/pam_pwhistory/opasswd.h.pwhhelper Linux-PAM-1.4.0/modules/pam_pwhistory/opasswd.h
--- Linux-PAM-1.4.0/modules/pam_pwhistory/opasswd.h.pwhhelper 2020-06-08 12:17:27.000000000 +0200
+++ Linux-PAM-1.4.0/modules/pam_pwhistory/opasswd.h 2020-06-22 13:13:23.722445347 +0200
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2008 Thorsten Kukuk <kukuk@suse.de>
@ -239,11 +241,11 @@ diff -up Linux-PAM-1.3.0/modules/pam_pwhistory/opasswd.h.pwhhelper Linux-PAM-1.3
+save_old_pass, const char *user, int howmany, int debug);
#endif /* __OPASSWD_H__ */
diff -up Linux-PAM-1.3.0/modules/pam_pwhistory/pam_pwhistory.c.pwhhelper Linux-PAM-1.3.0/modules/pam_pwhistory/pam_pwhistory.c
--- Linux-PAM-1.3.0/modules/pam_pwhistory/pam_pwhistory.c.pwhhelper 2016-04-04 11:22:28.000000000 +0200
+++ Linux-PAM-1.3.0/modules/pam_pwhistory/pam_pwhistory.c 2016-05-06 15:19:31.610785512 +0200
@@ -1,6 +1,7 @@
/*
diff -up Linux-PAM-1.4.0/modules/pam_pwhistory/pam_pwhistory.c.pwhhelper Linux-PAM-1.4.0/modules/pam_pwhistory/pam_pwhistory.c
--- Linux-PAM-1.4.0/modules/pam_pwhistory/pam_pwhistory.c.pwhhelper 2020-06-08 12:17:27.000000000 +0200
+++ Linux-PAM-1.4.0/modules/pam_pwhistory/pam_pwhistory.c 2020-06-22 13:25:23.107497539 +0200
@@ -3,6 +3,7 @@
*
* Copyright (c) 2008, 2012 Thorsten Kukuk
* Author: Thorsten Kukuk <kukuk@thkukuk.de>
+ * Copyright (c) 2013 Red Hat, Inc.
@ -266,15 +268,15 @@ diff -up Linux-PAM-1.3.0/modules/pam_pwhistory/pam_pwhistory.c.pwhhelper Linux-P
#include <security/pam_modules.h>
#include <security/pam_modutil.h>
@@ -59,6 +64,7 @@
#include "opasswd.h"
@@ -60,6 +65,7 @@
#include "pam_inline.h"
#define DEFAULT_BUFLEN 2048
+#define MAX_FD_NO 20000
struct options_t {
int debug;
@@ -102,6 +108,184 @@ parse_option (pam_handle_t *pamh, const
@@ -105,6 +111,184 @@ parse_option (pam_handle_t *pamh, const
pam_syslog (pamh, LOG_ERR, "pam_pwhistory: unknown option: %s", argv);
}
@ -459,7 +461,7 @@ diff -up Linux-PAM-1.3.0/modules/pam_pwhistory/pam_pwhistory.c.pwhhelper Linux-P
/* This module saves the current crypted password in /etc/security/opasswd
and then compares the new password with all entries in this file. */
@@ -109,7 +293,6 @@ parse_option (pam_handle_t *pamh, const
@@ -112,7 +296,6 @@ parse_option (pam_handle_t *pamh, const
int
pam_sm_chauthtok (pam_handle_t *pamh, int flags, int argc, const char **argv)
{
@ -467,7 +469,7 @@ diff -up Linux-PAM-1.3.0/modules/pam_pwhistory/pam_pwhistory.c.pwhhelper Linux-P
const char *newpass;
const char *user;
int retval, tries;
@@ -154,31 +337,13 @@ pam_sm_chauthtok (pam_handle_t *pamh, in
@@ -148,31 +331,13 @@ pam_sm_chauthtok (pam_handle_t *pamh, in
return PAM_SUCCESS;
}
@ -505,7 +507,7 @@ diff -up Linux-PAM-1.3.0/modules/pam_pwhistory/pam_pwhistory.c.pwhhelper Linux-P
newpass = NULL;
tries = 0;
@@ -207,8 +372,11 @@ pam_sm_chauthtok (pam_handle_t *pamh, in
@@ -201,8 +366,11 @@ pam_sm_chauthtok (pam_handle_t *pamh, in
if (options.debug)
pam_syslog (pamh, LOG_DEBUG, "check against old password file");
@ -519,9 +521,81 @@ diff -up Linux-PAM-1.3.0/modules/pam_pwhistory/pam_pwhistory.c.pwhhelper Linux-P
{
if (getuid() || options.enforce_for_root ||
(flags & PAM_CHANGE_EXPIRED_AUTHTOK))
diff -up Linux-PAM-1.3.0/modules/pam_pwhistory/pwhistory_helper.c.pwhhelper Linux-PAM-1.3.0/modules/pam_pwhistory/pwhistory_helper.c
--- Linux-PAM-1.3.0/modules/pam_pwhistory/pwhistory_helper.c.pwhhelper 2016-05-06 15:18:42.308637957 +0200
+++ Linux-PAM-1.3.0/modules/pam_pwhistory/pwhistory_helper.c 2016-05-06 15:18:42.308637957 +0200
diff -up Linux-PAM-1.4.0/modules/pam_pwhistory/pwhistory_helper.8.xml.pwhhelper Linux-PAM-1.4.0/modules/pam_pwhistory/pwhistory_helper.8.xml
--- Linux-PAM-1.4.0/modules/pam_pwhistory/pwhistory_helper.8.xml.pwhhelper 2020-06-22 13:13:23.723445361 +0200
+++ Linux-PAM-1.4.0/modules/pam_pwhistory/pwhistory_helper.8.xml 2020-06-22 13:13:23.723445361 +0200
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="pwhistory_helper">
+
+ <refmeta>
+ <refentrytitle>pwhistory_helper</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id="pwhistory_helper-name">
+ <refname>pwhistory_helper</refname>
+ <refpurpose>Helper binary that transfers password hashes from passwd or shadow to opasswd</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pwhistory_helper-cmdsynopsis">
+ <command>pwhistory_helper</command>
+ <arg choice="opt">
+ ...
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="pwhistory_helper-description">
+
+ <title>DESCRIPTION</title>
+
+ <para>
+ <emphasis>pwhistory_helper</emphasis> is a helper program for the
+ <emphasis>pam_pwhistory</emphasis> module that transfers password hashes
+ from passwd or shadow file to the opasswd file and checks a password
+ supplied by user against the existing hashes in the opasswd file.
+ </para>
+
+ <para>
+ The purpose of the helper is to enable tighter confinement of
+ login and password changing services. The helper is thus called only
+ when SELinux is enabled on the system.
+ </para>
+
+ <para>
+ The interface of the helper - command line options, and input/output
+ data format are internal to the <emphasis>pam_pwhistory</emphasis>
+ module and it should not be called directly from applications.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pwhistory_helper-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>pam_pwhistory</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pwhistory_helper-author'>
+ <title>AUTHOR</title>
+ <para>
+ Written by Tomas Mraz based on the code originally in
+ <emphasis>pam_pwhistory and pam_unix</emphasis> modules.
+ </para>
+ </refsect1>
+
+</refentry>
diff -up Linux-PAM-1.4.0/modules/pam_pwhistory/pwhistory_helper.c.pwhhelper Linux-PAM-1.4.0/modules/pam_pwhistory/pwhistory_helper.c
--- Linux-PAM-1.4.0/modules/pam_pwhistory/pwhistory_helper.c.pwhhelper 2020-06-22 13:13:23.723445361 +0200
+++ Linux-PAM-1.4.0/modules/pam_pwhistory/pwhistory_helper.c 2020-06-22 13:13:23.723445361 +0200
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2013 Red Hat, Inc.
@ -732,75 +806,3 @@ diff -up Linux-PAM-1.3.0/modules/pam_pwhistory/pwhistory_helper.c.pwhhelper Linu
+ return PAM_SYSTEM_ERR;
+}
+
diff -up Linux-PAM-1.3.0/modules/pam_pwhistory/pwhistory_helper.8.xml.pwhhelper Linux-PAM-1.3.0/modules/pam_pwhistory/pwhistory_helper.8.xml
--- Linux-PAM-1.3.0/modules/pam_pwhistory/pwhistory_helper.8.xml.pwhhelper 2016-05-06 15:18:42.308637957 +0200
+++ Linux-PAM-1.3.0/modules/pam_pwhistory/pwhistory_helper.8.xml 2016-05-06 15:18:42.308637957 +0200
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="pwhistory_helper">
+
+ <refmeta>
+ <refentrytitle>pwhistory_helper</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id="pwhistory_helper-name">
+ <refname>pwhistory_helper</refname>
+ <refpurpose>Helper binary that transfers password hashes from passwd or shadow to opasswd</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pwhistory_helper-cmdsynopsis">
+ <command>pwhistory_helper</command>
+ <arg choice="opt">
+ ...
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="pwhistory_helper-description">
+
+ <title>DESCRIPTION</title>
+
+ <para>
+ <emphasis>pwhistory_helper</emphasis> is a helper program for the
+ <emphasis>pam_pwhistory</emphasis> module that transfers password hashes
+ from passwd or shadow file to the opasswd file and checks a password
+ supplied by user against the existing hashes in the opasswd file.
+ </para>
+
+ <para>
+ The purpose of the helper is to enable tighter confinement of
+ login and password changing services. The helper is thus called only
+ when SELinux is enabled on the system.
+ </para>
+
+ <para>
+ The interface of the helper - command line options, and input/output
+ data format are internal to the <emphasis>pam_pwhistory</emphasis>
+ module and it should not be called directly from applications.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pwhistory_helper-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>pam_pwhistory</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pwhistory_helper-author'>
+ <title>AUTHOR</title>
+ <para>
+ Written by Tomas Mraz based on the code originally in
+ <emphasis>pam_pwhistory and pam_unix</emphasis> modules.
+ </para>
+ </refsect1>
+
+</refentry>

View File

@ -0,0 +1,25 @@
diff -up Linux-PAM-1.4.0/configure.ac.redhat-modules Linux-PAM-1.4.0/configure.ac
--- Linux-PAM-1.4.0/configure.ac.redhat-modules 2020-06-08 12:17:27.000000000 +0200
+++ Linux-PAM-1.4.0/configure.ac 2020-06-22 12:55:55.889827909 +0200
@@ -712,6 +712,8 @@ AC_CONFIG_FILES([Makefile libpam/Makefil
po/Makefile.in \
Make.xml.rules \
modules/Makefile \
+ modules/pam_chroot/Makefile modules/pam_console/Makefile \
+ modules/pam_postgresok/Makefile \
modules/pam_access/Makefile modules/pam_cracklib/Makefile \
modules/pam_debug/Makefile modules/pam_deny/Makefile \
modules/pam_echo/Makefile modules/pam_env/Makefile \
diff -up Linux-PAM-1.4.0/modules/Makefile.am.redhat-modules Linux-PAM-1.4.0/modules/Makefile.am
--- Linux-PAM-1.4.0/modules/Makefile.am.redhat-modules 2020-06-22 12:55:55.889827909 +0200
+++ Linux-PAM-1.4.0/modules/Makefile.am 2020-06-22 12:59:19.718670992 +0200
@@ -56,6 +56,9 @@ SUBDIRS := \
pam_debug \
pam_deny \
pam_echo \
+ pam_chroot \
+ pam_console \
+ pam_postgresok \
pam_env \
pam_exec \
pam_faildelay \

View File

@ -1,9 +1,9 @@
%global pam_redhat_version 1.1.2
%global pam_redhat_version 1.1.3
Summary: An extensible library which provides authentication for applications
Name: pam
Version: 1.3.1
Release: 28%{?dist}
Version: 1.4.0
Release: 1%{?dist}
# The library is BSD licensed with option to relicense as GPLv2+
# - this option is redundant as the BSD license allows that anyway.
# pam_timestamp, pam_loginuid, and pam_console modules are GPLv2+.
@ -24,58 +24,27 @@ Source15: pamtmp.conf
Source16: postlogin.pamd
Source17: postlogin.5
Source18: https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
Patch1: pam-1.3.1-redhat-modules.patch
Patch9: pam-1.3.1-noflex.patch
Patch10: pam-1.1.3-nouserenv.patch
Patch1: pam-1.4.0-redhat-modules.patch
Patch9: pam-1.4.0-noflex.patch
Patch10: pam-1.4.0-nouserenv.patch
Patch13: pam-1.1.6-limits-user.patch
Patch15: pam-1.1.8-full-relro.patch
Patch15: pam-1.4.0-full-relro.patch
# Upstreamed partially
Patch29: pam-1.3.0-pwhistory-helper.patch
Patch29: pam-1.4.0-pwhistory-helper.patch
Patch31: pam-1.1.8-audit-user-mgmt.patch
Patch33: pam-1.3.0-unix-nomsg.patch
Patch34: pam-1.3.1-coverity.patch
# https://github.com/linux-pam/linux-pam/commit/a2b72aeb86f297d349bc9e6a8f059fedf97a499a
Patch36: pam-1.3.1-unix-remove-obsolete-_unix_read_password-prototype.patch
# https://github.com/linux-pam/linux-pam/commit/f7abb8c1ef3aa31e6c2564a8aaf69683a77c2016.patch
Patch37: pam-1.3.1-unix-bcrypt_b.patch
# https://github.com/linux-pam/linux-pam/commit/dce80b3f11b3c3aa137d18f22699809094dd64b6
Patch38: pam-1.3.1-unix-gensalt-autoentropy.patch
# https://github.com/linux-pam/linux-pam/commit/4da9febc39b955892a30686e8396785b96bb8ba5
Patch39: pam-1.3.1-unix-crypt_checksalt.patch
# https://github.com/linux-pam/linux-pam/commit/16bd523f85ede9fa9115f80e826f2d803d7e61d4
Patch40: pam-1.3.1-unix-yescrypt.patch
# To be upstreamed soon.
Patch41: pam-1.3.1-unix-no-fallback.patch
# https://github.com/linux-pam/linux-pam/commit/f9c9c72121eada731e010ab3620762bcf63db08f
# https://github.com/linux-pam/linux-pam/commit/8eaf5570cf011148a0b55c53570df5edaafebdb0
Patch42: pam-1.3.1-motd-multiple-paths.patch
# https://github.com/linux-pam/linux-pam/commit/86eed7ca01864b9fd17099e57f10f2b9b6b568a1
Patch43: pam-1.3.1-unix-checksalt_syslog.patch
# https://github.com/linux-pam/linux-pam/commit/d8d11db2cef65da5d2afa7acf21aa9c8cd88abed
Patch44: pam-1.3.1-unix-fix_checksalt_syslog.patch
Patch45: pam-1.3.1-namespace-mntopts.patch
Patch46: pam-1.3.1-lastlog-no-showfailed.patch
Patch47: pam-1.3.1-lastlog-unlimited-fsize.patch
Patch48: pam-1.3.1-unix-improve-logging.patch
Patch49: pam-1.3.1-tty-audit-manfix.patch
Patch50: pam-1.3.1-fds-closing.patch
Patch51: pam-1.3.1-authtok-verify-fix.patch
Patch52: pam-1.3.1-add-pam_usertype.patch
Patch53: pam-1.3.1-add-pam_usertype-fix-backport.patch
Patch54: pam-1.3.1-pam_selinux-check-unknown-objects.patch
# Upstreamed
Patch55: pam-1.3.1-audit-error.patch
# Upstreamed
Patch56: pam-1.3.1-pam-modutil-close-write.patch
# Upstreamed
Patch57: pam-1.3.1-determinine-user-exists.patch
# Upstreamed
Patch34: pam-1.4.0-coverity.patch
# https://github.com/linux-pam/linux-pam/commit/af0faf666c5008e54dfe43684f210e3581ff1bca
# https://github.com/linux-pam/linux-pam/commit/0e9b286afe1224b91ff00936058b084ad4b776e4
Patch57: pam-1.4.0-determine-user-exists.patch
# https://github.com/linux-pam/linux-pam/commit/395915dae1571e10e2766c999974de864655ea3a
Patch58: pam-1.3.1-faillock-change-file-permissions.patch
%global _pamlibdir %{_libdir}
%global _moduledir %{_libdir}/security
%global _secconfdir %{_sysconfdir}/security
%global _pamconfdir %{_sysconfdir}/pam.d
%global _systemdlibdir /usr/lib/systemd/system
%if %{?WITH_SELINUX:0}%{!?WITH_SELINUX:1}
%global WITH_SELINUX 1
@ -85,12 +54,10 @@ Patch58: pam-1.3.1-faillock-change-file-permissions.patch
%endif
%global _performance_build 1
Recommends: cracklib-dicts >= 2.8
Requires: libpwquality >= 0.9.9
BuildRequires: autoconf >= 2.60
BuildRequires: automake, libtool
BuildRequires: bison, flex, sed
BuildRequires: cracklib-devel
BuildRequires: perl-interpreter, pkgconfig, gettext-devel
BuildRequires: libtirpc-devel, libnsl2-devel
%if %{WITH_AUDIT}
@ -156,28 +123,7 @@ cp %{SOURCE18} .
%patch31 -p1 -b .audit-user-mgmt
%patch33 -p1 -b .nomsg
%patch34 -p1 -b .coverity
%patch36 -p1 -b .remove-prototype
%patch37 -p1 -b .bcrypt_b
%patch38 -p1 -b .gensalt-autoentropy
%patch39 -p1 -b .crypt_checksalt
%patch40 -p1 -b .yescrypt
%patch41 -p1 -b .no-fallback
%patch42 -p1 -b .multiple-paths
%patch43 -p1 -b .checksalt_syslog
%patch44 -p1 -b .fix_checksalt_syslog
%patch45 -p1 -b .mntopts
%patch46 -p1 -b .no-showfailed
%patch47 -p1 -b .unlimited-fsize
%patch48 -p1 -b .improve-logging
%patch49 -p1 -b .tty-audit-manfix
%patch50 -p1 -b .fds-closing
%patch51 -p1 -b .authtok-verify-fix
%patch52 -p1 -b .add-pam_usertype
%patch53 -p1 -b .add-pam_usertype-backport
%patch54 -p1 -b .pam_selinux-check-unknown-objects
%patch55 -p1 -b .audit-error
%patch56 -p1 -b .pam-modutil-close-write
%patch57 -p1 -b .determinine-user-exists
%patch57 -p1 -b .determine-user-exists
%patch58 -p1 -b .faillock-change-file-permissions
autoreconf -i
@ -284,8 +230,10 @@ if [ -d ${dir} ] ; then
%if ! %{WITH_AUDIT}
[ ${dir} = "modules/pam_tty_audit" ] && continue
%endif
# pam_tally, pam_tally2 and pam_cracklib have been deprecated and will be removed in next upstream release. So, they have been removed downstream
[ ${dir} = "modules/pam_tally" ] && continue
[ ${dir} = "modules/pam_tally2" ] && continue
[ ${dir} = "modules/pam_cracklib" ] && continue
if ! ls -1 $RPM_BUILD_ROOT%{_moduledir}/`basename ${dir}`*.so ; then
echo ERROR `basename ${dir}` did not build a module.
exit 1
@ -322,6 +270,7 @@ done
%{_pamlibdir}/libpamc.so.*
%{_pamlibdir}/libpam_misc.so.*
%{_sbindir}/pam_console_apply
%{_sbindir}/pam_namespace_helper
%{_sbindir}/faillock
%attr(4755,root,root) %{_sbindir}/pam_timestamp_check
%attr(4755,root,root) %{_sbindir}/unix_chkpwd
@ -332,7 +281,6 @@ done
%{_moduledir}/pam_access.so
%{_moduledir}/pam_chroot.so
%{_moduledir}/pam_console.so
%{_moduledir}/pam_cracklib.so
%{_moduledir}/pam_debug.so
%{_moduledir}/pam_deny.so
%{_moduledir}/pam_echo.so
@ -366,6 +314,7 @@ done
%{_moduledir}/pam_sepermit.so
%endif
%{_moduledir}/pam_securetty.so
%{_moduledir}/pam_setquota.so
%{_moduledir}/pam_shells.so
%{_moduledir}/pam_stress.so
%{_moduledir}/pam_succeed_if.so
@ -386,6 +335,7 @@ done
%{_moduledir}/pam_wheel.so
%{_moduledir}/pam_xauth.so
%{_moduledir}/pam_filter
%{_systemdlibdir}/pam_namespace.service
%dir %{_secconfdir}
%config(noreplace) %{_secconfdir}/access.conf
%config(noreplace) %{_secconfdir}/chroot.conf
@ -431,6 +381,11 @@ done
%doc doc/sag/*.txt doc/sag/html
%changelog
* Wed Jun 24 2020 Iker Pedrosa <ipedrosa@redhat.com> - 1.4.0-1
- Rebased to release 1.4.0
- Rebased to pam-redhat-1.1.3
- Removed pam_cracklib as it has been deprecated
* Mon Jun 22 2020 Iker Pedrosa <ipedrosa@redhat.com> - 1.3.1-28
- pam_faillock: change /run/faillock/$USER permissions to 0660 (#1661822)

View File

@ -1,3 +1,2 @@
SHA512 (Linux-PAM-1.3.1.tar.xz) = 6bc8e2a5b64686f0a23846221c5228c88418ba485b17c53b3a12f91262b5bb73566d6b6a5daa1f63bbae54310aee918b987e44a72ce809b4e7c668f0fadfe08e
SHA512 (Linux-PAM-1.3.1.tar.xz.asc) = 8b3ad3f4f29fad663e375296dca00f736b3de764f11d7b7aa615d00efe1c702c9060f244967f2d84d8ef3a342c3a1f8eba6dd52847df427bb3ce0ff765a8108a
SHA512 (pam-redhat-1.1.2.tar.bz2) = 9e70376a4b33d0e0df1a2f8158b25b540559f3c952a435574e619262f0d2da71d381336a06edee08a032c5096d7ae24cb7fc91a8cf8518dd5ad4f93d62b7d582
SHA512 (Linux-PAM-1.4.0.tar.xz) = 26eda95c45598a500bc142da4d1abf93d03b3bbb0f2390fa87c72dcbffa208dbfa115c0b411095c31ee9955e36422ccf3e2df3bd486818fafffef8c4310798c4
SHA512 (Linux-PAM-1.4.0.tar.xz.asc) = df8d35840838854b2cd6fdb5763e6b3a713dda839c1bc36e752243e76ea0414e99351b32691a6e08f2ee07013c6c4142f21e469374ec06be66887384207933b4