diff --git a/SOURCES/pam-1.3.1-audit-error.patch b/SOURCES/pam-1.3.1-audit-error.patch
new file mode 100644
index 0000000..f01172b
--- /dev/null
+++ b/SOURCES/pam-1.3.1-audit-error.patch
@@ -0,0 +1,35 @@
+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
+
diff --git a/SOURCES/pam-1.3.1-pam-modutil-close-write.patch b/SOURCES/pam-1.3.1-pam-modutil-close-write.patch
new file mode 100644
index 0000000..611e855
--- /dev/null
+++ b/SOURCES/pam-1.3.1-pam-modutil-close-write.patch
@@ -0,0 +1,74 @@
+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
+
diff --git a/SOURCES/pam-1.3.1-pam-usertype.patch b/SOURCES/pam-1.3.1-pam-usertype.patch
new file mode 100644
index 0000000..bada491
--- /dev/null
+++ b/SOURCES/pam-1.3.1-pam-usertype.patch
@@ -0,0 +1,712 @@
+diff -up Linux-PAM-1.3.1/configure.ac.pam-usertype Linux-PAM-1.3.1/configure.ac
+--- Linux-PAM-1.3.1/configure.ac.pam-usertype	2020-05-15 10:03:27.247468160 +0200
++++ Linux-PAM-1.3.1/configure.ac	2020-05-15 10:03:27.270468089 +0200
+@@ -606,6 +606,27 @@ AC_SUBST([HAVE_KEY_MANAGEMENT], $HAVE_KE
+ 
+ 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/Makefil
+ 	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 -up Linux-PAM-1.3.1/modules/Makefile.am.pam-usertype Linux-PAM-1.3.1/modules/Makefile.am
+--- Linux-PAM-1.3.1/modules/Makefile.am.pam-usertype	2020-05-15 10:03:27.247468160 +0200
++++ Linux-PAM-1.3.1/modules/Makefile.am	2020-05-15 10:03:27.270468089 +0200
+@@ -12,7 +12,7 @@ SUBDIRS = pam_access pam_cracklib pam_de
+ 	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 -up Linux-PAM-1.3.1/modules/pam_usertype/Makefile.am.pam-usertype Linux-PAM-1.3.1/modules/pam_usertype/Makefile.am
+--- Linux-PAM-1.3.1/modules/pam_usertype/Makefile.am.pam-usertype	2020-05-15 10:03:27.270468089 +0200
++++ Linux-PAM-1.3.1/modules/pam_usertype/Makefile.am	2020-05-15 10:03:27.270468089 +0200
+@@ -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 -up Linux-PAM-1.3.1/modules/pam_usertype/pam_usertype.8.xml.pam-usertype Linux-PAM-1.3.1/modules/pam_usertype/pam_usertype.8.xml
+--- Linux-PAM-1.3.1/modules/pam_usertype/pam_usertype.8.xml.pam-usertype	2020-05-15 10:03:27.270468089 +0200
++++ Linux-PAM-1.3.1/modules/pam_usertype/pam_usertype.8.xml	2020-05-15 10:03:27.270468089 +0200
+@@ -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 -up Linux-PAM-1.3.1/modules/pam_usertype/pam_usertype.c.pam-usertype Linux-PAM-1.3.1/modules/pam_usertype/pam_usertype.c
+--- Linux-PAM-1.3.1/modules/pam_usertype/pam_usertype.c.pam-usertype	2020-05-15 10:03:27.270468089 +0200
++++ Linux-PAM-1.3.1/modules/pam_usertype/pam_usertype.c	2020-05-15 10:16:08.053198025 +0200
+@@ -0,0 +1,394 @@
++/******************************************************************************
++ * 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>
++#include <stdio.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
++
++/* lookup a value for key in login.defs file or similar key value format */
++char *
++pam_usertype_search_key(pam_handle_t *pamh UNUSED,
++		       const char *file_name,
++		       const char *key)
++{
++	FILE *fp;
++	char *buf = NULL;
++	size_t buflen = 0;
++	char *retval = NULL;
++
++	fp = fopen(file_name, "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;
++		if (cp[n - 1] == '\n')
++			cp[n - 1] = '\0';
++
++		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;
++
++		tmp = strsep (&cp, " \t=");
++		if (cp != NULL)
++			while (isspace((int)*cp) || *cp == '=')
++				++cp;
++		else
++			cp = "";
++
++		if (strcasecmp(tmp, key) == 0) {
++			retval = strdup(cp);
++			break;
++		}
++	}
++	fclose(fp);
++
++	free(buf);
++
++	return retval;
++}
++
++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_usertype_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 -up Linux-PAM-1.3.1/modules/pam_usertype/README.xml.pam-usertype Linux-PAM-1.3.1/modules/pam_usertype/README.xml
+--- Linux-PAM-1.3.1/modules/pam_usertype/README.xml.pam-usertype	2020-05-15 10:03:27.270468089 +0200
++++ Linux-PAM-1.3.1/modules/pam_usertype/README.xml	2020-05-15 10:03:27.270468089 +0200
+@@ -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 -up Linux-PAM-1.3.1/modules/pam_usertype/tst-pam_usertype.pam-usertype Linux-PAM-1.3.1/modules/pam_usertype/tst-pam_usertype
+--- Linux-PAM-1.3.1/modules/pam_usertype/tst-pam_usertype.pam-usertype	2020-05-15 10:03:27.270468089 +0200
++++ Linux-PAM-1.3.1/modules/pam_usertype/tst-pam_usertype	2020-05-15 10:03:27.270468089 +0200
+@@ -0,0 +1,2 @@
++#!/bin/sh
++../../tests/tst-dlopen .libs/pam_usertype.so
diff --git a/SPECS/pam.spec b/SPECS/pam.spec
index 315e533..af1f3e1 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.3.1
-Release: 8%{?dist}
+Release: 11%{?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+.
@@ -53,6 +53,12 @@ Patch41: pam-1.3.1-tty-audit-manfix.patch
 Patch42: pam-1.3.1-fds-closing.patch
 Patch43: pam-1.3.1-authtok-verify-fix.patch
 Patch44: pam-1.3.1-motd-manpage.patch
+# Upstreamed
+Patch45: pam-1.3.1-pam-usertype.patch
+# Upstreamed
+Patch46: pam-1.3.1-audit-error.patch
+# Upstreamed
+Patch47: pam-1.3.1-pam-modutil-close-write.patch
 
 %define _pamlibdir %{_libdir}
 %define _moduledir %{_libdir}/security
@@ -145,6 +151,9 @@ cp %{SOURCE18} .
 %patch42 -p1 -b .fds-closing
 %patch43 -p1 -b .authtok-verify-fix
 %patch44 -p1 -b .motd-manpage
+%patch45 -p1 -b .pam-usertype
+%patch46 -p1 -b .audit-error
+%patch47 -p1 -b .pam-modutil-close-write
 autoreconf -i
 
 %build
@@ -347,6 +356,7 @@ done
 %{_moduledir}/pam_unix_passwd.so
 %{_moduledir}/pam_unix_session.so
 %{_moduledir}/pam_userdb.so
+%{_moduledir}/pam_usertype.so
 %{_moduledir}/pam_warn.so
 %{_moduledir}/pam_wheel.so
 %{_moduledir}/pam_xauth.so
@@ -389,6 +399,16 @@ done
 %doc doc/specs/rfc86.0.txt
 
 %changelog
+* Fri May 15 2020 Iker Pedrosa <ipedrosa@redhat.com> 1.3.1-11
+- pam_usertype: fixed malformed patch
+
+* Tue Apr 21 2020 Iker Pedrosa <ipedrosa@redhat.com> 1.3.1-10
+- pam_modutil_sanitize_helper_fds: fix SIGPIPE effect of PAM_MODUTIL_PIPE_FD (#1791970)
+
+* Fri Apr 17 2020 Iker Pedrosa <ipedrosa@redhat.com> 1.3.1-9
+- pam_usertype: new module to tell if uid is in login.defs ranges (#1810474)
+- pam_tty_audit: if kernel audit is disabled return PAM_IGNORE (#1775357)
+
 * Thu Dec 19 2019 Tomáš Mráz <tmraz@redhat.com> 1.3.1-8
 - pam_motd: Document how to properly silence unwanted motd messages