Compare commits

...

No commits in common. 'c9' and 'cs10' have entirely different histories.
c9 ... cs10

4
.gitignore vendored

@ -1,2 +1,2 @@
SOURCES/Linux-PAM-1.5.1.tar.xz
SOURCES/pam-redhat-1.1.4.tar.bz2
SOURCES/Linux-PAM-1.6.1.tar.xz
SOURCES/pam-redhat-1.2.0.tar.xz

@ -1,2 +1,2 @@
ad43b7fbdfdd38886fdf27e098b49f2db1c2a13d SOURCES/Linux-PAM-1.5.1.tar.xz
bf661c44f34c2d4d34eaee695b36e638f4d44ba8 SOURCES/pam-redhat-1.1.4.tar.bz2
633dfd431955044f7a4087553a5b00b509897197 SOURCES/Linux-PAM-1.6.1.tar.xz
d84f186748f6b9ff84980a39acdaf76531c4990e SOURCES/pam-redhat-1.2.0.tar.xz

@ -1,16 +0,0 @@
-----BEGIN PGP SIGNATURE-----
iQIcBAABCAAGBQJfvo0CAAoJEKgEH6g54W42L+0P/19bgVH4cRd7ONZLwYvWvWlQ
NXkjwn26MEXElWESlKnQQz08W5QASWCz3vgAn9NGDmS+lJ38i4Li4aGpn3COPE2g
BAN9LEaAErK60b3ZkWwDEARDs1JntA1vUuuHx0EoLEMtFEeU20h5PPMrsDwu7LGF
sD6KYdM6TWLMXcRybqGOeWmWxfp8S8MVNwVN3C3q0aVIOMxky0i4rzCL7zRTJztQ
q7FaX2xrTGfUiAI7smT/KGoK7pbQTzZtoR67uE/2WZ4bSyWMZcuDkt16WP/L6x9v
c5DnVaLazM9xYUAOn4tlPiG8LLmfXo1MjD+KOS9byAx+uTij3avxaC/vv0BDcATH
jywxH8iTPkvYXP0uJIa4Gbs1qi3vNZn+gaQt/T+rCVNo3dfFZZxBvLbTQ8AN1hKr
MnoQbIQh0buuSuwmAxF0EDIefX3bDCurKOTQrRajK7huFm0w2NgBqL8WR8f1Wmm9
mGSdKuVpWSk5uEygCUFOfwviYbi1I1K2Dmo3TsLBgNPKvAF3LAGJC7KzD+Q+Nmos
XBOljilcAfdJ7t2P8W7xTSMEnXu7nI1TM+Er80ukfu0fipJEP0xyi+XWh+2n0Bx+
3wwt8fSL7rmI4I4l6GRb3Jk/Gq1bKy956tgm3TE6gXTXVGZqNs0E28rNRURXDqZu
XrjVwhlpsH/Auk17hU65
=E0ev
-----END PGP SIGNATURE-----

@ -0,0 +1,16 @@
-----BEGIN PGP SIGNATURE-----
iQIcBAABCgAGBQJmFWt/AAoJEKgEH6g54W42NCwP/iWl8igdScTreVF6zV79Dqu1
sl+ZjBr/dL+DOTcotsRnoAZUOy4ug3iktMZr1t0BMpWUorNmUofH4SZuhsX0CgRq
47t5mVqCakwn4JLq8J9cLOciMno6ips5ZT4RbMgzRYd1WcBurCAxQSNLP3aQGgub
RFObkqw5814ksz9Ge6QVhJ4l9P0wUoKfcpkzHj2Vq+cy0EzlBtnBGCHrMDgrz5aT
mXqGVvWTPO+lR2S+7wOLUtPoRv0uvN6h97ZszaoGoJ6wa6yYwOYz12/AiIsVQhet
cnr29ymuwPDqlrYGD1Hb0+ZUQExjVDQY90hdJ/ZntUlK7CY/2SotpDGB9kR8dTYJ
fpIVmR6GEZ+xSjBqa7RaiL8ieZCgT3TIvsMqteiFkqI+2lhlSGHX3g3oNSd3sbqd
PLok6W4L+xWDp89aMyYDDs/ISjBt5sSNK4NOOTZIMK4oeScGJJvrDL3S5DOSk1ku
o3l9N62WStD7fk0LYnyUGZORg/ccK6Yy2fV22zBMm/76PoyA1yHfFxCW+HwwmcqR
0riaFjA8cesZ3Dj79q24U3FRVdW5fTF9gS/5mK/Yj51KMMzTkUmbjksEC/AEBKzB
9laXxPdIeKUwNlGs7Heo/NE87u4OZfyihwpzLaTcOzbpN3zDyH6aH5poDs1FSaQ2
UoUkHsbCWJU/ksn/9BIQ
=Dbz2
-----END PGP SIGNATURE-----

@ -8,7 +8,7 @@ config-util \- Common PAM configuration file for configuration utilities
.sp 2
.SH DESCRIPTION
The purpose of this configuration file is to provide common
The purpose of this configuration file is to provide common
configuration file for all configuration utilities which must be run
from the supervisor account and use the userhelper wrapper application.
@ -23,7 +23,7 @@ There are not usually any other modules in the individual configuration
files of these utilities.
.sp
It is possible for example to modify duration of the validity of the
It is possible for example to modify duration of the validity of the
authentication timestamp there. See
.BR pam_timestamp(8)
for details.

@ -1,19 +0,0 @@
#%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 sufficient pam_fprintd.so
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 required pam_deny.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

@ -0,0 +1,5 @@
%_pam_libdir %{_libdir}
%_pam_moduledir %{_libdir}/security
%_pam_secconfdir %{_sysconfdir}/security
%_pam_confdir %{_sysconfdir}/pam.d
%_pam_vendordir %{_datadir}/pam.d

@ -1,144 +0,0 @@
From 244b46908df930626535c0cd7c2867407fe8714a Mon Sep 17 00:00:00 2001
From: Thorsten Kukuk <kukuk@suse.com>
Date: Tue, 14 Feb 2023 14:57:40 +0100
Subject: [PATCH] libpam: use getlogin() from libc and not utmp
utmp uses 32bit time_t for compatibility with 32bit userland on some
64bit systems and is thus not Y2038 safe. Use getlogin() from libc
which avoids using utmp and is more safe than the old utmp-based
implementation by using /proc/self/loginuid.
* libpam/pam_modutil_getlogin.c: Use getlogin() instead of parsing utmp
---
libpam/pam_modutil_getlogin.c | 52 ++++++++---------------------------
1 file changed, 11 insertions(+), 41 deletions(-)
diff --git a/libpam/pam_modutil_getlogin.c b/libpam/pam_modutil_getlogin.c
index 04a20fd8..633dd676 100644
--- a/libpam/pam_modutil_getlogin.c
+++ b/libpam/pam_modutil_getlogin.c
@@ -10,7 +10,6 @@
#include <stdlib.h>
#include <unistd.h>
-#include <utmp.h>
#define _PAMMODUTIL_GETLOGIN "_pammodutil_getlogin"
@@ -19,62 +18,33 @@ pam_modutil_getlogin(pam_handle_t *pamh)
{
int status;
const void *logname;
- const void *void_curr_tty;
- const char *curr_tty;
char *curr_user;
- struct utmp *ut, line;
+ size_t curr_user_len;
status = pam_get_data(pamh, _PAMMODUTIL_GETLOGIN, &logname);
if (status == PAM_SUCCESS) {
return logname;
}
- status = pam_get_item(pamh, PAM_TTY, &void_curr_tty);
- if ((status != PAM_SUCCESS) || (void_curr_tty == NULL))
- curr_tty = ttyname(0);
- else
- curr_tty = (const char*)void_curr_tty;
-
- if (curr_tty == NULL) {
- return NULL;
- }
-
- if (curr_tty[0] == '/') { /* full path */
- const char *t;
- curr_tty++;
- if ((t = strchr(curr_tty, '/')) != NULL) {
- curr_tty = t + 1;
- }
+ logname = getlogin();
+ if (logname == NULL) {
+ return NULL;
}
- logname = NULL;
- setutent();
- strncpy(line.ut_line, curr_tty, sizeof(line.ut_line));
-
- if ((ut = getutline(&line)) == NULL) {
- goto clean_up_and_go_home;
- }
-
- curr_user = calloc(sizeof(line.ut_user)+1, 1);
+ curr_user_len = strlen(logname)+1;
+ curr_user = calloc(curr_user_len, 1);
if (curr_user == NULL) {
- goto clean_up_and_go_home;
+ return NULL;
}
- strncpy(curr_user, ut->ut_user, sizeof(ut->ut_user));
- /* calloc already zeroed the memory */
+ memcpy(curr_user, logname, curr_user_len);
status = pam_set_data(pamh, _PAMMODUTIL_GETLOGIN, curr_user,
pam_modutil_cleanup);
if (status != PAM_SUCCESS) {
- free(curr_user);
- goto clean_up_and_go_home;
+ free(curr_user);
+ return NULL;
}
- logname = curr_user;
-
-clean_up_and_go_home:
-
- endutent();
-
- return logname;
+ return curr_user;
}
--
2.43.0
From f26d873435be9f35fa7953493cc07a9bc4e31876 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Sat, 18 Feb 2023 14:37:04 +0100
Subject: [PATCH] libpam: simplify string copying using strdup
---
libpam/pam_modutil_getlogin.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/libpam/pam_modutil_getlogin.c b/libpam/pam_modutil_getlogin.c
index 633dd676..2e7a0116 100644
--- a/libpam/pam_modutil_getlogin.c
+++ b/libpam/pam_modutil_getlogin.c
@@ -19,7 +19,6 @@ pam_modutil_getlogin(pam_handle_t *pamh)
int status;
const void *logname;
char *curr_user;
- size_t curr_user_len;
status = pam_get_data(pamh, _PAMMODUTIL_GETLOGIN, &logname);
if (status == PAM_SUCCESS) {
@@ -31,14 +30,11 @@ pam_modutil_getlogin(pam_handle_t *pamh)
return NULL;
}
- curr_user_len = strlen(logname)+1;
- curr_user = calloc(curr_user_len, 1);
+ curr_user = strdup(logname);
if (curr_user == NULL) {
return NULL;
}
- memcpy(curr_user, logname, curr_user_len);
-
status = pam_set_data(pamh, _PAMMODUTIL_GETLOGIN, curr_user,
pam_modutil_cleanup);
if (status != PAM_SUCCESS) {
--
2.43.0

@ -1,24 +0,0 @@
diff -up Linux-PAM-1.5.0/doc/Makefile.am.noflex Linux-PAM-1.5.0/doc/Makefile.am
--- Linux-PAM-1.5.0/doc/Makefile.am.noflex 2020-11-10 16:46:13.000000000 +0100
+++ Linux-PAM-1.5.0/doc/Makefile.am 2020-11-11 11:39:00.980421433 +0100
@@ -2,7 +2,7 @@
# Copyright (c) 2005, 2006 Thorsten Kukuk <kukuk@suse.de>
#
-SUBDIRS = man specs sag adg mwg
+SUBDIRS = man sag adg mwg
CLEANFILES = *~
diff -up Linux-PAM-1.5.0/Makefile.am.noflex Linux-PAM-1.5.0/Makefile.am
--- Linux-PAM-1.5.0/Makefile.am.noflex 2020-11-11 11:39:00.980421433 +0100
+++ Linux-PAM-1.5.0/Makefile.am 2020-11-11 11:39:15.887625418 +0100
@@ -4,7 +4,7 @@
AUTOMAKE_OPTIONS = 1.9 gnu dist-xz no-dist-gzip check-news
-SUBDIRS = libpam tests libpamc libpam_misc modules po conf examples xtests
+SUBDIRS = libpam tests libpamc libpam_misc modules po doc examples xtests
if HAVE_DOC
SUBDIRS += doc

@ -1,25 +0,0 @@
diff -up Linux-PAM-1.5.0/configure.ac.redhat-modules Linux-PAM-1.5.0/configure.ac
--- Linux-PAM-1.5.0/configure.ac.redhat-modules 2020-11-11 11:21:21.947857371 +0100
+++ Linux-PAM-1.5.0/configure.ac 2020-11-11 11:22:58.638193747 +0100
@@ -639,6 +639,8 @@ AC_CONFIG_FILES([Makefile libpam/Makefil
po/Makefile.in \
Make.xml.rules \
modules/Makefile \
+ modules/pam_chroot/Makefile modules/pam_console/Makefile \
+ modules/pam_postgresok/Makefile \
modules/pam_access/Makefile \
modules/pam_debug/Makefile modules/pam_deny/Makefile \
modules/pam_echo/Makefile modules/pam_env/Makefile \
diff -up Linux-PAM-1.5.0/modules/Makefile.am.redhat-modules Linux-PAM-1.5.0/modules/Makefile.am
--- Linux-PAM-1.5.0/modules/Makefile.am.redhat-modules 2020-11-10 16:46:13.000000000 +0100
+++ Linux-PAM-1.5.0/modules/Makefile.am 2020-11-11 11:21:21.947857371 +0100
@@ -47,6 +47,9 @@ SUBDIRS := \
pam_debug \
pam_deny \
pam_echo \
+ pam_chroot \
+ pam_console \
+ pam_postgresok \
pam_env \
pam_exec \
pam_faildelay \

@ -1,168 +0,0 @@
diff -up Linux-PAM-1.5.1/modules/pam_access/pam_access.c.access-handle-hostnames Linux-PAM-1.5.1/modules/pam_access/pam_access.c
--- Linux-PAM-1.5.1/modules/pam_access/pam_access.c.access-handle-hostnames 2020-11-25 17:57:02.000000000 +0100
+++ Linux-PAM-1.5.1/modules/pam_access/pam_access.c 2024-01-22 15:56:09.977868880 +0100
@@ -662,7 +662,7 @@ from_match (pam_handle_t *pamh UNUSED, c
}
}
} else {
- /* Assume network/netmask with a IP of a host. */
+ /* Assume network/netmask, IP address or hostname. */
if (network_netmask_match(pamh, tok, string, item))
return YES;
}
@@ -684,7 +684,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 */
@@ -702,7 +702,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,
@@ -711,10 +712,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)
{
@@ -748,54 +751,108 @@ 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)
{
+ pam_syslog(pamh, LOG_ERR, "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];
- DIAG_PUSH_IGNORE_CAST_ALIGN;
- 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));
- DIAG_POP_IGNORE_CAST_ALIGN;
+ 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;
}

