Compare commits
No commits in common. 'c9' and 'i8-beta' have entirely different histories.
@ -1,2 +1,2 @@
|
||||
SOURCES/Linux-PAM-1.5.1.tar.xz
|
||||
SOURCES/pam-redhat-1.1.4.tar.bz2
|
||||
SOURCES/Linux-PAM-1.3.1.tar.xz
|
||||
SOURCES/pam-redhat-0.99.11.tar.bz2
|
||||
|
@ -1,2 +1,2 @@
|
||||
ad43b7fbdfdd38886fdf27e098b49f2db1c2a13d SOURCES/Linux-PAM-1.5.1.tar.xz
|
||||
bf661c44f34c2d4d34eaee695b36e638f4d44ba8 SOURCES/pam-redhat-1.1.4.tar.bz2
|
||||
e89b6d279c9bf8cb495dfc0b3f3931eb50f818e9 SOURCES/Linux-PAM-1.3.1.tar.xz
|
||||
42206fe8319723ef23ab646b2eab496c86de3f5b SOURCES/pam-redhat-0.99.11.tar.bz2
|
||||
|
@ -0,0 +1,40 @@
|
||||
From 0d07891ec991d1a3acb80f098d5a1b3ea3ad1480 Mon Sep 17 00:00:00 2001
|
||||
From: Sergey Cherevko <s.cherevko@msvsphere-os.ru>
|
||||
Date: Thu, 14 Mar 2024 14:10:47 +0300
|
||||
Subject: [PATCH] Fix Russian translation
|
||||
|
||||
---
|
||||
po/ru.po | 4 +---
|
||||
1 file changed, 1 insertion(+), 3 deletions(-)
|
||||
|
||||
diff --git a/po/ru.po b/po/ru.po
|
||||
index 0332308..9900c36 100644
|
||||
--- a/po/ru.po
|
||||
+++ b/po/ru.po
|
||||
@@ -43,7 +43,7 @@ msgid "Password: "
|
||||
msgstr "Пароль: "
|
||||
|
||||
#: libpam/pam_get_authtok.c:41
|
||||
-#, fuzzy, c-format
|
||||
+#, c-format
|
||||
msgid "Current %s%spassword: "
|
||||
msgstr "Новый пароль %s%s: "
|
||||
|
||||
@@ -545,14 +545,12 @@ msgstr ""
|
||||
"Срок действия учетной записи истек; обратитесь к системному администратору"
|
||||
|
||||
#: modules/pam_unix/pam_unix_acct.c:261
|
||||
-#, fuzzy
|
||||
msgid ""
|
||||
"You are required to change your password immediately (administrator enforced)"
|
||||
msgstr ""
|
||||
"Вам необходимо немедленно сменить пароль (в принудительном режиме root)"
|
||||
|
||||
#: modules/pam_unix/pam_unix_acct.c:267
|
||||
-#, fuzzy
|
||||
msgid "You are required to change your password immediately (password expired)"
|
||||
msgstr "Вам необходимо немедленно сменить пароль (пароль устарел)"
|
||||
|
||||
--
|
||||
2.39.3
|
||||
|
@ -0,0 +1,7 @@
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
Version: GnuPG v2
|
||||
|
||||
iD8DBQBa/r62bRp/BS5ZJLsRArnKAJ9pGaJHpsEsbOVa5dBQLHYC4DhPuACeJNrg
|
||||
+DaNc8W13E4Z2ZEUSsgUGe4=
|
||||
=aSTW
|
||||
-----END PGP SIGNATURE-----
|
@ -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-----
|
@ -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
|
||||
|
@ -0,0 +1,26 @@
|
||||
diff -up Linux-PAM-1.1.0/modules/pam_console/console.handlers.nochmod Linux-PAM-1.1.0/modules/pam_console/console.handlers
|
||||
--- Linux-PAM-1.1.0/modules/pam_console/console.handlers.nochmod 2008-12-16 13:37:52.000000000 +0100
|
||||
+++ Linux-PAM-1.1.0/modules/pam_console/console.handlers 2009-09-01 17:20:08.000000000 +0200
|
||||
@@ -15,5 +15,3 @@
|
||||
# touch unlock wait /var/run/console-unlocked
|
||||
|
||||
console consoledevs tty[0-9][0-9]* vc/[0-9][0-9]* :[0-9]+\.[0-9]+ :[0-9]+
|
||||
-/sbin/pam_console_apply lock logfail wait -t tty -s
|
||||
-/sbin/pam_console_apply unlock logfail wait -r -t tty -s
|
||||
diff -up Linux-PAM-1.1.0/modules/pam_console/Makefile.am.nochmod Linux-PAM-1.1.0/modules/pam_console/Makefile.am
|
||||
--- Linux-PAM-1.1.0/modules/pam_console/Makefile.am.nochmod 2008-12-16 13:37:52.000000000 +0100
|
||||
+++ Linux-PAM-1.1.0/modules/pam_console/Makefile.am 2009-09-01 17:42:47.000000000 +0200
|
||||
@@ -38,7 +38,6 @@ sbin_PROGRAMS = pam_console_apply
|
||||
|
||||
|
||||
secureconf_DATA = console.perms console.handlers
|
||||
-permsd_DATA = 50-default.perms
|
||||
|
||||
FLEX_OPTS = -Cr
|
||||
BISON_OPTS = -d
|
||||
@@ -62,4 +61,5 @@ configfile.c: configfile.tab.c configfil
|
||||
|
||||
install-data-local:
|
||||
mkdir -p $(DESTDIR)$(secureconfdir)/console.apps
|
||||
+ mkdir -p $(DESTDIR)$(permsddir)
|
||||
mkdir -m $(LOCKMODE) -p -p $(DESTDIR)$(LOCKDIR)
|
@ -0,0 +1,12 @@
|
||||
diff -up Linux-PAM-1.1.0/modules/Makefile.am.notally Linux-PAM-1.1.0/modules/Makefile.am
|
||||
--- Linux-PAM-1.1.0/modules/Makefile.am.notally 2009-07-27 17:39:25.000000000 +0200
|
||||
+++ Linux-PAM-1.1.0/modules/Makefile.am 2009-09-01 17:40:16.000000000 +0200
|
||||
@@ -10,7 +10,7 @@ SUBDIRS = pam_access pam_cracklib pam_de
|
||||
pam_mkhomedir pam_motd pam_namespace pam_nologin \
|
||||
pam_permit pam_pwhistory pam_rhosts pam_rootok pam_securetty \
|
||||
pam_selinux pam_sepermit pam_shells pam_stress \
|
||||
- pam_succeed_if pam_tally pam_tally2 pam_time pam_timestamp \
|
||||
+ pam_succeed_if pam_time pam_timestamp \
|
||||
pam_tty_audit pam_umask \
|
||||
pam_unix pam_userdb pam_warn pam_wheel pam_xauth
|
||||
|
@ -0,0 +1,12 @@
|
||||
diff -up Linux-PAM-1.1.1/modules/pam_console/pam_console_apply.c.errmsg Linux-PAM-1.1.1/modules/pam_console/pam_console_apply.c
|
||||
--- Linux-PAM-1.1.1/modules/pam_console/pam_console_apply.c.errmsg 2008-12-16 13:37:52.000000000 +0100
|
||||
+++ Linux-PAM-1.1.1/modules/pam_console/pam_console_apply.c 2014-06-19 13:23:28.948343737 +0200
|
||||
@@ -65,7 +65,7 @@ parse_files(void)
|
||||
on system locale */
|
||||
oldlocale = setlocale(LC_COLLATE, "C");
|
||||
|
||||
- rc = glob(PERMS_GLOB, GLOB_NOCHECK, NULL, &globbuf);
|
||||
+ rc = glob(PERMS_GLOB, 0, NULL, &globbuf);
|
||||
setlocale(LC_COLLATE, oldlocale);
|
||||
if (rc)
|
||||
return;
|
@ -0,0 +1,27 @@
|
||||
diff -up pam/modules/pam_env/pam_env.c.nouserenv pam/modules/pam_env/pam_env.c
|
||||
--- pam/modules/pam_env/pam_env.c.nouserenv 2010-10-20 09:59:30.000000000 +0200
|
||||
+++ pam/modules/pam_env/pam_env.c 2010-11-01 14:42:01.000000000 +0100
|
||||
@@ -10,7 +10,7 @@
|
||||
#define DEFAULT_READ_ENVFILE 1
|
||||
|
||||
#define DEFAULT_USER_ENVFILE ".pam_environment"
|
||||
-#define DEFAULT_USER_READ_ENVFILE 1
|
||||
+#define DEFAULT_USER_READ_ENVFILE 0
|
||||
|
||||
#include "config.h"
|
||||
|
||||
diff -up pam/modules/pam_env/pam_env.8.xml.nouserenv pam/modules/pam_env/pam_env.8.xml
|
||||
--- pam/modules/pam_env/pam_env.8.xml.nouserenv 2010-10-20 09:59:30.000000000 +0200
|
||||
+++ pam/modules/pam_env/pam_env.8.xml 2010-11-01 14:42:01.000000000 +0100
|
||||
@@ -147,7 +147,10 @@
|
||||
<listitem>
|
||||
<para>
|
||||
Turns on or off the reading of the user specific environment
|
||||
- file. 0 is off, 1 is on. By default this option is on.
|
||||
+ file. 0 is off, 1 is on. By default this option is off as user
|
||||
+ supplied environment variables in the PAM environment could affect
|
||||
+ behavior of subsequent modules in the stack without the consent
|
||||
+ of the system administrator.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
@ -0,0 +1,20 @@
|
||||
diff -up Linux-PAM-1.1.6/modules/pam_limits/limits.conf.limits Linux-PAM-1.1.6/modules/pam_limits/limits.conf
|
||||
--- Linux-PAM-1.1.6/modules/pam_limits/limits.conf.limits 2012-08-15 13:08:43.000000000 +0200
|
||||
+++ Linux-PAM-1.1.6/modules/pam_limits/limits.conf 2013-03-14 16:43:37.615087671 +0100
|
||||
@@ -1,5 +1,16 @@
|
||||
# /etc/security/limits.conf
|
||||
#
|
||||
+#This file sets the resource limits for the users logged in via PAM.
|
||||
+#It does not affect resource limits of the system services.
|
||||
+#
|
||||
+#Also note that configuration files in /etc/security/limits.d directory,
|
||||
+#which are read in alphabetical order, override the settings in this
|
||||
+#file in case the domain is the same or more specific.
|
||||
+#That means for example that setting a limit for wildcard domain here
|
||||
+#can be overriden with a wildcard setting in a config file in the
|
||||
+#subdirectory, but a user specific setting here can be overriden only
|
||||
+#with a user specific setting in the subdirectory.
|
||||
+#
|
||||
#Each line describes a limit for a user in the form:
|
||||
#
|
||||
#<domain> <type> <item> <value>
|
@ -0,0 +1,31 @@
|
||||
diff -up Linux-PAM-1.1.8/modules/pam_tally2/pam_tally2.c.audit-user-mgmt Linux-PAM-1.1.8/modules/pam_tally2/pam_tally2.c
|
||||
--- Linux-PAM-1.1.8/modules/pam_tally2/pam_tally2.c.audit-user-mgmt 2013-06-18 16:11:21.000000000 +0200
|
||||
+++ Linux-PAM-1.1.8/modules/pam_tally2/pam_tally2.c 2014-10-17 12:09:12.965490940 +0200
|
||||
@@ -997,9 +997,9 @@ main( int argc UNUSED, char **argv )
|
||||
#ifdef HAVE_LIBAUDIT
|
||||
char buf[64];
|
||||
int audit_fd = audit_open();
|
||||
- snprintf(buf, sizeof(buf), "pam_tally2 uid=%u reset=%hu", uid, cline_reset);
|
||||
- audit_log_user_message(audit_fd, AUDIT_USER_ACCT,
|
||||
- buf, NULL, NULL, ttyname(STDIN_FILENO), 1);
|
||||
+ snprintf(buf, sizeof(buf), "pam_tally2 reset=%hu", cline_reset);
|
||||
+ audit_log_acct_message(audit_fd, AUDIT_USER_MGMT, NULL,
|
||||
+ buf, NULL, uid, NULL, NULL, ttyname(STDIN_FILENO), 1);
|
||||
if (audit_fd >=0)
|
||||
close(audit_fd);
|
||||
#endif
|
||||
@@ -1040,11 +1040,10 @@ main( int argc UNUSED, char **argv )
|
||||
}
|
||||
else if ( !cline_reset ) {
|
||||
#ifdef HAVE_LIBAUDIT
|
||||
- char buf[64];
|
||||
int audit_fd = audit_open();
|
||||
- snprintf(buf, sizeof(buf), "pam_tally2 uid=all reset=0");
|
||||
- audit_log_user_message(audit_fd, AUDIT_USER_ACCT,
|
||||
- buf, NULL, NULL, ttyname(STDIN_FILENO), 1);
|
||||
+ audit_log_acct_message(audit_fd, AUDIT_USER_MGMT, NULL,
|
||||
+ "pam_tally2-reset-all-accts reset=0", "*", -1,
|
||||
+ NULL, NULL, ttyname(STDIN_FILENO), 1);
|
||||
if (audit_fd >=0)
|
||||
close(audit_fd);
|
||||
#endif
|
@ -0,0 +1,88 @@
|
||||
diff -up Linux-PAM-1.1.8/modules/pam_console/Makefile.am.relro Linux-PAM-1.1.8/modules/pam_console/Makefile.am
|
||||
--- Linux-PAM-1.1.8/modules/pam_console/Makefile.am.relro 2014-08-13 16:02:49.000000000 +0200
|
||||
+++ Linux-PAM-1.1.8/modules/pam_console/Makefile.am 2014-09-10 17:14:33.245554314 +0200
|
||||
@@ -33,6 +33,8 @@ pam_console_la_LIBADD = -L$(top_builddir
|
||||
|
||||
pam_console_apply_LDADD = -L$(top_builddir)/libpam -lpam
|
||||
|
||||
+pam_console_apply_LDFLAGS = -Wl,-z,now @PIE_LDFLAGS@
|
||||
+
|
||||
securelib_LTLIBRARIES = pam_console.la
|
||||
sbin_PROGRAMS = pam_console_apply
|
||||
|
||||
@@ -47,7 +49,7 @@ pam_console_apply_SOURCES = pam_console_
|
||||
configfile.c configfile.h hashtable.c hashtable.h hashtable_private.h
|
||||
|
||||
pam_console_la_CFLAGS = $(AM_CFLAGS)
|
||||
-pam_console_apply_CFLAGS = $(AM_CFLAGS)
|
||||
+pam_console_apply_CFLAGS = $(AM_CFLAGS) @PIE_CFLAGS@
|
||||
|
||||
configfile.tab.c: configfile.y
|
||||
$(YACC) $(BISON_OPTS) -o $@ -p _pc_yy $<
|
||||
diff -up Linux-PAM-1.1.8/modules/pam_filter/upperLOWER/Makefile.am.relro Linux-PAM-1.1.8/modules/pam_filter/upperLOWER/Makefile.am
|
||||
--- Linux-PAM-1.1.8/modules/pam_filter/upperLOWER/Makefile.am.relro 2014-09-10 17:17:20.273401344 +0200
|
||||
+++ Linux-PAM-1.1.8/modules/pam_filter/upperLOWER/Makefile.am 2014-09-10 17:17:07.857115369 +0200
|
||||
@@ -9,7 +9,7 @@ securelibfilterdir = $(SECUREDIR)/pam_fi
|
||||
|
||||
AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
|
||||
-I$(srcdir)/.. @PIE_CFLAGS@
|
||||
-AM_LDFLAGS = @PIE_LDFLAGS@
|
||||
+AM_LDFLAGS = -Wl,-z,now @PIE_LDFLAGS@
|
||||
LDADD = $(top_builddir)/libpam/libpam.la
|
||||
|
||||
securelibfilter_PROGRAMS = upperLOWER
|
||||
diff -up Linux-PAM-1.1.8/modules/pam_mkhomedir/Makefile.am.relro Linux-PAM-1.1.8/modules/pam_mkhomedir/Makefile.am
|
||||
--- Linux-PAM-1.1.8/modules/pam_mkhomedir/Makefile.am.relro 2013-06-18 16:11:21.000000000 +0200
|
||||
+++ Linux-PAM-1.1.8/modules/pam_mkhomedir/Makefile.am 2014-09-10 17:18:42.922304935 +0200
|
||||
@@ -30,6 +30,8 @@ endif
|
||||
|
||||
sbin_PROGRAMS = mkhomedir_helper
|
||||
mkhomedir_helper_SOURCES = mkhomedir_helper.c
|
||||
+mkhomedir_helper_CFLAGS = $(AM_CFLAGS) @PIE_CFLAGS@
|
||||
+mkhomedir_helper_LDFLAGS = -Wl,-z,now @PIE_LDFLAGS@
|
||||
mkhomedir_helper_LDADD = $(top_builddir)/libpam/libpam.la
|
||||
|
||||
if ENABLE_REGENERATE_MAN
|
||||
diff -up Linux-PAM-1.1.8/modules/pam_tally2/Makefile.am.relro Linux-PAM-1.1.8/modules/pam_tally2/Makefile.am
|
||||
--- Linux-PAM-1.1.8/modules/pam_tally2/Makefile.am.relro 2013-06-18 16:11:21.000000000 +0200
|
||||
+++ Linux-PAM-1.1.8/modules/pam_tally2/Makefile.am 2014-09-10 17:22:04.339944040 +0200
|
||||
@@ -26,6 +26,8 @@ if HAVE_VERSIONING
|
||||
pam_tally2_la_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
|
||||
endif
|
||||
|
||||
+pam_tally2_CFLAGS = $(AM_CFLAGS) @PIE_CFLAGS@
|
||||
+pam_tally2_LDFLAGS = -Wl,-z,now @PIE_LDFLAGS@
|
||||
pam_tally2_LDADD = $(top_builddir)/libpam/libpam.la $(LIBAUDIT)
|
||||
|
||||
securelib_LTLIBRARIES = pam_tally2.la
|
||||
diff -up Linux-PAM-1.1.8/modules/pam_timestamp/Makefile.am.relro Linux-PAM-1.1.8/modules/pam_timestamp/Makefile.am
|
||||
--- Linux-PAM-1.1.8/modules/pam_timestamp/Makefile.am.relro 2013-06-18 16:11:21.000000000 +0200
|
||||
+++ Linux-PAM-1.1.8/modules/pam_timestamp/Makefile.am 2014-08-13 16:02:49.906688139 +0200
|
||||
@@ -36,7 +36,7 @@ pam_timestamp_la_CFLAGS = $(AM_CFLAGS)
|
||||
pam_timestamp_check_SOURCES = pam_timestamp_check.c
|
||||
pam_timestamp_check_CFLAGS = $(AM_CFLAGS) @PIE_CFLAGS@
|
||||
pam_timestamp_check_LDADD = $(top_builddir)/libpam/libpam.la
|
||||
-pam_timestamp_check_LDFLAGS = @PIE_LDFLAGS@
|
||||
+pam_timestamp_check_LDFLAGS = -Wl,-z,now @PIE_LDFLAGS@
|
||||
|
||||
hmacfile_SOURCES = hmacfile.c hmacsha1.c sha1.c
|
||||
hmacfile_LDADD = $(top_builddir)/libpam/libpam.la
|
||||
diff -up Linux-PAM-1.1.8/modules/pam_unix/Makefile.am.relro Linux-PAM-1.1.8/modules/pam_unix/Makefile.am
|
||||
--- Linux-PAM-1.1.8/modules/pam_unix/Makefile.am.relro 2013-06-18 16:11:21.000000000 +0200
|
||||
+++ Linux-PAM-1.1.8/modules/pam_unix/Makefile.am 2014-08-13 16:02:49.906688139 +0200
|
||||
@@ -55,13 +55,13 @@ bigcrypt_LDADD = @LIBCRYPT@
|
||||
unix_chkpwd_SOURCES = unix_chkpwd.c md5_good.c md5_broken.c bigcrypt.c \
|
||||
passverify.c
|
||||
unix_chkpwd_CFLAGS = $(AM_CFLAGS) @PIE_CFLAGS@ -DHELPER_COMPILE=\"unix_chkpwd\"
|
||||
-unix_chkpwd_LDFLAGS = @PIE_LDFLAGS@
|
||||
+unix_chkpwd_LDFLAGS = -Wl,-z,now @PIE_LDFLAGS@
|
||||
unix_chkpwd_LDADD = @LIBCRYPT@ @LIBSELINUX@ @LIBAUDIT@
|
||||
|
||||
unix_update_SOURCES = unix_update.c md5_good.c md5_broken.c bigcrypt.c \
|
||||
passverify.c
|
||||
unix_update_CFLAGS = $(AM_CFLAGS) @PIE_CFLAGS@ -DHELPER_COMPILE=\"unix_update\"
|
||||
-unix_update_LDFLAGS = @PIE_LDFLAGS@
|
||||
+unix_update_LDFLAGS = -Wl,-z,now @PIE_LDFLAGS@
|
||||
unix_update_LDADD = @LIBCRYPT@ @LIBSELINUX@
|
||||
|
||||
if ENABLE_REGENERATE_MAN
|
@ -0,0 +1,23 @@
|
||||
diff -up Linux-PAM-1.2.0/configure.ac.redhat-modules Linux-PAM-1.2.0/configure.ac
|
||||
--- Linux-PAM-1.2.0/configure.ac.redhat-modules 2015-03-25 16:50:10.000000000 +0100
|
||||
+++ Linux-PAM-1.2.0/configure.ac 2015-05-15 15:46:50.996074677 +0200
|
||||
@@ -616,6 +616,8 @@ AC_CONFIG_FILES([Makefile libpam/Makefil
|
||||
libpam_misc/Makefile conf/Makefile conf/pam_conv1/Makefile \
|
||||
po/Makefile.in \
|
||||
modules/Makefile \
|
||||
+ modules/pam_chroot/Makefile modules/pam_console/Makefile \
|
||||
+ modules/pam_postgresok/Makefile \
|
||||
modules/pam_access/Makefile modules/pam_cracklib/Makefile \
|
||||
modules/pam_debug/Makefile modules/pam_deny/Makefile \
|
||||
modules/pam_echo/Makefile modules/pam_env/Makefile \
|
||||
diff -up Linux-PAM-1.2.0/modules/Makefile.am.redhat-modules Linux-PAM-1.2.0/modules/Makefile.am
|
||||
--- Linux-PAM-1.2.0/modules/Makefile.am.redhat-modules 2015-03-24 13:02:32.000000000 +0100
|
||||
+++ Linux-PAM-1.2.0/modules/Makefile.am 2015-05-15 15:46:50.995074654 +0200
|
||||
@@ -3,6 +3,7 @@
|
||||
#
|
||||
|
||||
SUBDIRS = pam_access pam_cracklib pam_debug pam_deny pam_echo \
|
||||
+ pam_chroot pam_console pam_postgresok \
|
||||
pam_env pam_exec pam_faildelay pam_filter pam_ftp \
|
||||
pam_group pam_issue pam_keyinit pam_lastlog pam_limits \
|
||||
pam_listfile pam_localuser pam_loginuid pam_mail \
|
@ -0,0 +1,73 @@
|
||||
diff -up Linux-PAM-1.2.0/modules/pam_unix/pam_unix.8.xml.no-fallback Linux-PAM-1.2.0/modules/pam_unix/pam_unix.8.xml
|
||||
--- Linux-PAM-1.2.0/modules/pam_unix/pam_unix.8.xml.no-fallback 2015-04-27 16:38:03.000000000 +0200
|
||||
+++ Linux-PAM-1.2.0/modules/pam_unix/pam_unix.8.xml 2015-05-15 15:54:21.524440864 +0200
|
||||
@@ -284,11 +284,10 @@
|
||||
<listitem>
|
||||
<para>
|
||||
When a user changes their password next,
|
||||
- encrypt it with the SHA256 algorithm. If the
|
||||
- SHA256 algorithm is not known to the <citerefentry>
|
||||
+ encrypt it with the SHA256 algorithm. The
|
||||
+ SHA256 algorithm must be supported by the <citerefentry>
|
||||
<refentrytitle>crypt</refentrytitle><manvolnum>3</manvolnum>
|
||||
- </citerefentry> function,
|
||||
- fall back to MD5.
|
||||
+ </citerefentry> function.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
@@ -299,11 +298,10 @@
|
||||
<listitem>
|
||||
<para>
|
||||
When a user changes their password next,
|
||||
- encrypt it with the SHA512 algorithm. If the
|
||||
- SHA512 algorithm is not known to the <citerefentry>
|
||||
+ encrypt it with the SHA512 algorithm. The
|
||||
+ SHA512 algorithm must be supported by the <citerefentry>
|
||||
<refentrytitle>crypt</refentrytitle><manvolnum>3</manvolnum>
|
||||
- </citerefentry> function,
|
||||
- fall back to MD5.
|
||||
+ </citerefentry> function.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
@@ -314,11 +312,10 @@
|
||||
<listitem>
|
||||
<para>
|
||||
When a user changes their password next,
|
||||
- encrypt it with the blowfish algorithm. If the
|
||||
- blowfish algorithm is not known to the <citerefentry>
|
||||
+ encrypt it with the blowfish algorithm. The
|
||||
+ blowfish algorithm must be supported by the <citerefentry>
|
||||
<refentrytitle>crypt</refentrytitle><manvolnum>3</manvolnum>
|
||||
- </citerefentry> function,
|
||||
- fall back to MD5.
|
||||
+ </citerefentry> function.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
diff -up Linux-PAM-1.2.0/modules/pam_unix/passverify.c.no-fallback Linux-PAM-1.2.0/modules/pam_unix/passverify.c
|
||||
--- Linux-PAM-1.2.0/modules/pam_unix/passverify.c.no-fallback 2015-05-15 15:54:21.525440887 +0200
|
||||
+++ Linux-PAM-1.2.0/modules/pam_unix/passverify.c 2015-05-15 15:57:23.138613273 +0200
|
||||
@@ -437,10 +437,9 @@ PAMH_ARG_DECL(char * create_password_has
|
||||
sp = crypt(password, salt);
|
||||
#endif
|
||||
if (!sp || strncmp(algoid, sp, strlen(algoid)) != 0) {
|
||||
- /* libxcrypt/libc doesn't know the algorithm, use MD5 */
|
||||
+ /* libxcrypt/libc doesn't know the algorithm, error out */
|
||||
pam_syslog(pamh, LOG_ERR,
|
||||
- "Algo %s not supported by the crypto backend, "
|
||||
- "falling back to MD5\n",
|
||||
+ "Algo %s not supported by the crypto backend.\n",
|
||||
on(UNIX_BLOWFISH_PASS, ctrl) ? "blowfish" :
|
||||
on(UNIX_SHA256_PASS, ctrl) ? "sha256" :
|
||||
on(UNIX_SHA512_PASS, ctrl) ? "sha512" : algoid);
|
||||
@@ -450,7 +449,7 @@ PAMH_ARG_DECL(char * create_password_has
|
||||
#ifdef HAVE_CRYPT_R
|
||||
free(cdata);
|
||||
#endif
|
||||
- return crypt_md5_wrapper(password);
|
||||
+ return NULL;
|
||||
}
|
||||
sp = x_strdup(sp);
|
||||
#ifdef HAVE_CRYPT_R
|
@ -0,0 +1,9 @@
|
||||
diff -up Linux-PAM-1.2.1/modules/pam_console/console.handlers.devname Linux-PAM-1.2.1/modules/pam_console/console.handlers
|
||||
--- Linux-PAM-1.2.1/modules/pam_console/console.handlers.devname 2015-10-16 14:15:48.000000000 +0200
|
||||
+++ Linux-PAM-1.2.1/modules/pam_console/console.handlers 2016-02-05 17:47:26.056787517 +0100
|
||||
@@ -14,4 +14,4 @@
|
||||
# echo lock wait Locking console for user on tty
|
||||
# touch unlock wait /var/run/console-unlocked
|
||||
|
||||
-console consoledevs tty[0-9][0-9]* vc/[0-9][0-9]* :[0-9]+\.[0-9]+ :[0-9]+
|
||||
+console consoledevs /dev/tty[0-9][0-9]* tty[0-9][0-9]* vc/[0-9][0-9]* :[0-9]+\.[0-9]+ :[0-9]+
|
@ -0,0 +1,133 @@
|
||||
diff -up Linux-PAM-1.3.0/modules/pam_faillock/pam_faillock.c.admin-group Linux-PAM-1.3.0/modules/pam_faillock/pam_faillock.c
|
||||
--- Linux-PAM-1.3.0/modules/pam_faillock/pam_faillock.c.admin-group 2016-04-04 16:37:38.696260359 +0200
|
||||
+++ Linux-PAM-1.3.0/modules/pam_faillock/pam_faillock.c 2017-08-21 16:40:01.624706864 +0200
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
- * Copyright (c) 2010 Tomas Mraz <tmraz@redhat.com>
|
||||
+ * Copyright (c) 2010, 2017 Tomas Mraz <tmraz@redhat.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@@ -78,9 +78,11 @@ struct options {
|
||||
unsigned int root_unlock_time;
|
||||
const char *dir;
|
||||
const char *user;
|
||||
+ const char *admin_group;
|
||||
int failures;
|
||||
uint64_t latest_time;
|
||||
uid_t uid;
|
||||
+ int is_admin;
|
||||
uint64_t now;
|
||||
};
|
||||
|
||||
@@ -152,6 +154,9 @@ args_parse(pam_handle_t *pamh, int argc,
|
||||
opts->root_unlock_time = temp;
|
||||
}
|
||||
}
|
||||
+ else if (strncmp(argv[i], "admin_group=", 12) == 0) {
|
||||
+ opts->admin_group = argv[i] + 12;
|
||||
+ }
|
||||
else if (strcmp(argv[i], "preauth") == 0) {
|
||||
opts->action = FAILLOCK_ACTION_PREAUTH;
|
||||
}
|
||||
@@ -209,6 +214,17 @@ static int get_pam_user(pam_handle_t *pa
|
||||
}
|
||||
opts->user = user;
|
||||
opts->uid = pwd->pw_uid;
|
||||
+
|
||||
+ if (pwd->pw_uid == 0) {
|
||||
+ opts->is_admin = 1;
|
||||
+ return PAM_SUCCESS;
|
||||
+ }
|
||||
+
|
||||
+ if (opts->admin_group && *opts->admin_group) {
|
||||
+ opts->is_admin = pam_modutil_user_in_group_uid_nam(pamh,
|
||||
+ pwd->pw_uid, opts->admin_group);
|
||||
+ }
|
||||
+
|
||||
return PAM_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -239,7 +255,7 @@ check_tally(pam_handle_t *pamh, struct o
|
||||
return PAM_SYSTEM_ERR;
|
||||
}
|
||||
|
||||
- if (opts->uid == 0 && !(opts->flags & FAILLOCK_FLAG_DENY_ROOT)) {
|
||||
+ if (opts->is_admin && !(opts->flags & FAILLOCK_FLAG_DENY_ROOT)) {
|
||||
return PAM_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -262,13 +278,9 @@ check_tally(pam_handle_t *pamh, struct o
|
||||
|
||||
opts->failures = failures;
|
||||
|
||||
- if (opts->uid == 0 && !(opts->flags & FAILLOCK_FLAG_DENY_ROOT)) {
|
||||
- return PAM_SUCCESS;
|
||||
- }
|
||||
-
|
||||
if (opts->deny && failures >= opts->deny) {
|
||||
- if ((opts->uid && opts->unlock_time && latest_time + opts->unlock_time < opts->now) ||
|
||||
- (!opts->uid && opts->root_unlock_time && latest_time + opts->root_unlock_time < opts->now)) {
|
||||
+ if ((!opts->is_admin && opts->unlock_time && latest_time + opts->unlock_time < opts->now) ||
|
||||
+ (opts->is_admin && opts->root_unlock_time && latest_time + opts->root_unlock_time < opts->now)) {
|
||||
#ifdef HAVE_LIBAUDIT
|
||||
if (opts->action != FAILLOCK_ACTION_PREAUTH) { /* do not audit in preauth */
|
||||
char buf[64];
|
||||
@@ -401,7 +413,7 @@ write_tally(pam_handle_t *pamh, struct o
|
||||
audit_log_user_message(audit_fd, AUDIT_ANOM_LOGIN_FAILURES, buf,
|
||||
NULL, NULL, NULL, 1);
|
||||
|
||||
- if (opts->uid != 0 || (opts->flags & FAILLOCK_FLAG_DENY_ROOT)) {
|
||||
+ if (!opts->is_admin || (opts->flags & FAILLOCK_FLAG_DENY_ROOT)) {
|
||||
audit_log_user_message(audit_fd, AUDIT_RESP_ACCT_LOCK, buf,
|
||||
NULL, NULL, NULL, 1);
|
||||
}
|
||||
@@ -425,11 +437,11 @@ faillock_message(pam_handle_t *pamh, str
|
||||
int64_t left;
|
||||
|
||||
if (!(opts->flags & FAILLOCK_FLAG_SILENT)) {
|
||||
- if (opts->uid) {
|
||||
- left = opts->latest_time + opts->unlock_time - opts->now;
|
||||
+ if (opts->is_admin) {
|
||||
+ left = opts->latest_time + opts->root_unlock_time - opts->now;
|
||||
}
|
||||
else {
|
||||
- left = opts->latest_time + opts->root_unlock_time - opts->now;
|
||||
+ left = opts->latest_time + opts->unlock_time - opts->now;
|
||||
}
|
||||
|
||||
if (left > 0) {
|
||||
diff -up Linux-PAM-1.3.0/modules/pam_faillock/pam_faillock.8.xml.admin-group Linux-PAM-1.3.0/modules/pam_faillock/pam_faillock.8.xml
|
||||
--- Linux-PAM-1.3.0/modules/pam_faillock/pam_faillock.8.xml.admin-group 2016-05-06 15:24:10.328281818 +0200
|
||||
+++ Linux-PAM-1.3.0/modules/pam_faillock/pam_faillock.8.xml 2017-08-21 16:16:09.448033843 +0200
|
||||
@@ -40,6 +40,9 @@
|
||||
root_unlock_time=<replaceable>n</replaceable>
|
||||
</arg>
|
||||
<arg choice="opt">
|
||||
+ admin_group=<replaceable>name</replaceable>
|
||||
+ </arg>
|
||||
+ <arg choice="opt">
|
||||
audit
|
||||
</arg>
|
||||
<arg choice="opt">
|
||||
@@ -243,6 +246,20 @@
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
+ <varlistentry>
|
||||
+ <term>
|
||||
+ <option>admin_group=<replaceable>name</replaceable></option>
|
||||
+ </term>
|
||||
+ <listitem>
|
||||
+ <para>
|
||||
+ If a group name is specified with this option, members
|
||||
+ of the group will be handled by this module the same as
|
||||
+ the root account (the options <option>even_deny_root></option>
|
||||
+ and <option>root_unlock_time</option> will apply to them.
|
||||
+ By default the option is not set.
|
||||
+ </para>
|
||||
+ </listitem>
|
||||
+ </varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,806 @@
|
||||
diff -up Linux-PAM-1.3.0/modules/pam_pwhistory/Makefile.am.pwhhelper Linux-PAM-1.3.0/modules/pam_pwhistory/Makefile.am
|
||||
--- Linux-PAM-1.3.0/modules/pam_pwhistory/Makefile.am.pwhhelper 2016-03-24 12:45:42.000000000 +0100
|
||||
+++ Linux-PAM-1.3.0/modules/pam_pwhistory/Makefile.am 2016-05-06 15:18:42.307637933 +0200
|
||||
@@ -1,5 +1,6 @@
|
||||
#
|
||||
# Copyright (c) 2008, 2009 Thorsten Kukuk <kukuk@suse.de>
|
||||
+# Copyright (c) 2013 Red Hat, Inc.
|
||||
#
|
||||
|
||||
CLEANFILES = *~
|
||||
@@ -9,25 +10,34 @@ EXTRA_DIST = README $(MANS) $(XMLS) tst-
|
||||
|
||||
TESTS = tst-pam_pwhistory
|
||||
|
||||
-man_MANS = pam_pwhistory.8
|
||||
+man_MANS = pam_pwhistory.8 pwhistory_helper.8
|
||||
|
||||
-XMLS = README.xml pam_pwhistory.8.xml
|
||||
+XMLS = README.xml pam_pwhistory.8.xml pwhistory_helper.8.xml
|
||||
|
||||
securelibdir = $(SECUREDIR)
|
||||
secureconfdir = $(SCONFIGDIR)
|
||||
|
||||
-AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include
|
||||
-AM_LDFLAGS = -no-undefined -avoid-version -module
|
||||
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
|
||||
+ -DPWHISTORY_HELPER=\"$(sbindir)/pwhistory_helper\"
|
||||
+
|
||||
+pam_pwhistory_la_LDFLAGS = -no-undefined -avoid-version -module
|
||||
if HAVE_VERSIONING
|
||||
- AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
|
||||
+ pam_pwhistory_la_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
|
||||
endif
|
||||
|
||||
noinst_HEADERS = opasswd.h
|
||||
|
||||
securelib_LTLIBRARIES = pam_pwhistory.la
|
||||
-pam_pwhistory_la_LIBADD = $(top_builddir)/libpam/libpam.la @LIBCRYPT@
|
||||
+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
|
||||
|
||||
+sbin_PROGRAMS = pwhistory_helper
|
||||
+pwhistory_helper_CFLAGS = $(AM_CFLAGS) -DHELPER_COMPILE=\"pwhistory_helper\" @PIE_CFLAGS@
|
||||
+pwhistory_helper_SOURCES = pwhistory_helper.c opasswd.c
|
||||
+pwhistory_helper_LDFLAGS = -Wl,-z,now @PIE_LDFLAGS@
|
||||
+pwhistory_helper_LDADD = $(top_builddir)/libpam/libpam.la @LIBCRYPT@
|
||||
+
|
||||
if ENABLE_REGENERATE_MAN
|
||||
noinst_DATA = README
|
||||
README: pam_pwhistory.8.xml
|
||||
diff -up Linux-PAM-1.3.0/modules/pam_pwhistory/opasswd.c.pwhhelper Linux-PAM-1.3.0/modules/pam_pwhistory/opasswd.c
|
||||
--- Linux-PAM-1.3.0/modules/pam_pwhistory/opasswd.c.pwhhelper 2016-03-24 12:45:42.000000000 +0100
|
||||
+++ Linux-PAM-1.3.0/modules/pam_pwhistory/opasswd.c 2016-05-06 15:18:42.307637933 +0200
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2008 Thorsten Kukuk <kukuk@suse.de>
|
||||
+ * Copyright (c) 2013 Red Hat, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@@ -38,6 +39,7 @@
|
||||
#endif
|
||||
|
||||
#include <pwd.h>
|
||||
+#include <shadow.h>
|
||||
#include <time.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
@@ -47,6 +49,7 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <syslog.h>
|
||||
+#include <stdarg.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#if defined (HAVE_XCRYPT_H)
|
||||
@@ -55,7 +58,14 @@
|
||||
#include <crypt.h>
|
||||
#endif
|
||||
|
||||
+#ifdef HELPER_COMPILE
|
||||
+#define pam_modutil_getpwnam(h,n) getpwnam(n)
|
||||
+#define pam_modutil_getspnam(h,n) getspnam(n)
|
||||
+#define pam_syslog(h,a,...) helper_log_err(a,__VA_ARGS__)
|
||||
+#else
|
||||
+#include <security/pam_modutil.h>
|
||||
#include <security/pam_ext.h>
|
||||
+#endif
|
||||
#include <security/pam_modules.h>
|
||||
|
||||
#include "opasswd.h"
|
||||
@@ -76,6 +86,19 @@ typedef struct {
|
||||
char *old_passwords;
|
||||
} opwd;
|
||||
|
||||
+#ifdef HELPER_COMPILE
|
||||
+void
|
||||
+helper_log_err(int err, const char *format, ...)
|
||||
+{
|
||||
+ va_list args;
|
||||
+
|
||||
+ va_start(args, format);
|
||||
+ openlog(HELPER_COMPILE, LOG_CONS | LOG_PID, LOG_AUTHPRIV);
|
||||
+ vsyslog(err, format, args);
|
||||
+ va_end(args);
|
||||
+ closelog();
|
||||
+}
|
||||
+#endif
|
||||
|
||||
static int
|
||||
parse_entry (char *line, opwd *data)
|
||||
@@ -117,8 +140,8 @@ compare_password(const char *newpass, co
|
||||
}
|
||||
|
||||
/* Check, if the new password is already in the opasswd file. */
|
||||
-int
|
||||
-check_old_pass (pam_handle_t *pamh, const char *user,
|
||||
+PAMH_ARG_DECL(int
|
||||
+check_old_pass, const char *user,
|
||||
const char *newpass, int debug)
|
||||
{
|
||||
int retval = PAM_SUCCESS;
|
||||
@@ -128,6 +151,11 @@ check_old_pass (pam_handle_t *pamh, cons
|
||||
opwd entry;
|
||||
int found = 0;
|
||||
|
||||
+#ifndef HELPER_COMPILE
|
||||
+ if (SELINUX_ENABLED)
|
||||
+ return PAM_PWHISTORY_RUN_HELPER;
|
||||
+#endif
|
||||
+
|
||||
if ((oldpf = fopen (OLD_PASSWORDS_FILE, "r")) == NULL)
|
||||
{
|
||||
if (errno != ENOENT)
|
||||
@@ -213,9 +241,9 @@ check_old_pass (pam_handle_t *pamh, cons
|
||||
return retval;
|
||||
}
|
||||
|
||||
-int
|
||||
-save_old_pass (pam_handle_t *pamh, const char *user, uid_t uid,
|
||||
- const char *oldpass, int howmany, int debug UNUSED)
|
||||
+PAMH_ARG_DECL(int
|
||||
+save_old_pass, const char *user,
|
||||
+ int howmany, int debug UNUSED)
|
||||
{
|
||||
char opasswd_tmp[] = TMP_PASSWORDS_FILE;
|
||||
struct stat opasswd_stat;
|
||||
@@ -226,10 +254,35 @@ save_old_pass (pam_handle_t *pamh, const
|
||||
char *buf = NULL;
|
||||
size_t buflen = 0;
|
||||
int found = 0;
|
||||
+ struct passwd *pwd;
|
||||
+ const char *oldpass;
|
||||
+
|
||||
+ pwd = pam_modutil_getpwnam (pamh, user);
|
||||
+ if (pwd == NULL)
|
||||
+ return PAM_USER_UNKNOWN;
|
||||
|
||||
if (howmany <= 0)
|
||||
return PAM_SUCCESS;
|
||||
|
||||
+#ifndef HELPER_COMPILE
|
||||
+ if (SELINUX_ENABLED)
|
||||
+ return PAM_PWHISTORY_RUN_HELPER;
|
||||
+#endif
|
||||
+
|
||||
+ if ((strcmp(pwd->pw_passwd, "x") == 0) ||
|
||||
+ ((pwd->pw_passwd[0] == '#') &&
|
||||
+ (pwd->pw_passwd[1] == '#') &&
|
||||
+ (strcmp(pwd->pw_name, pwd->pw_passwd + 2) == 0)))
|
||||
+ {
|
||||
+ struct spwd *spw = pam_modutil_getspnam (pamh, user);
|
||||
+
|
||||
+ if (spw == NULL)
|
||||
+ return PAM_USER_UNKNOWN;
|
||||
+ oldpass = spw->sp_pwdp;
|
||||
+ }
|
||||
+ else
|
||||
+ oldpass = pwd->pw_passwd;
|
||||
+
|
||||
if (oldpass == NULL || *oldpass == '\0')
|
||||
return PAM_SUCCESS;
|
||||
|
||||
@@ -452,7 +505,7 @@ save_old_pass (pam_handle_t *pamh, const
|
||||
{
|
||||
char *out;
|
||||
|
||||
- if (asprintf (&out, "%s:%d:1:%s\n", user, uid, oldpass) < 0)
|
||||
+ if (asprintf (&out, "%s:%d:1:%s\n", user, pwd->pw_uid, oldpass) < 0)
|
||||
{
|
||||
retval = PAM_AUTHTOK_ERR;
|
||||
if (oldpf)
|
||||
diff -up Linux-PAM-1.3.0/modules/pam_pwhistory/opasswd.h.pwhhelper Linux-PAM-1.3.0/modules/pam_pwhistory/opasswd.h
|
||||
--- Linux-PAM-1.3.0/modules/pam_pwhistory/opasswd.h.pwhhelper 2016-03-24 12:45:42.000000000 +0100
|
||||
+++ Linux-PAM-1.3.0/modules/pam_pwhistory/opasswd.h 2016-05-06 15:18:42.307637933 +0200
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2008 Thorsten Kukuk <kukuk@suse.de>
|
||||
+ * Copyright (c) 2013 Red Hat, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@@ -36,10 +37,32 @@
|
||||
#ifndef __OPASSWD_H__
|
||||
#define __OPASSWD_H__
|
||||
|
||||
-extern int check_old_pass (pam_handle_t *pamh, const char *user,
|
||||
- const char *newpass, int debug);
|
||||
-extern int save_old_pass (pam_handle_t *pamh, const char *user,
|
||||
- uid_t uid, const char *oldpass,
|
||||
- int howmany, int debug);
|
||||
+#define PAM_PWHISTORY_RUN_HELPER PAM_CRED_INSUFFICIENT
|
||||
+
|
||||
+#ifdef WITH_SELINUX
|
||||
+#include <selinux/selinux.h>
|
||||
+#define SELINUX_ENABLED is_selinux_enabled()>0
|
||||
+#else
|
||||
+#define SELINUX_ENABLED 0
|
||||
+#endif
|
||||
+
|
||||
+#ifdef HELPER_COMPILE
|
||||
+#define PAMH_ARG_DECL(fname, ...) fname(__VA_ARGS__)
|
||||
+#define PAMH_ARG(...) __VA_ARGS__
|
||||
+#else
|
||||
+#define PAMH_ARG_DECL(fname, ...) fname(pam_handle_t *pamh, __VA_ARGS__)
|
||||
+#define PAMH_ARG(...) pamh, __VA_ARGS__
|
||||
+#endif
|
||||
+
|
||||
+#ifdef HELPER_COMPILE
|
||||
+void
|
||||
+helper_log_err(int err, const char *format, ...);
|
||||
+#endif
|
||||
+
|
||||
+PAMH_ARG_DECL(int
|
||||
+check_old_pass, const char *user, const char *newpass, int debug);
|
||||
+
|
||||
+PAMH_ARG_DECL(int
|
||||
+save_old_pass, const char *user, int howmany, int debug);
|
||||
|
||||
#endif /* __OPASSWD_H__ */
|
||||
diff -up Linux-PAM-1.3.0/modules/pam_pwhistory/pam_pwhistory.c.pwhhelper Linux-PAM-1.3.0/modules/pam_pwhistory/pam_pwhistory.c
|
||||
--- Linux-PAM-1.3.0/modules/pam_pwhistory/pam_pwhistory.c.pwhhelper 2016-04-04 11:22:28.000000000 +0200
|
||||
+++ Linux-PAM-1.3.0/modules/pam_pwhistory/pam_pwhistory.c 2016-05-06 15:19:31.610785512 +0200
|
||||
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2012 Thorsten Kukuk
|
||||
* Author: Thorsten Kukuk <kukuk@thkukuk.de>
|
||||
+ * Copyright (c) 2013 Red Hat, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@@ -46,10 +47,14 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
-#include <shadow.h>
|
||||
#include <syslog.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
+#include <sys/time.h>
|
||||
+#include <sys/resource.h>
|
||||
+#include <sys/wait.h>
|
||||
+#include <signal.h>
|
||||
+#include <fcntl.h>
|
||||
|
||||
#include <security/pam_modules.h>
|
||||
#include <security/pam_modutil.h>
|
||||
@@ -59,6 +64,7 @@
|
||||
#include "opasswd.h"
|
||||
|
||||
#define DEFAULT_BUFLEN 2048
|
||||
+#define MAX_FD_NO 20000
|
||||
|
||||
struct options_t {
|
||||
int debug;
|
||||
@@ -102,6 +108,184 @@ parse_option (pam_handle_t *pamh, const
|
||||
pam_syslog (pamh, LOG_ERR, "pam_pwhistory: unknown option: %s", argv);
|
||||
}
|
||||
|
||||
+static int
|
||||
+run_save_helper(pam_handle_t *pamh, const char *user,
|
||||
+ int howmany, int debug)
|
||||
+{
|
||||
+ int retval, child;
|
||||
+ struct sigaction newsa, oldsa;
|
||||
+
|
||||
+ memset(&newsa, '\0', sizeof(newsa));
|
||||
+ newsa.sa_handler = SIG_DFL;
|
||||
+ sigaction(SIGCHLD, &newsa, &oldsa);
|
||||
+
|
||||
+ child = fork();
|
||||
+ if (child == 0)
|
||||
+ {
|
||||
+ int i = 0;
|
||||
+ struct rlimit rlim;
|
||||
+ int dummyfds[2];
|
||||
+ static char *envp[] = { NULL };
|
||||
+ char *args[] = { NULL, NULL, NULL, NULL, NULL, NULL };
|
||||
+
|
||||
+ /* replace std file descriptors with a dummy pipe */
|
||||
+ if (pipe2(dummyfds, O_NONBLOCK) == 0)
|
||||
+ {
|
||||
+ dup2(dummyfds[0], STDIN_FILENO);
|
||||
+ dup2(dummyfds[1], STDOUT_FILENO);
|
||||
+ dup2(dummyfds[1], STDERR_FILENO);
|
||||
+ }
|
||||
+
|
||||
+ if (getrlimit(RLIMIT_NOFILE,&rlim) == 0)
|
||||
+ {
|
||||
+ if (rlim.rlim_max >= MAX_FD_NO)
|
||||
+ rlim.rlim_max = MAX_FD_NO;
|
||||
+ for (i = STDERR_FILENO + 1; i < (int)rlim.rlim_max; i++)
|
||||
+ {
|
||||
+ if (i != dummyfds[0])
|
||||
+ close(i);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* exec binary helper */
|
||||
+ args[0] = strdup(PWHISTORY_HELPER);
|
||||
+ args[1] = strdup("save");
|
||||
+ args[2] = x_strdup(user);
|
||||
+ asprintf(&args[3], "%d", howmany);
|
||||
+ asprintf(&args[4], "%d", debug);
|
||||
+
|
||||
+ execve(args[0], args, envp);
|
||||
+
|
||||
+ _exit(PAM_SYSTEM_ERR);
|
||||
+ }
|
||||
+ else if (child > 0)
|
||||
+ {
|
||||
+ /* wait for child */
|
||||
+ int rc = 0;
|
||||
+ rc = waitpid(child, &retval, 0); /* wait for helper to complete */
|
||||
+ if (rc < 0)
|
||||
+ {
|
||||
+ pam_syslog(pamh, LOG_ERR, "pwhistory_helper save waitpid returned %d: %m", rc);
|
||||
+ retval = PAM_SYSTEM_ERR;
|
||||
+ }
|
||||
+ else if (!WIFEXITED(retval))
|
||||
+ {
|
||||
+ pam_syslog(pamh, LOG_ERR, "pwhistory_helper save abnormal exit: %d", retval);
|
||||
+ retval = PAM_SYSTEM_ERR;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ retval = WEXITSTATUS(retval);
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ retval = PAM_SYSTEM_ERR;
|
||||
+ }
|
||||
+
|
||||
+ sigaction(SIGCHLD, &oldsa, NULL); /* restore old signal handler */
|
||||
+
|
||||
+ return retval;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+run_check_helper(pam_handle_t *pamh, const char *user,
|
||||
+ const char *newpass, int debug)
|
||||
+{
|
||||
+ int retval, child, fds[2];
|
||||
+ struct sigaction newsa, oldsa;
|
||||
+
|
||||
+ /* create a pipe for the password */
|
||||
+ if (pipe(fds) != 0)
|
||||
+ return PAM_SYSTEM_ERR;
|
||||
+
|
||||
+ memset(&newsa, '\0', sizeof(newsa));
|
||||
+ newsa.sa_handler = SIG_DFL;
|
||||
+ sigaction(SIGCHLD, &newsa, &oldsa);
|
||||
+
|
||||
+ child = fork();
|
||||
+ if (child == 0)
|
||||
+ {
|
||||
+ int i = 0;
|
||||
+ struct rlimit rlim;
|
||||
+ int dummyfds[2];
|
||||
+ static char *envp[] = { NULL };
|
||||
+ char *args[] = { NULL, NULL, NULL, NULL, NULL };
|
||||
+
|
||||
+ /* reopen stdin as pipe */
|
||||
+ dup2(fds[0], STDIN_FILENO);
|
||||
+
|
||||
+ /* replace std file descriptors with a dummy pipe */
|
||||
+ if (pipe2(dummyfds, O_NONBLOCK) == 0)
|
||||
+ {
|
||||
+ dup2(dummyfds[1], STDOUT_FILENO);
|
||||
+ dup2(dummyfds[1], STDERR_FILENO);
|
||||
+ }
|
||||
+
|
||||
+ if (getrlimit(RLIMIT_NOFILE,&rlim) == 0)
|
||||
+ {
|
||||
+ if (rlim.rlim_max >= MAX_FD_NO)
|
||||
+ rlim.rlim_max = MAX_FD_NO;
|
||||
+ for (i = STDERR_FILENO + 1; i < (int)rlim.rlim_max; i++)
|
||||
+ {
|
||||
+ if (i != dummyfds[0])
|
||||
+ close(i);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* exec binary helper */
|
||||
+ args[0] = strdup(PWHISTORY_HELPER);
|
||||
+ args[1] = strdup("check");
|
||||
+ args[2] = x_strdup(user);
|
||||
+ asprintf(&args[3], "%d", debug);
|
||||
+
|
||||
+ execve(args[0], args, envp);
|
||||
+
|
||||
+ _exit(PAM_SYSTEM_ERR);
|
||||
+ }
|
||||
+ else if (child > 0)
|
||||
+ {
|
||||
+ /* wait for child */
|
||||
+ int rc = 0;
|
||||
+ if (newpass == NULL)
|
||||
+ newpass = "";
|
||||
+
|
||||
+ /* send the password to the child */
|
||||
+ if (write(fds[1], newpass, strlen(newpass)+1) == -1)
|
||||
+ {
|
||||
+ pam_syslog(pamh, LOG_ERR, "Cannot send password to helper: %m");
|
||||
+ retval = PAM_SYSTEM_ERR;
|
||||
+ }
|
||||
+ newpass = NULL;
|
||||
+ close(fds[0]); /* close here to avoid possible SIGPIPE above */
|
||||
+ close(fds[1]);
|
||||
+ rc = waitpid(child, &retval, 0); /* wait for helper to complete */
|
||||
+ if (rc < 0)
|
||||
+ {
|
||||
+ pam_syslog(pamh, LOG_ERR, "pwhistory_helper check waitpid returned %d: %m", rc);
|
||||
+ retval = PAM_SYSTEM_ERR;
|
||||
+ }
|
||||
+ else if (!WIFEXITED(retval))
|
||||
+ {
|
||||
+ pam_syslog(pamh, LOG_ERR, "pwhistory_helper check abnormal exit: %d", retval);
|
||||
+ retval = PAM_SYSTEM_ERR;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ retval = WEXITSTATUS(retval);
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ close(fds[0]);
|
||||
+ close(fds[1]);
|
||||
+ retval = PAM_SYSTEM_ERR;
|
||||
+ }
|
||||
+
|
||||
+ sigaction(SIGCHLD, &oldsa, NULL); /* restore old signal handler */
|
||||
+
|
||||
+ return retval;
|
||||
+}
|
||||
|
||||
/* This module saves the current crypted password in /etc/security/opasswd
|
||||
and then compares the new password with all entries in this file. */
|
||||
@@ -109,7 +293,6 @@ parse_option (pam_handle_t *pamh, const
|
||||
int
|
||||
pam_sm_chauthtok (pam_handle_t *pamh, int flags, int argc, const char **argv)
|
||||
{
|
||||
- struct passwd *pwd;
|
||||
const char *newpass;
|
||||
const char *user;
|
||||
int retval, tries;
|
||||
@@ -154,31 +337,13 @@ pam_sm_chauthtok (pam_handle_t *pamh, in
|
||||
return PAM_SUCCESS;
|
||||
}
|
||||
|
||||
- pwd = pam_modutil_getpwnam (pamh, user);
|
||||
- if (pwd == NULL)
|
||||
- return PAM_USER_UNKNOWN;
|
||||
-
|
||||
- if ((strcmp(pwd->pw_passwd, "x") == 0) ||
|
||||
- ((pwd->pw_passwd[0] == '#') &&
|
||||
- (pwd->pw_passwd[1] == '#') &&
|
||||
- (strcmp(pwd->pw_name, pwd->pw_passwd + 2) == 0)))
|
||||
- {
|
||||
- struct spwd *spw = pam_modutil_getspnam (pamh, user);
|
||||
- if (spw == NULL)
|
||||
- return PAM_USER_UNKNOWN;
|
||||
+ retval = save_old_pass (pamh, user, options.remember, options.debug);
|
||||
|
||||
- retval = save_old_pass (pamh, user, pwd->pw_uid, spw->sp_pwdp,
|
||||
- options.remember, options.debug);
|
||||
- if (retval != PAM_SUCCESS)
|
||||
- return retval;
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- retval = save_old_pass (pamh, user, pwd->pw_uid, pwd->pw_passwd,
|
||||
- options.remember, options.debug);
|
||||
- if (retval != PAM_SUCCESS)
|
||||
- return retval;
|
||||
- }
|
||||
+ if (retval == PAM_PWHISTORY_RUN_HELPER)
|
||||
+ retval = run_save_helper(pamh, user, options.remember, options.debug);
|
||||
+
|
||||
+ if (retval != PAM_SUCCESS)
|
||||
+ return retval;
|
||||
|
||||
newpass = NULL;
|
||||
tries = 0;
|
||||
@@ -207,8 +372,11 @@ pam_sm_chauthtok (pam_handle_t *pamh, in
|
||||
if (options.debug)
|
||||
pam_syslog (pamh, LOG_DEBUG, "check against old password file");
|
||||
|
||||
- if (check_old_pass (pamh, user, newpass,
|
||||
- options.debug) != PAM_SUCCESS)
|
||||
+ retval = check_old_pass (pamh, user, newpass, options.debug);
|
||||
+ if (retval == PAM_PWHISTORY_RUN_HELPER)
|
||||
+ retval = run_check_helper(pamh, user, newpass, options.debug);
|
||||
+
|
||||
+ if (retval != PAM_SUCCESS)
|
||||
{
|
||||
if (getuid() || options.enforce_for_root ||
|
||||
(flags & PAM_CHANGE_EXPIRED_AUTHTOK))
|
||||
diff -up Linux-PAM-1.3.0/modules/pam_pwhistory/pwhistory_helper.c.pwhhelper Linux-PAM-1.3.0/modules/pam_pwhistory/pwhistory_helper.c
|
||||
--- Linux-PAM-1.3.0/modules/pam_pwhistory/pwhistory_helper.c.pwhhelper 2016-05-06 15:18:42.308637957 +0200
|
||||
+++ Linux-PAM-1.3.0/modules/pam_pwhistory/pwhistory_helper.c 2016-05-06 15:18:42.308637957 +0200
|
||||
@@ -0,0 +1,209 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2013 Red Hat, Inc.
|
||||
+ * Author: Tomas Mraz <tmraz@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 <errno.h>
|
||||
+#include <unistd.h>
|
||||
+#include <signal.h>
|
||||
+#include <security/_pam_types.h>
|
||||
+#include <security/_pam_macros.h>
|
||||
+#include "opasswd.h"
|
||||
+
|
||||
+#define MAXPASS 200
|
||||
+
|
||||
+static void
|
||||
+su_sighandler(int sig)
|
||||
+{
|
||||
+#ifndef SA_RESETHAND
|
||||
+ /* emulate the behaviour of the SA_RESETHAND flag */
|
||||
+ if ( sig == SIGILL || sig == SIGTRAP || sig == SIGBUS || sig = SIGSERV ) {
|
||||
+ struct sigaction sa;
|
||||
+ memset(&sa, '\0', sizeof(sa));
|
||||
+ sa.sa_handler = SIG_DFL;
|
||||
+ sigaction(sig, &sa, NULL);
|
||||
+ }
|
||||
+#endif
|
||||
+ if (sig > 0) {
|
||||
+ _exit(sig);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+setup_signals(void)
|
||||
+{
|
||||
+ struct sigaction action; /* posix signal structure */
|
||||
+
|
||||
+ /*
|
||||
+ * Setup signal handlers
|
||||
+ */
|
||||
+ (void) memset((void *) &action, 0, sizeof(action));
|
||||
+ action.sa_handler = su_sighandler;
|
||||
+#ifdef SA_RESETHAND
|
||||
+ action.sa_flags = SA_RESETHAND;
|
||||
+#endif
|
||||
+ (void) sigaction(SIGILL, &action, NULL);
|
||||
+ (void) sigaction(SIGTRAP, &action, NULL);
|
||||
+ (void) sigaction(SIGBUS, &action, NULL);
|
||||
+ (void) sigaction(SIGSEGV, &action, NULL);
|
||||
+ action.sa_handler = SIG_IGN;
|
||||
+ action.sa_flags = 0;
|
||||
+ (void) sigaction(SIGTERM, &action, NULL);
|
||||
+ (void) sigaction(SIGHUP, &action, NULL);
|
||||
+ (void) sigaction(SIGINT, &action, NULL);
|
||||
+ (void) sigaction(SIGQUIT, &action, NULL);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+read_passwords(int fd, int npass, char **passwords)
|
||||
+{
|
||||
+ int rbytes = 0;
|
||||
+ int offset = 0;
|
||||
+ int i = 0;
|
||||
+ char *pptr;
|
||||
+ while (npass > 0)
|
||||
+ {
|
||||
+ rbytes = read(fd, passwords[i]+offset, MAXPASS-offset);
|
||||
+
|
||||
+ if (rbytes < 0)
|
||||
+ {
|
||||
+ if (errno == EINTR) continue;
|
||||
+ break;
|
||||
+ }
|
||||
+ if (rbytes == 0)
|
||||
+ break;
|
||||
+
|
||||
+ while (npass > 0 && (pptr=memchr(passwords[i]+offset, '\0', rbytes))
|
||||
+ != NULL)
|
||||
+ {
|
||||
+ rbytes -= pptr - (passwords[i]+offset) + 1;
|
||||
+ i++;
|
||||
+ offset = 0;
|
||||
+ npass--;
|
||||
+ if (rbytes > 0)
|
||||
+ {
|
||||
+ if (npass > 0)
|
||||
+ memcpy(passwords[i], pptr+1, rbytes);
|
||||
+ memset(pptr+1, '\0', rbytes);
|
||||
+ }
|
||||
+ }
|
||||
+ offset += rbytes;
|
||||
+ }
|
||||
+
|
||||
+ /* clear up */
|
||||
+ if (offset > 0 && npass > 0)
|
||||
+ memset(passwords[i], '\0', offset);
|
||||
+
|
||||
+ return i;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static int
|
||||
+check_history(const char *user, const char *debug)
|
||||
+{
|
||||
+ char pass[MAXPASS + 1];
|
||||
+ char *passwords[] = { pass };
|
||||
+ int npass;
|
||||
+ int dbg = atoi(debug); /* no need to be too fancy here */
|
||||
+ int retval;
|
||||
+
|
||||
+ /* read the password from stdin (a pipe from the pam_pwhistory module) */
|
||||
+ npass = read_passwords(STDIN_FILENO, 1, passwords);
|
||||
+
|
||||
+ if (npass != 1)
|
||||
+ { /* is it a valid password? */
|
||||
+ helper_log_err(LOG_DEBUG, "no password supplied");
|
||||
+ return PAM_AUTHTOK_ERR;
|
||||
+ }
|
||||
+
|
||||
+ retval = check_old_pass(user, pass, dbg);
|
||||
+
|
||||
+ memset(pass, '\0', MAXPASS); /* clear memory of the password */
|
||||
+
|
||||
+ return retval;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+save_history(const char *user, const char *howmany, const char *debug)
|
||||
+{
|
||||
+ int num = atoi(howmany);
|
||||
+ int dbg = atoi(debug); /* no need to be too fancy here */
|
||||
+ int retval;
|
||||
+
|
||||
+ retval = save_old_pass(user, num, dbg);
|
||||
+
|
||||
+ return retval;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+main(int argc, char *argv[])
|
||||
+{
|
||||
+ const char *option;
|
||||
+ const char *user;
|
||||
+
|
||||
+ /*
|
||||
+ * Catch or ignore as many signal as possible.
|
||||
+ */
|
||||
+ setup_signals();
|
||||
+
|
||||
+ /*
|
||||
+ * we establish that this program is running with non-tty stdin.
|
||||
+ * this is to discourage casual use.
|
||||
+ */
|
||||
+
|
||||
+ if (isatty(STDIN_FILENO) || argc < 4)
|
||||
+ {
|
||||
+ fprintf(stderr,
|
||||
+ "This binary is not designed for running in this way.\n");
|
||||
+ sleep(10); /* this should discourage/annoy the user */
|
||||
+ return PAM_SYSTEM_ERR;
|
||||
+ }
|
||||
+
|
||||
+ option = argv[1];
|
||||
+ user = argv[2];
|
||||
+
|
||||
+ if (strcmp(option, "check") == 0 && argc == 4)
|
||||
+ return check_history(user, argv[3]);
|
||||
+ else if (strcmp(option, "save") == 0 && argc == 5)
|
||||
+ return save_history(user, argv[3], argv[4]);
|
||||
+
|
||||
+ return PAM_SYSTEM_ERR;
|
||||
+}
|
||||
+
|
||||
diff -up Linux-PAM-1.3.0/modules/pam_pwhistory/pwhistory_helper.8.xml.pwhhelper Linux-PAM-1.3.0/modules/pam_pwhistory/pwhistory_helper.8.xml
|
||||
--- Linux-PAM-1.3.0/modules/pam_pwhistory/pwhistory_helper.8.xml.pwhhelper 2016-05-06 15:18:42.308637957 +0200
|
||||
+++ Linux-PAM-1.3.0/modules/pam_pwhistory/pwhistory_helper.8.xml 2016-05-06 15:18:42.308637957 +0200
|
||||
@@ -0,0 +1,68 @@
|
||||
+<?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_helper">
|
||||
+
|
||||
+ <refmeta>
|
||||
+ <refentrytitle>pwhistory_helper</refentrytitle>
|
||||
+ <manvolnum>8</manvolnum>
|
||||
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
|
||||
+ </refmeta>
|
||||
+
|
||||
+ <refnamediv id="pwhistory_helper-name">
|
||||
+ <refname>pwhistory_helper</refname>
|
||||
+ <refpurpose>Helper binary that transfers password hashes from passwd or shadow to opasswd</refpurpose>
|
||||
+ </refnamediv>
|
||||
+
|
||||
+ <refsynopsisdiv>
|
||||
+ <cmdsynopsis id="pwhistory_helper-cmdsynopsis">
|
||||
+ <command>pwhistory_helper</command>
|
||||
+ <arg choice="opt">
|
||||
+ ...
|
||||
+ </arg>
|
||||
+ </cmdsynopsis>
|
||||
+ </refsynopsisdiv>
|
||||
+
|
||||
+ <refsect1 id="pwhistory_helper-description">
|
||||
+
|
||||
+ <title>DESCRIPTION</title>
|
||||
+
|
||||
+ <para>
|
||||
+ <emphasis>pwhistory_helper</emphasis> is a helper program for the
|
||||
+ <emphasis>pam_pwhistory</emphasis> module that transfers password hashes
|
||||
+ from passwd or shadow file to the opasswd file and checks a password
|
||||
+ supplied by user against the existing hashes in the opasswd file.
|
||||
+ </para>
|
||||
+
|
||||
+ <para>
|
||||
+ The purpose of the helper is to enable tighter confinement of
|
||||
+ login and password changing services. The helper is thus called only
|
||||
+ when SELinux is enabled on the system.
|
||||
+ </para>
|
||||
+
|
||||
+ <para>
|
||||
+ The interface of the helper - command line options, and input/output
|
||||
+ data format are internal to the <emphasis>pam_pwhistory</emphasis>
|
||||
+ module and it should not be called directly from applications.
|
||||
+ </para>
|
||||
+ </refsect1>
|
||||
+
|
||||
+ <refsect1 id='pwhistory_helper-see_also'>
|
||||
+ <title>SEE ALSO</title>
|
||||
+ <para>
|
||||
+ <citerefentry>
|
||||
+ <refentrytitle>pam_pwhistory</refentrytitle><manvolnum>8</manvolnum>
|
||||
+ </citerefentry>
|
||||
+ </para>
|
||||
+ </refsect1>
|
||||
+
|
||||
+ <refsect1 id='pwhistory_helper-author'>
|
||||
+ <title>AUTHOR</title>
|
||||
+ <para>
|
||||
+ Written by Tomas Mraz based on the code originally in
|
||||
+ <emphasis>pam_pwhistory and pam_unix</emphasis> modules.
|
||||
+ </para>
|
||||
+ </refsect1>
|
||||
+
|
||||
+</refentry>
|
@ -0,0 +1,35 @@
|
||||
From b429ea18b1c9c8953df5169c6a453b4255a6f23d Mon Sep 17 00:00:00 2001
|
||||
From: Iker Pedrosa <ikerpedrosam@gmail.com>
|
||||
Date: Thu, 27 Feb 2020 11:48:47 +0100
|
||||
Subject: [PATCH] pam_tty_audit: if kernel audit is disabled return PAM_IGNORE
|
||||
|
||||
If kernel audit is disabled the socket open will return
|
||||
EPROTONOSUPPORT.
|
||||
Return PAM_IGNORE from pam_tty_audit and log a warning
|
||||
in this situation so login is not blocked by the module.
|
||||
---
|
||||
modules/pam_tty_audit/pam_tty_audit.c | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
diff --git a/modules/pam_tty_audit/pam_tty_audit.c b/modules/pam_tty_audit/pam_tty_audit.c
|
||||
index 7dbcada2..589c60a2 100644
|
||||
--- a/modules/pam_tty_audit/pam_tty_audit.c
|
||||
+++ b/modules/pam_tty_audit/pam_tty_audit.c
|
||||
@@ -351,6 +351,14 @@ pam_sm_open_session (pam_handle_t *pamh, int flags, int argc, const char **argv)
|
||||
|
||||
fd = nl_open ();
|
||||
if (fd == -1
|
||||
+ && errno == EPROTONOSUPPORT)
|
||||
+ {
|
||||
+ pam_syslog (pamh, LOG_WARNING, "unable to open audit socket, audit not "
|
||||
+ "supported; tty_audit skipped");
|
||||
+ free (old_status);
|
||||
+ return PAM_IGNORE;
|
||||
+ }
|
||||
+ else if (fd == -1
|
||||
|| nl_send (fd, AUDIT_TTY_GET, 0, NULL, 0) != 0
|
||||
|| nl_recv (fd, AUDIT_TTY_GET, old_status, sizeof (*old_status)) != 0)
|
||||
{
|
||||
--
|
||||
2.25.2
|
||||
|
@ -0,0 +1,88 @@
|
||||
From 27d04a849fd9f9cfd4b35eb80d687817830183df Mon Sep 17 00:00:00 2001
|
||||
From: Tomas Mraz <tmraz@fedoraproject.org>
|
||||
Date: Wed, 7 Aug 2019 12:22:55 +0200
|
||||
Subject: [PATCH] pam_get_authtok_verify: Avoid duplicate password verification
|
||||
|
||||
If password was already verified by previous modules in the stack
|
||||
it does not need to be verified by pam_get_authtok_verify either.
|
||||
|
||||
* libpam/pam_get_authtok.c (pam_get_authtok_internal): Set the authtok_verified
|
||||
appropriately.
|
||||
(pam_get_authtok_verify): Do not prompt if authtok_verified is set and
|
||||
set it when the password is verified.
|
||||
* libpam/pam_private.h: Add authtok_verified to the pam handle struct.
|
||||
* libpam/pam_start.c (pam_start): Initialize authtok_verified.
|
||||
---
|
||||
libpam/pam_get_authtok.c | 10 ++++++++++
|
||||
libpam/pam_private.h | 1 +
|
||||
libpam/pam_start.c | 1 +
|
||||
3 files changed, 12 insertions(+)
|
||||
|
||||
diff --git a/libpam/pam_get_authtok.c b/libpam/pam_get_authtok.c
|
||||
index 800c6e5..99eb25f 100644
|
||||
--- a/libpam/pam_get_authtok.c
|
||||
+++ b/libpam/pam_get_authtok.c
|
||||
@@ -140,6 +140,8 @@ pam_get_authtok_internal (pam_handle_t *pamh, int item,
|
||||
}
|
||||
else if (chpass)
|
||||
{
|
||||
+ pamh->authtok_verified = 0;
|
||||
+
|
||||
retval = pam_prompt (pamh, PAM_PROMPT_ECHO_OFF, &resp[0],
|
||||
PROMPT1, authtok_type,
|
||||
strlen (authtok_type) > 0?" ":"");
|
||||
@@ -184,6 +186,9 @@ pam_get_authtok_internal (pam_handle_t *pamh, int item,
|
||||
if (retval != PAM_SUCCESS)
|
||||
return retval;
|
||||
|
||||
+ if (chpass > 1)
|
||||
+ pamh->authtok_verified = 1;
|
||||
+
|
||||
return pam_get_item(pamh, item, (const void **)authtok);
|
||||
}
|
||||
|
||||
@@ -214,6 +219,9 @@ pam_get_authtok_verify (pam_handle_t *pamh, const char **authtok,
|
||||
if (authtok == NULL || pamh->choice != PAM_CHAUTHTOK)
|
||||
return PAM_SYSTEM_ERR;
|
||||
|
||||
+ if (pamh->authtok_verified)
|
||||
+ return pam_get_item (pamh, PAM_AUTHTOK, (const void **)authtok);
|
||||
+
|
||||
if (prompt != NULL)
|
||||
{
|
||||
retval = pam_prompt (pamh, PAM_PROMPT_ECHO_OFF, &resp,
|
||||
@@ -252,5 +260,7 @@ pam_get_authtok_verify (pam_handle_t *pamh, const char **authtok,
|
||||
if (retval != PAM_SUCCESS)
|
||||
return retval;
|
||||
|
||||
+ pamh->authtok_verified = 1;
|
||||
+
|
||||
return pam_get_item(pamh, PAM_AUTHTOK, (const void **)authtok);
|
||||
}
|
||||
diff --git a/libpam/pam_private.h b/libpam/pam_private.h
|
||||
index 7ff9f75..58a26f5 100644
|
||||
--- a/libpam/pam_private.h
|
||||
+++ b/libpam/pam_private.h
|
||||
@@ -172,6 +172,7 @@ struct pam_handle {
|
||||
#ifdef HAVE_LIBAUDIT
|
||||
int audit_state; /* keep track of reported audit messages */
|
||||
#endif
|
||||
+ int authtok_verified;
|
||||
};
|
||||
|
||||
/* Values for select arg to _pam_dispatch() */
|
||||
diff --git a/libpam/pam_start.c b/libpam/pam_start.c
|
||||
index 328416d..e27c64b 100644
|
||||
--- a/libpam/pam_start.c
|
||||
+++ b/libpam/pam_start.c
|
||||
@@ -94,6 +94,7 @@ int pam_start (
|
||||
#endif
|
||||
(*pamh)->xdisplay = NULL;
|
||||
(*pamh)->authtok_type = NULL;
|
||||
+ (*pamh)->authtok_verified = 0;
|
||||
memset (&((*pamh)->xauth), 0, sizeof ((*pamh)->xauth));
|
||||
|
||||
if (((*pamh)->pam_conversation = (struct pam_conv *)
|
||||
--
|
||||
2.20.1
|
||||
|
@ -0,0 +1,11 @@
|
||||
diff -up Linux-PAM-1.3.1/modules/pam_console/sed-static.console-build Linux-PAM-1.3.1/modules/pam_console/sed-static
|
||||
--- Linux-PAM-1.3.1/modules/pam_console/sed-static.console-build 2014-01-31 14:17:53.000000000 +0100
|
||||
+++ Linux-PAM-1.3.1/modules/pam_console/sed-static 2018-09-10 15:06:04.115302315 +0200
|
||||
@@ -13,6 +13,7 @@ sed '
|
||||
/^YY_BUFFER_STATE yy_scan_buffer/s/^/STATIC /
|
||||
/^YY_BUFFER_STATE yy_scan_string/s/^/STATIC /
|
||||
/^void yy_switch_to_buffer/s/^/STATIC /
|
||||
+/^extern int yylex/s/^extern /STATIC /
|
||||
/define YY_DECL int yylex/s/YY_DECL /YY_DECL STATIC /
|
||||
/^int yyparse/s/^/STATIC /
|
||||
/^void yyrestart/s/^/STATIC /
|
@ -0,0 +1,185 @@
|
||||
diff --git a/libpam/pam_handlers.c b/libpam/pam_handlers.c
|
||||
index 106ef7c..b2e94c7 100644
|
||||
--- a/libpam/pam_handlers.c
|
||||
+++ b/libpam/pam_handlers.c
|
||||
@@ -282,7 +282,6 @@ _pam_open_config_file(pam_handle_t *pamh
|
||||
{
|
||||
char *p;
|
||||
FILE *f;
|
||||
- int err = 0;
|
||||
|
||||
/* Absolute path */
|
||||
if (service[0] == '/') {
|
||||
diff --git a/libpam_misc/misc_conv.c b/libpam_misc/misc_conv.c
|
||||
index be53f34..07dce36 100644
|
||||
--- a/libpam_misc/misc_conv.c
|
||||
+++ b/libpam_misc/misc_conv.c
|
||||
@@ -211,7 +211,7 @@ static int read_string(int echo, const char *prompt, char **retstr)
|
||||
line[nc] = '\0';
|
||||
}
|
||||
*retstr = strdup(line);
|
||||
- _pam_overwrite(line);
|
||||
+ _pam_overwrite_n(line, sizeof(line));
|
||||
if (!*retstr) {
|
||||
D(("no memory for response string"));
|
||||
nc = -1;
|
||||
@@ -244,7 +244,7 @@ static int read_string(int echo, const char *prompt, char **retstr)
|
||||
D(("the timer appears to have expired"));
|
||||
|
||||
*retstr = NULL;
|
||||
- _pam_overwrite(line);
|
||||
+ _pam_overwrite_n(line, sizeof(line));
|
||||
|
||||
cleanexit:
|
||||
|
||||
diff --git a/modules/pam_access/pam_access.c b/modules/pam_access/pam_access.c
|
||||
index 80d885d..3801862 100644
|
||||
--- a/modules/pam_access/pam_access.c
|
||||
+++ b/modules/pam_access/pam_access.c
|
||||
@@ -806,7 +806,7 @@ pam_sm_authenticate (pam_handle_t *pamh, int flags UNUSED,
|
||||
const char *user=NULL;
|
||||
const void *void_from=NULL;
|
||||
const char *from;
|
||||
- const char const *default_config = PAM_ACCESS_CONFIG;
|
||||
+ const char * const default_config = PAM_ACCESS_CONFIG;
|
||||
struct passwd *user_pw;
|
||||
char hostname[MAXHOSTNAMELEN + 1];
|
||||
int rv;
|
||||
diff --git a/modules/pam_limits/pam_limits.c b/modules/pam_limits/pam_limits.c
|
||||
index 4bc4ae7..f8476b4 100644
|
||||
--- a/modules/pam_limits/pam_limits.c
|
||||
+++ b/modules/pam_limits/pam_limits.c
|
||||
@@ -342,7 +342,7 @@ static const char *lnames[RLIM_NLIMITS] = {
|
||||
#endif
|
||||
};
|
||||
|
||||
-static int str2rlimit(char *name) {
|
||||
+static int str2rlimit(const char *name) {
|
||||
int i;
|
||||
if (!name || *name == '\0')
|
||||
return -1;
|
||||
@@ -352,7 +352,7 @@ static int str2rlimit(char *name) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
-static rlim_t str2rlim_t(char *value) {
|
||||
+static rlim_t str2rlim_t(const char *value) {
|
||||
unsigned long long rlimit = 0;
|
||||
|
||||
if (!value) return (rlim_t)rlimit;
|
||||
@@ -384,7 +384,7 @@ static void parse_kernel_limits(pam_handle_t *pamh, struct pam_limit_s *pl, int
|
||||
FILE *limitsfile;
|
||||
const char *proclimits = "/proc/1/limits";
|
||||
char line[256];
|
||||
- char *units, *hard, *soft, *name;
|
||||
+ const char *units, *hard, *soft, *name;
|
||||
|
||||
if (!(limitsfile = fopen(proclimits, "r"))) {
|
||||
pam_syslog(pamh, LOG_WARNING, "Could not read %s (%s), using PAM defaults", proclimits, strerror(errno));
|
||||
diff --git a/modules/pam_loginuid/pam_loginuid.c b/modules/pam_loginuid/pam_loginuid.c
|
||||
index 96bfd98..66d202c 100644
|
||||
--- a/modules/pam_loginuid/pam_loginuid.c
|
||||
+++ b/modules/pam_loginuid/pam_loginuid.c
|
||||
@@ -64,7 +64,7 @@ static int set_loginuid(pam_handle_t *pamh, uid_t uid)
|
||||
fd = open("/proc/self/uid_map", O_RDONLY);
|
||||
if (fd >= 0) {
|
||||
count = pam_modutil_read(fd, uid_map, sizeof(uid_map));
|
||||
- if (strncmp(uid_map, host_uid_map, count) != 0)
|
||||
+ if (count <= 0 || strncmp(uid_map, host_uid_map, count) != 0)
|
||||
rc = PAM_IGNORE;
|
||||
close(fd);
|
||||
}
|
||||
diff --git a/modules/pam_mkhomedir/mkhomedir_helper.c b/modules/pam_mkhomedir/mkhomedir_helper.c
|
||||
index 9e204c1..4b8d6b7 100644
|
||||
--- a/modules/pam_mkhomedir/mkhomedir_helper.c
|
||||
+++ b/modules/pam_mkhomedir/mkhomedir_helper.c
|
||||
@@ -232,6 +232,8 @@ create_homedir(const struct passwd *pwd,
|
||||
{
|
||||
pam_syslog(NULL, LOG_DEBUG,
|
||||
"unable to open or stat src file %s: %m", newsource);
|
||||
+ if (srcfd >= 0)
|
||||
+ close(srcfd);
|
||||
closedir(d);
|
||||
|
||||
#ifndef PATH_MAX
|
||||
diff --git a/modules/pam_namespace/pam_namespace.c b/modules/pam_namespace/pam_namespace.c
|
||||
index f541f89..85f5efa 100644
|
||||
--- a/modules/pam_namespace/pam_namespace.c
|
||||
+++ b/modules/pam_namespace/pam_namespace.c
|
||||
@@ -1418,6 +1418,7 @@ static int create_instance(struct polydir_s *polyptr, char *ipath, struct stat *
|
||||
if (fstat(fd, &newstatbuf) < 0) {
|
||||
pam_syslog(idata->pamh, LOG_ERR, "Error stating %s, %m",
|
||||
ipath);
|
||||
+ close(fd);
|
||||
rmdir(ipath);
|
||||
return PAM_SESSION_ERR;
|
||||
}
|
||||
diff --git a/modules/pam_pwhistory/opasswd.c b/modules/pam_pwhistory/opasswd.c
|
||||
index e6cf346..813f579 100644
|
||||
--- a/modules/pam_pwhistory/opasswd.c
|
||||
+++ b/modules/pam_pwhistory/opasswd.c
|
||||
@@ -326,6 +326,9 @@ save_old_pass (pam_handle_t *pamh, const char *user, uid_t uid,
|
||||
n = strlen (buf);
|
||||
#endif /* HAVE_GETLINE / HAVE_GETDELIM */
|
||||
|
||||
+ if (n < 1)
|
||||
+ break;
|
||||
+
|
||||
cp = buf;
|
||||
save = strdup (buf); /* Copy to write the original data back. */
|
||||
if (save == NULL)
|
||||
@@ -336,9 +339,6 @@ save_old_pass (pam_handle_t *pamh, const char *user, uid_t uid,
|
||||
goto error_opasswd;
|
||||
}
|
||||
|
||||
- if (n < 1)
|
||||
- break;
|
||||
-
|
||||
tmp = strchr (cp, '#'); /* remove comments */
|
||||
if (tmp)
|
||||
*tmp = '\0';
|
||||
diff --git a/modules/pam_rootok/pam_rootok.c b/modules/pam_rootok/pam_rootok.c
|
||||
index 17baabe..a9d9140 100644
|
||||
--- a/modules/pam_rootok/pam_rootok.c
|
||||
+++ b/modules/pam_rootok/pam_rootok.c
|
||||
@@ -66,14 +66,17 @@ log_callback (int type, const char *fmt, ...)
|
||||
int audit_fd;
|
||||
va_list ap;
|
||||
|
||||
- va_start(ap, fmt);
|
||||
#ifdef HAVE_LIBAUDIT
|
||||
audit_fd = audit_open();
|
||||
|
||||
if (audit_fd >= 0) {
|
||||
char *buf;
|
||||
+ int ret;
|
||||
|
||||
- if (vasprintf (&buf, fmt, ap) < 0)
|
||||
+ va_start(ap, fmt);
|
||||
+ ret = vasprintf (&buf, fmt, ap);
|
||||
+ va_end(ap);
|
||||
+ if (ret < 0)
|
||||
return 0;
|
||||
audit_log_user_avc_message(audit_fd, AUDIT_USER_AVC, buf, NULL, NULL,
|
||||
NULL, 0);
|
||||
@@ -83,6 +86,7 @@ log_callback (int type, const char *fmt, ...)
|
||||
}
|
||||
|
||||
#endif
|
||||
+ va_start(ap, fmt);
|
||||
vsyslog (LOG_USER | LOG_INFO, fmt, ap);
|
||||
va_end(ap);
|
||||
return 0;
|
||||
diff --git a/modules/pam_sepermit/pam_sepermit.c b/modules/pam_sepermit/pam_sepermit.c
|
||||
index c653290..f37af0f 100644
|
||||
--- a/modules/pam_sepermit/pam_sepermit.c
|
||||
+++ b/modules/pam_sepermit/pam_sepermit.c
|
||||
@@ -353,7 +353,7 @@ sepermit_match(pam_handle_t *pamh, const char *cfgfile, const char *user,
|
||||
if (*sense == PAM_SUCCESS) {
|
||||
if (ignore)
|
||||
*sense = PAM_IGNORE;
|
||||
- if (geteuid() == 0 && exclusive && get_loginuid(pamh) == -1)
|
||||
+ if (geteuid() == 0 && exclusive && get_loginuid(pamh) == (uid_t)-1)
|
||||
if (sepermit_lock(pamh, user, debug) < 0)
|
||||
*sense = PAM_AUTH_ERR;
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
diff -up Linux-PAM-1.3.1/modules/pam_faillock/faillock.c.faillock-create-tallydir Linux-PAM-1.3.1/modules/pam_faillock/faillock.c
|
||||
--- Linux-PAM-1.3.1/modules/pam_faillock/faillock.c.faillock-create-tallydir 2024-01-08 11:32:02.122392119 +0100
|
||||
+++ Linux-PAM-1.3.1/modules/pam_faillock/faillock.c 2024-01-08 11:33:10.916515943 +0100
|
||||
@@ -74,6 +74,9 @@ open_tally (const char *dir, const char
|
||||
|
||||
if (create) {
|
||||
flags |= O_CREAT;
|
||||
+ if (access(dir, F_OK) != 0) {
|
||||
+ mkdir(dir, 0755);
|
||||
+ }
|
||||
}
|
||||
|
||||
fd = open(path, flags, 0600);
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,70 @@
|
||||
diff -up Linux-PAM-1.3.1/libpam/pam_modutil_sanitize.c.fds-closing Linux-PAM-1.3.1/libpam/pam_modutil_sanitize.c
|
||||
--- Linux-PAM-1.3.1/libpam/pam_modutil_sanitize.c.fds-closing 2017-02-10 11:10:15.000000000 +0100
|
||||
+++ Linux-PAM-1.3.1/libpam/pam_modutil_sanitize.c 2019-10-16 16:07:31.259021159 +0200
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <fcntl.h>
|
||||
#include <syslog.h>
|
||||
#include <sys/resource.h>
|
||||
+#include <dirent.h>
|
||||
|
||||
/*
|
||||
* Creates a pipe, closes its write end, redirects fd to its read end.
|
||||
@@ -116,27 +117,45 @@ redirect_out(pam_handle_t *pamh, enum pa
|
||||
static void
|
||||
close_fds(void)
|
||||
{
|
||||
+ DIR *dir = NULL;
|
||||
+ struct dirent *dent;
|
||||
+ int dfd = -1;
|
||||
+ int fd;
|
||||
+ struct rlimit rlim;
|
||||
+
|
||||
/*
|
||||
* An arbitrary upper limit for the maximum file descriptor number
|
||||
* returned by RLIMIT_NOFILE.
|
||||
*/
|
||||
- const int MAX_FD_NO = 65535;
|
||||
+ const unsigned int MAX_FD_NO = 65535;
|
||||
|
||||
/* The lower limit is the same as for _POSIX_OPEN_MAX. */
|
||||
- const int MIN_FD_NO = 20;
|
||||
+ const unsigned int MIN_FD_NO = 20;
|
||||
|
||||
- int fd;
|
||||
- struct rlimit rlim;
|
||||
-
|
||||
- if (getrlimit(RLIMIT_NOFILE, &rlim) || rlim.rlim_max > MAX_FD_NO)
|
||||
- fd = MAX_FD_NO;
|
||||
- else if (rlim.rlim_max < MIN_FD_NO)
|
||||
- fd = MIN_FD_NO;
|
||||
- else
|
||||
- fd = rlim.rlim_max - 1;
|
||||
+ /* If /proc is mounted, we can optimize which fd can be closed. */
|
||||
+ if ((dir = opendir("/proc/self/fd")) != NULL) {
|
||||
+ if ((dfd = dirfd(dir)) >= 0) {
|
||||
+ while ((dent = readdir(dir)) != NULL) {
|
||||
+ fd = atoi(dent->d_name);
|
||||
+ if (fd > STDERR_FILENO && fd != dfd)
|
||||
+ close(fd);
|
||||
+ }
|
||||
+ }
|
||||
+ closedir(dir);
|
||||
+ }
|
||||
+
|
||||
+ /* If /proc isn't available, fallback to the previous behavior. */
|
||||
+ if (dfd < 0) {
|
||||
+ if (getrlimit(RLIMIT_NOFILE, &rlim) || rlim.rlim_max > MAX_FD_NO)
|
||||
+ fd = MAX_FD_NO;
|
||||
+ else if (rlim.rlim_max < MIN_FD_NO)
|
||||
+ fd = MIN_FD_NO;
|
||||
+ else
|
||||
+ fd = rlim.rlim_max - 1;
|
||||
|
||||
- for (; fd > STDERR_FILENO; --fd)
|
||||
- close(fd);
|
||||
+ for (; fd > STDERR_FILENO; --fd)
|
||||
+ close(fd);
|
||||
+ }
|
||||
}
|
||||
|
||||
int
|
@ -0,0 +1,105 @@
|
||||
diff -up Linux-PAM-1.3.1/libpam/include/pam_cc_compat.h.inline Linux-PAM-1.3.1/libpam/include/pam_cc_compat.h
|
||||
--- Linux-PAM-1.3.1/libpam/include/pam_cc_compat.h.inline 2022-05-26 10:44:31.702623614 +0200
|
||||
+++ Linux-PAM-1.3.1/libpam/include/pam_cc_compat.h 2022-05-26 10:44:31.703623621 +0200
|
||||
@@ -44,4 +44,17 @@
|
||||
# define DIAG_POP_IGNORE_CAST_ALIGN /* empty */
|
||||
#endif
|
||||
|
||||
+/*
|
||||
+ * Evaluates to
|
||||
+ * 1, if the given two types are known to be the same
|
||||
+ * 0, otherwise.
|
||||
+ */
|
||||
+#if PAM_GNUC_PREREQ(3, 0)
|
||||
+# define PAM_IS_SAME_TYPE(x_, y_) \
|
||||
+ __builtin_types_compatible_p(__typeof__(x_), __typeof__(y_))
|
||||
+#else
|
||||
+/* Cannot tell whether these types are the same. */
|
||||
+# define PAM_IS_SAME_TYPE(x_, y_) 0
|
||||
+#endif
|
||||
+
|
||||
#endif /* PAM_CC_COMPAT_H */
|
||||
diff -up Linux-PAM-1.3.1/libpam/include/pam_inline.h.inline Linux-PAM-1.3.1/libpam/include/pam_inline.h
|
||||
--- Linux-PAM-1.3.1/libpam/include/pam_inline.h.inline 2022-05-26 10:44:31.703623621 +0200
|
||||
+++ Linux-PAM-1.3.1/libpam/include/pam_inline.h 2022-05-26 10:44:31.703623621 +0200
|
||||
@@ -0,0 +1,67 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2020 Dmitry V. Levin <ldv@altlinux.org>
|
||||
+ *
|
||||
+ * Handy inline functions and macros providing some convenient functionality
|
||||
+ * to libpam and its modules.
|
||||
+ */
|
||||
+
|
||||
+#ifndef PAM_INLINE_H
|
||||
+#define PAM_INLINE_H
|
||||
+
|
||||
+#include "pam_cc_compat.h"
|
||||
+#include <string.h>
|
||||
+
|
||||
+/*
|
||||
+ * Evaluates to
|
||||
+ * - a syntax error if the argument is 0,
|
||||
+ * 0, otherwise.
|
||||
+ */
|
||||
+#define PAM_FAIL_BUILD_ON_ZERO(e_) (sizeof(int[-1 + 2 * !!(e_)]) * 0)
|
||||
+
|
||||
+/*
|
||||
+ * Evaluates to
|
||||
+ * 1, if the given type is known to be a non-array type
|
||||
+ * 0, otherwise.
|
||||
+ */
|
||||
+#define PAM_IS_NOT_ARRAY(a_) PAM_IS_SAME_TYPE((a_), &(a_)[0])
|
||||
+
|
||||
+/*
|
||||
+ * Evaluates to
|
||||
+ * - a syntax error if the argument is not an array,
|
||||
+ * 0, otherwise.
|
||||
+ */
|
||||
+#define PAM_MUST_BE_ARRAY(a_) PAM_FAIL_BUILD_ON_ZERO(!PAM_IS_NOT_ARRAY(a_))
|
||||
+
|
||||
+/* Evaluates to the number of elements in the specified array. */
|
||||
+#define PAM_ARRAY_SIZE(a_) (sizeof(a_) / sizeof((a_)[0]) + PAM_MUST_BE_ARRAY(a_))
|
||||
+
|
||||
+/*
|
||||
+ * Returns NULL if STR does not start with PREFIX,
|
||||
+ * or a pointer to the first char in STR after PREFIX.
|
||||
+ * The length of PREFIX is specified by PREFIX_LEN.
|
||||
+ */
|
||||
+static inline const char *
|
||||
+pam_str_skip_prefix_len(const char *str, const char *prefix, size_t prefix_len)
|
||||
+{
|
||||
+ return strncmp(str, prefix, prefix_len) ? NULL : str + prefix_len;
|
||||
+}
|
||||
+
|
||||
+#define pam_str_skip_prefix(str_, prefix_) \
|
||||
+ pam_str_skip_prefix_len((str_), (prefix_), sizeof(prefix_) - 1 + PAM_MUST_BE_ARRAY(prefix_))
|
||||
+
|
||||
+/*
|
||||
+ * Returns NULL if STR does not start with PREFIX
|
||||
+ * (ignoring the case of the characters),
|
||||
+ * or a pointer to the first char in STR after PREFIX.
|
||||
+ * The length of PREFIX is specified by PREFIX_LEN.
|
||||
+ */
|
||||
+static inline const char *
|
||||
+pam_str_skip_icase_prefix_len(const char *str, const char *prefix, size_t prefix_len)
|
||||
+{
|
||||
+ return strncasecmp(str, prefix, prefix_len) ? NULL : str + prefix_len;
|
||||
+}
|
||||
+
|
||||
+#define pam_str_skip_icase_prefix(str_, prefix_) \
|
||||
+ pam_str_skip_icase_prefix_len((str_), (prefix_), sizeof(prefix_) - 1 + PAM_MUST_BE_ARRAY(prefix_))
|
||||
+
|
||||
+#endif /* PAM_INLINE_H */
|
||||
diff -up Linux-PAM-1.3.1/libpam/Makefile.am.inline Linux-PAM-1.3.1/libpam/Makefile.am
|
||||
--- Linux-PAM-1.3.1/libpam/Makefile.am.inline 2022-05-26 10:44:31.702623614 +0200
|
||||
+++ Linux-PAM-1.3.1/libpam/Makefile.am 2022-05-26 10:45:21.146977780 +0200
|
||||
@@ -18,7 +18,8 @@ include_HEADERS = include/security/_pam_
|
||||
include/security/pam_ext.h include/security/pam_modutil.h
|
||||
|
||||
noinst_HEADERS = pam_prelude.h pam_private.h pam_tokens.h \
|
||||
- pam_modutil_private.h include/pam_cc_compat.h
|
||||
+ pam_modutil_private.h include/pam_cc_compat.h \
|
||||
+ include/pam_inline.h
|
||||
|
||||
libpam_la_LDFLAGS = -no-undefined -version-info 84:2:84
|
||||
libpam_la_LIBADD = @LIBAUDIT@ $(LIBPRELUDE_LIBS) @LIBDL@
|
@ -0,0 +1,82 @@
|
||||
From c426914fa166ffb0482b6f6ad659ddf17d5dfaa1 Mon Sep 17 00:00:00 2001
|
||||
From: Nir Soffer <nsoffer@redhat.com>
|
||||
Date: Wed, 9 Jan 2019 23:41:16 +0200
|
||||
Subject: [PATCH] pam_lastlog: Improve silent option documentation
|
||||
|
||||
The silent option explicitly silents only the last login message and not
|
||||
bad logins. Add a note to the manual to make this clear.
|
||||
|
||||
* modules/pam_lastlog/pam_lastlog.8.xml: Clearify "silent showfailed"
|
||||
---
|
||||
modules/pam_lastlog/pam_lastlog.8.xml | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/modules/pam_lastlog/pam_lastlog.8.xml b/modules/pam_lastlog/pam_lastlog.8.xml
|
||||
index c8f247e..bc2e1be 100644
|
||||
--- a/modules/pam_lastlog/pam_lastlog.8.xml
|
||||
+++ b/modules/pam_lastlog/pam_lastlog.8.xml
|
||||
@@ -102,6 +102,7 @@
|
||||
<para>
|
||||
Don't inform the user about any previous login,
|
||||
just update the <filename>/var/log/lastlog</filename> file.
|
||||
+ This option does not affect display of bad login attempts.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
--
|
||||
2.20.1
|
||||
|
||||
From 7d036249a9772c546ede1f38ad68b3f1575216d6 Mon Sep 17 00:00:00 2001
|
||||
From: Nir Soffer <nsoffer@redhat.com>
|
||||
Date: Sun, 6 Jan 2019 00:36:27 +0200
|
||||
Subject: [PATCH] pam_lastlog: Respect PAM_SILENT flag
|
||||
|
||||
pam_lastlog module will not log info about failed login if the session
|
||||
was opened with PAM_SILENT flag.
|
||||
|
||||
Example use case enabled by this change:
|
||||
|
||||
sudo --non-interactive program
|
||||
|
||||
If this command is run by another program expecting specific output from
|
||||
the command run by sudo, the unexpected info about failed logins will
|
||||
break this program.
|
||||
|
||||
* modules/pam_lastlog/pam_lastlog.c: Respect silent option.
|
||||
(_pam_session_parse): Unset LASTLOG_BTMP if PAM_SILENT is set.
|
||||
---
|
||||
modules/pam_lastlog/pam_lastlog.c | 11 ++++++-----
|
||||
1 file changed, 6 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/modules/pam_lastlog/pam_lastlog.c b/modules/pam_lastlog/pam_lastlog.c
|
||||
index 18bf7be..e980c04 100644
|
||||
--- a/modules/pam_lastlog/pam_lastlog.c
|
||||
+++ b/modules/pam_lastlog/pam_lastlog.c
|
||||
@@ -135,11 +135,6 @@ _pam_session_parse(pam_handle_t *pamh, int flags, int argc, const char **argv)
|
||||
{
|
||||
int ctrl=(LASTLOG_DATE|LASTLOG_HOST|LASTLOG_LINE|LASTLOG_WTMP|LASTLOG_UPDATE);
|
||||
|
||||
- /* does the appliction require quiet? */
|
||||
- if (flags & PAM_SILENT) {
|
||||
- ctrl |= LASTLOG_QUIET;
|
||||
- }
|
||||
-
|
||||
/* step through arguments */
|
||||
for (; argc-- > 0; ++argv) {
|
||||
|
||||
@@ -168,6 +163,12 @@ _pam_session_parse(pam_handle_t *pamh, int flags, int argc, const char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
+ /* does the appliction require quiet? */
|
||||
+ if (flags & PAM_SILENT) {
|
||||
+ ctrl |= LASTLOG_QUIET;
|
||||
+ ctrl &= ~LASTLOG_BTMP;
|
||||
+ }
|
||||
+
|
||||
D(("ctrl = %o", ctrl));
|
||||
return ctrl;
|
||||
}
|
||||
--
|
||||
2.20.1
|
||||
|
@ -0,0 +1,227 @@
|
||||
From 3a3e70739834cd5cbd17469907ef718c81ae40c0 Mon Sep 17 00:00:00 2001
|
||||
From: Carlos Santos <casantos@redhat.com>
|
||||
Date: Wed, 11 Sep 2019 11:50:28 -0300
|
||||
Subject: [PATCH] pam_lastlog: document the 'unlimited' option
|
||||
|
||||
Signed-off-by: Carlos Santos <casantos@redhat.com>
|
||||
---
|
||||
modules/pam_lastlog/pam_lastlog.8.xml | 18 ++++++++++++++++++
|
||||
1 file changed, 18 insertions(+)
|
||||
|
||||
diff --git a/modules/pam_lastlog/pam_lastlog.8.xml b/modules/pam_lastlog/pam_lastlog.8.xml
|
||||
index bc2e1be..f10e94a 100644
|
||||
--- a/modules/pam_lastlog/pam_lastlog.8.xml
|
||||
+++ b/modules/pam_lastlog/pam_lastlog.8.xml
|
||||
@@ -48,6 +48,9 @@
|
||||
<arg choice="opt">
|
||||
inactive=<days>
|
||||
</arg>
|
||||
+ <arg choice="opt">
|
||||
+ unlimited
|
||||
+ </arg>
|
||||
</cmdsynopsis>
|
||||
</refsynopsisdiv>
|
||||
|
||||
@@ -196,6 +199,18 @@
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
+ <varlistentry>
|
||||
+ <term>
|
||||
+ <option>unlimited</option>
|
||||
+ </term>
|
||||
+ <listitem>
|
||||
+ <para>
|
||||
+ If the <emphasis>fsize</emphasis> limit is set, this option can be
|
||||
+ used to override it, preventing failures on systems with large UID
|
||||
+ values that lead lastlog to become a huge sparse file.
|
||||
+ </para>
|
||||
+ </listitem>
|
||||
+ </varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
@@ -300,6 +315,9 @@
|
||||
<refsect1 id='pam_lastlog-see_also'>
|
||||
<title>SEE ALSO</title>
|
||||
<para>
|
||||
+ <citerefentry>
|
||||
+ <refentrytitle>limits.conf</refentrytitle><manvolnum>5</manvolnum>
|
||||
+ </citerefentry>,
|
||||
<citerefentry>
|
||||
<refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
|
||||
</citerefentry>,
|
||||
--
|
||||
2.20.1
|
||||
|
||||
From 9349333a9ae958205294cd25e97fd6b4805bd82b Mon Sep 17 00:00:00 2001
|
||||
From: Carlos Santos <casantos@redhat.com>
|
||||
Date: Tue, 10 Sep 2019 23:08:30 -0300
|
||||
Subject: [PATCH] pam_lastlog: prevent crash due to reduced 'fsize' limit
|
||||
|
||||
It a reduced fsize limit is set in /etc/security/limits.conf and
|
||||
pam_limits is in use pam_lastlog may cause a crash, e.g.
|
||||
|
||||
----- begin /etc/pam.d/su ----
|
||||
auth sufficient pam_rootok.so
|
||||
auth required pam_wheel.so use_uid
|
||||
auth required pam_env.so
|
||||
auth required pam_unix.so nullok
|
||||
account required pam_unix.so
|
||||
password required pam_unix.so nullok
|
||||
session required pam_limits.so
|
||||
session required pam_env.so
|
||||
session required pam_unix.so
|
||||
session optional pam_lastlog.so
|
||||
----- end /etc/pam.d/su -----
|
||||
|
||||
----- begin /etc/security/limits.d/fsize.conf -----
|
||||
* soft fsize 1710
|
||||
* hard fsize 1710
|
||||
----- end /etc/security/limits.d/fsize.conf -----
|
||||
|
||||
# id user1
|
||||
uid=1000(user1) gid=1000(user1) groups=1000(user1)
|
||||
# su - user1
|
||||
Last login: Wed Sep 11 01:52:44 UTC 2019 on console
|
||||
$ exit
|
||||
# id user2
|
||||
uid=60000(user2) gid=60000(user2) groups=60000(user2)
|
||||
# su - user2
|
||||
File size limit exceeded
|
||||
|
||||
This happens because pam_limits sets RLIMIT_FSIZE before pam_lastlog
|
||||
attempts to write /var/log/lastlog, leading to a SIGXFSZ signal.
|
||||
|
||||
In order to fix this, and an 'unlimited' option, which leads to saving
|
||||
the 'fsize' limit and set it to unlimited before writing lastlog. After
|
||||
that, restore the saved value. If 'fsize' is already unlimited nothing
|
||||
is done.
|
||||
|
||||
Failing to set the 'fsize' limit is not a fatal error. With luck the
|
||||
configured limit will suffice, so we try to write lastlog anyway, even
|
||||
under the risk of dying due to a SIGXFSZ.
|
||||
|
||||
Failing to restore the 'fsize' limit is a fatal error, since we don't
|
||||
want to keep it unlimited.
|
||||
|
||||
Signed-off-by: Carlos Santos <casantos@redhat.com>
|
||||
---
|
||||
modules/pam_lastlog/pam_lastlog.c | 66 ++++++++++++++++++++++++++-----
|
||||
1 file changed, 57 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/modules/pam_lastlog/pam_lastlog.c b/modules/pam_lastlog/pam_lastlog.c
|
||||
index e980c04..a135c9f 100644
|
||||
--- a/modules/pam_lastlog/pam_lastlog.c
|
||||
+++ b/modules/pam_lastlog/pam_lastlog.c
|
||||
@@ -25,6 +25,8 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
+#include <sys/time.h>
|
||||
+#include <sys/resource.h>
|
||||
#include <syslog.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@@ -82,15 +84,16 @@ struct lastlog {
|
||||
|
||||
/* argument parsing */
|
||||
|
||||
-#define LASTLOG_DATE 01 /* display the date of the last login */
|
||||
-#define LASTLOG_HOST 02 /* display the last host used (if set) */
|
||||
-#define LASTLOG_LINE 04 /* display the last terminal used */
|
||||
-#define LASTLOG_NEVER 010 /* display a welcome message for first login */
|
||||
-#define LASTLOG_DEBUG 020 /* send info to syslog(3) */
|
||||
-#define LASTLOG_QUIET 040 /* keep quiet about things */
|
||||
-#define LASTLOG_WTMP 0100 /* log to wtmp as well as lastlog */
|
||||
-#define LASTLOG_BTMP 0200 /* display failed login info from btmp */
|
||||
-#define LASTLOG_UPDATE 0400 /* update the lastlog and wtmp files (default) */
|
||||
+#define LASTLOG_DATE 01 /* display the date of the last login */
|
||||
+#define LASTLOG_HOST 02 /* display the last host used (if set) */
|
||||
+#define LASTLOG_LINE 04 /* display the last terminal used */
|
||||
+#define LASTLOG_NEVER 010 /* display a welcome message for first login */
|
||||
+#define LASTLOG_DEBUG 020 /* send info to syslog(3) */
|
||||
+#define LASTLOG_QUIET 040 /* keep quiet about things */
|
||||
+#define LASTLOG_WTMP 0100 /* log to wtmp as well as lastlog */
|
||||
+#define LASTLOG_BTMP 0200 /* display failed login info from btmp */
|
||||
+#define LASTLOG_UPDATE 0400 /* update the lastlog and wtmp files (default) */
|
||||
+#define LASTLOG_UNLIMITED 01000 /* unlimited file size (ignore 'fsize' limit) */
|
||||
|
||||
static int
|
||||
_pam_auth_parse(pam_handle_t *pamh, int flags, int argc, const char **argv,
|
||||
@@ -158,6 +161,8 @@ _pam_session_parse(pam_handle_t *pamh, int flags, int argc, const char **argv)
|
||||
ctrl &= ~(LASTLOG_WTMP|LASTLOG_UPDATE);
|
||||
} else if (!strcmp(*argv,"showfailed")) {
|
||||
ctrl |= LASTLOG_BTMP;
|
||||
+ } else if (!strcmp(*argv,"unlimited")) {
|
||||
+ ctrl |= LASTLOG_UNLIMITED;
|
||||
} else {
|
||||
pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv);
|
||||
}
|
||||
@@ -373,6 +378,12 @@ static int
|
||||
last_login_write(pam_handle_t *pamh, int announce, int last_fd,
|
||||
uid_t uid, const char *user)
|
||||
{
|
||||
+ static struct rlimit no_limit = {
|
||||
+ RLIM_INFINITY,
|
||||
+ RLIM_INFINITY
|
||||
+ };
|
||||
+ struct rlimit old_limit;
|
||||
+ int setrlimit_res;
|
||||
struct flock last_lock;
|
||||
struct lastlog last_login;
|
||||
time_t ll_time;
|
||||
@@ -427,6 +438,31 @@ last_login_write(pam_handle_t *pamh, int announce, int last_fd,
|
||||
sleep(LASTLOG_IGNORE_LOCK_TIME);
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * Failing to set the 'fsize' limit is not a fatal error. We try to write
|
||||
+ * lastlog anyway, under the risk of dying due to a SIGXFSZ.
|
||||
+ */
|
||||
+ D(("setting limit for 'fsize'"));
|
||||
+
|
||||
+ if ((announce & LASTLOG_UNLIMITED) == 0) { /* don't set to unlimted */
|
||||
+ setrlimit_res = -1;
|
||||
+ } else if (getrlimit(RLIMIT_FSIZE, &old_limit) == 0) {
|
||||
+ if (old_limit.rlim_cur == RLIM_INFINITY) { /* already unlimited */
|
||||
+ setrlimit_res = -1;
|
||||
+ } else {
|
||||
+ setrlimit_res = setrlimit(RLIMIT_FSIZE, &no_limit);
|
||||
+ if (setrlimit_res != 0)
|
||||
+ pam_syslog(pamh, LOG_WARNING, "Could not set limit for 'fsize': %m");
|
||||
+ }
|
||||
+ } else {
|
||||
+ setrlimit_res = -1;
|
||||
+ if (errno == EINVAL) {
|
||||
+ pam_syslog(pamh, LOG_INFO, "Limit for 'fsize' not supported: %m");
|
||||
+ } else {
|
||||
+ pam_syslog(pamh, LOG_WARNING, "Could not get limit for 'fsize': %m");
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
D(("writing to the lastlog file"));
|
||||
if (pam_modutil_write (last_fd, (char *) &last_login,
|
||||
sizeof (last_login)) != sizeof(last_login)) {
|
||||
@@ -434,6 +470,18 @@ last_login_write(pam_handle_t *pamh, int announce, int last_fd,
|
||||
retval = PAM_SERVICE_ERR;
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * Failing to restore the 'fsize' limit is a fatal error.
|
||||
+ */
|
||||
+ D(("restoring limit for 'fsize'"));
|
||||
+ if (setrlimit_res == 0) {
|
||||
+ setrlimit_res = setrlimit(RLIMIT_FSIZE, &old_limit);
|
||||
+ if (setrlimit_res != 0) {
|
||||
+ pam_syslog(pamh, LOG_ERR, "Could not restore limit for 'fsize': %m");
|
||||
+ retval = PAM_SERVICE_ERR;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
last_lock.l_type = F_UNLCK;
|
||||
(void) fcntl(last_fd, F_SETLK, &last_lock); /* unlock */
|
||||
D(("unlocked"));
|
||||
--
|
||||
2.20.1
|
||||
|
@ -0,0 +1,25 @@
|
||||
diff -up Linux-PAM-1.3.1/modules/pam_motd/pam_motd.8.xml.motd-manpage Linux-PAM-1.3.1/modules/pam_motd/pam_motd.8.xml
|
||||
--- Linux-PAM-1.3.1/modules/pam_motd/pam_motd.8.xml.motd-manpage 2018-05-18 11:50:46.000000000 +0200
|
||||
+++ Linux-PAM-1.3.1/modules/pam_motd/pam_motd.8.xml 2019-12-19 10:29:36.243558251 +0100
|
||||
@@ -31,10 +31,19 @@
|
||||
<para>
|
||||
pam_motd is a PAM module that can be used to display
|
||||
arbitrary motd (message of the day) files after a successful
|
||||
- login. By default the <filename>/etc/motd</filename> file is
|
||||
+ login. By default the <filename>/etc/motd</filename> file and
|
||||
+ all files from <filename>/etc/motd.d</filename> are
|
||||
shown. The message size is limited to 64KB.
|
||||
</para>
|
||||
-
|
||||
+ <para>
|
||||
+ To silence a message,
|
||||
+ a symbolic link with target <filename>/dev/null</filename>
|
||||
+ may be placed in <filename>/etc/motd.d</filename> with
|
||||
+ the same filename as the message to be silenced. Example:
|
||||
+ </para>
|
||||
+ <para>
|
||||
+ <command>ln -sfn /dev/null /etc/motd.d/my_motd</command>
|
||||
+ </para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1 id="pam_motd-options">
|
@ -0,0 +1,68 @@
|
||||
From 491e5500b6b3913f531574208274358a2df88659 Mon Sep 17 00:00:00 2001
|
||||
From: ikerexxe <ipedrosa@redhat.com>
|
||||
Date: Mon, 5 Oct 2020 10:41:29 +0200
|
||||
Subject: [PATCH] pam_namespace: polyinstantiation refer to gdm doc
|
||||
|
||||
modules/pam_namespace/pam_namespace.8.xml: delete obsolete information
|
||||
about polyinstantiation and refer to gdm's documentation.
|
||||
|
||||
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1861841
|
||||
---
|
||||
modules/pam_namespace/pam_namespace.8.xml | 41 ++---------------------
|
||||
1 file changed, 2 insertions(+), 39 deletions(-)
|
||||
|
||||
diff --git a/modules/pam_namespace/pam_namespace.8.xml b/modules/pam_namespace/pam_namespace.8.xml
|
||||
index f0f80d33..57c44c4b 100644
|
||||
--- a/modules/pam_namespace/pam_namespace.8.xml
|
||||
+++ b/modules/pam_namespace/pam_namespace.8.xml
|
||||
@@ -343,45 +343,8 @@
|
||||
</para>
|
||||
|
||||
<para>
|
||||
- To use polyinstantiation with graphical display manager gdm, insert the
|
||||
- following line, before exit 0, in /etc/gdm/PostSession/Default:
|
||||
- </para>
|
||||
-
|
||||
- <para>
|
||||
- /usr/sbin/gdm-safe-restart
|
||||
- </para>
|
||||
-
|
||||
- <para>
|
||||
- This allows gdm to restart after each session and appropriately adjust
|
||||
- namespaces of display manager and the X server. If polyinstantiation
|
||||
- of /tmp is desired along with the graphical environment, then additional
|
||||
- configuration changes are needed to address the interaction of X server
|
||||
- and font server namespaces with their use of /tmp to create
|
||||
- communication sockets. Please use the initialization script
|
||||
- <filename>/etc/security/namespace.init</filename> to ensure that
|
||||
- the X server and its clients can appropriately access the
|
||||
- communication socket X0. Please refer to the sample instructions
|
||||
- provided in the comment section of the instance initialization script
|
||||
- <filename>/etc/security/namespace.init</filename>. In addition,
|
||||
- perform the following changes to use graphical environment with
|
||||
- polyinstantiation of /tmp:
|
||||
- </para>
|
||||
-
|
||||
- <para>
|
||||
- <literallayout>
|
||||
- 1. Disable the use of font server by commenting out "FontPath"
|
||||
- line in /etc/X11/xorg.conf. If you do want to use the font server
|
||||
- then you will have to augment the instance initialization
|
||||
- script to appropriately provide /tmp/.font-unix from the
|
||||
- polyinstantiated /tmp.
|
||||
- 2. Ensure that the gdm service is setup to use pam_namespace,
|
||||
- as described above, by modifying /etc/pam.d/gdm.
|
||||
- 3. Ensure that the display manager is configured to restart X server
|
||||
- with each new session. This default setup can be verified by
|
||||
- making sure that /usr/share/gdm/defaults.conf contains
|
||||
- "AlwaysRestartServer=true", and it is not overridden by
|
||||
- /etc/gdm/custom.conf.
|
||||
- </literallayout>
|
||||
+ To use polyinstantiation with graphical display manager gdm, please refer
|
||||
+ to gdm's documentation.
|
||||
</para>
|
||||
|
||||
</refsect1>
|
||||
--
|
||||
2.26.2
|
||||
|
@ -0,0 +1,131 @@
|
||||
diff --git a/modules/pam_namespace/namespace.conf.5.xml b/modules/pam_namespace/namespace.conf.5.xml
|
||||
index c7698cb..a94b49e 100644
|
||||
--- a/modules/pam_namespace/namespace.conf.5.xml
|
||||
+++ b/modules/pam_namespace/namespace.conf.5.xml
|
||||
@@ -122,9 +122,14 @@
|
||||
<para><emphasis>mntopts</emphasis>=<replaceable>value</replaceable>
|
||||
- value of this flag is passed to the mount call when the tmpfs mount is
|
||||
done. It allows for example the specification of the maximum size of the
|
||||
- tmpfs instance that is created by the mount call. See <citerefentry>
|
||||
- <refentrytitle>mount</refentrytitle><manvolnum>8</manvolnum>
|
||||
- </citerefentry> for details.
|
||||
+ tmpfs instance that is created by the mount call. In addition to
|
||||
+ options specified in the <citerefentry>
|
||||
+ <refentrytitle>tmpfs</refentrytitle><manvolnum>5</manvolnum>
|
||||
+ </citerefentry> manual the <emphasis>nosuid</emphasis>,
|
||||
+ <emphasis>noexec</emphasis>, and <emphasis>nodev</emphasis> flags
|
||||
+ can be used to respectively disable setuid bit effect, disable running
|
||||
+ executables, and disable devices to be interpreted on the mounted
|
||||
+ tmpfs filesystem.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
diff --git a/modules/pam_namespace/pam_namespace.c b/modules/pam_namespace/pam_namespace.c
|
||||
index f541f89..660c7a1 100644
|
||||
--- a/modules/pam_namespace/pam_namespace.c
|
||||
+++ b/modules/pam_namespace/pam_namespace.c
|
||||
@@ -230,6 +230,73 @@ static int parse_iscript_params(char *params, struct polydir_s *poly)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+struct mntflag {
|
||||
+ const char *name;
|
||||
+ size_t len;
|
||||
+ unsigned long flag;
|
||||
+};
|
||||
+
|
||||
+#define LITERAL_AND_LEN(x) x, sizeof(x) - 1
|
||||
+
|
||||
+static const struct mntflag mntflags[] = {
|
||||
+ { LITERAL_AND_LEN("noexec"), MS_NOEXEC },
|
||||
+ { LITERAL_AND_LEN("nosuid"), MS_NOSUID },
|
||||
+ { LITERAL_AND_LEN("nodev"), MS_NODEV }
|
||||
+ };
|
||||
+
|
||||
+static int filter_mntopts(const char *opts, char **filtered,
|
||||
+ unsigned long *mountflags)
|
||||
+{
|
||||
+ size_t origlen = strlen(opts);
|
||||
+ const char *end;
|
||||
+ char *dest;
|
||||
+
|
||||
+ dest = *filtered = NULL;
|
||||
+ *mountflags = 0;
|
||||
+
|
||||
+ if (origlen == 0)
|
||||
+ return 0;
|
||||
+
|
||||
+ do {
|
||||
+ size_t len;
|
||||
+ int i;
|
||||
+
|
||||
+ end = strchr(opts, ',');
|
||||
+ if (end == NULL) {
|
||||
+ len = strlen(opts);
|
||||
+ } else {
|
||||
+ len = end - opts;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < (int)(sizeof(mntflags)/sizeof(mntflags[0])); i++) {
|
||||
+ if (mntflags[i].len != len)
|
||||
+ continue;
|
||||
+ if (memcmp(mntflags[i].name, opts, len) == 0) {
|
||||
+ *mountflags |= mntflags[i].flag;
|
||||
+ opts = end;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (opts != end) {
|
||||
+ if (dest != NULL) {
|
||||
+ *dest = ',';
|
||||
+ ++dest;
|
||||
+ } else {
|
||||
+ dest = *filtered = calloc(1, origlen + 1);
|
||||
+ if (dest == NULL)
|
||||
+ return -1;
|
||||
+ }
|
||||
+ memcpy(dest, opts, len);
|
||||
+ dest += len;
|
||||
+ }
|
||||
+
|
||||
+ opts = end + 1;
|
||||
+ } while (end != NULL);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int parse_method(char *method, struct polydir_s *poly,
|
||||
struct instance_data *idata)
|
||||
{
|
||||
@@ -289,7 +356,8 @@ static int parse_method(char *method, struct polydir_s *poly,
|
||||
break;
|
||||
}
|
||||
free(poly->mount_opts); /* if duplicate mntopts specified */
|
||||
- if ((poly->mount_opts = strdup(flag+namelen+1)) == NULL) {
|
||||
+ poly->mount_opts = NULL;
|
||||
+ if (filter_mntopts(flag+namelen+1, &poly->mount_opts, &poly->mount_flags) != 0) {
|
||||
pam_syslog(idata->pamh, LOG_CRIT, "Memory allocation error");
|
||||
return -1;
|
||||
}
|
||||
@@ -1484,7 +1552,7 @@ static int ns_setup(struct polydir_s *polyptr,
|
||||
}
|
||||
|
||||
if (polyptr->method == TMPFS) {
|
||||
- if (mount("tmpfs", polyptr->dir, "tmpfs", 0, polyptr->mount_opts) < 0) {
|
||||
+ if (mount("tmpfs", polyptr->dir, "tmpfs", polyptr->mount_flags, polyptr->mount_opts) < 0) {
|
||||
pam_syslog(idata->pamh, LOG_ERR, "Error mounting tmpfs on %s, %m",
|
||||
polyptr->dir);
|
||||
return PAM_SESSION_ERR;
|
||||
diff --git a/modules/pam_namespace/pam_namespace.h b/modules/pam_namespace/pam_namespace.h
|
||||
index 47ebcc3..1522386 100644
|
||||
--- a/modules/pam_namespace/pam_namespace.h
|
||||
+++ b/modules/pam_namespace/pam_namespace.h
|
||||
@@ -166,6 +166,7 @@ struct polydir_s {
|
||||
unsigned int flags; /* polydir flags */
|
||||
char *init_script; /* path to init script */
|
||||
char *mount_opts; /* mount options for tmpfs mount */
|
||||
+ unsigned long mount_flags; /* mount flags for tmpfs mount */
|
||||
uid_t owner; /* user which should own the polydir */
|
||||
gid_t group; /* group which should own the polydir */
|
||||
mode_t mode; /* mode of the polydir */
|
@ -0,0 +1,24 @@
|
||||
diff -up Linux-PAM-1.3.1/doc/Makefile.am.noflex Linux-PAM-1.3.1/doc/Makefile.am
|
||||
--- Linux-PAM-1.3.1/doc/Makefile.am.noflex 2017-02-10 11:10:15.000000000 +0100
|
||||
+++ Linux-PAM-1.3.1/doc/Makefile.am 2018-05-18 14:53:50.300997606 +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 = *~
|
||||
|
||||
diff -up Linux-PAM-1.3.1/Makefile.am.noflex Linux-PAM-1.3.1/Makefile.am
|
||||
--- Linux-PAM-1.3.1/Makefile.am.noflex 2018-05-18 14:53:50.301997629 +0200
|
||||
+++ Linux-PAM-1.3.1/Makefile.am 2018-05-18 14:55:31.576353800 +0200
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
AUTOMAKE_OPTIONS = 1.9 gnu dist-bzip2 dist-xz check-news
|
||||
|
||||
-SUBDIRS = libpam tests libpamc libpam_misc modules po conf doc examples xtests
|
||||
+SUBDIRS = libpam tests libpamc libpam_misc modules po doc examples xtests
|
||||
|
||||
CLEANFILES = *~
|
||||
|
@ -0,0 +1,63 @@
|
||||
diff -up Linux-PAM-1.3.1/libpam/include/pam_cc_compat.h.pam-cc-compat Linux-PAM-1.3.1/libpam/include/pam_cc_compat.h
|
||||
--- Linux-PAM-1.3.1/libpam/include/pam_cc_compat.h.pam-cc-compat 2022-05-26 10:43:50.436328027 +0200
|
||||
+++ Linux-PAM-1.3.1/libpam/include/pam_cc_compat.h 2022-05-26 10:43:50.436328027 +0200
|
||||
@@ -0,0 +1,47 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2020 Dmitry V. Levin <ldv@altlinux.org>
|
||||
+ */
|
||||
+
|
||||
+#ifndef PAM_CC_COMPAT_H
|
||||
+#define PAM_CC_COMPAT_H
|
||||
+
|
||||
+#include "config.h"
|
||||
+#include <security/_pam_types.h>
|
||||
+
|
||||
+#if defined __clang__ && defined __clang_major__ && defined __clang_minor__
|
||||
+# define PAM_CLANG_PREREQ(maj, min) \
|
||||
+ ((__clang_major__ << 16) + __clang_minor__ >= ((maj) << 16) + (min))
|
||||
+#else
|
||||
+# define PAM_CLANG_PREREQ(maj, min) 0
|
||||
+#endif
|
||||
+
|
||||
+#if PAM_GNUC_PREREQ(4, 6)
|
||||
+# define DIAG_PUSH_IGNORE_CAST_QUAL \
|
||||
+ _Pragma("GCC diagnostic push"); \
|
||||
+ _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
|
||||
+# define DIAG_POP_IGNORE_CAST_QUAL \
|
||||
+ _Pragma("GCC diagnostic pop")
|
||||
+# define DIAG_PUSH_IGNORE_CAST_ALIGN \
|
||||
+ _Pragma("GCC diagnostic push"); \
|
||||
+ _Pragma("GCC diagnostic ignored \"-Wcast-align\"")
|
||||
+# define DIAG_POP_IGNORE_CAST_ALIGN \
|
||||
+ _Pragma("GCC diagnostic pop")
|
||||
+#elif PAM_CLANG_PREREQ(2, 6)
|
||||
+# define DIAG_PUSH_IGNORE_CAST_QUAL \
|
||||
+ _Pragma("clang diagnostic push"); \
|
||||
+ _Pragma("clang diagnostic ignored \"-Wcast-qual\"")
|
||||
+# define DIAG_POP_IGNORE_CAST_QUAL \
|
||||
+ _Pragma("clang diagnostic pop")
|
||||
+# define DIAG_PUSH_IGNORE_CAST_ALIGN \
|
||||
+ _Pragma("clang diagnostic push"); \
|
||||
+ _Pragma("clang diagnostic ignored \"-Wcast-align\"")
|
||||
+# define DIAG_POP_IGNORE_CAST_ALIGN \
|
||||
+ _Pragma("clang diagnostic pop")
|
||||
+#else
|
||||
+# define DIAG_PUSH_IGNORE_CAST_QUAL /* empty */
|
||||
+# define DIAG_POP_IGNORE_CAST_QUAL /* empty */
|
||||
+# define DIAG_PUSH_IGNORE_CAST_ALIGN /* empty */
|
||||
+# define DIAG_POP_IGNORE_CAST_ALIGN /* empty */
|
||||
+#endif
|
||||
+
|
||||
+#endif /* PAM_CC_COMPAT_H */
|
||||
diff -up Linux-PAM-1.3.1/libpam/Makefile.am.pam-cc-compat Linux-PAM-1.3.1/libpam/Makefile.am
|
||||
--- Linux-PAM-1.3.1/libpam/Makefile.am.pam-cc-compat 2022-05-26 10:43:50.436328027 +0200
|
||||
+++ Linux-PAM-1.3.1/libpam/Makefile.am 2022-05-26 10:44:00.865402730 +0200
|
||||
@@ -18,7 +18,7 @@ include_HEADERS = include/security/_pam_
|
||||
include/security/pam_ext.h include/security/pam_modutil.h
|
||||
|
||||
noinst_HEADERS = pam_prelude.h pam_private.h pam_tokens.h \
|
||||
- pam_modutil_private.h
|
||||
+ pam_modutil_private.h include/pam_cc_compat.h
|
||||
|
||||
libpam_la_LDFLAGS = -no-undefined -version-info 84:2:84
|
||||
libpam_la_LIBADD = @LIBAUDIT@ $(LIBPRELUDE_LIBS) @LIBDL@
|
@ -0,0 +1,125 @@
|
||||
diff -up Linux-PAM-1.3.1/modules/pam_keyinit/pam_keyinit.c.pam_keyinit-thread-safe Linux-PAM-1.3.1/modules/pam_keyinit/pam_keyinit.c
|
||||
--- Linux-PAM-1.3.1/modules/pam_keyinit/pam_keyinit.c.pam_keyinit-thread-safe 2017-02-10 11:10:15.000000000 +0100
|
||||
+++ Linux-PAM-1.3.1/modules/pam_keyinit/pam_keyinit.c 2022-04-25 12:10:28.071240439 +0200
|
||||
@@ -20,6 +20,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 */
|
||||
@@ -30,12 +31,12 @@
|
||||
#define KEYCTL_REVOKE 3 /* revoke a key */
|
||||
#define KEYCTL_LINK 8 /* link a key into a keyring */
|
||||
|
||||
-static int my_session_keyring;
|
||||
-static int session_counter;
|
||||
-static int do_revoke;
|
||||
-static int revoke_as_uid;
|
||||
-static int 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)));
|
||||
@@ -65,6 +66,33 @@ static int error(pam_handle_t *pamh, con
|
||||
return PAM_SESSION_ERR;
|
||||
}
|
||||
|
||||
+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
|
||||
*/
|
||||
@@ -139,23 +167,25 @@ static void kill_keyrings(pam_handle_t *
|
||||
|
||||
/* 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);
|
||||
|
||||
- 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 && pam_setregid(-1, old_gid) < 0)
|
||||
+ error(pamh, "Unable to change GID back to %d\n", old_gid);
|
||||
|
||||
syscall(__NR_keyctl,
|
||||
KEYCTL_REVOKE,
|
||||
my_session_keyring);
|
||||
|
||||
/* return to the orignal 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);
|
||||
|
||||
- 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);
|
||||
|
||||
my_session_keyring = 0;
|
||||
@@ -210,14 +240,14 @@ int pam_sm_open_session(pam_handle_t *pa
|
||||
|
||||
/* 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 PAM_SESSION_ERR;
|
||||
}
|
||||
|
||||
- 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 PAM_SESSION_ERR;
|
||||
}
|
||||
@@ -225,10 +255,10 @@ int pam_sm_open_session(pam_handle_t *pa
|
||||
ret = init_keyrings(pamh, force);
|
||||
|
||||
/* return to the orignal UID and GID (probably root) */
|
||||
- if (uid != old_uid && setreuid(old_uid, -1) < 0)
|
||||
+ if (uid != old_uid && pam_setreuid(old_uid, -1) < 0)
|
||||
ret = error(pamh, "Unable to change UID back to %d\n", old_uid);
|
||||
|
||||
- if (gid != old_gid && setregid(old_gid, -1) < 0)
|
||||
+ if (gid != old_gid && pam_setregid(old_gid, -1) < 0)
|
||||
ret = error(pamh, "Unable to change GID back to %d\n", old_gid);
|
||||
|
||||
return ret;
|
@ -0,0 +1,29 @@
|
||||
diff -up Linux-PAM-1.3.1/configure.ac.pam-misc-configurable Linux-PAM-1.3.1/configure.ac
|
||||
--- Linux-PAM-1.3.1/configure.ac.pam-misc-configurable 2023-06-26 09:57:00.243146563 +0200
|
||||
+++ Linux-PAM-1.3.1/configure.ac 2023-06-26 09:59:45.353636685 +0200
|
||||
@@ -621,6 +621,13 @@ if test x"$opt_kerneloverflowuid" == x;
|
||||
fi
|
||||
AC_DEFINE_UNQUOTED(PAM_USERTYPE_OVERFLOW_UID, $opt_kerneloverflowuid, [Kernel overflow uid.])
|
||||
|
||||
+AC_ARG_WITH([misc-conv-bufsize],
|
||||
+AS_HELP_STRING([--with-misc-conv-bufsize=<number>],
|
||||
+ [Size of input buffer for libpam_misc's misc_conv() conversation function, default=4096]),
|
||||
+ [],
|
||||
+ [with_misc_conv_bufsize=4096])
|
||||
+AC_DEFINE_UNQUOTED(PAM_MISC_CONV_BUFSIZE, $with_misc_conv_bufsize, [libpam_misc misc_conv() buffer size.])
|
||||
+
|
||||
dnl Files to be created from when we run configure
|
||||
AC_CONFIG_FILES([Makefile libpam/Makefile libpamc/Makefile libpamc/test/Makefile \
|
||||
libpam_misc/Makefile conf/Makefile conf/pam_conv1/Makefile \
|
||||
diff -up Linux-PAM-1.3.1/libpam_misc/misc_conv.c.pam-misc-configurable Linux-PAM-1.3.1/libpam_misc/misc_conv.c
|
||||
--- Linux-PAM-1.3.1/libpam_misc/misc_conv.c.pam-misc-configurable 2023-06-26 09:57:00.242146560 +0200
|
||||
+++ Linux-PAM-1.3.1/libpam_misc/misc_conv.c 2023-06-26 10:00:38.023787972 +0200
|
||||
@@ -18,7 +18,7 @@
|
||||
#include <security/pam_appl.h>
|
||||
#include <security/pam_misc.h>
|
||||
|
||||
-#define INPUTSIZE PAM_MAX_MSG_SIZE /* maximum length of input+1 */
|
||||
+#define INPUTSIZE PAM_MISC_CONV_BUFSIZE /* maximum length of input+1 */
|
||||
#define CONV_ECHO_ON 1 /* types of echo state */
|
||||
#define CONV_ECHO_OFF 0
|
||||
|
@ -0,0 +1,74 @@
|
||||
From b6f73810a2e7afd02a231e2dfa14b05752c83db7 Mon Sep 17 00:00:00 2001
|
||||
From: "Dmitry V. Levin" <ldv@altlinux.org>
|
||||
Date: Wed, 26 Feb 2020 19:20:58 +0000
|
||||
Subject: [PATCH] pam_modutil_sanitize_helper_fds: fix SIGPIPE effect of
|
||||
PAM_MODUTIL_PIPE_FD
|
||||
|
||||
When pam_modutil_sanitize_helper_fds() is invoked with
|
||||
PAM_MODUTIL_PIPE_FD to provide a dummy pipe descriptor for stdout
|
||||
or stderr, it closes the read end of the newly created dummy pipe.
|
||||
The negative side effect of this approach is that any write to such
|
||||
descriptor triggers a SIGPIPE. Avoid this by closing the write end of
|
||||
the dummy pipe and using its read end as a dummy pipe descriptor for
|
||||
output. Any read from such descriptor returns 0, and any write just
|
||||
fails with EBADF, which should work better with unprepared writers.
|
||||
|
||||
* libpam/pam_modutil_sanitize.c (redirect_out_pipe): Remove.
|
||||
(redirect_out): Call redirect_in_pipe instead of redirect_out_pipe.
|
||||
|
||||
Fixes: b0ec5d1e ("Introduce pam_modutil_sanitize_helper_fds")
|
||||
---
|
||||
libpam/pam_modutil_sanitize.c | 30 +-----------------------------
|
||||
1 file changed, 1 insertion(+), 29 deletions(-)
|
||||
|
||||
diff --git a/libpam/pam_modutil_sanitize.c b/libpam/pam_modutil_sanitize.c
|
||||
index 605c859d..58b9537c 100644
|
||||
--- a/libpam/pam_modutil_sanitize.c
|
||||
+++ b/libpam/pam_modutil_sanitize.c
|
||||
@@ -46,34 +46,6 @@ redirect_in_pipe(pam_handle_t *pamh, int fd, const char *name)
|
||||
return fd;
|
||||
}
|
||||
|
||||
-/*
|
||||
- * Creates a pipe, closes its read end, redirects fd to its write end.
|
||||
- * Returns fd on success, -1 otherwise.
|
||||
- */
|
||||
-static int
|
||||
-redirect_out_pipe(pam_handle_t *pamh, int fd, const char *name)
|
||||
-{
|
||||
- int out[2];
|
||||
-
|
||||
- if (pipe(out) < 0) {
|
||||
- pam_syslog(pamh, LOG_ERR, "Could not create pipe: %m");
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- close(out[0]);
|
||||
-
|
||||
- if (out[1] == fd)
|
||||
- return fd;
|
||||
-
|
||||
- if (dup2(out[1], fd) != fd) {
|
||||
- pam_syslog(pamh, LOG_ERR, "dup2 of %s failed: %m", name);
|
||||
- fd = -1;
|
||||
- }
|
||||
-
|
||||
- close(out[1]);
|
||||
- return fd;
|
||||
-}
|
||||
-
|
||||
/*
|
||||
* Opens /dev/null for writing, redirects fd there.
|
||||
* Returns fd on success, -1 otherwise.
|
||||
@@ -106,7 +78,7 @@ redirect_out(pam_handle_t *pamh, enum pam_modutil_redirect_fd mode,
|
||||
{
|
||||
switch (mode) {
|
||||
case PAM_MODUTIL_PIPE_FD:
|
||||
- if (redirect_out_pipe(pamh, fd, name) < 0)
|
||||
+ if (redirect_in_pipe(pamh, fd, name) < 0)
|
||||
return -1;
|
||||
break;
|
||||
case PAM_MODUTIL_NULL_FD:
|
||||
--
|
||||
2.25.3
|
||||
|
@ -0,0 +1,283 @@
|
||||
From d57ab22133654033ee1da89f128a81572d320985 Mon Sep 17 00:00:00 2001
|
||||
From: Tomas Mraz <tmraz@fedoraproject.org>
|
||||
Date: Thu, 20 Dec 2018 13:59:25 +0100
|
||||
Subject: [PATCH] pam_motd: Cleanup the code and avoid unnecessary logging
|
||||
|
||||
The pam_motd module will not log if the default motd.d directories
|
||||
are missing.
|
||||
|
||||
Also cleanup some code cleanliness issues and fix compilation
|
||||
warnings.
|
||||
|
||||
* modules/pam_motd/pam_motd.c: Constification of constant strings.
|
||||
(try_to_display_directory): Removed unused function.
|
||||
(pam_split_string): Replace uint with unsigned int. Fix warnings.
|
||||
(compare_strings): Fix warnings by proper constification.
|
||||
(try_to_display_directories_with_overrides): Cleanups. Switch
|
||||
off the logging if the motd.d directories are missing and they
|
||||
are default ones.
|
||||
(pam_sm_open_session): Cleanup warnings. Pass the information
|
||||
to try_to_display_directories_with_overrides() that non-default
|
||||
motd options are used.
|
||||
---
|
||||
modules/pam_motd/pam_motd.c | 88 ++++++++++++++++---------------------
|
||||
1 file changed, 37 insertions(+), 51 deletions(-)
|
||||
|
||||
diff --git a/modules/pam_motd/pam_motd.c b/modules/pam_motd/pam_motd.c
|
||||
index ec3ebd58..dbd718b6 100644
|
||||
--- a/modules/pam_motd/pam_motd.c
|
||||
+++ b/modules/pam_motd/pam_motd.c
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include <pwd.h>
|
||||
#include <syslog.h>
|
||||
+#include <errno.h>
|
||||
|
||||
#include <security/_pam_macros.h>
|
||||
#include <security/pam_ext.h>
|
||||
@@ -48,8 +49,8 @@ pam_sm_close_session (pam_handle_t *pamh UNUSED, int flags UNUSED,
|
||||
return PAM_IGNORE;
|
||||
}
|
||||
|
||||
-static char default_motd[] = DEFAULT_MOTD;
|
||||
-static char default_motd_dir[] = DEFAULT_MOTD_D;
|
||||
+static const char default_motd[] = DEFAULT_MOTD;
|
||||
+static const char default_motd_dir[] = DEFAULT_MOTD_D;
|
||||
|
||||
static void try_to_display_fd(pam_handle_t *pamh, int fd)
|
||||
{
|
||||
@@ -75,28 +76,6 @@ static void try_to_display_fd(pam_handle_t *pamh, int fd)
|
||||
_pam_drop(mtmp);
|
||||
}
|
||||
|
||||
-static void try_to_display_directory(pam_handle_t *pamh, const char *dirname)
|
||||
-{
|
||||
- DIR *dirp;
|
||||
-
|
||||
- dirp = opendir(dirname);
|
||||
-
|
||||
- if (dirp != NULL) {
|
||||
- struct dirent *entry;
|
||||
-
|
||||
- while ((entry = readdir(dirp))) {
|
||||
- int fd = openat(dirfd(dirp), entry->d_name, O_RDONLY);
|
||||
-
|
||||
- if (fd >= 0) {
|
||||
- try_to_display_fd(pamh, fd);
|
||||
- close(fd);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- closedir(dirp);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
/*
|
||||
* Split a DELIM-separated string ARG into an array.
|
||||
* Outputs a newly allocated array of strings OUT_ARG_SPLIT
|
||||
@@ -104,14 +83,14 @@ static void try_to_display_directory(pam_handle_t *pamh, const char *dirname)
|
||||
* Returns 0 in case of error, 1 in case of success.
|
||||
*/
|
||||
static int pam_split_string(const pam_handle_t *pamh, char *arg, char delim,
|
||||
- char ***out_arg_split, uint *out_num_strs)
|
||||
+ char ***out_arg_split, unsigned int *out_num_strs)
|
||||
{
|
||||
char *arg_extracted = NULL;
|
||||
const char *arg_ptr = arg;
|
||||
char **arg_split = NULL;
|
||||
char delim_str[2];
|
||||
- int i = 0;
|
||||
- uint num_strs = 0;
|
||||
+ unsigned int i = 0;
|
||||
+ unsigned int num_strs = 0;
|
||||
int retval = 0;
|
||||
|
||||
delim_str[0] = delim;
|
||||
@@ -126,7 +105,7 @@ static int pam_split_string(const pam_handle_t *pamh, char *arg, char delim,
|
||||
arg_ptr = strchr(arg_ptr + sizeof(const char), delim);
|
||||
}
|
||||
|
||||
- arg_split = (char **)calloc(num_strs, sizeof(char *));
|
||||
+ arg_split = calloc(num_strs, sizeof(char *));
|
||||
if (arg_split == NULL) {
|
||||
pam_syslog(pamh, LOG_CRIT, "pam_motd: failed to allocate string array");
|
||||
goto out;
|
||||
@@ -180,10 +159,10 @@ static int join_dir_strings(char **strp_out, const char *a_str, const char *b_st
|
||||
return retval;
|
||||
}
|
||||
|
||||
-static int compare_strings(const void * a, const void * b)
|
||||
+static int compare_strings(const void *a, const void *b)
|
||||
{
|
||||
- const char *a_str = *(char **)a;
|
||||
- const char *b_str = *(char **)b;
|
||||
+ const char *a_str = *(const char * const *)a;
|
||||
+ const char *b_str = *(const char * const *)b;
|
||||
|
||||
if (a_str == NULL && b_str == NULL) {
|
||||
return 0;
|
||||
@@ -205,13 +184,13 @@ static int filter_dirents(const struct dirent *d)
|
||||
}
|
||||
|
||||
static void try_to_display_directories_with_overrides(pam_handle_t *pamh,
|
||||
- char **motd_dir_path_split, int num_motd_dirs)
|
||||
+ char **motd_dir_path_split, unsigned int num_motd_dirs, int report_missing)
|
||||
{
|
||||
struct dirent ***dirscans = NULL;
|
||||
- int *dirscans_sizes = NULL;
|
||||
- int dirscans_size_total = 0;
|
||||
+ unsigned int *dirscans_sizes = NULL;
|
||||
+ unsigned int dirscans_size_total = 0;
|
||||
char **dirnames_all = NULL;
|
||||
- int i;
|
||||
+ unsigned int i;
|
||||
int i_dirnames = 0;
|
||||
|
||||
if (pamh == NULL || motd_dir_path_split == NULL) {
|
||||
@@ -221,29 +200,31 @@ static void try_to_display_directories_with_overrides(pam_handle_t *pamh,
|
||||
goto out;
|
||||
}
|
||||
|
||||
- if ((dirscans = (struct dirent ***)calloc(num_motd_dirs,
|
||||
- sizeof(struct dirent **))) == NULL) {
|
||||
+ if ((dirscans = calloc(num_motd_dirs, sizeof(struct dirent **))) == NULL) {
|
||||
pam_syslog(pamh, LOG_CRIT, "pam_motd: failed to allocate dirent arrays");
|
||||
goto out;
|
||||
}
|
||||
- if ((dirscans_sizes = (int *)calloc(num_motd_dirs, sizeof(int))) == NULL) {
|
||||
+ if ((dirscans_sizes = calloc(num_motd_dirs, sizeof(int))) == NULL) {
|
||||
pam_syslog(pamh, LOG_CRIT, "pam_motd: failed to allocate dirent array sizes");
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_motd_dirs; i++) {
|
||||
- dirscans_sizes[i] = scandir(motd_dir_path_split[i], &(dirscans[i]),
|
||||
+ int rv;
|
||||
+ rv = scandir(motd_dir_path_split[i], &(dirscans[i]),
|
||||
filter_dirents, alphasort);
|
||||
- if (dirscans_sizes[i] < 0) {
|
||||
- pam_syslog(pamh, LOG_ERR, "pam_motd: error scanning directory %s", motd_dir_path_split[i]);
|
||||
- dirscans_sizes[i] = 0;
|
||||
+ if (rv < 0) {
|
||||
+ if (errno != ENOENT || report_missing) {
|
||||
+ pam_syslog(pamh, LOG_ERR, "pam_motd: error scanning directory %s: %m",
|
||||
+ motd_dir_path_split[i]);
|
||||
+ }
|
||||
+ dirscans_sizes[i] = rv;
|
||||
}
|
||||
dirscans_size_total += dirscans_sizes[i];
|
||||
}
|
||||
|
||||
/* Allocate space for all file names found in the directories, including duplicates. */
|
||||
- if ((dirnames_all = (char **)calloc(dirscans_size_total,
|
||||
- sizeof(char *))) == NULL) {
|
||||
+ if ((dirnames_all = calloc(dirscans_size_total, sizeof(char *))) == NULL) {
|
||||
pam_syslog(pamh, LOG_CRIT, "pam_motd: failed to allocate dirname array");
|
||||
goto out;
|
||||
}
|
||||
@@ -253,7 +234,7 @@ static void try_to_display_directories_with_overrides(pam_handle_t *pamh,
|
||||
}
|
||||
|
||||
for (i = 0; i < num_motd_dirs; i++) {
|
||||
- int j;
|
||||
+ unsigned int j;
|
||||
|
||||
for (j = 0; j < dirscans_sizes[i]; j++) {
|
||||
dirnames_all[i_dirnames] = dirscans[i][j]->d_name;
|
||||
@@ -265,7 +246,7 @@ static void try_to_display_directories_with_overrides(pam_handle_t *pamh,
|
||||
sizeof(const char *), compare_strings);
|
||||
|
||||
for (i = 0; i < dirscans_size_total; i++) {
|
||||
- int j;
|
||||
+ unsigned int j;
|
||||
|
||||
if (dirnames_all[i] == NULL) {
|
||||
continue;
|
||||
@@ -301,7 +282,8 @@ static void try_to_display_directories_with_overrides(pam_handle_t *pamh,
|
||||
out:
|
||||
_pam_drop(dirnames_all);
|
||||
for (i = 0; i < num_motd_dirs; i++) {
|
||||
- int j;
|
||||
+ unsigned int j;
|
||||
+
|
||||
for (j = 0; j < dirscans_sizes[i]; j++) {
|
||||
_pam_drop(dirscans[i][j]);
|
||||
}
|
||||
@@ -319,12 +301,13 @@ int pam_sm_open_session(pam_handle_t *pamh, int flags,
|
||||
int retval = PAM_IGNORE;
|
||||
const char *motd_path = NULL;
|
||||
char *motd_path_copy = NULL;
|
||||
- int num_motd_paths = 0;
|
||||
+ unsigned int num_motd_paths = 0;
|
||||
char **motd_path_split = NULL;
|
||||
const char *motd_dir_path = NULL;
|
||||
char *motd_dir_path_copy = NULL;
|
||||
- int num_motd_dir_paths = 0;
|
||||
+ unsigned int num_motd_dir_paths = 0;
|
||||
char **motd_dir_path_split = NULL;
|
||||
+ int report_missing;
|
||||
|
||||
if (flags & PAM_SILENT) {
|
||||
return retval;
|
||||
@@ -360,6 +343,9 @@ int pam_sm_open_session(pam_handle_t *pamh, int flags,
|
||||
if (motd_path == NULL && motd_dir_path == NULL) {
|
||||
motd_path = default_motd;
|
||||
motd_dir_path = default_motd_dir;
|
||||
+ report_missing = 0;
|
||||
+ } else {
|
||||
+ report_missing = 1;
|
||||
}
|
||||
|
||||
if (motd_path != NULL) {
|
||||
@@ -385,7 +371,7 @@ int pam_sm_open_session(pam_handle_t *pamh, int flags,
|
||||
}
|
||||
|
||||
if (motd_path_split != NULL) {
|
||||
- int i;
|
||||
+ unsigned int i;
|
||||
|
||||
for (i = 0; i < num_motd_paths; i++) {
|
||||
int fd = open(motd_path_split[i], O_RDONLY, 0);
|
||||
@@ -402,7 +388,7 @@ int pam_sm_open_session(pam_handle_t *pamh, int flags,
|
||||
|
||||
if (motd_dir_path_split != NULL)
|
||||
try_to_display_directories_with_overrides(pamh, motd_dir_path_split,
|
||||
- num_motd_dir_paths);
|
||||
+ num_motd_dir_paths, report_missing);
|
||||
|
||||
out:
|
||||
_pam_drop(motd_path_copy);
|
||||
--
|
||||
2.37.3
|
||||
|
||||
From c2c0434bd634a817f2b16ce7f58fc96c04e88b03 Mon Sep 17 00:00:00 2001
|
||||
From: "Dmitry V. Levin" <ldv@altlinux.org>
|
||||
Date: Sun, 26 Apr 2020 11:12:59 +0000
|
||||
Subject: [PATCH] pam_motd: fix NULL dereference when at least one of motd
|
||||
directories is not available
|
||||
|
||||
* modules/pam_motd/pam_motd.c
|
||||
(try_to_display_directories_with_overrides): Do not assign -1U to
|
||||
dirscans_sizes[i] when scandir(motd_dir_path_split[i]) returns an error.
|
||||
|
||||
Resolves: https://bugzilla.altlinux.org/38389
|
||||
Fixes: d57ab221 ("pam_motd: Cleanup the code and avoid unnecessary logging")
|
||||
---
|
||||
modules/pam_motd/pam_motd.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/modules/pam_motd/pam_motd.c b/modules/pam_motd/pam_motd.c
|
||||
index df09b7d0..8147c6fd 100644
|
||||
--- a/modules/pam_motd/pam_motd.c
|
||||
+++ b/modules/pam_motd/pam_motd.c
|
||||
@@ -219,6 +219,7 @@ static void try_to_display_directories_with_overrides(pam_handle_t *pamh,
|
||||
pam_syslog(pamh, LOG_ERR, "pam_motd: error scanning directory %s: %m",
|
||||
motd_dir_path_split[i]);
|
||||
}
|
||||
+ } else {
|
||||
dirscans_sizes[i] = rv;
|
||||
}
|
||||
dirscans_size_total += dirscans_sizes[i];
|
||||
--
|
||||
2.37.3
|
||||
|
@ -0,0 +1,57 @@
|
||||
From 62cd745d730e5ba13d5d7092ac566fc0b2148e61 Mon Sep 17 00:00:00 2001
|
||||
From: "Dmitry V. Levin" <ldv@altlinux.org>
|
||||
Date: Sun, 26 Apr 2020 11:12:59 +0000
|
||||
Subject: [PATCH] pam_motd: fix memory leak
|
||||
|
||||
pam_motd used to leak memory allocated for each motd file
|
||||
successfully opened in try_to_display_directories_with_overrides.
|
||||
|
||||
* modules/pam_motd/pam_motd.c
|
||||
(try_to_display_directories_with_overrides): Free abs_path.
|
||||
|
||||
Fixes: f9c9c721 ("pam_motd: Support multiple motd paths specified, with filename overrides (#69)")
|
||||
---
|
||||
modules/pam_motd/pam_motd.c | 20 ++++++++++----------
|
||||
1 file changed, 10 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/modules/pam_motd/pam_motd.c b/modules/pam_motd/pam_motd.c
|
||||
index f0cd317d..3be129a5 100644
|
||||
--- a/modules/pam_motd/pam_motd.c
|
||||
+++ b/modules/pam_motd/pam_motd.c
|
||||
@@ -259,23 +259,23 @@ static void try_to_display_directories_with_overrides(pam_handle_t *pamh,
|
||||
|
||||
for (j = 0; j < num_motd_dirs; j++) {
|
||||
char *abs_path = NULL;
|
||||
+ int fd;
|
||||
|
||||
if (join_dir_strings(&abs_path, motd_dir_path_split[j],
|
||||
- dirnames_all[i]) < 0) {
|
||||
+ dirnames_all[i]) < 0 || abs_path == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
- if (abs_path != NULL) {
|
||||
- int fd = open(abs_path, O_RDONLY, 0);
|
||||
- if (fd >= 0) {
|
||||
- try_to_display_fd(pamh, fd);
|
||||
- close(fd);
|
||||
+ fd = open(abs_path, O_RDONLY, 0);
|
||||
+ _pam_drop(abs_path);
|
||||
|
||||
- /* We displayed a file, skip to the next file name. */
|
||||
- break;
|
||||
- }
|
||||
+ if (fd >= 0) {
|
||||
+ try_to_display_fd(pamh, fd);
|
||||
+ close(fd);
|
||||
+
|
||||
+ /* We displayed a file, skip to the next file name. */
|
||||
+ break;
|
||||
}
|
||||
- _pam_drop(abs_path);
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
2.35.3
|
||||
|
@ -0,0 +1,133 @@
|
||||
From 8eaf5570cf011148a0b55c53570df5edaafebdb0 Mon Sep 17 00:00:00 2001
|
||||
From: Robert Fairley <rfairley@users.noreply.github.com>
|
||||
Date: Wed, 21 Nov 2018 02:46:02 -0500
|
||||
Subject: [PATCH] pam_motd: Fix segmentation fault when no motd_dir specified
|
||||
(#76)
|
||||
|
||||
This fixes a regression introduced by #69, where motd_path was set
|
||||
to NULL and passed into strdup() if the motd_dir argument was
|
||||
not specified in the configuration file. This caused a segmentation
|
||||
fault.
|
||||
|
||||
* modules/pam_motd/pam_motd.c: fix checks for NULL in arguments
|
||||
* xtests/Makefile.am: add test scripts and config file
|
||||
* xtests/tst-pam_motd.sh: add running tst-pam_motd4.sh
|
||||
* xtests/tst-pam_motd4.pamd: create
|
||||
* xtests/tst-pam_motd4.sh: create
|
||||
---
|
||||
modules/pam_motd/pam_motd.c | 15 ++++++++++-----
|
||||
xtests/Makefile.am | 4 ++--
|
||||
xtests/tst-pam_motd.sh | 1 +
|
||||
xtests/tst-pam_motd4.pamd | 3 +++
|
||||
xtests/tst-pam_motd4.sh | 27 +++++++++++++++++++++++++++
|
||||
5 files changed, 43 insertions(+), 7 deletions(-)
|
||||
create mode 100644 xtests/tst-pam_motd4.pamd
|
||||
create mode 100755 xtests/tst-pam_motd4.sh
|
||||
|
||||
diff --git a/modules/pam_motd/pam_motd.c b/modules/pam_motd/pam_motd.c
|
||||
index 1c1cfcfa..ec3ebd58 100644
|
||||
--- a/modules/pam_motd/pam_motd.c
|
||||
+++ b/modules/pam_motd/pam_motd.c
|
||||
@@ -132,7 +132,6 @@ static int pam_split_string(const pam_handle_t *pamh, char *arg, char delim,
|
||||
goto out;
|
||||
}
|
||||
|
||||
-
|
||||
arg_extracted = strtok_r(arg, delim_str, &arg);
|
||||
while (arg_extracted != NULL && i < num_strs) {
|
||||
arg_split[i++] = arg_extracted;
|
||||
@@ -363,15 +362,21 @@ int pam_sm_open_session(pam_handle_t *pamh, int flags,
|
||||
motd_dir_path = default_motd_dir;
|
||||
}
|
||||
|
||||
- motd_path_copy = strdup(motd_path);
|
||||
+ if (motd_path != NULL) {
|
||||
+ motd_path_copy = strdup(motd_path);
|
||||
+ }
|
||||
+
|
||||
if (motd_path_copy != NULL) {
|
||||
- if (pam_split_string(pamh, motd_path_copy, ':', &motd_path_split,
|
||||
- &num_motd_paths) == 0) {
|
||||
+ if (pam_split_string(pamh, motd_path_copy, ':',
|
||||
+ &motd_path_split, &num_motd_paths) == 0) {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
- motd_dir_path_copy = strdup(motd_dir_path);
|
||||
+ if (motd_dir_path != NULL) {
|
||||
+ motd_dir_path_copy = strdup(motd_dir_path);
|
||||
+ }
|
||||
+
|
||||
if (motd_dir_path_copy != NULL) {
|
||||
if (pam_split_string(pamh, motd_dir_path_copy, ':',
|
||||
&motd_dir_path_split, &num_motd_dir_paths) == 0) {
|
||||
diff --git a/xtests/Makefile.am b/xtests/Makefile.am
|
||||
index 555d5e33..4d5aba3d 100644
|
||||
--- a/xtests/Makefile.am
|
||||
+++ b/xtests/Makefile.am
|
||||
@@ -34,8 +34,8 @@ EXTRA_DIST = run-xtests.sh tst-pam_dispatch1.pamd tst-pam_dispatch2.pamd \
|
||||
tst-pam_pwhistory1.pamd tst-pam_pwhistory1.sh \
|
||||
tst-pam_time1.pamd time.conf \
|
||||
tst-pam_motd.sh tst-pam_motd1.sh tst-pam_motd2.sh \
|
||||
- tst-pam_motd3.sh tst-pam_motd1.pamd \
|
||||
- tst-pam_motd2.pamd tst-pam_motd3.pamd
|
||||
+ tst-pam_motd3.sh tst-pam_motd4.sh tst-pam_motd1.pamd \
|
||||
+ tst-pam_motd2.pamd tst-pam_motd3.pamd tst-pam_motd4.pamd
|
||||
|
||||
XTESTS = tst-pam_dispatch1 tst-pam_dispatch2 tst-pam_dispatch3 \
|
||||
tst-pam_dispatch4 tst-pam_dispatch5 \
|
||||
diff --git a/xtests/tst-pam_motd.sh b/xtests/tst-pam_motd.sh
|
||||
index 9b0c38f6..90801280 100755
|
||||
--- a/xtests/tst-pam_motd.sh
|
||||
+++ b/xtests/tst-pam_motd.sh
|
||||
@@ -5,3 +5,4 @@ set -e
|
||||
./tst-pam_motd1.sh
|
||||
./tst-pam_motd2.sh
|
||||
./tst-pam_motd3.sh
|
||||
+./tst-pam_motd4.sh
|
||||
diff --git a/xtests/tst-pam_motd4.pamd b/xtests/tst-pam_motd4.pamd
|
||||
new file mode 100644
|
||||
index 00000000..9dc311ad
|
||||
--- /dev/null
|
||||
+++ b/xtests/tst-pam_motd4.pamd
|
||||
@@ -0,0 +1,3 @@
|
||||
+#%PAM-1.0
|
||||
+session required pam_permit.so
|
||||
+session optional pam_motd.so motd=tst-pam_motd4.d/etc/motd
|
||||
diff --git a/xtests/tst-pam_motd4.sh b/xtests/tst-pam_motd4.sh
|
||||
new file mode 100755
|
||||
index 00000000..6022177f
|
||||
--- /dev/null
|
||||
+++ b/xtests/tst-pam_motd4.sh
|
||||
@@ -0,0 +1,27 @@
|
||||
+#!/bin/bash
|
||||
+
|
||||
+TST_DIR="tst-pam_motd4.d"
|
||||
+
|
||||
+function tst_cleanup() {
|
||||
+ rm -rf "${TST_DIR}"
|
||||
+ rm -f tst-pam_motd4.out
|
||||
+}
|
||||
+
|
||||
+mkdir -p ${TST_DIR}/etc
|
||||
+
|
||||
+# Verify the case of single motd with no motd_dir given in tst-pam_motd4.pamd
|
||||
+echo "motd: /etc/motd" > ${TST_DIR}/etc/motd
|
||||
+
|
||||
+./tst-pam_motd tst-pam_motd4 > tst-pam_motd4.out
|
||||
+
|
||||
+RET=$?
|
||||
+
|
||||
+motd_to_show_output=$(cat tst-pam_motd4.out | grep "motd: /etc/motd")
|
||||
+if [ -z "${motd_to_show_output}" ];
|
||||
+then
|
||||
+ tst_cleanup
|
||||
+ exit 1
|
||||
+fi
|
||||
+
|
||||
+tst_cleanup
|
||||
+exit $RET
|
||||
--
|
||||
2.35.1
|
||||
|
@ -0,0 +1,691 @@
|
||||
diff -up Linux-PAM-1.3.1/modules/pam_motd/pam_motd.8.xml.pam_motd-support-multiple-motd-paths1 Linux-PAM-1.3.1/modules/pam_motd/pam_motd.8.xml
|
||||
--- Linux-PAM-1.3.1/modules/pam_motd/pam_motd.8.xml.pam_motd-support-multiple-motd-paths1 2022-04-25 12:32:36.939663167 +0200
|
||||
+++ Linux-PAM-1.3.1/modules/pam_motd/pam_motd.8.xml 2022-04-25 12:34:43.506582206 +0200
|
||||
@@ -21,6 +21,9 @@
|
||||
<arg choice="opt">
|
||||
motd=<replaceable>/path/filename</replaceable>
|
||||
</arg>
|
||||
+ <arg choice="opt">
|
||||
+ motd_dir=<replaceable>/path/dirname.d</replaceable>
|
||||
+ </arg>
|
||||
</cmdsynopsis>
|
||||
</refsynopsisdiv>
|
||||
|
||||
@@ -31,18 +34,49 @@
|
||||
<para>
|
||||
pam_motd is a PAM module that can be used to display
|
||||
arbitrary motd (message of the day) files after a successful
|
||||
- login. By default the <filename>/etc/motd</filename> file and
|
||||
- all files from <filename>/etc/motd.d</filename> are
|
||||
- shown. The message size is limited to 64KB.
|
||||
+ login. By default, pam_motd shows files in the
|
||||
+ following locations:
|
||||
+ </para>
|
||||
+ <para>
|
||||
+ <simplelist type='vert'>
|
||||
+ <member><filename>/etc/motd</filename></member>
|
||||
+ <member><filename>/run/motd</filename></member>
|
||||
+ <member><filename>/usr/lib/motd</filename></member>
|
||||
+ <member><filename>/etc/motd.d/</filename></member>
|
||||
+ <member><filename>/run/motd.d/</filename></member>
|
||||
+ <member><filename>/usr/lib/motd.d/</filename></member>
|
||||
+ </simplelist>
|
||||
+ </para>
|
||||
+ <para>
|
||||
+ Each message size is limited to 64KB.
|
||||
+ </para>
|
||||
+ <para>
|
||||
+ If <filename>/etc/motd</filename> does not exist,
|
||||
+ then <filename>/run/motd</filename> is shown. If
|
||||
+ <filename>/run/motd</filename> does not exist, then
|
||||
+ <filename>/usr/lib/motd</filename> is shown.
|
||||
+ </para>
|
||||
+ <para>
|
||||
+ Similar overriding behavior applies to the directories.
|
||||
+ Files in <filename>/etc/motd.d/</filename> override files
|
||||
+ with the same name in <filename>/run/motd.d/</filename> and
|
||||
+ <filename>/usr/lib/motd.d/</filename>. Files in <filename>/run/motd.d/</filename>
|
||||
+ override files with the same name in <filename>/usr/lib/motd.d/</filename>.
|
||||
+ </para>
|
||||
+ <para>
|
||||
+ Files in the directories listed above are displayed in lexicographic
|
||||
+ order by name. Moreover, the files are filtered by reading them with the
|
||||
+ credentials of the target user authenticating on the system.
|
||||
</para>
|
||||
<para>
|
||||
To silence a message,
|
||||
a symbolic link with target <filename>/dev/null</filename>
|
||||
may be placed in <filename>/etc/motd.d</filename> with
|
||||
the same filename as the message to be silenced. Example:
|
||||
+ Creating a symbolic link as follows silences <filename>/usr/lib/motd.d/my_motd</filename>.
|
||||
</para>
|
||||
<para>
|
||||
- <command>ln -sfn /dev/null /etc/motd.d/my_motd</command>
|
||||
+ <command>ln -s /dev/null /etc/motd.d/my_motd</command>
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
@@ -56,8 +90,10 @@
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
- The <filename>/path/filename</filename> file is displayed
|
||||
- as message of the day.
|
||||
+ The <filename>/path/filename</filename> file is displayed
|
||||
+ as message of the day. Multiple paths to try can be
|
||||
+ specified as a colon-separated list. By default this option
|
||||
+ is set to <filename>/etc/motd:/run/motd:/usr/lib/motd</filename>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
@@ -68,16 +104,17 @@
|
||||
<listitem>
|
||||
<para>
|
||||
The <filename>/path/dirname.d</filename> directory is scanned
|
||||
- and each file contained inside of it is displayed.
|
||||
+ and each file contained inside of it is displayed. Multiple
|
||||
+ directories to scan can be specified as a colon-separated list.
|
||||
+ By default this option is set to <filename>/etc/motd.d:/run/motd.d:/usr/lib/motd.d</filename>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
<para>
|
||||
- When no options are given, the default is to display both
|
||||
- <filename>/etc/motd</filename> and the contents of
|
||||
- <filename>/etc/motd.d</filename>. Specifying either option (or both)
|
||||
- will disable this default behavior.
|
||||
+ When no options are given, the default behavior applies for both
|
||||
+ options. Specifying either option (or both) will disable the
|
||||
+ default behavior for both options.
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
diff -up Linux-PAM-1.3.1/modules/pam_motd/pam_motd.c.pam_motd-support-multiple-motd-paths1 Linux-PAM-1.3.1/modules/pam_motd/pam_motd.c
|
||||
--- Linux-PAM-1.3.1/modules/pam_motd/pam_motd.c.pam_motd-support-multiple-motd-paths1 2018-05-18 11:50:46.000000000 +0200
|
||||
+++ Linux-PAM-1.3.1/modules/pam_motd/pam_motd.c 2022-04-25 12:32:36.947663225 +0200
|
||||
@@ -33,8 +33,8 @@
|
||||
*/
|
||||
|
||||
#define PAM_SM_SESSION
|
||||
-#define DEFAULT_MOTD "/etc/motd"
|
||||
-#define DEFAULT_MOTD_D "/etc/motd.d"
|
||||
+#define DEFAULT_MOTD "/etc/motd:/run/motd:/usr/lib/motd"
|
||||
+#define DEFAULT_MOTD_D "/etc/motd.d:/run/motd.d:/usr/lib/motd.d"
|
||||
|
||||
#include <security/pam_modules.h>
|
||||
#include <security/pam_modutil.h>
|
||||
@@ -97,12 +97,235 @@ static void try_to_display_directory(pam
|
||||
}
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Split a DELIM-separated string ARG into an array.
|
||||
+ * Outputs a newly allocated array of strings OUT_ARG_SPLIT
|
||||
+ * and the number of strings OUT_NUM_STRS.
|
||||
+ * Returns 0 in case of error, 1 in case of success.
|
||||
+ */
|
||||
+static int pam_split_string(const pam_handle_t *pamh, char *arg, char delim,
|
||||
+ char ***out_arg_split, uint *out_num_strs)
|
||||
+{
|
||||
+ char *arg_extracted = NULL;
|
||||
+ const char *arg_ptr = arg;
|
||||
+ char **arg_split = NULL;
|
||||
+ char delim_str[2];
|
||||
+ int i = 0;
|
||||
+ uint num_strs = 0;
|
||||
+ int retval = 0;
|
||||
+
|
||||
+ delim_str[0] = delim;
|
||||
+ delim_str[1] = '\0';
|
||||
+
|
||||
+ if (arg == NULL) {
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ while (arg_ptr != NULL) {
|
||||
+ num_strs++;
|
||||
+ arg_ptr = strchr(arg_ptr + sizeof(const char), delim);
|
||||
+ }
|
||||
+
|
||||
+ arg_split = (char **)calloc(num_strs, sizeof(char *));
|
||||
+ if (arg_split == NULL) {
|
||||
+ pam_syslog(pamh, LOG_CRIT, "pam_motd: failed to allocate string array");
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ arg_extracted = strtok_r(arg, delim_str, &arg);
|
||||
+ while (arg_extracted != NULL && i < num_strs) {
|
||||
+ arg_split[i++] = arg_extracted;
|
||||
+ arg_extracted = strtok_r(NULL, delim_str, &arg);
|
||||
+ }
|
||||
+
|
||||
+ retval = 1;
|
||||
+
|
||||
+ out:
|
||||
+ *out_num_strs = num_strs;
|
||||
+ *out_arg_split = arg_split;
|
||||
+
|
||||
+ return retval;
|
||||
+}
|
||||
+
|
||||
+/* Join A_STR and B_STR, inserting a "/" between them if one is not already trailing
|
||||
+ * in A_STR or beginning B_STR. A pointer to a newly allocated string holding the
|
||||
+ * joined string is returned in STRP_OUT.
|
||||
+ * Returns -1 in case of error, or the number of bytes in the joined string in
|
||||
+ * case of success. */
|
||||
+static int join_dir_strings(char **strp_out, const char *a_str, const char *b_str)
|
||||
+{
|
||||
+ int has_sep = 0;
|
||||
+ int retval = -1;
|
||||
+ char *join_strp = NULL;
|
||||
+
|
||||
+ if (strp_out == NULL || a_str == NULL || b_str == NULL) {
|
||||
+ goto out;
|
||||
+ }
|
||||
+ if (strlen(a_str) == 0) {
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ has_sep = (a_str[strlen(a_str) - 1] == '/') || (b_str[0] == '/');
|
||||
+
|
||||
+ retval = asprintf(&join_strp, "%s%s%s", a_str,
|
||||
+ (has_sep == 1) ? "" : "/", b_str);
|
||||
+
|
||||
+ if (retval < 0) {
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ *strp_out = join_strp;
|
||||
+
|
||||
+ out:
|
||||
+ return retval;
|
||||
+}
|
||||
+
|
||||
+static int compare_strings(const void * a, const void * b)
|
||||
+{
|
||||
+ const char *a_str = *(char **)a;
|
||||
+ const char *b_str = *(char **)b;
|
||||
+
|
||||
+ if (a_str == NULL && b_str == NULL) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+ else if (a_str == NULL) {
|
||||
+ return -1;
|
||||
+ }
|
||||
+ else if (b_str == NULL) {
|
||||
+ return 1;
|
||||
+ }
|
||||
+ else {
|
||||
+ return strcmp(a_str, b_str);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int filter_dirents(const struct dirent *d)
|
||||
+{
|
||||
+ return (d->d_type == DT_REG || d->d_type == DT_LNK);
|
||||
+}
|
||||
+
|
||||
+static void try_to_display_directories_with_overrides(pam_handle_t *pamh,
|
||||
+ char **motd_dir_path_split, int num_motd_dirs)
|
||||
+{
|
||||
+ struct dirent ***dirscans = NULL;
|
||||
+ int *dirscans_sizes = NULL;
|
||||
+ int dirscans_size_total = 0;
|
||||
+ char **dirnames_all = NULL;
|
||||
+ int i;
|
||||
+ int i_dirnames = 0;
|
||||
+
|
||||
+ if (pamh == NULL || motd_dir_path_split == NULL) {
|
||||
+ goto out;
|
||||
+ }
|
||||
+ if (num_motd_dirs < 1) {
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if ((dirscans = (struct dirent ***)calloc(num_motd_dirs,
|
||||
+ sizeof(struct dirent **))) == NULL) {
|
||||
+ pam_syslog(pamh, LOG_CRIT, "pam_motd: failed to allocate dirent arrays");
|
||||
+ goto out;
|
||||
+ }
|
||||
+ if ((dirscans_sizes = (int *)calloc(num_motd_dirs, sizeof(int))) == NULL) {
|
||||
+ pam_syslog(pamh, LOG_CRIT, "pam_motd: failed to allocate dirent array sizes");
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < num_motd_dirs; i++) {
|
||||
+ dirscans_sizes[i] = scandir(motd_dir_path_split[i], &(dirscans[i]),
|
||||
+ filter_dirents, alphasort);
|
||||
+ if (dirscans_sizes[i] < 0) {
|
||||
+ pam_syslog(pamh, LOG_ERR, "pam_motd: error scanning directory %s", motd_dir_path_split[i]);
|
||||
+ dirscans_sizes[i] = 0;
|
||||
+ }
|
||||
+ dirscans_size_total += dirscans_sizes[i];
|
||||
+ }
|
||||
+
|
||||
+ /* Allocate space for all file names found in the directories, including duplicates. */
|
||||
+ if ((dirnames_all = (char **)calloc(dirscans_size_total,
|
||||
+ sizeof(char *))) == NULL) {
|
||||
+ pam_syslog(pamh, LOG_CRIT, "pam_motd: failed to allocate dirname array");
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < dirscans_size_total; i++) {
|
||||
+ dirnames_all[i] = NULL;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < num_motd_dirs; i++) {
|
||||
+ int j;
|
||||
+
|
||||
+ for (j = 0; j < dirscans_sizes[i]; j++) {
|
||||
+ dirnames_all[i_dirnames] = dirscans[i][j]->d_name;
|
||||
+ i_dirnames++;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ qsort(dirnames_all, dirscans_size_total,
|
||||
+ sizeof(const char *), compare_strings);
|
||||
+
|
||||
+ for (i = 0; i < dirscans_size_total; i++) {
|
||||
+ int j;
|
||||
+
|
||||
+ if (dirnames_all[i] == NULL) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ /* Skip duplicate file names. */
|
||||
+ if (i > 0 && strcmp(dirnames_all[i], dirnames_all[i - 1]) == 0) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ for (j = 0; j < num_motd_dirs; j++) {
|
||||
+ char *abs_path = NULL;
|
||||
+
|
||||
+ if (join_dir_strings(&abs_path, motd_dir_path_split[j],
|
||||
+ dirnames_all[i]) < 0) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (abs_path != NULL) {
|
||||
+ int fd = open(abs_path, O_RDONLY, 0);
|
||||
+ if (fd >= 0) {
|
||||
+ try_to_display_fd(pamh, fd);
|
||||
+ close(fd);
|
||||
+
|
||||
+ /* We displayed a file, skip to the next file name. */
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ _pam_drop(abs_path);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ out:
|
||||
+ _pam_drop(dirnames_all);
|
||||
+ for (i = 0; i < num_motd_dirs; i++) {
|
||||
+ int j;
|
||||
+ for (j = 0; j < dirscans_sizes[i]; j++) {
|
||||
+ _pam_drop(dirscans[i][j]);
|
||||
+ }
|
||||
+ _pam_drop(dirscans[i]);
|
||||
+ }
|
||||
+ _pam_drop(dirscans_sizes);
|
||||
+ _pam_drop(dirscans);
|
||||
+
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
int pam_sm_open_session(pam_handle_t *pamh, int flags,
|
||||
int argc, const char **argv)
|
||||
{
|
||||
int retval = PAM_IGNORE;
|
||||
const char *motd_path = NULL;
|
||||
+ char *motd_path_copy = NULL;
|
||||
+ int num_motd_paths = 0;
|
||||
+ char **motd_path_split = NULL;
|
||||
const char *motd_dir_path = NULL;
|
||||
+ char *motd_dir_path_copy = NULL;
|
||||
+ int num_motd_dir_paths = 0;
|
||||
+ char **motd_dir_path_split = NULL;
|
||||
|
||||
if (flags & PAM_SILENT) {
|
||||
return retval;
|
||||
@@ -140,17 +363,47 @@ int pam_sm_open_session(pam_handle_t *pa
|
||||
motd_dir_path = default_motd_dir;
|
||||
}
|
||||
|
||||
- if (motd_path != NULL) {
|
||||
- int fd = open(motd_path, O_RDONLY, 0);
|
||||
+ motd_path_copy = strdup(motd_path);
|
||||
+ if (motd_path_copy != NULL) {
|
||||
+ if (pam_split_string(pamh, motd_path_copy, ':', &motd_path_split,
|
||||
+ &num_motd_paths) == 0) {
|
||||
+ goto out;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ motd_dir_path_copy = strdup(motd_dir_path);
|
||||
+ if (motd_dir_path_copy != NULL) {
|
||||
+ if (pam_split_string(pamh, motd_dir_path_copy, ':',
|
||||
+ &motd_dir_path_split, &num_motd_dir_paths) == 0) {
|
||||
+ goto out;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (motd_path_split != NULL) {
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < num_motd_paths; i++) {
|
||||
+ int fd = open(motd_path_split[i], O_RDONLY, 0);
|
||||
|
||||
- if (fd >= 0) {
|
||||
- try_to_display_fd(pamh, fd);
|
||||
- close(fd);
|
||||
+ if (fd >= 0) {
|
||||
+ try_to_display_fd(pamh, fd);
|
||||
+ close(fd);
|
||||
+
|
||||
+ /* We found and displayed a file, move onto next filename. */
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
- if (motd_dir_path != NULL)
|
||||
- try_to_display_directory(pamh, motd_dir_path);
|
||||
+ if (motd_dir_path_split != NULL)
|
||||
+ try_to_display_directories_with_overrides(pamh, motd_dir_path_split,
|
||||
+ num_motd_dir_paths);
|
||||
+
|
||||
+ out:
|
||||
+ _pam_drop(motd_path_copy);
|
||||
+ _pam_drop(motd_path_split);
|
||||
+ _pam_drop(motd_dir_path_copy);
|
||||
+ _pam_drop(motd_dir_path_split);
|
||||
|
||||
return retval;
|
||||
}
|
||||
diff -up Linux-PAM-1.3.1/xtests/Makefile.am.pam_motd-support-multiple-motd-paths1 Linux-PAM-1.3.1/xtests/Makefile.am
|
||||
--- Linux-PAM-1.3.1/xtests/Makefile.am.pam_motd-support-multiple-motd-paths1 2017-02-10 11:10:15.000000000 +0100
|
||||
+++ Linux-PAM-1.3.1/xtests/Makefile.am 2022-04-25 12:32:36.947663225 +0200
|
||||
@@ -32,7 +32,10 @@ EXTRA_DIST = run-xtests.sh tst-pam_dispa
|
||||
tst-pam_substack5.pamd tst-pam_substack5a.pamd tst-pam_substack5.sh \
|
||||
tst-pam_assemble_line1.pamd tst-pam_assemble_line1.sh \
|
||||
tst-pam_pwhistory1.pamd tst-pam_pwhistory1.sh \
|
||||
- tst-pam_time1.pamd time.conf
|
||||
+ tst-pam_time1.pamd time.conf \
|
||||
+ tst-pam_motd.sh tst-pam_motd1.sh tst-pam_motd2.sh \
|
||||
+ tst-pam_motd3.sh tst-pam_motd1.pamd \
|
||||
+ tst-pam_motd2.pamd tst-pam_motd3.pamd
|
||||
|
||||
XTESTS = tst-pam_dispatch1 tst-pam_dispatch2 tst-pam_dispatch3 \
|
||||
tst-pam_dispatch4 tst-pam_dispatch5 \
|
||||
@@ -41,7 +44,7 @@ XTESTS = tst-pam_dispatch1 tst-pam_dispa
|
||||
tst-pam_access1 tst-pam_access2 tst-pam_access3 \
|
||||
tst-pam_access4 tst-pam_limits1 tst-pam_succeed_if1 \
|
||||
tst-pam_group1 tst-pam_authfail tst-pam_authsucceed \
|
||||
- tst-pam_pwhistory1 tst-pam_time1
|
||||
+ tst-pam_pwhistory1 tst-pam_time1 tst-pam_motd
|
||||
|
||||
NOSRCTESTS = tst-pam_substack1 tst-pam_substack2 tst-pam_substack3 \
|
||||
tst-pam_substack4 tst-pam_substack5 tst-pam_assemble_line1
|
||||
diff -up Linux-PAM-1.3.1/xtests/tst-pam_motd1.pamd.pam_motd-support-multiple-motd-paths1 Linux-PAM-1.3.1/xtests/tst-pam_motd1.pamd
|
||||
--- Linux-PAM-1.3.1/xtests/tst-pam_motd1.pamd.pam_motd-support-multiple-motd-paths1 2022-04-25 12:32:36.947663225 +0200
|
||||
+++ Linux-PAM-1.3.1/xtests/tst-pam_motd1.pamd 2022-04-25 12:32:36.947663225 +0200
|
||||
@@ -0,0 +1,3 @@
|
||||
+#%PAM-1.0
|
||||
+session required pam_permit.so
|
||||
+session optional pam_motd.so motd=tst-pam_motd1.d/etc/motd motd_dir=tst-pam_motd1.d/etc/motd.d
|
||||
diff -up Linux-PAM-1.3.1/xtests/tst-pam_motd1.sh.pam_motd-support-multiple-motd-paths1 Linux-PAM-1.3.1/xtests/tst-pam_motd1.sh
|
||||
--- Linux-PAM-1.3.1/xtests/tst-pam_motd1.sh.pam_motd-support-multiple-motd-paths1 2022-04-25 12:32:36.947663225 +0200
|
||||
+++ Linux-PAM-1.3.1/xtests/tst-pam_motd1.sh 2022-04-25 12:32:36.947663225 +0200
|
||||
@@ -0,0 +1,36 @@
|
||||
+#!/bin/bash
|
||||
+
|
||||
+TST_DIR="tst-pam_motd1.d"
|
||||
+
|
||||
+function tst_cleanup() {
|
||||
+ rm -rf "${TST_DIR}"
|
||||
+ rm -f tst-pam_motd1.out
|
||||
+}
|
||||
+
|
||||
+mkdir -p ${TST_DIR}
|
||||
+mkdir -p ${TST_DIR}/etc/motd.d
|
||||
+
|
||||
+# Verify the case of single motd and motd.d directory works
|
||||
+echo "motd: /etc/motd" > ${TST_DIR}/etc/motd
|
||||
+echo "motd: /etc/motd.d/test" > ${TST_DIR}/etc/motd.d/test
|
||||
+
|
||||
+./tst-pam_motd tst-pam_motd1 > tst-pam_motd1.out
|
||||
+
|
||||
+RET=$?
|
||||
+
|
||||
+motd_to_show_output=$(cat tst-pam_motd1.out | grep "motd: /etc/motd")
|
||||
+if [ -z "${motd_to_show_output}" ];
|
||||
+then
|
||||
+ tst_cleanup
|
||||
+ exit 1
|
||||
+fi
|
||||
+
|
||||
+motd_dir_to_show_output=$(cat tst-pam_motd1.out | grep "motd: /etc/motd.d/test")
|
||||
+if [ -z "${motd_dir_to_show_output}" ];
|
||||
+then
|
||||
+ tst_cleanup
|
||||
+ exit 1
|
||||
+fi
|
||||
+
|
||||
+tst_cleanup
|
||||
+exit $RET
|
||||
diff -up Linux-PAM-1.3.1/xtests/tst-pam_motd2.pamd.pam_motd-support-multiple-motd-paths1 Linux-PAM-1.3.1/xtests/tst-pam_motd2.pamd
|
||||
--- Linux-PAM-1.3.1/xtests/tst-pam_motd2.pamd.pam_motd-support-multiple-motd-paths1 2022-04-25 12:32:36.947663225 +0200
|
||||
+++ Linux-PAM-1.3.1/xtests/tst-pam_motd2.pamd 2022-04-25 12:32:36.947663225 +0200
|
||||
@@ -0,0 +1,3 @@
|
||||
+#%PAM-1.0
|
||||
+session required pam_permit.so
|
||||
+session optional pam_motd.so motd=tst-pam_motd2.d/etc/motd:tst-pam_motd2.d/run/motd:tst-pam_motd2.d/usr/lib/motd motd_dir=tst-pam_motd2.d/etc/motd.d:tst-pam_motd2.d/run/motd.d:tst-pam_motd2.d/usr/lib/motd.d
|
||||
diff -up Linux-PAM-1.3.1/xtests/tst-pam_motd2.sh.pam_motd-support-multiple-motd-paths1 Linux-PAM-1.3.1/xtests/tst-pam_motd2.sh
|
||||
--- Linux-PAM-1.3.1/xtests/tst-pam_motd2.sh.pam_motd-support-multiple-motd-paths1 2022-04-25 12:32:36.947663225 +0200
|
||||
+++ Linux-PAM-1.3.1/xtests/tst-pam_motd2.sh 2022-04-25 12:32:36.947663225 +0200
|
||||
@@ -0,0 +1,53 @@
|
||||
+#!/bin/bash
|
||||
+
|
||||
+TST_DIR="tst-pam_motd2.d"
|
||||
+
|
||||
+function tst_cleanup() {
|
||||
+ rm -rf "${TST_DIR}"
|
||||
+ rm -f tst-pam_motd2.out
|
||||
+}
|
||||
+
|
||||
+mkdir -p ${TST_DIR}
|
||||
+mkdir -p ${TST_DIR}/etc/motd.d
|
||||
+mkdir -p ${TST_DIR}/run/motd.d
|
||||
+mkdir -p ${TST_DIR}/usr/lib/motd.d
|
||||
+
|
||||
+echo "motd: /etc/motd" > ${TST_DIR}/etc/motd
|
||||
+echo "motd: /run/motd" > ${TST_DIR}/run/motd
|
||||
+echo "motd: /usr/lib/motd" > ${TST_DIR}/usr/lib/motd
|
||||
+
|
||||
+# Drop a motd file in test directories such that every overriding
|
||||
+# condition (for 3 directories in this case) will be seen.
|
||||
+echo "motd: e0r0u1 in usr/lib - will show" > ${TST_DIR}/usr/lib/motd.d/e0r0u1.motd
|
||||
+echo "motd: e0r1u0 in run - will show" > ${TST_DIR}/run/motd.d/e0r1u0.motd
|
||||
+echo "motd: e0r1u1 in usr/lib - not show" > ${TST_DIR}/usr/lib/motd.d/e0r1u1.motd
|
||||
+echo "motd: e0r1u1 in run - will show" > ${TST_DIR}/run/motd.d/e0r1u1.motd
|
||||
+echo "motd: e1r0u0 in etc - will show" > ${TST_DIR}/etc/motd.d/e1r0u0.motd
|
||||
+echo "motd: e1r0u1 in usr/lib - not show" > ${TST_DIR}/usr/lib/motd.d/e1r0u1.motd
|
||||
+echo "motd: e1r0u1 in etc - will show" > ${TST_DIR}/etc/motd.d/e1r0u1.motd
|
||||
+echo "motd: e1r1u0 in run - not show" > ${TST_DIR}/run/motd.d/e1r1u0.motd
|
||||
+echo "motd: e1r1u0 in etc - will show" > ${TST_DIR}/etc/motd.d/e1r1u0.motd
|
||||
+echo "motd: e1r1u1 in usr/lib - not show" > ${TST_DIR}/usr/lib/motd.d/e1r1u1.motd
|
||||
+echo "motd: e1r1u1 in run - not show" > ${TST_DIR}/run/motd.d/e1r1u1.motd
|
||||
+echo "motd: e1r1u1 in etc - will show" > ${TST_DIR}/etc/motd.d/e1r1u1.motd
|
||||
+
|
||||
+./tst-pam_motd tst-pam_motd2 > tst-pam_motd2.out
|
||||
+
|
||||
+RET=$?
|
||||
+
|
||||
+motd_to_show_output=$(cat tst-pam_motd2.out | grep "motd: /etc/motd")
|
||||
+if [ -z "${motd_to_show_output}" ];
|
||||
+then
|
||||
+ tst_cleanup
|
||||
+ exit 1
|
||||
+fi
|
||||
+
|
||||
+motd_dir_not_show_output=$(cat tst-pam_motd2.out | grep "not show")
|
||||
+if [ -n "${motd_dir_not_show_output}" ];
|
||||
+then
|
||||
+ tst_cleanup
|
||||
+ exit 1
|
||||
+fi
|
||||
+
|
||||
+tst_cleanup
|
||||
+exit $RET
|
||||
diff -up Linux-PAM-1.3.1/xtests/tst-pam_motd3.pamd.pam_motd-support-multiple-motd-paths1 Linux-PAM-1.3.1/xtests/tst-pam_motd3.pamd
|
||||
--- Linux-PAM-1.3.1/xtests/tst-pam_motd3.pamd.pam_motd-support-multiple-motd-paths1 2022-04-25 12:32:36.947663225 +0200
|
||||
+++ Linux-PAM-1.3.1/xtests/tst-pam_motd3.pamd 2022-04-25 12:32:36.947663225 +0200
|
||||
@@ -0,0 +1,3 @@
|
||||
+#%PAM-1.0
|
||||
+session required pam_permit.so
|
||||
+session optional pam_motd.so motd=tst-pam_motd3.d/etc/motd:tst-pam_motd3.d/run/motd:tst-pam_motd3.d/usr/lib/motd motd_dir=tst-pam_motd3.d/etc/motd.d:tst-pam_motd3.d/run/motd.d:tst-pam_motd3.d/usr/lib/motd.d
|
||||
diff -up Linux-PAM-1.3.1/xtests/tst-pam_motd3.sh.pam_motd-support-multiple-motd-paths1 Linux-PAM-1.3.1/xtests/tst-pam_motd3.sh
|
||||
--- Linux-PAM-1.3.1/xtests/tst-pam_motd3.sh.pam_motd-support-multiple-motd-paths1 2022-04-25 12:32:36.947663225 +0200
|
||||
+++ Linux-PAM-1.3.1/xtests/tst-pam_motd3.sh 2022-04-25 12:32:36.947663225 +0200
|
||||
@@ -0,0 +1,53 @@
|
||||
+#!/bin/bash
|
||||
+
|
||||
+TST_DIR="tst-pam_motd3.d"
|
||||
+
|
||||
+function tst_cleanup() {
|
||||
+ rm -rf "${TST_DIR}"
|
||||
+ rm -f tst-pam_motd3.out
|
||||
+}
|
||||
+
|
||||
+mkdir -p ${TST_DIR}
|
||||
+mkdir -p ${TST_DIR}/etc/motd.d
|
||||
+mkdir -p ${TST_DIR}/run/motd.d
|
||||
+mkdir -p ${TST_DIR}/usr/lib/motd.d
|
||||
+
|
||||
+# Verify motd is still displayed when not overridden
|
||||
+echo "motd: test-show in run - show" > ${TST_DIR}/run/motd.d/test-show.motd
|
||||
+
|
||||
+# Test overridden by a symlink to a file that isn't /dev/null; symlink target should show
|
||||
+echo "motd: hidden-by-symlink in usr/lib - not show" > ${TST_DIR}/usr/lib/motd.d/hidden-by-symlink.motd
|
||||
+echo "motd: test-from-symlink - show" > ${TST_DIR}/test-from-symlink.motd
|
||||
+ln -sr ${TST_DIR}/test-from-symlink.motd ${TST_DIR}/run/motd.d/hidden-by-symlink.motd
|
||||
+
|
||||
+# Test hidden by a null symlink
|
||||
+echo "motd: hidden-by-null-symlink in run - not show" > ${TST_DIR}/run/motd.d/hidden-by-null-symlink.motd
|
||||
+ln -s /dev/null ${TST_DIR}/etc/motd.d/hidden-by-null-symlink.motd
|
||||
+
|
||||
+./tst-pam_motd tst-pam_motd3 > tst-pam_motd3.out
|
||||
+
|
||||
+RET=$?
|
||||
+
|
||||
+motd_dir_not_show_output=$(cat tst-pam_motd3.out | grep "not show")
|
||||
+if [ -n "${motd_dir_not_show_output}" ];
|
||||
+then
|
||||
+ tst_cleanup
|
||||
+ exit 1
|
||||
+fi
|
||||
+
|
||||
+motd_test_show_output=$(cat tst-pam_motd3.out | grep "test-show.*- show")
|
||||
+if [ -z "${motd_test_show_output}" ];
|
||||
+then
|
||||
+ tst_cleanup
|
||||
+ exit 1
|
||||
+fi
|
||||
+
|
||||
+motd_general_symlink_show_output=$(cat tst-pam_motd3.out | grep "test-from-symlink.*- show")
|
||||
+if [ -z "${motd_general_symlink_show_output}" ];
|
||||
+then
|
||||
+ tst_cleanup
|
||||
+ exit 1
|
||||
+fi
|
||||
+
|
||||
+tst_cleanup
|
||||
+exit $RET
|
||||
diff -up Linux-PAM-1.3.1/xtests/tst-pam_motd.c.pam_motd-support-multiple-motd-paths1 Linux-PAM-1.3.1/xtests/tst-pam_motd.c
|
||||
--- Linux-PAM-1.3.1/xtests/tst-pam_motd.c.pam_motd-support-multiple-motd-paths1 2022-04-25 12:32:36.947663225 +0200
|
||||
+++ Linux-PAM-1.3.1/xtests/tst-pam_motd.c 2022-04-25 12:32:36.947663225 +0200
|
||||
@@ -0,0 +1,69 @@
|
||||
+/*
|
||||
+ * 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.
|
||||
+ */
|
||||
+
|
||||
+#ifdef HAVE_CONFIG_H
|
||||
+#include <config.h>
|
||||
+#endif
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <security/pam_appl.h>
|
||||
+#include <security/pam_misc.h>
|
||||
+
|
||||
+static struct pam_conv conv = {
|
||||
+ misc_conv,
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+int main(int argc, char *argv[])
|
||||
+{
|
||||
+ pam_handle_t *pamh=NULL;
|
||||
+ char *tst_arg = NULL;
|
||||
+ int retval;
|
||||
+
|
||||
+ if (argc > 1)
|
||||
+ tst_arg = argv[1];
|
||||
+
|
||||
+ retval = pam_start(tst_arg, NULL, &conv, &pamh);
|
||||
+
|
||||
+ retval = pam_open_session(pamh, 0);
|
||||
+
|
||||
+ retval = pam_close_session(pamh, 0);
|
||||
+
|
||||
+ if (pam_end(pamh,retval) != PAM_SUCCESS) { /* close Linux-PAM */
|
||||
+ pamh = NULL;
|
||||
+ exit(1);
|
||||
+ }
|
||||
+
|
||||
+ return ( retval == PAM_SUCCESS ? 0:1 ); /* indicate success */
|
||||
+}
|
||||
diff -up Linux-PAM-1.3.1/xtests/tst-pam_motd.sh.pam_motd-support-multiple-motd-paths1 Linux-PAM-1.3.1/xtests/tst-pam_motd.sh
|
||||
--- Linux-PAM-1.3.1/xtests/tst-pam_motd.sh.pam_motd-support-multiple-motd-paths1 2022-04-25 12:32:36.947663225 +0200
|
||||
+++ Linux-PAM-1.3.1/xtests/tst-pam_motd.sh 2022-04-25 12:32:36.947663225 +0200
|
||||
@@ -0,0 +1,7 @@
|
||||
+#!/bin/bash
|
||||
+
|
||||
+set -e
|
||||
+
|
||||
+./tst-pam_motd1.sh
|
||||
+./tst-pam_motd2.sh
|
||||
+./tst-pam_motd3.sh
|
@ -0,0 +1,111 @@
|
||||
From a7453aeeb398d6cbb7a709c4e2a1d75905220fff Mon Sep 17 00:00:00 2001
|
||||
From: Stanislav Zidek <szidek@redhat.com>
|
||||
Date: Fri, 16 Apr 2021 19:14:18 +0200
|
||||
Subject: [PATCH] pam_userdb: Prevent garbage characters from db
|
||||
|
||||
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1791965
|
||||
---
|
||||
modules/pam_userdb/pam_userdb.8.xml | 3 +-
|
||||
modules/pam_userdb/pam_userdb.c | 56 +++++++++++++++++------------
|
||||
2 files changed, 36 insertions(+), 23 deletions(-)
|
||||
|
||||
diff --git a/modules/pam_userdb/pam_userdb.8.xml b/modules/pam_userdb/pam_userdb.8.xml
|
||||
index fa628ada..bce92850 100644
|
||||
--- a/modules/pam_userdb/pam_userdb.8.xml
|
||||
+++ b/modules/pam_userdb/pam_userdb.8.xml
|
||||
@@ -100,7 +100,8 @@
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
- Print debug information.
|
||||
+ Print debug information. Note that password hashes, both from db
|
||||
+ and computed, will be printed to syslog.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
diff --git a/modules/pam_userdb/pam_userdb.c b/modules/pam_userdb/pam_userdb.c
|
||||
index dc2ca232..d59801bf 100644
|
||||
--- a/modules/pam_userdb/pam_userdb.c
|
||||
+++ b/modules/pam_userdb/pam_userdb.c
|
||||
@@ -194,7 +194,7 @@ user_lookup (pam_handle_t *pamh, const char *database, const char *cryptmode,
|
||||
}
|
||||
|
||||
if (data.dptr != NULL) {
|
||||
- int compare = 0;
|
||||
+ int compare = -2;
|
||||
|
||||
if (ctrl & PAM_KEY_ONLY_ARG)
|
||||
{
|
||||
@@ -209,36 +209,48 @@ user_lookup (pam_handle_t *pamh, const char *database, const char *cryptmode,
|
||||
char *cryptpw = NULL;
|
||||
|
||||
if (data.dsize < 13) {
|
||||
- compare = -2;
|
||||
+ /* hash is too short */
|
||||
+ pam_syslog(pamh, LOG_INFO, "password hash in database is too short");
|
||||
} else if (ctrl & PAM_ICASE_ARG) {
|
||||
- compare = -2;
|
||||
+ pam_syslog(pamh, LOG_INFO,
|
||||
+ "case-insensitive comparison only works with plaintext passwords");
|
||||
} else {
|
||||
+ /* libdb is not guaranteed to produce null terminated strings */
|
||||
+ char *pwhash = strndup(data.dptr, data.dsize);
|
||||
+
|
||||
+ if (pwhash == NULL) {
|
||||
+ pam_syslog(pamh, LOG_CRIT, "strndup failed: data.dptr");
|
||||
+ } else {
|
||||
#ifdef HAVE_CRYPT_R
|
||||
- struct crypt_data *cdata = NULL;
|
||||
- cdata = malloc(sizeof(*cdata));
|
||||
- if (cdata != NULL) {
|
||||
- cdata->initialized = 0;
|
||||
- cryptpw = crypt_r(pass, data.dptr, cdata);
|
||||
- }
|
||||
+ struct crypt_data *cdata = NULL;
|
||||
+ cdata = malloc(sizeof(*cdata));
|
||||
+ if (cdata == NULL) {
|
||||
+ pam_syslog(pamh, LOG_CRIT, "malloc failed: struct crypt_data");
|
||||
+ } else {
|
||||
+ cdata->initialized = 0;
|
||||
+ cryptpw = crypt_r(pass, pwhash, cdata);
|
||||
+ }
|
||||
#else
|
||||
- cryptpw = crypt (pass, data.dptr);
|
||||
+ cryptpw = crypt (pass, pwhash);
|
||||
#endif
|
||||
- if (cryptpw && strlen(cryptpw) == (size_t)data.dsize) {
|
||||
- compare = memcmp(data.dptr, cryptpw, data.dsize);
|
||||
- } else {
|
||||
- compare = -2;
|
||||
- if (ctrl & PAM_DEBUG_ARG) {
|
||||
- if (cryptpw)
|
||||
- pam_syslog(pamh, LOG_INFO, "lengths of computed and stored hashes differ");
|
||||
- else
|
||||
- pam_syslog(pamh, LOG_INFO, "crypt() returned NULL");
|
||||
+ if (cryptpw && strlen(cryptpw) == (size_t)data.dsize) {
|
||||
+ compare = memcmp(data.dptr, cryptpw, data.dsize);
|
||||
+ } else {
|
||||
+ if (ctrl & PAM_DEBUG_ARG) {
|
||||
+ if (cryptpw) {
|
||||
+ pam_syslog(pamh, LOG_INFO, "lengths of computed and stored hashes differ");
|
||||
+ pam_syslog(pamh, LOG_INFO, "computed hash: %s", cryptpw);
|
||||
+ } else {
|
||||
+ pam_syslog(pamh, LOG_ERR, "crypt() returned NULL");
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
- }
|
||||
#ifdef HAVE_CRYPT_R
|
||||
- free(cdata);
|
||||
+ free(cdata);
|
||||
#endif
|
||||
+ }
|
||||
+ free(pwhash);
|
||||
}
|
||||
-
|
||||
} else {
|
||||
|
||||
/* Unknown password encryption method -
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,75 @@
|
||||
diff -up Linux-PAM-1.3.1/configure.ac.pam-usertype-SYS_UID_MAX Linux-PAM-1.3.1/configure.ac
|
||||
--- Linux-PAM-1.3.1/configure.ac.pam-usertype-SYS_UID_MAX 2022-06-22 16:41:09.169146826 +0200
|
||||
+++ Linux-PAM-1.3.1/configure.ac 2022-06-22 16:43:54.343373619 +0200
|
||||
@@ -615,12 +615,6 @@ if test x"$opt_uidmin" == x; then
|
||||
fi
|
||||
AC_DEFINE_UNQUOTED(PAM_USERTYPE_UIDMIN, $opt_uidmin, [Minimum regular user uid.])
|
||||
|
||||
-AC_ARG_WITH([sysuidmin], AS_HELP_STRING([--with-sysuidmin=<number>],[default value for system user min uid (101)]), opt_sysuidmin=$withval)
|
||||
-if test x"$opt_sysuidmin" == x; then
|
||||
- opt_sysuidmin=101
|
||||
-fi
|
||||
-AC_DEFINE_UNQUOTED(PAM_USERTYPE_SYSUIDMIN, $opt_sysuidmin, [Minimum system user uid.])
|
||||
-
|
||||
AC_ARG_WITH([kerneloverflowuid], AS_HELP_STRING([--with-kernel-overflow-uid=<number>],[kernel overflow uid, default (uint16_t)-2=65534]), opt_kerneloverflowuid=$withval)
|
||||
if test x"$opt_kerneloverflowuid" == x; then
|
||||
opt_kerneloverflowuid=65534
|
||||
diff -up Linux-PAM-1.3.1/modules/pam_usertype/pam_usertype.8.xml.pam-usertype-SYS_UID_MAX Linux-PAM-1.3.1/modules/pam_usertype/pam_usertype.8.xml
|
||||
--- Linux-PAM-1.3.1/modules/pam_usertype/pam_usertype.8.xml.pam-usertype-SYS_UID_MAX 2022-06-22 16:41:09.155146722 +0200
|
||||
+++ Linux-PAM-1.3.1/modules/pam_usertype/pam_usertype.8.xml 2022-06-22 16:41:09.169146826 +0200
|
||||
@@ -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 -up Linux-PAM-1.3.1/modules/pam_usertype/pam_usertype.c.pam-usertype-SYS_UID_MAX Linux-PAM-1.3.1/modules/pam_usertype/pam_usertype.c
|
||||
--- Linux-PAM-1.3.1/modules/pam_usertype/pam_usertype.c.pam-usertype-SYS_UID_MAX 2022-06-22 16:41:09.155146722 +0200
|
||||
+++ Linux-PAM-1.3.1/modules/pam_usertype/pam_usertype.c 2022-06-22 16:41:09.169146826 +0200
|
||||
@@ -277,7 +277,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) {
|
||||
@@ -285,21 +284,19 @@ pam_usertype_is_system(pam_handle_t *pam
|
||||
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
|
||||
@@ -336,7 +333,7 @@ pam_usertype_evaluate(struct pam_usertyp
|
||||
|
||||
/**
|
||||
* 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
|
@ -0,0 +1,712 @@
|
||||
diff -up Linux-PAM-1.3.1/configure.ac.pam-usertype Linux-PAM-1.3.1/configure.ac
|
||||
--- Linux-PAM-1.3.1/configure.ac.pam-usertype 2020-05-15 10:03:27.247468160 +0200
|
||||
+++ Linux-PAM-1.3.1/configure.ac 2020-05-15 10:03:27.270468089 +0200
|
||||
@@ -606,6 +606,27 @@ AC_SUBST([HAVE_KEY_MANAGEMENT], $HAVE_KE
|
||||
|
||||
AM_CONDITIONAL([HAVE_KEY_MANAGEMENT], [test "$have_key_syscalls" = 1])
|
||||
|
||||
+dnl
|
||||
+dnl Get values for default uid ranges in login.defs used in pam_usertype
|
||||
+dnl
|
||||
+AC_ARG_WITH([uidmin], AS_HELP_STRING([--with-uidmin=<number>],[default value for regular user min uid (1000)]), opt_uidmin=$withval)
|
||||
+if test x"$opt_uidmin" == x; then
|
||||
+ opt_uidmin=1000
|
||||
+fi
|
||||
+AC_DEFINE_UNQUOTED(PAM_USERTYPE_UIDMIN, $opt_uidmin, [Minimum regular user uid.])
|
||||
+
|
||||
+AC_ARG_WITH([sysuidmin], AS_HELP_STRING([--with-sysuidmin=<number>],[default value for system user min uid (101)]), opt_sysuidmin=$withval)
|
||||
+if test x"$opt_sysuidmin" == x; then
|
||||
+ opt_sysuidmin=101
|
||||
+fi
|
||||
+AC_DEFINE_UNQUOTED(PAM_USERTYPE_SYSUIDMIN, $opt_sysuidmin, [Minimum system user uid.])
|
||||
+
|
||||
+AC_ARG_WITH([kerneloverflowuid], AS_HELP_STRING([--with-kernel-overflow-uid=<number>],[kernel overflow uid, default (uint16_t)-2=65534]), opt_kerneloverflowuid=$withval)
|
||||
+if test x"$opt_kerneloverflowuid" == x; then
|
||||
+ opt_kerneloverflowuid=65534
|
||||
+fi
|
||||
+AC_DEFINE_UNQUOTED(PAM_USERTYPE_OVERFLOW_UID, $opt_kerneloverflowuid, [Kernel overflow uid.])
|
||||
+
|
||||
dnl Files to be created from when we run configure
|
||||
AC_CONFIG_FILES([Makefile libpam/Makefile libpamc/Makefile libpamc/test/Makefile \
|
||||
libpam_misc/Makefile conf/Makefile conf/pam_conv1/Makefile \
|
||||
@@ -636,6 +657,7 @@ AC_CONFIG_FILES([Makefile libpam/Makefil
|
||||
modules/pam_timestamp/Makefile modules/pam_tty_audit/Makefile \
|
||||
modules/pam_umask/Makefile \
|
||||
modules/pam_unix/Makefile modules/pam_userdb/Makefile \
|
||||
+ modules/pam_usertype/Makefile \
|
||||
modules/pam_warn/Makefile modules/pam_wheel/Makefile \
|
||||
modules/pam_xauth/Makefile doc/Makefile doc/specs/Makefile \
|
||||
doc/man/Makefile doc/sag/Makefile doc/adg/Makefile \
|
||||
diff -up Linux-PAM-1.3.1/modules/Makefile.am.pam-usertype Linux-PAM-1.3.1/modules/Makefile.am
|
||||
--- Linux-PAM-1.3.1/modules/Makefile.am.pam-usertype 2020-05-15 10:03:27.247468160 +0200
|
||||
+++ Linux-PAM-1.3.1/modules/Makefile.am 2020-05-15 10:03:27.270468089 +0200
|
||||
@@ -12,7 +12,7 @@ SUBDIRS = pam_access pam_cracklib pam_de
|
||||
pam_selinux pam_sepermit pam_shells pam_stress \
|
||||
pam_succeed_if pam_time pam_timestamp \
|
||||
pam_tty_audit pam_umask \
|
||||
- pam_unix pam_userdb pam_warn pam_wheel pam_xauth
|
||||
+ pam_unix pam_userdb pam_usertype pam_warn pam_wheel pam_xauth
|
||||
|
||||
CLEANFILES = *~
|
||||
|
||||
diff -up Linux-PAM-1.3.1/modules/pam_usertype/Makefile.am.pam-usertype Linux-PAM-1.3.1/modules/pam_usertype/Makefile.am
|
||||
--- Linux-PAM-1.3.1/modules/pam_usertype/Makefile.am.pam-usertype 2020-05-15 10:03:27.270468089 +0200
|
||||
+++ Linux-PAM-1.3.1/modules/pam_usertype/Makefile.am 2020-05-15 10:03:27.270468089 +0200
|
||||
@@ -0,0 +1,34 @@
|
||||
+#
|
||||
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
|
||||
+# Copyright (c) 2020 Red Hat, Inc.
|
||||
+#
|
||||
+
|
||||
+CLEANFILES = *~
|
||||
+MAINTAINERCLEANFILES = $(MANS) README
|
||||
+
|
||||
+EXTRA_DIST = README ${MANS} ${XMLS} tst-pam_usertype
|
||||
+
|
||||
+TESTS = tst-pam_usertype
|
||||
+
|
||||
+man_MANS = pam_usertype.8
|
||||
+
|
||||
+XMLS = README.xml pam_usertype.8.xml
|
||||
+
|
||||
+securelibdir = $(SECUREDIR)
|
||||
+secureconfdir = $(SCONFIGDIR)
|
||||
+
|
||||
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
|
||||
+ $(WARN_CFLAGS)
|
||||
+AM_LDFLAGS = -no-undefined -avoid-version -module
|
||||
+if HAVE_VERSIONING
|
||||
+ AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
|
||||
+endif
|
||||
+
|
||||
+securelib_LTLIBRARIES = pam_usertype.la
|
||||
+pam_usertype_la_LIBADD = $(top_builddir)/libpam/libpam.la
|
||||
+
|
||||
+if ENABLE_REGENERATE_MAN
|
||||
+noinst_DATA = README
|
||||
+README: pam_usertype.8.xml
|
||||
+-include $(top_srcdir)/Make.xml.rules
|
||||
+endif
|
||||
diff -up Linux-PAM-1.3.1/modules/pam_usertype/pam_usertype.8.xml.pam-usertype Linux-PAM-1.3.1/modules/pam_usertype/pam_usertype.8.xml
|
||||
--- Linux-PAM-1.3.1/modules/pam_usertype/pam_usertype.8.xml.pam-usertype 2020-05-15 10:03:27.270468089 +0200
|
||||
+++ Linux-PAM-1.3.1/modules/pam_usertype/pam_usertype.8.xml 2020-05-15 10:03:27.270468089 +0200
|
||||
@@ -0,0 +1,170 @@
|
||||
+<?xml version="1.0" encoding='UTF-8'?>
|
||||
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
|
||||
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
|
||||
+
|
||||
+
|
||||
+<refentry id='pam_usertype'>
|
||||
+ <refmeta>
|
||||
+ <refentrytitle>pam_usertype</refentrytitle>
|
||||
+ <manvolnum>8</manvolnum>
|
||||
+ <refmiscinfo class='sectdesc'>Linux-PAM</refmiscinfo>
|
||||
+ </refmeta>
|
||||
+
|
||||
+ <refnamediv id='pam_usertype-name'>
|
||||
+ <refname>pam_usertype</refname>
|
||||
+ <refpurpose>check if the authenticated user is a system or regular account</refpurpose>
|
||||
+ </refnamediv>
|
||||
+
|
||||
+
|
||||
+ <refsynopsisdiv>
|
||||
+ <cmdsynopsis id='pam_usertype-cmdsynopsis'>
|
||||
+ <command>pam_usertype.so</command>
|
||||
+ <arg choice='opt' rep='repeat'><replaceable>flag</replaceable></arg>
|
||||
+ <arg choice='req'><replaceable>condition</replaceable></arg>
|
||||
+ </cmdsynopsis>
|
||||
+ </refsynopsisdiv>
|
||||
+
|
||||
+
|
||||
+ <refsect1 id='pam_usertype-description'>
|
||||
+ <title>DESCRIPTION</title>
|
||||
+ <para>
|
||||
+ pam_usertype.so is designed to succeed or fail authentication
|
||||
+ based on type of the account of the authenticated user.
|
||||
+ The type of the account is decided with help of
|
||||
+ <emphasis>SYS_UID_MIN</emphasis> and <emphasis>SYS_UID_MAX</emphasis>
|
||||
+ settings in <emphasis>/etc/login.defs</emphasis>. One use is to select
|
||||
+ whether to load other modules based on this test.
|
||||
+ </para>
|
||||
+
|
||||
+ <para>
|
||||
+ The module should be given only one condition as module argument.
|
||||
+ Authentication will succeed only if the condition is met.
|
||||
+ </para>
|
||||
+ </refsect1>
|
||||
+
|
||||
+ <refsect1 id="pam_usertype-options">
|
||||
+ <title>OPTIONS</title>
|
||||
+ <para>
|
||||
+ The following <emphasis>flag</emphasis>s are supported:
|
||||
+ </para>
|
||||
+
|
||||
+ <variablelist>
|
||||
+ <varlistentry>
|
||||
+ <term><option>use_uid</option></term>
|
||||
+ <listitem>
|
||||
+ <para>
|
||||
+ Evaluate conditions using the account of the user whose UID
|
||||
+ the application is running under instead of the user being
|
||||
+ authenticated.
|
||||
+ </para>
|
||||
+ </listitem>
|
||||
+ </varlistentry>
|
||||
+ <varlistentry>
|
||||
+ <term><option>audit</option></term>
|
||||
+ <listitem>
|
||||
+ <para>
|
||||
+ Log unknown users to the system log.
|
||||
+ </para>
|
||||
+ </listitem>
|
||||
+ </varlistentry>
|
||||
+ </variablelist>
|
||||
+
|
||||
+ <para>
|
||||
+ Available <emphasis>condition</emphasis>s are:
|
||||
+ </para>
|
||||
+
|
||||
+ <variablelist>
|
||||
+ <varlistentry>
|
||||
+ <term><option>issystem</option></term>
|
||||
+ <listitem>
|
||||
+ <para>Succeed if the user is a system user.</para>
|
||||
+ </listitem>
|
||||
+ </varlistentry>
|
||||
+ <varlistentry>
|
||||
+ <term><option>isregular</option></term>
|
||||
+ <listitem>
|
||||
+ <para>Succeed if the user is a regular user.</para>
|
||||
+ </listitem>
|
||||
+ </varlistentry>
|
||||
+ </variablelist>
|
||||
+ </refsect1>
|
||||
+
|
||||
+ <refsect1 id="pam_usertype-types">
|
||||
+ <title>MODULE TYPES PROVIDED</title>
|
||||
+ <para>
|
||||
+ All module types (<option>account</option>, <option>auth</option>,
|
||||
+ <option>password</option> and <option>session</option>) are provided.
|
||||
+ </para>
|
||||
+ </refsect1>
|
||||
+
|
||||
+ <refsect1 id='pam_usertype-return_values'>
|
||||
+ <title>RETURN VALUES</title>
|
||||
+ <variablelist>
|
||||
+
|
||||
+ <varlistentry>
|
||||
+ <term>PAM_SUCCESS</term>
|
||||
+ <listitem>
|
||||
+ <para>
|
||||
+ The condition was true.
|
||||
+ </para>
|
||||
+ </listitem>
|
||||
+ </varlistentry>
|
||||
+
|
||||
+ <varlistentry>
|
||||
+ <term>PAM_AUTH_ERR</term>
|
||||
+ <listitem>
|
||||
+ <para>
|
||||
+ The condition was false.
|
||||
+ </para>
|
||||
+ </listitem>
|
||||
+ </varlistentry>
|
||||
+
|
||||
+ <varlistentry>
|
||||
+ <term>PAM_SERVICE_ERR</term>
|
||||
+ <listitem>
|
||||
+ <para>
|
||||
+ A service error occurred or the arguments can't be
|
||||
+ parsed correctly.
|
||||
+ </para>
|
||||
+ </listitem>
|
||||
+ </varlistentry>
|
||||
+
|
||||
+ <varlistentry>
|
||||
+ <term>PAM_USER_UNKNOWN</term>
|
||||
+ <listitem>
|
||||
+ <para>
|
||||
+ User was not found.
|
||||
+ </para>
|
||||
+ </listitem>
|
||||
+ </varlistentry>
|
||||
+ </variablelist>
|
||||
+ </refsect1>
|
||||
+
|
||||
+
|
||||
+ <refsect1 id='pam_usertype-examples'>
|
||||
+ <title>EXAMPLES</title>
|
||||
+ <para>
|
||||
+ Skip remaining modules if the user is a system user:
|
||||
+ </para>
|
||||
+ <programlisting>
|
||||
+account sufficient pam_usertype.so issystem
|
||||
+ </programlisting>
|
||||
+ </refsect1>
|
||||
+
|
||||
+ <refsect1 id='pam_usertype-see_also'>
|
||||
+ <title>SEE ALSO</title>
|
||||
+ <para>
|
||||
+ <citerefentry>
|
||||
+ <refentrytitle>login.defs</refentrytitle><manvolnum>5</manvolnum>
|
||||
+ </citerefentry>,
|
||||
+ <citerefentry>
|
||||
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
|
||||
+ </citerefentry>
|
||||
+ </para>
|
||||
+ </refsect1>
|
||||
+
|
||||
+ <refsect1 id='pam_usertype-author'>
|
||||
+ <title>AUTHOR</title>
|
||||
+ <para>Pavel Březina <pbrezina@redhat.com></para>
|
||||
+ </refsect1>
|
||||
+</refentry>
|
||||
diff -up Linux-PAM-1.3.1/modules/pam_usertype/pam_usertype.c.pam-usertype Linux-PAM-1.3.1/modules/pam_usertype/pam_usertype.c
|
||||
--- Linux-PAM-1.3.1/modules/pam_usertype/pam_usertype.c.pam-usertype 2020-05-15 10:03:27.270468089 +0200
|
||||
+++ Linux-PAM-1.3.1/modules/pam_usertype/pam_usertype.c 2020-05-15 10:16:08.053198025 +0200
|
||||
@@ -0,0 +1,394 @@
|
||||
+/******************************************************************************
|
||||
+ * Check user type based on login.defs.
|
||||
+ *
|
||||
+ * Copyright (c) 2020 Red Hat, Inc.
|
||||
+ * Written by Pavel Březina <pbrezina@redhat.com>
|
||||
+ *
|
||||
+ * Redistribution and use in source and binary forms, with or without
|
||||
+ * modification, are permitted provided that the following conditions
|
||||
+ * are met:
|
||||
+ * 1. Redistributions of source code must retain the above copyright
|
||||
+ * notice, and the entire permission notice in its entirety,
|
||||
+ * including the disclaimer of warranties.
|
||||
+ * 2. Redistributions in binary form must reproduce the above copyright
|
||||
+ * notice, this list of conditions and the following disclaimer in the
|
||||
+ * documentation and/or other materials provided with the distribution.
|
||||
+ * 3. The name of the author may not be used to endorse or promote
|
||||
+ * products derived from this software without specific prior
|
||||
+ * written permission.
|
||||
+ *
|
||||
+ * ALTERNATIVELY, this product may be distributed under the terms of
|
||||
+ * the GNU Public License, in which case the provisions of the GPL are
|
||||
+ * required INSTEAD OF the above restrictions. (This clause is
|
||||
+ * necessary due to a potential bad interaction between the GPL and
|
||||
+ * the restrictions contained in a BSD-style copyright.)
|
||||
+ *
|
||||
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include "config.h"
|
||||
+
|
||||
+#include <sys/types.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+#include <syslog.h>
|
||||
+#include <unistd.h>
|
||||
+#include <pwd.h>
|
||||
+#include <ctype.h>
|
||||
+#include <errno.h>
|
||||
+#include <stdio.h>
|
||||
+
|
||||
+#define PAM_SM_AUTH
|
||||
+#define PAM_SM_ACCOUNT
|
||||
+#define PAM_SM_SESSION
|
||||
+#define PAM_SM_PASSWORD
|
||||
+
|
||||
+#include <security/pam_modules.h>
|
||||
+#include <security/pam_modutil.h>
|
||||
+#include <security/pam_ext.h>
|
||||
+
|
||||
+#define LOGIN_DEFS "/etc/login.defs"
|
||||
+
|
||||
+enum pam_usertype_op {
|
||||
+ OP_IS_SYSTEM,
|
||||
+ OP_IS_REGULAR,
|
||||
+
|
||||
+ OP_SENTINEL
|
||||
+};
|
||||
+
|
||||
+struct pam_usertype_opts {
|
||||
+ enum pam_usertype_op op;
|
||||
+ int use_uid;
|
||||
+ int audit;
|
||||
+};
|
||||
+
|
||||
+static int
|
||||
+pam_usertype_parse_args(struct pam_usertype_opts *opts,
|
||||
+ pam_handle_t *pamh,
|
||||
+ int argc,
|
||||
+ const char **argv)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ memset(opts, 0, sizeof(struct pam_usertype_opts));
|
||||
+ opts->op = OP_SENTINEL;
|
||||
+
|
||||
+ for (i = 0; i < argc; i++) {
|
||||
+ if (strcmp(argv[i], "use_uid") == 0) {
|
||||
+ opts->use_uid = 1;
|
||||
+ } else if (strcmp(argv[i], "audit") == 0) {
|
||||
+ opts->audit = 1;
|
||||
+ } else if (strcmp(argv[i], "issystem") == 0) {
|
||||
+ opts->op = OP_IS_SYSTEM;
|
||||
+ } else if (strcmp(argv[i], "isregular") == 0) {
|
||||
+ opts->op = OP_IS_REGULAR;
|
||||
+ } else {
|
||||
+ pam_syslog(pamh, LOG_WARNING, "Unknown argument: %s", argv[i]);
|
||||
+ /* Just continue. */
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (opts->op == OP_SENTINEL) {
|
||||
+ pam_syslog(pamh, LOG_ERR, "Operation not specified");
|
||||
+ return PAM_SERVICE_ERR;
|
||||
+ }
|
||||
+
|
||||
+ return PAM_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+pam_usertype_get_uid(struct pam_usertype_opts *opts,
|
||||
+ pam_handle_t *pamh,
|
||||
+ uid_t *_uid)
|
||||
+{
|
||||
+ struct passwd *pwd;
|
||||
+ const void *prompt;
|
||||
+ const char *username;
|
||||
+ int ret;
|
||||
+
|
||||
+ /* Get uid of user that runs the application. */
|
||||
+ if (opts->use_uid) {
|
||||
+ pwd = pam_modutil_getpwuid(pamh, getuid());
|
||||
+ if (pwd == NULL) {
|
||||
+ pam_syslog(pamh, LOG_ERR,
|
||||
+ "error retrieving information about user %lu",
|
||||
+ (unsigned long)getuid());
|
||||
+ return PAM_USER_UNKNOWN;
|
||||
+ }
|
||||
+
|
||||
+ *_uid = pwd->pw_uid;
|
||||
+ return PAM_SUCCESS;
|
||||
+ }
|
||||
+
|
||||
+ /* Get uid of user that is being authenticated. */
|
||||
+ ret = pam_get_item(pamh, PAM_USER_PROMPT, &prompt);
|
||||
+ if (ret != PAM_SUCCESS || prompt == NULL || strlen(prompt) == 0) {
|
||||
+ prompt = "login: ";
|
||||
+ }
|
||||
+
|
||||
+ ret = pam_get_user(pamh, &username, prompt);
|
||||
+ if (ret != PAM_SUCCESS || username == NULL) {
|
||||
+ pam_syslog(pamh, LOG_ERR, "error retrieving user name: %s",
|
||||
+ pam_strerror(pamh, ret));
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ pwd = pam_modutil_getpwnam(pamh, username);
|
||||
+ if (pwd == NULL) {
|
||||
+ if (opts->audit) {
|
||||
+ pam_syslog(pamh, LOG_NOTICE,
|
||||
+ "error retrieving information about user %s", username);
|
||||
+ }
|
||||
+
|
||||
+ return PAM_USER_UNKNOWN;
|
||||
+ }
|
||||
+
|
||||
+ *_uid = pwd->pw_uid;
|
||||
+
|
||||
+ return PAM_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+#define MAX_UID_VALUE 0xFFFFFFFFUL
|
||||
+
|
||||
+/* lookup a value for key in login.defs file or similar key value format */
|
||||
+char *
|
||||
+pam_usertype_search_key(pam_handle_t *pamh UNUSED,
|
||||
+ const char *file_name,
|
||||
+ const char *key)
|
||||
+{
|
||||
+ FILE *fp;
|
||||
+ char *buf = NULL;
|
||||
+ size_t buflen = 0;
|
||||
+ char *retval = NULL;
|
||||
+
|
||||
+ fp = fopen(file_name, "r");
|
||||
+ if (NULL == fp)
|
||||
+ return NULL;
|
||||
+
|
||||
+ while (!feof(fp)) {
|
||||
+ char *tmp, *cp;
|
||||
+#if defined(HAVE_GETLINE)
|
||||
+ ssize_t n = getline(&buf, &buflen, fp);
|
||||
+#elif defined (HAVE_GETDELIM)
|
||||
+ ssize_t n = getdelim(&buf, &buflen, '\n', fp);
|
||||
+#else
|
||||
+ ssize_t n;
|
||||
+
|
||||
+ if (buf == NULL) {
|
||||
+ buflen = BUF_SIZE;
|
||||
+ buf = malloc(buflen);
|
||||
+ if (buf == NULL) {
|
||||
+ fclose(fp);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ }
|
||||
+ buf[0] = '\0';
|
||||
+ if (fgets(buf, buflen - 1, fp) == NULL)
|
||||
+ break;
|
||||
+ else if (buf != NULL)
|
||||
+ n = strlen(buf);
|
||||
+ else
|
||||
+ n = 0;
|
||||
+#endif /* HAVE_GETLINE / HAVE_GETDELIM */
|
||||
+ cp = buf;
|
||||
+
|
||||
+ if (n < 1)
|
||||
+ break;
|
||||
+ if (cp[n - 1] == '\n')
|
||||
+ cp[n - 1] = '\0';
|
||||
+
|
||||
+ tmp = strchr(cp, '#'); /* remove comments */
|
||||
+ if (tmp)
|
||||
+ *tmp = '\0';
|
||||
+ while (isspace((int)*cp)) /* remove spaces and tabs */
|
||||
+ ++cp;
|
||||
+ if (*cp == '\0') /* ignore empty lines */
|
||||
+ continue;
|
||||
+
|
||||
+ tmp = strsep (&cp, " \t=");
|
||||
+ if (cp != NULL)
|
||||
+ while (isspace((int)*cp) || *cp == '=')
|
||||
+ ++cp;
|
||||
+ else
|
||||
+ cp = "";
|
||||
+
|
||||
+ if (strcasecmp(tmp, key) == 0) {
|
||||
+ retval = strdup(cp);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ fclose(fp);
|
||||
+
|
||||
+ free(buf);
|
||||
+
|
||||
+ return retval;
|
||||
+}
|
||||
+
|
||||
+static uid_t
|
||||
+pam_usertype_get_id(pam_handle_t *pamh,
|
||||
+ const char *key,
|
||||
+ uid_t default_value)
|
||||
+{
|
||||
+ unsigned long ul;
|
||||
+ char *value;
|
||||
+ char *ep;
|
||||
+ uid_t uid;
|
||||
+
|
||||
+ value = pam_usertype_search_key(pamh, LOGIN_DEFS, key);
|
||||
+ if (value == NULL) {
|
||||
+ return default_value;
|
||||
+ }
|
||||
+
|
||||
+ /* taken from get_lastlog_uid_max() */
|
||||
+ ep = value + strlen(value);
|
||||
+ while (ep > value && isspace(*(--ep))) {
|
||||
+ *ep = '\0';
|
||||
+ }
|
||||
+
|
||||
+ errno = 0;
|
||||
+ ul = strtoul(value, &ep, 10);
|
||||
+ if (!(ul >= MAX_UID_VALUE
|
||||
+ || (uid_t)ul >= MAX_UID_VALUE
|
||||
+ || (errno != 0 && ul == 0)
|
||||
+ || value == ep
|
||||
+ || *ep != '\0')) {
|
||||
+ uid = (uid_t)ul;
|
||||
+ } else {
|
||||
+ uid = default_value;
|
||||
+ }
|
||||
+
|
||||
+ free(value);
|
||||
+
|
||||
+ return uid;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+pam_usertype_is_system(pam_handle_t *pamh, uid_t uid)
|
||||
+{
|
||||
+ uid_t uid_min;
|
||||
+ uid_t sys_min;
|
||||
+ uid_t sys_max;
|
||||
+
|
||||
+ if (uid == (uid_t)-1) {
|
||||
+ pam_syslog(pamh, LOG_WARNING, "invalid uid");
|
||||
+ return PAM_USER_UNKNOWN;
|
||||
+ }
|
||||
+
|
||||
+ if (uid <= 99) {
|
||||
+ /* Reserved. */
|
||||
+ return PAM_SUCCESS;
|
||||
+ }
|
||||
+
|
||||
+ if (uid == PAM_USERTYPE_OVERFLOW_UID) {
|
||||
+ /* nobody */
|
||||
+ return PAM_SUCCESS;
|
||||
+ }
|
||||
+
|
||||
+ uid_min = pam_usertype_get_id(pamh, "UID_MIN", PAM_USERTYPE_UIDMIN);
|
||||
+ sys_min = pam_usertype_get_id(pamh, "SYS_UID_MIN", PAM_USERTYPE_SYSUIDMIN);
|
||||
+ sys_max = pam_usertype_get_id(pamh, "SYS_UID_MAX", uid_min - 1);
|
||||
+
|
||||
+ return uid >= sys_min && uid <= sys_max ? PAM_SUCCESS : PAM_AUTH_ERR;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+pam_usertype_is_regular(pam_handle_t *pamh, uid_t uid)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = pam_usertype_is_system(pamh, uid);
|
||||
+ switch (ret) {
|
||||
+ case PAM_SUCCESS:
|
||||
+ return PAM_AUTH_ERR;
|
||||
+ case PAM_USER_UNKNOWN:
|
||||
+ return PAM_USER_UNKNOWN;
|
||||
+ default:
|
||||
+ return PAM_SUCCESS;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+pam_usertype_evaluate(struct pam_usertype_opts *opts,
|
||||
+ pam_handle_t *pamh,
|
||||
+ uid_t uid)
|
||||
+{
|
||||
+ switch (opts->op) {
|
||||
+ case OP_IS_SYSTEM:
|
||||
+ return pam_usertype_is_system(pamh, uid);
|
||||
+ case OP_IS_REGULAR:
|
||||
+ return pam_usertype_is_regular(pamh, uid);
|
||||
+ default:
|
||||
+ pam_syslog(pamh, LOG_ERR, "Unknown operation: %d", opts->op);
|
||||
+ return PAM_SERVICE_ERR;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * Arguments:
|
||||
+ * - issystem: uid in <SYS_UID_MIN, SYS_UID_MAX>
|
||||
+ * - isregular: not issystem
|
||||
+ * - use_uid: use user that runs application not that is being authenticate (same as in pam_succeed_if)
|
||||
+ * - audit: log unknown users to syslog
|
||||
+ */
|
||||
+int
|
||||
+pam_sm_authenticate(pam_handle_t *pamh, int flags UNUSED,
|
||||
+ int argc, const char **argv)
|
||||
+{
|
||||
+ struct pam_usertype_opts opts;
|
||||
+ uid_t uid;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = pam_usertype_parse_args(&opts, pamh, argc, argv);
|
||||
+ if (ret != PAM_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = pam_usertype_get_uid(&opts, pamh, &uid);
|
||||
+ if (ret != PAM_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return pam_usertype_evaluate(&opts, pamh, uid);
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+pam_sm_setcred(pam_handle_t *pamh UNUSED, int flags UNUSED,
|
||||
+ int argc UNUSED, const char **argv UNUSED)
|
||||
+{
|
||||
+ return PAM_IGNORE;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv)
|
||||
+{
|
||||
+ return pam_sm_authenticate(pamh, flags, argc, argv);
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv)
|
||||
+{
|
||||
+ return pam_sm_authenticate(pamh, flags, argc, argv);
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, const char **argv)
|
||||
+{
|
||||
+ return pam_sm_authenticate(pamh, flags, argc, argv);
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv)
|
||||
+{
|
||||
+ return pam_sm_authenticate(pamh, flags, argc, argv);
|
||||
+}
|
||||
diff -up Linux-PAM-1.3.1/modules/pam_usertype/README.xml.pam-usertype Linux-PAM-1.3.1/modules/pam_usertype/README.xml
|
||||
--- Linux-PAM-1.3.1/modules/pam_usertype/README.xml.pam-usertype 2020-05-15 10:03:27.270468089 +0200
|
||||
+++ Linux-PAM-1.3.1/modules/pam_usertype/README.xml 2020-05-15 10:03:27.270468089 +0200
|
||||
@@ -0,0 +1,41 @@
|
||||
+<?xml version="1.0" encoding='UTF-8'?>
|
||||
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
|
||||
+"http://www.docbook.org/xml/4.3/docbookx.dtd"
|
||||
+[
|
||||
+<!--
|
||||
+<!ENTITY pamaccess SYSTEM "pam_usertype.8.xml">
|
||||
+-->
|
||||
+]>
|
||||
+
|
||||
+<article>
|
||||
+
|
||||
+ <articleinfo>
|
||||
+
|
||||
+ <title>
|
||||
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
+ href="pam_usertype.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_usertype-name"]/*)'/>
|
||||
+ </title>
|
||||
+
|
||||
+ </articleinfo>
|
||||
+
|
||||
+ <section>
|
||||
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
+ href="pam_usertype.8.xml" xpointer='xpointer(//refsect1[@id = "pam_usertype-description"]/*)'/>
|
||||
+ </section>
|
||||
+
|
||||
+ <section>
|
||||
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
+ href="pam_usertype.8.xml" xpointer='xpointer(//refsect1[@id = "pam_usertype-options"]/*)'/>
|
||||
+ </section>
|
||||
+
|
||||
+ <section>
|
||||
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
+ href="pam_usertype.8.xml" xpointer='xpointer(//refsect1[@id = "pam_usertype-examples"]/*)'/>
|
||||
+ </section>
|
||||
+
|
||||
+ <section>
|
||||
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
+ href="pam_usertype.8.xml" xpointer='xpointer(//refsect1[@id = "pam_usertype-author"]/*)'/>
|
||||
+ </section>
|
||||
+
|
||||
+</article>
|
||||
diff -up Linux-PAM-1.3.1/modules/pam_usertype/tst-pam_usertype.pam-usertype Linux-PAM-1.3.1/modules/pam_usertype/tst-pam_usertype
|
||||
--- Linux-PAM-1.3.1/modules/pam_usertype/tst-pam_usertype.pam-usertype 2020-05-15 10:03:27.270468089 +0200
|
||||
+++ Linux-PAM-1.3.1/modules/pam_usertype/tst-pam_usertype 2020-05-15 10:03:27.270468089 +0200
|
||||
@@ -0,0 +1,2 @@
|
||||
+#!/bin/sh
|
||||
+../../tests/tst-dlopen .libs/pam_usertype.so
|
@ -0,0 +1,33 @@
|
||||
From e31dd6c7d0faa7a06d3ebd50a0b6957b9f822d15 Mon Sep 17 00:00:00 2001
|
||||
From: Tomas Mraz <tmraz@fedoraproject.org>
|
||||
Date: Wed, 7 Aug 2019 18:13:57 +0200
|
||||
Subject: [PATCH] pam_tty_audit: Manual page clarification about password
|
||||
logging
|
||||
|
||||
* modules/pam_tty_audit/pam_tty_audit.8.xml: Explanation why passwords
|
||||
can be sometimes logged even when the option is not set.
|
||||
---
|
||||
modules/pam_tty_audit/pam_tty_audit.8.xml | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/modules/pam_tty_audit/pam_tty_audit.8.xml b/modules/pam_tty_audit/pam_tty_audit.8.xml
|
||||
index 59a3406..e346c68 100644
|
||||
--- a/modules/pam_tty_audit/pam_tty_audit.8.xml
|
||||
+++ b/modules/pam_tty_audit/pam_tty_audit.8.xml
|
||||
@@ -149,6 +149,13 @@
|
||||
greater than or equal to <replaceable>min_uid</replaceable> will be
|
||||
matched.
|
||||
</para>
|
||||
+ <para>
|
||||
+ Please note that passwords in some circumstances may be logged by TTY auditing
|
||||
+ even if the <option>log_passwd</option> is not used. For example, all input to
|
||||
+ an ssh session will be logged - even if there is a password being typed into
|
||||
+ some software running at the remote host because only the local TTY state
|
||||
+ affects the local TTY auditing.
|
||||
+ </para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1 id='pam_tty_audit-examples'>
|
||||
--
|
||||
2.20.1
|
||||
|
@ -0,0 +1,12 @@
|
||||
diff -up Linux-PAM-1.3.1/modules/pam_unix/pam_unix_passwd.c.unix-default-rounds Linux-PAM-1.3.1/modules/pam_unix/pam_unix_passwd.c
|
||||
--- Linux-PAM-1.3.1/modules/pam_unix/pam_unix_passwd.c.unix-default-rounds 2023-11-02 09:59:54.533238124 +0100
|
||||
+++ Linux-PAM-1.3.1/modules/pam_unix/pam_unix_passwd.c 2023-11-02 10:40:58.017404936 +0100
|
||||
@@ -607,7 +607,7 @@ pam_sm_chauthtok(pam_handle_t *pamh, int
|
||||
unsigned int ctrl, lctrl;
|
||||
int retval;
|
||||
int remember = -1;
|
||||
- int rounds = -1;
|
||||
+ int rounds = 0;
|
||||
int pass_min_len = 0;
|
||||
|
||||
/* <DO NOT free() THESE> */
|
@ -0,0 +1,174 @@
|
||||
From f7abb8c1ef3aa31e6c2564a8aaf69683a77c2016 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= <besser82@fedoraproject.org>
|
||||
Date: Thu, 15 Nov 2018 15:01:57 +0100
|
||||
Subject: [PATCH] pam_unix: Use bcrypt b-variant for computing new hashes.
|
||||
|
||||
Bcrypt hashes used the "$2a$" prefix since 1997.
|
||||
However, in 2011 an implementation bug was discovered in bcrypt
|
||||
affecting the handling of characters in passphrases with the 8th
|
||||
bit set.
|
||||
|
||||
Besides fixing the bug, OpenBSD 5.5 introduced the "$2b$" prefix
|
||||
for a behavior that exactly matches crypt_blowfish's "$2y$", and
|
||||
the crypt_blowfish implementation supports it as well since v1.1.
|
||||
|
||||
That said new computed bcrypt hashes should use the "$2b$" prefix.
|
||||
|
||||
* modules/pam_unix/passverify.c: Use bcrypt b-variant.
|
||||
---
|
||||
modules/pam_unix/passverify.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/modules/pam_unix/passverify.c b/modules/pam_unix/passverify.c
|
||||
index 9c1771e2..1f433b3a 100644
|
||||
--- a/modules/pam_unix/passverify.c
|
||||
+++ b/modules/pam_unix/passverify.c
|
||||
@@ -385,7 +385,7 @@ PAMH_ARG_DECL(char * create_password_hash,
|
||||
/* algoid = "$1" */
|
||||
return crypt_md5_wrapper(password);
|
||||
} else if (on(UNIX_BLOWFISH_PASS, ctrl)) {
|
||||
- algoid = "$2a$";
|
||||
+ algoid = "$2b$";
|
||||
} else if (on(UNIX_SHA256_PASS, ctrl)) {
|
||||
algoid = "$5$";
|
||||
} else if (on(UNIX_SHA512_PASS, ctrl)) {
|
||||
--
|
||||
2.41.0
|
||||
|
||||
diff -up Linux-PAM-1.3.1/configure.ac.legacy-xcrypt Linux-PAM-1.3.1/configure.ac
|
||||
--- Linux-PAM-1.3.1/configure.ac.legacy-xcrypt 2023-10-26 12:08:46.896437225 +0200
|
||||
+++ Linux-PAM-1.3.1/configure.ac 2023-10-26 12:10:38.289654696 +0200
|
||||
@@ -395,19 +395,32 @@ AC_SUBST(LIBAUDIT)
|
||||
AM_CONDITIONAL([HAVE_AUDIT_TTY_STATUS],
|
||||
[test "x$HAVE_AUDIT_TTY_STATUS" = xyes])
|
||||
|
||||
-AC_CHECK_HEADERS(xcrypt.h crypt.h)
|
||||
-AS_IF([test "x$ac_cv_header_xcrypt_h" = "xyes"],
|
||||
- [crypt_libs="xcrypt crypt"],
|
||||
- [crypt_libs="crypt"])
|
||||
+AC_CHECK_HEADERS(crypt.h)
|
||||
|
||||
BACKUP_LIBS=$LIBS
|
||||
-AC_SEARCH_LIBS([crypt],[$crypt_libs], LIBCRYPT="${ac_lib:+-l$ac_lib}", LIBCRYPT="")
|
||||
-AC_CHECK_FUNCS(crypt_r crypt_gensalt_r)
|
||||
+LIBCRYPT=""
|
||||
+PKG_CHECK_MODULES([CRYPT], [libcrypt], [
|
||||
+ CFLAGS="$CFLAGS $CRYPT_CFLAGS"
|
||||
+ CPPFLAGS="$CPPFLAGS $CRYPT_CFLAGS"
|
||||
+ LIBS="$LIBS $CRYPT_LIBS"
|
||||
+ LIBCRYPT="$CRYPT_LIBS"
|
||||
+], [
|
||||
+ AC_SEARCH_LIBS([crypt_gensalt_rn],[crypt])
|
||||
+ case "$ac_cv_search_crypt_gensalt_rn" in
|
||||
+ -l*) LIBCRYPT="$ac_cv_search_crypt_gensalt_rn" ;;
|
||||
+ no) AC_SEARCH_LIBS([crypt_r],[crypt])
|
||||
+ case "$ac_cv_search_crypt_r" in
|
||||
+ -l*) LIBCRYPT="$ac_cv_search_crypt_r" ;;
|
||||
+ no ) AC_SEARCH_LIBS([crypt],[crypt])
|
||||
+ case "$ac_cv_search_crypt" in
|
||||
+ -l*) LIBCRYPT="$ac_cv_search_crypt" ;;
|
||||
+ esac ;;
|
||||
+ esac ;;
|
||||
+ esac
|
||||
+])
|
||||
+AC_CHECK_FUNCS([crypt_r])
|
||||
LIBS=$BACKUP_LIBS
|
||||
AC_SUBST(LIBCRYPT)
|
||||
-if test "$LIBCRYPT" = "-lxcrypt" -a "$ac_cv_header_xcrypt_h" = "yes" ; then
|
||||
- AC_DEFINE([HAVE_LIBXCRYPT], 1, [Define to 1 if xcrypt support should be compiled in.])
|
||||
-fi
|
||||
|
||||
AC_ARG_WITH([randomdev], AS_HELP_STRING([--with-randomdev=(<path>|yes|no)],[use specified random device instead of /dev/urandom or 'no' to disable]), opt_randomdev=$withval)
|
||||
if test "$opt_randomdev" = yes -o -z "$opt_randomdev"; then
|
||||
diff -up Linux-PAM-1.3.1/modules/pam_pwhistory/opasswd.c.legacy-xcrypt Linux-PAM-1.3.1/modules/pam_pwhistory/opasswd.c
|
||||
--- Linux-PAM-1.3.1/modules/pam_pwhistory/opasswd.c.legacy-xcrypt 2023-10-26 12:08:46.896437225 +0200
|
||||
+++ Linux-PAM-1.3.1/modules/pam_pwhistory/opasswd.c 2023-10-26 12:11:14.437725259 +0200
|
||||
@@ -52,9 +52,7 @@
|
||||
#include <stdarg.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
-#if defined (HAVE_XCRYPT_H)
|
||||
-#include <xcrypt.h>
|
||||
-#elif defined (HAVE_CRYPT_H)
|
||||
+#ifdef HAVE_CRYPT_H
|
||||
#include <crypt.h>
|
||||
#endif
|
||||
|
||||
diff -up Linux-PAM-1.3.1/modules/pam_unix/bigcrypt.c.legacy-xcrypt Linux-PAM-1.3.1/modules/pam_unix/bigcrypt.c
|
||||
--- Linux-PAM-1.3.1/modules/pam_unix/bigcrypt.c.legacy-xcrypt 2017-02-10 11:10:15.000000000 +0100
|
||||
+++ Linux-PAM-1.3.1/modules/pam_unix/bigcrypt.c 2023-10-26 12:08:46.896437225 +0200
|
||||
@@ -29,9 +29,7 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <security/_pam_macros.h>
|
||||
-#ifdef HAVE_LIBXCRYPT
|
||||
-#include <xcrypt.h>
|
||||
-#elif defined(HAVE_CRYPT_H)
|
||||
+#ifdef HAVE_CRYPT_H
|
||||
#include <crypt.h>
|
||||
#endif
|
||||
|
||||
diff -up Linux-PAM-1.3.1/modules/pam_unix/passverify.c.legacy-xcrypt Linux-PAM-1.3.1/modules/pam_unix/passverify.c
|
||||
--- Linux-PAM-1.3.1/modules/pam_unix/passverify.c.legacy-xcrypt 2023-10-26 12:08:46.895437223 +0200
|
||||
+++ Linux-PAM-1.3.1/modules/pam_unix/passverify.c 2023-10-26 12:16:25.470320408 +0200
|
||||
@@ -19,9 +19,7 @@
|
||||
#include <sys/time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
-#ifdef HAVE_LIBXCRYPT
|
||||
-#include <xcrypt.h>
|
||||
-#elif defined(HAVE_CRYPT_H)
|
||||
+#ifdef HAVE_CRYPT_H
|
||||
#include <crypt.h>
|
||||
#endif
|
||||
|
||||
@@ -406,23 +404,19 @@ PAMH_ARG_DECL(char * create_password_has
|
||||
return crypted;
|
||||
}
|
||||
|
||||
-#ifdef HAVE_CRYPT_GENSALT_R
|
||||
- if (on(UNIX_BLOWFISH_PASS, ctrl)) {
|
||||
- char entropy[17];
|
||||
- crypt_make_salt(entropy, sizeof(entropy) - 1);
|
||||
- sp = crypt_gensalt_r (algoid, rounds,
|
||||
- entropy, sizeof(entropy),
|
||||
- salt, sizeof(salt));
|
||||
- } else {
|
||||
-#endif
|
||||
- sp = stpcpy(salt, algoid);
|
||||
- if (on(UNIX_ALGO_ROUNDS, ctrl)) {
|
||||
- sp += snprintf(sp, sizeof(salt) - (16 + 1 + (sp - salt)), "rounds=%u$", rounds);
|
||||
- }
|
||||
- crypt_make_salt(sp, 16);
|
||||
-#ifdef HAVE_CRYPT_GENSALT_R
|
||||
+#if defined(CRYPT_GENSALT_IMPLEMENTS_AUTO_ENTROPY) && CRYPT_GENSALT_IMPLEMENTS_AUTO_ENTROPY
|
||||
+ /*
|
||||
+ * Any version of libcrypt supporting auto entropy is
|
||||
+ * guaranteed to have crypt_gensalt_rn().
|
||||
+ */
|
||||
+ sp = crypt_gensalt_rn(algoid, rounds, NULL, 0, salt, sizeof(salt));
|
||||
+#else
|
||||
+ sp = stpcpy(salt, algoid);
|
||||
+ if (on(UNIX_ALGO_ROUNDS, ctrl)) {
|
||||
+ sp += snprintf(sp, sizeof(salt) - (16 + 1 + (sp - salt)), "rounds=%u$", rounds);
|
||||
}
|
||||
-#endif
|
||||
+ crypt_make_salt(sp, 16);
|
||||
+#endif /* CRYPT_GENSALT_IMPLEMENTS_AUTO_ENTROPY */
|
||||
#ifdef HAVE_CRYPT_R
|
||||
sp = NULL;
|
||||
cdata = malloc(sizeof(*cdata));
|
||||
diff -up Linux-PAM-1.3.1/modules/pam_userdb/pam_userdb.c.legacy-xcrypt Linux-PAM-1.3.1/modules/pam_userdb/pam_userdb.c
|
||||
--- Linux-PAM-1.3.1/modules/pam_userdb/pam_userdb.c.legacy-xcrypt 2023-10-26 12:08:46.880437194 +0200
|
||||
+++ Linux-PAM-1.3.1/modules/pam_userdb/pam_userdb.c 2023-10-26 12:08:46.896437225 +0200
|
||||
@@ -17,9 +17,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
-#ifdef HAVE_LIBXCRYPT
|
||||
-#include <xcrypt.h>
|
||||
-#elif defined(HAVE_CRYPT_H)
|
||||
+#ifdef HAVE_CRYPT_H
|
||||
#include <crypt.h>
|
||||
#endif
|
||||
|
@ -0,0 +1,57 @@
|
||||
From a6845905869ccabb5eb802be37241eabec085dc7 Mon Sep 17 00:00:00 2001
|
||||
From: Tomas Mraz <tmraz@fedoraproject.org>
|
||||
Date: Mon, 14 Oct 2019 16:52:46 +0200
|
||||
Subject: [PATCH] pam_unix: Add logging useful for debugging problems
|
||||
|
||||
Two messages added about obtaining the username are guarded
|
||||
by the debug option as these should not be normally
|
||||
logged - they can be useful for debugging but they do not
|
||||
indicate any special condition.
|
||||
|
||||
The message about authenticating user with blank password is
|
||||
still just LOG_DEBUG priority but it is logged unconditionally
|
||||
because it is somewhat extraordinary condition to have an user
|
||||
with blank password.
|
||||
|
||||
* modules/pam_unix/pam_unix_auth.c (pam_sm_authenticate): Replace
|
||||
D() macro calls which are not enabled on production builds with
|
||||
regular pam_syslog() calls.
|
||||
---
|
||||
modules/pam_unix/pam_unix_auth.c | 7 ++++---
|
||||
1 file changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/modules/pam_unix/pam_unix_auth.c b/modules/pam_unix/pam_unix_auth.c
|
||||
index 681e49d..3fca945 100644
|
||||
--- a/modules/pam_unix/pam_unix_auth.c
|
||||
+++ b/modules/pam_unix/pam_unix_auth.c
|
||||
@@ -130,15 +130,16 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv)
|
||||
AUTH_RETURN;
|
||||
}
|
||||
if (on(UNIX_DEBUG, ctrl))
|
||||
- D(("username [%s] obtained", name));
|
||||
+ pam_syslog(pamh, LOG_DEBUG, "username [%s] obtained", name);
|
||||
} else {
|
||||
- D(("trouble reading username"));
|
||||
if (retval == PAM_CONV_AGAIN) {
|
||||
D(("pam_get_user/conv() function is not ready yet"));
|
||||
/* it is safe to resume this function so we translate this
|
||||
* retval to the value that indicates we're happy to resume.
|
||||
*/
|
||||
retval = PAM_INCOMPLETE;
|
||||
+ } else if (on(UNIX_DEBUG, ctrl)) {
|
||||
+ pam_syslog(pamh, LOG_DEBUG, "could not obtain username");
|
||||
}
|
||||
AUTH_RETURN;
|
||||
}
|
||||
@@ -146,7 +147,7 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv)
|
||||
/* if this user does not have a password... */
|
||||
|
||||
if (_unix_blankpasswd(pamh, ctrl, name)) {
|
||||
- D(("user '%s' has blank passwd", name));
|
||||
+ pam_syslog(pamh, LOG_DEBUG, "user [%s] has blank password; authenticated without it", name);
|
||||
name = NULL;
|
||||
retval = PAM_SUCCESS;
|
||||
AUTH_RETURN;
|
||||
--
|
||||
2.20.1
|
||||
|
@ -0,0 +1,134 @@
|
||||
From 6bf9b454eb971083f0cce49faa2aa1cde329ff5d Mon Sep 17 00:00:00 2001
|
||||
From: ikerexxe <ipedrosa@redhat.com>
|
||||
Date: Wed, 26 Aug 2020 14:44:23 +0200
|
||||
Subject: [PATCH 1/3] pam_wheel: improve coding style
|
||||
|
||||
modules/pam_wheel/pam_wheel.c: improve indentation and explicitly state
|
||||
condition statements
|
||||
---
|
||||
modules/pam_wheel/pam_wheel.c | 36 ++++++++++++++++++-----------------
|
||||
1 file changed, 19 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/modules/pam_wheel/pam_wheel.c b/modules/pam_wheel/pam_wheel.c
|
||||
index a025ebaf..94cb7d89 100644
|
||||
--- a/modules/pam_wheel/pam_wheel.c
|
||||
+++ b/modules/pam_wheel/pam_wheel.c
|
||||
@@ -130,25 +130,27 @@ perform_check (pam_handle_t *pamh, int ctrl, const char *use_group)
|
||||
}
|
||||
|
||||
if (ctrl & PAM_USE_UID_ARG) {
|
||||
- tpwd = pam_modutil_getpwuid (pamh, getuid());
|
||||
- if (!tpwd) {
|
||||
- if (ctrl & PAM_DEBUG_ARG) {
|
||||
+ tpwd = pam_modutil_getpwuid (pamh, getuid());
|
||||
+ if (tpwd == NULL) {
|
||||
+ if (ctrl & PAM_DEBUG_ARG) {
|
||||
pam_syslog(pamh, LOG_NOTICE, "who is running me ?!");
|
||||
- }
|
||||
- return PAM_SERVICE_ERR;
|
||||
- }
|
||||
- fromsu = tpwd->pw_name;
|
||||
+ }
|
||||
+ return PAM_SERVICE_ERR;
|
||||
+ }
|
||||
+ fromsu = tpwd->pw_name;
|
||||
} else {
|
||||
- fromsu = pam_modutil_getlogin(pamh);
|
||||
- if (fromsu) {
|
||||
- tpwd = pam_modutil_getpwnam (pamh, fromsu);
|
||||
- }
|
||||
- if (!fromsu || !tpwd) {
|
||||
- if (ctrl & PAM_DEBUG_ARG) {
|
||||
- pam_syslog(pamh, LOG_NOTICE, "who is running me ?!");
|
||||
- }
|
||||
- return PAM_SERVICE_ERR;
|
||||
- }
|
||||
+ fromsu = pam_modutil_getlogin(pamh);
|
||||
+
|
||||
+ if (fromsu != NULL) {
|
||||
+ tpwd = pam_modutil_getpwnam (pamh, fromsu);
|
||||
+ }
|
||||
+
|
||||
+ if (fromsu == NULL || tpwd == NULL) {
|
||||
+ if (ctrl & PAM_DEBUG_ARG) {
|
||||
+ pam_syslog(pamh, LOG_NOTICE, "who is running me ?!");
|
||||
+ }
|
||||
+ return PAM_SERVICE_ERR;
|
||||
+ }
|
||||
}
|
||||
|
||||
/*
|
||||
--
|
||||
2.26.2
|
||||
|
||||
|
||||
From 9091ea1d81e85f49a221b0325d27b22ce69e444a Mon Sep 17 00:00:00 2001
|
||||
From: ikerexxe <ipedrosa@redhat.com>
|
||||
Date: Thu, 27 Aug 2020 09:16:15 +0200
|
||||
Subject: [PATCH 2/3] pam_wheel: if getlogin fails fallback to PAM_RUSER
|
||||
|
||||
modules/pam_wheel/pam_wheel.c: if getlogin fails to obtain the real user
|
||||
ID, then try with PAM_RUSER.
|
||||
|
||||
Resolves:
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=1866866
|
||||
---
|
||||
modules/pam_wheel/pam_wheel.c | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
|
||||
diff --git a/modules/pam_wheel/pam_wheel.c b/modules/pam_wheel/pam_wheel.c
|
||||
index 94cb7d89..7fa3cfa9 100644
|
||||
--- a/modules/pam_wheel/pam_wheel.c
|
||||
+++ b/modules/pam_wheel/pam_wheel.c
|
||||
@@ -141,6 +141,16 @@ perform_check (pam_handle_t *pamh, int ctrl, const char *use_group)
|
||||
} else {
|
||||
fromsu = pam_modutil_getlogin(pamh);
|
||||
|
||||
+ /* if getlogin fails try a fallback to PAM_RUSER */
|
||||
+ if (fromsu == NULL) {
|
||||
+ const char *rhostname;
|
||||
+
|
||||
+ retval = pam_get_item(pamh, PAM_RHOST, (const void **)&rhostname);
|
||||
+ if (retval != PAM_SUCCESS || rhostname == NULL) {
|
||||
+ retval = pam_get_item(pamh, PAM_RUSER, (const void **)&fromsu);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (fromsu != NULL) {
|
||||
tpwd = pam_modutil_getpwnam (pamh, fromsu);
|
||||
}
|
||||
--
|
||||
2.26.2
|
||||
|
||||
|
||||
From a3a5cbf86083c43026b558e2023f597530626267 Mon Sep 17 00:00:00 2001
|
||||
From: ikerexxe <ipedrosa@redhat.com>
|
||||
Date: Wed, 9 Sep 2020 10:32:03 +0200
|
||||
Subject: [PATCH 3/3] pam_wheel: clarify use_uid option in man page
|
||||
|
||||
modules/pam_wheel/pam_wheel.8.xml: indicate that use_uid option uses the
|
||||
real uid of the calling process.
|
||||
---
|
||||
modules/pam_wheel/pam_wheel.8.xml | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/modules/pam_wheel/pam_wheel.8.xml b/modules/pam_wheel/pam_wheel.8.xml
|
||||
index b32f5e2b..ee8c7d26 100644
|
||||
--- a/modules/pam_wheel/pam_wheel.8.xml
|
||||
+++ b/modules/pam_wheel/pam_wheel.8.xml
|
||||
@@ -122,9 +122,9 @@
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
- The check for wheel membership will be done against
|
||||
- the current uid instead of the original one (useful when
|
||||
- jumping with su from one account to another for example).
|
||||
+ The check will be done against the real uid of the calling process,
|
||||
+ instead of trying to obtain the user from the login session
|
||||
+ associated with the terminal in use.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
--
|
||||
2.26.2
|
||||
|
@ -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,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,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,211 +0,0 @@
|
||||
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.
|
||||
</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">
|
||||
debug
|
||||
</arg>
|
||||
+ <arg choice="opt" rep="norepeat">
|
||||
+ noaudit
|
||||
+ </arg>
|
||||
<arg choice="opt">
|
||||
nodefgroup
|
||||
</arg>
|
||||
- <arg choice="opt">
|
||||
- noaudit
|
||||
+ <arg choice="opt" rep="norepeat">
|
||||
+ nodns
|
||||
</arg>
|
||||
<arg choice="opt">
|
||||
accessfile=<replaceable>file</replaceable>
|
||||
@@ -114,7 +117,46 @@
|
||||
|
||||
<varlistentry>
|
||||
<term>
|
||||
- <option>fieldsep=<replaceable>separators</replaceable></option>
|
||||
+ nodefgroup
|
||||
+ </term>
|
||||
+ <listitem>
|
||||
+ <para>
|
||||
+ User tokens which are not enclosed in parentheses will not be
|
||||
+ matched against the group database. The backwards compatible default is
|
||||
+ to try the group database match even for tokens not enclosed
|
||||
+ in parentheses.
|
||||
+ </para>
|
||||
+ </listitem>
|
||||
+ </varlistentry>
|
||||
+
|
||||
+ <varlistentry>
|
||||
+ <term>
|
||||
+ nodns
|
||||
+ </term>
|
||||
+ <listitem>
|
||||
+ <para>
|
||||
+ Do not try to resolve tokens as hostnames, only IPv4 and IPv6
|
||||
+ addresses will be resolved. Which means to allow login from a
|
||||
+ remote host, the IP addresses need to be specified in <filename>access.conf</filename>.
|
||||
+ </para>
|
||||
+ </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>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
-
|
||||
- <varlistentry>
|
||||
- <term>
|
||||
- <option>nodefgroup</option>
|
||||
- </term>
|
||||
- <listitem>
|
||||
- <para>
|
||||
- User tokens which are not enclosed in parentheses will not be
|
||||
- matched against the group database. The backwards compatible default is
|
||||
- to try the group database match even for tokens not enclosed
|
||||
- in parentheses.
|
||||
- </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. */
|
||||
int only_new_group_syntax; /* Only allow group entries of the form "(xyz)" */
|
||||
int noaudit; /* Do not audit 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) {
|
||||
loginfo->noaudit = 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
|
||||
}
|
||||
|
||||
|
||||
+static int
|
||||
+is_device (pam_handle_t *pamh, const char *tok)
|
||||
+{
|
||||
+ struct stat st;
|
||||
+ const char *dev = "/dev/";
|
||||
+ char *devname;
|
||||
+
|
||||
+ devname = malloc (strlen(dev) + strlen (tok) + 1);
|
||||
+ if (devname == NULL) {
|
||||
+ pam_syslog(pamh, LOG_ERR, "Cannot allocate memory for device name: %m");
|
||||
+ /*
|
||||
+ * We should return an error and abort, but pam_access has no good
|
||||
+ * error handling.
|
||||
+ */
|
||||
+ return NO;
|
||||
+ }
|
||||
+
|
||||
+ char *cp = stpcpy (devname, dev);
|
||||
+ strcpy (cp, tok);
|
||||
+
|
||||
+ if (lstat(devname, &st) != 0)
|
||||
+ {
|
||||
+ free (devname);
|
||||
+ return NO;
|
||||
+ }
|
||||
+ free (devname);
|
||||
+
|
||||
+ if (S_ISCHR(st.st_mode))
|
||||
+ return YES;
|
||||
+
|
||||
+ return NO;
|
||||
+}
|
||||
+
|
||||
/* 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
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
+ else if (isipaddr(tok, NULL, NULL) == YES)
|
||||
+ {
|
||||
+ if (getaddrinfo (tok, NULL, NULL, &ai) != 0)
|
||||
+ {
|
||||
+ if (item->debug)
|
||||
+ pam_syslog(pamh, LOG_DEBUG, "cannot resolve IP address \"%s\"", tok);
|
||||
+
|
||||
+ return NO;
|
||||
+ }
|
||||
+ netmask_ptr = NULL;
|
||||
+ }
|
||||
+ else if (item->nodns)
|
||||
+ {
|
||||
+ /* Only hostnames are left, which we would need to resolve via DNS */
|
||||
+ return NO;
|
||||
+ }
|
||||
else
|
||||
{
|
||||
+ /* Bail out on X11 Display entries and ttys. */
|
||||
+ if (tok[0] == ':')
|
||||
+ {
|
||||
+ if (item->debug)
|
||||
+ pam_syslog (pamh, LOG_DEBUG,
|
||||
+ "network_netmask_match: tok=%s is X11 display", tok);
|
||||
+ return NO;
|
||||
+ }
|
||||
+ if (is_device (pamh, tok))
|
||||
+ {
|
||||
+ if (item->debug)
|
||||
+ pam_syslog (pamh, LOG_DEBUG,
|
||||
+ "network_netmask_match: tok=%s is a TTY", tok);
|
||||
+ return NO;
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
- * It is either an IP address or a hostname.
|
||||
+ * It is most likely a hostname.
|
||||
* Let getaddrinfo sort everything out
|
||||
*/
|
||||
if (getaddrinfo (tok, NULL, NULL, &ai) != 0)
|
@ -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,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,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,19 +1,4 @@
|
||||
#%PAM-1.0
|
||||
# This file is auto-generated.
|
||||
# User changes will be destroyed the next time authselect is run.
|
||||
auth required pam_env.so
|
||||
auth [success=done ignore=ignore default=die] pam_pkcs11.so wait_for_card
|
||||
auth required pam_deny.so
|
||||
|
||||
account required pam_unix.so
|
||||
account sufficient pam_localuser.so
|
||||
account sufficient pam_succeed_if.so uid < 500 quiet
|
||||
account required pam_permit.so
|
||||
|
||||
password optional pam_pkcs11.so
|
||||
|
||||
session optional pam_keyinit.so revoke
|
||||
session required pam_limits.so
|
||||
-session optional pam_systemd.so
|
||||
session [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
|
||||
session required pam_unix.so
|
||||
auth sufficient pam_sss.so allow_missing_name
|
||||
|
Loading…
Reference in new issue