Compare commits

...

No commits in common. "imports/c8s/pam-1.3.1-22.el8" and "c8" have entirely different histories.

13 changed files with 1498 additions and 17 deletions

View File

@ -0,0 +1,158 @@
diff -up Linux-PAM-1.3.1/modules/pam_access/pam_access.c.access-handle-hostnames Linux-PAM-1.3.1/modules/pam_access/pam_access.c
--- Linux-PAM-1.3.1/modules/pam_access/pam_access.c.access-handle-hostnames 2024-01-19 16:45:18.319862531 +0100
+++ Linux-PAM-1.3.1/modules/pam_access/pam_access.c 2024-01-19 16:50:34.239545948 +0100
@@ -683,7 +683,7 @@ string_match (pam_handle_t *pamh, const
/*
* If the token has the magic value "ALL" the match always succeeds.
* Otherwise, return YES if the token fully matches the string.
- * "NONE" token matches NULL string.
+ * "NONE" token matches NULL string.
*/
if (strcasecmp(tok, "ALL") == 0) { /* all: always matches */
@@ -701,7 +701,8 @@ string_match (pam_handle_t *pamh, const
/* network_netmask_match - match a string against one token
* where string is a hostname or ip (v4,v6) address and tok
- * represents either a single ip (v4,v6) address or a network/netmask
+ * represents either a hostname, a single ip (v4,v6) address
+ * or a network/netmask
*/
static int
network_netmask_match (pam_handle_t *pamh,
@@ -710,10 +711,12 @@ network_netmask_match (pam_handle_t *pam
char *netmask_ptr;
char netmask_string[MAXHOSTNAMELEN + 1];
int addr_type;
+ struct addrinfo *ai = NULL;
if (item->debug)
- pam_syslog (pamh, LOG_DEBUG,
+ pam_syslog (pamh, LOG_DEBUG,
"network_netmask_match: tok=%s, item=%s", tok, string);
+
/* OK, check if tok is of type addr/mask */
if ((netmask_ptr = strchr(tok, '/')) != NULL)
{
@@ -745,52 +748,109 @@ network_netmask_match (pam_handle_t *pam
netmask_ptr = number_to_netmask(netmask, addr_type,
netmask_string, MAXHOSTNAMELEN);
}
- }
+
+ /*
+ * Construct an addrinfo list from the IP address.
+ * This should not fail as the input is a correct IP address...
+ */
+ if (getaddrinfo (tok, NULL, NULL, &ai) != 0)
+ {
+ return NO;
+ }
+ }
else
- /* NO, then check if it is only an addr */
- if (isipaddr(tok, NULL, NULL) != YES)
+ {
+ /*
+ * It is either an IP address or a hostname.
+ * Let getaddrinfo sort everything out
+ */
+ if (getaddrinfo (tok, NULL, NULL, &ai) != 0)
{
+ if (item->debug)
+ pam_syslog(pamh, LOG_DEBUG, "cannot resolve hostname \"%s\"", tok);
+
return NO;
}
+ netmask_ptr = NULL;
+ }
if (isipaddr(string, NULL, NULL) != YES)
{
- /* Assume network/netmask with a name of a host. */
struct addrinfo hint;
+ /* Assume network/netmask with a name of a host. */
memset (&hint, '\0', sizeof (hint));
hint.ai_flags = AI_CANONNAME;
hint.ai_family = AF_UNSPEC;
if (item->gai_rv != 0)
+ {
+ freeaddrinfo(ai);
return NO;
+ }
else if (!item->res &&
(item->gai_rv = getaddrinfo (string, NULL, &hint, &item->res)) != 0)
+ {
+ freeaddrinfo(ai);
return NO;
+ }
else
{
struct addrinfo *runp = item->res;
+ struct addrinfo *runp1;
while (runp != NULL)
{
char buf[INET6_ADDRSTRLEN];
- inet_ntop (runp->ai_family,
- runp->ai_family == AF_INET
- ? (void *) &((struct sockaddr_in *) runp->ai_addr)->sin_addr
- : (void *) &((struct sockaddr_in6 *) runp->ai_addr)->sin6_addr,
- buf, sizeof (buf));
+ if (getnameinfo (runp->ai_addr, runp->ai_addrlen, buf, sizeof (buf), NULL, 0, NI_NUMERICHOST) != 0)
+ {
+ freeaddrinfo(ai);
+ return NO;
+ }
- if (are_addresses_equal(buf, tok, netmask_ptr))
+ for (runp1 = ai; runp1 != NULL; runp1 = runp1->ai_next)
{
- return YES;
+ char buf1[INET6_ADDRSTRLEN];
+
+ if (runp->ai_family != runp1->ai_family)
+ continue;
+
+ if (getnameinfo (runp1->ai_addr, runp1->ai_addrlen, buf1, sizeof (buf1), NULL, 0, NI_NUMERICHOST) != 0)
+ {
+ freeaddrinfo(ai);
+ return NO;
+ }
+
+ if (are_addresses_equal (buf, buf1, netmask_ptr))
+ {
+ freeaddrinfo(ai);
+ return YES;
+ }
}
runp = runp->ai_next;
}
}
}
else
- return (are_addresses_equal(string, tok, netmask_ptr));
+ {
+ struct addrinfo *runp1;
+
+ for (runp1 = ai; runp1 != NULL; runp1 = runp1->ai_next)
+ {
+ char buf1[INET6_ADDRSTRLEN];
+
+ (void) getnameinfo (runp1->ai_addr, runp1->ai_addrlen, buf1, sizeof (buf1), NULL, 0, NI_NUMERICHOST);
+
+ if (are_addresses_equal(string, buf1, netmask_ptr))
+ {
+ freeaddrinfo(ai);
+ return YES;
+ }
+ }
+ }
+
+ freeaddrinfo(ai);
return NO;
}

View File

@ -0,0 +1,13 @@
diff -up Linux-PAM-1.3.1/modules/pam_faillock/faillock.c.faillock-create-tallydir Linux-PAM-1.3.1/modules/pam_faillock/faillock.c
--- Linux-PAM-1.3.1/modules/pam_faillock/faillock.c.faillock-create-tallydir 2024-01-08 11:32:02.122392119 +0100
+++ Linux-PAM-1.3.1/modules/pam_faillock/faillock.c 2024-01-08 11:33:10.916515943 +0100
@@ -74,6 +74,9 @@ open_tally (const char *dir, const char
if (create) {
flags |= O_CREAT;
+ if (access(dir, F_OK) != 0) {
+ mkdir(dir, 0755);
+ }
}
fd = open(path, flags, 0600);

View File

@ -0,0 +1,58 @@
From 031bb5a5d0d950253b68138b498dc93be69a64cb Mon Sep 17 00:00:00 2001
From: Matthias Gerstner <matthias.gerstner@suse.de>
Date: Wed, 27 Dec 2023 14:01:59 +0100
Subject: [PATCH] pam_namespace: protect_dir(): use O_DIRECTORY to prevent
local DoS situations
Without O_DIRECTORY the path crawling logic is subject to e.g. FIFOs
being placed in user controlled directories, causing the PAM module to
block indefinitely during `openat()`.
Pass O_DIRECTORY to cause the `openat()` to fail if the path does not
refer to a directory.
With this the check whether the final path element is a directory
becomes unnecessary, drop it.
---
modules/pam_namespace/pam_namespace.c | 18 +-----------------
1 file changed, 1 insertion(+), 17 deletions(-)
diff --git a/modules/pam_namespace/pam_namespace.c b/modules/pam_namespace/pam_namespace.c
index 2528cff8..f72d6718 100644
--- a/modules/pam_namespace/pam_namespace.c
+++ b/modules/pam_namespace/pam_namespace.c
@@ -1201,7 +1201,7 @@ static int protect_dir(const char *path, mode_t mode, int do_mkdir,
int dfd = AT_FDCWD;
int dfd_next;
int save_errno;
- int flags = O_RDONLY;
+ int flags = O_RDONLY | O_DIRECTORY;
int rv = -1;
struct stat st;
@@ -1255,22 +1255,6 @@ static int protect_dir(const char *path, mode_t mode, int do_mkdir,
rv = openat(dfd, dir, flags);
}
- if (rv != -1) {
- if (fstat(rv, &st) != 0) {
- save_errno = errno;
- close(rv);
- rv = -1;
- errno = save_errno;
- goto error;
- }
- if (!S_ISDIR(st.st_mode)) {
- close(rv);
- errno = ENOTDIR;
- rv = -1;
- goto error;
- }
- }
-
if (flags & O_NOFOLLOW) {
/* we are inside user-owned dir - protect */
if (protect_mount(rv, p, idata) == -1) {
--
2.43.0

View File

@ -0,0 +1,29 @@
diff -up Linux-PAM-1.3.1/configure.ac.pam-misc-configurable Linux-PAM-1.3.1/configure.ac
--- Linux-PAM-1.3.1/configure.ac.pam-misc-configurable 2023-06-26 09:57:00.243146563 +0200
+++ Linux-PAM-1.3.1/configure.ac 2023-06-26 09:59:45.353636685 +0200
@@ -621,6 +621,13 @@ if test x"$opt_kerneloverflowuid" == x;
fi
AC_DEFINE_UNQUOTED(PAM_USERTYPE_OVERFLOW_UID, $opt_kerneloverflowuid, [Kernel overflow uid.])
+AC_ARG_WITH([misc-conv-bufsize],
+AS_HELP_STRING([--with-misc-conv-bufsize=<number>],
+ [Size of input buffer for libpam_misc's misc_conv() conversation function, default=4096]),
+ [],
+ [with_misc_conv_bufsize=4096])
+AC_DEFINE_UNQUOTED(PAM_MISC_CONV_BUFSIZE, $with_misc_conv_bufsize, [libpam_misc misc_conv() buffer size.])
+
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 \
diff -up Linux-PAM-1.3.1/libpam_misc/misc_conv.c.pam-misc-configurable Linux-PAM-1.3.1/libpam_misc/misc_conv.c
--- Linux-PAM-1.3.1/libpam_misc/misc_conv.c.pam-misc-configurable 2023-06-26 09:57:00.242146560 +0200
+++ Linux-PAM-1.3.1/libpam_misc/misc_conv.c 2023-06-26 10:00:38.023787972 +0200
@@ -18,7 +18,7 @@
#include <security/pam_appl.h>
#include <security/pam_misc.h>
-#define INPUTSIZE PAM_MAX_MSG_SIZE /* maximum length of input+1 */
+#define INPUTSIZE PAM_MISC_CONV_BUFSIZE /* maximum length of input+1 */
#define CONV_ECHO_ON 1 /* types of echo state */
#define CONV_ECHO_OFF 0

View File

@ -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

View File

@ -0,0 +1,573 @@
diff -up Linux-PAM-1.3.1/modules/pam_pwhistory/Makefile.am.pam-pwhistory-load-conf-from-file Linux-PAM-1.3.1/modules/pam_pwhistory/Makefile.am
--- Linux-PAM-1.3.1/modules/pam_pwhistory/Makefile.am.pam-pwhistory-load-conf-from-file 2022-09-29 10:13:35.709355179 +0200
+++ Linux-PAM-1.3.1/modules/pam_pwhistory/Makefile.am 2022-09-29 10:13:35.780355766 +0200
@@ -10,9 +10,10 @@ EXTRA_DIST = README $(MANS) $(XMLS) tst-
TESTS = tst-pam_pwhistory
-man_MANS = pam_pwhistory.8 pwhistory_helper.8
+man_MANS = pam_pwhistory.8 pwhistory_helper.8 pwhistory.conf.5
-XMLS = README.xml pam_pwhistory.8.xml pwhistory_helper.8.xml
+XMLS = README.xml pam_pwhistory.8.xml pwhistory_helper.8.xml \
+ pwhistory.conf.5.xml
securelibdir = $(SECUREDIR)
secureconfdir = $(SCONFIGDIR)
@@ -25,12 +26,14 @@ if HAVE_VERSIONING
pam_pwhistory_la_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
endif
-noinst_HEADERS = opasswd.h
+noinst_HEADERS = opasswd.h pwhistory_config.h
+
+dist_secureconf_DATA = pwhistory.conf
securelib_LTLIBRARIES = pam_pwhistory.la
pam_pwhistory_la_CFLAGS = $(AM_CFLAGS)
pam_pwhistory_la_LIBADD = $(top_builddir)/libpam/libpam.la @LIBCRYPT@ @LIBSELINUX@
-pam_pwhistory_la_SOURCES = pam_pwhistory.c opasswd.c
+pam_pwhistory_la_SOURCES = pam_pwhistory.c opasswd.c pwhistory_config.c
sbin_PROGRAMS = pwhistory_helper
pwhistory_helper_CFLAGS = $(AM_CFLAGS) -DHELPER_COMPILE=\"pwhistory_helper\" @PIE_CFLAGS@
diff -up Linux-PAM-1.3.1/modules/pam_pwhistory/pam_pwhistory.8.xml.pam-pwhistory-load-conf-from-file Linux-PAM-1.3.1/modules/pam_pwhistory/pam_pwhistory.8.xml
--- Linux-PAM-1.3.1/modules/pam_pwhistory/pam_pwhistory.8.xml.pam-pwhistory-load-conf-from-file 2017-02-10 11:10:15.000000000 +0100
+++ Linux-PAM-1.3.1/modules/pam_pwhistory/pam_pwhistory.8.xml 2022-09-29 10:13:35.780355766 +0200
@@ -36,6 +36,9 @@
<arg choice="opt">
authtok_type=<replaceable>STRING</replaceable>
</arg>
+ <arg choice="opt">
+ conf=<replaceable>/path/to/config-file</replaceable>
+ </arg>
</cmdsynopsis>
</refsynopsisdiv>
@@ -104,7 +107,7 @@
<listitem>
<para>
The last <replaceable>N</replaceable> passwords for each
- user are saved in <filename>/etc/security/opasswd</filename>.
+ user are saved.
The default is <emphasis>10</emphasis>. Value of
<emphasis>0</emphasis> makes the module to keep the existing
contents of the <filename>opasswd</filename> file unchanged.
@@ -137,7 +140,26 @@
</listitem>
</varlistentry>
+ <varlistentry>
+ <term>
+ <option>conf=<replaceable>/path/to/config-file</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ Use another configuration file instead of the default
+ <filename>/etc/security/pwhistory.conf</filename>.
+ </para>
+ </listitem>
+ </varlistentry>
+
</variablelist>
+ <para>
+ The options for configuring the module behavior are described in the
+ <citerefentry><refentrytitle>pwhistory.conf</refentrytitle>
+ <manvolnum>5</manvolnum></citerefentry> manual page. The options
+ specified on the module command line override the values from the
+ configuration file.
+ </para>
</refsect1>
<refsect1 id="pam_pwhistory-types">
@@ -223,6 +245,9 @@ password required pam_unix.so
<title>SEE ALSO</title>
<para>
<citerefentry>
+ <refentrytitle>pwhistory.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
<refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
</citerefentry>,
<citerefentry>
diff -up Linux-PAM-1.3.1/modules/pam_pwhistory/pam_pwhistory.c.pam-pwhistory-load-conf-from-file Linux-PAM-1.3.1/modules/pam_pwhistory/pam_pwhistory.c
--- Linux-PAM-1.3.1/modules/pam_pwhistory/pam_pwhistory.c.pam-pwhistory-load-conf-from-file 2022-09-29 10:13:35.711355195 +0200
+++ Linux-PAM-1.3.1/modules/pam_pwhistory/pam_pwhistory.c 2022-09-29 10:13:35.780355766 +0200
@@ -62,18 +62,11 @@
#include <security/_pam_macros.h>
#include "opasswd.h"
+#include "pwhistory_config.h"
#define DEFAULT_BUFLEN 2048
#define MAX_FD_NO 20000
-struct options_t {
- int debug;
- int enforce_for_root;
- int remember;
- int tries;
-};
-typedef struct options_t options_t;
-
static void
parse_option (pam_handle_t *pamh, const char *argv, options_t *options)
@@ -304,6 +297,8 @@ pam_sm_chauthtok (pam_handle_t *pamh, in
options.remember = 10;
options.tries = 1;
+ parse_config_file(pamh, argc, argv, &options);
+
/* Parse parameters for module */
for ( ; argc-- > 0; argv++)
parse_option (pamh, *argv, &options);
@@ -311,7 +306,6 @@ pam_sm_chauthtok (pam_handle_t *pamh, in
if (options.debug)
pam_syslog (pamh, LOG_DEBUG, "pam_sm_chauthtok entered");
-
if (options.remember == 0)
return PAM_IGNORE;
diff -up Linux-PAM-1.3.1/modules/pam_pwhistory/pwhistory.conf.5.xml.pam-pwhistory-load-conf-from-file Linux-PAM-1.3.1/modules/pam_pwhistory/pwhistory.conf.5.xml
--- Linux-PAM-1.3.1/modules/pam_pwhistory/pwhistory.conf.5.xml.pam-pwhistory-load-conf-from-file 2022-09-29 10:13:35.780355766 +0200
+++ Linux-PAM-1.3.1/modules/pam_pwhistory/pwhistory.conf.5.xml 2022-09-29 10:13:35.780355766 +0200
@@ -0,0 +1,155 @@
+<?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.conf">
+
+ <refmeta>
+ <refentrytitle>pwhistory.conf</refentrytitle>
+ <manvolnum>5</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id="pwhistory.conf-name">
+ <refname>pwhistory.conf</refname>
+ <refpurpose>pam_pwhistory configuration file</refpurpose>
+ </refnamediv>
+
+ <refsect1 id="pwhistory.conf-description">
+
+ <title>DESCRIPTION</title>
+ <para>
+ <emphasis remap='B'>pwhistory.conf</emphasis> provides a way to configure the
+ default settings for saving the last passwords for each user.
+ This file is read by the <emphasis>pam_pwhistory</emphasis> module and is the
+ preferred method over configuring <emphasis>pam_pwhistory</emphasis> directly.
+ </para>
+ <para>
+ The file has a very simple <emphasis>name = value</emphasis> format with possible comments
+ starting with <emphasis>#</emphasis> character. The whitespace at the beginning of line, end
+ of line, and around the <emphasis>=</emphasis> sign is ignored.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pwhistory.conf-options">
+
+ <title>OPTIONS</title>
+ <variablelist>
+ <varlistentry>
+ <term>
+ <option>debug</option>
+ </term>
+ <listitem>
+ <para>
+ Turns on debugging via
+ <citerefentry>
+ <refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>enforce_for_root</option>
+ </term>
+ <listitem>
+ <para>
+ If this option is set, the check is enforced for root, too.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>remember=<replaceable>N</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ The last <replaceable>N</replaceable> passwords for each
+ user are saved.
+ The default is <emphasis>10</emphasis>. Value of
+ <emphasis>0</emphasis> makes the module to keep the existing
+ contents of the <filename>opasswd</filename> file unchanged.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>retry=<replaceable>N</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ Prompt user at most <replaceable>N</replaceable> times
+ before returning with error. The default is 1.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>file=<replaceable>/path/filename</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ Store password history in file
+ <replaceable>/path/filename</replaceable> rather than the default
+ location. The default location is
+ <filename>/etc/security/opasswd</filename>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id='pwhistory.conf-examples'>
+ <title>EXAMPLES</title>
+ <para>
+ /etc/security/pwhistory.conf file example:
+ </para>
+ <programlisting>
+debug
+remember=5
+file=/tmp/opasswd
+ </programlisting>
+ </refsect1>
+
+ <refsect1 id="pwhistory.conf-files">
+ <title>FILES</title>
+ <variablelist>
+ <varlistentry>
+ <term><filename>/etc/security/pwhistory.conf</filename></term>
+ <listitem>
+ <para>the config file for custom options</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id='pwhistory.conf-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>pwhistory</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam_pwhistory</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pwhistory.conf-author'>
+ <title>AUTHOR</title>
+ <para>
+ pam_pwhistory was written by Thorsten Kukuk. The support for
+ pwhistory.conf was written by Iker Pedrosa.
+ </para>
+ </refsect1>
+
+</refentry>
diff -up Linux-PAM-1.3.1/modules/pam_pwhistory/pwhistory_config.c.pam-pwhistory-load-conf-from-file Linux-PAM-1.3.1/modules/pam_pwhistory/pwhistory_config.c
--- Linux-PAM-1.3.1/modules/pam_pwhistory/pwhistory_config.c.pam-pwhistory-load-conf-from-file 2022-09-29 10:13:35.781355775 +0200
+++ Linux-PAM-1.3.1/modules/pam_pwhistory/pwhistory_config.c 2022-09-29 10:14:33.377832622 +0200
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2022 Iker Pedrosa <ipedrosa@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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <ctype.h>
+
+#include <security/pam_modutil.h>
+
+#include "pam_inline.h"
+#include "pwhistory_config.h"
+
+#define PWHISTORY_DEFAULT_CONF "/etc/security/pwhistory.conf"
+
+/* lookup a value for key in login.defs file or similar key value format */
+static char *
+pwhistory_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;
+
+#ifdef USE_ECONF
+ if (strcmp (file_name, LOGIN_DEFS) == 0)
+ return econf_search_key ("login", ".defs", key);
+#endif
+
+ 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 = buf + n; /* empty string */
+
+ if (strcasecmp(tmp, key) == 0) {
+ retval = strdup(cp);
+ break;
+ }
+ }
+ fclose(fp);
+
+ free(buf);
+
+ return retval;
+}
+
+void
+parse_config_file(pam_handle_t *pamh, int argc, const char **argv,
+ struct options_t *options)
+{
+ const char *fname = NULL;
+ int i;
+ char *val;
+
+ for (i = 0; i < argc; ++i) {
+ const char *str = pam_str_skip_prefix(argv[i], "conf=");
+
+ if (str != NULL) {
+ fname = str;
+ }
+ }
+
+ if (fname == NULL) {
+ fname = PWHISTORY_DEFAULT_CONF;
+ }
+
+ val = pwhistory_search_key (pamh, fname, "debug");
+ if (val != NULL) {
+ options->debug = 1;
+ free(val);
+ }
+
+ val = pwhistory_search_key (pamh, fname, "enforce_for_root");
+ if (val != NULL) {
+ options->enforce_for_root = 1;
+ free(val);
+ }
+
+ val = pwhistory_search_key (pamh, fname, "remember");
+ if (val != NULL) {
+ unsigned int temp;
+ if (sscanf(val, "%u", &temp) != 1) {
+ pam_syslog(pamh, LOG_ERR,
+ "Bad number supplied for remember argument");
+ } else {
+ options->remember = temp;
+ }
+ free(val);
+ }
+
+ val = pwhistory_search_key (pamh, fname, "retry");
+ if (val != NULL) {
+ unsigned int temp;
+ if (sscanf(val, "%u", &temp) != 1) {
+ pam_syslog(pamh, LOG_ERR,
+ "Bad number supplied for retry argument");
+ } else {
+ options->tries = temp;
+ }
+ free(val);
+ }
+
+ val = pwhistory_search_key (pamh, fname, "file");
+ if (val != NULL) {
+ if (*val != '/') {
+ pam_syslog (pamh, LOG_ERR,
+ "File path should be absolute: %s", val);
+ } else {
+ options->filename = val;
+ }
+ }
+}
diff -up Linux-PAM-1.3.1/modules/pam_pwhistory/pwhistory_config.h.pam-pwhistory-load-conf-from-file Linux-PAM-1.3.1/modules/pam_pwhistory/pwhistory_config.h
--- Linux-PAM-1.3.1/modules/pam_pwhistory/pwhistory_config.h.pam-pwhistory-load-conf-from-file 2022-09-29 10:13:35.781355775 +0200
+++ Linux-PAM-1.3.1/modules/pam_pwhistory/pwhistory_config.h 2022-09-29 10:13:35.781355775 +0200
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2022 Iker Pedrosa <ipedrosa@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.
+ */
+
+#ifndef _PWHISTORY_CONFIG_H
+#define _PWHISTORY_CONFIG_H
+
+#include <security/pam_ext.h>
+
+struct options_t {
+ int debug;
+ int enforce_for_root;
+ int remember;
+ int tries;
+ const char *filename;
+};
+typedef struct options_t options_t;
+
+void
+parse_config_file(pam_handle_t *pamh, int argc, const char **argv,
+ struct options_t *options);
+
+#endif /* _PWHISTORY_CONFIG_H */
diff -up Linux-PAM-1.3.1/modules/pam_pwhistory/pwhistory.conf.pam-pwhistory-load-conf-from-file Linux-PAM-1.3.1/modules/pam_pwhistory/pwhistory.conf
--- Linux-PAM-1.3.1/modules/pam_pwhistory/pwhistory.conf.pam-pwhistory-load-conf-from-file 2022-09-29 10:13:35.781355775 +0200
+++ Linux-PAM-1.3.1/modules/pam_pwhistory/pwhistory.conf 2022-09-29 10:13:35.781355775 +0200
@@ -0,0 +1,21 @@
+# Configuration for remembering the last passwords used by a user.
+#
+# Enable the debugging logs.
+# Enabled if option is present.
+# debug
+#
+# root account's passwords are also remembered.
+# Enabled if option is present.
+# enforce_for_root
+#
+# Number of passwords to remember.
+# The default is 10.
+# remember = 10
+#
+# Number of times to prompt for the password.
+# The default is 1.
+# retry = 1
+#
+# The directory where the last passwords are kept.
+# The default is /etc/security/opasswd.
+# file = /etc/security/opasswd

View File

@ -0,0 +1,12 @@
diff -up Linux-PAM-1.3.1/modules/pam_unix/pam_unix_passwd.c.unix-default-rounds Linux-PAM-1.3.1/modules/pam_unix/pam_unix_passwd.c
--- Linux-PAM-1.3.1/modules/pam_unix/pam_unix_passwd.c.unix-default-rounds 2023-11-02 09:59:54.533238124 +0100
+++ Linux-PAM-1.3.1/modules/pam_unix/pam_unix_passwd.c 2023-11-02 10:40:58.017404936 +0100
@@ -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> */

View File

@ -0,0 +1,174 @@
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)) {
--
2.41.0
diff -up Linux-PAM-1.3.1/configure.ac.legacy-xcrypt Linux-PAM-1.3.1/configure.ac
--- Linux-PAM-1.3.1/configure.ac.legacy-xcrypt 2023-10-26 12:08:46.896437225 +0200
+++ Linux-PAM-1.3.1/configure.ac 2023-10-26 12:10:38.289654696 +0200
@@ -395,19 +395,32 @@ AC_SUBST(LIBAUDIT)
AM_CONDITIONAL([HAVE_AUDIT_TTY_STATUS],
[test "x$HAVE_AUDIT_TTY_STATUS" = xyes])
-AC_CHECK_HEADERS(xcrypt.h crypt.h)
-AS_IF([test "x$ac_cv_header_xcrypt_h" = "xyes"],
- [crypt_libs="xcrypt crypt"],
- [crypt_libs="crypt"])
+AC_CHECK_HEADERS(crypt.h)
BACKUP_LIBS=$LIBS
-AC_SEARCH_LIBS([crypt],[$crypt_libs], LIBCRYPT="${ac_lib:+-l$ac_lib}", LIBCRYPT="")
-AC_CHECK_FUNCS(crypt_r crypt_gensalt_r)
+LIBCRYPT=""
+PKG_CHECK_MODULES([CRYPT], [libcrypt], [
+ CFLAGS="$CFLAGS $CRYPT_CFLAGS"
+ CPPFLAGS="$CPPFLAGS $CRYPT_CFLAGS"
+ LIBS="$LIBS $CRYPT_LIBS"
+ LIBCRYPT="$CRYPT_LIBS"
+], [
+ AC_SEARCH_LIBS([crypt_gensalt_rn],[crypt])
+ case "$ac_cv_search_crypt_gensalt_rn" in
+ -l*) LIBCRYPT="$ac_cv_search_crypt_gensalt_rn" ;;
+ no) AC_SEARCH_LIBS([crypt_r],[crypt])
+ case "$ac_cv_search_crypt_r" in
+ -l*) LIBCRYPT="$ac_cv_search_crypt_r" ;;
+ no ) AC_SEARCH_LIBS([crypt],[crypt])
+ case "$ac_cv_search_crypt" in
+ -l*) LIBCRYPT="$ac_cv_search_crypt" ;;
+ esac ;;
+ esac ;;
+ esac
+])
+AC_CHECK_FUNCS([crypt_r])
LIBS=$BACKUP_LIBS
AC_SUBST(LIBCRYPT)
-if test "$LIBCRYPT" = "-lxcrypt" -a "$ac_cv_header_xcrypt_h" = "yes" ; then
- AC_DEFINE([HAVE_LIBXCRYPT], 1, [Define to 1 if xcrypt support should be compiled in.])
-fi
AC_ARG_WITH([randomdev], AS_HELP_STRING([--with-randomdev=(<path>|yes|no)],[use specified random device instead of /dev/urandom or 'no' to disable]), opt_randomdev=$withval)
if test "$opt_randomdev" = yes -o -z "$opt_randomdev"; then
diff -up Linux-PAM-1.3.1/modules/pam_pwhistory/opasswd.c.legacy-xcrypt Linux-PAM-1.3.1/modules/pam_pwhistory/opasswd.c
--- Linux-PAM-1.3.1/modules/pam_pwhistory/opasswd.c.legacy-xcrypt 2023-10-26 12:08:46.896437225 +0200
+++ Linux-PAM-1.3.1/modules/pam_pwhistory/opasswd.c 2023-10-26 12:11:14.437725259 +0200
@@ -52,9 +52,7 @@
#include <stdarg.h>
#include <sys/stat.h>
-#if defined (HAVE_XCRYPT_H)
-#include <xcrypt.h>
-#elif defined (HAVE_CRYPT_H)
+#ifdef HAVE_CRYPT_H
#include <crypt.h>
#endif
diff -up Linux-PAM-1.3.1/modules/pam_unix/bigcrypt.c.legacy-xcrypt Linux-PAM-1.3.1/modules/pam_unix/bigcrypt.c
--- Linux-PAM-1.3.1/modules/pam_unix/bigcrypt.c.legacy-xcrypt 2017-02-10 11:10:15.000000000 +0100
+++ Linux-PAM-1.3.1/modules/pam_unix/bigcrypt.c 2023-10-26 12:08:46.896437225 +0200
@@ -29,9 +29,7 @@
#include <string.h>
#include <stdlib.h>
#include <security/_pam_macros.h>
-#ifdef HAVE_LIBXCRYPT
-#include <xcrypt.h>
-#elif defined(HAVE_CRYPT_H)
+#ifdef HAVE_CRYPT_H
#include <crypt.h>
#endif
diff -up Linux-PAM-1.3.1/modules/pam_unix/passverify.c.legacy-xcrypt Linux-PAM-1.3.1/modules/pam_unix/passverify.c
--- Linux-PAM-1.3.1/modules/pam_unix/passverify.c.legacy-xcrypt 2023-10-26 12:08:46.895437223 +0200
+++ Linux-PAM-1.3.1/modules/pam_unix/passverify.c 2023-10-26 12:16:25.470320408 +0200
@@ -19,9 +19,7 @@
#include <sys/time.h>
#include <sys/stat.h>
#include <fcntl.h>
-#ifdef HAVE_LIBXCRYPT
-#include <xcrypt.h>
-#elif defined(HAVE_CRYPT_H)
+#ifdef HAVE_CRYPT_H
#include <crypt.h>
#endif
@@ -406,23 +404,19 @@ PAMH_ARG_DECL(char * create_password_has
return crypted;
}
-#ifdef HAVE_CRYPT_GENSALT_R
- if (on(UNIX_BLOWFISH_PASS, ctrl)) {
- char entropy[17];
- crypt_make_salt(entropy, sizeof(entropy) - 1);
- sp = crypt_gensalt_r (algoid, rounds,
- entropy, sizeof(entropy),
- salt, sizeof(salt));
- } else {
-#endif
- sp = stpcpy(salt, algoid);
- if (on(UNIX_ALGO_ROUNDS, ctrl)) {
- sp += snprintf(sp, sizeof(salt) - (16 + 1 + (sp - salt)), "rounds=%u$", rounds);
- }
- crypt_make_salt(sp, 16);
-#ifdef HAVE_CRYPT_GENSALT_R
+#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
+ sp = stpcpy(salt, algoid);
+ if (on(UNIX_ALGO_ROUNDS, ctrl)) {
+ sp += snprintf(sp, sizeof(salt) - (16 + 1 + (sp - salt)), "rounds=%u$", rounds);
}
-#endif
+ crypt_make_salt(sp, 16);
+#endif /* CRYPT_GENSALT_IMPLEMENTS_AUTO_ENTROPY */
#ifdef HAVE_CRYPT_R
sp = NULL;
cdata = malloc(sizeof(*cdata));
diff -up Linux-PAM-1.3.1/modules/pam_userdb/pam_userdb.c.legacy-xcrypt Linux-PAM-1.3.1/modules/pam_userdb/pam_userdb.c
--- Linux-PAM-1.3.1/modules/pam_userdb/pam_userdb.c.legacy-xcrypt 2023-10-26 12:08:46.880437194 +0200
+++ Linux-PAM-1.3.1/modules/pam_userdb/pam_userdb.c 2023-10-26 12:08:46.896437225 +0200
@@ -17,9 +17,7 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
-#ifdef HAVE_LIBXCRYPT
-#include <xcrypt.h>
-#elif defined(HAVE_CRYPT_H)
+#ifdef HAVE_CRYPT_H
#include <crypt.h>
#endif

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -1,19 +1,4 @@
#%PAM-1.0
# This file is auto-generated.
# User changes will be destroyed the next time authselect is run.
auth required pam_env.so
auth [success=done ignore=ignore default=die] pam_pkcs11.so wait_for_card
auth required pam_deny.so
account required pam_unix.so
account sufficient pam_localuser.so
account sufficient pam_succeed_if.so uid < 500 quiet
account required pam_permit.so
password optional pam_pkcs11.so
session optional pam_keyinit.so revoke
session required pam_limits.so
-session optional pam_systemd.so
session [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
session required pam_unix.so
auth sufficient pam_sss.so allow_missing_name

View File

@ -3,7 +3,7 @@
Summary: An extensible library which provides authentication for applications
Name: pam
Version: 1.3.1
Release: 22%{?dist}
Release: 33%{?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+.
@ -85,6 +85,31 @@ Patch57: pam-1.3.1-inline.patch
Patch58: pam-1.3.1-faillock-load-conf-from-file.patch
# https://github.com/linux-pam/linux-pam/commit/370064ef6f99581b08d473a42bb3417d5dda3e4e
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
# https://github.com/linux-pam/linux-pam/commit/55f206447a1e4ee26e307e7a9c069236e823b1a5
# https://github.com/linux-pam/linux-pam/commit/80bfda5962e5be3daa70e0fc8c75fc97d1c55121
Patch65: pam-1.3.1-pam-misc-configurable.patch
# https://github.com/linux-pam/linux-pam/commit/530c9f9e2d746e1d168c6b17863debda7664ac7c
# https://github.com/linux-pam/linux-pam/commit/f7abb8c1ef3aa31e6c2564a8aaf69683a77c2016
Patch66: pam-1.3.1-unix-enable-bcrypt.patch
Patch67: pam-1.3.1-unix-default-rounds.patch
# https://github.com/linux-pam/linux-pam/commit/d54870f993e97fe75e2cd0470a3701d5af22877c
Patch68: pam-1.3.1-faillock-create-tallydir.patch
# https://github.com/linux-pam/linux-pam/commit/23393bef92c1e768eda329813d7af55481c6ca9f
Patch69: pam-1.3.1-access-handle-hostnames.patch
# https://github.com/linux-pam/linux-pam/commit/031bb5a5d0d950253b68138b498dc93be69a64cb
Patch70: pam-1.3.1-namespace-protect-dir.patch
%define _pamlibdir %{_libdir}
%define _moduledir %{_libdir}/security
@ -192,6 +217,17 @@ cp %{SOURCE18} .
%patch57 -p1 -b .inline
%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
%patch65 -p1 -b .pam-misc-configurable
%patch66 -p1 -b .unix-enable-bcrypt
%patch67 -p1 -b .unix-default-rounds
%patch68 -p1 -b .faillock-create-tallydir
%patch69 -p1 -b .access-handle-hostnames
%patch70 -p1 -b .namespace-protect-dir
autoreconf -i
@ -416,6 +452,7 @@ done
%dir %{_secconfdir}/namespace.d
%attr(755,root,root) %config(noreplace) %{_secconfdir}/namespace.init
%config(noreplace) %{_secconfdir}/pam_env.conf
%config(noreplace) %{_secconfdir}/pwhistory.conf
%config(noreplace) %{_secconfdir}/time.conf
%config(noreplace) %{_secconfdir}/opasswd
%dir %{_secconfdir}/console.apps
@ -444,6 +481,34 @@ done
%doc doc/specs/rfc86.0.txt
%changelog
* Mon Feb 12 2024 Iker Pedrosa <ipedrosa@redhat.com> - 1.3.1-33
- pam_namespace: protect_dir(): use O_DIRECTORY to prevent local DoS
situations. CVE-2024-22365. Resolves: RHEL-21242
* Fri Jan 26 2024 Iker Pedrosa <ipedrosa@redhat.com> - 1.3.1-32
- pam_access: handle hostnames in access.conf. Resolves: RHEL-3374
* Mon Jan 8 2024 Iker Pedrosa <ipedrosa@redhat.com> - 1.3.1-31
- pam_faillock: create tallydir before creating tallyfile. Resolves: RHEL-19810
* Thu Nov 2 2023 Iker Pedrosa <ipedrosa@redhat.com> - 1.3.1-30
- pam_unix: enable bcrypt. Resolves: RHEL-5057
* Mon Jun 26 2023 Iker Pedrosa <ipedrosa@redhat.com> - 1.3.1-27
- pam_misc: make length of misc_conv() configurable and set to 4096. Resolves: #2209785
* Tue May 16 2023 Iker Pedrosa <ipedrosa@redhat.com> - 1.3.1-26
- smartcard-auth: modify the content to remove unnecessary modules. Resolves: #1983683
* 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
* Wed Jul 13 2022 Iker Pedrosa <ipedrosa@redhat.com> - 1.3.1-22
- Regenerate the /run/motd.d at each boot. Resolves: #2104878