@ -1,72 +0,0 @@
From c85513220c1bd3150e39c6277422d29cfa44acc7 Mon Sep 17 00:00:00 2001
From: Steve Grubb <sgrubb@redhat.com>
Date: Thu, 27 Jul 2023 13:14:42 -0400
Subject: [PATCH 1/2] pam_faillock: fix formatting of audit messages
pam_faillock uses audit_log_user_message to write to the audit system.
It does not take an op argument, so you have to add one yourself. Otherwise
the pam_faillock part of the message is lost because it's not in key=value
format.
Also, we can't use uid in that event because the kernel already adds that
field. What we normally do is use 'suid' (meaning sender uid) as the
field name.
---
modules/pam_faillock/pam_faillock.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/modules/pam_faillock/pam_faillock.c b/modules/pam_faillock/pam_faillock.c
index ca1c7035..a89909ab 100644
--- a/modules/pam_faillock/pam_faillock.c
+++ b/modules/pam_faillock/pam_faillock.c
@@ -248,7 +248,7 @@ check_tally(pam_handle_t *pamh, struct options *opts, struct tally_data *tallies
(void)pam_get_item(pamh, PAM_TTY, &tty);
(void)pam_get_item(pamh, PAM_RHOST, &rhost);
- snprintf(buf, sizeof(buf), "pam_faillock uid=%u ", opts->uid);
+ snprintf(buf, sizeof(buf), "op=pam_faillock suid=%u ", opts->uid);
audit_log_user_message(audit_fd, AUDIT_RESP_ACCT_UNLOCK_TIMED, buf,
rhost, NULL, tty, 1);
}
@@ -364,7 +364,7 @@ write_tally(pam_handle_t *pamh, struct options *opts, struct tally_data *tallies
errno == EAFNOSUPPORT))
return PAM_SYSTEM_ERR;
- snprintf(buf, sizeof(buf), "pam_faillock uid=%u ", opts->uid);
+ snprintf(buf, sizeof(buf), "op=pam_faillock suid=%u ", opts->uid);
audit_log_user_message(audit_fd, AUDIT_ANOM_LOGIN_FAILURES, buf,
NULL, NULL, NULL, 1);
--
2.41.0
From 1648734a69c31e9ce834da70144ac9a453296807 Mon Sep 17 00:00:00 2001
From: Steve Grubb <sgrubb@redhat.com>
Date: Fri, 4 Aug 2023 17:45:45 -0400
Subject: [PATCH 2/2] pam_selinux: fix formatting of audit messages
pam_selinux uses audit_log_user_message to write to the audit system.
It does not take an op argument, so you have to add one yourself. Otherwise
the pam_selinux part of the message is lost because it's not in key=value
format.
---
modules/pam_selinux/pam_selinux.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/pam_selinux/pam_selinux.c b/modules/pam_selinux/pam_selinux.c
index e52e0fc4..713b3f73 100644
--- a/modules/pam_selinux/pam_selinux.c
+++ b/modules/pam_selinux/pam_selinux.c
@@ -97,7 +97,7 @@ send_audit_message(const pam_handle_t *pamh, int success, const char *default_co
pam_syslog(pamh, LOG_ERR, "Error translating selected context '%s'.", selected_context);
selected_raw = NULL;
}
- if (asprintf(&msg, "pam: default-context=%s selected-context=%s",
+ if (asprintf(&msg, "op=pam_selinux default-context=%s selected-context=%s",
default_raw ? default_raw : (default_context ? default_context : "?"),
selected_raw ? selected_raw : (selected_context ? selected_context : "?")) < 0) {
msg = NULL; /* asprintf leaves msg in undefined state on failure */
--
2.41.0

@ -1,36 +0,0 @@
From d54870f993e97fe75e2cd0470a3701d5af22877c Mon Sep 17 00:00:00 2001
From: Changqing Li <changqing.li@windriver.com>
Date: Tue, 12 Jan 2021 14:45:34 +0800
Subject: [PATCH] faillock: create tallydir before creating tallyfile
The default tallydir is "/var/run/faillock", and this default
tallydir may not exist.
Function open may fail as tallydir does not exist when creating
the tallyfile. Therefore, faillock will not work well.
Fix this problem by creating tallydir before creating tallyfile
when the tallydir does not exist.
Signed-off-by: Changqing Li <changqing.li@windriver.com>
---
modules/pam_faillock/faillock.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/modules/pam_faillock/faillock.c b/modules/pam_faillock/faillock.c
index 4ea94cbe..091f253a 100644
--- a/modules/pam_faillock/faillock.c
+++ b/modules/pam_faillock/faillock.c
@@ -74,6 +74,9 @@ open_tally (const char *dir, const char *user, uid_t uid, int create)
if (create) {
flags |= O_CREAT;
+ if (access(dir, F_OK) != 0) {
+ mkdir(dir, 0755);
+ }
}
fd = open(path, flags, 0660);
--
2.43.0

@ -1,848 +0,0 @@
diff -up Linux-PAM-1.5.1/modules/pam_faillock/faillock.8.xml.faillock-load-conf-from-file Linux-PAM-1.5.1/modules/pam_faillock/faillock.8.xml
--- Linux-PAM-1.5.1/modules/pam_faillock/faillock.8.xml.faillock-load-conf-from-file 2020-11-25 17:57:02.000000000 +0100
+++ Linux-PAM-1.5.1/modules/pam_faillock/faillock.8.xml 2022-05-25 15:30:33.700518571 +0200
@@ -57,12 +57,29 @@
<variablelist>
<varlistentry>
<term>
+ <option>--conf <replaceable>/path/to/config-file</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ The file where the configuration is located. The default is
+ <filename>/etc/security/faillock.conf</filename>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
<option>--dir <replaceable>/path/to/tally-directory</replaceable></option>
</term>
<listitem>
<para>
- The directory where the user files with the failure records are kept. The
- default is <filename>/var/run/faillock</filename>.
+ The directory where the user files with the failure records are kept.
+ </para>
+ <para>
+ The priority to set this option is to use the value provided
+ from the command line. If this isn't provided, then the value
+ from the configuration file is used. Finally, if neither of
+ them has been provided, then
+ <filename>/var/run/faillock</filename> is used.
</para>
</listitem>
</varlistentry>
diff -up Linux-PAM-1.5.1/modules/pam_faillock/faillock_config.c.faillock-load-conf-from-file Linux-PAM-1.5.1/modules/pam_faillock/faillock_config.c
--- Linux-PAM-1.5.1/modules/pam_faillock/faillock_config.c.faillock-load-conf-from-file 2022-05-25 15:30:33.699518564 +0200
+++ Linux-PAM-1.5.1/modules/pam_faillock/faillock_config.c 2022-05-25 15:30:33.700518571 +0200
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 2022 Tomas Mraz <tm@t8m.info>
+ * 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 <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+
+#include <security/pam_modules.h>
+
+#include "faillock_config.h"
+#include "faillock.h"
+
+#define FAILLOCK_DEFAULT_CONF "/etc/security/faillock.conf"
+
+static void PAM_FORMAT((printf, 3, 4)) PAM_NONNULL((3))
+config_log(const pam_handle_t *pamh, int priority, const char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ if (pamh) {
+ pam_vsyslog(pamh, priority, fmt, args);
+ } else {
+ char *buf = NULL;
+
+ if (vasprintf(&buf, fmt, args) < 0) {
+ fprintf(stderr, "vasprintf: %m");
+ va_end(args);
+ return;
+ }
+ fprintf(stderr, "%s\n", buf);
+ free(buf);
+ }
+ va_end(args);
+}
+
+/* parse a single configuration file */
+int
+read_config_file(pam_handle_t *pamh, struct options *opts, const char *cfgfile)
+{
+ char linebuf[FAILLOCK_CONF_MAX_LINELEN+1];
+ const char *fname = (cfgfile != NULL) ? cfgfile : FAILLOCK_DEFAULT_CONF;
+ FILE *f = fopen(fname, "r");
+
+#ifdef VENDOR_FAILLOCK_DEFAULT_CONF
+ if (f == NULL && errno == ENOENT && cfgfile == NULL) {
+ /*
+ * If the default configuration file in /etc does not exist,
+ * try the vendor configuration file as fallback.
+ */
+ f = fopen(VENDOR_FAILLOCK_DEFAULT_CONF, "r");
+ }
+#endif /* VENDOR_FAILLOCK_DEFAULT_CONF */
+
+ if (f == NULL) {
+ /* ignore non-existent default config file */
+ if (errno == ENOENT && cfgfile == NULL)
+ return PAM_SUCCESS;
+ return PAM_SERVICE_ERR;
+ }
+
+ while (fgets(linebuf, sizeof(linebuf), f) != NULL) {
+ size_t len;
+ char *ptr;
+ char *name;
+ int eq;
+
+ len = strlen(linebuf);
+ /* len cannot be 0 unless there is a bug in fgets */
+ if (len && linebuf[len - 1] != '\n' && !feof(f)) {
+ (void) fclose(f);
+ return PAM_SERVICE_ERR;
+ }
+
+ if ((ptr=strchr(linebuf, '#')) != NULL) {
+ *ptr = '\0';
+ } else {
+ ptr = linebuf + len;
+ }
+
+ /* drop terminating whitespace including the \n */
+ while (ptr > linebuf) {
+ if (!isspace(*(ptr-1))) {
+ *ptr = '\0';
+ break;
+ }
+ --ptr;
+ }
+
+ /* skip initial whitespace */
+ for (ptr = linebuf; isspace(*ptr); ptr++);
+ if (*ptr == '\0')
+ continue;
+
+ /* grab the key name */
+ eq = 0;
+ name = ptr;
+ while (*ptr != '\0') {
+ if (isspace(*ptr) || *ptr == '=') {
+ eq = *ptr == '=';
+ *ptr = '\0';
+ ++ptr;
+ break;
+ }
+ ++ptr;
+ }
+
+ /* grab the key value */
+ while (*ptr != '\0') {
+ if (*ptr != '=' || eq) {
+ if (!isspace(*ptr)) {
+ break;
+ }
+ } else {
+ eq = 1;
+ }
+ ++ptr;
+ }
+
+ /* set the key:value pair on opts */
+ set_conf_opt(pamh, opts, name, ptr);
+ }
+
+ (void)fclose(f);
+ return PAM_SUCCESS;
+}
+
+void
+set_conf_opt(pam_handle_t *pamh, struct options *opts, const char *name,
+ const char *value)
+{
+ if (strcmp(name, "dir") == 0) {
+ if (value[0] != '/') {
+ config_log(pamh, LOG_ERR,
+ "Tally directory is not absolute path (%s); keeping value",
+ value);
+ } else {
+ free(opts->dir);
+ opts->dir = strdup(value);
+ if (opts->dir == NULL) {
+ opts->fatal_error = 1;
+ config_log(pamh, LOG_CRIT, "Error allocating memory: %m");
+ }
+ }
+ }
+ else if (strcmp(name, "deny") == 0) {
+ if (sscanf(value, "%hu", &opts->deny) != 1) {
+ config_log(pamh, LOG_ERR,
+ "Bad number supplied for deny argument");
+ }
+ }
+ else if (strcmp(name, "fail_interval") == 0) {
+ unsigned int temp;
+ if (sscanf(value, "%u", &temp) != 1 ||
+ temp > MAX_TIME_INTERVAL) {
+ config_log(pamh, LOG_ERR,
+ "Bad number supplied for fail_interval argument");
+ } else {
+ opts->fail_interval = temp;
+ }
+ }
+ else if (strcmp(name, "unlock_time") == 0) {
+ unsigned int temp;
+
+ if (strcmp(value, "never") == 0) {
+ opts->unlock_time = 0;
+ }
+ else if (sscanf(value, "%u", &temp) != 1 ||
+ temp > MAX_TIME_INTERVAL) {
+ config_log(pamh, LOG_ERR,
+ "Bad number supplied for unlock_time argument");
+ }
+ else {
+ opts->unlock_time = temp;
+ }
+ }
+ else if (strcmp(name, "root_unlock_time") == 0) {
+ unsigned int temp;
+
+ if (strcmp(value, "never") == 0) {
+ opts->root_unlock_time = 0;
+ }
+ else if (sscanf(value, "%u", &temp) != 1 ||
+ temp > MAX_TIME_INTERVAL) {
+ config_log(pamh, LOG_ERR,
+ "Bad number supplied for root_unlock_time argument");
+ } else {
+ opts->root_unlock_time = temp;
+ }
+ }
+ else if (strcmp(name, "admin_group") == 0) {
+ free(opts->admin_group);
+ opts->admin_group = strdup(value);
+ if (opts->admin_group == NULL) {
+ opts->fatal_error = 1;
+ config_log(pamh, LOG_CRIT, "Error allocating memory: %m");
+ }
+ }
+ else if (strcmp(name, "even_deny_root") == 0) {
+ opts->flags |= FAILLOCK_FLAG_DENY_ROOT;
+ }
+ else if (strcmp(name, "audit") == 0) {
+ opts->flags |= FAILLOCK_FLAG_AUDIT;
+ }
+ else if (strcmp(name, "silent") == 0) {
+ opts->flags |= FAILLOCK_FLAG_SILENT;
+ }
+ else if (strcmp(name, "no_log_info") == 0) {
+ opts->flags |= FAILLOCK_FLAG_NO_LOG_INFO;
+ }
+ else if (strcmp(name, "local_users_only") == 0) {
+ opts->flags |= FAILLOCK_FLAG_LOCAL_ONLY;
+ }
+ else if (strcmp(name, "nodelay") == 0) {
+ opts->flags |= FAILLOCK_FLAG_NO_DELAY;
+ }
+ else {
+ config_log(pamh, LOG_ERR, "Unknown option: %s", name);
+ }
+}
+
+const char *get_tally_dir(const struct options *opts)
+{
+ return (opts->dir != NULL) ? opts->dir : FAILLOCK_DEFAULT_TALLYDIR;
+}
diff -up Linux-PAM-1.5.1/modules/pam_faillock/faillock_config.h.faillock-load-conf-from-file Linux-PAM-1.5.1/modules/pam_faillock/faillock_config.h
--- Linux-PAM-1.5.1/modules/pam_faillock/faillock_config.h.faillock-load-conf-from-file 2022-05-25 15:30:33.699518564 +0200
+++ Linux-PAM-1.5.1/modules/pam_faillock/faillock_config.h 2022-05-25 15:30:33.700518571 +0200
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2022 Tomas Mraz <tm@t8m.info>
+ * 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.
+ */
+
+/*
+ * faillock_config.h - load configuration options from file
+ *
+ */
+
+#ifndef _FAILLOCK_CONFIG_H
+#define _FAILLOCK_CONFIG_H
+
+#include <limits.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <security/pam_ext.h>
+
+#define FAILLOCK_FLAG_DENY_ROOT 0x1
+#define FAILLOCK_FLAG_AUDIT 0x2
+#define FAILLOCK_FLAG_SILENT 0x4
+#define FAILLOCK_FLAG_NO_LOG_INFO 0x8
+#define FAILLOCK_FLAG_UNLOCKED 0x10
+#define FAILLOCK_FLAG_LOCAL_ONLY 0x20
+#define FAILLOCK_FLAG_NO_DELAY 0x40
+
+#define FAILLOCK_CONF_MAX_LINELEN 1023
+#define MAX_TIME_INTERVAL 604800 /* 7 days */
+
+struct options {
+ unsigned int action;
+ unsigned int flags;
+ unsigned short deny;
+ unsigned int fail_interval;
+ unsigned int unlock_time;
+ unsigned int root_unlock_time;
+ char *dir;
+ const char *user;
+ char *admin_group;
+ int failures;
+ uint64_t latest_time;
+ uid_t uid;
+ int is_admin;
+ uint64_t now;
+ int fatal_error;
+
+ unsigned int reset;
+ const char *progname;
+};
+
+int read_config_file(pam_handle_t *pamh, struct options *opts,
+ const char *cfgfile);
+void set_conf_opt(pam_handle_t *pamh, struct options *opts, const char *name,
+ const char *value);
+const char *get_tally_dir(const struct options *opts);
+
+#endif /* _FAILLOCK_CONFIG_H */
diff -up Linux-PAM-1.5.1/modules/pam_faillock/main.c.faillock-load-conf-from-file Linux-PAM-1.5.1/modules/pam_faillock/main.c
--- Linux-PAM-1.5.1/modules/pam_faillock/main.c.faillock-load-conf-from-file 2020-11-25 17:57:02.000000000 +0100
+++ Linux-PAM-1.5.1/modules/pam_faillock/main.c 2022-05-25 15:37:05.801216176 +0200
@@ -51,33 +51,40 @@
#define AUDIT_NO_ID ((unsigned int) -1)
#endif
+#include "pam_inline.h"
#include "faillock.h"
-
-struct options {
- unsigned int reset;
- const char *dir;
- const char *user;
- const char *progname;
-};
+#include "faillock_config.h"
static int
args_parse(int argc, char **argv, struct options *opts)
{
int i;
+ int rv;
+ const char *dir = NULL;
+ const char *conf = NULL;
+
memset(opts, 0, sizeof(*opts));
- opts->dir = FAILLOCK_DEFAULT_TALLYDIR;
opts->progname = argv[0];
for (i = 1; i < argc; ++i) {
-
- if (strcmp(argv[i], "--dir") == 0) {
+ if (strcmp(argv[i], "--conf") == 0) {
+ ++i;
+ if (i >= argc || strlen(argv[i]) == 0) {
+ fprintf(stderr, "%s: No configuration file supplied.\n",
+ argv[0]);
+ return -1;
+ }
+ conf = argv[i];
+ }
+ else if (strcmp(argv[i], "--dir") == 0) {
++i;
if (i >= argc || strlen(argv[i]) == 0) {
- fprintf(stderr, "%s: No directory supplied.\n", argv[0]);
+ fprintf(stderr, "%s: No records directory supplied.\n",
+ argv[0]);
return -1;
}
- opts->dir = argv[i];
+ dir = argv[i];
}
else if (strcmp(argv[i], "--user") == 0) {
++i;
@@ -85,7 +92,7 @@ args_parse(int argc, char **argv, struct
fprintf(stderr, "%s: No user name supplied.\n", argv[0]);
return -1;
}
- opts->user = argv[i];
+ opts->user = argv[i];
}
else if (strcmp(argv[i], "--reset") == 0) {
opts->reset = 1;
@@ -95,6 +102,21 @@ args_parse(int argc, char **argv, struct
return -1;
}
}
+
+ if ((rv = read_config_file(NULL, opts, conf)) != PAM_SUCCESS) {
+ fprintf(stderr, "Configuration file missing or broken");
+ return rv;
+ }
+
+ if (dir != NULL) {
+ free(opts->dir);
+ opts->dir = strdup(dir);
+ if (opts->dir == NULL) {
+ fprintf(stderr, "Error allocating memory: %m");
+ return -1;
+ }
+ }
+
return 0;
}
@@ -112,10 +134,11 @@ do_user(struct options *opts, const char
int rv;
struct tally_data tallies;
struct passwd *pwd;
+ const char *dir = get_tally_dir(opts);
pwd = getpwnam(user);
- fd = open_tally(opts->dir, user, pwd != NULL ? pwd->pw_uid : 0, 0);
+ fd = open_tally(dir, user, pwd != NULL ? pwd->pw_uid : 0, 0);
if (fd == -1) {
if (errno == ENOENT) {
@@ -191,8 +214,9 @@ do_allusers(struct options *opts)
{
struct dirent **userlist;
int rv, i;
+ const char *dir = get_tally_dir(opts);
- rv = scandir(opts->dir, &userlist, NULL, alphasort);
+ rv = scandir(dir, &userlist, NULL, alphasort);
if (rv < 0) {
fprintf(stderr, "%s: Error reading tally directory: %m\n", opts->progname);
return 2;
diff -up Linux-PAM-1.5.1/modules/pam_faillock/Makefile.am.faillock-load-conf-from-file Linux-PAM-1.5.1/modules/pam_faillock/Makefile.am
--- Linux-PAM-1.5.1/modules/pam_faillock/Makefile.am.faillock-load-conf-from-file 2020-11-25 17:57:02.000000000 +0100
+++ Linux-PAM-1.5.1/modules/pam_faillock/Makefile.am 2022-05-25 15:30:33.700518571 +0200
@@ -20,7 +20,7 @@ TESTS = $(dist_check_SCRIPTS)
securelibdir = $(SECUREDIR)
secureconfdir = $(SCONFIGDIR)
-noinst_HEADERS = faillock.h
+noinst_HEADERS = faillock.h faillock_config.h
AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
$(WARN_CFLAGS)
@@ -41,8 +41,8 @@ dist_secureconf_DATA = faillock.conf
securelib_LTLIBRARIES = pam_faillock.la
sbin_PROGRAMS = faillock
-pam_faillock_la_SOURCES = pam_faillock.c faillock.c
-faillock_SOURCES = main.c faillock.c
+pam_faillock_la_SOURCES = pam_faillock.c faillock.c faillock_config.c
+faillock_SOURCES = main.c faillock.c faillock_config.c
if ENABLE_REGENERATE_MAN
dist_noinst_DATA = README
diff -up Linux-PAM-1.5.1/modules/pam_faillock/pam_faillock.c.faillock-load-conf-from-file Linux-PAM-1.5.1/modules/pam_faillock/pam_faillock.c
--- Linux-PAM-1.5.1/modules/pam_faillock/pam_faillock.c.faillock-load-conf-from-file 2020-11-25 17:57:02.000000000 +0100
+++ Linux-PAM-1.5.1/modules/pam_faillock/pam_faillock.c 2022-05-25 15:33:03.885551825 +0200
@@ -38,7 +38,6 @@
#include <stdio.h>
#include <string.h>
#include <unistd.h>
-#include <stdint.h>
#include <stdlib.h>
#include <errno.h>
#include <time.h>
@@ -56,55 +55,12 @@
#include "pam_inline.h"
#include "faillock.h"
+#include "faillock_config.h"
#define FAILLOCK_ACTION_PREAUTH 0
#define FAILLOCK_ACTION_AUTHSUCC 1
#define FAILLOCK_ACTION_AUTHFAIL 2
-#define FAILLOCK_FLAG_DENY_ROOT 0x1
-#define FAILLOCK_FLAG_AUDIT 0x2
-#define FAILLOCK_FLAG_SILENT 0x4
-#define FAILLOCK_FLAG_NO_LOG_INFO 0x8
-#define FAILLOCK_FLAG_UNLOCKED 0x10
-#define FAILLOCK_FLAG_LOCAL_ONLY 0x20
-#define FAILLOCK_FLAG_NO_DELAY 0x40
-
-#define MAX_TIME_INTERVAL 604800 /* 7 days */
-#define FAILLOCK_CONF_MAX_LINELEN 1023
-
-static const char default_faillock_conf[] = FAILLOCK_DEFAULT_CONF;
-
-struct options {
- unsigned int action;
- unsigned int flags;
- unsigned short deny;
- unsigned int fail_interval;
- unsigned int unlock_time;
- unsigned int root_unlock_time;
- char *dir;
- const char *user;
- char *admin_group;
- int failures;
- uint64_t latest_time;
- uid_t uid;
- int is_admin;
- uint64_t now;
- int fatal_error;
-};
-
-static int read_config_file(
- pam_handle_t *pamh,
- struct options *opts,
- const char *cfgfile
-);
-
-static void set_conf_opt(
- pam_handle_t *pamh,
- struct options *opts,
- const char *name,
- const char *value
-);
-
static int
args_parse(pam_handle_t *pamh, int argc, const char **argv,
int flags, struct options *opts)
@@ -112,11 +68,10 @@ args_parse(pam_handle_t *pamh, int argc,
int i;
int config_arg_index = -1;
int rv;
- const char *conf = default_faillock_conf;
+ const char *conf = NULL;
memset(opts, 0, sizeof(*opts));
- opts->dir = strdup(FAILLOCK_DEFAULT_TALLYDIR);
opts->deny = 3;
opts->fail_interval = 900;
opts->unlock_time = 600;
@@ -174,185 +129,11 @@ args_parse(pam_handle_t *pamh, int argc,
if (flags & PAM_SILENT)
opts->flags |= FAILLOCK_FLAG_SILENT;
- if (opts->dir == NULL) {
- pam_syslog(pamh, LOG_CRIT, "Error allocating memory: %m");
- opts->fatal_error = 1;
- }
-
if (opts->fatal_error)
return PAM_BUF_ERR;
return PAM_SUCCESS;
}
-/* parse a single configuration file */
-static int
-read_config_file(pam_handle_t *pamh, struct options *opts, const char *cfgfile)
-{
- FILE *f;
- char linebuf[FAILLOCK_CONF_MAX_LINELEN+1];
-
- f = fopen(cfgfile, "r");
- if (f == NULL) {
- /* ignore non-existent default config file */
- if (errno == ENOENT && cfgfile == default_faillock_conf)
- return PAM_SUCCESS;
- return PAM_SERVICE_ERR;
- }
-
- while (fgets(linebuf, sizeof(linebuf), f) != NULL) {
- size_t len;
- char *ptr;
- char *name;
- int eq;
-
- len = strlen(linebuf);
- /* len cannot be 0 unless there is a bug in fgets */
- if (len && linebuf[len - 1] != '\n' && !feof(f)) {
- (void) fclose(f);
- return PAM_SERVICE_ERR;
- }
-
- if ((ptr=strchr(linebuf, '#')) != NULL) {
- *ptr = '\0';
- } else {
- ptr = linebuf + len;
- }
-
- /* drop terminating whitespace including the \n */
- while (ptr > linebuf) {
- if (!isspace(*(ptr-1))) {
- *ptr = '\0';
- break;
- }
- --ptr;
- }
-
- /* skip initial whitespace */
- for (ptr = linebuf; isspace(*ptr); ptr++);
- if (*ptr == '\0')
- continue;
-
- /* grab the key name */
- eq = 0;
- name = ptr;
- while (*ptr != '\0') {
- if (isspace(*ptr) || *ptr == '=') {
- eq = *ptr == '=';
- *ptr = '\0';
- ++ptr;
- break;
- }
- ++ptr;
- }
-
- /* grab the key value */
- while (*ptr != '\0') {
- if (*ptr != '=' || eq) {
- if (!isspace(*ptr)) {
- break;
- }
- } else {
- eq = 1;
- }
- ++ptr;
- }
-
- /* set the key:value pair on opts */
- set_conf_opt(pamh, opts, name, ptr);
- }
-
- (void)fclose(f);
- return PAM_SUCCESS;
-}
-
-static void
-set_conf_opt(pam_handle_t *pamh, struct options *opts, const char *name, const char *value)
-{
- if (strcmp(name, "dir") == 0) {
- if (value[0] != '/') {
- pam_syslog(pamh, LOG_ERR,
- "Tally directory is not absolute path (%s); keeping default", value);
- } else {
- free(opts->dir);
- opts->dir = strdup(value);
- }
- }
- else if (strcmp(name, "deny") == 0) {
- if (sscanf(value, "%hu", &opts->deny) != 1) {
- pam_syslog(pamh, LOG_ERR,
- "Bad number supplied for deny argument");
- }
- }
- else if (strcmp(name, "fail_interval") == 0) {
- unsigned int temp;
- if (sscanf(value, "%u", &temp) != 1 ||
- temp > MAX_TIME_INTERVAL) {
- pam_syslog(pamh, LOG_ERR,
- "Bad number supplied for fail_interval argument");
- } else {
- opts->fail_interval = temp;
- }
- }
- else if (strcmp(name, "unlock_time") == 0) {
- unsigned int temp;
-
- if (strcmp(value, "never") == 0) {
- opts->unlock_time = 0;
- }
- else if (sscanf(value, "%u", &temp) != 1 ||
- temp > MAX_TIME_INTERVAL) {
- pam_syslog(pamh, LOG_ERR,
- "Bad number supplied for unlock_time argument");
- }
- else {
- opts->unlock_time = temp;
- }
- }
- else if (strcmp(name, "root_unlock_time") == 0) {
- unsigned int temp;
-
- if (strcmp(value, "never") == 0) {
- opts->root_unlock_time = 0;
- }
- else if (sscanf(value, "%u", &temp) != 1 ||
- temp > MAX_TIME_INTERVAL) {
- pam_syslog(pamh, LOG_ERR,
- "Bad number supplied for root_unlock_time argument");
- } else {
- opts->root_unlock_time = temp;
- }
- }
- else if (strcmp(name, "admin_group") == 0) {
- free(opts->admin_group);
- opts->admin_group = strdup(value);
- if (opts->admin_group == NULL) {
- opts->fatal_error = 1;
- pam_syslog(pamh, LOG_CRIT, "Error allocating memory: %m");
- }
- }
- else if (strcmp(name, "even_deny_root") == 0) {
- opts->flags |= FAILLOCK_FLAG_DENY_ROOT;
- }
- else if (strcmp(name, "audit") == 0) {
- opts->flags |= FAILLOCK_FLAG_AUDIT;
- }
- else if (strcmp(name, "silent") == 0) {
- opts->flags |= FAILLOCK_FLAG_SILENT;
- }
- else if (strcmp(name, "no_log_info") == 0) {
- opts->flags |= FAILLOCK_FLAG_NO_LOG_INFO;
- }
- else if (strcmp(name, "local_users_only") == 0) {
- opts->flags |= FAILLOCK_FLAG_LOCAL_ONLY;
- }
- else if (strcmp(name, "nodelay") == 0) {
- opts->flags |= FAILLOCK_FLAG_NO_DELAY;
- }
- else {
- pam_syslog(pamh, LOG_ERR, "Unknown option: %s", name);
- }
-}
-
static int
check_local_user (pam_handle_t *pamh, const char *user)
{
@@ -406,10 +187,11 @@ check_tally(pam_handle_t *pamh, struct o
unsigned int i;
uint64_t latest_time;
int failures;
+ const char *dir = get_tally_dir(opts);
opts->now = time(NULL);
- tfd = open_tally(opts->dir, opts->user, opts->uid, 0);
+ tfd = open_tally(dir, opts->user, opts->uid, 0);
*fd = tfd;
@@ -483,9 +265,10 @@ static void
reset_tally(pam_handle_t *pamh, struct options *opts, int *fd)
{
int rv;
+ const char *dir = get_tally_dir(opts);
if (*fd == -1) {
- *fd = open_tally(opts->dir, opts->user, opts->uid, 1);
+ *fd = open_tally(dir, opts->user, opts->uid, 1);
}
else {
while ((rv=ftruncate(*fd, 0)) == -1 && errno == EINTR);
@@ -504,9 +287,10 @@ write_tally(pam_handle_t *pamh, struct o
unsigned int oldest;
uint64_t oldtime;
const void *source = NULL;
+ const char *dir = get_tally_dir(opts);
if (*fd == -1) {
- *fd = open_tally(opts->dir, opts->user, opts->uid, 1);
+ *fd = open_tally(dir, opts->user, opts->uid, 1);
}
if (*fd == -1) {
if (errno == EACCES) {
diff --git a/modules/pam_faillock/faillock.h b/modules/pam_faillock/faillock.h
index b22a9dfb..0ea0ffba 100644
--- a/modules/pam_faillock/faillock.h
+++ b/modules/pam_faillock/faillock.h
diff -up Linux-PAM-1.5.1/modules/pam_faillock/faillock.h.faillock-load-conf-from-file Linux-PAM-1.5.1/modules/pam_faillock/faillock.h
--- Linux-PAM-1.5.1/modules/pam_faillock/faillock.h.faillock-load-conf-from-file 2020-11-25 17:57:02.000000000 +0100
+++ Linux-PAM-1.5.1/modules/pam_faillock/faillock.h 2022-05-25 15:33:03.885551825 +0200
@@ -67,7 +67,6 @@ struct tally_data {
};
#define FAILLOCK_DEFAULT_TALLYDIR "/var/run/faillock"
-#define FAILLOCK_DEFAULT_CONF "/etc/security/faillock.conf"
int open_tally(const char *dir, const char *user, uid_t uid, int create);
int read_tally(int fd, struct tally_data *tallies);

@ -1,55 +0,0 @@
diff -up Linux-PAM-1.5.1/configure.ac.libpam-close-range Linux-PAM-1.5.1/configure.ac
--- Linux-PAM-1.5.1/configure.ac.libpam-close-range 2023-11-10 10:35:00.142833269 +0100
+++ Linux-PAM-1.5.1/configure.ac 2023-11-10 10:36:29.158987392 +0100
@@ -552,6 +552,7 @@ AC_CHECK_FUNCS(inet_ntop inet_pton innet
AC_CHECK_FUNCS(quotactl)
AC_CHECK_FUNCS(unshare)
AC_CHECK_FUNCS([ruserok_af ruserok], [break])
+AC_CHECK_FUNCS(close_range)
BACKUP_LIBS=$LIBS
LIBS="$LIBS -lutil"
AC_CHECK_FUNCS([logwtmp])
diff -up Linux-PAM-1.5.1/libpam/pam_modutil_sanitize.c.libpam-close-range Linux-PAM-1.5.1/libpam/pam_modutil_sanitize.c
--- Linux-PAM-1.5.1/libpam/pam_modutil_sanitize.c.libpam-close-range 2020-11-25 17:57:02.000000000 +0100
+++ Linux-PAM-1.5.1/libpam/pam_modutil_sanitize.c 2023-11-10 10:35:00.142833269 +0100
@@ -11,6 +11,10 @@
#include <syslog.h>
#include <sys/resource.h>
+#ifndef CLOSE_RANGE_UNSHARE
+#define CLOSE_RANGE_UNSHARE (1U << 1)
+#endif /* CLOSE_RANGE_UNSHARE */
+
/*
* Creates a pipe, closes its write end, redirects fd to its read end.
* Returns fd on success, -1 otherwise.
@@ -84,9 +88,8 @@ redirect_out(pam_handle_t *pamh, enum pa
return fd;
}
-/* Closes all descriptors after stderr. */
static void
-close_fds(void)
+close_fds_iteratively(void)
{
/*
* An arbitrary upper limit for the maximum file descriptor number
@@ -111,6 +114,18 @@ close_fds(void)
close(fd);
}
+/* Closes all descriptors after stderr. */
+static void
+close_fds(void)
+{
+#ifdef HAVE_CLOSE_RANGE
+ if (close_range(STDERR_FILENO+1, -1U, CLOSE_RANGE_UNSHARE) == 0)
+ return;
+#endif /* HAVE_CLOSE_RANGE */
+
+ close_fds_iteratively();
+}
+
int
pam_modutil_sanitize_helper_fds(pam_handle_t *pamh,
enum pam_modutil_redirect_fd stdin_mode,

@ -1,654 +0,0 @@
diff -up Linux-PAM-1.5.1/libpam/pam_handlers.c.libpam-support-long-lines Linux-PAM-1.5.1/libpam/pam_handlers.c
--- Linux-PAM-1.5.1/libpam/pam_handlers.c.libpam-support-long-lines 2020-11-25 17:57:02.000000000 +0100
+++ Linux-PAM-1.5.1/libpam/pam_handlers.c 2024-06-18 10:07:12.434785557 +0200
@@ -17,21 +17,30 @@
#include <fcntl.h>
#include <unistd.h>
-#define BUF_SIZE 1024
#define MODULE_CHUNK 4
#define UNKNOWN_MODULE "<*unknown module*>"
#ifndef _PAM_ISA
#define _PAM_ISA "."
#endif
-static int _pam_assemble_line(FILE *f, char *buf, int buf_len);
+struct line_buffer {
+ char *assembled;
+ char *chunk;
+ size_t chunk_size;
+ size_t len;
+ size_t size;
+};
+
+static void _pam_buffer_init(struct line_buffer *buffer);
+
+static int _pam_assemble_line(FILE *f, struct line_buffer *buf);
static void _pam_free_handlers_aux(struct handler **hp);
static int _pam_add_handler(pam_handle_t *pamh
, int must_fail, int other, int stack_level, int type
, int *actions, const char *mod_path
- , int argc, char **argv, int argvlen);
+ , int argc, char **argv, size_t argvlen);
/* Values for module type */
@@ -59,12 +68,15 @@ static int _pam_parse_conf_file(pam_hand
#endif /* PAM_READ_BOTH_CONFS */
)
{
- char buf[BUF_SIZE];
+ struct line_buffer buffer;
int x; /* read a line from the FILE *f ? */
+
+ _pam_buffer_init(&buffer);
/*
* read a line from the configuration (FILE *) f
*/
- while ((x = _pam_assemble_line(f, buf, BUF_SIZE)) > 0) {
+ while ((x = _pam_assemble_line(f, &buffer)) > 0) {
+ char *buf = buffer.assembled;
char *tok, *nexttok=NULL;
const char *this_service;
const char *mod_path;
@@ -74,7 +86,7 @@ static int _pam_parse_conf_file(pam_hand
int handler_type = PAM_HT_MODULE; /* regular handler from a module */
int argc;
char **argv;
- int argvlen;
+ size_t argvlen;
D(("_pam_init_handler: LINE: %s", buf));
if (known_service != NULL) {
@@ -233,10 +245,11 @@ static int _pam_parse_conf_file(pam_hand
if (nexttok != NULL) {
D(("list: %s",nexttok));
argvlen = _pam_mkargv(nexttok, &argv, &argc);
- D(("argvlen = %d",argvlen));
+ D(("argvlen = %zu",argvlen));
} else { /* there are no arguments so fix by hand */
D(("_pam_init_handlers: empty argument list"));
- argvlen = argc = 0;
+ argvlen = 0;
+ argc = 0;
argv = NULL;
}
@@ -557,88 +570,243 @@ int _pam_init_handlers(pam_handle_t *pam
return PAM_SUCCESS;
}
+static int _pam_buffer_add(struct line_buffer *buffer, char *start, char *end)
+{
+ size_t len = end - start;
+
+ D(("assembled: [%zu/%zu] '%s', adding [%zu] '%s'",
+ buffer->len, buffer->size,
+ buffer->assembled == NULL ? "" : buffer->assembled, len, start));
+
+ if (start == end)
+ return 0;
+
+ if (buffer->assembled == NULL && buffer->chunk == start) {
+ /* no extra allocation needed, just move chunk to assembled */
+ buffer->assembled = buffer->chunk;
+ buffer->len = len;
+ buffer->size = buffer->chunk_size;
+
+ buffer->chunk = NULL;
+ buffer->chunk_size = 0;
+
+ D(("exiting with quick exchange"));
+ return 0;
+ }
+
+ if (buffer->len + len + 1 > buffer->size) {
+ size_t size;
+ char *p;
+
+ size = buffer->len + len + 1;
+ if ((p = realloc(buffer->assembled, size)) == NULL)
+ return -1;
+
+ buffer->assembled = p;
+ buffer->size = size;
+ }
+
+ memcpy(buffer->assembled + buffer->len, start, len);
+ buffer->len += len;
+ buffer->assembled[buffer->len] = '\0';
+
+ D(("exiting"));
+ return 0;
+}
+
+static inline int _pam_buffer_add_eol(struct line_buffer *buffer,
+ char *start, char *end)
+{
+ if (buffer->assembled != NULL || (*start != '\0' && *start != '\n'))
+ return _pam_buffer_add(buffer, start, end);
+ return 0;
+}
+
+static void _pam_buffer_clear(struct line_buffer *buffer)
+{
+ _pam_drop(buffer->assembled);
+ _pam_drop(buffer->chunk);
+ buffer->chunk_size = 0;
+ buffer->len = 0;
+ buffer->size = 0;
+}
+
+static void _pam_buffer_init(struct line_buffer *buffer)
+{
+ buffer->assembled = NULL;
+ buffer->chunk = NULL;
+ _pam_buffer_clear(buffer);
+}
+
+static void _pam_buffer_purge(struct line_buffer *buffer)
+{
+ _pam_drop(buffer->chunk);
+ buffer->chunk_size = 0;
+}
+
+static void _pam_buffer_shift(struct line_buffer *buffer)
+{
+ if (buffer->assembled == NULL)
+ return;
+
+ _pam_buffer_purge(buffer);
+ buffer->chunk = buffer->assembled;
+ buffer->chunk_size = buffer->size;
+
+ buffer->assembled = NULL;
+ buffer->size = 0;
+ buffer->len = 0;
+}
+
+static inline int _pam_buffer_valid(struct line_buffer *buffer)
+{
+ return buffer->assembled != NULL && *buffer->assembled != '\0';
+}
+
+/*
+ * Trim string to relevant parts of a configuration line.
+ *
+ * Preceding whitespaces are skipped and comment (#) marks the end of
+ * configuration line.
+ *
+ * Returns start of configuration line.
+ */
+static inline char *_pam_str_trim(char *str)
+{
+ /* skip leading spaces */
+ str += strspn(str, " \t");
+ /*
+ * we are only interested in characters before the first '#'
+ * character
+ */
+ str[strcspn(str, "#")] = '\0';
+
+ return str;
+}
+
+/*
+ * Remove escaped newline from end of string.
+ *
+ * Configuration lines may span across multiple lines in a file
+ * by ending a line with a backslash (\).
+ *
+ * If an escaped newline is encountered, the backslash will be
+ * replaced with a blank ' ' and the newline itself removed.
+ * Then the variable "end" will point to the new end of line.
+ *
+ * Returns 0 if escaped newline was found and replaced, 1 otherwise.
+ */
+static inline int _pam_str_unescnl(char *start, char **end)
+{
+ int ret = 1;
+ char *p = *end;
+
+ /*
+ * Check for backslash by scanning back from the end of
+ * the entered line, the '\n' should be included since
+ * normally a line is terminated with this character.
+ */
+ while (p > start && ((*--p == ' ') || (*p == '\t') || (*p == '\n')))
+ ;
+ if (*p == '\\') {
+ *p++ = ' '; /* replace backslash with ' ' */
+ *p = '\0'; /* truncate the line here */
+ *end = p;
+ ret = 0;
+ }
+
+ return ret;
+}
+
+/*
+ * Prepare line from file for configuration line parsing.
+ *
+ * A configuration line may span across multiple lines in a file.
+ * Remove comments and skip preceding whitespaces.
+ *
+ * Returns 0 if line spans across multiple lines, 1 if
+ * end of line is encountered.
+ */
+static inline int _pam_str_prepare(char *line, ssize_t len,
+ char **start, char **end)
+{
+ int ret;
+
+ *start = line;
+ *end = line + len;
+
+ ret = _pam_str_unescnl(*start, end) || strchr(*start, '#') != NULL;
+
+ *start = _pam_str_trim(*start);
+
+ return ret;
+}
+
/*
* This is where we read a line of the PAM config file. The line may be
* preceded by lines of comments and also extended with "\\\n"
+ *
+ * Returns 0 on EOF, 1 on successful line parsing, or -1 on error.
*/
-static int _pam_assemble_line(FILE *f, char *buffer, int buf_len)
+static int _pam_assemble_line(FILE *f, struct line_buffer *buffer)
{
- char *p = buffer;
- char *endp = buffer + buf_len;
- char *s, *os;
- int used = 0;
+ int ret = 0;
/* loop broken with a 'break' when a non-'\\n' ended line is read */
D(("called."));
+
+ _pam_buffer_shift(buffer);
+
for (;;) {
- if (p >= endp) {
- /* Overflow */
- D(("_pam_assemble_line: overflow"));
- return -1;
- }
- if (fgets(p, endp - p, f) == NULL) {
- if (used) {
+ char *start, *end;
+ ssize_t n;
+ int eol;
+
+ if ((n = getline(&buffer->chunk, &buffer->chunk_size, f)) == -1) {
+ if (ret) {
/* Incomplete read */
- return -1;
+ ret = -1;
} else {
/* EOF */
- return 0;
+ ret = 0;
}
+ break;
}
- /* skip leading spaces --- line may be blank */
-
- s = p + strspn(p, " \n\t");
- if (*s && (*s != '#')) {
- os = s;
-
- /*
- * we are only interested in characters before the first '#'
- * character
- */
-
- while (*s && *s != '#')
- ++s;
- if (*s == '#') {
- *s = '\0';
- used += strlen(os);
- break; /* the line has been read */
- }
-
- s = os;
-
- /*
- * Check for backslash by scanning back from the end of
- * the entered line, the '\n' has been included since
- * normally a line is terminated with this
- * character. fgets() should only return one though!
- */
-
- s += strlen(s);
- while (s > os && ((*--s == ' ') || (*s == '\t')
- || (*s == '\n')));
-
- /* check if it ends with a backslash */
- if (*s == '\\') {
- *s++ = ' '; /* replace backslash with ' ' */
- *s = '\0'; /* truncate the line here */
- used += strlen(os);
- p = s; /* there is more ... */
- } else {
- /* End of the line! */
- used += strlen(os);
- break; /* this is the complete line */
- }
+ eol = _pam_str_prepare(buffer->chunk, n, &start, &end);
+ if (eol) {
+ if (_pam_buffer_add_eol(buffer, start, end)) {
+ ret = -1;
+ break;
+ }
+ if (_pam_buffer_valid(buffer)) {
+ /* Successfully parsed a line */
+ ret = 1;
+ break;
+ }
+ /* Start parsing next line */
+ _pam_buffer_shift(buffer);
+ ret = 0;
} else {
- /* Nothing in this line */
- /* Don't move p */
+ /* Configuration line spans across multiple lines in file */
+ if (_pam_buffer_add(buffer, start, end)) {
+ ret = -1;
+ break;
+ }
+ /* Keep parsing line */
+ ret = 1;
}
}
- return used;
+ if (ret == 1)
+ _pam_buffer_purge(buffer);
+ else
+ _pam_buffer_clear(buffer);
+
+ return ret;
}
static char *
@@ -777,7 +945,7 @@ _pam_load_module(pam_handle_t *pamh, con
int _pam_add_handler(pam_handle_t *pamh
, int handler_type, int other, int stack_level, int type
, int *actions, const char *mod_path
- , int argc, char **argv, int argvlen)
+ , int argc, char **argv, size_t argvlen)
{
struct loaded_module *mod = NULL;
struct handler **handler_p;
diff -up Linux-PAM-1.5.1/libpam/pam_misc.c.libpam-support-long-lines Linux-PAM-1.5.1/libpam/pam_misc.c
--- Linux-PAM-1.5.1/libpam/pam_misc.c.libpam-support-long-lines 2024-06-18 09:52:38.726482849 +0200
+++ Linux-PAM-1.5.1/libpam/pam_misc.c 2024-06-18 10:02:13.132973447 +0200
@@ -39,6 +39,8 @@
#include <stdarg.h>
#include <stdlib.h>
+#include <stdint.h>
+#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <syslog.h>
@@ -163,60 +164,55 @@ char *_pam_memdup(const char *x, int len
/* Generate argv, argc from s */
/* caller must free(argv) */
-int _pam_mkargv(const char *s, char ***argv, int *argc)
+size_t _pam_mkargv(const char *s, char ***argv, int *argc)
{
- int l;
- int argvlen = 0;
- char *sbuf, *sbuf_start;
+ size_t l;
+ size_t argvlen = 0;
char **our_argv = NULL;
- char **argvbuf;
- char *argvbufp;
-#ifdef PAM_DEBUG
- int count=0;
-#endif
- D(("_pam_mkargv called: %s",s));
+ D(("called: %s",s));
*argc = 0;
l = strlen(s);
- if (l) {
- if ((sbuf = sbuf_start = _pam_strdup(s)) == NULL) {
- pam_syslog(NULL, LOG_CRIT,
- "pam_mkargv: null returned by _pam_strdup");
- D(("arg NULL"));
+ if (l && l < SIZE_MAX / (sizeof(char) + sizeof(char *))) {
+ char **argvbuf;
+ /* Overkill on the malloc, but not large */
+ argvlen = (l + 1) * (sizeof(char) + sizeof(char *));
+ if ((our_argv = argvbuf = malloc(argvlen)) == NULL) {
+ pam_syslog(NULL, LOG_CRIT, "pam_mkargv: null returned by malloc");
+ argvlen = 0;
} else {
- /* Overkill on the malloc, but not large */
- argvlen = (l + 1) * ((sizeof(char)) + sizeof(char *));
- if ((our_argv = argvbuf = malloc(argvlen)) == NULL) {
- pam_syslog(NULL, LOG_CRIT,
- "pam_mkargv: null returned by malloc");
- } else {
- char *tmp=NULL;
-
- argvbufp = (char *) argvbuf + (l * sizeof(char *));
- D(("[%s]",sbuf));
- while ((sbuf = _pam_StrTok(sbuf, " \n\t", &tmp))) {
- D(("arg #%d",++count));
- D(("->[%s]",sbuf));
- strcpy(argvbufp, sbuf);
- D(("copied token"));
- *argvbuf = argvbufp;
- argvbufp += strlen(argvbufp) + 1;
- D(("stepped in argvbufp"));
- (*argc)++;
- argvbuf++;
- sbuf = NULL;
- D(("loop again?"));
+ char *argvbufp;
+ char *tmp=NULL;
+ char *tok;
+#ifdef PAM_DEBUG
+ unsigned count=0;
+#endif
+ argvbufp = (char *) argvbuf + (l * sizeof(char *));
+ strcpy(argvbufp, s);
+ D(("[%s]",argvbufp));
+ while ((tok = _pam_StrTok(argvbufp, " \n\t", &tmp))) {
+ D(("arg #%u",++count));
+ D(("->[%s]",tok));
+ *argvbuf++ = tok;
+ if (*argc == INT_MAX) {
+ pam_syslog(NULL, LOG_CRIT,
+ "pam_mkargv: too many arguments");
+ argvlen = 0;
+ _pam_drop(our_argv);
+ break;
}
+ (*argc)++;
+ argvbufp = NULL;
+ D(("loop again?"));
}
- _pam_drop(sbuf_start);
}
}
*argv = our_argv;
- D(("_pam_mkargv returned"));
+ D(("exiting"));
return(argvlen);
}
diff -up Linux-PAM-1.5.1/libpam/pam_private.h.libpam-support-long-lines Linux-PAM-1.5.1/libpam/pam_private.h
--- Linux-PAM-1.5.1/libpam/pam_private.h.libpam-support-long-lines 2020-11-25 17:57:02.000000000 +0100
+++ Linux-PAM-1.5.1/libpam/pam_private.h 2024-06-18 09:52:38.726482849 +0200
@@ -16,6 +16,7 @@
#include "config.h"
+#include <stddef.h>
#include <syslog.h>
#include <security/pam_appl.h>
@@ -272,7 +273,7 @@ char *_pam_strdup(const char *s);
char *_pam_memdup(const char *s, int len);
-int _pam_mkargv(const char *s, char ***argv, int *argc);
+size_t _pam_mkargv(const char *s, char ***argv, int *argc);
void _pam_sanitize(pam_handle_t *pamh);
diff -up Linux-PAM-1.5.1/modules/pam_exec/pam_exec.c.libpam-support-long-lines Linux-PAM-1.5.1/modules/pam_exec/pam_exec.c
--- Linux-PAM-1.5.1/modules/pam_exec/pam_exec.c.libpam-support-long-lines 2020-11-25 17:57:02.000000000 +0100
+++ Linux-PAM-1.5.1/modules/pam_exec/pam_exec.c 2024-06-18 09:52:38.725482846 +0200
@@ -407,7 +407,7 @@ call_exec (const char *pam_type, pam_han
_exit (err);
}
- arggv = calloc (argc + 4, sizeof (char *));
+ arggv = calloc ((size_t) argc + 1, sizeof (char *));
if (arggv == NULL)
_exit (ENOMEM);
diff -up Linux-PAM-1.5.1/modules/pam_filter/pam_filter.c.libpam-support-long-lines Linux-PAM-1.5.1/modules/pam_filter/pam_filter.c
--- Linux-PAM-1.5.1/modules/pam_filter/pam_filter.c.libpam-support-long-lines 2024-06-18 09:52:38.725482846 +0200
+++ Linux-PAM-1.5.1/modules/pam_filter/pam_filter.c 2024-06-18 09:54:17.102732759 +0200
@@ -96,7 +96,8 @@ static int process_args(pam_handle_t *pa
char **levp;
const char *user = NULL;
const void *tmp;
- int i,size, retval;
+ int i, retval;
+ size_t size;
*filtername = *++argv;
if (ctrl & FILTER_DEBUG) {
diff -up Linux-PAM-1.5.1/modules/pam_motd/pam_motd.c.libpam-support-long-lines Linux-PAM-1.5.1/modules/pam_motd/pam_motd.c
--- Linux-PAM-1.5.1/modules/pam_motd/pam_motd.c.libpam-support-long-lines 2020-11-25 17:57:02.000000000 +0100
+++ Linux-PAM-1.5.1/modules/pam_motd/pam_motd.c 2024-06-18 09:55:44.530954883 +0200
@@ -71,14 +71,14 @@ static void try_to_display_fd(pam_handle
* 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, unsigned int *out_num_strs)
+ char ***out_arg_split, size_t *out_num_strs)
{
char *arg_extracted = NULL;
const char *arg_ptr = arg;
char **arg_split = NULL;
char delim_str[2];
- unsigned int i = 0;
- unsigned int num_strs = 0;
+ size_t i = 0;
+ size_t num_strs = 0;
int retval = 0;
delim_str[0] = delim;
@@ -172,13 +172,13 @@ static int filter_dirents(const struct d
}
static void try_to_display_directories_with_overrides(pam_handle_t *pamh,
- char **motd_dir_path_split, unsigned int num_motd_dirs, int report_missing)
+ char **motd_dir_path_split, size_t num_motd_dirs, int report_missing)
{
struct dirent ***dirscans = NULL;
unsigned int *dirscans_sizes = NULL;
unsigned int dirscans_size_total = 0;
char **dirnames_all = NULL;
- unsigned int i;
+ size_t i;
int i_dirnames = 0;
if (pamh == NULL || motd_dir_path_split == NULL) {
@@ -304,9 +304,8 @@ static int drop_privileges(pam_handle_t
}
static int try_to_display(pam_handle_t *pamh, char **motd_path_split,
- unsigned int num_motd_paths,
- char **motd_dir_path_split,
- unsigned int num_motd_dir_paths, int report_missing)
+ size_t num_motd_paths, char **motd_dir_path_split,
+ size_t num_motd_dir_paths, int report_missing)
{
PAM_MODUTIL_DEF_PRIVS(privs);
@@ -316,7 +315,7 @@ static int try_to_display(pam_handle_t *
}
if (motd_path_split != NULL) {
- unsigned int i;
+ size_t i;
for (i = 0; i < num_motd_paths; i++) {
int fd = open(motd_path_split[i], O_RDONLY, 0);
@@ -354,11 +353,11 @@ int pam_sm_open_session(pam_handle_t *pa
int retval = PAM_IGNORE;
const char *motd_path = NULL;
char *motd_path_copy = NULL;
- unsigned int num_motd_paths = 0;
+ size_t num_motd_paths = 0;
char **motd_path_split = NULL;
const char *motd_dir_path = NULL;
char *motd_dir_path_copy = NULL;
- unsigned int num_motd_dir_paths = 0;
+ size_t num_motd_dir_paths = 0;
char **motd_dir_path_split = NULL;
int report_missing;
diff -up Linux-PAM-1.5.1/modules/pam_permit/tst-pam_permit-retval.c.libpam-support-long-lines Linux-PAM-1.5.1/modules/pam_permit/tst-pam_permit-retval.c
--- Linux-PAM-1.5.1/modules/pam_permit/tst-pam_permit-retval.c.libpam-support-long-lines 2020-11-25 17:57:02.000000000 +0100
+++ Linux-PAM-1.5.1/modules/pam_permit/tst-pam_permit-retval.c 2024-06-18 09:52:38.726482849 +0200
@@ -52,6 +52,35 @@ main(void)
ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
pamh = NULL;
+ /* Perform a test dedicated to configuration file parsing. */
+ ASSERT_NE(NULL, fp = fopen(service_file, "w"));
+ ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n"
+ "# ignore escaped newlines in comments \\\n"
+ "auth required \\\n"
+ " %s/.libs/%s.so\n"
+ "# allow unneeded whitespaces\n"
+ " account required %s/.libs/%s.so%c\\\n"
+ "line after NUL byte continues up to here\n"
+ "password required %s/.libs/%s.so # eol comment\n"
+ "session required %s/.libs/%s.so",
+ cwd, MODULE_NAME,
+ cwd, MODULE_NAME, '\0',
+ cwd, MODULE_NAME,
+ cwd, MODULE_NAME));
+ ASSERT_EQ(0, fclose(fp));
+
+ ASSERT_EQ(PAM_SUCCESS,
+ pam_start_confdir(service_file, user_name, &conv, ".", &pamh));
+ ASSERT_NE(NULL, pamh);
+ ASSERT_EQ(PAM_SUCCESS, pam_authenticate(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_setcred(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_acct_mgmt(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_chauthtok(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_open_session(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_close_session(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
+ pamh = NULL;
+
ASSERT_EQ(0, unlink(service_file));
return 0;

@ -1,58 +0,0 @@
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

@ -1,37 +0,0 @@
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

@ -1,53 +0,0 @@
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

@ -1,150 +0,0 @@
From a35e092e24ee7632346a0e1b4a203c04d4cd2c62 Mon Sep 17 00:00:00 2001
From: Iker Pedrosa <ipedrosa@redhat.com>
Date: Mon, 24 Jan 2022 15:43:23 +0100
Subject: [PATCH] pam_keyinit: thread-safe implementation
* modules/pam_keyinit/pam_keyinit.c: Bypass setre*id() C library calls
with kernel calls and change global variables definitions to be
thread-safe.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1997969
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
Co-Authored-By: Andreas Schneider <asn@samba.org>
---
modules/pam_keyinit/pam_keyinit.c | 60 ++++++++++++++++++++++---------
1 file changed, 44 insertions(+), 16 deletions(-)
diff --git a/modules/pam_keyinit/pam_keyinit.c b/modules/pam_keyinit/pam_keyinit.c
index 92e4953b..df9804b9 100644
--- a/modules/pam_keyinit/pam_keyinit.c
+++ b/modules/pam_keyinit/pam_keyinit.c
@@ -21,6 +21,7 @@
#include <security/pam_modutil.h>
#include <security/pam_ext.h>
#include <sys/syscall.h>
+#include <stdatomic.h>
#define KEY_SPEC_SESSION_KEYRING -3 /* ID for session keyring */
#define KEY_SPEC_USER_KEYRING -4 /* ID for UID-specific keyring */
@@ -31,12 +32,12 @@
#define KEYCTL_REVOKE 3 /* revoke a key */
#define KEYCTL_LINK 8 /* link a key into a keyring */
-static int my_session_keyring = 0;
-static int session_counter = 0;
-static int do_revoke = 0;
-static uid_t revoke_as_uid;
-static gid_t revoke_as_gid;
-static int xdebug = 0;
+static _Thread_local int my_session_keyring = 0;
+static _Atomic int session_counter = 0;
+static _Thread_local int do_revoke = 0;
+static _Thread_local uid_t revoke_as_uid;
+static _Thread_local gid_t revoke_as_gid;
+static _Thread_local int xdebug = 0;
static void debug(pam_handle_t *pamh, const char *fmt, ...)
__attribute__((format(printf, 2, 3)));
@@ -64,6 +65,33 @@ static void error(pam_handle_t *pamh, const char *fmt, ...)
va_end(va);
}
+static int pam_setreuid(uid_t ruid, uid_t euid)
+{
+#if defined(SYS_setreuid32)
+ return syscall(SYS_setreuid32, ruid, euid);
+#else
+ return syscall(SYS_setreuid, ruid, euid);
+#endif
+}
+
+static int pam_setregid(gid_t rgid, gid_t egid)
+{
+#if defined(SYS_setregid32)
+ return syscall(SYS_setregid32, rgid, egid);
+#else
+ return syscall(SYS_setregid, rgid, egid);
+#endif
+}
+
+static int pam_setresuid(uid_t ruid, uid_t euid, uid_t suid)
+{
+#if defined(SYS_setresuid32)
+ return syscall(SYS_setresuid32, ruid, euid, suid);
+#else
+ return syscall(SYS_setresuid, ruid, euid, suid);
+#endif
+}
+
/*
* initialise the session keyring for this process
*/
@@ -140,14 +168,14 @@ static int kill_keyrings(pam_handle_t *pamh, int error_ret)
/* switch to the real UID and GID so that we have permission to
* revoke the key */
- if (revoke_as_gid != old_gid && setregid(-1, revoke_as_gid) < 0) {
+ if (revoke_as_gid != old_gid && pam_setregid(-1, revoke_as_gid) < 0) {
error(pamh, "Unable to change GID to %d temporarily\n", revoke_as_gid);
return error_ret;
}
- if (revoke_as_uid != old_uid && setresuid(-1, revoke_as_uid, old_uid) < 0) {
+ if (revoke_as_uid != old_uid && pam_setresuid(-1, revoke_as_uid, old_uid) < 0) {
error(pamh, "Unable to change UID to %d temporarily\n", revoke_as_uid);
- if (getegid() != old_gid && setregid(-1, old_gid) < 0)
+ if (getegid() != old_gid && pam_setregid(-1, old_gid) < 0)
error(pamh, "Unable to change GID back to %d\n", old_gid);
return error_ret;
}
@@ -157,12 +185,12 @@ static int kill_keyrings(pam_handle_t *pamh, int error_ret)
}
/* return to the original UID and GID (probably root) */
- if (revoke_as_uid != old_uid && setreuid(-1, old_uid) < 0) {
+ if (revoke_as_uid != old_uid && pam_setreuid(-1, old_uid) < 0) {
error(pamh, "Unable to change UID back to %d\n", old_uid);
ret = error_ret;
}
- if (revoke_as_gid != old_gid && setregid(-1, old_gid) < 0) {
+ if (revoke_as_gid != old_gid && pam_setregid(-1, old_gid) < 0) {
error(pamh, "Unable to change GID back to %d\n", old_gid);
ret = error_ret;
}
@@ -215,14 +243,14 @@ static int do_keyinit(pam_handle_t *pamh, int argc, const char **argv, int error
/* switch to the real UID and GID so that the keyring ends up owned by
* the right user */
- if (gid != old_gid && setregid(gid, -1) < 0) {
+ if (gid != old_gid && pam_setregid(gid, -1) < 0) {
error(pamh, "Unable to change GID to %d temporarily\n", gid);
return error_ret;
}
- if (uid != old_uid && setreuid(uid, -1) < 0) {
+ if (uid != old_uid && pam_setreuid(uid, -1) < 0) {
error(pamh, "Unable to change UID to %d temporarily\n", uid);
- if (setregid(old_gid, -1) < 0)
+ if (pam_setregid(old_gid, -1) < 0)
error(pamh, "Unable to change GID back to %d\n", old_gid);
return error_ret;
}
@@ -230,12 +258,12 @@ static int do_keyinit(pam_handle_t *pamh, int argc, const char **argv, int error
ret = init_keyrings(pamh, force, error_ret);
/* return to the original UID and GID (probably root) */
- if (uid != old_uid && setreuid(old_uid, -1) < 0) {
+ if (uid != old_uid && pam_setreuid(old_uid, -1) < 0) {
error(pamh, "Unable to change UID back to %d\n", old_uid);
ret = error_ret;
}
- if (gid != old_gid && setregid(old_gid, -1) < 0) {
+ if (gid != old_gid && pam_setregid(old_gid, -1) < 0) {
error(pamh, "Unable to change GID back to %d\n", old_gid);
ret = error_ret;
}
--
2.35.1

@ -1,41 +0,0 @@
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

@ -1,99 +0,0 @@
From 3234488f2c52a021eec87df1990d256314c21bff Mon Sep 17 00:00:00 2001
From: Josef Moellers <jmoellers@suse.de>
Date: Wed, 14 Apr 2021 16:39:28 +0200
Subject: [PATCH] pam_limits: "Unlimited" is not a valid value for
RLIMIT_NOFILE.
Replace it with a value obtained from /proc/sys/fs/nr_open
* modules/pam_limits/limits.conf.5.xml: Document the replacement.
* modules/pam_limits/pam_limits.c: Replace unlimited RLIMIT_NOFILE
value with a value obtained from /proc/sys/fs/nr_open
---
modules/pam_limits/limits.conf.5.xml | 2 ++
modules/pam_limits/pam_limits.c | 49 ++++++++++++++++++++++++++++
2 files changed, 51 insertions(+)
diff --git a/modules/pam_limits/limits.conf.5.xml b/modules/pam_limits/limits.conf.5.xml
index cd64ac90..c5bd6768 100644
--- a/modules/pam_limits/limits.conf.5.xml
+++ b/modules/pam_limits/limits.conf.5.xml
@@ -283,6 +283,8 @@
<emphasis>unlimited</emphasis> or <emphasis>infinity</emphasis> indicating no limit,
except for <emphasis remap='B'>priority</emphasis>, <emphasis remap='B'>nice</emphasis>,
and <emphasis remap='B'>nonewprivs</emphasis>.
+ If <emphasis remap='B'>nofile</emphasis> is to be set to one of these values,
+ it will be set to the contents of /proc/sys/fs/nr_open instead (see setrlimit(3)).
</para>
<para>
If a hard limit or soft limit of a resource is set to a valid value,
diff --git a/modules/pam_limits/pam_limits.c b/modules/pam_limits/pam_limits.c
index 10049973..7cc45d77 100644
--- a/modules/pam_limits/pam_limits.c
+++ b/modules/pam_limits/pam_limits.c
@@ -487,6 +487,41 @@ static int init_limits(pam_handle_t *pamh, struct pam_limit_s *pl, int ctrl)
return retval;
}
+/*
+ * Read the contents of <pathname> and return it in *valuep
+ * return 1 if conversion succeeds, result is in *valuep
+ * return 0 if conversion fails, *valuep is untouched.
+ */
+static int
+value_from_file(const char *pathname, rlim_t *valuep)
+{
+ char buf[128];
+ FILE *fp;
+ int retval;
+
+ retval = 0;
+
+ if ((fp = fopen(pathname, "r")) != NULL) {
+ if (fgets(buf, sizeof(buf), fp) != NULL) {
+ char *endptr;
+ unsigned long long value;
+
+ errno = 0;
+ value = strtoull(buf, &endptr, 10);
+ if (endptr != buf &&
+ (value != ULLONG_MAX || errno == 0) &&
+ (unsigned long long) (rlim_t) value == value) {
+ *valuep = (rlim_t) value;
+ retval = 1;
+ }
+ }
+
+ fclose(fp);
+ }
+
+ return retval;
+}
+
static void
process_limit (const pam_handle_t *pamh, int source, const char *lim_type,
const char *lim_item, const char *lim_value,
@@ -666,6 +701,20 @@ process_limit (const pam_handle_t *pamh, int source, const char *lim_type,
rlimit_value = 20 - int_value;
break;
#endif
+ case RLIMIT_NOFILE:
+ /*
+ * If nofile is to be set to "unlimited", try to set it to
+ * the value in /proc/sys/fs/nr_open instead.
+ */
+ if (rlimit_value == RLIM_INFINITY) {
+ if (!value_from_file("/proc/sys/fs/nr_open", &rlimit_value))
+ pam_syslog(pamh, LOG_WARNING,
+ "Cannot set \"nofile\" to a sensible value");
+ else if (ctrl & PAM_DEBUG_ARG)
+ pam_syslog(pamh, LOG_DEBUG, "Setting \"nofile\" limit to %llu",
+ (unsigned long long) rlimit_value);
+ }
+ break;
}
if ( (limit_item != LIMIT_LOGIN)
--
2.33.1

@ -1,79 +0,0 @@
From 55f206447a1e4ee26e307e7a9c069236e823b1a5 Mon Sep 17 00:00:00 2001
From: Jeff Squyres <jsquyres@cisco.com>
Date: Fri, 30 Apr 2021 15:16:38 -0700
Subject: [PATCH 1/2] pam_misc: make length of misc_conv() configurable
Add --with-misc-conv-bufsize=<number> option to configure to allow
a longer buffer size for libpam_misc's misc_conv() function (it still
defaults to 512 bytes).
Signed-off-by: Jeff Squyres <jsquyres@cisco.com>
---
configure.ac | 7 +++++++
libpam_misc/misc_conv.c | 2 +-
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/configure.ac b/configure.ac
index 9c92d0de..b283db1b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -648,6 +648,13 @@ case "$enable_unix" in
*) AC_MSG_ERROR([bad value $enable_unix for --enable-unix option]) ;;
esac
+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=512]),
+ [],
+ [with_misc_conv_bufsize=512])
+AC_DEFINE_UNQUOTED(PAM_MISC_CONV_BUFSIZE, $with_misc_conv_bufsize, [libpam_misc misc_conv() buffer size.])
+
AM_CONDITIONAL([COND_BUILD_PAM_KEYINIT], [test "$have_key_syscalls" = 1])
AM_CONDITIONAL([COND_BUILD_PAM_LASTLOG], [test "$ac_cv_func_logwtmp" = yes])
AM_CONDITIONAL([COND_BUILD_PAM_NAMESPACE], [test "$ac_cv_func_unshare" = yes])
diff --git a/libpam_misc/misc_conv.c b/libpam_misc/misc_conv.c
index f28b1093..908ee890 100644
--- a/libpam_misc/misc_conv.c
+++ b/libpam_misc/misc_conv.c
@@ -18,7 +18,7 @@
#include <security/pam_appl.h>
#include <security/pam_misc.h>
-#define INPUTSIZE PAM_MAX_RESP_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
--
2.41.0
From 80bfda5962e5be3daa70e0fc8c75fc97d1c55121 Mon Sep 17 00:00:00 2001
From: Jeff Squyres <jsquyres@cisco.com>
Date: Fri, 30 Apr 2021 15:28:33 -0700
Subject: [PATCH 2/2] pam_misc: set default length of misc_conv() buffer to
4096
---
configure.ac | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/configure.ac b/configure.ac
index b283db1b..8e5d0ff7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -650,9 +650,9 @@ esac
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=512]),
+ [Size of input buffer for libpam_misc's misc_conv() conversation function, default=4096]),
[],
- [with_misc_conv_bufsize=512])
+ [with_misc_conv_bufsize=4096])
AC_DEFINE_UNQUOTED(PAM_MISC_CONV_BUFSIZE, $with_misc_conv_bufsize, [libpam_misc misc_conv() buffer size.])
AM_CONDITIONAL([COND_BUILD_PAM_KEYINIT], [test "$have_key_syscalls" = 1])
--
2.41.0

@ -1,489 +0,0 @@
diff -up Linux-PAM-1.5.1/modules/pam_pwhistory/Makefile.am.pam-pwhistory-load-conf-from-file Linux-PAM-1.5.1/modules/pam_pwhistory/Makefile.am
--- Linux-PAM-1.5.1/modules/pam_pwhistory/Makefile.am.pam-pwhistory-load-conf-from-file 2020-11-25 17:57:02.000000000 +0100
+++ Linux-PAM-1.5.1/modules/pam_pwhistory/Makefile.am 2022-08-22 09:08:48.916487811 +0200
@@ -9,9 +9,10 @@ MAINTAINERCLEANFILES = $(MANS) README
EXTRA_DIST = $(XMLS)
if HAVE_DOC
-dist_man_MANS = pam_pwhistory.8 pwhistory_helper.8
+dist_man_MANS = pam_pwhistory.8 pwhistory_helper.8 pwhistory.conf.5
endif
-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
dist_check_SCRIPTS = tst-pam_pwhistory
TESTS = $(dist_check_SCRIPTS)
@@ -26,12 +27,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\" @EXE_CFLAGS@
diff -up Linux-PAM-1.5.1/modules/pam_pwhistory/pam_pwhistory.8.xml.pam-pwhistory-load-conf-from-file Linux-PAM-1.5.1/modules/pam_pwhistory/pam_pwhistory.8.xml
--- Linux-PAM-1.5.1/modules/pam_pwhistory/pam_pwhistory.8.xml.pam-pwhistory-load-conf-from-file 2020-11-25 17:57:02.000000000 +0100
+++ Linux-PAM-1.5.1/modules/pam_pwhistory/pam_pwhistory.8.xml 2022-08-22 09:13:08.715628372 +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.5.1/modules/pam_pwhistory/pam_pwhistory.c.pam-pwhistory-load-conf-from-file Linux-PAM-1.5.1/modules/pam_pwhistory/pam_pwhistory.c
--- Linux-PAM-1.5.1/modules/pam_pwhistory/pam_pwhistory.c.pam-pwhistory-load-conf-from-file 2020-11-25 17:57:02.000000000 +0100
+++ Linux-PAM-1.5.1/modules/pam_pwhistory/pam_pwhistory.c 2022-08-22 09:11:34.949855242 +0200
@@ -63,14 +63,8 @@
#include "opasswd.h"
#include "pam_inline.h"
+#include "pwhistory_config.h"
-struct options_t {
- int debug;
- int enforce_for_root;
- int remember;
- int tries;
-};
-typedef struct options_t options_t;
static void
@@ -299,6 +293,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);
@@ -306,7 +302,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.5.1/modules/pam_pwhistory/pwhistory.conf.5.xml.pam-pwhistory-load-conf-from-file Linux-PAM-1.5.1/modules/pam_pwhistory/pwhistory.conf.5.xml
--- Linux-PAM-1.5.1/modules/pam_pwhistory/pwhistory.conf.5.xml.pam-pwhistory-load-conf-from-file 2022-08-22 09:08:48.916487811 +0200
+++ Linux-PAM-1.5.1/modules/pam_pwhistory/pwhistory.conf.5.xml 2022-08-22 09:08:48.916487811 +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.5.1/modules/pam_pwhistory/pwhistory_config.c.pam-pwhistory-load-conf-from-file Linux-PAM-1.5.1/modules/pam_pwhistory/pwhistory_config.c
--- Linux-PAM-1.5.1/modules/pam_pwhistory/pwhistory_config.c.pam-pwhistory-load-conf-from-file 2022-08-22 09:08:48.916487811 +0200
+++ Linux-PAM-1.5.1/modules/pam_pwhistory/pwhistory_config.c 2022-08-22 09:08:48.916487811 +0200
@@ -0,0 +1,115 @@
+/*
+ * 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 <security/pam_modutil.h>
+
+#include "pam_inline.h"
+#include "pwhistory_config.h"
+
+#define PWHISTORY_DEFAULT_CONF "/etc/security/pwhistory.conf"
+
+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 = pam_modutil_search_key (pamh, fname, "debug");
+ if (val != NULL) {
+ options->debug = 1;
+ free(val);
+ }
+
+ val = pam_modutil_search_key (pamh, fname, "enforce_for_root");
+ if (val != NULL) {
+ options->enforce_for_root = 1;
+ free(val);
+ }
+
+ val = pam_modutil_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 = pam_modutil_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 = pam_modutil_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.5.1/modules/pam_pwhistory/pwhistory_config.h.pam-pwhistory-load-conf-from-file Linux-PAM-1.5.1/modules/pam_pwhistory/pwhistory_config.h
--- Linux-PAM-1.5.1/modules/pam_pwhistory/pwhistory_config.h.pam-pwhistory-load-conf-from-file 2022-08-22 09:08:48.916487811 +0200
+++ Linux-PAM-1.5.1/modules/pam_pwhistory/pwhistory_config.h 2022-08-22 09:08:48.916487811 +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.5.1/modules/pam_pwhistory/pwhistory.conf.pam-pwhistory-load-conf-from-file Linux-PAM-1.5.1/modules/pam_pwhistory/pwhistory.conf
--- Linux-PAM-1.5.1/modules/pam_pwhistory/pwhistory.conf.pam-pwhistory-load-conf-from-file 2022-08-22 09:08:48.916487811 +0200
+++ Linux-PAM-1.5.1/modules/pam_pwhistory/pwhistory.conf 2022-08-22 09:08:48.916487811 +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

@ -1,114 +0,0 @@
diff -up Linux-PAM-1.5.1/modules/pam_unix/passverify.c.fail1 Linux-PAM-1.5.1/modules/pam_unix/passverify.c
--- Linux-PAM-1.5.1/modules/pam_unix/passverify.c.fail1 2024-11-04 11:42:51.962791265 +0100
+++ Linux-PAM-1.5.1/modules/pam_unix/passverify.c 2024-11-04 11:45:18.246218579 +0100
@@ -239,17 +239,21 @@ PAMH_ARG_DECL(int get_account_info,
return PAM_UNIX_RUN_HELPER;
#endif
} else if (is_pwd_shadowed(*pwd)) {
+#ifdef HELPER_COMPILE
/*
- * ...and shadow password file entry for this user,
+ * shadow password file entry for this user,
* if shadowing is enabled
*/
-#ifndef HELPER_COMPILE
- if (geteuid() || SELINUX_ENABLED)
- return PAM_UNIX_RUN_HELPER;
-#endif
- *spwdent = pam_modutil_getspnam(pamh, name);
+ *spwdent = getspnam(name);
if (*spwdent == NULL || (*spwdent)->sp_pwdp == NULL)
return PAM_AUTHINFO_UNAVAIL;
+#else
+ /*
+ * The helper has to be invoked to deal with
+ * the shadow password file entry.
+ */
+ return PAM_UNIX_RUN_HELPER;
+#endif
}
} else {
return PAM_USER_UNKNOWN;
From 8d0c575336ad301cd14e16ad2fdec6fe621764b8 Mon Sep 17 00:00:00 2001
From: Sergei Trofimovich <slyich@gmail.com>
Date: Thu, 28 Mar 2024 21:58:35 +0000
Subject: [PATCH] pam_unix: allow empty passwords with non-empty hashes
Before the change pam_unix has different behaviours for a user with
empty password for these two `/etc/shadow` entries:
nulloktest:$6$Yy4ty2jJ$bsVQWo8qlXC6UHq1/qTC3UR60ZJKmKApJ3Wj7DreAy8FxlVKtlDnplFQ7jMLVlDqordE7e4t49GvTb.aI59TP0:1::::::
nulloktest::1::::::
The entry with a hash was rejected and the entry without was accepted.
The rejection happened because 9e74e90147c "pam_unix: avoid determining
if user exists" introduced the following rejection check (slightly
simplified):
...
} else if (p[0] == '\0' && nullok) {
if (hash[0] != '\0') {
retval = PAM_AUTH_ERR;
}
We should not reject the user with a hash assuming it's non-empty.
The change does that by pushing empty password check into
`verify_pwd_hash()`.
`NixOS` generates such hashed entries for empty passwords as if they
were non-empty using the following perl code:
sub hashPassword {
my ($password) = @_;
my $salt = "";
my @chars = ('.', '/', 0..9, 'A'..'Z', 'a'..'z');
$salt .= $chars[rand 64] for (1..8);
return crypt($password, '$6$' . $salt . '$');
}
Resolves: https://github.com/linux-pam/linux-pam/issues/758
Fixes: 9e74e90147c "pam_unix: avoid determining if user exists"
Signed-off-by: Sergei Trofimovich <slyich@gmail.com>
---
modules/pam_unix/passverify.c | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/modules/pam_unix/passverify.c b/modules/pam_unix/passverify.c
index 30045333..1c83f1aa 100644
--- a/modules/pam_unix/passverify.c
+++ b/modules/pam_unix/passverify.c
@@ -76,9 +76,13 @@ PAMH_ARG_DECL(int verify_pwd_hash,
strip_hpux_aging(hash);
hash_len = strlen(hash);
- if (!hash_len) {
+
+ if (p && p[0] == '\0' && !nullok) {
+ /* The passed password is empty */
+ retval = PAM_AUTH_ERR;
+ } else if (!hash_len) {
/* the stored password is NULL */
- if (nullok) { /* this means we've succeeded */
+ if (p && p[0] == '\0' && nullok) { /* this means we've succeeded */
D(("user has empty password - access granted"));
retval = PAM_SUCCESS;
} else {
@@ -1109,12 +1113,6 @@ helper_verify_password(const char *name, const char *p, int nullok)
if (pwd == NULL || hash == NULL) {
helper_log_err(LOG_NOTICE, "check pass; user unknown");
retval = PAM_USER_UNKNOWN;
- } else if (p[0] == '\0' && nullok) {
- if (hash[0] == '\0') {
- retval = PAM_SUCCESS;
- } else {
- retval = PAM_AUTH_ERR;
- }
} else {
retval = verify_pwd_hash(p, hash, nullok);
}
--
2.47.0

@ -1,100 +0,0 @@
From 370064ef6f99581b08d473a42bb3417d5dda3e4e Mon Sep 17 00:00:00 2001
From: Iker Pedrosa <ipedrosa@redhat.com>
Date: Thu, 17 Feb 2022 10:24:03 +0100
Subject: [PATCH] pam_usertype: only use SYS_UID_MAX for system users
* modules/pam_usertype/pam_usertype.c (pam_usertype_is_system): Stop
using SYS_UID_MIN to check if it is a system account, because all
accounts below the SYS_UID_MAX are system users.
* modules/pam_usertype/pam_usertype.8.xml: Remove reference to SYS_UID_MIN
as it is no longer used to calculate the system accounts.
* configure.ac: Remove PAM_USERTYPE_SYSUIDMIN.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1949137
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
---
configure.ac | 5 -----
modules/pam_usertype/pam_usertype.8.xml | 2 +-
modules/pam_usertype/pam_usertype.c | 15 ++++++---------
3 files changed, 7 insertions(+), 15 deletions(-)
diff --git a/configure.ac b/configure.ac
index 639fc1ad..79113ad1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -632,11 +632,6 @@ test -n "$opt_uidmin" ||
opt_uidmin=1000
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)
-test -n "$opt_sysuidmin" ||
- opt_sysuidmin=101
-AC_DEFINE_UNQUOTED(PAM_USERTYPE_SYSUIDMIN, $opt_sysuidmin, [Minimum system user uid.])
-
AC_ARG_WITH([kernel-overflow-uid], AS_HELP_STRING([--with-kernel-overflow-uid=<number>],[kernel overflow uid, default (uint16_t)-2=65534]), opt_kerneloverflowuid=$withval)
test -n "$opt_kerneloverflowuid" ||
opt_kerneloverflowuid=65534
diff --git a/modules/pam_usertype/pam_usertype.8.xml b/modules/pam_usertype/pam_usertype.8.xml
index 7651da6e..d9307ba3 100644
--- a/modules/pam_usertype/pam_usertype.8.xml
+++ b/modules/pam_usertype/pam_usertype.8.xml
@@ -31,7 +31,7 @@
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>
+ <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>
diff --git a/modules/pam_usertype/pam_usertype.c b/modules/pam_usertype/pam_usertype.c
index d03b73b5..cfd9c8bb 100644
--- a/modules/pam_usertype/pam_usertype.c
+++ b/modules/pam_usertype/pam_usertype.c
@@ -194,7 +194,6 @@ 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) {
@@ -202,21 +201,19 @@ pam_usertype_is_system(pam_handle_t *pamh, uid_t 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;
+ if (uid <= sys_max && uid < uid_min) {
+ return PAM_SUCCESS;
+ }
+
+ return PAM_AUTH_ERR;
}
static int
@@ -253,7 +250,7 @@ pam_usertype_evaluate(struct pam_usertype_opts *opts,
/**
* Arguments:
- * - issystem: uid in <SYS_UID_MIN, SYS_UID_MAX>
+ * - issystem: uid less than 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
--
2.36.1

@ -1,42 +0,0 @@
From ec0e724fe53188c5c762c34ca9db6681c0de01b8 Mon Sep 17 00:00:00 2001
From: Iker Pedrosa <ipedrosa@redhat.com>
Date: Thu, 1 Jul 2021 12:14:29 +0200
Subject: [PATCH] pam_filter: Close file after controlling tty
Failing to check the descriptor value meant that there was a bug in the
attempt to close the controlling tty. Moreover, this would lead to a
file descriptor leak as pointed out by the static analyzer tool:
Error: RESOURCE_LEAK (CWE-772): [#def26]
Linux-PAM-1.5.1/modules/pam_filter/pam_filter.c:356: open_fn: Returning handle opened by "open". [Note: The source code implementation of the function has been overridden by a user model.]
Linux-PAM-1.5.1/modules/pam_filter/pam_filter.c:356: var_assign: Assigning: "t" = handle returned from "open("/dev/tty", 2)".
Linux-PAM-1.5.1/modules/pam_filter/pam_filter.c:357: off_by_one: Testing whether handle "t" is strictly greater than zero is suspicious. "t" leaks when it is zero.
Linux-PAM-1.5.1/modules/pam_filter/pam_filter.c:357: remediation: Did you intend to include equality with zero?
Linux-PAM-1.5.1/modules/pam_filter/pam_filter.c:367: leaked_handle: Handle variable "t" going out of scope leaks the handle.
365| pam_syslog(pamh, LOG_ERR,
366| "child cannot become new session: %m");
367|-> return PAM_ABORT;
368| }
369|
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
---
modules/pam_filter/pam_filter.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/pam_filter/pam_filter.c b/modules/pam_filter/pam_filter.c
index 2f0af4fb..6e6def37 100644
--- a/modules/pam_filter/pam_filter.c
+++ b/modules/pam_filter/pam_filter.c
@@ -354,7 +354,7 @@ set_filter (pam_handle_t *pamh, int flags UNUSED, int ctrl,
int t = open("/dev/tty", O_RDWR|O_NOCTTY);
#else
int t = open("/dev/tty",O_RDWR);
- if (t > 0) {
+ if (t >= 0) {
(void) ioctl(t, TIOCNOTTY, NULL);
close(t);
}
--
2.31.1

@ -1,738 +0,0 @@
From b3bb13e18a74e9ece825b7de1b81db97ebb107a0 Mon Sep 17 00:00:00 2001
From: Iker Pedrosa <ipedrosa@redhat.com>
Date: Thu, 25 Mar 2021 09:43:30 +0100
Subject: [PATCH] pam_timestamp: replace hmac implementation
sha1 is no longer recommended as a cryptographic algorithm for
authentication. Thus, the idea of this change is to replace the
implementation provided by hmacsha1 included in pam_timestamp module by
the one in the openssl library. This way, there's no need to maintain
the cryptographic algorithm implementation and it can be easily changed
with a single configuration change.
modules/pam_timestamp/hmac_openssl_wrapper.c: implement wrapper
functions around openssl's hmac implementation. Moreover, manage the key
generation and its read and write in a file. Include an option to
configure the cryptographic algorithm in login.defs file.
modules/pam_timestamp/hmac_openssl_wrapper.h: likewise.
modules/pam_timestamp/pam_timestamp.c: replace calls to functions
provided by hmacsha1 by functions provided by openssl's wrapper.
configure.ac: include openssl dependecy if it is enabled.
modules/pam_timestamp/Makefile.am: include new files and openssl library
to compilation.
ci/install-dependencies.sh: include openssl library to dependencies.
NEWS: add new item to next release.
Make.xml.rules.in: add stringparam profiling for hmac
doc/custom-man.xsl: change import docbook to one with profiling
modules/pam_timestamp/pam_timestamp.8.xml: add conditional paragraph to
indicate the value in /etc/login.defs that holds the value for the
encryption algorithm
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1947294
---
Make.xml.rules.in | 2 +-
NEWS | 5 +
configure.ac | 16 +
doc/custom-man.xsl | 2 +-
modules/pam_timestamp/Makefile.am | 15 +-
modules/pam_timestamp/hmac_openssl_wrapper.c | 381 +++++++++++++++++++
modules/pam_timestamp/hmac_openssl_wrapper.h | 57 +++
modules/pam_timestamp/pam_timestamp.8.xml | 5 +
modules/pam_timestamp/pam_timestamp.c | 53 ++-
10 files changed, 524 insertions(+), 13 deletions(-)
create mode 100644 modules/pam_timestamp/hmac_openssl_wrapper.c
create mode 100644 modules/pam_timestamp/hmac_openssl_wrapper.h
diff --git a/Make.xml.rules.in b/Make.xml.rules.in
index daa1b97b..27bb510e 100644
--- a/Make.xml.rules.in
+++ b/Make.xml.rules.in
@@ -21,6 +21,6 @@ README: README.xml
%.8: %.8.xml
$(XMLLINT) --nonet --xinclude --postvalid --noout $<
- $(XSLTPROC) -o $(srcdir)/$@ --path $(srcdir) --xinclude @STRINGPARAM_VENDORDIR@ --nonet $(top_srcdir)/doc/custom-man.xsl $<
+ $(XSLTPROC) -o $(srcdir)/$@ --path $(srcdir) --xinclude @STRINGPARAM_VENDORDIR@ @STRINGPARAM_HMAC@ --nonet $(top_srcdir)/doc/custom-man.xsl $<
#CLEANFILES += $(man_MANS) README
diff --git a/NEWS b/NEWS
index 2d49ec39..f4d11303 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,10 @@
Linux-PAM NEWS -- history of user-visible changes.
+Release next
+* pam_timestamp: change hmac algorithm to call openssl instead of the bundled
+ sha1 implementation if selected. Add option to select the hash
+ algorithm to use with HMAC.
+
Release 1.5.1
* pam_unix: fixed CVE-2020-27780 - authentication bypass when a user
doesn't exist and root password is blank
diff --git a/configure.ac b/configure.ac
index bd806473..9c92d0de 100644
--- a/configure.ac
+++ b/configure.ac
@@ -504,6 +504,22 @@ else
fi
AC_SUBST([STRINGPARAM_VENDORDIR])
+AC_ARG_ENABLE([openssl],
+ AS_HELP_STRING([--enable-openssl],[use OpenSSL crypto libraries]),
+ [OPENSSL_ENABLED=$enableval], OPENSSL_ENABLED=no)
+if test "$OPENSSL_ENABLED" = "yes" ; then
+ AC_CHECK_LIB([crypto], [EVP_MAC_CTX_new],
+ [CRYPTO_LIBS="-lcrypto"
+ use_openssl=yes
+ AC_DEFINE([WITH_OPENSSL], 1, [OpenSSL provides crypto algorithm for hmac])
+ STRINGPARAM_HMAC="--stringparam profile.condition 'openssl_hmac'"],
+ [CRYPTO_LIBS=""
+ STRINGPARAM_HMAC="--stringparam profile.condition 'no_openssl_hmac'"])
+fi
+AC_SUBST([CRYPTO_LIBS])
+AC_SUBST([STRINGPARAM_HMAC])
+AM_CONDITIONAL([COND_USE_OPENSSL], [test "x$use_openssl" = "xyes"])
+
dnl Checks for header files.
AC_HEADER_DIRENT
AC_HEADER_STDC
diff --git a/doc/custom-man.xsl b/doc/custom-man.xsl
index 4c35e839..a3408e6c 100644
--- a/doc/custom-man.xsl
+++ b/doc/custom-man.xsl
@@ -1,6 +1,6 @@
<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ss="http://docbook.sf.net/xmlns/string.subst/1.0" version="1.0">
- <xsl:import href="http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl"/>
+ <xsl:import href="http://docbook.sourceforge.net/release/xsl/current/manpages/profile-docbook.xsl"/>
<xsl:param name="vendordir"/>
<xsl:param name="man.string.subst.map.local.pre">
diff --git a/modules/pam_timestamp/Makefile.am b/modules/pam_timestamp/Makefile.am
index 1faa324a..d290b85f 100644
--- a/modules/pam_timestamp/Makefile.am
+++ b/modules/pam_timestamp/Makefile.am
@@ -18,12 +18,12 @@ TESTS = $(dist_check_SCRIPTS) $(check_PROGRAMS)
securelibdir = $(SECUREDIR)
secureconfdir = $(SCONFIGDIR)
-noinst_HEADERS = hmacsha1.h sha1.h
+noinst_HEADERS = hmacsha1.h sha1.h hmac_openssl_wrapper.h
AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
$(WARN_CFLAGS)
-pam_timestamp_la_LDFLAGS = -no-undefined -avoid-version -module $(AM_LDFLAGS)
+pam_timestamp_la_LDFLAGS = -no-undefined -avoid-version -module $(AM_LDFLAGS) $(CRYPTO_LIBS)
pam_timestamp_la_LIBADD = $(top_builddir)/libpam/libpam.la
if HAVE_VERSIONING
pam_timestamp_la_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
@@ -32,7 +32,12 @@ endif
securelib_LTLIBRARIES = pam_timestamp.la
sbin_PROGRAMS = pam_timestamp_check
-pam_timestamp_la_SOURCES = pam_timestamp.c hmacsha1.c sha1.c
+pam_timestamp_la_SOURCES = pam_timestamp.c
+if COND_USE_OPENSSL
+pam_timestamp_la_SOURCES += hmac_openssl_wrapper.c
+else
+pam_timestamp_la_SOURCES += hmacsha1.c sha1.c
+endif
pam_timestamp_la_CFLAGS = $(AM_CFLAGS)
pam_timestamp_check_SOURCES = pam_timestamp_check.c
@@ -40,7 +45,11 @@ pam_timestamp_check_CFLAGS = $(AM_CFLAGS) @EXE_CFLAGS@
pam_timestamp_check_LDADD = $(top_builddir)/libpam/libpam.la
pam_timestamp_check_LDFLAGS = @EXE_LDFLAGS@
+if COND_USE_OPENSSL
+hmacfile_SOURCES = hmac_openssl_wrapper.c
+else
hmacfile_SOURCES = hmacfile.c hmacsha1.c sha1.c
+endif
hmacfile_LDADD = $(top_builddir)/libpam/libpam.la
check_PROGRAMS = hmacfile
diff --git a/modules/pam_timestamp/hmac_openssl_wrapper.c b/modules/pam_timestamp/hmac_openssl_wrapper.c
new file mode 100644
index 00000000..926c2fb9
--- /dev/null
+++ b/modules/pam_timestamp/hmac_openssl_wrapper.c
@@ -0,0 +1,381 @@
+/* Wrapper for hmac openssl implementation.
+ *
+ * Copyright (c) 2021 Red Hat, Inc.
+ * Written by 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"
+
+#ifdef WITH_OPENSSL
+
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <syslog.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <openssl/evp.h>
+#include <openssl/params.h>
+#include <openssl/core_names.h>
+
+#include <security/pam_ext.h>
+#include <security/pam_modutil.h>
+
+#include "hmac_openssl_wrapper.h"
+
+#define LOGIN_DEFS "/etc/login.defs"
+#define CRYPTO_KEY "HMAC_CRYPTO_ALGO"
+#define DEFAULT_ALGORITHM "SHA512"
+#define MAX_HMAC_LENGTH 512
+#define MAX_KEY_LENGTH EVP_MAX_KEY_LENGTH
+
+static char *
+get_crypto_algorithm(pam_handle_t *pamh, int debug){
+ char *config_value = NULL;
+
+ config_value = pam_modutil_search_key(pamh, LOGIN_DEFS, CRYPTO_KEY);
+
+ if (config_value == NULL) {
+ config_value = strdup(DEFAULT_ALGORITHM);
+ if (debug) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "Key [%s] not found, falling back to default algorithm [%s]\n",
+ CRYPTO_KEY, DEFAULT_ALGORITHM);
+ }
+ }
+
+ return config_value;
+}
+
+static int
+generate_key(pam_handle_t *pamh, char **key, size_t key_size)
+{
+ int fd = 0;
+ size_t bytes_read = 0;
+ char * tmp = NULL;
+
+ fd = open("/dev/urandom", O_RDONLY);
+ if (fd == -1) {
+ pam_syslog(pamh, LOG_ERR, "Cannot open /dev/urandom: %m");
+ return PAM_AUTH_ERR;
+ }
+
+ tmp = malloc(key_size);
+ if (!tmp) {
+ pam_syslog(pamh, LOG_CRIT, "Not enough memory");
+ close(fd);
+ return PAM_AUTH_ERR;
+ }
+
+ bytes_read = pam_modutil_read(fd, tmp, key_size);
+ close(fd);
+
+ if (bytes_read < key_size) {
+ pam_syslog(pamh, LOG_ERR, "Short read on random device");
+ free(tmp);
+ return PAM_AUTH_ERR;
+ }
+
+ *key = tmp;
+
+ return PAM_SUCCESS;
+}
+
+static int
+read_file(pam_handle_t *pamh, int fd, char **text, size_t *text_length)
+{
+ struct stat st;
+ size_t bytes_read = 0;
+ char *tmp = NULL;
+
+ if (fstat(fd, &st) == -1) {
+ pam_syslog(pamh, LOG_ERR, "Unable to stat file: %m");
+ close(fd);
+ return PAM_AUTH_ERR;
+ }
+
+ if (st.st_size == 0) {
+ pam_syslog(pamh, LOG_ERR, "Key file size cannot be 0");
+ close(fd);
+ return PAM_AUTH_ERR;
+ }
+
+ tmp = malloc(st.st_size);
+ if (!tmp) {
+ pam_syslog(pamh, LOG_CRIT, "Not enough memory");
+ close(fd);
+ return PAM_AUTH_ERR;
+ }
+
+ bytes_read = pam_modutil_read(fd, tmp, st.st_size);
+ close(fd);
+
+ if (bytes_read < (size_t)st.st_size) {
+ pam_syslog(pamh, LOG_ERR, "Short read on key file");
+ memset(tmp, 0, st.st_size);
+ free(tmp);
+ return PAM_AUTH_ERR;
+ }
+
+ *text = tmp;
+ *text_length = st.st_size;
+
+ return PAM_SUCCESS;
+}
+
+static int
+write_file(pam_handle_t *pamh, const char *file_name, char *text,
+ size_t text_length, uid_t owner, gid_t group)
+{
+ int fd = 0;
+ size_t bytes_written = 0;
+
+ fd = open(file_name,
+ O_WRONLY | O_CREAT | O_TRUNC,
+ S_IRUSR | S_IWUSR);
+ if (fd == -1) {
+ pam_syslog(pamh, LOG_ERR, "Unable to open [%s]: %m", file_name);
+ memset(text, 0, text_length);
+ free(text);
+ return PAM_AUTH_ERR;
+ }
+
+ if (fchown(fd, owner, group) == -1) {
+ pam_syslog(pamh, LOG_ERR, "Unable to change ownership [%s]: %m", file_name);
+ memset(text, 0, text_length);
+ free(text);
+ close(fd);
+ return PAM_AUTH_ERR;
+ }
+
+ bytes_written = pam_modutil_write(fd, text, text_length);
+ close(fd);
+
+ if (bytes_written < text_length) {
+ pam_syslog(pamh, LOG_ERR, "Short write on %s", file_name);
+ free(text);
+ return PAM_AUTH_ERR;
+ }
+
+ return PAM_SUCCESS;
+}
+
+static int
+key_management(pam_handle_t *pamh, const char *file_name, char **text,
+ size_t text_length, uid_t owner, gid_t group)
+{
+ int fd = 0;
+
+ fd = open(file_name, O_RDONLY | O_NOFOLLOW);
+ if (fd == -1) {
+ if (errno == ENOENT) {
+ if (generate_key(pamh, text, text_length)) {
+ pam_syslog(pamh, LOG_ERR, "Unable to generate key");
+ return PAM_AUTH_ERR;
+ }
+
+ if (write_file(pamh, file_name, *text, text_length, owner, group)) {
+ pam_syslog(pamh, LOG_ERR, "Unable to write key");
+ return PAM_AUTH_ERR;
+ }
+ } else {
+ pam_syslog(pamh, LOG_ERR, "Unable to open %s: %m", file_name);
+ return PAM_AUTH_ERR;
+ }
+ } else {
+ if (read_file(pamh, fd, text, &text_length)) {
+ pam_syslog(pamh, LOG_ERR, "Error reading key file %s\n", file_name);
+ return PAM_AUTH_ERR;
+ }
+ }
+
+ return PAM_SUCCESS;
+}
+
+static int
+hmac_management(pam_handle_t *pamh, int debug, void **out, size_t *out_length,
+ char *key, size_t key_length,
+ const void *text, size_t text_length)
+{
+ int ret = PAM_AUTH_ERR;
+ EVP_MAC *evp_mac = NULL;
+ EVP_MAC_CTX *ctx = NULL;
+ unsigned char *hmac_message = NULL;
+ size_t hmac_length;
+ char *algo = NULL;
+ OSSL_PARAM subalg_param[] = { OSSL_PARAM_END, OSSL_PARAM_END };
+
+ algo = get_crypto_algorithm(pamh, debug);
+
+ subalg_param[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
+ algo,
+ 0);
+
+ evp_mac = EVP_MAC_fetch(NULL, "HMAC", NULL);
+ if (evp_mac == NULL) {
+ pam_syslog(pamh, LOG_ERR, "Unable to create hmac implementation");
+ goto done;
+ }
+
+ ctx = EVP_MAC_CTX_new(evp_mac);
+ if (ctx == NULL) {
+ pam_syslog(pamh, LOG_ERR, "Unable to create hmac context");
+ goto done;
+ }
+
+ ret = EVP_MAC_init(ctx, (const unsigned char *)key, key_length, subalg_param);
+ if (ret == 0) {
+ pam_syslog(pamh, LOG_ERR, "Unable to initialize hmac context");
+ goto done;
+ }
+
+ ret = EVP_MAC_update(ctx, (const unsigned char *)text, text_length);
+ if (ret == 0) {
+ pam_syslog(pamh, LOG_ERR, "Unable to update hmac context");
+ goto done;
+ }
+
+ hmac_message = (unsigned char*)malloc(sizeof(unsigned char) * MAX_HMAC_LENGTH);
+ if (!hmac_message) {
+ pam_syslog(pamh, LOG_CRIT, "Not enough memory");
+ goto done;
+ }
+
+ ret = EVP_MAC_final(ctx, hmac_message, &hmac_length, MAX_HMAC_LENGTH);
+ if (ret == 0) {
+ pam_syslog(pamh, LOG_ERR, "Unable to calculate hmac message");
+ goto done;
+ }
+
+ *out_length = hmac_length;
+ *out = malloc(*out_length);
+ if (*out == NULL) {
+ pam_syslog(pamh, LOG_CRIT, "Not enough memory");
+ goto done;
+ }
+
+ memcpy(*out, hmac_message, *out_length);
+ ret = PAM_SUCCESS;
+
+done:
+ if (hmac_message != NULL) {
+ free(hmac_message);
+ }
+ if (key != NULL) {
+ memset(key, 0, key_length);
+ free(key);
+ }
+ if (ctx != NULL) {
+ EVP_MAC_CTX_free(ctx);
+ }
+ if (evp_mac != NULL) {
+ EVP_MAC_free(evp_mac);
+ }
+ free(algo);
+
+ return ret;
+}
+
+int
+hmac_size(pam_handle_t *pamh, int debug, size_t *hmac_length)
+{
+ int ret = PAM_AUTH_ERR;
+ EVP_MAC *evp_mac = NULL;
+ EVP_MAC_CTX *ctx = NULL;
+ const unsigned char key[] = "ThisIsJustAKey";
+ size_t key_length = MAX_KEY_LENGTH;
+ char *algo = NULL;
+ OSSL_PARAM subalg_param[] = { OSSL_PARAM_END, OSSL_PARAM_END };
+
+ algo = get_crypto_algorithm(pamh, debug);
+
+ subalg_param[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
+ algo,
+ 0);
+
+ evp_mac = EVP_MAC_fetch(NULL, "HMAC", NULL);
+ if (evp_mac == NULL) {
+ pam_syslog(pamh, LOG_ERR, "Unable to create hmac implementation");
+ goto done;
+ }
+
+ ctx = EVP_MAC_CTX_new(evp_mac);
+ if (ctx == NULL) {
+ pam_syslog(pamh, LOG_ERR, "Unable to create hmac context");
+ goto done;
+ }
+
+ ret = EVP_MAC_init(ctx, key, key_length, subalg_param);
+ if (ret == 0) {
+ pam_syslog(pamh, LOG_ERR, "Unable to initialize hmac context");
+ goto done;
+ }
+
+ *hmac_length = EVP_MAC_CTX_get_mac_size(ctx);
+ ret = PAM_SUCCESS;
+
+done:
+ if (ctx != NULL) {
+ EVP_MAC_CTX_free(ctx);
+ }
+ if (evp_mac != NULL) {
+ EVP_MAC_free(evp_mac);
+ }
+ free(algo);
+
+ return ret;
+}
+
+int
+hmac_generate(pam_handle_t *pamh, int debug, void **mac, size_t *mac_length,
+ const char *key_file, uid_t owner, gid_t group,
+ const void *text, size_t text_length)
+{
+ char *key = NULL;
+ size_t key_length = MAX_KEY_LENGTH;
+
+ if (key_management(pamh, key_file, &key, key_length, owner, group)) {
+ return PAM_AUTH_ERR;
+ }
+
+ if (hmac_management(pamh, debug, mac, mac_length, key, key_length,
+ text, text_length)) {
+ return PAM_AUTH_ERR;
+ }
+
+ return PAM_SUCCESS;
+}
+
+#endif /* WITH_OPENSSL */
diff --git a/modules/pam_timestamp/hmac_openssl_wrapper.h b/modules/pam_timestamp/hmac_openssl_wrapper.h
new file mode 100644
index 00000000..cc27c811
--- /dev/null
+++ b/modules/pam_timestamp/hmac_openssl_wrapper.h
@@ -0,0 +1,57 @@
+/* Wrapper for hmac openssl implementation.
+ *
+ * Copyright (c) 2021 Red Hat, Inc.
+ * Written by 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 PAM_TIMESTAMP_HMAC_OPENSSL_WRAPPER_H
+#define PAM_TIMESTAMP_HMAC_OPENSSL_WRAPPER_H
+
+#include "config.h"
+
+#ifdef WITH_OPENSSL
+
+#include <openssl/hmac.h>
+#include <security/pam_modules.h>
+
+int
+hmac_size(pam_handle_t *pamh, int debug, size_t *hmac_length);
+
+int
+hmac_generate(pam_handle_t *pamh, int debug, void **mac, size_t *mac_length,
+ const char *key_file, uid_t owner, gid_t group,
+ const void *text, size_t text_length);
+
+#endif /* WITH_OPENSSL */
+#endif /* PAM_TIMESTAMP_HMAC_OPENSSL_WRAPPER_H */
diff --git a/modules/pam_timestamp/pam_timestamp.8.xml b/modules/pam_timestamp/pam_timestamp.8.xml
index e19a0bcf..83e5aea8 100644
--- a/modules/pam_timestamp/pam_timestamp.8.xml
+++ b/modules/pam_timestamp/pam_timestamp.8.xml
@@ -50,6 +50,11 @@ for the user. When an application attempts to authenticate the user, a
<emphasis>pam_timestamp</emphasis> will treat a sufficiently recent timestamp
file as grounds for succeeding.
</para>
+ <para condition="openssl_hmac">
+ The default encryption hash is taken from the
+ <emphasis remap='B'>HMAC_CRYPTO_ALGO</emphasis> variable from
+ <emphasis>/etc/login.defs</emphasis>.
+ </para>
</refsect1>
<refsect1 id="pam_timestamp-options">
diff --git a/modules/pam_timestamp/pam_timestamp.c b/modules/pam_timestamp/pam_timestamp.c
index 30be883c..01dd1385 100644
--- a/modules/pam_timestamp/pam_timestamp.c
+++ b/modules/pam_timestamp/pam_timestamp.c
@@ -56,7 +56,11 @@
#include <utmp.h>
#include <syslog.h>
#include <paths.h>
+#ifdef WITH_OPENSSL
+#include "hmac_openssl_wrapper.h"
+#else
#include "hmacsha1.h"
+#endif /* WITH_OPENSSL */
#include <security/pam_modules.h>
#include <security/_pam_macros.h>
@@ -79,6 +83,9 @@
#define BUFLEN PATH_MAX
#endif
+#define ROOT_USER 0
+#define ROOT_GROUP 0
+
/* Return PAM_SUCCESS if the given directory looks "safe". */
static int
check_dir_perms(pam_handle_t *pamh, const char *tdir)
@@ -449,6 +456,13 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv)
return PAM_AUTH_ERR;
}
+#ifdef WITH_OPENSSL
+ if (hmac_size(pamh, debug, &maclen)) {
+ return PAM_AUTH_ERR;
+ }
+#else
+ maclen = hmac_sha1_size();
+#endif /* WITH_OPENSSL */
/* Check that the file is the expected size. */
if (st.st_size == 0) {
/* Invalid, but may have been created by sudo. */
@@ -456,7 +470,7 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv)
return PAM_AUTH_ERR;
}
if (st.st_size !=
- (off_t)(strlen(path) + 1 + sizeof(then) + hmac_sha1_size())) {
+ (off_t)(strlen(path) + 1 + sizeof(then) + maclen)) {
pam_syslog(pamh, LOG_NOTICE, "timestamp file `%s' "
"appears to be corrupted", path);
close(fd);
@@ -487,8 +501,17 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv)
message_end = message + strlen(path) + 1 + sizeof(then);
/* Regenerate the MAC. */
- hmac_sha1_generate_file(pamh, &mac, &maclen, TIMESTAMPKEY, 0, 0,
- message, message_end - message);
+#ifdef WITH_OPENSSL
+ if (hmac_generate(pamh, debug, &mac, &maclen, TIMESTAMPKEY,
+ ROOT_USER, ROOT_GROUP, message, message_end - message)) {
+ close(fd);
+ free(message);
+ return PAM_AUTH_ERR;
+ }
+#else
+ hmac_sha1_generate_file(pamh, &mac, &maclen, TIMESTAMPKEY,
+ ROOT_USER, ROOT_GROUP, message, message_end - message);
+#endif /* WITH_OPENSSL */
if ((mac == NULL) ||
(memcmp(path, message, strlen(path)) != 0) ||
(memcmp(mac, message_end, maclen) != 0)) {
@@ -605,8 +628,16 @@ pam_sm_open_session(pam_handle_t *pamh, int flags UNUSED, int argc, const char *
}
}
+#ifdef WITH_OPENSSL
+ if (hmac_size(pamh, debug, &maclen)) {
+ return PAM_SESSION_ERR;
+ }
+#else
+ maclen = hmac_sha1_size();
+#endif /* WITH_OPENSSL */
+
/* Generate the message. */
- text = malloc(strlen(path) + 1 + sizeof(now) + hmac_sha1_size());
+ text = malloc(strlen(path) + 1 + sizeof(now) + maclen);
if (text == NULL) {
pam_syslog(pamh, LOG_CRIT, "unable to allocate memory: %m");
return PAM_SESSION_ERR;
@@ -621,15 +652,21 @@ pam_sm_open_session(pam_handle_t *pamh, int flags UNUSED, int argc, const char *
p += sizeof(now);
/* Generate the MAC and append it to the plaintext. */
- hmac_sha1_generate_file(pamh, &mac, &maclen,
- TIMESTAMPKEY,
- 0, 0,
- text, p - text);
+#ifdef WITH_OPENSSL
+ if (hmac_generate(pamh, debug, &mac, &maclen, TIMESTAMPKEY,
+ ROOT_USER, ROOT_GROUP, text, p - text)) {
+ free(text);
+ return PAM_SESSION_ERR;
+ }
+#else
+ hmac_sha1_generate_file(pamh, &mac, &maclen, TIMESTAMPKEY,
+ ROOT_USER, ROOT_GROUP, text, p - text);
if (mac == NULL) {
pam_syslog(pamh, LOG_ERR, "failure generating MAC: %m");
free(text);
return PAM_SESSION_ERR;
}
+#endif /* WITH_OPENSSL */
memmove(p, mac, maclen);
p += maclen;
free(mac);
--
2.31.1

@ -1,7 +1,8 @@
diff -up Linux-PAM-1.3.0/modules/pam_unix/pam_unix_passwd.c.nomsg Linux-PAM-1.3.0/modules/pam_unix/pam_unix_passwd.c
--- Linux-PAM-1.3.0/modules/pam_unix/pam_unix_passwd.c.nomsg 2016-04-11 13:08:47.000000000 +0200
+++ Linux-PAM-1.3.0/modules/pam_unix/pam_unix_passwd.c 2017-04-20 16:51:24.853106709 +0200
@@ -687,12 +687,6 @@ pam_sm_chauthtok(pam_handle_t *pamh, int
Index: Linux-PAM-1.5.3/modules/pam_unix/pam_unix_passwd.c
===================================================================
--- Linux-PAM-1.5.3.orig/modules/pam_unix/pam_unix_passwd.c
+++ Linux-PAM-1.5.3/modules/pam_unix/pam_unix_passwd.c
@@ -678,12 +678,6 @@ pam_sm_chauthtok(pam_handle_t *pamh, int
return PAM_SUCCESS;
} else if (off(UNIX__IAMROOT, ctrl) ||
(on(UNIX_NIS, ctrl) && _unix_comesfromsource(pamh, user, 0, 1))) {

@ -0,0 +1,24 @@
diff -up Linux-PAM-1.6.0/configure.ac.redhat-modules Linux-PAM-1.6.0/configure.ac
--- Linux-PAM-1.6.0/configure.ac.redhat-modules 2024-01-23 13:16:34.854753145 +0100
+++ Linux-PAM-1.6.0/configure.ac 2024-01-23 13:17:52.855859922 +0100
@@ -774,6 +774,8 @@ AC_CONFIG_FILES([Makefile libpam/Makefil
po/Makefile.in \
Make.xml.rules \
modules/Makefile \
+ modules/pam_chroot/Makefile \
+ modules/pam_postgresok/Makefile \
modules/pam_access/Makefile \
modules/pam_canonicalize_user/Makefile \
modules/pam_debug/Makefile modules/pam_deny/Makefile \
diff -up Linux-PAM-1.6.0/modules/Makefile.am.redhat-modules Linux-PAM-1.6.0/modules/Makefile.am
--- Linux-PAM-1.6.0/modules/Makefile.am.redhat-modules 2024-01-17 11:29:36.000000000 +0100
+++ Linux-PAM-1.6.0/modules/Makefile.am 2024-01-23 13:16:34.855753147 +0100
@@ -48,6 +48,8 @@ SUBDIRS := \
pam_debug \
pam_deny \
pam_echo \
+ pam_chroot \
+ pam_postgresok \
pam_env \
pam_exec \
pam_faildelay \

@ -0,0 +1,24 @@
diff -up Linux-PAM-1.6.1/doc/Makefile.am.noflex Linux-PAM-1.6.1/doc/Makefile.am
--- Linux-PAM-1.6.1/doc/Makefile.am.noflex 2024-04-09 18:22:59.000000000 +0200
+++ Linux-PAM-1.6.1/doc/Makefile.am 2024-04-10 11:09:39.304086982 +0200
@@ -2,7 +2,7 @@
# Copyright (c) 2005, 2006 Thorsten Kukuk <kukuk@suse.de>
#
-SUBDIRS = man specs sag adg mwg
+SUBDIRS = man sag adg mwg
CLEANFILES = *~
DISTCLEANFILES = custom-html.xsl custom-man.xsl
diff -up Linux-PAM-1.6.1/Makefile.am.noflex Linux-PAM-1.6.1/Makefile.am
--- Linux-PAM-1.6.1/Makefile.am.noflex 2024-04-10 11:09:39.304086982 +0200
+++ Linux-PAM-1.6.1/Makefile.am 2024-04-10 11:13:15.057352362 +0200
@@ -4,7 +4,7 @@
AUTOMAKE_OPTIONS = 1.9 gnu dist-xz no-dist-gzip check-news
-SUBDIRS = libpam_internal libpam tests libpamc libpam_misc modules po conf \
+SUBDIRS = libpam_internal libpam tests libpamc libpam_misc modules po doc \
xtests
if HAVE_DOC

@ -0,0 +1,119 @@
From ecaaf4456e5aeacae1acdb1775bb5aadd3b19e13 Mon Sep 17 00:00:00 2001
From: Iker Pedrosa <ipedrosa@redhat.com>
Date: Wed, 16 Oct 2024 12:41:09 +0200
Subject: [PATCH 1/2] pam_access: always match local address
* modules/pam_access/pam_access.c: match the local address regardless of
the IP version in use.
In some circumstances the `localhost` may be translated to IPv4 or IPv6,
but the configuration file only indicated the address for one of the two
versions. Since the originating value is set in `PAM_RHOST` and PAM has
no control over it, let's match the local addresses regardless of the IP
version in use.
Resolves: https://issues.redhat.com/browse/RHEL-23018
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
---
modules/pam_access/pam_access.c | 30 ++++++++++++++++++++++++++++--
1 file changed, 28 insertions(+), 2 deletions(-)
diff --git a/modules/pam_access/pam_access.c b/modules/pam_access/pam_access.c
index bfbc6d57..48e7c7e9 100644
--- a/modules/pam_access/pam_access.c
+++ b/modules/pam_access/pam_access.c
@@ -306,6 +306,23 @@ isipaddr (const char *string, int *addr_type,
return is_ip;
}
+/* is_local_addr - checks if the IP address is local */
+static int
+is_local_addr (const char *string, int addr_type)
+{
+ if (addr_type == AF_INET) {
+ if (strcmp(string, "127.0.0.1") == 0) {
+ return YES;
+ }
+ } else if (addr_type == AF_INET6) {
+ if (strcmp(string, "::1") == 0) {
+ return YES;
+ }
+ }
+
+ return NO;
+}
+
/* are_addresses_equal - translate IP address strings to real IP
* addresses and compare them to find out if they are equal.
@@ -327,9 +344,18 @@ are_addresses_equal (const char *ipaddr0, const char *ipaddr1,
if (isipaddr (ipaddr1, &addr_type1, &addr1) == NO)
return NO;
- if (addr_type0 != addr_type1)
- /* different address types */
+ if (addr_type0 != addr_type1) {
+ /* different address types, but there is still a possibility that they are
+ * both local addresses
+ */
+ int local1 = is_local_addr(ipaddr0, addr_type0);
+ int local2 = is_local_addr(ipaddr1, addr_type1);
+
+ if (local1 == YES && local2 == YES)
+ return YES;
+
return NO;
+ }
if (netmask != NULL) {
/* Got a netmask, so normalize addresses? */
--
2.47.0
From 641dfd1084508c63f3590e93a35b80ffc50774e5 Mon Sep 17 00:00:00 2001
From: Iker Pedrosa <ipedrosa@redhat.com>
Date: Fri, 18 Oct 2024 10:27:07 +0200
Subject: [PATCH 2/2] pam_access: clarify `LOCAL` keyword behaviour
* modules/pam_access/access.conf.5.xml: `LOCAL` keyword behaviour
explanation was focused on the development internals. Let's clarify it
by rephrasing it to something a sysadmin can understand.
Resolves: https://issues.redhat.com/browse/RHEL-39943
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
---
modules/pam_access/access.conf.5.xml | 17 ++++++-----------
1 file changed, 6 insertions(+), 11 deletions(-)
diff --git a/modules/pam_access/access.conf.5.xml b/modules/pam_access/access.conf.5.xml
index 35a1a8fe..0b93db00 100644
--- a/modules/pam_access/access.conf.5.xml
+++ b/modules/pam_access/access.conf.5.xml
@@ -79,17 +79,12 @@
with network mask (where network mask can be a decimal number or an
internet address also), <emphasis>ALL</emphasis> (which always matches)
or <emphasis>LOCAL</emphasis>. The <emphasis>LOCAL</emphasis>
- keyword matches if and only if
- <citerefentry><refentrytitle>pam_get_item</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
- when called with an <parameter>item_type</parameter> of
- <emphasis>PAM_RHOST</emphasis>, returns <code>NULL</code> or an
- empty string (and therefore the
- <replaceable>origins</replaceable> field is compared against the
- return value of
- <citerefentry><refentrytitle>pam_get_item</refentrytitle><manvolnum>3</manvolnum></citerefentry>
- called with an <parameter>item_type</parameter> of
- <emphasis>PAM_TTY</emphasis> or, absent that,
- <emphasis>PAM_SERVICE</emphasis>).
+ keyword matches when the user connects without a network
+ connection (e.g., <emphasis>su</emphasis>,
+ <emphasis>login</emphasis>). A connection through the loopback
+ device (e.g., <command>ssh user@localhost</command>) is
+ considered a network connection, and thus, the
+ <emphasis>LOCAL</emphasis> keyword does not match.
</para>
<para>
--
2.47.0

@ -1,46 +1,62 @@
diff -up Linux-PAM-1.5.1/modules/pam_access/access.conf.5.xml.pam-access-resolve-ip Linux-PAM-1.5.1/modules/pam_access/access.conf.5.xml
--- Linux-PAM-1.5.1/modules/pam_access/access.conf.5.xml.pam-access-resolve-ip 2020-11-25 17:57:02.000000000 +0100
+++ Linux-PAM-1.5.1/modules/pam_access/access.conf.5.xml 2024-11-21 10:04:58.553127026 +0100
@@ -226,6 +226,14 @@
item and the line will be most probably ignored. For this reason, it is not
recommended to put spaces around the ':' characters.
From 940747f88c16e029b69a74e80a2e94f65cb3e628 Mon Sep 17 00:00:00 2001
From: Thorsten Kukuk <kukuk@suse.com>
Date: Thu, 14 Nov 2024 10:27:28 +0100
Subject: [PATCH] pam_access: rework resolving of tokens as hostname
* modules/pam_access/pam_access.c: separate resolving of IP addresses
from hostnames. Don't resolve TTYs or display variables as hostname
(#834).
Add "nodns" option to disallow resolving of tokens as hostname.
* modules/pam_access/pam_access.8.xml: document nodns option
* modules/pam_access/access.conf.5.xml: document that hostnames should
be written as FQHN.
---
modules/pam_access/access.conf.5.xml | 4 ++
modules/pam_access/pam_access.8.xml | 46 ++++++++++++------
modules/pam_access/pam_access.c | 72 +++++++++++++++++++++++++++-
3 files changed, 105 insertions(+), 17 deletions(-)
diff --git a/modules/pam_access/access.conf.5.xml b/modules/pam_access/access.conf.5.xml
index 0b93db00..10b8ba92 100644
--- a/modules/pam_access/access.conf.5.xml
+++ b/modules/pam_access/access.conf.5.xml
@@ -233,6 +233,10 @@
An IPv6 link local host address must contain the interface
identifier. IPv6 link local network/netmask is not supported.
</para>
+ <para>
+ An IPv6 link local host address must contain the interface
+ identifier. IPv6 link local network/netmask is not supported.
+ </para>
+ <para>
+ Hostnames should be written as Fully-Qualified Host Name (FQHN) to avoid
+ confusion with device names or PAM service names.
+ </para>
</refsect1>
<refsect1 id="access.conf-see_also">
diff -up Linux-PAM-1.5.1/modules/pam_access/pam_access.8.xml.pam-access-resolve-ip Linux-PAM-1.5.1/modules/pam_access/pam_access.8.xml
--- Linux-PAM-1.5.1/modules/pam_access/pam_access.8.xml.pam-access-resolve-ip 2020-11-25 17:57:02.000000000 +0100
+++ Linux-PAM-1.5.1/modules/pam_access/pam_access.8.xml 2024-11-21 10:04:58.553127026 +0100
@@ -25,11 +25,14 @@
<arg choice="opt">
<refsect1 xml:id="access.conf-see_also">
diff --git a/modules/pam_access/pam_access.8.xml b/modules/pam_access/pam_access.8.xml
index c991d7a0..71a4f7ee 100644
--- a/modules/pam_access/pam_access.8.xml
+++ b/modules/pam_access/pam_access.8.xml
@@ -22,11 +22,14 @@
<arg choice="opt" rep="norepeat">
debug
</arg>
+ <arg choice="opt" rep="norepeat">
+ noaudit
+ </arg>
<arg choice="opt">
<arg choice="opt" rep="norepeat">
nodefgroup
</arg>
- <arg choice="opt">
<arg choice="opt" rep="norepeat">
- noaudit
+ <arg choice="opt" rep="norepeat">
+ nodns
</arg>
<arg choice="opt">
accessfile=<replaceable>file</replaceable>
@@ -114,7 +117,46 @@
<arg choice="opt" rep="norepeat">
quiet_log
@@ -132,6 +135,33 @@
</listitem>
</varlistentry>
<varlistentry>
<term>
- <option>fieldsep=<replaceable>separators</replaceable></option>
+ <varlistentry>
+ <term>
+ nodefgroup
+ </term>
+ <listitem>
@ -66,32 +82,16 @@ diff -up Linux-PAM-1.5.1/modules/pam_access/pam_access.8.xml.pam-access-resolve-
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ quiet_log
+ </term>
+ <listitem>
+ <para>
+ Do not log denials with
+ <citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ fieldsep=separators
</term>
<listitem>
<para>
@@ -152,20 +194,6 @@
</para>
<varlistentry>
<term>
quiet_log
@@ -185,20 +215,6 @@
</listitem>
</varlistentry>
-
- <varlistentry>
- <term>
- <option>nodefgroup</option>
- nodefgroup
- </term>
- <listitem>
- <para>
@ -102,30 +102,41 @@ diff -up Linux-PAM-1.5.1/modules/pam_access/pam_access.8.xml.pam-access-resolve-
- </para>
- </listitem>
- </varlistentry>
-
</variablelist>
</refsect1>
diff -up Linux-PAM-1.5.1/modules/pam_access/pam_access.c.pam-access-resolve-ip Linux-PAM-1.5.1/modules/pam_access/pam_access.c
--- Linux-PAM-1.5.1/modules/pam_access/pam_access.c.pam-access-resolve-ip 2024-11-21 10:04:58.547127010 +0100
+++ Linux-PAM-1.5.1/modules/pam_access/pam_access.c 2024-11-21 10:04:58.553127026 +0100
@@ -92,6 +92,7 @@ struct login_info {
int debug; /* Print debugging messages. */
diff --git a/modules/pam_access/pam_access.c b/modules/pam_access/pam_access.c
index 48e7c7e9..109115e9 100644
--- a/modules/pam_access/pam_access.c
+++ b/modules/pam_access/pam_access.c
@@ -100,6 +100,7 @@ struct login_info {
int only_new_group_syntax; /* Only allow group entries of the form "(xyz)" */
int noaudit; /* Do not audit denials */
int quiet_log; /* Do not log denials */
+ int nodns; /* Do not try to resolve tokens as hostnames */
const char *fs; /* field separator */
const char *sep; /* list-element separator */
int from_remote_host; /* If PAM_RHOST was used for from */
@@ -143,6 +144,8 @@ parse_args(pam_handle_t *pamh, struct lo
loginfo->only_new_group_syntax = YES;
} else if (strcmp (argv[i], "noaudit") == 0) {
@@ -154,6 +155,8 @@ parse_args(pam_handle_t *pamh, struct login_info *loginfo,
loginfo->noaudit = YES;
} else if (strcmp (argv[i], "quiet_log") == 0) {
loginfo->quiet_log = YES;
+ } else if (strcmp (argv[i], "nodns") == 0) {
+ loginfo->nodns = YES;
} else {
pam_syslog(pamh, LOG_ERR, "unrecognized option [%s]", argv[i]);
}
@@ -700,6 +703,39 @@ string_match (pam_handle_t *pamh, const
@@ -820,7 +823,7 @@ remote_match (pam_handle_t *pamh, char *tok, struct login_info *item)
if ((str_len = strlen(string)) > tok_len
&& strcasecmp(tok, string + str_len - tok_len) == 0)
return YES;
- } else if (tok[tok_len - 1] == '.') { /* internet network numbers (end with ".") */
+ } else if (tok[tok_len - 1] == '.') { /* internet network numbers/subnet (end with ".") */
struct addrinfo hint;
memset (&hint, '\0', sizeof (hint));
@@ -895,6 +898,39 @@ string_match (pam_handle_t *pamh, const char *tok, const char *string,
}
@ -165,7 +176,7 @@ diff -up Linux-PAM-1.5.1/modules/pam_access/pam_access.c.pam-access-resolve-ip L
/* network_netmask_match - match a string against one token
* where string is a hostname or ip (v4,v6) address and tok
* represents either a hostname, a single ip (v4,v6) address
@@ -761,10 +797,42 @@ network_netmask_match (pam_handle_t *pam
@@ -956,10 +992,42 @@ network_netmask_match (pam_handle_t *pamh,
return NO;
}
}
@ -209,3 +220,6 @@ diff -up Linux-PAM-1.5.1/modules/pam_access/pam_access.c.pam-access-resolve-ip L
* Let getaddrinfo sort everything out
*/
if (getaddrinfo (tok, NULL, NULL, &ai) != 0)
--
2.47.0

@ -0,0 +1,86 @@
From aabd5314a6d76968c377969b49118a2df3f97003 Mon Sep 17 00:00:00 2001
From: "Dmitry V. Levin" <ldv@strace.io>
Date: Sun, 19 May 2024 15:00:00 +0000
Subject: [PATCH 1/2] pam_env: fix NULL dereference on error path in
econf_read_file
* modules/pam_env/pam_env.c [USE_ECONF] (econf_read_file): Handle NULL
value returned by econf_getStringValue().
Resolves: https://github.com/linux-pam/linux-pam/issues/796
---
modules/pam_env/pam_env.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/pam_env/pam_env.c b/modules/pam_env/pam_env.c
index 2cc58228..6d39bb24 100644
--- a/modules/pam_env/pam_env.c
+++ b/modules/pam_env/pam_env.c
@@ -287,7 +287,7 @@ econf_read_file(const pam_handle_t *pamh, const char *filename, const char *deli
char *val;
error = econf_getStringValue (key_file, NULL, keys[i], &val);
- if (error != ECONF_SUCCESS) {
+ if (error != ECONF_SUCCESS || val == NULL) {
pam_syslog(pamh, LOG_ERR, "Unable to get string from key %s: %s",
keys[i],
econf_errString(error));
--
2.45.1
From 75292685a625153c6e28bdd820e97421c258c04a Mon Sep 17 00:00:00 2001
From: "Dmitry V. Levin" <ldv@strace.io>
Date: Sun, 19 May 2024 15:00:00 +0000
Subject: [PATCH 2/2] pam_env: fix error handling in econf_read_file
* modules/pam_env/pam_env.c [USE_ECONF] (econf_read_file): Make sure
the returned array of strings is properly initialized
when econf_getStringValue() fails to return a value.
---
modules/pam_env/pam_env.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/modules/pam_env/pam_env.c b/modules/pam_env/pam_env.c
index 6d39bb24..7c146439 100644
--- a/modules/pam_env/pam_env.c
+++ b/modules/pam_env/pam_env.c
@@ -273,7 +273,7 @@ econf_read_file(const pam_handle_t *pamh, const char *filename, const char *deli
return PAM_ABORT;
}
- *lines = malloc((key_number +1)* sizeof(char**));
+ *lines = calloc((key_number + 1), sizeof(char**));
if (*lines == NULL) {
pam_syslog(pamh, LOG_ERR, "Cannot allocate memory.");
econf_free(keys);
@@ -281,8 +281,7 @@ econf_read_file(const pam_handle_t *pamh, const char *filename, const char *deli
return PAM_BUF_ERR;
}
- (*lines)[key_number] = 0;
-
+ size_t n = 0;
for (size_t i = 0; i < key_number; i++) {
char *val;
@@ -293,7 +292,7 @@ econf_read_file(const pam_handle_t *pamh, const char *filename, const char *deli
econf_errString(error));
} else {
econf_unescnl(val);
- if (asprintf(&(*lines)[i],"%s%c%s", keys[i], delim[0], val) < 0) {
+ if (asprintf(&(*lines)[n],"%s%c%s", keys[i], delim[0], val) < 0) {
pam_syslog(pamh, LOG_ERR, "Cannot allocate memory.");
econf_free(keys);
econf_freeFile(key_file);
@@ -303,6 +302,7 @@ econf_read_file(const pam_handle_t *pamh, const char *filename, const char *deli
return PAM_BUF_ERR;
}
free (val);
+ n++;
}
}
--
2.45.1

@ -0,0 +1,212 @@
From 5eccaf9b3488d3f6da800281363697e4e4834e77 Mon Sep 17 00:00:00 2001
From: Iker Pedrosa <ipedrosa@redhat.com>
Date: Wed, 22 May 2024 11:16:28 +0200
Subject: [PATCH 1/5] pam_faillock: close the audit socket after use
* modules/pam_faillock/pam_faillock.c (check_tally): Close the audit
socket when it will no longer be used.
```
Error: RESOURCE_LEAK (CWE-772):
Linux-PAM-1.6.0/modules/pam_faillock/pam_faillock.c:247: open_fn: Returning handle opened by "audit_open".
Linux-PAM-1.6.0/modules/pam_faillock/pam_faillock.c:247: var_assign: Assigning: "audit_fd" = handle returned from "audit_open()".
Linux-PAM-1.6.0/modules/pam_faillock/pam_faillock.c:256: noescape: Resource "audit_fd" is not freed or pointed-to in "audit_log_user_message".
Linux-PAM-1.6.0/modules/pam_faillock/pam_faillock.c:258: leaked_handle: Handle variable "audit_fd" going out of scope leaks the handle.
256| audit_log_user_message(audit_fd, AUDIT_RESP_ACCT_UNLOCK_TIMED, buf,
257| rhost, NULL, tty, 1);
258|-> }
259| #endif
260| opts->flags |= FAILLOCK_FLAG_UNLOCKED;
```
Resolves: https://issues.redhat.com/browse/RHEL-36475
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
---
modules/pam_faillock/pam_faillock.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/modules/pam_faillock/pam_faillock.c b/modules/pam_faillock/pam_faillock.c
index e636a24e..f39a9d95 100644
--- a/modules/pam_faillock/pam_faillock.c
+++ b/modules/pam_faillock/pam_faillock.c
@@ -255,6 +255,7 @@ check_tally(pam_handle_t *pamh, struct options *opts, struct tally_data *tallies
snprintf(buf, sizeof(buf), "op=pam_faillock suid=%u ", opts->uid);
audit_log_user_message(audit_fd, AUDIT_RESP_ACCT_UNLOCK_TIMED, buf,
rhost, NULL, tty, 1);
+ audit_close(audit_fd);
}
#endif
opts->flags |= FAILLOCK_FLAG_UNLOCKED;
--
2.45.2
From d00f6cb366b492de455f9b72fcbd2e49abf323e0 Mon Sep 17 00:00:00 2001
From: Iker Pedrosa <ipedrosa@redhat.com>
Date: Wed, 22 May 2024 11:20:02 +0200
Subject: [PATCH 2/5] pam_rootok: close the audit socket on error path
* modules/pam_rootok/pam_rootok.c (log_callback): Close the audit socket
if vasprintf returned an error.
```
Error: RESOURCE_LEAK (CWE-772):
Linux-PAM-1.6.0/modules/pam_rootok/pam_rootok.c:59: open_fn: Returning handle opened by "audit_open".
Linux-PAM-1.6.0/modules/pam_rootok/pam_rootok.c:59: var_assign: Assigning: "audit_fd" = handle returned from "audit_open()".
Linux-PAM-1.6.0/modules/pam_rootok/pam_rootok.c:69: leaked_handle: Handle variable "audit_fd" going out of scope leaks the handle.
67| va_end(ap);
68| if (ret < 0) {
69|-> return 0;
70| }
71| audit_log_user_avc_message(audit_fd, AUDIT_USER_AVC, buf, NULL, NULL,
```
Resolves: https://issues.redhat.com/browse/RHEL-36475
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
---
modules/pam_rootok/pam_rootok.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/modules/pam_rootok/pam_rootok.c b/modules/pam_rootok/pam_rootok.c
index 6d2dfa07..1b88fb19 100644
--- a/modules/pam_rootok/pam_rootok.c
+++ b/modules/pam_rootok/pam_rootok.c
@@ -66,6 +66,7 @@ log_callback (int type UNUSED, const char *fmt, ...)
ret = vasprintf (&buf, fmt, ap);
va_end(ap);
if (ret < 0) {
+ audit_close(audit_fd);
return 0;
}
audit_log_user_avc_message(audit_fd, AUDIT_USER_AVC, buf, NULL, NULL,
--
2.45.2
From 1ca5bfed50bd9f6c2f1e3e36c2df3253923dadf6 Mon Sep 17 00:00:00 2001
From: Iker Pedrosa <ipedrosa@redhat.com>
Date: Wed, 22 May 2024 12:27:00 +0200
Subject: [PATCH 3/5] pam_timestamp: close the timestamp file on error path
* modules/pam_timestamp/pam_timestamp.c (pam_sm_authenticate)
[WITH_OPENSSL]: Close the timestamp file if hmac_size returned
an error.
```
Error: RESOURCE_LEAK (CWE-772):
Linux-PAM-1.6.0/modules/pam_timestamp/pam_timestamp.c:450: open_fn: Returning handle opened by "open". [Note: The source code implementation of the function has been overridden by a user model.]
Linux-PAM-1.6.0/modules/pam_timestamp/pam_timestamp.c:450: var_assign: Assigning: "fd" = handle returned from "open(path, 131072)".
Linux-PAM-1.6.0/modules/pam_timestamp/pam_timestamp.c:460: noescape: Resource "fd" is not freed or pointed-to in "fstat".
Linux-PAM-1.6.0/modules/pam_timestamp/pam_timestamp.c:484: leaked_handle: Handle variable "fd" going out of scope leaks the handle.
482| #ifdef WITH_OPENSSL
483| if (hmac_size(pamh, debug, &maclen)) {
484|-> return PAM_AUTH_ERR;
485| }
486| #else
```
Resolves: https://issues.redhat.com/browse/RHEL-36475
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
---
modules/pam_timestamp/pam_timestamp.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/modules/pam_timestamp/pam_timestamp.c b/modules/pam_timestamp/pam_timestamp.c
index 7c5457c4..edecc052 100644
--- a/modules/pam_timestamp/pam_timestamp.c
+++ b/modules/pam_timestamp/pam_timestamp.c
@@ -481,6 +481,7 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv)
#ifdef WITH_OPENSSL
if (hmac_size(pamh, debug, &maclen)) {
+ close(fd);
return PAM_AUTH_ERR;
}
#else
--
2.45.2
From 667204d7e3e4a0341c529f7566d62dd64dd80866 Mon Sep 17 00:00:00 2001
From: Iker Pedrosa <ipedrosa@redhat.com>
Date: Wed, 22 May 2024 12:25:34 +0200
Subject: [PATCH 4/5] pam_namespace: free SELinux context
* modules/pam_namespace/pam_namespace.c [WITH_SELINUX] (form_context):
Free SELinux context before returning.
```
Error: RESOURCE_LEAK (CWE-772):
Linux-PAM-1.6.0/modules/pam_namespace/pam_namespace.c:928: alloc_arg: "getexeccon" allocates memory that is stored into "scon".
Linux-PAM-1.6.0/modules/pam_namespace/pam_namespace.c:1004: leaked_storage: Variable "scon" going out of scope leaks the storage it points to.
1002| }
1003| /* Should never get here */
1004|-> return PAM_SUCCESS;
1005| }
1006| #endif
```
Resolves: https://issues.redhat.com/browse/RHEL-36475
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
---
modules/pam_namespace/pam_namespace.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/modules/pam_namespace/pam_namespace.c b/modules/pam_namespace/pam_namespace.c
index e499d95a..781dac20 100644
--- a/modules/pam_namespace/pam_namespace.c
+++ b/modules/pam_namespace/pam_namespace.c
@@ -1003,6 +1003,7 @@ static int form_context(const struct polydir_s *polyptr,
return rc;
}
/* Should never get here */
+ freecon(scon);
return PAM_SUCCESS;
}
#endif
--
2.45.2
From bd2f695b3d89efe0c52bba975f9540634125178a Mon Sep 17 00:00:00 2001
From: Iker Pedrosa <ipedrosa@redhat.com>
Date: Wed, 22 May 2024 12:29:07 +0200
Subject: [PATCH 5/5] pam_namespace: free SELinux context on error path
* modules/pam_namespace/pam_namespace.c (create_polydir) [WITH_SELINUX]:
Free SELinux context in case of an error.
```
Error: RESOURCE_LEAK (CWE-772):
Linux-PAM-1.6.0/modules/pam_namespace/pam_namespace.c:1433: alloc_arg: "getfscreatecon_raw" allocates memory that is stored into "oldcon_raw".
Linux-PAM-1.6.0/modules/pam_namespace/pam_namespace.c:1462: leaked_storage: Variable "oldcon_raw" going out of scope leaks the storage it points to.
1460| pam_syslog(idata->pamh, LOG_ERR,
1461| "Error creating directory %s: %m", dir);
1462|-> return PAM_SESSION_ERR;
1463| }
1464|
```
Resolves: https://issues.redhat.com/browse/RHEL-36475
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
---
modules/pam_namespace/pam_namespace.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/modules/pam_namespace/pam_namespace.c b/modules/pam_namespace/pam_namespace.c
index 781dac20..2dab49ef 100644
--- a/modules/pam_namespace/pam_namespace.c
+++ b/modules/pam_namespace/pam_namespace.c
@@ -1462,6 +1462,9 @@ static int create_polydir(struct polydir_s *polyptr,
if (rc == -1) {
pam_syslog(idata->pamh, LOG_ERR,
"Error creating directory %s: %m", dir);
+#ifdef WITH_SELINUX
+ freecon(oldcon_raw);
+#endif
return PAM_SESSION_ERR;
}
--
2.45.2

@ -1,5 +1,3 @@
d /run/console 0755 root root -
d /run/faillock 0755 root root -
d /run/sepermit 0755 root root -
d /run/motd.d 0755 root root -
f /var/log/tallylog 0600 root root -

@ -1,18 +0,0 @@
#%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 sufficient pam_unix.so try_first_pass nullok
auth required pam_deny.so
account required pam_unix.so
password requisite pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type=
password sufficient pam_unix.so try_first_pass use_authtok nullok sha512 shadow
password required pam_deny.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

@ -1,8 +0,0 @@
#%PAM-1.0
# This file is auto-generated.
# User changes will be destroyed the next time authselect is run.
session optional pam_umask.so silent
session [success=1 default=ignore] pam_succeed_if.so service !~ gdm* service !~ su* quiet
session [default=1] pam_lastlog.so nowtmp showfailed
session optional pam_lastlog.so silent noupdate showfailed

@ -1,19 +0,0 @@
#%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

@ -1,18 +0,0 @@
#%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 sufficient pam_unix.so try_first_pass nullok
auth required pam_deny.so
account required pam_unix.so
password requisite pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type=
password sufficient pam_unix.so try_first_pass use_authtok nullok sha512 shadow
password required pam_deny.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

@ -1,121 +1,70 @@
%global pam_redhat_version 1.1.4
%global so_ver 0
%global pam_redhat_version 1.2.0
Summary: An extensible library which provides authentication for applications
Name: pam
Version: 1.5.1
Release: 22%{?dist}
Version: 1.6.1
Release: 7%{?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+.
License: BSD and GPLv2+
# pam_timestamp and pam_loginuid modules are GPLv2+.
License: BSD-3-Clause AND GPL-2.0-or-later
URL: http://www.linux-pam.org/
Source0: https://github.com/linux-pam/linux-pam/releases/download/v%{version}/Linux-PAM-%{version}.tar.xz
Source1: https://github.com/linux-pam/linux-pam/releases/download/v%{version}/Linux-PAM-%{version}.tar.xz.asc
Source2: https://releases.pagure.org/pam-redhat/pam-redhat-%{pam_redhat_version}.tar.bz2
Source2: https://releases.pagure.org/pam-redhat/pam-redhat-%{pam_redhat_version}.tar.xz
Source3: macros.%{name}
Source5: other.pamd
Source6: system-auth.pamd
Source7: password-auth.pamd
Source8: fingerprint-auth.pamd
Source9: smartcard-auth.pamd
Source10: config-util.pamd
Source11: dlopen.sh
Source12: system-auth.5
Source13: config-util.5
Source15: pamtmp.conf
Source16: postlogin.pamd
Source17: postlogin.5
Source18: https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
Patch1: pam-1.5.0-redhat-modules.patch
Patch2: pam-1.5.0-noflex.patch
Patch3: pam-1.3.0-unix-nomsg.patch
Patch4: pam-1.5.1-timestamp-openssl-hmac-authentication.patch
# https://github.com/linux-pam/linux-pam/commit/ec0e724fe53188c5c762c34ca9db6681c0de01b8
Patch5: pam-1.5.1-pam_filter_close_file_after_controlling_tty.patch
# https://github.com/linux-pam/linux-pam/commit/3234488f2c52a021eec87df1990d256314c21bff
Patch6: pam-1.5.1-pam-limits-unlimited-value.patch
# https://github.com/linux-pam/linux-pam/commit/a35e092e24ee7632346a0e1b4a203c04d4cd2c62
Patch7: pam-1.5.1-pam-keyinit-thread-safe.patch
# https://github.com/linux-pam/linux-pam/commit/9bcbe96d9e82a23d983c0618178a8dc25596ac2d
# https://github.com/linux-pam/linux-pam/commit/fc867a9e22eac2c9a0ed0577776bba4df21c9aad
Patch8: pam-1.5.1-faillock-load-conf-from-file.patch
# https://github.com/linux-pam/linux-pam/commit/370064ef6f99581b08d473a42bb3417d5dda3e4e
Patch9: pam-1.5.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
Patch10: pam-1.5.1-pam-pwhistory-load-conf-from-file.patch
# https://github.com/linux-pam/linux-pam/commit/40c271164dbcebfc5304d0537a42fb42e6b6803c
Patch11: pam-1.5.1-pam-lastlog-check-localtime_r-return-value.patch
# https://github.com/linux-pam/linux-pam/commit/bcbf145ce925934214e48200c27c9ff736452549
Patch12: pam-1.5.1-pam-faillock-clarify-missing-user.patch
# https://github.com/linux-pam/linux-pam/commit/10086bc69663fa819277af244eeb5b629a2403b8
Patch13: 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
Patch14: pam-1.5.1-pam-misc-configurable.patch
# https://github.com/linux-pam/linux-pam/commit/d6103b30050554d7b6ca6d55cb5b4ed3c9516663
Patch15: pam-1.5.1-libpam-close-range.patch
# https://github.com/linux-pam/linux-pam/commit/c85513220c1bd3150e39c6277422d29cfa44acc7
# https://github.com/linux-pam/linux-pam/commit/1648734a69c31e9ce834da70144ac9a453296807
Patch16: pam-1.5.1-audit-messages-formatting.patch
# https://github.com/linux-pam/linux-pam/commit/d54870f993e97fe75e2cd0470a3701d5af22877c
Patch17: pam-1.5.1-faillock-create-tallydir.patch
# https://github.com/linux-pam/linux-pam/commit/244b46908df930626535c0cd7c2867407fe8714a
# https://github.com/linux-pam/linux-pam/commit/f26d873435be9f35fa7953493cc07a9bc4e31876
Patch18: pam-1-5-1-libpam-getlogin.patch
# https://github.com/linux-pam/linux-pam/commit/23393bef92c1e768eda329813d7af55481c6ca9f
Patch19: pam-1.5.1-access-handle-hostnames.patch
# https://github.com/linux-pam/linux-pam/commit/031bb5a5d0d950253b68138b498dc93be69a64cb
Patch20: pam-1.5.1-namespace-protect-dir.patch
# https://github.com/linux-pam/linux-pam/commit/ec1fb9ddc6c252d8c61379e9385ca19c036fcb96
Patch21: pam-1.5.1-libpam-support-long-lines.patch
# https://github.com/linux-pam/linux-pam/commit/b3020da7da384d769f27a8713257fbe1001878be
# https://github.com/linux-pam/linux-pam/commit/8d0c575336ad301cd14e16ad2fdec6fe621764b8
Patch22: pam-1.5.1-pam-unix-shadow-password.patch
Patch1: pam-1.6.0-redhat-modules.patch
Patch2: pam-1.6.1-noflex.patch
Patch3: pam-1.5.3-unix-nomsg.patch
# https://github.com/linux-pam/linux-pam/commit/bd2f695b3d89efe0c52bba975f9540634125178a
Patch4: pam-1.6.1-sast-fixes.patch
# https://github.com/linux-pam/linux-pam/commit/aabd5314a6d76968c377969b49118a2df3f97003
Patch5: pam-1.6.1-pam-env-econf-read-file-fixes.patch
# https://github.com/linux-pam/linux-pam/commit/641dfd1084508c63f3590e93a35b80ffc50774e5
Patch6: pam-1.6.1-pam-access-local.patch
# https://github.com/linux-pam/linux-pam/commit/940747f88c16e029b69a74e80a2e94f65cb3e628
Patch23: pam-1.5.1-pam-access-resolve-ip.patch
Patch7: pam-1.6.1-pam-access-resolve-ip.patch
%global _pamlibdir %{_libdir}
%global _moduledir %{_libdir}/security
%global _secconfdir %{_sysconfdir}/security
%global _pamconfdir %{_sysconfdir}/pam.d
%global _pamvendordir %{_datadir}/pam.d
%global _systemdlibdir /usr/lib/systemd/system
%{load:%{SOURCE3}}
%if %{?WITH_SELINUX:0}%{!?WITH_SELINUX:1}
%global WITH_SELINUX 1
%endif
%if %{?WITH_AUDIT:0}%{!?WITH_AUDIT:1}
%global WITH_AUDIT 1
%endif
%global _performance_build 1
### Dependencies ###
Requires(meta): authselect >= 1.3
Requires: gdbm
Requires: libpwquality%{?_isa}
Requires: pam-libs%{?_isa} = %{version}-%{release}
Requires: setup
Requires: libpwquality >= 0.9.9
BuildRequires: make
BuildRequires: autoconf >= 2.60
BuildRequires: automake, libtool
BuildRequires: bison, flex, sed
BuildRequires: perl-interpreter, pkgconfig, gettext-devel
BuildRequires: libtirpc-devel
%if %{WITH_AUDIT}
BuildRequires: audit-libs-devel >= 1.0.8
Requires: audit-libs >= 1.0.8
%endif
%if %{WITH_SELINUX}
BuildRequires: libselinux-devel >= 1.33.2
Requires: libselinux >= 1.33.2
%endif
BuildRequires: libeconf-devel >= 0.3.5
Requires: libeconf >= 0.3.5
Requires: glibc >= 2.3.90-37
BuildRequires: libxcrypt-devel >= 4.3.3-2
BuildRequires: libdb-devel
# Following deps are necessary only to build the pam library documentation.
BuildRequires: linuxdoc-tools, elinks, libxslt
BuildRequires: docbook-style-xsl, docbook-dtds
BuildRequires: gcc
BuildRequires: openssl-devel >= 3.0.0
Requires: openssl >= 3.0.0
Suggests: libdb-convert-util
URL: http://www.linux-pam.org/
### Build Dependencies ###
BuildRequires: audit-libs-devel
BuildRequires: autoconf
BuildRequires: automake
BuildRequires: bison
BuildRequires: flex
BuildRequires: gcc
BuildRequires: gdbm-devel
BuildRequires: gettext-devel
BuildRequires: libeconf-devel
BuildRequires: libselinux-devel
BuildRequires: libtirpc-devel
BuildRequires: libtool
BuildRequires: libxcrypt-devel
BuildRequires: make
BuildRequires: openssl-devel
BuildRequires: perl-interpreter
BuildRequires: pkgconfig
BuildRequires: sed
BuildRequires: systemd
%description
PAM (Pluggable Authentication Modules) is a system security tool that
@ -124,7 +73,7 @@ having to recompile programs that handle authentication.
%package devel
Summary: Files needed for developing PAM-aware applications and modules for PAM
Requires: pam%{?_isa} = %{version}-%{release}
Requires: pam-libs%{?_isa} = %{version}-%{release}
%description devel
PAM (Pluggable Authentication Modules) is a system security tool that
@ -133,17 +82,37 @@ having to recompile programs that handle authentication. This package
contains header files used for building both PAM-aware applications
and modules for use with the PAM system.
%package docs
%package doc
Summary: Extra documentation for PAM.
Requires: pam%{?_isa} = %{version}-%{release}
%description docs
Requires: pam = %{version}-%{release}
Obsoletes: pam-docs < 1.5.2-6
Provides: pam-docs = %{version}-%{release}
BuildArch: noarch
BuildRequires: docbook5-schemas
BuildRequires: docbook5-style-xsl
BuildRequires: elinks
BuildRequires: libxslt
BuildRequires: linuxdoc-tools
%description doc
PAM (Pluggable Authentication Modules) is a system security tool that
allows system administrators to set authentication policy without
having to recompile programs that handle authentication. The pam-docs
having to recompile programs that handle authentication. The pam-doc
contains extra documentation for PAM. Currently, this includes additional
documentation in txt and html format.
%package libs
Summary: Shared libraries of the PAM package
# Make sure that if we don't try to upgrade -libs but not the
# main pam package and get file conflicts:
Conflicts: pam < 1.5.2-11
%description libs
PAM (Pluggable Authentication Modules) is a system security tool that
allows system administrators to set authentication policy without
having to recompile programs that handle authentication. The pam-libs
contains the shared libraries for PAM.
%prep
%setup -q -n Linux-PAM-%{version} -a 2
perl -pi -e "s/ppc64-\*/ppc64-\* \| ppc64p7-\*/" build-aux/config.sub
@ -154,121 +123,109 @@ mv pam-redhat-%{pam_redhat_version}/* modules
cp %{SOURCE18} .
%patch1 -p1 -b .redhat-modules
%patch2 -p1 -b .noflex
%patch3 -p1 -b .nomsg
%patch4 -p1 -b .timestamp-openssl-hmac-authentication
%patch5 -p1 -b .pam_filter_close_file_after_controlling_tty
%patch6 -p1 -b .pam-limits-unlimited-value
%patch7 -p1 -b .pam-keyinit-thread-safe
%patch8 -p1 -b .faillock-load-conf-from-file
%patch9 -p1 -b .pam-usertype-SYS_UID_MAX
%patch10 -p1 -b .pam-pwhistory-load-conf-from-file
%patch11 -p1 -b .pam-lastlog-check-localtime_r-return-value
%patch12 -p1 -b .pam-faillock-clarify-missing-user
%patch13 -p1 -b .pam-faillock-avoid-logging-erroneous
%patch14 -p1 -b .pam-misc-configurable
%patch15 -p1 -b .libpam-close-range
%patch16 -p1 -b .audit-messages-formatting
%patch17 -p1 -b .faillock-create-tallydir
%patch18 -p1 -b .libpam-getlogin
%patch19 -p1 -b .access-handle-hostnames
%patch20 -p1 -b .namespace-protect-dir
%patch21 -p1 -b .libpam-support-long-lines
%patch22 -p1 -b .pam-unix-shadow-password
%patch23 -p1 -b .pam-access-resolve-ip
%patch -P 1 -p1 -b .redhat-modules
%patch -P 2 -p1 -b .noflex
%patch -P 3 -p1 -b .nomsg
%patch -P 4 -p1 -b .sast-fixes
%patch -P 5 -p1 -b .pam-env-econf-read-file-fixes
%patch -P 6 -p1 -b .pam-access-local
%patch -P 7 -p1 -b .pam-access-resolve-ip
autoreconf -i
%build
%configure \
--disable-rpath \
--libdir=%{_pamlibdir} \
--includedir=%{_includedir}/security \
--enable-vendordir=%{_datadir} \
%if ! %{WITH_SELINUX}
--disable-selinux \
%endif
%if ! %{WITH_AUDIT}
--disable-audit \
%endif
--disable-static \
--disable-prelude \
--disable-nis \
--enable-openssl
make -C po update-gmo
make
# we do not use _smp_mflags because the build of sources in yacc/flex fails
--libdir=%{_pam_libdir} \
--includedir=%{_includedir}/security \
--disable-rpath \
--disable-static \
--disable-prelude \
--disable-nis \
--enable-audit \
--enable-openssl \
--enable-selinux \
--enable-lastlog \
--enable-db=gdbm
%make_build -C po update-gmo
%make_build
%install
mkdir -p doc/txts
for readme in modules/pam_*/README ; do
cp -f ${readme} doc/txts/README.`dirname ${readme} | sed -e 's|^modules/||'`
cp -f ${readme} doc/txts/README.`dirname ${readme} | sed -e 's|^modules/||'`
done
# Install the macros file
install -D -m 644 %{SOURCE3} %{buildroot}%{_rpmconfigdir}/macros.d/macros.%{name}
# Install the binaries, libraries, and modules.
make install DESTDIR=$RPM_BUILD_ROOT LDCONFIG=:
%make_install LDCONFIG=:
%if %{WITH_SELINUX}
# Temporary compat link
ln -sf pam_sepermit.so $RPM_BUILD_ROOT%{_moduledir}/pam_selinux_permit.so
%endif
ln -sf pam_sepermit.so %{buildroot}%{_pam_moduledir}/pam_selinux_permit.so
# RPM uses docs from source tree
rm -rf $RPM_BUILD_ROOT%{_datadir}/doc/Linux-PAM
rm -rf %{buildroot}%{_datadir}/doc/Linux-PAM
# Included in setup package
rm -f $RPM_BUILD_ROOT%{_sysconfdir}/environment
rm -f %{buildroot}%{_sysconfdir}/environment
# Install default configuration files.
install -d -m 755 $RPM_BUILD_ROOT%{_pamconfdir}
install -d -m 755 $RPM_BUILD_ROOT%{_pamvendordir}
install -m 644 %{SOURCE5} $RPM_BUILD_ROOT%{_pamconfdir}/other
install -m 644 %{SOURCE6} $RPM_BUILD_ROOT%{_pamconfdir}/system-auth
install -m 644 %{SOURCE7} $RPM_BUILD_ROOT%{_pamconfdir}/password-auth
install -m 644 %{SOURCE8} $RPM_BUILD_ROOT%{_pamconfdir}/fingerprint-auth
install -m 644 %{SOURCE9} $RPM_BUILD_ROOT%{_pamconfdir}/smartcard-auth
install -m 644 %{SOURCE10} $RPM_BUILD_ROOT%{_pamconfdir}/config-util
install -m 644 %{SOURCE16} $RPM_BUILD_ROOT%{_pamconfdir}/postlogin
install -m 600 /dev/null $RPM_BUILD_ROOT%{_secconfdir}/opasswd
install -d -m 755 $RPM_BUILD_ROOT/var/log
install -d -m 755 $RPM_BUILD_ROOT/var/run/faillock
install -d -m 755 $RPM_BUILD_ROOT%{_sysconfdir}/motd.d
install -d -m 755 $RPM_BUILD_ROOT/usr/lib/motd.d
install -d -m 755 $RPM_BUILD_ROOT/run/motd.d
install -d -m 755 %{buildroot}%{_pam_confdir}
install -d -m 755 %{buildroot}%{_pam_vendordir}
install -m 644 %{SOURCE5} %{buildroot}%{_pam_confdir}/other
install -m 644 %{SOURCE10} %{buildroot}%{_pam_confdir}/config-util
install -m 600 /dev/null %{buildroot}%{_pam_secconfdir}/opasswd
install -d -m 755 %{buildroot}/var/log
install -d -m 755 %{buildroot}/var/run/faillock
# Install man pages.
install -m 644 %{SOURCE12} %{SOURCE13} %{SOURCE17} $RPM_BUILD_ROOT%{_mandir}/man5/
ln -sf system-auth.5 $RPM_BUILD_ROOT%{_mandir}/man5/password-auth.5
ln -sf system-auth.5 $RPM_BUILD_ROOT%{_mandir}/man5/fingerprint-auth.5
ln -sf system-auth.5 $RPM_BUILD_ROOT%{_mandir}/man5/smartcard-auth.5
install -m 644 %{SOURCE12} %{SOURCE13} %{SOURCE17} %{buildroot}%{_mandir}/man5/
ln -sf system-auth.5 %{buildroot}%{_mandir}/man5/password-auth.5
ln -sf system-auth.5 %{buildroot}%{_mandir}/man5/fingerprint-auth.5
ln -sf system-auth.5 %{buildroot}%{_mandir}/man5/smartcard-auth.5
for phase in auth acct passwd session ; do
ln -sf pam_unix.so $RPM_BUILD_ROOT%{_moduledir}/pam_unix_${phase}.so
ln -sf pam_unix.so %{buildroot}%{_pam_moduledir}/pam_unix_${phase}.so
done
# Remove .la files and make new .so links -- this depends on the value
# of _libdir not changing, and *not* being /usr/lib.
for lib in libpam libpamc libpam_misc ; do
rm -f $RPM_BUILD_ROOT%{_pamlibdir}/${lib}.la
rm -f %{buildroot}%{_pam_libdir}/${lib}.la
done
rm -f $RPM_BUILD_ROOT%{_moduledir}/*.la
rm -f %{buildroot}%{_pam_moduledir}/*.la
%if "%{_pamlibdir}" != "%{_libdir}"
install -d -m 755 $RPM_BUILD_ROOT%{_libdir}
%if "%{_pam_libdir}" != "%{_libdir}"
install -d -m 755 %{buildroot}%{_libdir}
for lib in libpam libpamc libpam_misc ; do
pushd $RPM_BUILD_ROOT%{_libdir}
ln -sf %{_pamlibdir}/${lib}.so.*.* ${lib}.so
popd
rm -f $RPM_BUILD_ROOT%{_pamlibdir}/${lib}.so
pushd %{buildroot}%{_libdir}
ln -sf %{_pam_libdir}/${lib}.so.*.* ${lib}.so
popd
rm -f %{buildroot}%{_pam_libdir}/${lib}.so
done
%endif
# Duplicate doc file sets.
rm -fr $RPM_BUILD_ROOT/usr/share/doc/pam
rm -fr %{buildroot}/usr/share/doc/pam
# Install the file for autocreation of /var/run subdirectories on boot
install -m644 -D %{SOURCE15} $RPM_BUILD_ROOT%{_prefix}/lib/tmpfiles.d/pam.conf
install -m644 -D %{SOURCE15} %{buildroot}%{_prefix}/lib/tmpfiles.d/pam.conf
# Install systemd unit file.
install -m644 -D modules/pam_namespace/pam_namespace.service \
%{buildroot}%{_unitdir}/pam_namespace.service
# Install doc files to unified location.
install -d -m 755 %{buildroot}%{_pkgdocdir}/{adg/html,mwg/html,sag/html,txts}
install -p -m 644 doc/specs/rfc86.0.txt %{buildroot}%{_pkgdocdir}
install -p -m 644 doc/txts/* %{buildroot}%{_pkgdocdir}/txts
for i in adg mwg sag; do
install -p -m 644 doc/$i/*.txt %{buildroot}%{_pkgdocdir}/$i
cp -pr doc/$i/html/* %{buildroot}%{_pkgdocdir}/$i/html
done
find %{buildroot}%{_pkgdocdir} -type d | xargs chmod 755
find %{buildroot}%{_pkgdocdir} -type f | xargs chmod 644
%find_lang Linux-PAM
@ -276,50 +233,35 @@ install -m644 -D %{SOURCE15} $RPM_BUILD_ROOT%{_prefix}/lib/tmpfiles.d/pam.conf
# Make sure every module subdirectory gave us a module. Yes, this is hackish.
for dir in modules/pam_* ; do
if [ -d ${dir} ] ; then
%if ! %{WITH_SELINUX}
[ ${dir} = "modules/pam_selinux" ] && continue
[ ${dir} = "modules/pam_sepermit" ] && continue
%endif
%if ! %{WITH_AUDIT}
[ ${dir} = "modules/pam_tty_audit" ] && continue
%endif
if ! ls -1 $RPM_BUILD_ROOT%{_moduledir}/`basename ${dir}`*.so ; then
echo ERROR `basename ${dir}` did not build a module.
exit 1
fi
[ ${dir} = "modules/pam_selinux" ] && continue
[ ${dir} = "modules/pam_sepermit" ] && continue
[ ${dir} = "modules/pam_tty_audit" ] && continue
if ! ls -1 %{buildroot}%{_pam_moduledir}/`basename ${dir}`*.so ; then
echo ERROR `basename ${dir}` did not build a module.
exit 1
fi
fi
done
# Check for module problems. Specifically, check that every module we just
# installed can actually be loaded by a minimal PAM-aware application.
/sbin/ldconfig -n $RPM_BUILD_ROOT%{_pamlibdir}
for module in $RPM_BUILD_ROOT%{_moduledir}/pam*.so ; do
if ! env LD_LIBRARY_PATH=$RPM_BUILD_ROOT%{_pamlibdir} \
%{SOURCE11} -ldl -lpam -L$RPM_BUILD_ROOT%{_libdir} ${module} ; then
echo ERROR module: ${module} cannot be loaded.
exit 1
fi
/sbin/ldconfig -n %{buildroot}%{_pam_libdir}
for module in %{buildroot}%{_pam_moduledir}/pam*.so ; do
if ! env LD_LIBRARY_PATH=%{buildroot}%{_pam_libdir} \
%{SOURCE11} -ldl -lpam -L%{buildroot}%{_libdir} ${module} ; then
echo ERROR module: ${module} cannot be loaded.
exit 1
fi
done
%ldconfig_scriptlets
%files -f Linux-PAM.lang
%dir %{_pamconfdir}
%dir %{_pamvendordir}
%config(noreplace) %{_pamconfdir}/other
%config(noreplace) %{_pamconfdir}/system-auth
%config(noreplace) %{_pamconfdir}/password-auth
%config(noreplace) %{_pamconfdir}/fingerprint-auth
%config(noreplace) %{_pamconfdir}/smartcard-auth
%config(noreplace) %{_pamconfdir}/config-util
%config(noreplace) %{_pamconfdir}/postlogin
%{!?_licensedir:%global license %%doc}
%license Copyright
%license gpl-2.0.txt
%{_pamlibdir}/libpam.so.*
%{_pamlibdir}/libpamc.so.*
%{_pamlibdir}/libpam_misc.so.*
%{_sbindir}/pam_console_apply
%dir %{_pam_confdir}
%dir %{_pam_vendordir}
%config(noreplace) %{_pam_confdir}/other
%config(noreplace) %{_pam_confdir}/config-util
%{_rpmconfigdir}/macros.d/macros.%{name}
%{_sbindir}/pam_namespace_helper
%{_sbindir}/faillock
%attr(4755,root,root) %{_sbindir}/pam_timestamp_check
@ -327,175 +269,265 @@ done
%attr(0700,root,root) %{_sbindir}/unix_update
%attr(0755,root,root) %{_sbindir}/mkhomedir_helper
%attr(0755,root,root) %{_sbindir}/pwhistory_helper
%dir %{_moduledir}
%{_moduledir}/pam_access.so
%{_moduledir}/pam_chroot.so
%{_moduledir}/pam_console.so
%{_moduledir}/pam_debug.so
%{_moduledir}/pam_deny.so
%{_moduledir}/pam_echo.so
%{_moduledir}/pam_env.so
%{_moduledir}/pam_exec.so
%{_moduledir}/pam_faildelay.so
%{_moduledir}/pam_faillock.so
%{_moduledir}/pam_filter.so
%{_moduledir}/pam_ftp.so
%{_moduledir}/pam_group.so
%{_moduledir}/pam_issue.so
%{_moduledir}/pam_keyinit.so
%{_moduledir}/pam_lastlog.so
%{_moduledir}/pam_limits.so
%{_moduledir}/pam_listfile.so
%{_moduledir}/pam_localuser.so
%{_moduledir}/pam_loginuid.so
%{_moduledir}/pam_mail.so
%{_moduledir}/pam_mkhomedir.so
%{_moduledir}/pam_motd.so
%{_moduledir}/pam_namespace.so
%{_moduledir}/pam_nologin.so
%{_moduledir}/pam_permit.so
%{_moduledir}/pam_postgresok.so
%{_moduledir}/pam_pwhistory.so
%{_moduledir}/pam_rhosts.so
%{_moduledir}/pam_rootok.so
%if %{WITH_SELINUX}
%{_moduledir}/pam_selinux.so
%{_moduledir}/pam_selinux_permit.so
%{_moduledir}/pam_sepermit.so
%endif
%{_moduledir}/pam_securetty.so
%{_moduledir}/pam_setquota.so
%{_moduledir}/pam_shells.so
%{_moduledir}/pam_stress.so
%{_moduledir}/pam_succeed_if.so
%{_moduledir}/pam_time.so
%{_moduledir}/pam_timestamp.so
%if %{WITH_AUDIT}
%{_moduledir}/pam_tty_audit.so
%endif
%{_moduledir}/pam_umask.so
%{_moduledir}/pam_unix.so
%{_moduledir}/pam_unix_acct.so
%{_moduledir}/pam_unix_auth.so
%{_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
%{_moduledir}/pam_filter
%{_systemdlibdir}/pam_namespace.service
%dir %{_secconfdir}
%config(noreplace) %{_secconfdir}/access.conf
%config(noreplace) %{_secconfdir}/chroot.conf
%config %{_secconfdir}/console.perms
%config(noreplace) %{_secconfdir}/console.handlers
%config(noreplace) %{_secconfdir}/faillock.conf
%config(noreplace) %{_secconfdir}/group.conf
%config(noreplace) %{_secconfdir}/limits.conf
%dir %{_secconfdir}/limits.d
%config(noreplace) %{_secconfdir}/namespace.conf
%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
%dir %{_secconfdir}/console.perms.d
%dir /var/run/console
%if %{WITH_SELINUX}
%config(noreplace) %{_secconfdir}/sepermit.conf
%dir %{_pam_moduledir}
%{_pam_moduledir}/pam_access.so
%{_pam_moduledir}/pam_canonicalize_user.so
%{_pam_moduledir}/pam_chroot.so
%{_pam_moduledir}/pam_debug.so
%{_pam_moduledir}/pam_deny.so
%{_pam_moduledir}/pam_echo.so
%{_pam_moduledir}/pam_env.so
%{_pam_moduledir}/pam_exec.so
%{_pam_moduledir}/pam_faildelay.so
%{_pam_moduledir}/pam_faillock.so
%{_pam_moduledir}/pam_filter.so
%{_pam_moduledir}/pam_ftp.so
%{_pam_moduledir}/pam_group.so
%{_pam_moduledir}/pam_issue.so
%{_pam_moduledir}/pam_keyinit.so
%{_pam_moduledir}/pam_lastlog.so
%{_pam_moduledir}/pam_limits.so
%{_pam_moduledir}/pam_listfile.so
%{_pam_moduledir}/pam_localuser.so
%{_pam_moduledir}/pam_loginuid.so
%{_pam_moduledir}/pam_mail.so
%{_pam_moduledir}/pam_mkhomedir.so
%{_pam_moduledir}/pam_motd.so
%{_pam_moduledir}/pam_namespace.so
%{_pam_moduledir}/pam_nologin.so
%{_pam_moduledir}/pam_permit.so
%{_pam_moduledir}/pam_postgresok.so
%{_pam_moduledir}/pam_pwhistory.so
%{_pam_moduledir}/pam_rhosts.so
%{_pam_moduledir}/pam_rootok.so
%{_pam_moduledir}/pam_selinux.so
%{_pam_moduledir}/pam_selinux_permit.so
%{_pam_moduledir}/pam_sepermit.so
%{_pam_moduledir}/pam_securetty.so
%{_pam_moduledir}/pam_setquota.so
%{_pam_moduledir}/pam_shells.so
%{_pam_moduledir}/pam_stress.so
%{_pam_moduledir}/pam_succeed_if.so
%{_pam_moduledir}/pam_time.so
%{_pam_moduledir}/pam_timestamp.so
%{_pam_moduledir}/pam_tty_audit.so
%{_pam_moduledir}/pam_umask.so
%{_pam_moduledir}/pam_unix.so
%{_pam_moduledir}/pam_unix_acct.so
%{_pam_moduledir}/pam_unix_auth.so
%{_pam_moduledir}/pam_unix_passwd.so
%{_pam_moduledir}/pam_unix_session.so
%{_pam_moduledir}/pam_userdb.so
%{_pam_moduledir}/pam_usertype.so
%{_pam_moduledir}/pam_warn.so
%{_pam_moduledir}/pam_wheel.so
%{_pam_moduledir}/pam_xauth.so
%{_pam_moduledir}/pam_filter
%{_unitdir}/pam_namespace.service
%dir %{_pam_secconfdir}
%config(noreplace) %{_pam_secconfdir}/access.conf
%config(noreplace) %{_pam_secconfdir}/chroot.conf
%config(noreplace) %{_pam_secconfdir}/faillock.conf
%config(noreplace) %{_pam_secconfdir}/group.conf
%config(noreplace) %{_pam_secconfdir}/limits.conf
%dir %{_pam_secconfdir}/limits.d
%config(noreplace) %{_pam_secconfdir}/namespace.conf
%dir %{_pam_secconfdir}/namespace.d
%attr(755,root,root) %config(noreplace) %{_pam_secconfdir}/namespace.init
%config(noreplace) %{_pam_secconfdir}/pam_env.conf
%config(noreplace) %{_pam_secconfdir}/pwhistory.conf
%config(noreplace) %{_pam_secconfdir}/time.conf
%config(noreplace) %{_pam_secconfdir}/opasswd
%config(noreplace) %{_pam_secconfdir}/sepermit.conf
%dir /var/run/sepermit
%endif
%dir /var/run/faillock
%dir %{_sysconfdir}/motd.d
%dir /run/motd.d
%dir /usr/lib/motd.d
%{_prefix}/lib/tmpfiles.d/pam.conf
%{_mandir}/man5/*
%{_mandir}/man8/*
%files devel
%dir %{_pkgdocdir}
%doc %{_pkgdocdir}/rfc86.0.txt
%{_includedir}/security
%{_mandir}/man3/*
%{_libdir}/libpam.so
%{_libdir}/libpamc.so
%{_libdir}/libpam_misc.so
%doc doc/mwg/*.txt doc/mwg/html
%doc doc/adg/*.txt doc/adg/html
%doc doc/specs/rfc86.0.txt
%{_libdir}/pkgconfig/pam.pc
%{_libdir}/pkgconfig/pam_misc.pc
%{_libdir}/pkgconfig/pamc.pc
%files docs
%doc doc/txts
%doc doc/sag/*.txt doc/sag/html
%files doc
%doc %{_pkgdocdir}
%files libs
%license Copyright
%license gpl-2.0.txt
%{_pam_libdir}/libpam.so.%{so_ver}*
%{_pam_libdir}/libpamc.so.%{so_ver}*
%{_pam_libdir}/libpam_misc.so.%{so_ver}*
%changelog
* Thu Nov 21 2024 Iker Pedrosa <ipedrosa@redhat.com> - 1.5.1-22
* Thu Nov 21 2024 Iker Pedrosa <ipedrosa@redhat.com> - 1.6.1-7
- pam_access: rework resolving of tokens as hostname.
Resolves: CVE-2024-10963 and RHEL-66245
Resolves: CVE-2024-10963 and RHEL-66241
* Mon Nov 4 2024 Iker Pedrosa <ipedrosa@redhat.com> - 1.6.1-6
- pam_access: always match local address and clarify LOCAL keyword behaviour.
Resolves: RHEL-65223
* Tue Oct 29 2024 Troy Dawson <tdawson@redhat.com>
- Bump release for October 2024 mass rebuild:
Resolves: RHEL-64018
* Fri Aug 30 2024 Iker Pedrosa <ipedrosa@redhat.com> - 1.6.1-4
- spec: Use Requires(meta): authselect. Resolves: RHEL-56703
* Mon Jun 24 2024 Troy Dawson <tdawson@redhat.com>
- Bump release for June 2024 mass rebuild
* Tue Jun 18 2024 Iker Pedrosa <ipedrosa@redhat.com> - 1.6.1-2
- Fix static analyzer detected issues. Resolves: RHEL-36475
- pam_env: fixes for NULL environment variables
* Wed Apr 10 2024 Iker Pedrosa <ipedrosa@redhat.com> - 1.6.1-1
- Rebase to release 1.6.1
- Disable nis support
* Thu Feb 15 2024 Iker Pedrosa <ipedrosa@redhat.com> - 1.6.0-2
- pam_unix: do not warn if password aging is disabled (#2263689)
* Tue Jan 23 2024 Iker Pedrosa <ipedrosa@redhat.com> - 1.6.0-1
- Rebase to release 1.6.0
Resolves: #2258964
* Sun Jan 21 2024 Fedora Release Engineering <releng@fedoraproject.org>
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
* Mon Dec 18 2023 Ding-Yi Chen <dchen@redhat.com> - 1.5.3-9
- pam.conf: Remove tallylog (#2253817)
* Tue Nov 21 2023 Iker Pedrosa <ipedrosa@redhat.com> - 1.5.3-8
- Suggest libdb-convert-util (#2245149 and #1788543)
* Tue Nov 7 2023 Iker Pedrosa <ipedrosa@redhat.com> - 1.5.3-7
- Include openssl-devel build dependency
* Wed Nov 6 2024 Diaa Sami <disami@redhat.com> - 1.5.1-21
- pam_unix: always run the helper to obtain shadow password file entries.
CVE-2024-10041. Resolves: RHEL-62880
* Fri Nov 3 2023 Iker Pedrosa <ipedrosa@redhat.com> - 1.5.3-6
- Drop explicit dependencies (#2247250)
* Tue Jun 18 2024 Iker Pedrosa <ipedrosa@redhat.com> - 1.5.1-20
- libpam: support long lines in service files. Resolves: RHEL-40705
* Mon Oct 30 2023 Iker Pedrosa <ipedrosa@redhat.com> - 1.5.3-5
- Explicitly state package dependencies and reorganize them
* Mon Feb 12 2024 Iker Pedrosa <ipedrosa@redhat.com> - 1.5.1-19
- pam_namespace: protect_dir(): use O_DIRECTORY to prevent local DoS
situations. CVE-2024-22365. Resolves: RHEL-21244
* Mon Oct 23 2023 Iker Pedrosa <ipedrosa@redhat.com> - 1.5.2-4
- Switch pam_userdb from BerkeleyDB to GDBM (#2245149 and #1788543)
* Fri Jan 26 2024 Iker Pedrosa <ipedrosa@redhat.com> - 1.5.1-18
- libpam: use getlogin() from libc and not utmp. Resolves: RHEL-16727
- pam_access: handle hostnames in access.conf. Resolves: RHEL-22300
* Thu Oct 19 2023 Iker Pedrosa <ipedrosa@redhat.com> - 1.5.3-3
- pam_pwhistory: fix passing NULL filename argument to pwhistory helper
* Mon Jan 8 2024 Iker Pedrosa <ipedrosa@redhat.com> - 1.5.1-17
- pam_faillock: create tallydir before creating tallyfile. Resolves: RHEL-20943
* Thu Jul 20 2023 Fedora Release Engineering <releng@fedoraproject.org>
- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
* Fri Nov 10 2023 Iker Pedrosa <ipedrosa@redhat.com> - 1.5.1-16
- libpam: use close_range() to close file descriptors. Resolves: RHEL-5099
- fix formatting of audit messages. Resolves: RHEL-5100
* Fri May 19 2023 Björn Esser <besser82@fedoraproject.org> - 1.5.3-1
- Rebase to release 1.5.3
Resolves: #2196709
- Drop pam-1.5.2-pwhistory-config.patch and pam-1.5.2-configure-c99.patch,
as those patches are implemented upstream
- Realign left-over patches
- Update build requirements for documentation (docbook5)
- Remove --enable-vendordir from configuration
- Enable (deprecated) pam_lastlog module
* Mon Jun 26 2023 Iker Pedrosa <ipedrosa@redhat.com> - 1.5.1-15
- pam_misc: make length of misc_conv() configurable and set to 4096. Resolves: #2215007
* Tue Apr 25 2023 Björn Esser <besser82@fedoraproject.org> - 1.5.2-19
- Replace deprecated '%%patchN' with '%%patch -P N'
* Tue Nov 29 2022 Iker Pedrosa <ipedrosa@redhat.com> - 1.5.1-14
- pam_lastlog: check localtime_r() return value. Resolves: #2130124
- pam_faillock: clarify missing user faillock files after reboot. Resolves: #2126632
- pam_faillock: avoid logging an erroneous consecutive login failure message. Resolves: #2126648
* Tue Apr 25 2023 Arjun Shankar <arjun@redhat.com> - 1.5.2-18
- Port configure script to C99
* Wed Sep 28 2022 Iker Pedrosa <ipedrosa@redhat.com> - 1.5.1-13
- pam_pwhistory: load configuration from file. Resolves: #2126640
* Thu Feb 9 2023 Iker Pedrosa <ipedrosa@redhat.com> - 1.5.2-17
- Remove pam_console (#2166692)
- Rebase to pam-redhat-1.2.0
* Thu Jun 23 2022 Iker Pedrosa <ipedrosa@redhat.com> - 1.5.1-12
- pam_usertype: only use SYS_UID_MAX for system users. Resolves: #2078421
* Thu Jan 19 2023 Fedora Release Engineering <releng@fedoraproject.org>
- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild
* Wed May 25 2022 Iker Pedrosa <ipedrosa@redhat.com> - 1.5.1-11
- faillock: load configuration from file. Resolves: #2061698
* Mon Dec 19 2022 Iker Pedrosa <ipedrosa@redhat.com> - 1.5.2-15
- SPDX license migration
* Tue May 17 2022 Iker Pedrosa <ipedrosa@redhat.com> - 1.5.1-10
- pam_keyinit: thread-safe implementation. Resolves: #2061696
* Fri Jul 22 2022 Fedora Release Engineering <releng@fedoraproject.org>
- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild
* Thu Dec 2 2021 Iker Pedrosa <ipedrosa@redhat.com> - 1.5.1-9
- pam_limits: "Unlimited" is not a valid value for RLIMIT_NOFILE. Resolves: #1989900
* Mon Jul 18 2022 Iker Pedrosa <ipedrosa@redhat.com> - 1.5.2-13
- pam_pwhistory: load config from file
* Mon Aug 09 2021 Mohan Boddu <mboddu@redhat.com> - 1.5.1-8
- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
Related: rhbz#1991688
* Sun Feb 27 2022 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 1.5.2-12
- Add Conflicts for pam version before the split
* Wed Jul 14 2021 Iker Pedrosa <ipedrosa@redhat.com> - 1.5.1-7
* Thu Feb 17 2022 Björn Esser <besser82@fedoraproject.org> - 1.5.2-11
- Split shared libraries into pam-libs package (#2055572)
* Thu Jan 20 2022 Fedora Release Engineering <releng@fedoraproject.org>
- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild
* Mon Jan 10 2022 Ondrej Mosnacek <omosnace@redhat.com> - 1.5.2-9
- Remove conflicting ownership of motd.d directories
* Tue Nov 16 2021 Pavel Březina <pbrezina@redhat.com> - 1.5.2-8
- systemd-auth, smartcard-auth, fingerprint-auth, password-auth and postlogin are now owned by authselect (#2023738)
* Fri Nov 12 2021 Björn Esser <besser82@fedoraproject.org> - 1.5.2-7
- Rebuild(libnsl2)
* Wed Oct 06 2021 Björn Esser <besser82@fedoraproject.org> - 1.5.2-6
- Remove old cruft from spec file
- Rename docs sub-package to doc
- Replace $RPM_BUILD_ROOT with %%{buildroot}
- Move documentation to %%{_pkgdocdir}
- Constantly use spaces for indentation
* Thu Sep 23 2021 Björn Esser <besser82@fedoraproject.org> - 1.5.2-5
- Rebase to pam-redhat-1.1.5
- Drop explicit dependency on openssl, as auto-deps will pull it in
- Conditionalize BR: openssl >= 3.0.0 to supported distributions
* Thu Sep 23 2021 Iker Pedrosa <ipedrosa@redhat.com> - 1.5.2-4
- Remove the /etc/motd.d directory to exclude its ownership from pam (#1968131)
- pam_timestamp: enable openssl hmac authentication on supported
distributions (Fedora >= 36 and RHEL >= 9) (#1947294)
- Clean spec file: organize dependencies and move URL location
* Thu Sep 23 2021 Björn Esser <besser82@fedoraproject.org> - 1.5.2-3
- Update patch for parallel build
* Wed Sep 22 2021 Björn Esser <besser82@fedoraproject.org> - 1.5.2-2
- Add a patch to fix parallel builds with autgenerated sources
* Sat Sep 04 2021 Björn Esser <besser82@fedoraproject.org> - 1.5.2-1
- Rebase to release 1.5.2
Resolves: #2001208
- Add so_ver macro to avoid accidental soname bumps
- Add a patch to fix a missing header include in pam_console
* Thu Jul 22 2021 Iker Pedrosa <ipedrosa@redhat.com> - 1.5.1-9
- Add macros file to allow other packages to stop hardcoding directory names
* Fri Jul 9 2021 Iker Pedrosa <ipedrosa@redhat.com> - 1.5.1-8
- Fix issues detected by covscan tool
* Fri Jul 2 2021 Iker Pedrosa <ipedrosa@redhat.com> - 1.5.1-6
- pam_timestamp: openssl hmac authentication. Resolves: #1934975
* Thu Jun 10 2021 Björn Esser <besser82@fedoraproject.org> - 1.5.1-7
- Change the default password hash method to yescrypt
* Thu Jun 10 2021 Björn Esser <besser82@fedoraproject.org> - 1.5.1-6
- Add a patch to not use crypt_checksalt for password expiration
Resolves: #1965345, #1967150
* Mon Apr 19 2021 Iker Pedrosa <ipedrosa@redhat.com> - 1.5.1-5
- Disable nis support. Resolves: #1942373
* Fri Apr 16 2021 Benjamin Berg <bberg@redhat.com> - 1.5.1-5
- Add script to avoid fingerprint-auth issues for long term Fedora users
Resolves: #1942443
* Fri Apr 16 2021 Mohan Boddu <mboddu@redhat.com> - 1.5.1-4
- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937
* Mon Apr 12 2021 Iker Pedrosa <ipedrosa@redhat.com> - 1.5.1-4
- Change fingerprint-auth.pamd to return PAM_AUTHINFO_UNAVAIL from pam_fprintd.so
- Clean auto-generated message from pam stack files
* Tue Jan 26 2021 Fedora Release Engineering <releng@fedoraproject.org> - 1.5.1-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
@ -1351,12 +1383,12 @@ support)
- pam_unix: always honor nis flag on password change (by Aaron Hope)
* Wed Aug 24 2005 Tomas Mraz <tmraz@redhat.com> 0.80-7
- don't fail in audit code when audit is not compiled in
- don't fail in audit code when audit is not compiled in
on the newest kernels (#166422)
* Mon Aug 01 2005 Tomas Mraz <tmraz@redhat.com> 0.80-6
- add option to pam_loginuid to require auditd
* Fri Jul 29 2005 Tomas Mraz <tmraz@redhat.com> 0.80-5
- fix NULL dereference in pam_userdb (#164418)
@ -1491,17 +1523,17 @@ support)
* Tue Oct 19 2004 Tomas Mraz <tmraz@redhat.com> 0.77-63
- Fix checking of group %%group syntax in pam_limits
- Drop fencepost patch as it was already fixed
- Drop fencepost patch as it was already fixed
by upstream change from 0.75 to 0.77
- Fix brokenshadow patch
* Mon Oct 11 2004 Tomas Mraz <tmraz@redhat.com> 0.77-62
- Added bluetooth, raw1394 and flash to console.perms
- pam_console manpage fix
- pam_console manpage fix
* Mon Oct 11 2004 Tomas Mraz <tmraz@redhat.com> 0.77-61
- #129328 pam_env shouldn't abort on missing /etc/environment
- #126985 pam_stack should always copy the conversation function
- #126985 pam_stack should always copy the conversation function
- #127524 add /etc/security/opasswd to files
* Tue Sep 28 2004 Phil Knirsch <pknirsch@redhat.com> 0.77-60
@ -1518,7 +1550,7 @@ support)
* Mon Sep 13 2004 Tomas Mraz <tmraz@redhat.com> 0.77-56
- #75454 fixed locking when changing password
- #127054
- #127054
- #125653 removed unnecessary getgrouplist call
- #124979 added quiet option to pam_succeed_if
@ -1529,7 +1561,7 @@ support)
- Move pam_console.lock to /var/run/console/
* Thu Jul 29 2004 Dan Walsh <dwalsh@redhat.com> 0.77-53
- Close fd[1] before pam_modutilread so that unix_verify will complete
- Close fd[1] before pam_modutilread so that unix_verify will complete
* Tue Jul 27 2004 Alan Cox <alan@redhat.com> 0.77-52
- First chunk of Steve Grubb's resource leak and other fixes
@ -1641,7 +1673,7 @@ support)
- Cleanup unix_chkpwd
* Mon Nov 03 2003 Dan Walsh <dwalsh@redhat.com> 0.77-17.sel
- Fix tty handling
- Fix tty handling
- Add back multiple handling
* Mon Oct 27 2003 Dan Walsh <dwalsh@redhat.com> 0.77-16.sel
@ -1663,7 +1695,7 @@ support)
- Add Russell Coker patch to handle /dev/pty
* Fri Oct 17 2003 Dan Walsh <dwalsh@redhat.com> 0.77-13.sel
- Turn on Selinux
- Turn on Selinux
* Fri Oct 17 2003 Dan Walsh <dwalsh@redhat.com> 0.77-12
- Fix pam_timestamp to work when 0 seconds have elapsed
@ -1672,7 +1704,7 @@ support)
- Turn off selinux
* Thu Sep 25 2003 Dan Walsh <dwalsh@redhat.com> 0.77-10.sel
- Turn on Selinux and remove multiple choice of context.
- Turn on Selinux and remove multiple choice of context.
* Wed Sep 24 2003 Dan Walsh <dwalsh@redhat.com> 0.77-10
- Turn off selinux
@ -1759,9 +1791,9 @@ support)
- use $ISA in default configs
* Fri Oct 04 2002 Elliot Lee <sopwith@redhat.com> 0.75-42
- Since cracklib-dicts location will not be correctly detected without
- Since cracklib-dicts location will not be correctly detected without
that package being installed, add buildreq for cracklib-dicts.
- Add patch57: makes configure use $LIBNAME when searching for cracklib
- Add patch57: makes configure use $LIBNAME when searching for cracklib
dicts, and error out if not found.
* Thu Sep 12 2002 Than Ngo <than@redhat.com> 0.75-41.1

Loading…
Cancel
Save