Compare commits

...

2 Commits

Author SHA1 Message Date
Iker Pedrosa 311368f80b - libpam: use getlogin() from libc and not utmp - pam_access: handle hostnames in access.conf 2024-01-27 03:30:38 +00:00
Iker Pedrosa f955ee172d pam_faillock: create tallydir before creating tallyfile
Resolves: RHEL-20943

Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2024-01-08 11:22:04 +01:00
5 changed files with 370 additions and 2 deletions

3
.pam.metadata Normal file
View File

@ -0,0 +1,3 @@
ad43b7fbdfdd38886fdf27e098b49f2db1c2a13d Linux-PAM-1.5.1.tar.xz
594daf1d3b96a37ec43962c9100ff5c641caba34 Linux-PAM-1.5.1.tar.xz.asc
bf661c44f34c2d4d34eaee695b36e638f4d44ba8 pam-redhat-1.1.4.tar.bz2

View File

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

View File

@ -0,0 +1,168 @@
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;
}

View File

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

View File

@ -3,7 +3,7 @@
Summary: An extensible library which provides authentication for applications
Name: pam
Version: 1.5.1
Release: 16%{?dist}
Release: 18%{?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+.
@ -56,6 +56,13 @@ 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
%global _pamlibdir %{_libdir}
%global _moduledir %{_libdir}/security
@ -154,6 +161,9 @@ cp %{SOURCE18} .
%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
autoreconf -i
@ -409,7 +419,14 @@ done
%doc doc/sag/*.txt doc/sag/html
%changelog
* Fri Oct 10 2023 Iker Pedrosa <ipedrosa@redhat.com> - 1.5.1-16
* Fri Jan 26 2024 Iker Pedrosa <ipedrosa@redhat.com> - 1.3.1-18
- libpam: use getlogin() from libc and not utmp. Resolves: RHEL-16727
- pam_access: handle hostnames in access.conf. Resolves: RHEL-22300
* Mon Jan 8 2024 Iker Pedrosa <ipedrosa@redhat.com> - 1.5.1-17
- pam_faillock: create tallydir before creating tallyfile. Resolves: RHEL-20943
* 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