diff --git a/SOURCES/pam-1.3.1-pam-motd-avoid-unnecessary-logging.patch b/SOURCES/pam-1.3.1-pam-motd-avoid-unnecessary-logging.patch
new file mode 100644
index 0000000..52f7292
--- /dev/null
+++ b/SOURCES/pam-1.3.1-pam-motd-avoid-unnecessary-logging.patch
@@ -0,0 +1,283 @@
+From d57ab22133654033ee1da89f128a81572d320985 Mon Sep 17 00:00:00 2001
+From: Tomas Mraz <tmraz@fedoraproject.org>
+Date: Thu, 20 Dec 2018 13:59:25 +0100
+Subject: [PATCH] pam_motd: Cleanup the code and avoid unnecessary logging
+
+The pam_motd module will not log if the default motd.d directories
+are missing.
+
+Also cleanup some code cleanliness issues and fix compilation
+warnings.
+
+* modules/pam_motd/pam_motd.c: Constification of constant strings.
+  (try_to_display_directory): Removed unused function.
+  (pam_split_string): Replace uint with unsigned int. Fix warnings.
+  (compare_strings): Fix warnings by proper constification.
+  (try_to_display_directories_with_overrides): Cleanups. Switch
+  off the logging if the motd.d directories are missing and they
+  are default ones.
+  (pam_sm_open_session): Cleanup warnings. Pass the information
+  to try_to_display_directories_with_overrides() that non-default
+  motd options are used.
+---
+ modules/pam_motd/pam_motd.c | 88 ++++++++++++++++---------------------
+ 1 file changed, 37 insertions(+), 51 deletions(-)
+
+diff --git a/modules/pam_motd/pam_motd.c b/modules/pam_motd/pam_motd.c
+index ec3ebd58..dbd718b6 100644
+--- a/modules/pam_motd/pam_motd.c
++++ b/modules/pam_motd/pam_motd.c
+@@ -22,6 +22,7 @@
+ #include <sys/stat.h>
+ #include <pwd.h>
+ #include <syslog.h>
++#include <errno.h>
+ 
+ #include <security/_pam_macros.h>
+ #include <security/pam_ext.h>
+@@ -48,8 +49,8 @@ pam_sm_close_session (pam_handle_t *pamh UNUSED, int flags UNUSED,
+      return PAM_IGNORE;
+ }
+ 
+-static char default_motd[] = DEFAULT_MOTD;
+-static char default_motd_dir[] = DEFAULT_MOTD_D;
++static const char default_motd[] = DEFAULT_MOTD;
++static const char default_motd_dir[] = DEFAULT_MOTD_D;
+ 
+ static void try_to_display_fd(pam_handle_t *pamh, int fd)
+ {
+@@ -75,28 +76,6 @@ static void try_to_display_fd(pam_handle_t *pamh, int fd)
+     _pam_drop(mtmp);
+ }
+ 
+-static void try_to_display_directory(pam_handle_t *pamh, const char *dirname)
+-{
+-    DIR *dirp;
+-
+-    dirp = opendir(dirname);
+-
+-    if (dirp != NULL) {
+-	struct dirent *entry;
+-
+-	while ((entry = readdir(dirp))) {
+-	    int fd = openat(dirfd(dirp), entry->d_name, O_RDONLY);
+-
+-	    if (fd >= 0) {
+-		try_to_display_fd(pamh, fd);
+-		close(fd);
+-	    }
+-	}
+-
+-	closedir(dirp);
+-    }
+-}
+-
+ /*
+  * Split a DELIM-separated string ARG into an array.
+  * Outputs a newly allocated array of strings OUT_ARG_SPLIT
+@@ -104,14 +83,14 @@ static void try_to_display_directory(pam_handle_t *pamh, const char *dirname)
+  * 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 ***out_arg_split, unsigned int *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;
++    unsigned int i = 0;
++    unsigned int num_strs = 0;
+     int retval = 0;
+ 
+     delim_str[0] = delim;
+@@ -126,7 +105,7 @@ static int pam_split_string(const pam_handle_t *pamh, char *arg, char delim,
+ 	arg_ptr = strchr(arg_ptr + sizeof(const char), delim);
+     }
+ 
+-    arg_split = (char **)calloc(num_strs, sizeof(char *));
++    arg_split = calloc(num_strs, sizeof(char *));
+     if (arg_split == NULL) {
+ 	pam_syslog(pamh, LOG_CRIT, "pam_motd: failed to allocate string array");
+ 	goto out;
+@@ -180,10 +159,10 @@ static int join_dir_strings(char **strp_out, const char *a_str, const char *b_st
+     return retval;
+ }
+ 
+-static int compare_strings(const void * a, const void * b)
++static int compare_strings(const void *a, const void *b)
+ {
+-    const char *a_str = *(char **)a;
+-    const char *b_str = *(char **)b;
++    const char *a_str = *(const char * const *)a;
++    const char *b_str = *(const char * const *)b;
+ 
+     if (a_str == NULL && b_str == NULL) {
+         return 0;
+@@ -205,13 +184,13 @@ static int filter_dirents(const struct dirent *d)
+ }
+ 
+ static void try_to_display_directories_with_overrides(pam_handle_t *pamh,
+-	char **motd_dir_path_split, int num_motd_dirs)
++	char **motd_dir_path_split, unsigned int num_motd_dirs, int report_missing)
+ {
+     struct dirent ***dirscans = NULL;
+-    int *dirscans_sizes = NULL;
+-    int dirscans_size_total = 0;
++    unsigned int *dirscans_sizes = NULL;
++    unsigned int dirscans_size_total = 0;
+     char **dirnames_all = NULL;
+-    int i;
++    unsigned int i;
+     int i_dirnames = 0;
+ 
+     if (pamh == NULL || motd_dir_path_split == NULL) {
+@@ -221,29 +200,31 @@ static void try_to_display_directories_with_overrides(pam_handle_t *pamh,
+ 	goto out;
+     }
+ 
+-    if ((dirscans = (struct dirent ***)calloc(num_motd_dirs,
+-	    sizeof(struct dirent **))) == NULL) {
++    if ((dirscans = 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) {
++    if ((dirscans_sizes = 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]),
++	int rv;
++	rv = 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;
++	if (rv < 0) {
++	    if (errno != ENOENT || report_missing) {
++		pam_syslog(pamh, LOG_ERR, "pam_motd: error scanning directory %s: %m",
++		    motd_dir_path_split[i]);
++	    }
++	    dirscans_sizes[i] = rv;
+ 	}
+ 	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) {
++    if ((dirnames_all = calloc(dirscans_size_total, sizeof(char *))) == NULL) {
+ 	pam_syslog(pamh, LOG_CRIT, "pam_motd: failed to allocate dirname array");
+ 	goto out;
+     }
+@@ -253,7 +234,7 @@ static void try_to_display_directories_with_overrides(pam_handle_t *pamh,
+     }
+ 
+     for (i = 0; i < num_motd_dirs; i++) {
+-	int j;
++	unsigned int j;
+ 
+ 	for (j = 0; j < dirscans_sizes[i]; j++) {
+ 	    dirnames_all[i_dirnames] = dirscans[i][j]->d_name;
+@@ -265,7 +246,7 @@ static void try_to_display_directories_with_overrides(pam_handle_t *pamh,
+ 	    sizeof(const char *), compare_strings);
+ 
+     for (i = 0; i < dirscans_size_total; i++) {
+-	int j;
++	unsigned int j;
+ 
+ 	if (dirnames_all[i] == NULL) {
+ 	    continue;
+@@ -301,7 +282,8 @@ static void try_to_display_directories_with_overrides(pam_handle_t *pamh,
+   out:
+     _pam_drop(dirnames_all);
+     for (i = 0; i < num_motd_dirs; i++) {
+-	int j;
++	unsigned int j;
++
+ 	for (j = 0; j < dirscans_sizes[i]; j++) {
+ 	    _pam_drop(dirscans[i][j]);
+ 	}
+@@ -319,12 +301,13 @@ int pam_sm_open_session(pam_handle_t *pamh, int flags,
+     int retval = PAM_IGNORE;
+     const char *motd_path = NULL;
+     char *motd_path_copy = NULL;
+-    int num_motd_paths = 0;
++    unsigned 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;
++    unsigned int num_motd_dir_paths = 0;
+     char **motd_dir_path_split = NULL;
++    int report_missing;
+ 
+     if (flags & PAM_SILENT) {
+ 	return retval;
+@@ -360,6 +343,9 @@ int pam_sm_open_session(pam_handle_t *pamh, int flags,
+     if (motd_path == NULL && motd_dir_path == NULL) {
+ 	motd_path = default_motd;
+ 	motd_dir_path = default_motd_dir;
++	report_missing = 0;
++    } else {
++	report_missing = 1;
+     }
+ 
+     if (motd_path != NULL) {
+@@ -385,7 +371,7 @@ int pam_sm_open_session(pam_handle_t *pamh, int flags,
+     }
+ 
+     if (motd_path_split != NULL) {
+-	int i;
++	unsigned int i;
+ 
+ 	for (i = 0; i < num_motd_paths; i++) {
+ 	    int fd = open(motd_path_split[i], O_RDONLY, 0);
+@@ -402,7 +388,7 @@ int pam_sm_open_session(pam_handle_t *pamh, int flags,
+ 
+     if (motd_dir_path_split != NULL)
+ 	try_to_display_directories_with_overrides(pamh, motd_dir_path_split,
+-		num_motd_dir_paths);
++		num_motd_dir_paths, report_missing);
+ 
+   out:
+     _pam_drop(motd_path_copy);
+-- 
+2.37.3
+
+From c2c0434bd634a817f2b16ce7f58fc96c04e88b03 Mon Sep 17 00:00:00 2001
+From: "Dmitry V. Levin" <ldv@altlinux.org>
+Date: Sun, 26 Apr 2020 11:12:59 +0000
+Subject: [PATCH] pam_motd: fix NULL dereference when at least one of motd
+ directories is not available
+
+* modules/pam_motd/pam_motd.c
+(try_to_display_directories_with_overrides): Do not assign -1U to
+dirscans_sizes[i] when scandir(motd_dir_path_split[i]) returns an error.
+
+Resolves: https://bugzilla.altlinux.org/38389
+Fixes: d57ab221 ("pam_motd: Cleanup the code and avoid unnecessary logging")
+---
+ modules/pam_motd/pam_motd.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/modules/pam_motd/pam_motd.c b/modules/pam_motd/pam_motd.c
+index df09b7d0..8147c6fd 100644
+--- a/modules/pam_motd/pam_motd.c
++++ b/modules/pam_motd/pam_motd.c
+@@ -219,6 +219,7 @@ static void try_to_display_directories_with_overrides(pam_handle_t *pamh,
+ 		pam_syslog(pamh, LOG_ERR, "pam_motd: error scanning directory %s: %m",
+ 		    motd_dir_path_split[i]);
+ 	    }
++	} else {
+ 	    dirscans_sizes[i] = rv;
+ 	}
+ 	dirscans_size_total += dirscans_sizes[i];
+-- 
+2.37.3
+
diff --git a/SOURCES/pam-1.5.1-pam-faillock-avoid-logging-erroneous.patch b/SOURCES/pam-1.5.1-pam-faillock-avoid-logging-erroneous.patch
new file mode 100644
index 0000000..016bb15
--- /dev/null
+++ b/SOURCES/pam-1.5.1-pam-faillock-avoid-logging-erroneous.patch
@@ -0,0 +1,37 @@
+From 10086bc69663fa819277af244eeb5b629a2403b8 Mon Sep 17 00:00:00 2001
+From: Deepak Das <ddas@redhat.com>
+Date: Mon, 10 Oct 2022 21:21:35 +0530
+Subject: [PATCH] pam_faillock: avoid logging an erroneous consecutive login
+ failure message
+
+* modules/pam_faillock/pam_faillock.c (write_tally): Avoid logging
+a consecutive login failure message for the root user in case when
+even_deny_root is not set.
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2082442
+---
+ modules/pam_faillock/pam_faillock.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/modules/pam_faillock/pam_faillock.c b/modules/pam_faillock/pam_faillock.c
+index ddbb90e7..ca1c7035 100644
+--- a/modules/pam_faillock/pam_faillock.c
++++ b/modules/pam_faillock/pam_faillock.c
+@@ -374,9 +374,11 @@ write_tally(pam_handle_t *pamh, struct options *opts, struct tally_data *tallies
+ 		}
+ 		close(audit_fd);
+ #endif
+-		if (!(opts->flags & FAILLOCK_FLAG_NO_LOG_INFO)) {
+-			pam_syslog(pamh, LOG_INFO, "Consecutive login failures for user %s account temporarily locked",
+-				opts->user);
++		if (!(opts->flags & FAILLOCK_FLAG_NO_LOG_INFO) &&
++		    ((opts->flags & FAILLOCK_FLAG_DENY_ROOT) || (opts->uid != 0))) {
++			pam_syslog(pamh, LOG_INFO,
++				   "Consecutive login failures for user %s account temporarily locked",
++				   opts->user);
+ 		}
+ 	}
+ 
+-- 
+2.38.1
+
diff --git a/SOURCES/pam-1.5.1-pam-faillock-clarify-missing-user.patch b/SOURCES/pam-1.5.1-pam-faillock-clarify-missing-user.patch
new file mode 100644
index 0000000..3f15eb8
--- /dev/null
+++ b/SOURCES/pam-1.5.1-pam-faillock-clarify-missing-user.patch
@@ -0,0 +1,53 @@
+From bcbf145ce925934214e48200c27c9ff736452549 Mon Sep 17 00:00:00 2001
+From: Deepak Das <ddas@redhat.com>
+Date: Mon, 10 Oct 2022 17:55:53 +0530
+Subject: [PATCH] pam_faillock: Clarify missing user faillock files after
+ reboot
+
+* modules/pam_faillock/faillock.conf.5.xml: Adding note related to missing
+user specific faillock files after reboot.
+
+* modules/pam_faillock/pam_faillock.8.xml: Adding note related to missing
+user specific faillock files after reboot.
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2062512
+---
+ modules/pam_faillock/faillock.conf.5.xml | 4 ++++
+ modules/pam_faillock/pam_faillock.8.xml  | 6 ++++++
+ 2 files changed, 10 insertions(+)
+
+diff --git a/modules/pam_faillock/faillock.conf.5.xml b/modules/pam_faillock/faillock.conf.5.xml
+index 04a84107..8faa5915 100644
+--- a/modules/pam_faillock/faillock.conf.5.xml
++++ b/modules/pam_faillock/faillock.conf.5.xml
+@@ -44,6 +44,10 @@
+                   The directory where the user files with the failure records are kept. The
+                   default is <filename>/var/run/faillock</filename>.
+                 </para>
++                <para>
++                  Note: These files will disappear after reboot on systems configured with
++                  directory <filename>/var/run/faillock</filename> mounted on virtual memory.
++                </para>
+               </listitem>
+             </varlistentry>
+             <varlistentry>
+diff --git a/modules/pam_faillock/pam_faillock.8.xml b/modules/pam_faillock/pam_faillock.8.xml
+index 79bcbbd0..b7b7b0db 100644
+--- a/modules/pam_faillock/pam_faillock.8.xml
++++ b/modules/pam_faillock/pam_faillock.8.xml
+@@ -327,6 +327,12 @@ session  required       pam_selinux.so open
+         <term><filename>/var/run/faillock/*</filename></term>
+         <listitem>
+           <para>the files logging the authentication failures for users</para>
++          <para>
++            Note: These files will disappear after reboot on systems configured with
++            directory <filename>/var/run/faillock</filename> mounted on virtual memory.
++            For persistent storage use the option <emphasis>dir=</emphasis> in
++            file <filename>/etc/security/faillock.conf</filename>.
++          </para>
+         </listitem>
+       </varlistentry>
+       <varlistentry>
+-- 
+2.38.1
+
diff --git a/SOURCES/pam-1.5.1-pam-lastlog-check-localtime_r-return-value.patch b/SOURCES/pam-1.5.1-pam-lastlog-check-localtime_r-return-value.patch
new file mode 100644
index 0000000..80ad508
--- /dev/null
+++ b/SOURCES/pam-1.5.1-pam-lastlog-check-localtime_r-return-value.patch
@@ -0,0 +1,41 @@
+From 40c271164dbcebfc5304d0537a42fb42e6b6803c Mon Sep 17 00:00:00 2001
+From: Iker Pedrosa <ipedrosa@redhat.com>
+Date: Mon, 26 Sep 2022 12:16:53 +0200
+Subject: [PATCH] pam_lastlog: check localtime_r() return value
+
+Check the return value of localtime_r() before calling strftime(). This
+function crashes if the argument is NULL.
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2012871
+
+Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
+---
+ modules/pam_lastlog/pam_lastlog.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/modules/pam_lastlog/pam_lastlog.c b/modules/pam_lastlog/pam_lastlog.c
+index abd048df..121e7560 100644
+--- a/modules/pam_lastlog/pam_lastlog.c
++++ b/modules/pam_lastlog/pam_lastlog.c
+@@ -573,12 +573,12 @@ last_login_failed(pam_handle_t *pamh, int announce, const char *user, time_t llt
+ 	    time_t lf_time;
+ 
+ 	    lf_time = utuser.ut_tv.tv_sec;
+-	    tm = localtime_r (&lf_time, &tm_buf);
+-	    strftime (the_time, sizeof (the_time),
+-	        /* TRANSLATORS: "strftime options for date of last login" */
+-		_(" %a %b %e %H:%M:%S %Z %Y"), tm);
+-
+-	    date = the_time;
++	    if ((tm = localtime_r (&lf_time, &tm_buf)) != NULL) {
++	        strftime (the_time, sizeof (the_time),
++	            /* TRANSLATORS: "strftime options for date of last login" */
++	                  _(" %a %b %e %H:%M:%S %Z %Y"), tm);
++	        date = the_time;
++	    }
+ 	}
+ 
+ 	/* we want & have the host? */
+-- 
+2.38.1
+
diff --git a/SPECS/pam.spec b/SPECS/pam.spec
index 77e71c1..25deb7d 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: 24%{?dist}
+Release: 25%{?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+.
@@ -88,6 +88,15 @@ Patch59: pam-1.3.1-pam-usertype-SYS_UID_MAX.patch
 # https://github.com/linux-pam/linux-pam/commit/ba2f6dd8b81ea2a58262c1709bec906b6852591d
 # https://github.com/linux-pam/linux-pam/commit/1180bde923a22605fe8075cd1fe7992ed7513411
 Patch60: pam-1.3.1-pam-pwhistory-load-conf-from-file.patch
+# https://github.com/linux-pam/linux-pam/commit/d57ab22133654033ee1da89f128a81572d320985
+# https://github.com/linux-pam/linux-pam/commit/c2c0434bd634a817f2b16ce7f58fc96c04e88b03
+Patch61: pam-1.3.1-pam-motd-avoid-unnecessary-logging.patch
+# https://github.com/linux-pam/linux-pam/commit/40c271164dbcebfc5304d0537a42fb42e6b6803c
+Patch62: pam-1.5.1-pam-lastlog-check-localtime_r-return-value.patch
+# https://github.com/linux-pam/linux-pam/commit/bcbf145ce925934214e48200c27c9ff736452549
+Patch63: pam-1.5.1-pam-faillock-clarify-missing-user.patch
+# https://github.com/linux-pam/linux-pam/commit/10086bc69663fa819277af244eeb5b629a2403b8
+Patch64: pam-1.5.1-pam-faillock-avoid-logging-erroneous.patch
 
 %define _pamlibdir %{_libdir}
 %define _moduledir %{_libdir}/security
@@ -196,6 +205,10 @@ cp %{SOURCE18} .
 %patch58 -p1 -b .faillock-load-conf-from-file
 %patch59 -p1 -b .pam-usertype-SYS_UID_MAX
 %patch60 -p1 -b .pam-pwhistory-load-conf-from-file
+%patch61 -p1 -b .pam-motd-avoid-unnecessary-logging
+%patch62 -p1 -b .pam-lastlog-check-localtime_r-return-value
+%patch63 -p1 -b .pam-faillock-clarify-missing-user
+%patch64 -p1 -b .pam-faillock-avoid-logging-erroneous
 
 autoreconf -i
 
@@ -449,6 +462,12 @@ done
 %doc doc/specs/rfc86.0.txt
 
 %changelog
+* Tue Nov 29 2022 Iker Pedrosa <ipedrosa@redhat.com> - 1.3.1-25
+- pam_motd: avoid unnecessary logging. Resolves: #2091062
+- pam_lastlog: check localtime_r() return value. Resolves: #2012871
+- pam_faillock: clarify missing user faillock files after reboot. Resolves: #2062512
+- pam_faillock: avoid logging an erroneous consecutive login failure message. Resolves: #2082442
+
 * Thu Sep 29 2022 Iker Pedrosa <ipedrosa@redhat.com> - 1.3.1-24
 - pam_pwhistory: load configuration from file. Resolves: #2068461