diff --git a/SOURCES/pam-1.1.8-authtok-verified.patch b/SOURCES/pam-1.1.8-authtok-verified.patch
new file mode 100644
index 0000000..a28e968
--- /dev/null
+++ b/SOURCES/pam-1.1.8-authtok-verified.patch
@@ -0,0 +1,73 @@
+diff --git a/libpam/pam_get_authtok.c b/libpam/pam_get_authtok.c
+index 800c6e5..3cdec5e 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,
+@@ -239,6 +247,7 @@ pam_get_authtok_verify (pam_handle_t *pamh, const char **authtok,
+
+ if (strcmp (*authtok, resp) != 0)
+ {
++ pamh->authtok_verified = 0;
+ pam_set_item (pamh, PAM_AUTHTOK, NULL);
+ pam_error (pamh, MISTYPED_PASS);
+ _pam_overwrite (resp);
+@@ -252,5 +261,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 *)
diff --git a/SOURCES/pam-1.1.8-loginuid-containers.patch b/SOURCES/pam-1.1.8-loginuid-containers.patch
new file mode 100644
index 0000000..b27f237
--- /dev/null
+++ b/SOURCES/pam-1.1.8-loginuid-containers.patch
@@ -0,0 +1,147 @@
+diff -up Linux-PAM-1.1.8/modules/pam_loginuid/pam_loginuid.8.xml.containers Linux-PAM-1.1.8/modules/pam_loginuid/pam_loginuid.8.xml
+--- Linux-PAM-1.1.8/modules/pam_loginuid/pam_loginuid.8.xml.containers 2013-06-18 16:11:21.000000000 +0200
++++ Linux-PAM-1.1.8/modules/pam_loginuid/pam_loginuid.8.xml 2019-08-06 14:54:33.491053203 +0200
+@@ -69,14 +69,31 @@
+
+
+
++ PAM_SUCCESS
++
++
++ The loginuid value is set and auditd is running if check requested.
++
++
++
++
++ PAM_IGNORE
++
++
++ The /proc/self/loginuid file is not present on the system or the
++ login process runs inside uid namespace and kernel does not support
++ overwriting loginuid.
++
++
++
++
+ PAM_SESSION_ERR
+
+
+- An error occurred during session management.
++ Any other error prevented setting loginuid or auditd is not running.
+
+
+
+-
+
+
+
+diff -up Linux-PAM-1.1.8/modules/pam_loginuid/pam_loginuid.c.containers Linux-PAM-1.1.8/modules/pam_loginuid/pam_loginuid.c
+--- Linux-PAM-1.1.8/modules/pam_loginuid/pam_loginuid.c.containers 2017-11-02 14:04:25.898425389 +0100
++++ Linux-PAM-1.1.8/modules/pam_loginuid/pam_loginuid.c 2019-08-06 14:51:31.905761192 +0200
+@@ -47,25 +47,56 @@
+
+ /*
+ * This function writes the loginuid to the /proc system. It returns
+- * 0 on success and 1 on failure.
++ * PAM_SUCCESS on success,
++ * PAM_IGNORE when /proc/self/loginuid does not exist,
++ * PAM_SESSION_ERR in case of any other error.
+ */
+ static int set_loginuid(pam_handle_t *pamh, uid_t uid)
+ {
+- int fd, count, rc = 0;
+- char loginuid[24];
++ int fd, count, rc = PAM_SESSION_ERR;
++ char loginuid[24], buf[24];
++ static const char host_uid_map[] = " 0 0 4294967295\n";
++ char uid_map[sizeof(host_uid_map)];
++
++ /* loginuid in user namespaces currently isn't writable and in some
++ case, not even readable, so consider any failure as ignorable (but try
++ anyway, in case we hit a kernel which supports it). */
++ 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)
++ rc = PAM_IGNORE;
++ close(fd);
++ }
+
+- count = snprintf(loginuid, sizeof(loginuid), "%lu", (unsigned long)uid);
+- fd = open("/proc/self/loginuid", O_NOFOLLOW|O_WRONLY|O_TRUNC);
++ fd = open("/proc/self/loginuid", O_NOFOLLOW|O_RDWR);
+ if (fd < 0) {
+- if (errno != ENOENT) {
+- rc = 1;
+- pam_syslog(pamh, LOG_ERR,
+- "Cannot open /proc/self/loginuid: %m");
++ if (errno == ENOENT) {
++ rc = PAM_IGNORE;
++ }
++ if (rc != PAM_IGNORE) {
++ pam_syslog(pamh, LOG_ERR, "Cannot open %s: %m",
++ "/proc/self/loginuid");
+ }
+ return rc;
+ }
+- if (pam_modutil_write(fd, loginuid, count) != count)
+- rc = 1;
++
++ count = snprintf(loginuid, sizeof(loginuid), "%lu", (unsigned long)uid);
++ if (pam_modutil_read(fd, buf, sizeof(buf)) == count &&
++ memcmp(buf, loginuid, count) == 0) {
++ rc = PAM_SUCCESS;
++ goto done; /* already correct */
++ }
++ if (lseek(fd, 0, SEEK_SET) == 0 && ftruncate(fd, 0) == 0 &&
++ pam_modutil_write(fd, loginuid, count) == count) {
++ rc = PAM_SUCCESS;
++ } else {
++ if (rc != PAM_IGNORE) {
++ pam_syslog(pamh, LOG_ERR, "Error writing %s: %m",
++ "/proc/self/loginuid");
++ }
++ }
++ done:
+ close(fd);
+ return rc;
+ }
+@@ -165,6 +196,7 @@ _pam_loginuid(pam_handle_t *pamh, int fl
+ {
+ const char *user = NULL;
+ struct passwd *pwd;
++ int ret;
+ #ifdef HAVE_LIBAUDIT
+ int require_auditd = 0;
+ #endif
+@@ -183,9 +215,14 @@ _pam_loginuid(pam_handle_t *pamh, int fl
+ return PAM_SESSION_ERR;
+ }
+
+- if (set_loginuid(pamh, pwd->pw_uid)) {
+- pam_syslog(pamh, LOG_ERR, "set_loginuid failed\n");
+- return PAM_SESSION_ERR;
++ ret = set_loginuid(pamh, pwd->pw_uid);
++ switch (ret) {
++ case PAM_SUCCESS:
++ case PAM_IGNORE:
++ break;
++ default:
++ pam_syslog(pamh, LOG_ERR, "set_loginuid failed");
++ return ret;
+ }
+
+ #ifdef HAVE_LIBAUDIT
+@@ -199,10 +236,10 @@ _pam_loginuid(pam_handle_t *pamh, int fl
+ int rc = check_auditd();
+ if (rc != PAM_SUCCESS)
+ pam_syslog(pamh, LOG_ERR, "required running auditd not detected");
+- return rc;
++ return rc != PAM_SUCCESS ? rc : ret;
+ } else
+ #endif
+- return PAM_SUCCESS;
++ return ret;
+ }
+
+ /*
diff --git a/SOURCES/pam-1.1.8-man-fixes.patch b/SOURCES/pam-1.1.8-man-fixes.patch
new file mode 100644
index 0000000..5942d94
--- /dev/null
+++ b/SOURCES/pam-1.1.8-man-fixes.patch
@@ -0,0 +1,41 @@
+diff -up Linux-PAM-1.1.8/modules/pam_tty_audit/pam_tty_audit.8.xml.manfix Linux-PAM-1.1.8/modules/pam_tty_audit/pam_tty_audit.8.xml
+--- Linux-PAM-1.1.8/modules/pam_tty_audit/pam_tty_audit.8.xml.manfix 2017-11-02 14:04:25.908425629 +0100
++++ Linux-PAM-1.1.8/modules/pam_tty_audit/pam_tty_audit.8.xml 2019-08-06 14:38:58.826456399 +0200
+@@ -149,6 +149,13 @@
+ greater than or equal to min_uid will be
+ matched.
+
++
++ Please note that passwords in some circumstances may be logged by TTY auditing
++ even if the is not used. For example all input to
++ a 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.
++
+
+
+
+diff -up Linux-PAM-1.1.8/modules/pam_wheel/pam_wheel.8.xml.manfix Linux-PAM-1.1.8/modules/pam_wheel/pam_wheel.8.xml
+--- Linux-PAM-1.1.8/modules/pam_wheel/pam_wheel.8.xml.manfix 2013-06-18 16:11:21.000000000 +0200
++++ Linux-PAM-1.1.8/modules/pam_wheel/pam_wheel.8.xml 2019-08-06 14:38:01.938442949 +0200
+@@ -43,8 +43,8 @@
+ DESCRIPTION
+
+ The pam_wheel PAM module is used to enforce the so-called
+- wheel group. By default it permits root
+- access to the system if the applicant user is a member of the
++ wheel group. By default it permits
++ access to the target user if the applicant user is a member of the
+ wheel group. If no group with this name exist,
+ the module is using the group with the group-ID
+ 0.
+@@ -97,7 +97,8 @@
+
+
+
+- The check for wheel membership is done only.
++ The check for wheel membership is done only when the target user
++ UID is 0.
+
+
+
diff --git a/SOURCES/pam-1.1.8-unix-max-fd-no.patch b/SOURCES/pam-1.1.8-unix-max-fd-no.patch
new file mode 100644
index 0000000..8612f1c
--- /dev/null
+++ b/SOURCES/pam-1.1.8-unix-max-fd-no.patch
@@ -0,0 +1,12 @@
+diff -up Linux-PAM-1.1.8/modules/pam_unix/support.h.max-fd-no Linux-PAM-1.1.8/modules/pam_unix/support.h
+--- Linux-PAM-1.1.8/modules/pam_unix/support.h.max-fd-no 2017-11-02 14:04:25.895425318 +0100
++++ Linux-PAM-1.1.8/modules/pam_unix/support.h 2019-08-06 14:46:59.237125151 +0200
+@@ -141,7 +141,7 @@ static const UNIX_Ctrls unix_args[UNIX_C
+
+ #define UNIX_DEFAULTS (unix_args[UNIX__NONULL].flag)
+
+-#define MAX_FD_NO 2000000
++#define MAX_FD_NO 65535
+
+ /* use this to free strings. ESPECIALLY password strings */
+
diff --git a/SPECS/pam.spec b/SPECS/pam.spec
index 0faa1d3..a0ec676 100644
--- a/SPECS/pam.spec
+++ b/SPECS/pam.spec
@@ -3,7 +3,7 @@
Summary: An extensible library which provides authentication for applications
Name: pam
Version: 1.1.8
-Release: 22%{?dist}
+Release: 23%{?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+.
@@ -69,6 +69,10 @@ Patch54: pam-1.1.8-man-space.patch
Patch55: pam-1.1.8-tty-audit-uid-range.patch
Patch56: pam-1.1.8-faillock-admin-group.patch
Patch57: pam-1.1.8-mkhomedir-inroot.patch
+Patch58: pam-1.1.8-authtok-verified.patch
+Patch59: pam-1.1.8-man-fixes.patch
+Patch60: pam-1.1.8-unix-max-fd-no.patch
+Patch61: pam-1.1.8-loginuid-containers.patch
%define _pamlibdir %{_libdir}
%define _moduledir %{_libdir}/security
@@ -171,6 +175,10 @@ mv pam-redhat-%{pam_redhat_version}/* modules
%patch55 -p1 -b .uid-range
%patch56 -p1 -b .admin-group
%patch57 -p1 -b .mkhomedir-inroot
+%patch58 -p1 -b .authtok-verified
+%patch59 -p1 -b .manfix
+%patch60 -p1 -b .max-fd-no
+%patch61 -p1 -b .containers
%build
autoreconf -i
@@ -419,6 +427,13 @@ fi
%doc doc/adg/*.txt doc/adg/html
%changelog
+* Tue Aug 6 2019 Tomáš Mráz 1.1.8-23
+- pam_get_authtok_verify: ensure no double verification happens
+- manual page fixes for pam_tty_audit and pam_wheel
+- pam_unix: lower the excessive maximum number of closed fd descriptors
+ when spawning handlers
+- pam_loginuid: do not prevent login in unprivileged containers
+
* Fri Nov 3 2017 Tomáš Mráz 1.1.8-22
- pam_mkhomedir: do not fail creating parent dir if in /