Browse Source

pam package update

Signed-off-by: basebuilder_pel7ppc64bebuilder0 <basebuilder@powerel.org>
master
basebuilder_pel7ppc64bebuilder0 6 years ago
parent
commit
48ecccb970
  1. 6
      SOURCES/20-nproc.conf
  2. 36
      SOURCES/config-util.5
  3. 8
      SOURCES/config-util.pamd
  4. 75
      SOURCES/dlopen.sh
  5. 19
      SOURCES/fingerprint-auth.pamd
  6. 5
      SOURCES/other.pamd
  7. 23
      SOURCES/pam-1.0.90-redhat-modules.patch
  8. 26
      SOURCES/pam-1.1.0-console-nochmod.patch
  9. 12
      SOURCES/pam-1.1.0-notally.patch
  10. 12
      SOURCES/pam-1.1.1-console-errmsg.patch
  11. 1714
      SOURCES/pam-1.1.1-faillock.patch
  12. 167
      SOURCES/pam-1.1.3-faillock-screensaver.patch
  13. 27
      SOURCES/pam-1.1.3-nouserenv.patch
  14. 69
      SOURCES/pam-1.1.5-unix-no-fallback.patch
  15. 20
      SOURCES/pam-1.1.6-limits-user.patch
  16. 24
      SOURCES/pam-1.1.6-noflex.patch
  17. 146
      SOURCES/pam-1.1.6-std-noclose.patch
  18. 15
      SOURCES/pam-1.1.6-use-links.patch
  19. 48
      SOURCES/pam-1.1.7-tty-audit-init.patch
  20. 392
      SOURCES/pam-1.1.8-access-update.patch
  21. 435
      SOURCES/pam-1.1.8-audit-grantor.patch
  22. 47
      SOURCES/pam-1.1.8-audit-user-mgmt.patch
  23. 21
      SOURCES/pam-1.1.8-canonicalize-username.patch
  24. 52
      SOURCES/pam-1.1.8-cve-2013-7041.patch
  25. 56
      SOURCES/pam-1.1.8-cve-2014-2583.patch
  26. 130
      SOURCES/pam-1.1.8-cve-2015-3238.patch
  27. 151
      SOURCES/pam-1.1.8-faillock-admin-group.patch
  28. 91
      SOURCES/pam-1.1.8-faillock-never.patch
  29. 108
      SOURCES/pam-1.1.8-full-relro.patch
  30. 22
      SOURCES/pam-1.1.8-lastlog-localtime.patch
  31. 37
      SOURCES/pam-1.1.8-lastlog-uninitialized.patch
  32. 41
      SOURCES/pam-1.1.8-limits-check-process.patch
  33. 54
      SOURCES/pam-1.1.8-limits-docfix.patch
  34. 19
      SOURCES/pam-1.1.8-loginuid-log-auditd.patch
  35. 22
      SOURCES/pam-1.1.8-man-dbsuffix.patch
  36. 30
      SOURCES/pam-1.1.8-man-delay.patch
  37. 78
      SOURCES/pam-1.1.8-man-environment.patch
  38. 13
      SOURCES/pam-1.1.8-man-space.patch
  39. 29
      SOURCES/pam-1.1.8-mkhomedir-inroot.patch
  40. 50
      SOURCES/pam-1.1.8-opasswd-tolerant.patch
  41. 812
      SOURCES/pam-1.1.8-pwhistory-helper.patch
  42. 12
      SOURCES/pam-1.1.8-relax-audit.patch
  43. 85
      SOURCES/pam-1.1.8-succeed-if-large-uid.patch
  44. 1522
      SOURCES/pam-1.1.8-translation-updates.patch
  45. 167
      SOURCES/pam-1.1.8-tty-audit-uid-range.patch
  46. 134
      SOURCES/pam-1.1.8-unix-expiry.patch
  47. 3
      SOURCES/pamtmp.conf
  48. 18
      SOURCES/password-auth.pamd
  49. 46
      SOURCES/postlogin.5
  50. 7
      SOURCES/postlogin.pamd
  51. 19
      SOURCES/smartcard-auth.pamd
  52. 58
      SOURCES/system-auth.5
  53. 18
      SOURCES/system-auth.pamd
  54. 2118
      SPECS/pam.spec

6
SOURCES/20-nproc.conf

@ -0,0 +1,6 @@ @@ -0,0 +1,6 @@
# Default limit for number of user's processes to prevent
# accidental fork bombs.
# See rhbz #432903 for reasoning.

* soft nproc 4096
root soft nproc unlimited

36
SOURCES/config-util.5

@ -0,0 +1,36 @@ @@ -0,0 +1,36 @@
.TH SYSTEM-AUTH 5 "2006 Feb 3" "Red Hat" "Linux-PAM Manual"
.SH NAME

config-util \- Common PAM configuration file for configuration utilities

.SH SYNOPSIS
.B /etc/pam.d/config-util
.sp 2
.SH DESCRIPTION

The purpose of this configuration file is to provide common
configuration file for all configuration utilities which must be run
from the supervisor account and use the userhelper wrapper application.

.sp
The
.BR config-util
configuration file is included from all individual configuration
files of such utilities with the help of the
.BR include
directive.
There are not usually any other modules in the individual configuration
files of these utilities.

.sp
It is possible for example to modify duration of the validity of the
authentication timestamp there. See
.BR pam_timestamp(8)
for details.

.SH BUGS
.sp 2
None known.

.SH "SEE ALSO"
pam(8), config-util(5), pam_timestamp(8)

8
SOURCES/config-util.pamd

@ -0,0 +1,8 @@ @@ -0,0 +1,8 @@
#%PAM-1.0
auth sufficient pam_rootok.so
auth sufficient pam_timestamp.so
auth include system-auth
account required pam_permit.so
session required pam_permit.so
session optional pam_xauth.so
session optional pam_timestamp.so

75
SOURCES/dlopen.sh

@ -0,0 +1,75 @@ @@ -0,0 +1,75 @@
#!/bin/sh

tempdir=`mktemp -d /tmp/dlopenXXXXXX`
test -n "$tempdir" || exit 1
cat >> $tempdir/dlopen.c << _EOF
#include <dlfcn.h>
#include <stdio.h>
#include <limits.h>
#include <sys/stat.h>
/* Simple program to see if dlopen() would succeed. */
int main(int argc, char **argv)
{
int i;
struct stat st;
char buf[PATH_MAX];
for (i = 1; i < argc; i++) {
if (dlopen(argv[i], RTLD_NOW)) {
fprintf(stdout, "dlopen() of \"%s\" succeeded.\n",
argv[i]);
} else {
snprintf(buf, sizeof(buf), "./%s", argv[i]);
if ((stat(buf, &st) == 0) && dlopen(buf, RTLD_NOW)) {
fprintf(stdout, "dlopen() of \"./%s\" "
"succeeded.\n", argv[i]);
} else {
fprintf(stdout, "dlopen() of \"%s\" failed: "
"%s\n", argv[i], dlerror());
return 1;
}
}
}
return 0;
}
_EOF

for arg in $@ ; do
case "$arg" in
"")
;;
-I*|-D*|-f*|-m*|-g*|-O*|-W*)
cflags="$cflags $arg"
;;
-l*|-L*)
ldflags="$ldflags $arg"
;;
/*)
modules="$modules $arg"
;;
*)
modules="$modules $arg"
;;
esac
done

${CC:-gcc} $RPM_OPT_FLAGS $CFLAGS -o $tempdir/dlopen $cflags $tempdir/dlopen.c $ldflags -ldl

retval=0
for module in $modules ; do
case "$module" in
"")
;;
/*)
$tempdir/dlopen "$module"
retval=$?
;;
*)
$tempdir/dlopen ./"$module"
retval=$?
;;
esac
done

rm -f $tempdir/dlopen $tempdir/dlopen.c
rmdir $tempdir
exit $retval

19
SOURCES/fingerprint-auth.pamd

@ -0,0 +1,19 @@ @@ -0,0 +1,19 @@
#%PAM-1.0
# This file is auto-generated.
# User changes will be destroyed the next time authconfig is run.
auth required pam_env.so
auth sufficient pam_fprintd.so
auth required pam_deny.so

account required pam_unix.so
account sufficient pam_localuser.so
account sufficient pam_succeed_if.so uid < 500 quiet
account required pam_permit.so

password required pam_deny.so

session optional pam_keyinit.so revoke
session required pam_limits.so
-session optional pam_systemd.so
session [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
session required pam_unix.so

5
SOURCES/other.pamd

@ -0,0 +1,5 @@ @@ -0,0 +1,5 @@
#%PAM-1.0
auth required pam_deny.so
account required pam_deny.so
password required pam_deny.so
session required pam_deny.so

23
SOURCES/pam-1.0.90-redhat-modules.patch

@ -0,0 +1,23 @@ @@ -0,0 +1,23 @@
diff -up Linux-PAM-1.0.90/modules/Makefile.am.redhat-modules Linux-PAM-1.0.90/modules/Makefile.am
--- Linux-PAM-1.0.90/modules/Makefile.am.redhat-modules 2008-11-29 08:27:35.000000000 +0100
+++ Linux-PAM-1.0.90/modules/Makefile.am 2008-12-16 13:40:16.000000000 +0100
@@ -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 \
diff -up Linux-PAM-1.0.90/configure.in.redhat-modules Linux-PAM-1.0.90/configure.in
--- Linux-PAM-1.0.90/configure.in.redhat-modules 2008-12-02 16:25:01.000000000 +0100
+++ Linux-PAM-1.0.90/configure.in 2008-12-16 13:39:11.000000000 +0100
@@ -531,6 +531,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 \

26
SOURCES/pam-1.1.0-console-nochmod.patch

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

12
SOURCES/pam-1.1.0-notally.patch

@ -0,0 +1,12 @@ @@ -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_tally2 pam_time pam_timestamp \
pam_tty_audit pam_umask \
pam_unix pam_userdb pam_warn pam_wheel pam_xauth

12
SOURCES/pam-1.1.1-console-errmsg.patch

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

1714
SOURCES/pam-1.1.1-faillock.patch

File diff suppressed because it is too large Load Diff

167
SOURCES/pam-1.1.3-faillock-screensaver.patch

@ -0,0 +1,167 @@ @@ -0,0 +1,167 @@
diff -up Linux-PAM-1.1.3/modules/pam_faillock/faillock.c.screensaver Linux-PAM-1.1.3/modules/pam_faillock/faillock.c
--- Linux-PAM-1.1.3/modules/pam_faillock/faillock.c.screensaver 2010-11-10 11:46:07.000000000 +0100
+++ Linux-PAM-1.1.3/modules/pam_faillock/faillock.c 2010-11-10 11:46:07.000000000 +0100
@@ -41,13 +41,14 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
+#include <sys/stat.h>
#include <fcntl.h>
#include <security/pam_modutil.h>
#include "faillock.h"
int
-open_tally (const char *dir, const char *user, int create)
+open_tally (const char *dir, const char *user, uid_t uid, int create)
{
char *path;
int flags = O_RDWR;
@@ -69,8 +70,18 @@ open_tally (const char *dir, const char
fd = open(path, flags, 0600);
- if (fd != -1)
+ free(path);
+
+ if (fd != -1) {
+ struct stat st;
+
while (flock(fd, LOCK_EX) == -1 && errno == EINTR);
+ if (fstat(fd, &st) == 0) {
+ if (st.st_uid != uid) {
+ fchown(fd, uid, -1);
+ }
+ }
+ }
return fd;
}
diff -up Linux-PAM-1.1.3/modules/pam_faillock/faillock.h.screensaver Linux-PAM-1.1.3/modules/pam_faillock/faillock.h
--- Linux-PAM-1.1.3/modules/pam_faillock/faillock.h.screensaver 2010-11-10 11:46:07.000000000 +0100
+++ Linux-PAM-1.1.3/modules/pam_faillock/faillock.h 2010-11-10 11:46:07.000000000 +0100
@@ -45,6 +45,7 @@
#define _FAILLOCK_H
#include <stdint.h>
+#include <sys/types.h>
#define TALLY_STATUS_VALID 0x1 /* the tally file entry is valid */
#define TALLY_STATUS_RHOST 0x2 /* the source is rhost */
@@ -65,7 +66,7 @@ struct tally_data {
#define FAILLOCK_DEFAULT_TALLYDIR "/var/run/faillock"
-int open_tally(const char *dir, const char *user, int create);
+int open_tally(const char *dir, const char *user, uid_t uid, int create);
int read_tally(int fd, struct tally_data *tallies);
int update_tally(int fd, struct tally_data *tallies);
#endif
diff -up Linux-PAM-1.1.3/modules/pam_faillock/main.c.screensaver Linux-PAM-1.1.3/modules/pam_faillock/main.c
--- Linux-PAM-1.1.3/modules/pam_faillock/main.c.screensaver 2010-11-10 11:46:07.000000000 +0100
+++ Linux-PAM-1.1.3/modules/pam_faillock/main.c 2010-11-10 11:46:07.000000000 +0100
@@ -106,8 +106,11 @@ do_user(struct options *opts, const char
int fd;
int rv;
struct tally_data tallies;
+ struct passwd *pwd;
- fd = open_tally(opts->dir, user, 0);
+ pwd = getpwnam(user);
+
+ fd = open_tally(opts->dir, user, pwd != NULL ? pwd->pw_uid : 0, 0);
if (fd == -1) {
if (errno == ENOENT) {
@@ -134,9 +137,8 @@ do_user(struct options *opts, const char
#ifdef HAVE_LIBAUDIT
}
if ((audit_fd=audit_open()) >= 0) {
- struct passwd *pwd;
- if ((pwd=getpwnam(user)) != NULL) {
+ if (pwd != NULL) {
snprintf(buf, sizeof(buf), "faillock reset uid=%u",
pwd->pw_uid);
audit_log_user_message(audit_fd, AUDIT_USER_ACCT,
diff -up Linux-PAM-1.1.3/modules/pam_faillock/pam_faillock.c.screensaver Linux-PAM-1.1.3/modules/pam_faillock/pam_faillock.c
--- Linux-PAM-1.1.3/modules/pam_faillock/pam_faillock.c.screensaver 2010-11-10 11:46:07.000000000 +0100
+++ Linux-PAM-1.1.3/modules/pam_faillock/pam_faillock.c 2010-11-10 11:46:07.000000000 +0100
@@ -213,7 +213,7 @@ check_tally(pam_handle_t *pamh, struct o
opts->now = time(NULL);
- tfd = open_tally(opts->dir, opts->user, 0);
+ tfd = open_tally(opts->dir, opts->user, opts->uid, 0);
*fd = tfd;
@@ -289,9 +289,14 @@ reset_tally(pam_handle_t *pamh, struct o
{
int rv;
- while ((rv=ftruncate(*fd, 0)) == -1 && errno == EINTR);
- if (rv == -1) {
- pam_syslog(pamh, LOG_ERR, "Error clearing the tally file for %s: %m", opts->user);
+ if (*fd == -1) {
+ *fd = open_tally(opts->dir, opts->user, opts->uid, 1);
+ }
+ else {
+ while ((rv=ftruncate(*fd, 0)) == -1 && errno == EINTR);
+ if (rv == -1) {
+ pam_syslog(pamh, LOG_ERR, "Error clearing the tally file for %s: %m", opts->user);
+ }
}
}
@@ -306,7 +311,7 @@ write_tally(pam_handle_t *pamh, struct o
const void *source = NULL;
if (*fd == -1) {
- *fd = open_tally(opts->dir, opts->user, 1);
+ *fd = open_tally(opts->dir, opts->user, opts->uid, 1);
}
if (*fd == -1) {
if (errno == EACCES) {
@@ -463,7 +468,7 @@ pam_sm_authenticate(pam_handle_t *pamh,
case FAILLOCK_ACTION_AUTHSUCC:
rv = check_tally(pamh, &opts, &tallies, &fd);
- if (rv == PAM_SUCCESS && fd != -1) {
+ if (rv == PAM_SUCCESS) {
reset_tally(pamh, &opts, &fd);
}
break;
@@ -511,10 +516,8 @@ pam_sm_acct_mgmt(pam_handle_t *pamh, int
return rv;
}
- check_tally(pamh, &opts, &tallies, &fd);
- if (fd != -1) {
- reset_tally(pamh, &opts, &fd);
- }
+ check_tally(pamh, &opts, &tallies, &fd); /* for auditing */
+ reset_tally(pamh, &opts, &fd);
tally_cleanup(&tallies, fd);
diff -up Linux-PAM-1.1.3/modules/pam_faillock/pam_faillock.8.xml.screensaver Linux-PAM-1.1.3/modules/pam_faillock/pam_faillock.8.xml
--- Linux-PAM-1.1.3/modules/pam_faillock/pam_faillock.8.xml.screensaver 2010-11-10 11:46:07.000000000 +0100
+++ Linux-PAM-1.1.3/modules/pam_faillock/pam_faillock.8.xml 2010-11-10 11:47:14.000000000 +0100
@@ -277,13 +277,9 @@
from the <emphasis>pam_tally2</emphasis> module setup.
</para>
<para>
- There is no setuid wrapper for access to the data file such as when the
- <emphasis remap='B'>pam_faillock.so</emphasis> module is called from
- a screensaver. As this would make it impossible to share PAM configuration
- with such services the following workaround is used: If the data file
- cannot be opened because of insufficient permissions
- (<errorcode>EACCES</errorcode>) the module returns
- <errorcode>PAM_SUCCESS</errorcode>.
+ The individual files with the failure records are created as owned by
+ the user. This allows <emphasis remap='B'>pam_faillock.so</emphasis> module
+ to work correctly when it is called from a screensaver.
</para>
<para>
Note that using the module in <option>preauth</option> without the

27
SOURCES/pam-1.1.3-nouserenv.patch

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

69
SOURCES/pam-1.1.5-unix-no-fallback.patch

@ -0,0 +1,69 @@ @@ -0,0 +1,69 @@
diff -up Linux-PAM-1.1.5/modules/pam_unix/pam_unix.8.xml.no-fallback Linux-PAM-1.1.5/modules/pam_unix/pam_unix.8.xml
--- Linux-PAM-1.1.5/modules/pam_unix/pam_unix.8.xml.no-fallback 2011-06-21 11:04:56.000000000 +0200
+++ Linux-PAM-1.1.5/modules/pam_unix/pam_unix.8.xml 2012-05-09 11:54:34.442036404 +0200
@@ -265,11 +265,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>
@@ -280,11 +279,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>
@@ -295,11 +293,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.1.5/modules/pam_unix/passverify.c.no-fallback Linux-PAM-1.1.5/modules/pam_unix/passverify.c
--- Linux-PAM-1.1.5/modules/pam_unix/passverify.c.no-fallback 2012-05-09 11:48:12.409632377 +0200
+++ Linux-PAM-1.1.5/modules/pam_unix/passverify.c 2012-05-09 11:48:36.953172291 +0200
@@ -427,15 +427,14 @@ PAMH_ARG_DECL(char * create_password_has
if (!sp || strncmp(algoid, sp, strlen(algoid)) != 0) {
/* libxcrypt/libc doesn't know the algorithm, use MD5 */
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);
if(sp) {
memset(sp, '\0', strlen(sp));
}
- return crypt_md5_wrapper(password);
+ return NULL;
}
return x_strdup(sp);

20
SOURCES/pam-1.1.6-limits-user.patch

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

24
SOURCES/pam-1.1.6-noflex.patch

@ -0,0 +1,24 @@ @@ -0,0 +1,24 @@
diff -up Linux-PAM-1.1.6/doc/Makefile.am.noflex Linux-PAM-1.1.6/doc/Makefile.am
--- Linux-PAM-1.1.6/doc/Makefile.am.noflex 2012-08-15 13:08:43.000000000 +0200
+++ Linux-PAM-1.1.6/doc/Makefile.am 2012-08-17 14:13:11.904949748 +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.1.6/Makefile.am.noflex Linux-PAM-1.1.6/Makefile.am
--- Linux-PAM-1.1.6/Makefile.am.noflex 2012-08-15 13:08:43.000000000 +0200
+++ Linux-PAM-1.1.6/Makefile.am 2012-08-17 14:15:36.705359892 +0200
@@ -4,7 +4,7 @@
AUTOMAKE_OPTIONS = 1.9 gnu dist-bzip2 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 = *~

146
SOURCES/pam-1.1.6-std-noclose.patch

@ -0,0 +1,146 @@ @@ -0,0 +1,146 @@
diff -up Linux-PAM-1.1.6/modules/pam_mkhomedir/pam_mkhomedir.c.std-noclose Linux-PAM-1.1.6/modules/pam_mkhomedir/pam_mkhomedir.c
--- Linux-PAM-1.1.6/modules/pam_mkhomedir/pam_mkhomedir.c.std-noclose 2012-08-15 13:08:43.000000000 +0200
+++ Linux-PAM-1.1.6/modules/pam_mkhomedir/pam_mkhomedir.c 2013-04-24 13:11:14.768817086 +0200
@@ -35,6 +35,7 @@
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/wait.h>
+#include <fcntl.h>
#include <unistd.h>
#include <pwd.h>
#include <errno.h>
@@ -133,13 +134,21 @@ create_homedir (pam_handle_t *pamh, opti
if (child == 0) {
int i;
struct rlimit rlim;
+ int dummyfds[2];
static char *envp[] = { NULL };
char *args[] = { 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=0; i < (int)rlim.rlim_max; i++) {
+ for (i = STDERR_FILENO + 1; i < (int)rlim.rlim_max; i++) {
close(i);
}
}
diff -up Linux-PAM-1.1.6/modules/pam_unix/pam_unix_acct.c.std-noclose Linux-PAM-1.1.6/modules/pam_unix/pam_unix_acct.c
--- Linux-PAM-1.1.6/modules/pam_unix/pam_unix_acct.c.std-noclose 2012-08-15 13:08:43.000000000 +0200
+++ Linux-PAM-1.1.6/modules/pam_unix/pam_unix_acct.c 2013-04-24 13:12:17.105990961 +0200
@@ -39,6 +39,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/resource.h>
@@ -100,21 +101,26 @@ int _unix_run_verify_binary(pam_handle_t
if (child == 0) {
int i=0;
struct rlimit rlim;
+ int dummyfds[2];
static char *envp[] = { NULL };
char *args[] = { NULL, NULL, NULL, NULL };
/* reopen stdout as pipe */
dup2(fds[1], STDOUT_FILENO);
+ /* replace std file descriptors with a dummy pipe */
+ if (pipe2(dummyfds, O_NONBLOCK) == 0) {
+ dup2(dummyfds[0], STDIN_FILENO);
+ dup2(dummyfds[1], STDERR_FILENO);
+ }
+
/* XXX - should really tidy up PAM here too */
if (getrlimit(RLIMIT_NOFILE,&rlim)==0) {
if (rlim.rlim_max >= MAX_FD_NO)
rlim.rlim_max = MAX_FD_NO;
- for (i=0; i < (int)rlim.rlim_max; i++) {
- if (i != STDOUT_FILENO) {
- close(i);
- }
+ for (i = STDERR_FILENO + 1; i < (int)rlim.rlim_max; i++) {
+ close(i);
}
}
diff -up Linux-PAM-1.1.6/modules/pam_unix/pam_unix_passwd.c.std-noclose Linux-PAM-1.1.6/modules/pam_unix/pam_unix_passwd.c
--- Linux-PAM-1.1.6/modules/pam_unix/pam_unix_passwd.c.std-noclose 2012-08-15 13:08:43.000000000 +0200
+++ Linux-PAM-1.1.6/modules/pam_unix/pam_unix_passwd.c 2013-04-23 17:13:49.047499806 +0200
@@ -202,6 +202,7 @@ static int _unix_run_update_binary(pam_h
if (child == 0) {
int i=0;
struct rlimit rlim;
+ int dummyfds[2];
static char *envp[] = { NULL };
char *args[] = { NULL, NULL, NULL, NULL, NULL, NULL };
char buffer[16];
@@ -211,11 +212,17 @@ static int _unix_run_update_binary(pam_h
/* 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=0; i < (int)rlim.rlim_max; i++) {
- if (i != STDIN_FILENO)
+ for (i = STDERR_FILENO + 1; i < (int)rlim.rlim_max; i++) {
+ if (i != dummyfds[0])
close(i);
}
}
diff -up Linux-PAM-1.1.6/modules/pam_unix/support.c.std-noclose Linux-PAM-1.1.6/modules/pam_unix/support.c
--- Linux-PAM-1.1.6/modules/pam_unix/support.c.std-noclose 2012-08-15 13:08:43.000000000 +0200
+++ Linux-PAM-1.1.6/modules/pam_unix/support.c 2013-04-24 13:12:42.893064361 +0200
@@ -5,6 +5,7 @@
#include "config.h"
#include <stdlib.h>
+#include <fcntl.h>
#include <unistd.h>
#include <stdarg.h>
#include <stdio.h>
@@ -462,6 +463,7 @@ static int _unix_run_helper_binary(pam_h
if (child == 0) {
int i=0;
struct rlimit rlim;
+ int dummyfds[2];
static char *envp[] = { NULL };
char *args[] = { NULL, NULL, NULL, NULL };
@@ -470,11 +472,17 @@ static int _unix_run_helper_binary(pam_h
/* 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=0; i < (int)rlim.rlim_max; i++) {
- if (i != STDIN_FILENO)
+ for (i = STDERR_FILENO + 1; i < (int)rlim.rlim_max; i++) {
+ if (i != dummyfds[0])
close(i);
}
}

15
SOURCES/pam-1.1.6-use-links.patch

@ -0,0 +1,15 @@ @@ -0,0 +1,15 @@
diff -up Linux-PAM-1.1.6/configure.in.links Linux-PAM-1.1.6/configure.in
--- Linux-PAM-1.1.6/configure.in.links 2013-04-24 13:13:36.000000000 +0200
+++ Linux-PAM-1.1.6/configure.in 2013-08-07 14:08:03.818055990 +0200
@@ -548,9 +548,9 @@ JH_CHECK_XML_CATALOG([-//OASIS//DTD DocB
JH_CHECK_XML_CATALOG([http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl],
[DocBook XSL Stylesheets], [], enable_docu=no)
-AC_PATH_PROG([BROWSER], [w3m])
+AC_PATH_PROG([BROWSER], [links])
if test ! -z "$BROWSER"; then
- BROWSER="$BROWSER -T text/html -dump"
+ BROWSER="$BROWSER -no-numbering -no-references -dump"
else
enable_docu=no
fi

48
SOURCES/pam-1.1.7-tty-audit-init.patch

@ -0,0 +1,48 @@ @@ -0,0 +1,48 @@
diff -up Linux-PAM-1.1.7/modules/pam_tty_audit/pam_tty_audit.c.tty-audit-init Linux-PAM-1.1.7/modules/pam_tty_audit/pam_tty_audit.c
--- Linux-PAM-1.1.7/modules/pam_tty_audit/pam_tty_audit.c.tty-audit-init 2013-08-28 10:53:40.000000000 +0200
+++ Linux-PAM-1.1.7/modules/pam_tty_audit/pam_tty_audit.c 2013-10-04 14:51:19.944994905 +0200
@@ -36,6 +36,7 @@
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE. */
+#include "config.h"
#include <errno.h>
#include <fnmatch.h>
#include <stdlib.h>
@@ -108,7 +109,7 @@ nl_recv (int fd, unsigned type, void *bu
struct msghdr msg;
struct nlmsghdr nlm;
struct iovec iov[2];
- ssize_t res;
+ ssize_t res, resdiff;
again:
iov[0].iov_base = &nlm;
@@ -160,12 +161,17 @@ nl_recv (int fd, unsigned type, void *bu
res = recvmsg (fd, &msg, 0);
if (res == -1)
return -1;
- if ((size_t)res != NLMSG_LENGTH (size)
+ resdiff = NLMSG_LENGTH(size) - (size_t)res;
+ if (resdiff < 0
|| nlm.nlmsg_type != type)
{
errno = EIO;
return -1;
}
+ else if (resdiff > 0)
+ {
+ memset((char *)buf + size - resdiff, 0, resdiff);
+ }
return 0;
}
@@ -275,6 +281,8 @@ pam_sm_open_session (pam_handle_t *pamh,
return PAM_SESSION_ERR;
}
+ memcpy(&new_status, old_status, sizeof(new_status));
+
new_status.enabled = (command == CMD_ENABLE ? 1 : 0);
#ifdef HAVE_STRUCT_AUDIT_TTY_STATUS_LOG_PASSWD
new_status.log_passwd = log_passwd;

392
SOURCES/pam-1.1.8-access-update.patch

@ -0,0 +1,392 @@ @@ -0,0 +1,392 @@
diff -up Linux-PAM-1.1.8/modules/pam_access/access.conf.access-update Linux-PAM-1.1.8/modules/pam_access/access.conf
--- Linux-PAM-1.1.8/modules/pam_access/access.conf.access-update 2013-06-18 16:11:21.000000000 +0200
+++ Linux-PAM-1.1.8/modules/pam_access/access.conf 2017-09-08 14:06:16.420102221 +0200
@@ -18,7 +18,7 @@
# pam_access with X applications that provide PAM_TTY values that are
# the display variable like "host:0".]
#
-# permission : users : origins
+# permission:users:origins
#
# The first field should be a "+" (access granted) or "-" (access denied)
# character.
@@ -79,44 +79,44 @@
##############################################################################
#
# User "root" should be allowed to get access via cron .. tty5 tty6.
-#+ : root : cron crond :0 tty1 tty2 tty3 tty4 tty5 tty6
+#+:root:cron crond :0 tty1 tty2 tty3 tty4 tty5 tty6
#
# User "root" should be allowed to get access from hosts with ip addresses.
-#+ : root : 192.168.200.1 192.168.200.4 192.168.200.9
-#+ : root : 127.0.0.1
+#+:root:192.168.200.1 192.168.200.4 192.168.200.9
+#+:root:127.0.0.1
#
# User "root" should get access from network 192.168.201.
# This term will be evaluated by string matching.
# comment: It might be better to use network/netmask instead.
# The same is 192.168.201.0/24 or 192.168.201.0/255.255.255.0
-#+ : root : 192.168.201.
+#+:root:192.168.201.
#
# User "root" should be able to have access from domain.
# Uses string matching also.
-#+ : root : .foo.bar.org
+#+:root:.foo.bar.org
#
# User "root" should be denied to get access from all other sources.
-#- : root : ALL
+#-:root:ALL
#
# User "foo" and members of netgroup "nis_group" should be
# allowed to get access from all sources.
# This will only work if netgroup service is available.
-#+ : @nis_group foo : ALL
+#+:@nis_group foo:ALL
#
# User "john" should get access from ipv4 net/mask
-#+ : john : 127.0.0.0/24
+#+:john:127.0.0.0/24
#
# User "john" should get access from ipv4 as ipv6 net/mask
-#+ : john : ::ffff:127.0.0.0/127
+#+:john:::ffff:127.0.0.0/127
#
# User "john" should get access from ipv6 host address
-#+ : john : 2001:4ca0:0:101::1
+#+:john:2001:4ca0:0:101::1
#
# User "john" should get access from ipv6 host address (same as above)
-#+ : john : 2001:4ca0:0:101:0:0:0:1
+#+:john:2001:4ca0:0:101:0:0:0:1
#
# User "john" should get access from ipv6 net/mask
-#+ : john : 2001:4ca0:0:101::/64
+#+:john:2001:4ca0:0:101::/64
#
# All other users should be denied to get access from all sources.
-#- : ALL : ALL
+#-:ALL:ALL
diff -up Linux-PAM-1.1.8/modules/pam_access/access.conf.5.xml.access-update Linux-PAM-1.1.8/modules/pam_access/access.conf.5.xml
--- Linux-PAM-1.1.8/modules/pam_access/access.conf.5.xml.access-update 2013-06-18 16:11:21.000000000 +0200
+++ Linux-PAM-1.1.8/modules/pam_access/access.conf.5.xml 2017-09-08 14:05:41.126320653 +0200
@@ -21,8 +21,12 @@
<para>
The <filename>/etc/security/access.conf</filename> file specifies
(<replaceable>user/group</replaceable>, <replaceable>host</replaceable>),
- (<replaceable>user/group</replaceable>, <replaceable>network/netmask</replaceable>) or
- (<replaceable>user/group</replaceable>, <replaceable>tty</replaceable>)
+ (<replaceable>user/group</replaceable>, <replaceable>network/netmask</replaceable>),
+ (<replaceable>user/group</replaceable>, <replaceable>tty</replaceable>),
+ (<replaceable>user/group</replaceable>,
+ <replaceable>X-$DISPLAY-value</replaceable>), or
+ (<replaceable>user/group</replaceable>,
+ <replaceable>pam-service-name</replaceable>)
combinations for which a login will be either accepted or refused.
</para>
<para>
@@ -33,7 +37,14 @@
combination, or, in case of non-networked logins, the first entry
that matches the
(<replaceable>user/group</replaceable>, <replaceable>tty</replaceable>)
- combination. The permissions field of that table entry determines
+ combination, or in the case of non-networked logins without a
+ tty, the first entry that matches the
+ (<replaceable>user/group</replaceable>,
+ <replaceable>X-$DISPLAY-value</replaceable>) or
+ (<replaceable>user/group</replaceable>,
+ <replaceable>pam-service-name/</replaceable>)
+ combination. The permissions field of that table entry
+ determines
whether the login will be accepted or refused.
</para>
@@ -65,14 +76,27 @@
<para>
The third field, the <replaceable>origins</replaceable>
field, should be a list of one or more tty names (for non-networked
- logins), host names, domain names (begin with "."), host addresses,
+ logins), X <varname>$DISPLAY</varname> values or PAM service
+ names (for non-networked logins without a tty), host names,
+ domain names (begin with "."), host addresses,
internet network numbers (end with "."), internet network addresses
with network mask (where network mask can be a decimal number or an
internet address also), <emphasis>ALL</emphasis> (which always matches)
- or <emphasis>LOCAL</emphasis>. <emphasis>LOCAL</emphasis>
- keyword matches if and only if the <emphasis>PAM_RHOST</emphasis> is
- not set and &lt;origin&gt; field is thus set from
- <emphasis>PAM_TTY</emphasis> or <emphasis>PAM_SERVICE</emphasis>".
+ or <emphasis>LOCAL</emphasis>. The <emphasis>LOCAL</emphasis>
+ keyword matches if and only if
+ <citerefentry><refentrytitle>pam_get_item</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+ when called with an <parameter>item_type</parameter> of
+ <emphasis>PAM_RHOST</emphasis>, returns <code>NULL</code> or an
+ empty string (and therefore the
+ <replaceable>origins</replaceable> field is compared against the
+ return value of
+ <citerefentry><refentrytitle>pam_get_item</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+ called with an <parameter>item_type</parameter> of
+ <emphasis>PAM_TTY</emphasis> or, absent that,
+ <emphasis>PAM_SERVICE</emphasis>).
+ </para>
+
+ <para>
If supported by the system you can use
<emphasis>@netgroupname</emphasis> in host or user patterns. The
<emphasis>@@netgroupname</emphasis> syntax is supported in the user
@@ -115,7 +139,7 @@
<emphasis>tty1</emphasis>, ..., <emphasis>tty5</emphasis>,
<emphasis>tty6</emphasis>.
</para>
- <para>+ : root : crond :0 tty1 tty2 tty3 tty4 tty5 tty6</para>
+ <para>+:root:crond :0 tty1 tty2 tty3 tty4 tty5 tty6</para>
<para>
User <emphasis>root</emphasis> should be allowed to get access from
@@ -123,8 +147,8 @@
connection have to be a IPv4 one, a IPv6 connection from a host with
one of this IPv4 addresses does work, too.
</para>
- <para>+ : root : 192.168.200.1 192.168.200.4 192.168.200.9</para>
- <para>+ : root : 127.0.0.1</para>
+ <para>+:root:192.168.200.1 192.168.200.4 192.168.200.9</para>
+ <para>+:root:127.0.0.1</para>
<para>
User <emphasis>root</emphasis> should get access from network
@@ -134,44 +158,44 @@
<emphasis>192.168.201.0/24</emphasis> or
<emphasis>192.168.201.0/255.255.255.0</emphasis>.
</para>
- <para>+ : root : 192.168.201.</para>
+ <para>+:root:192.168.201.</para>
<para>
User <emphasis>root</emphasis> should be able to have access from hosts
<emphasis>foo1.bar.org</emphasis> and <emphasis>foo2.bar.org</emphasis>
(uses string matching also).
</para>
- <para>+ : root : foo1.bar.org foo2.bar.org</para>
+ <para>+:root:foo1.bar.org foo2.bar.org</para>
<para>
User <emphasis>root</emphasis> should be able to have access from
domain <emphasis>foo.bar.org</emphasis> (uses string matching also).
</para>
- <para>+ : root : .foo.bar.org</para>
+ <para>+:root:.foo.bar.org</para>
<para>
User <emphasis>root</emphasis> should be denied to get access
from all other sources.
</para>
- <para>- : root : ALL</para>
+ <para>-:root:ALL</para>
<para>
User <emphasis>foo</emphasis> and members of netgroup
<emphasis>admins</emphasis> should be allowed to get access
from all sources. This will only work if netgroup service is available.
</para>
- <para>+ : @admins foo : ALL</para>
+ <para>+:@admins foo:ALL</para>
<para>
User <emphasis>john</emphasis> and <emphasis>foo</emphasis>
should get access from IPv6 host address.
</para>
- <para>+ : john foo : 2001:db8:0:101::1</para>
+ <para>+:john foo:2001:db8:0:101::1</para>
<para>
User <emphasis>john</emphasis> should get access from IPv6 net/mask.
</para>
- <para>+ : john : 2001:db8:0:101::/64</para>
+ <para>+:john:2001:db8:0:101::/64</para>
<para>
Disallow console logins to all but the shutdown, sync and all
@@ -182,10 +206,22 @@
<para>
All other users should be denied to get access from all sources.
</para>
- <para>- : ALL : ALL</para>
+ <para>-:ALL:ALL</para>
</refsect1>
+ <refsect1 id="access.conf-notes">
+ <title>NOTES</title>
+ <para>
+ The default separators of list items in a field are space, ',', and tabulator
+ characters. Thus conveniently if spaces are put at the beginning and the end of
+ the fields they are ignored. However if the list separator is changed with the
+ <emphasis>listsep</emphasis> option, the spaces will become part of the actual
+ item and the line will be most probably ignored. For this reason, it is not
+ recommended to put spaces around the ':' characters.
+ </para>
+ </refsect1>
+
<refsect1 id="access.conf-see_also">
<title>SEE ALSO</title>
<para>
diff -up Linux-PAM-1.1.8/modules/pam_access/Makefile.am.access-update Linux-PAM-1.1.8/modules/pam_access/Makefile.am
--- Linux-PAM-1.1.8/modules/pam_access/Makefile.am.access-update 2013-06-18 16:11:21.000000000 +0200
+++ Linux-PAM-1.1.8/modules/pam_access/Makefile.am 2017-09-08 14:10:47.223163175 +0200
@@ -15,7 +15,8 @@ securelibdir = $(SECUREDIR)
secureconfdir = $(SCONFIGDIR)
AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
- -DPAM_ACCESS_CONFIG=\"$(SCONFIGDIR)/access.conf\" $(NIS_CFLAGS)
+ -DPAM_ACCESS_CONFIG=\"$(SCONFIGDIR)/access.conf\" \
+ -DACCESS_CONF_GLOB=\"$(SCONFIGDIR)/access.d/*.conf\" $(NIS_CFLAGS)
AM_LDFLAGS = -no-undefined -avoid-version -module
if HAVE_VERSIONING
AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
diff -up Linux-PAM-1.1.8/modules/pam_access/pam_access.c.access-update Linux-PAM-1.1.8/modules/pam_access/pam_access.c
--- Linux-PAM-1.1.8/modules/pam_access/pam_access.c.access-update 2013-06-18 16:11:21.000000000 +0200
+++ Linux-PAM-1.1.8/modules/pam_access/pam_access.c 2017-09-08 14:03:45.620762824 +0200
@@ -44,6 +44,7 @@
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/socket.h>
+#include <glob.h>
#ifdef HAVE_RPCSVC_YPCLNT_H
#include <rpcsvc/ypclnt.h>
#endif
@@ -90,6 +91,7 @@
#define ALL 2
#define YES 1
#define NO 0
+#define NOMATCH -1
/*
* A structure to bundle up all login-related information to keep the
@@ -412,13 +414,17 @@ login_access (pam_handle_t *pamh, struct
return NO;
}
#ifdef HAVE_LIBAUDIT
- if (!item->noaudit && line[0] == '-' && (match == YES || (match == ALL &&
- nonall_match == YES))) {
+ if (!item->noaudit && (match == YES || (match == ALL &&
+ nonall_match == YES)) && line[0] == '-') {
pam_modutil_audit_write(pamh, AUDIT_ANOM_LOGIN_LOCATION,
"pam_access", 0);
}
#endif
- return (match == NO || (line[0] == '+'));
+ if (match == NO)
+ return NOMATCH;
+ if (line[0] == '+')
+ return YES;
+ return NO;
}
@@ -524,7 +530,9 @@ user_match (pam_handle_t *pamh, char *to
/* Try to split on a pattern (@*[^@]+)(@+.*) */
for (at = tok; *at == '@'; ++at);
- if ((at = strchr(at, '@')) != NULL) {
+ if (tok[0] == '(' && tok[strlen(tok) - 1] == ')') {
+ return (group_match (pamh, tok, string, item->debug));
+ } else if ((at = strchr(at, '@')) != NULL) {
/* split user@host pattern */
if (item->hostname == NULL)
return NO;
@@ -549,9 +557,7 @@ user_match (pam_handle_t *pamh, char *to
hostname = item->hostname;
}
return (netgroup_match (pamh, tok + 1, hostname, string, item->debug));
- } else if (tok[0] == '(' && tok[strlen(tok) - 1] == ')')
- return (group_match (pamh, tok, string, item->debug));
- else if ((rv=string_match (pamh, tok, string, item->debug)) != NO) /* ALL or exact match */
+ } else if ((rv=string_match (pamh, tok, string, item->debug)) != NO) /* ALL or exact match */
return rv;
else if (item->only_new_group_syntax == NO &&
pam_modutil_user_in_group_nam_nam (pamh,
@@ -573,7 +579,7 @@ group_match (pam_handle_t *pamh, const c
if (debug)
pam_syslog (pamh, LOG_DEBUG,
- "group_match: grp=%s, user=%s", grptok, usr);
+ "group_match: grp=%s, user=%s", tok, usr);
if (strlen(tok) < 3)
return NO;
@@ -808,6 +814,7 @@ pam_sm_authenticate (pam_handle_t *pamh,
const char *user=NULL;
const void *void_from=NULL;
const char *from;
+ const char const *default_config = PAM_ACCESS_CONFIG;
struct passwd *user_pw;
char hostname[MAXHOSTNAMELEN + 1];
int rv;
@@ -829,7 +836,7 @@ pam_sm_authenticate (pam_handle_t *pamh,
*/
memset(&loginfo, '\0', sizeof(loginfo));
loginfo.user = user_pw;
- loginfo.config_file = PAM_ACCESS_CONFIG;
+ loginfo.config_file = default_config;
/* parse the argument list */
@@ -900,6 +907,26 @@ pam_sm_authenticate (pam_handle_t *pamh,
rv = login_access(pamh, &loginfo);
+ if (rv == NOMATCH && loginfo.config_file == default_config) {
+ glob_t globbuf;
+ int i, glob_rv;
+
+ /* We do not manipulate locale as setlocale() is not
+ * thread safe. We could use uselocale() in future.
+ */
+ glob_rv = glob(ACCESS_CONF_GLOB, GLOB_ERR, NULL, &globbuf);
+ if (!glob_rv) {
+ /* Parse the *.conf files. */
+ for (i = 0; globbuf.gl_pathv[i] != NULL; i++) {
+ loginfo.config_file = globbuf.gl_pathv[i];
+ rv = login_access(pamh, &loginfo);
+ if (rv != NOMATCH)
+ break;
+ }
+ globfree(&globbuf);
+ }
+ }
+
if (loginfo.gai_rv == 0 && loginfo.res)
freeaddrinfo(loginfo.res);
diff -up Linux-PAM-1.1.8/modules/pam_access/pam_access.8.xml.access-update Linux-PAM-1.1.8/modules/pam_access/pam_access.8.xml
--- Linux-PAM-1.1.8/modules/pam_access/pam_access.8.xml.access-update 2013-06-18 16:11:21.000000000 +0200
+++ Linux-PAM-1.1.8/modules/pam_access/pam_access.8.xml 2017-09-08 14:04:25.365642960 +0200
@@ -50,16 +50,25 @@
The pam_access PAM module is mainly for access management.
It provides logdaemon style login access control based on login
names, host or domain names, internet addresses or network numbers,
- or on terminal line names in case of non-networked logins.
+ or on terminal line names, X <varname>$DISPLAY</varname> values,
+ or PAM service names in case of non-networked logins.
</para>
<para>
By default rules for access management are taken from config file
<filename>/etc/security/access.conf</filename> if you don't specify
another file.
+ Then individual <filename>*.conf</filename> files from the
+ <filename>/etc/security/access.d/</filename> directory are read.
+ The files are parsed one after another in the order of the system locale.
+ The effect of the individual files is the same as if all the files were
+ concatenated together in the order of parsing. This means that once
+ a pattern is matched in some file no further files are parsed.
+ If a config file is explicitly specified with the <option>accessfile</option>
+ option the files in the above directory are not parsed.
</para>
<para>
If Linux PAM is compiled with audit support the module will report
- when it denies access based on origin (host or tty).
+ when it denies access based on origin (host, tty, etc.).
</para>
</refsect1>

435
SOURCES/pam-1.1.8-audit-grantor.patch

@ -0,0 +1,435 @@ @@ -0,0 +1,435 @@
From 0d29e379601819c7f7ed8de18b54de803a9f4049 Mon Sep 17 00:00:00 2001
From: Tomas Mraz <tmraz@fedoraproject.org>
Date: Fri, 5 Sep 2014 09:09:37 +0200
Subject: [PATCH] Add grantor field to audit records of libpam.

The grantor field gives audit trail of PAM modules which granted access
for successful return from libpam calls. In case of failed return
the grantor field is set to '?'.
libpam/pam_account.c (pam_acct_mgmt): Remove _pam_auditlog() call.
libpam/pam_auth.c (pam_authenticate, pam_setcred): Likewise.
libpam/pam_password.c (pam_chauthtok): Likewise.
libpam/pam_session.c (pam_open_session, pam_close_session): Likewise.
libpam/pam_audit.c (_pam_audit_writelog): Add grantors parameter,
add grantor= field to the message if grantors is set.
(_pam_list_grantors): New function creating the string with grantors list.
(_pam_auditlog): Add struct handler pointer parameter, call _pam_list_grantors()
to list the grantors from the handler list.
(_pam_audit_end): Add NULL handler parameter to _pam_auditlog() call.
(pam_modutil_audit_write): Add NULL grantors parameter to _pam_audit_writelog().
libpam/pam_dispatch.c (_pam_dispatch_aux): Set h->grantor where appropriate.
(_pam_clear_grantors): New function to clear grantor field of handler.
(_pam_dispatch): Call _pam_clear_grantors() before executing the stack.
Call _pam_auditlog() when appropriate.
libpam/pam_handlers.c (extract_modulename): Do not allow empty module name
or just "?" to avoid confusing audit trail.
(_pam_add_handler): Test for NULL return from extract_modulename().
Clear grantor field of handler.
libpam/pam_private.h: Add grantor field to struct handler, add handler pointer
parameter to _pam_auditlog().
---
libpam/pam_account.c | 4 ---
libpam/pam_audit.c | 84 +++++++++++++++++++++++++++++++++++++++++++--------
libpam/pam_auth.c | 8 -----
libpam/pam_dispatch.c | 41 ++++++++++++++++++++-----
libpam/pam_handlers.c | 14 +++++++--
libpam/pam_password.c | 4 ---
libpam/pam_private.h | 3 +-
libpam/pam_session.c | 7 -----
8 files changed, 119 insertions(+), 46 deletions(-)

diff --git a/libpam/pam_account.c b/libpam/pam_account.c
index 572acc4..3a4fb1f 100644
--- a/libpam/pam_account.c
+++ b/libpam/pam_account.c
@@ -19,9 +19,5 @@ int pam_acct_mgmt(pam_handle_t *pamh, int flags)
retval = _pam_dispatch(pamh, flags, PAM_ACCOUNT);
-#ifdef HAVE_LIBAUDIT
- retval = _pam_auditlog(pamh, PAM_ACCOUNT, retval, flags);
-#endif
-
return retval;
}
diff --git a/libpam/pam_audit.c b/libpam/pam_audit.c
index 531746a..24fb799 100644
--- a/libpam/pam_audit.c
+++ b/libpam/pam_audit.c
@@ -6,12 +6,12 @@
Authors:
Steve Grubb <sgrubb@redhat.com> */
-#include <stdio.h>
-#include <syslog.h>
#include "pam_private.h"
#include "pam_modutil_private.h"
#ifdef HAVE_LIBAUDIT
+#include <stdio.h>
+#include <syslog.h>
#include <libaudit.h>
#include <pwd.h>
#include <netdb.h>
@@ -25,17 +25,24 @@
static int
_pam_audit_writelog(pam_handle_t *pamh, int audit_fd, int type,
- const char *message, int retval)
+ const char *message, const char *grantors, int retval)
{
static int old_errno = -1;
- int rc;
- char buf[32];
+ int rc = -ENOMEM;
+ char *buf;
+ const char *grantors_field = " grantors=";
- snprintf(buf, sizeof(buf), "PAM:%s", message);
+ if (grantors == NULL) {
+ grantors = "";
+ grantors_field = "";
+ }
- rc = audit_log_acct_message (audit_fd, type, NULL, buf,
- (retval != PAM_USER_UNKNOWN && pamh->user) ? pamh->user : "?",
- -1, pamh->rhost, NULL, pamh->tty, retval == PAM_SUCCESS );
+ if (asprintf(&buf, "PAM:%s%s%s", message, grantors_field, grantors) >= 0) {
+ rc = audit_log_acct_message(audit_fd, type, NULL, buf,
+ (retval != PAM_USER_UNKNOWN && pamh->user) ? pamh->user : "?",
+ -1, pamh->rhost, NULL, pamh->tty, retval == PAM_SUCCESS);
+ free(buf);
+ }
/* libaudit sets errno to his own negative error code. This can be
an official errno number, but must not. It can also be a audit
@@ -78,12 +85,54 @@ _pam_audit_open(pam_handle_t *pamh)
return audit_fd;
}
+static int
+_pam_list_grantors(struct handler *hlist, int retval, char **list)
+{
+ *list = NULL;
+
+ if (retval == PAM_SUCCESS) {
+ struct handler *h;
+ char *p = NULL;
+ size_t len = 0;
+
+ for (h = hlist; h != NULL; h = h->next) {
+ if (h->grantor) {
+ len += strlen(h->mod_name) + 1;
+ }
+ }
+
+ if (len == 0) {
+ return 0;
+ }
+
+ *list = malloc(len);
+ if (*list == NULL) {
+ return -1;
+ }
+
+ for (h = hlist; h != NULL; h = h->next) {
+ if (h->grantor) {
+ if (p == NULL) {
+ p = *list;
+ } else {
+ p = stpcpy(p, ",");
+ }
+
+ p = stpcpy(p, h->mod_name);
+ }
+ }
+ }
+
+ return 0;
+}
+
int
-_pam_auditlog(pam_handle_t *pamh, int action, int retval, int flags)
+_pam_auditlog(pam_handle_t *pamh, int action, int retval, int flags, struct handler *h)
{
const char *message;
int type;
int audit_fd;
+ char *grantors;
if ((audit_fd=_pam_audit_open(pamh)) == -1) {
return PAM_SYSTEM_ERR;
@@ -134,8 +183,17 @@ _pam_auditlog(pam_handle_t *pamh, int action, int retval, int flags)
retval = PAM_SYSTEM_ERR;
}
- if (_pam_audit_writelog(pamh, audit_fd, type, message, retval) < 0)
+ if (_pam_list_grantors(h, retval, &grantors) < 0) {
+ /* allocation failure */
+ pam_syslog(pamh, LOG_CRIT, "_pam_list_grantors() failed: %m");
retval = PAM_SYSTEM_ERR;
+ }
+
+ if (_pam_audit_writelog(pamh, audit_fd, type, message,
+ grantors ? grantors : "?", retval) < 0)
+ retval = PAM_SYSTEM_ERR;
+
+ free(grantors);
audit_close(audit_fd);
return retval;
@@ -149,7 +207,7 @@ _pam_audit_end(pam_handle_t *pamh, int status UNUSED)
* stacks having been run. Assume that this is sshd faking
* things for an unknown user.
*/
- _pam_auditlog(pamh, _PAM_ACTION_DONE, PAM_USER_UNKNOWN, 0);
+ _pam_auditlog(pamh, _PAM_ACTION_DONE, PAM_USER_UNKNOWN, 0, NULL);
}
return 0;
@@ -168,7 +226,7 @@ pam_modutil_audit_write(pam_handle_t *pamh, int type,
return retval;
}
- rc = _pam_audit_writelog(pamh, audit_fd, type, message, retval);
+ rc = _pam_audit_writelog(pamh, audit_fd, type, message, NULL, retval);
audit_close(audit_fd);
diff --git a/libpam/pam_auth.c b/libpam/pam_auth.c
index 5984fa5..1e7bc6e 100644
--- a/libpam/pam_auth.c
+++ b/libpam/pam_auth.c
@@ -45,10 +45,6 @@ int pam_authenticate(pam_handle_t *pamh, int flags)
prelude_send_alert(pamh, retval);
#endif
-#ifdef HAVE_LIBAUDIT
- retval = _pam_auditlog(pamh, PAM_AUTHENTICATE, retval, flags);
-#endif
-
return retval;
}
@@ -71,10 +67,6 @@ int pam_setcred(pam_handle_t *pamh, int flags)
retval = _pam_dispatch(pamh, flags, PAM_SETCRED);
-#ifdef HAVE_LIBAUDIT
- retval = _pam_auditlog(pamh, PAM_SETCRED, retval, flags);
-#endif
-
D(("pam_setcred exit"));
return retval;
diff --git a/libpam/pam_dispatch.c b/libpam/pam_dispatch.c
index eb52c82..cf632e8 100644
--- a/libpam/pam_dispatch.c
+++ b/libpam/pam_dispatch.c
@@ -217,8 +217,14 @@ static int _pam_dispatch_aux(pam_handle_t *pamh, int flags, struct handler *h,
status = retval;
}
}
- if ( impression == _PAM_POSITIVE && action == _PAM_ACTION_DONE ) {
- goto decision_made;
+ if ( impression == _PAM_POSITIVE ) {
+ if ( retval == PAM_SUCCESS ) {
+ h->grantor = 1;
+ }
+
+ if ( action == _PAM_ACTION_DONE ) {
+ goto decision_made;
+ }
}
break;
@@ -262,6 +268,9 @@ static int _pam_dispatch_aux(pam_handle_t *pamh, int flags, struct handler *h,
|| (impression == _PAM_POSITIVE
&& status == PAM_SUCCESS) ) {
if ( retval != PAM_IGNORE || cached_retval == retval ) {
+ if ( impression == _PAM_UNDEF && retval == PAM_SUCCESS ) {
+ h->grantor = 1;
+ }
impression = _PAM_POSITIVE;
status = retval;
}
@@ -308,6 +317,13 @@ decision_made: /* by getting here we have made a decision */
return status;
}
+static void _pam_clear_grantors(struct handler *h)
+{
+ for (; h != NULL; h = h->next) {
+ h->grantor = 0;
+ }
+}
+
/*
* This function translates the module dispatch request into a pointer
* to the stack of modules that will actually be run. the
@@ -318,21 +334,21 @@ decision_made: /* by getting here we have made a decision */
int _pam_dispatch(pam_handle_t *pamh, int flags, int choice)
{
struct handler *h = NULL;
- int retval, use_cached_chain;
+ int retval = PAM_SYSTEM_ERR, use_cached_chain;
_pam_boolean resumed;
IF_NO_PAMH("_pam_dispatch", pamh, PAM_SYSTEM_ERR);
if (__PAM_FROM_MODULE(pamh)) {
D(("called from a module!?"));
- return PAM_SYSTEM_ERR;
+ goto end;
}
/* Load all modules, resolve all symbols */
if ((retval = _pam_init_handlers(pamh)) != PAM_SUCCESS) {
pam_syslog(pamh, LOG_ERR, "unable to dispatch function");
- return retval;
+ goto end;
}
use_cached_chain = _PAM_PLEASE_FREEZE;
@@ -360,7 +376,8 @@ int _pam_dispatch(pam_handle_t *pamh, int flags, int choice)
break;
default:
pam_syslog(pamh, LOG_ERR, "undefined fn choice; %d", choice);
- return PAM_ABORT;
+ retval = PAM_ABORT;
+ goto end;
}
if (h == NULL) { /* there was no handlers.conf... entry; will use
@@ -393,11 +410,13 @@ int _pam_dispatch(pam_handle_t *pamh, int flags, int choice)
pam_syslog(pamh, LOG_ERR,
"application failed to re-exec stack [%d:%d]",
pamh->former.choice, choice);
- return PAM_ABORT;
+ retval = PAM_ABORT;
+ goto end;
}
resumed = PAM_TRUE;
} else {
resumed = PAM_FALSE;
+ _pam_clear_grantors(h);
}
__PAM_TO_MODULE(pamh);
@@ -417,5 +436,13 @@ int _pam_dispatch(pam_handle_t *pamh, int flags, int choice)
pamh->former.choice = PAM_NOT_STACKED;
}
+end:
+
+#ifdef HAVE_LIBAUDIT
+ if (choice != PAM_CHAUTHTOK || flags & PAM_UPDATE_AUTHTOK || retval != PAM_SUCCESS) {
+ retval = _pam_auditlog(pamh, choice, retval, flags, h);
+ }
+#endif
+
return retval;
}
diff --git a/libpam/pam_handlers.c b/libpam/pam_handlers.c
index 02714f7..df3a1d9 100644
--- a/libpam/pam_handlers.c
+++ b/libpam/pam_handlers.c
@@ -611,6 +611,12 @@ extract_modulename(const char *mod_path)
if (dot)
*dot = '\0';
+ if (*retval == '\0' || strcmp(retval, "?") == 0) {
+ /* do not allow empty module name or "?" to avoid confusing audit trail */
+ _pam_drop(retval);
+ return NULL;
+ }
+
return retval;
}
@@ -888,7 +894,9 @@ int _pam_add_handler(pam_handle_t *pamh
(*handler_p)->cached_retval_p = &((*handler_p)->cached_retval);
(*handler_p)->argc = argc;
(*handler_p)->argv = argv; /* not a copy */
- (*handler_p)->mod_name = extract_modulename(mod_path);
+ if (((*handler_p)->mod_name = extract_modulename(mod_path)) == NULL)
+ return PAM_ABORT;
+ (*handler_p)->grantor = 0;
(*handler_p)->next = NULL;
/* some of the modules have a second calling function */
@@ -920,7 +928,9 @@ int _pam_add_handler(pam_handle_t *pamh
} else {
(*handler_p2)->argv = NULL; /* no arguments */
}
- (*handler_p2)->mod_name = extract_modulename(mod_path);
+ if (((*handler_p2)->mod_name = extract_modulename(mod_path)) == NULL)
+ return PAM_ABORT;
+ (*handler_p2)->grantor = 0;
(*handler_p2)->next = NULL;
}
diff --git a/libpam/pam_password.c b/libpam/pam_password.c
index 75db5e5..592e01f 100644
--- a/libpam/pam_password.c
+++ b/libpam/pam_password.c
@@ -57,9 +57,5 @@ int pam_chauthtok(pam_handle_t *pamh, int flags)
D(("will resume when ready", retval));
}
-#ifdef HAVE_LIBAUDIT
- retval = _pam_auditlog(pamh, PAM_CHAUTHTOK, retval, flags);
-#endif
-
return retval;
}
diff --git a/libpam/pam_private.h b/libpam/pam_private.h
index 134dc72..d93283c 100644
--- a/libpam/pam_private.h
+++ b/libpam/pam_private.h
@@ -55,6 +55,7 @@ struct handler {
struct handler *next;
char *mod_name;
int stack_level;
+ int grantor;
};
#define PAM_HT_MODULE 0
@@ -316,7 +317,7 @@ if ((pamh) == NULL) { \
do { (pamh)->caller_is = _PAM_CALLED_FROM_APP; } while (0)
#ifdef HAVE_LIBAUDIT
-extern int _pam_auditlog(pam_handle_t *pamh, int action, int retval, int flags);
+extern int _pam_auditlog(pam_handle_t *pamh, int action, int retval, int flags, struct handler *h);
extern int _pam_audit_end(pam_handle_t *pamh, int pam_status);
#endif
diff --git a/libpam/pam_session.c b/libpam/pam_session.c
index 512153f..cb393c1 100644
--- a/libpam/pam_session.c
+++ b/libpam/pam_session.c
@@ -22,9 +22,6 @@ int pam_open_session(pam_handle_t *pamh, int flags)
}
retval = _pam_dispatch(pamh, flags, PAM_OPEN_SESSION);
-#ifdef HAVE_LIBAUDIT
- retval = _pam_auditlog(pamh, PAM_OPEN_SESSION, retval, flags);
-#endif
return retval;
}
@@ -43,10 +40,6 @@ int pam_close_session(pam_handle_t *pamh, int flags)
retval = _pam_dispatch(pamh, flags, PAM_CLOSE_SESSION);
-#ifdef HAVE_LIBAUDIT
- retval = _pam_auditlog(pamh, PAM_CLOSE_SESSION, retval, flags);
-#endif
-
return retval;
}
--
1.8.3.1

47
SOURCES/pam-1.1.8-audit-user-mgmt.patch

@ -0,0 +1,47 @@ @@ -0,0 +1,47 @@
diff -urp Linux-PAM-1.1.8.orig/modules/pam_faillock/main.c Linux-PAM-1.1.8/modules/pam_faillock/main.c
--- Linux-PAM-1.1.8.orig/modules/pam_faillock/main.c 2014-10-16 10:12:57.117554380 -0400
+++ Linux-PAM-1.1.8/modules/pam_faillock/main.c 2014-10-16 10:38:00.199510093 -0400
@@ -141,10 +141,8 @@ do_user(struct options *opts, const char
if ((audit_fd=audit_open()) >= 0) {
if (pwd != NULL) {
- snprintf(buf, sizeof(buf), "faillock reset uid=%u",
- pwd->pw_uid);
- audit_log_user_message(audit_fd, AUDIT_USER_ACCT,
- buf, NULL, NULL, NULL, rv == 0);
+ audit_log_acct_message(audit_fd, AUDIT_USER_MGMT, NULL,
+ "faillock-reset", NULL, pwd->pw_uid, NULL, NULL, NULL, rv == 0);
}
close(audit_fd);
}
diff -urp Linux-PAM-1.1.8.orig/modules/pam_tally2/pam_tally2.c Linux-PAM-1.1.8/modules/pam_tally2/pam_tally2.c
--- Linux-PAM-1.1.8.orig/modules/pam_tally2/pam_tally2.c 2013-06-18 10:11:21.000000000 -0400
+++ Linux-PAM-1.1.8/modules/pam_tally2/pam_tally2.c 2014-10-16 10:37:05.072511717 -0400
@@ -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

21
SOURCES/pam-1.1.8-canonicalize-username.patch

@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
diff -up Linux-PAM-1.1.8/modules/pam_selinux/pam_selinux.c.canonicalize Linux-PAM-1.1.8/modules/pam_selinux/pam_selinux.c
--- Linux-PAM-1.1.8/modules/pam_selinux/pam_selinux.c.canonicalize 2013-06-18 16:11:21.000000000 +0200
+++ Linux-PAM-1.1.8/modules/pam_selinux/pam_selinux.c 2014-03-06 12:03:54.429639972 +0100
@@ -491,12 +491,17 @@ compute_exec_context(pam_handle_t *pamh,
char *level = NULL;
security_context_t *contextlist = NULL;
int num_contexts = 0;
+ const struct passwd *pwd;
if (!(username = get_item(pamh, PAM_USER))) {
pam_syslog(pamh, LOG_ERR, "Cannot obtain the user name");
return PAM_USER_UNKNOWN;
}
+ if ((pwd = pam_modutil_getpwnam(pamh, username)) != NULL) {
+ username = pwd->pw_name;
+ } /* ignore error and keep using original username */
+
/* compute execute context */
#ifdef HAVE_GETSEUSER
if (!(service = get_item(pamh, PAM_SERVICE))) {

52
SOURCES/pam-1.1.8-cve-2013-7041.patch

@ -0,0 +1,52 @@ @@ -0,0 +1,52 @@
From 57a1e2b274d0a6376d92ada9926e5c5741e7da20 Mon Sep 17 00:00:00 2001
From: "Dmitry V. Levin" <ldv@altlinux.org>
Date: Fri, 24 Jan 2014 22:18:32 +0000
Subject: [PATCH] pam_userdb: fix password hash comparison

Starting with commit Linux-PAM-0-77-28-g0b3e583 that introduced hashed
passwords support in pam_userdb, hashes are compared case-insensitively.
This bug leads to accepting hashes for completely different passwords in
addition to those that should be accepted.

Additionally, commit Linux-PAM-1_1_6-13-ge2a8187 that added support for
modern password hashes with different lengths and settings, did not
update the hash comparison accordingly, which leads to accepting
computed hashes longer than stored hashes when the latter is a prefix
of the former.

* modules/pam_userdb/pam_userdb.c (user_lookup): Reject the computed
hash whose length differs from the stored hash length.
Compare computed and stored hashes case-sensitively.
Fixes CVE-2013-7041.

Bug-Debian: http://bugs.debian.org/731368
---
modules/pam_userdb/pam_userdb.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/modules/pam_userdb/pam_userdb.c b/modules/pam_userdb/pam_userdb.c
index de8b5b1..ff040e6 100644
--- a/modules/pam_userdb/pam_userdb.c
+++ b/modules/pam_userdb/pam_userdb.c
@@ -222,12 +222,15 @@ user_lookup (pam_handle_t *pamh, const char *database, const char *cryptmode,
} else {
cryptpw = crypt (pass, data.dptr);
- if (cryptpw) {
- compare = strncasecmp (data.dptr, cryptpw, data.dsize);
+ if (cryptpw && strlen(cryptpw) == (size_t)data.dsize) {
+ compare = memcmp(data.dptr, cryptpw, data.dsize);
} else {
compare = -2;
if (ctrl & PAM_DEBUG_ARG) {
- pam_syslog(pamh, LOG_INFO, "crypt() returned NULL");
+ if (cryptpw)
+ pam_syslog(pamh, LOG_INFO, "lengths of computed and stored hashes differ");
+ else
+ pam_syslog(pamh, LOG_INFO, "crypt() returned NULL");
}
};
--
1.8.3.1

56
SOURCES/pam-1.1.8-cve-2014-2583.patch

@ -0,0 +1,56 @@ @@ -0,0 +1,56 @@
From 9dcead87e6d7f66d34e7a56d11a30daca367dffb Mon Sep 17 00:00:00 2001
From: "Dmitry V. Levin" <ldv@altlinux.org>
Date: Wed, 26 Mar 2014 22:17:23 +0000
Subject: [PATCH] pam_timestamp: fix potential directory traversal issue
(ticket #27)

pam_timestamp uses values of PAM_RUSER and PAM_TTY as components of
the timestamp pathname it creates, so extra care should be taken to
avoid potential directory traversal issues.

* modules/pam_timestamp/pam_timestamp.c (check_tty): Treat
"." and ".." tty values as invalid.
(get_ruser): Treat "." and ".." ruser values, as well as any ruser
value containing '/', as invalid.

Fixes CVE-2014-2583.

Reported-by: Sebastian Krahmer <krahmer@suse.de>
---
modules/pam_timestamp/pam_timestamp.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/modules/pam_timestamp/pam_timestamp.c b/modules/pam_timestamp/pam_timestamp.c
index 5193733..b3f08b1 100644
--- a/modules/pam_timestamp/pam_timestamp.c
+++ b/modules/pam_timestamp/pam_timestamp.c
@@ -158,7 +158,7 @@ check_tty(const char *tty)
tty = strrchr(tty, '/') + 1;
}
/* Make sure the tty wasn't actually a directory (no basename). */
- if (strlen(tty) == 0) {
+ if (!strlen(tty) || !strcmp(tty, ".") || !strcmp(tty, "..")) {
return NULL;
}
return tty;
@@ -243,6 +243,17 @@ get_ruser(pam_handle_t *pamh, char *ruserbuf, size_t ruserbuflen)
if (pwd != NULL) {
ruser = pwd->pw_name;
}
+ } else {
+ /*
+ * This ruser is used by format_timestamp_name as a component
+ * of constructed timestamp pathname, so ".", "..", and '/'
+ * are disallowed to avoid potential path traversal issues.
+ */
+ if (!strcmp(ruser, ".") ||
+ !strcmp(ruser, "..") ||
+ strchr(ruser, '/')) {
+ ruser = NULL;
+ }
}
if (ruser == NULL || strlen(ruser) >= ruserbuflen) {
*ruserbuf = '\0';
--
1.8.3.1

130
SOURCES/pam-1.1.8-cve-2015-3238.patch

@ -0,0 +1,130 @@ @@ -0,0 +1,130 @@
diff -up linux-pam/modules/pam_exec/pam_exec.c.password-limit linux-pam/modules/pam_exec/pam_exec.c
--- linux-pam/modules/pam_exec/pam_exec.c.password-limit 2014-08-26 14:02:19.000000000 +0200
+++ linux-pam/modules/pam_exec/pam_exec.c 2015-06-11 16:10:13.938035623 +0200
@@ -178,11 +178,11 @@ call_exec (const char *pam_type, pam_han
}
pam_set_item (pamh, PAM_AUTHTOK, resp);
- authtok = strdupa (resp);
+ authtok = strndupa (resp, PAM_MAX_RESP_SIZE);
_pam_drop (resp);
}
else
- authtok = void_pass;
+ authtok = strndupa (void_pass, PAM_MAX_RESP_SIZE);
if (pipe(fds) != 0)
{
diff -up linux-pam/modules/pam_exec/pam_exec.8.xml.password-limit linux-pam/modules/pam_exec/pam_exec.8.xml
--- linux-pam/modules/pam_exec/pam_exec.8.xml.password-limit 2013-09-11 13:59:00.072175034 +0200
+++ linux-pam/modules/pam_exec/pam_exec.8.xml 2015-06-11 16:09:06.446512718 +0200
@@ -106,7 +106,8 @@
During authentication the calling command can read
the password from <citerefentry>
<refentrytitle>stdin</refentrytitle><manvolnum>3</manvolnum>
- </citerefentry>.
+ </citerefentry>. Only first <emphasis>PAM_MAX_RESP_SIZE</emphasis>
+ bytes of a password are provided to the command.
</para>
</listitem>
</varlistentry>
diff -up linux-pam/modules/pam_unix/pam_unix_passwd.c.password-limit linux-pam/modules/pam_unix/pam_unix_passwd.c
--- linux-pam/modules/pam_unix/pam_unix_passwd.c.password-limit 2014-06-19 13:50:08.000000000 +0200
+++ linux-pam/modules/pam_unix/pam_unix_passwd.c 2015-06-11 16:34:02.226260435 +0200
@@ -240,15 +240,22 @@ static int _unix_run_update_binary(pam_h
/* wait for child */
/* if the stored password is NULL */
int rc=0;
- if (fromwhat)
- pam_modutil_write(fds[1], fromwhat, strlen(fromwhat)+1);
- else
- pam_modutil_write(fds[1], "", 1);
- if (towhat) {
- pam_modutil_write(fds[1], towhat, strlen(towhat)+1);
+ if (fromwhat) {
+ int len = strlen(fromwhat);
+
+ if (len > PAM_MAX_RESP_SIZE)
+ len = PAM_MAX_RESP_SIZE;
+ pam_modutil_write(fds[1], fromwhat, len);
}
- else
- pam_modutil_write(fds[1], "", 1);
+ pam_modutil_write(fds[1], "", 1);
+ if (towhat) {
+ int len = strlen(towhat);
+
+ if (len > PAM_MAX_RESP_SIZE)
+ len = PAM_MAX_RESP_SIZE;
+ pam_modutil_write(fds[1], towhat, len);
+ }
+ pam_modutil_write(fds[1], "", 1);
close(fds[0]); /* close here to avoid possible SIGPIPE above */
close(fds[1]);
diff -up linux-pam/modules/pam_unix/pam_unix.8.xml.password-limit linux-pam/modules/pam_unix/pam_unix.8.xml
--- linux-pam/modules/pam_unix/pam_unix.8.xml.password-limit 2015-06-11 15:46:55.000000000 +0200
+++ linux-pam/modules/pam_unix/pam_unix.8.xml 2015-06-11 16:38:42.628587102 +0200
@@ -80,6 +80,13 @@
</para>
<para>
+ The maximum length of a password supported by the pam_unix module
+ via the helper binary is <emphasis>PAM_MAX_RESP_SIZE</emphasis>
+ - currently 512 bytes. The rest of the password provided by the
+ conversation function to the module will be ignored.
+ </para>
+
+ <para>
The password component of this module performs the task of updating
the user's password. The default encryption hash is taken from the
<emphasis remap='B'>ENCRYPT_METHOD</emphasis> variable from
diff -up linux-pam/modules/pam_unix/passverify.c.password-limit linux-pam/modules/pam_unix/passverify.c
--- linux-pam/modules/pam_unix/passverify.c.password-limit 2015-04-07 10:23:50.000000000 +0200
+++ linux-pam/modules/pam_unix/passverify.c 2015-06-15 10:53:32.903900010 +0200
@@ -1115,12 +1115,15 @@ getuidname(uid_t uid)
int
read_passwords(int fd, int npass, char **passwords)
{
+ /* The passwords array must contain npass preallocated
+ * buffers of length MAXPASS + 1
+ */
int rbytes = 0;
int offset = 0;
int i = 0;
char *pptr;
while (npass > 0) {
- rbytes = read(fd, passwords[i]+offset, MAXPASS-offset);
+ rbytes = read(fd, passwords[i]+offset, MAXPASS+1-offset);
if (rbytes < 0) {
if (errno == EINTR) continue;
diff -up linux-pam/modules/pam_unix/passverify.h.password-limit linux-pam/modules/pam_unix/passverify.h
--- linux-pam/modules/pam_unix/passverify.h.password-limit 2011-03-21 21:59:22.000000000 +0100
+++ linux-pam/modules/pam_unix/passverify.h 2015-06-11 16:26:27.184994387 +0200
@@ -8,7 +8,7 @@
#define PAM_UNIX_RUN_HELPER PAM_CRED_INSUFFICIENT
-#define MAXPASS 200 /* the maximum length of a password */
+#define MAXPASS PAM_MAX_RESP_SIZE /* the maximum length of a password */
#define OLD_PASSWORDS_FILE "/etc/security/opasswd"
diff -up linux-pam/modules/pam_unix/support.c.password-limit linux-pam/modules/pam_unix/support.c
--- linux-pam/modules/pam_unix/support.c.password-limit 2014-01-27 18:08:28.000000000 +0100
+++ linux-pam/modules/pam_unix/support.c 2015-06-11 16:30:35.452595477 +0200
@@ -609,7 +609,12 @@ static int _unix_run_helper_binary(pam_h
/* if the stored password is NULL */
int rc=0;
if (passwd != NULL) { /* send the password to the child */
- if (write(fds[1], passwd, strlen(passwd)+1) == -1) {
+ int len = strlen(passwd);
+
+ if (len > PAM_MAX_RESP_SIZE)
+ len = PAM_MAX_RESP_SIZE;
+ if (write(fds[1], passwd, len) == -1 ||
+ write(fds[1], "", 1) == -1) {
pam_syslog (pamh, LOG_ERR, "Cannot send password to helper: %m");
retval = PAM_AUTH_ERR;
}

151
SOURCES/pam-1.1.8-faillock-admin-group.patch

@ -0,0 +1,151 @@ @@ -0,0 +1,151 @@
diff -up Linux-PAM-1.1.8/modules/pam_faillock/pam_faillock.c.admin-group Linux-PAM-1.1.8/modules/pam_faillock/pam_faillock.c
--- Linux-PAM-1.1.8/modules/pam_faillock/pam_faillock.c.admin-group 2016-04-22 15:25:57.673445386 +0200
+++ Linux-PAM-1.1.8/modules/pam_faillock/pam_faillock.c 2017-09-08 14:39:47.411306464 +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,17 +278,14 @@ 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];
int audit_fd;
+ const void *rhost = NULL, *tty = NULL;
audit_fd = audit_open();
/* If there is an error & audit support is in the kernel report error */
@@ -280,9 +293,11 @@ check_tally(pam_handle_t *pamh, struct o
errno == EAFNOSUPPORT))
return PAM_SYSTEM_ERR;
+ (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);
audit_log_user_message(audit_fd, AUDIT_RESP_ACCT_UNLOCK_TIMED, buf,
- NULL, NULL, NULL, 1);
+ rhost, NULL, tty, 1);
}
#endif
opts->flags |= FAILLOCK_FLAG_UNLOCKED;
@@ -398,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);
}
@@ -422,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.1.8/modules/pam_faillock/pam_faillock.8.xml.admin-group Linux-PAM-1.1.8/modules/pam_faillock/pam_faillock.8.xml
--- Linux-PAM-1.1.8/modules/pam_faillock/pam_faillock.8.xml.admin-group 2016-04-28 16:43:14.109794294 +0200
+++ Linux-PAM-1.1.8/modules/pam_faillock/pam_faillock.8.xml 2017-09-08 14:37:33.535130222 +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">
@@ -242,6 +245,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>

91
SOURCES/pam-1.1.8-faillock-never.patch

@ -0,0 +1,91 @@ @@ -0,0 +1,91 @@
diff -up Linux-PAM-1.1.8/modules/pam_faillock/pam_faillock.c.never Linux-PAM-1.1.8/modules/pam_faillock/pam_faillock.c
--- Linux-PAM-1.1.8/modules/pam_faillock/pam_faillock.c.never 2016-03-03 10:01:15.000000000 +0100
+++ Linux-PAM-1.1.8/modules/pam_faillock/pam_faillock.c 2016-04-22 14:31:34.239752334 +0200
@@ -125,17 +125,26 @@ args_parse(pam_handle_t *pamh, int argc,
}
else if (strncmp(argv[i], "unlock_time=", 12) == 0) {
unsigned int temp;
- if (sscanf(argv[i]+12, "%u", &temp) != 1 ||
+
+ if (strcmp(argv[i]+12, "never") == 0) {
+ opts->unlock_time = 0;
+ }
+ else if (sscanf(argv[i]+12, "%u", &temp) != 1 ||
temp > MAX_TIME_INTERVAL) {
pam_syslog(pamh, LOG_ERR,
"Bad number supplied for unlock_time argument");
- } else {
+ }
+ else {
opts->unlock_time = temp;
}
}
else if (strncmp(argv[i], "root_unlock_time=", 17) == 0) {
unsigned int temp;
- if (sscanf(argv[i]+17, "%u", &temp) != 1 ||
+
+ if (strcmp(argv[i]+17, "never") == 0) {
+ opts->root_unlock_time = 0;
+ }
+ else if (sscanf(argv[i]+17, "%u", &temp) != 1 ||
temp > MAX_TIME_INTERVAL) {
pam_syslog(pamh, LOG_ERR,
"Bad number supplied for root_unlock_time argument");
@@ -258,8 +267,8 @@ check_tally(pam_handle_t *pamh, struct o
}
if (opts->deny && failures >= opts->deny) {
- if ((opts->uid && latest_time + opts->unlock_time < opts->now) ||
- (!opts->uid && latest_time + opts->root_unlock_time < opts->now)) {
+ 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)) {
#ifdef HAVE_LIBAUDIT
if (opts->action != FAILLOCK_ACTION_PREAUTH) { /* do not audit in preauth */
char buf[64];
@@ -420,11 +429,17 @@ faillock_message(pam_handle_t *pamh, str
left = opts->latest_time + opts->root_unlock_time - opts->now;
}
- left /= 60; /* minutes */
+ if (left > 0) {
+ left = (left + 59)/60; /* minutes */
- pam_info(pamh, _("Account temporarily locked due to %d failed logins"),
- opts->failures);
- pam_info(pamh, _("(%d minutes left to unlock)"), (int)left);
+ pam_info(pamh, _("Account temporarily locked due to %d failed logins"),
+ opts->failures);
+ pam_info(pamh, _("(%d minutes left to unlock)"), (int)left);
+ }
+ else {
+ pam_info(pamh, _("Account locked due to %d failed logins"),
+ opts->failures);
+ }
}
}
diff -up Linux-PAM-1.1.8/modules/pam_faillock/pam_faillock.8.xml.never Linux-PAM-1.1.8/modules/pam_faillock/pam_faillock.8.xml
--- Linux-PAM-1.1.8/modules/pam_faillock/pam_faillock.8.xml.never 2016-04-22 15:25:57.000000000 +0200
+++ Linux-PAM-1.1.8/modules/pam_faillock/pam_faillock.8.xml 2016-04-28 16:43:14.109794294 +0200
@@ -201,6 +201,21 @@
<replaceable>n</replaceable> seconds after the lock out.
The default is 600 (10 minutes).
</para>
+ <para>
+ If the <replaceable>n</replaceable> is set to never or 0
+ the access will not be reenabled at all until administrator
+ explicitly reenables it with the <command>faillock</command> command.
+ Note though that the default directory that <emphasis>pam_faillock</emphasis>
+ uses is usually cleared on system boot so the access will be also reenabled
+ after system reboot. If that is undesirable a different tally directory
+ must be set with the <option>dir</option> option.
+ </para>
+ <para>
+ Also note that it is usually undesirable to permanently lock
+ out the users as they can become easily a target of denial of service
+ attack unless the usernames are random and kept secret to potential
+ attackers.
+ </para>
</listitem>
</varlistentry>
<varlistentry>

108
SOURCES/pam-1.1.8-full-relro.patch

@ -0,0 +1,108 @@ @@ -0,0 +1,108 @@
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_faillock/Makefile.am.relro Linux-PAM-1.1.8/modules/pam_faillock/Makefile.am
--- Linux-PAM-1.1.8/modules/pam_faillock/Makefile.am.relro 2014-08-13 16:02:49.000000000 +0200
+++ Linux-PAM-1.1.8/modules/pam_faillock/Makefile.am 2014-09-10 17:16:11.102808189 +0200
@@ -19,7 +19,7 @@ secureconfdir = $(SCONFIGDIR)
noinst_HEADERS = faillock.h
-faillock_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include
+faillock_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include @PIE_CFLAGS@
pam_faillock_la_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include
pam_faillock_la_LDFLAGS = -no-undefined -avoid-version -module
@@ -28,6 +28,7 @@ if HAVE_VERSIONING
pam_faillock_la_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
endif
+faillock_LDFLAGS = -Wl,-z,now @PIE_LDFLAGS@
faillock_LDADD = -L$(top_builddir)/libpam -lpam $(LIBAUDIT)
securelib_LTLIBRARIES = pam_faillock.la
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

22
SOURCES/pam-1.1.8-lastlog-localtime.patch

@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
diff -up Linux-PAM-1.1.8/modules/pam_lastlog/pam_lastlog.c.localtime Linux-PAM-1.1.8/modules/pam_lastlog/pam_lastlog.c
--- Linux-PAM-1.1.8/modules/pam_lastlog/pam_lastlog.c.localtime 2016-03-03 10:01:15.000000000 +0100
+++ Linux-PAM-1.1.8/modules/pam_lastlog/pam_lastlog.c 2016-04-22 15:24:10.085018141 +0200
@@ -276,12 +276,12 @@ last_login_read(pam_handle_t *pamh, int
time_t ll_time;
ll_time = last_login.ll_time;
- tm = localtime_r (&ll_time, &tm_buf);
- strftime (the_time, sizeof (the_time),
- /* TRANSLATORS: "strftime options for date of last login" */
- _(" %a %b %e %H:%M:%S %Z %Y"), tm);
-
- date = the_time;
+ if ((tm = localtime_r (&ll_time, &tm_buf)) != NULL) {
+ strftime (the_time, sizeof (the_time),
+ /* TRANSLATORS: "strftime options for date of last login" */
+ _(" %a %b %e %H:%M:%S %Z %Y"), tm);
+ date = the_time;
+ }
}
/* we want & have the host? */

37
SOURCES/pam-1.1.8-lastlog-uninitialized.patch

@ -0,0 +1,37 @@ @@ -0,0 +1,37 @@
diff -up Linux-PAM-1.1.8/modules/pam_lastlog/pam_lastlog.c.uninitialized Linux-PAM-1.1.8/modules/pam_lastlog/pam_lastlog.c
--- Linux-PAM-1.1.8/modules/pam_lastlog/pam_lastlog.c.uninitialized 2013-06-18 16:11:21.000000000 +0200
+++ Linux-PAM-1.1.8/modules/pam_lastlog/pam_lastlog.c 2014-08-25 16:44:24.365174752 +0200
@@ -350,6 +350,8 @@ last_login_write(pam_handle_t *pamh, int
return PAM_SERVICE_ERR;
}
+ memset(&last_login, 0, sizeof(last_login));
+
/* set this login date */
D(("set the most recent login time"));
(void) time(&ll_time); /* set the time */
@@ -364,14 +366,12 @@ last_login_write(pam_handle_t *pamh, int
}
/* copy to last_login */
- last_login.ll_host[0] = '\0';
strncat(last_login.ll_host, remote_host, sizeof(last_login.ll_host)-1);
/* set the terminal line */
terminal_line = get_tty(pamh);
/* copy to last_login */
- last_login.ll_line[0] = '\0';
strncat(last_login.ll_line, terminal_line, sizeof(last_login.ll_line)-1);
terminal_line = NULL;
@@ -628,7 +628,8 @@ pam_sm_authenticate(pam_handle_t *pamh,
lltime = (time(NULL) - lltime) / (24*60*60);
if (lltime > inactive_days) {
- pam_syslog(pamh, LOG_INFO, "user %s inactive for %d days - denied", user, lltime);
+ pam_syslog(pamh, LOG_INFO, "user %s inactive for %ld days - denied",
+ user, (long) lltime);
return PAM_AUTH_ERR;
}

41
SOURCES/pam-1.1.8-limits-check-process.patch

@ -0,0 +1,41 @@ @@ -0,0 +1,41 @@
diff -up Linux-PAM-1.1.8/modules/pam_limits/pam_limits.c.check-process Linux-PAM-1.1.8/modules/pam_limits/pam_limits.c
--- Linux-PAM-1.1.8/modules/pam_limits/pam_limits.c.check-process 2013-06-18 16:11:21.000000000 +0200
+++ Linux-PAM-1.1.8/modules/pam_limits/pam_limits.c 2014-09-10 16:39:36.263256066 +0200
@@ -27,6 +27,7 @@
#include <errno.h>
#include <syslog.h>
#include <stdarg.h>
+#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/resource.h>
@@ -269,16 +270,27 @@ check_logins (pam_handle_t *pamh, const
continue;
}
if (!pl->flag_numsyslogins) {
+ char user[sizeof(ut->UT_USER) + 1];
+ user[0] = '\0';
+ strncat(user, ut->UT_USER, sizeof(ut->UT_USER));
+
if (((pl->login_limit_def == LIMITS_DEF_USER)
|| (pl->login_limit_def == LIMITS_DEF_GROUP)
|| (pl->login_limit_def == LIMITS_DEF_DEFAULT))
- && strncmp(name, ut->UT_USER, sizeof(ut->UT_USER)) != 0) {
+ && strcmp(name, user) != 0) {
continue;
}
if ((pl->login_limit_def == LIMITS_DEF_ALLGROUP)
- && !pam_modutil_user_in_group_nam_nam(pamh, ut->UT_USER, pl->login_group)) {
+ && !pam_modutil_user_in_group_nam_nam(pamh, user, pl->login_group)) {
continue;
}
+ if (kill(ut->ut_pid, 0) == -1 && errno == ESRCH) {
+ /* process does not exist anymore */
+ pam_syslog(pamh, LOG_WARNING,
+ "Stale utmp entry (pid %d) for '%s' ignored",
+ ut->ut_pid, user);
+ continue;
+ }
}
if (++count > limit) {
break;

54
SOURCES/pam-1.1.8-limits-docfix.patch

@ -0,0 +1,54 @@ @@ -0,0 +1,54 @@
diff -up Linux-PAM-1.1.8/modules/pam_limits/limits.conf.docfix Linux-PAM-1.1.8/modules/pam_limits/limits.conf
--- Linux-PAM-1.1.8/modules/pam_limits/limits.conf.docfix 2014-07-14 14:58:05.000000000 +0200
+++ Linux-PAM-1.1.8/modules/pam_limits/limits.conf 2014-09-10 16:42:51.254747161 +0200
@@ -32,7 +32,7 @@
# - data - max data size (KB)
# - fsize - maximum filesize (KB)
# - memlock - max locked-in-memory address space (KB)
-# - nofile - max number of open files
+# - nofile - max number of open file descriptors
# - rss - max resident set size (KB)
# - stack - max stack size (KB)
# - cpu - max CPU time (MIN)
diff -up Linux-PAM-1.1.8/modules/pam_limits/limits.conf.5.xml.docfix Linux-PAM-1.1.8/modules/pam_limits/limits.conf.5.xml
--- Linux-PAM-1.1.8/modules/pam_limits/limits.conf.5.xml.docfix 2013-06-18 16:11:21.000000000 +0200
+++ Linux-PAM-1.1.8/modules/pam_limits/limits.conf.5.xml 2014-09-10 16:44:01.624367933 +0200
@@ -178,7 +178,7 @@
<varlistentry>
<term><option>nofile</option></term>
<listitem>
- <para>maximum number of open files</para>
+ <para>maximum number of open file descriptors</para>
</listitem>
</varlistentry>
<varlistentry>
@@ -214,14 +214,17 @@
<varlistentry>
<term><option>maxlogins</option></term>
<listitem>
- <para>maximum number of logins for this user except
- for this with <emphasis>uid=0</emphasis></para>
+ <para>maximum number of logins for this user (this limit does
+ not apply to user with <emphasis>uid=0</emphasis>)</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>maxsyslogins</option></term>
<listitem>
- <para>maximum number of all logins on system</para>
+ <para>maximum number of all logins on system; user is not
+ allowed to log-in if total number of all users' logins is
+ greater than specified number (this limit does not apply to
+ user with <emphasis>uid=0</emphasis>)</para>
</listitem>
</varlistentry>
<varlistentry>
@@ -292,7 +295,7 @@
permanent; existing only for the duration of the session.
One exception is the <emphasis>maxlogin</emphasis> option, this one
is system wide. But there is a race, concurrent logins at the same
- time will not always be detect as such but only counted as one.
+ time will not always be detected as such but only counted as one.
</para>
<para>
In the <emphasis>limits</emphasis> configuration file, the

19
SOURCES/pam-1.1.8-loginuid-log-auditd.patch

@ -0,0 +1,19 @@ @@ -0,0 +1,19 @@
diff -up Linux-PAM-1.1.8/modules/pam_loginuid/pam_loginuid.c.log-auditd Linux-PAM-1.1.8/modules/pam_loginuid/pam_loginuid.c
--- Linux-PAM-1.1.8/modules/pam_loginuid/pam_loginuid.c.log-auditd 2013-06-18 16:11:21.000000000 +0200
+++ Linux-PAM-1.1.8/modules/pam_loginuid/pam_loginuid.c 2016-04-22 14:21:35.868204427 +0200
@@ -195,9 +195,12 @@ _pam_loginuid(pam_handle_t *pamh, int fl
argv++;
}
- if (require_auditd)
- return check_auditd();
- else
+ if (require_auditd) {
+ int rc = check_auditd();
+ if (rc != PAM_SUCCESS)
+ pam_syslog(pamh, LOG_ERR, "required running auditd not detected");
+ return rc;
+ } else
#endif
return PAM_SUCCESS;
}

22
SOURCES/pam-1.1.8-man-dbsuffix.patch

@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
diff -up Linux-PAM-1.1.8/modules/pam_userdb/pam_userdb.8.xml.dbsuffix Linux-PAM-1.1.8/modules/pam_userdb/pam_userdb.8.xml
--- Linux-PAM-1.1.8/modules/pam_userdb/pam_userdb.8.xml.dbsuffix 2013-06-18 16:11:21.000000000 +0200
+++ Linux-PAM-1.1.8/modules/pam_userdb/pam_userdb.8.xml 2014-09-10 16:28:19.916678273 +0200
@@ -89,7 +89,8 @@
Use the <filename>/path/database</filename> database for
performing lookup. There is no default; the module will
return <emphasis remap='B'>PAM_IGNORE</emphasis> if no
- database is provided.
+ database is provided. Note that the path to the database file
+ should be specified without the <filename>.db</filename> suffix.
</para>
</listitem>
</varlistentry>
@@ -260,7 +261,7 @@
<refsect1 id='pam_userdb-examples'>
<title>EXAMPLES</title>
<programlisting>
-auth sufficient pam_userdb.so icase db=/etc/dbtest.db
+auth sufficient pam_userdb.so icase db=/etc/dbtest
</programlisting>
</refsect1>

30
SOURCES/pam-1.1.8-man-delay.patch

@ -0,0 +1,30 @@ @@ -0,0 +1,30 @@
diff -up Linux-PAM-1.1.8/doc/man/pam_fail_delay.3.xml.delay Linux-PAM-1.1.8/doc/man/pam_fail_delay.3.xml
--- Linux-PAM-1.1.8/doc/man/pam_fail_delay.3.xml.delay 2013-06-18 16:11:21.000000000 +0200
+++ Linux-PAM-1.1.8/doc/man/pam_fail_delay.3.xml 2016-05-30 12:08:40.708053159 +0200
@@ -39,7 +39,7 @@
<citerefentry>
<refentrytitle>pam_authenticate</refentrytitle><manvolnum>3</manvolnum>
</citerefentry> fail, the failing return to the application is
- delayed by an amount of time randomly distributed (by up to 25%)
+ delayed by an amount of time randomly distributed (by up to 50%)
about this longest value.
</para>
<para>
@@ -135,7 +135,7 @@ void (*delay_fn)(int retval, unsigned us
<para>
if the modules do not request a delay, the failure delay will be
- between 2.25 and 3.75 seconds.
+ between 1.5 and 4.5 seconds.
</para>
<para>
@@ -150,7 +150,7 @@ module #2: pam_fail_delay (pamh, 4000
<para>
in this case, it is the largest requested value that is used to
- compute the actual failed delay: here between 3 and 5 seconds.
+ compute the actual failed delay: here between 2 and 6 seconds.
</para>
</refsect1>

78
SOURCES/pam-1.1.8-man-environment.patch

@ -0,0 +1,78 @@ @@ -0,0 +1,78 @@
diff -up Linux-PAM-1.1.8/modules/pam_env/Makefile.am.environment Linux-PAM-1.1.8/modules/pam_env/Makefile.am
--- Linux-PAM-1.1.8/modules/pam_env/Makefile.am.environment 2013-06-18 16:11:21.000000000 +0200
+++ Linux-PAM-1.1.8/modules/pam_env/Makefile.am 2016-04-22 14:10:49.921649262 +0200
@@ -7,7 +7,7 @@ MAINTAINERCLEANFILES = $(MANS) README
EXTRA_DIST = README pam_env.conf $(MANS) $(XMLS) tst-pam_env environment
-man_MANS = pam_env.conf.5 pam_env.8
+man_MANS = pam_env.conf.5 pam_env.8 environment.5
XMLS = README.xml pam_env.conf.5.xml pam_env.8.xml
@@ -30,6 +30,7 @@ sysconf_DATA = environment
if ENABLE_REGENERATE_MAN
noinst_DATA = README
README: pam_env.8.xml pam_env.conf.5.xml
+environment.5: pam_env.conf.5.xml
-include $(top_srcdir)/Make.xml.rules
endif
diff -up Linux-PAM-1.1.8/modules/pam_env/Makefile.in.environment Linux-PAM-1.1.8/modules/pam_env/Makefile.in
--- Linux-PAM-1.1.8/modules/pam_env/Makefile.in.environment 2016-04-22 14:14:41.475866891 +0200
+++ Linux-PAM-1.1.8/modules/pam_env/Makefile.in 2016-04-22 14:13:58.239892651 +0200
@@ -285,7 +285,7 @@ top_srcdir = @top_srcdir@
CLEANFILES = *~
MAINTAINERCLEANFILES = $(MANS) README
EXTRA_DIST = README pam_env.conf $(MANS) $(XMLS) tst-pam_env environment
-man_MANS = pam_env.conf.5 pam_env.8
+man_MANS = pam_env.conf.5 pam_env.8 environment.5
XMLS = README.xml pam_env.conf.5.xml pam_env.8.xml
securelibdir = $(SECUREDIR)
secureconfdir = $(SCONFIGDIR)
@@ -836,6 +836,7 @@ uninstall-man: uninstall-man5 uninstall-
uninstall-sysconfDATA
@ENABLE_REGENERATE_MAN_TRUE@README: pam_env.8.xml pam_env.conf.5.xml
+@ENABLE_REGENERATE_MAN_TRUE@environment.5: pam_env.conf.5.xml
@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
# Tell versions [3.59,3.63) of GNU make to not export all variables.
diff -up Linux-PAM-1.1.8/modules/pam_env/pam_env.conf.5.xml.environment Linux-PAM-1.1.8/modules/pam_env/pam_env.conf.5.xml
--- Linux-PAM-1.1.8/modules/pam_env/pam_env.conf.5.xml.environment 2013-06-18 16:11:21.000000000 +0200
+++ Linux-PAM-1.1.8/modules/pam_env/pam_env.conf.5.xml 2016-04-22 14:12:49.150335851 +0200
@@ -12,7 +12,8 @@
<refnamediv>
<refname>pam_env.conf</refname>
- <refpurpose>the environment variables config file</refpurpose>
+ <refname>environment</refname>
+ <refpurpose>the environment variables config files</refpurpose>
</refnamediv>
@@ -58,6 +59,14 @@
at front) can be used to mark this line as a comment line.
</para>
+ <para>
+ The <filename>/etc/environment</filename> file specifies
+ the environment variables to be set. The file must consist of simple
+ <emphasis>NAME=VALUE</emphasis> pairs on separate lines.
+ The <citerefentry><refentrytitle>pam_env</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ module will read the file after the <filename>pam_env.conf</filename>
+ file.
+ </para>
</refsect1>
<refsect1 id="pam_env.conf-examples">
@@ -110,7 +119,8 @@
<para>
<citerefentry><refentrytitle>pam_env</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ <citerefentry><refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>environ</refentrytitle><manvolnum>7</manvolnum></citerefentry>
</para>
</refsect1>

13
SOURCES/pam-1.1.8-man-space.patch

@ -0,0 +1,13 @@ @@ -0,0 +1,13 @@
diff -up Linux-PAM-1.1.8/doc/man/pam.8.xml.space Linux-PAM-1.1.8/doc/man/pam.8.xml
--- Linux-PAM-1.1.8/doc/man/pam.8.xml.space 2013-06-18 16:11:21.000000000 +0200
+++ Linux-PAM-1.1.8/doc/man/pam.8.xml 2017-09-08 14:22:58.878416174 +0200
@@ -48,8 +48,7 @@
can be set by individual configuration files located in the
<filename>/etc/pam.d/</filename> directory. The presence of this
directory will cause <emphasis remap='B'>Linux-PAM</emphasis> to
- <emphasis remap='I'>ignore</emphasis>
- <filename>/etc/pam.conf</filename>.
+ <emphasis remap='I'>ignore </emphasis><filename>/etc/pam.conf</filename>.
</para>

29
SOURCES/pam-1.1.8-mkhomedir-inroot.patch

@ -0,0 +1,29 @@ @@ -0,0 +1,29 @@
diff -up Linux-PAM-1.1.8/modules/pam_mkhomedir/mkhomedir_helper.c.mkhomedir-inroot Linux-PAM-1.1.8/modules/pam_mkhomedir/mkhomedir_helper.c
--- Linux-PAM-1.1.8/modules/pam_mkhomedir/mkhomedir_helper.c.mkhomedir-inroot 2013-06-18 16:11:21.000000000 +0200
+++ Linux-PAM-1.1.8/modules/pam_mkhomedir/mkhomedir_helper.c 2017-11-03 10:20:59.823998481 +0100
@@ -352,16 +352,18 @@ make_parent_dirs(char *dir, int make)
char *cp = strrchr(dir, '/');
struct stat st;
- if (!cp || cp == dir)
+ if (!cp)
return rc;
- *cp = '\0';
- if (stat(dir, &st) && errno == ENOENT)
- rc = make_parent_dirs(dir, 1);
- *cp = '/';
+ if (cp != dir) {
+ *cp = '\0';
+ if (stat(dir, &st) && errno == ENOENT)
+ rc = make_parent_dirs(dir, 1);
+ *cp = '/';
- if (rc != PAM_SUCCESS)
- return rc;
+ if (rc != PAM_SUCCESS)
+ return rc;
+ }
if (make && mkdir(dir, 0755) && errno != EEXIST) {
pam_syslog(NULL, LOG_ERR, "unable to create directory %s: %m", dir);

50
SOURCES/pam-1.1.8-opasswd-tolerant.patch

@ -0,0 +1,50 @@ @@ -0,0 +1,50 @@
diff --git a/modules/pam_pwhistory/opasswd.c b/modules/pam_pwhistory/opasswd.c
index 836d713..c36628e 100644
--- a/modules/pam_pwhistory/opasswd.c
+++ b/modules/pam_pwhistory/opasswd.c
@@ -82,10 +82,15 @@ parse_entry (char *line, opwd *data)
{
const char delimiters[] = ":";
char *endptr;
+ char *count;
data->user = strsep (&line, delimiters);
data->uid = strsep (&line, delimiters);
- data->count = strtol (strsep (&line, delimiters), &endptr, 10);
+ count = strsep (&line, delimiters);
+ if (data->user == NULL || data->uid == NULL || count == NULL)
+ return 1;
+
+ data->count = strtol (count, &endptr, 10);
if (endptr != NULL && *endptr != '\0')
return 1;
diff --git a/modules/pam_unix/passverify.c b/modules/pam_unix/passverify.c
index 4840bb2..7f7bc49 100644
--- a/modules/pam_unix/passverify.c
+++ b/modules/pam_unix/passverify.c
@@ -639,11 +639,23 @@ save_old_password(pam_handle_t *pamh, const char *forwho, const char *oldpass,
continue;
buf[strlen(buf) - 1] = '\0';
s_luser = strtok_r(buf, ":", &sptr);
+ if (s_luser == NULL) {
+ found = 0;
+ continue;
+ }
s_uid = strtok_r(NULL, ":", &sptr);
+ if (s_uid == NULL) {
+ found = 0;
+ continue;
+ }
s_npas = strtok_r(NULL, ":", &sptr);
+ if (s_npas == NULL) {
+ found = 0;
+ continue;
+ }
s_pas = strtok_r(NULL, ":", &sptr);
npas = strtol(s_npas, NULL, 10) + 1;
- while (npas > howmany) {
+ while (npas > howmany && s_pas != NULL) {
s_pas = strpbrk(s_pas, ",");
if (s_pas != NULL)
s_pas++;

812
SOURCES/pam-1.1.8-pwhistory-helper.patch

@ -0,0 +1,812 @@ @@ -0,0 +1,812 @@
diff --git a/modules/pam_pwhistory/Makefile.am b/modules/pam_pwhistory/Makefile.am
index 4bb4d6d..9157b91 100644
--- a/modules/pam_pwhistory/Makefile.am
+++ b/modules/pam_pwhistory/Makefile.am
@@ -1,5 +1,6 @@
#
# Copyright (c) 2008, 2009 Thorsten Kukuk <kukuk@suse.de>
+# Copyright (c) 2013 Red Hat, Inc.
#
CLEANFILES = *~
@@ -9,25 +10,33 @@ EXTRA_DIST = README $(MANS) $(XMLS) tst-pam_pwhistory
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\"
+pwhistory_helper_SOURCES = pwhistory_helper.c opasswd.c
+pwhistory_helper_LDADD = $(top_builddir)/libpam/libpam.la @LIBCRYPT@
+
if ENABLE_REGENERATE_MAN
noinst_DATA = README
README: pam_pwhistory.8.xml
diff --git a/modules/pam_pwhistory/opasswd.c b/modules/pam_pwhistory/opasswd.c
index 836d713..e319ff3 100644
--- a/modules/pam_pwhistory/opasswd.c
+++ b/modules/pam_pwhistory/opasswd.c
@@ -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)
@@ -112,8 +135,8 @@ compare_password(const char *newpass, const char *oldpass)
}
/* 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;
@@ -123,6 +146,11 @@ check_old_pass (pam_handle_t *pamh, const char *user,
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)
@@ -208,9 +236,9 @@ check_old_pass (pam_handle_t *pamh, const char *user,
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;
@@ -221,10 +249,35 @@ save_old_pass (pam_handle_t *pamh, const char *user, uid_t uid,
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;
@@ -447,7 +500,7 @@ save_old_pass (pam_handle_t *pamh, const char *user, uid_t uid,
{
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 --git a/modules/pam_pwhistory/opasswd.h b/modules/pam_pwhistory/opasswd.h
index db3e656..1b08699 100644
--- a/modules/pam_pwhistory/opasswd.h
+++ b/modules/pam_pwhistory/opasswd.h
@@ -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 --git a/modules/pam_pwhistory/pam_pwhistory.c b/modules/pam_pwhistory/pam_pwhistory.c
index 654edd3..d6c5c47 100644
--- a/modules/pam_pwhistory/pam_pwhistory.c
+++ b/modules/pam_pwhistory/pam_pwhistory.c
@@ -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 char *argv, options_t *options)
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 char *argv, options_t *options)
PAM_EXTERN 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, int flags, int argc, const char **argv)
return PAM_SUCCESS;
}
- pwd = pam_modutil_getpwnam (pamh, user);
- if (pwd == NULL)
- return PAM_USER_UNKNOWN;
+ retval = save_old_pass (pamh, user, options.remember, options.debug);
- 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;
+ if (retval == PAM_PWHISTORY_RUN_HELPER)
+ retval = run_save_helper(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_SUCCESS)
+ return retval;
newpass = NULL;
tries = 0;
@@ -207,8 +372,11 @@ pam_sm_chauthtok (pam_handle_t *pamh, int flags, int argc, const char **argv)
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 --git a/modules/pam_pwhistory/pwhistory_helper.8.xml b/modules/pam_pwhistory/pwhistory_helper.8.xml
new file mode 100644
index 0000000..a030176
--- /dev/null
+++ b/modules/pam_pwhistory/pwhistory_helper.8.xml
@@ -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>
diff --git a/modules/pam_pwhistory/pwhistory_helper.c b/modules/pam_pwhistory/pwhistory_helper.c
new file mode 100644
index 0000000..b07ab81
--- /dev/null
+++ b/modules/pam_pwhistory/pwhistory_helper.c
@@ -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;
+}
+

12
SOURCES/pam-1.1.8-relax-audit.patch

@ -0,0 +1,12 @@ @@ -0,0 +1,12 @@
diff -up Linux-PAM-1.1.8/libpam/pam_audit.c.relax-audit Linux-PAM-1.1.8/libpam/pam_audit.c
--- Linux-PAM-1.1.8/libpam/pam_audit.c.relax-audit 2016-03-03 10:01:15.000000000 +0100
+++ Linux-PAM-1.1.8/libpam/pam_audit.c 2016-04-22 15:18:55.692925308 +0200
@@ -53,7 +53,7 @@ _pam_audit_writelog(pam_handle_t *pamh,
pamh->audit_state |= PAMAUDIT_LOGGED;
if (rc < 0) {
- if (rc == -EPERM && getuid() != 0)
+ if (rc == -EPERM)
return 0;
if (errno != old_errno) {
old_errno = errno;

85
SOURCES/pam-1.1.8-succeed-if-large-uid.patch

@ -0,0 +1,85 @@ @@ -0,0 +1,85 @@
diff -up Linux-PAM-1.1.8/modules/pam_succeed_if/pam_succeed_if.c.large-uid Linux-PAM-1.1.8/modules/pam_succeed_if/pam_succeed_if.c
--- Linux-PAM-1.1.8/modules/pam_succeed_if/pam_succeed_if.c.large-uid 2013-06-18 16:11:21.000000000 +0200
+++ Linux-PAM-1.1.8/modules/pam_succeed_if/pam_succeed_if.c 2016-07-19 15:00:57.366549150 +0200
@@ -68,20 +68,20 @@
* PAM_SERVICE_ERR if the arguments can't be parsed as numbers. */
static int
evaluate_num(const pam_handle_t *pamh, const char *left,
- const char *right, int (*cmp)(int, int))
+ const char *right, int (*cmp)(long long, long long))
{
- long l, r;
+ long long l, r;
char *p;
int ret = PAM_SUCCESS;
errno = 0;
- l = strtol(left, &p, 0);
+ l = strtoll(left, &p, 0);
if ((p == NULL) || (*p != '\0') || errno) {
pam_syslog(pamh, LOG_INFO, "\"%s\" is not a number", left);
ret = PAM_SERVICE_ERR;
}
- r = strtol(right, &p, 0);
+ r = strtoll(right, &p, 0);
if ((p == NULL) || (*p != '\0') || errno) {
pam_syslog(pamh, LOG_INFO, "\"%s\" is not a number", right);
ret = PAM_SERVICE_ERR;
@@ -96,32 +96,32 @@ evaluate_num(const pam_handle_t *pamh, c
/* Simple numeric comparison callbacks. */
static int
-eq(int i, int j)
+eq(long long i, long long j)
{
return i == j;
}
static int
-ne(int i, int j)
+ne(long long i, long long j)
{
return i != j;
}
static int
-lt(int i, int j)
+lt(long long i, long long j)
{
return i < j;
}
static int
-le(int i, int j)
+le(long long i, long long j)
{
return lt(i, j) || eq(i, j);
}
static int
-gt(int i, int j)
+gt(long long i, long long j)
{
return i > j;
}
static int
-ge(int i, int j)
+ge(long long i, long long j)
{
return gt(i, j) || eq(i, j);
}
@@ -298,7 +298,7 @@ evaluate(pam_handle_t *pamh, int debug,
}
if (strcasecmp(left, "rhost") == 0) {
const void *rhost;
- if (pam_get_item(pamh, PAM_SERVICE, &rhost) != PAM_SUCCESS ||
+ if (pam_get_item(pamh, PAM_RHOST, &rhost) != PAM_SUCCESS ||
rhost == NULL)
rhost = "";
snprintf(buf, sizeof(buf), "%s", (const char *)rhost);
@@ -306,7 +306,7 @@ evaluate(pam_handle_t *pamh, int debug,
}
if (strcasecmp(left, "tty") == 0) {
const void *tty;
- if (pam_get_item(pamh, PAM_SERVICE, &tty) != PAM_SUCCESS ||
+ if (pam_get_item(pamh, PAM_TTY, &tty) != PAM_SUCCESS ||
tty == NULL)
tty = "";
snprintf(buf, sizeof(buf), "%s", (const char *)tty);

1522
SOURCES/pam-1.1.8-translation-updates.patch

File diff suppressed because it is too large Load Diff

167
SOURCES/pam-1.1.8-tty-audit-uid-range.patch

@ -0,0 +1,167 @@ @@ -0,0 +1,167 @@
diff -up Linux-PAM-1.1.8/modules/pam_tty_audit/pam_tty_audit.c.uid-range Linux-PAM-1.1.8/modules/pam_tty_audit/pam_tty_audit.c
--- Linux-PAM-1.1.8/modules/pam_tty_audit/pam_tty_audit.c.uid-range 2017-09-08 14:46:58.869496414 +0200
+++ Linux-PAM-1.1.8/modules/pam_tty_audit/pam_tty_audit.c 2017-10-09 17:42:13.947599041 +0200
@@ -198,6 +198,54 @@ cleanup_old_status (pam_handle_t *pamh,
free (data);
}
+enum uid_range { UID_RANGE_NONE, UID_RANGE_MM, UID_RANGE_MIN,
+ UID_RANGE_ONE, UID_RANGE_ERR };
+
+static enum uid_range
+parse_uid_range(pam_handle_t *pamh, const char *s,
+ uid_t *min_uid, uid_t *max_uid)
+{
+ const char *range = s;
+ const char *pmax;
+ char *endptr;
+ enum uid_range rv = UID_RANGE_MM;
+
+ if ((pmax=strchr(range, ':')) == NULL)
+ return UID_RANGE_NONE;
+ ++pmax;
+
+ if (range[0] == ':')
+ rv = UID_RANGE_ONE;
+ else {
+ errno = 0;
+ *min_uid = strtoul (range, &endptr, 10);
+ if (errno != 0 || (range == endptr) || *endptr != ':') {
+ pam_syslog(pamh, LOG_DEBUG,
+ "wrong min_uid value in '%s'", s);
+ return UID_RANGE_ERR;
+ }
+ }
+
+ if (*pmax == '\0') {
+ if (rv == UID_RANGE_ONE)
+ return UID_RANGE_ERR;
+
+ return UID_RANGE_MIN;
+ }
+
+ errno = 0;
+ *max_uid = strtoul (pmax, &endptr, 10);
+ if (errno != 0 || (pmax == endptr) || *endptr != '\0') {
+ pam_syslog(pamh, LOG_DEBUG,
+ "wrong max_uid value in '%s'", s);
+ return UID_RANGE_ERR;
+ }
+
+ if (rv == UID_RANGE_ONE)
+ *min_uid = *max_uid;
+ return rv;
+}
+
int
pam_sm_open_session (pam_handle_t *pamh, int flags, int argc, const char **argv)
{
@@ -207,6 +255,7 @@ pam_sm_open_session (pam_handle_t *pamh,
struct audit_tty_status *old_status, new_status;
const char *user;
int i, fd, open_only;
+ struct passwd *pwd;
#ifdef HAVE_STRUCT_AUDIT_TTY_STATUS_LOG_PASSWD
int log_passwd;
#endif /* HAVE_STRUCT_AUDIT_TTY_STATUS_LOG_PASSWD */
@@ -219,6 +268,14 @@ pam_sm_open_session (pam_handle_t *pamh,
return PAM_SESSION_ERR;
}
+ pwd = pam_modutil_getpwnam(pamh, user);
+ if (pwd == NULL)
+ {
+ pam_syslog(pamh, LOG_WARNING,
+ "open_session unknown user '%s'", user);
+ return PAM_SESSION_ERR;
+ }
+
command = CMD_NONE;
open_only = 0;
#ifdef HAVE_STRUCT_AUDIT_TTY_STATUS_LOG_PASSWD
@@ -236,13 +293,31 @@ pam_sm_open_session (pam_handle_t *pamh,
copy = strdup (strchr (argv[i], '=') + 1);
if (copy == NULL)
return PAM_SESSION_ERR;
- for (tok = strtok_r (copy, ",", &tok_data); tok != NULL;
+ for (tok = strtok_r (copy, ",", &tok_data);
+ tok != NULL && command != this_command;
tok = strtok_r (NULL, ",", &tok_data))
{
- if (fnmatch (tok, user, 0) == 0)
+ uid_t min_uid = 0, max_uid = 0;
+ switch (parse_uid_range(pamh, tok, &min_uid, &max_uid))
{
- command = this_command;
- break;
+ case UID_RANGE_NONE:
+ if (fnmatch (tok, user, 0) == 0)
+ command = this_command;
+ break;
+ case UID_RANGE_MM:
+ if (pwd->pw_uid >= min_uid && pwd->pw_uid <= max_uid)
+ command = this_command;
+ break;
+ case UID_RANGE_MIN:
+ if (pwd->pw_uid >= min_uid)
+ command = this_command;
+ break;
+ case UID_RANGE_ONE:
+ if (pwd->pw_uid == max_uid)
+ command = this_command;
+ break;
+ case UID_RANGE_ERR:
+ break;
}
}
free (copy);
diff -up Linux-PAM-1.1.8/modules/pam_tty_audit/pam_tty_audit.8.xml.uid-range Linux-PAM-1.1.8/modules/pam_tty_audit/pam_tty_audit.8.xml
--- Linux-PAM-1.1.8/modules/pam_tty_audit/pam_tty_audit.8.xml.uid-range 2013-08-28 10:53:40.000000000 +0200
+++ Linux-PAM-1.1.8/modules/pam_tty_audit/pam_tty_audit.8.xml 2017-09-08 14:46:58.895497022 +0200
@@ -44,10 +44,10 @@
</term>
<listitem>
<para>
- For each user matching one of comma-separated glob
- <option><replaceable>patterns</replaceable></option>, disable
- TTY auditing. This overrides any previous <option>enable</option>
- option matching the same user name on the command line.
+ For each user matching <option><replaceable>patterns</replaceable></option>,
+ disable TTY auditing. This overrides any previous <option>enable</option>
+ option matching the same user name on the command line. See NOTES
+ for further description of <option><replaceable>patterns</replaceable></option>.
</para>
</listitem>
</varlistentry>
@@ -57,10 +57,10 @@
</term>
<listitem>
<para>
- For each user matching one of comma-separated glob
- <option><replaceable>patterns</replaceable></option>, enable
- TTY auditing. This overrides any previous <option>disable</option>
- option matching the same user name on the command line.
+ For each user matching <option><replaceable>patterns</replaceable></option>,
+ enable TTY auditing. This overrides any previous <option>disable</option>
+ option matching the same user name on the command line. See NOTES
+ for further description of <option><replaceable>patterns</replaceable></option>.
</para>
</listitem>
</varlistentry>
@@ -139,6 +139,16 @@
To view the data that was logged by the kernel to audit use
the command <command>aureport --tty</command>.
</para>
+ <para>
+ The <option><replaceable>patterns</replaceable></option> are comma separated
+ lists of glob patterns or ranges of uids. A range is specified as
+ <replaceable>min_uid</replaceable>:<replaceable>max_uid</replaceable> where
+ one of these values can be empty. If <replaceable>min_uid</replaceable> is
+ empty only user with the uid <replaceable>max_uid</replaceable> will be
+ matched. If <replaceable>max_uid</replaceable> is empty users with the uid
+ greater than or equal to <replaceable>min_uid</replaceable> will be
+ matched.
+ </para>
</refsect1>
<refsect1 id='pam_tty_audit-examples'>

134
SOURCES/pam-1.1.8-unix-expiry.patch

@ -0,0 +1,134 @@ @@ -0,0 +1,134 @@
diff -up Linux-PAM-1.1.8/modules/pam_unix/pam_unix_acct.c.expiry Linux-PAM-1.1.8/modules/pam_unix/pam_unix_acct.c
--- Linux-PAM-1.1.8/modules/pam_unix/pam_unix_acct.c.expiry 2016-03-03 09:58:52.677684261 +0100
+++ Linux-PAM-1.1.8/modules/pam_unix/pam_unix_acct.c 2016-03-03 09:58:52.712685101 +0100
@@ -244,6 +244,19 @@ pam_sm_acct_mgmt(pam_handle_t *pamh, int
} else
retval = check_shadow_expiry(pamh, spent, &daysleft);
+ if (on(UNIX_NO_PASS_EXPIRY, ctrl)) {
+ const void *pretval = NULL;
+ int authrv = PAM_AUTHINFO_UNAVAIL; /* authentication not called */
+
+ if (pam_get_data(pamh, "unix_setcred_return", &pretval) == PAM_SUCCESS
+ && pretval)
+ authrv = *(const int *)pretval;
+
+ if (authrv != PAM_SUCCESS
+ && (retval == PAM_NEW_AUTHTOK_REQD || retval == PAM_AUTHTOK_EXPIRED))
+ retval = PAM_SUCCESS;
+ }
+
switch (retval) {
case PAM_ACCT_EXPIRED:
pam_syslog(pamh, LOG_NOTICE,
diff -up Linux-PAM-1.1.8/modules/pam_unix/pam_unix_auth.c.expiry Linux-PAM-1.1.8/modules/pam_unix/pam_unix_auth.c
--- Linux-PAM-1.1.8/modules/pam_unix/pam_unix_auth.c.expiry 2013-06-18 16:11:21.000000000 +0200
+++ Linux-PAM-1.1.8/modules/pam_unix/pam_unix_auth.c 2016-03-03 09:58:52.712685101 +0100
@@ -82,14 +82,13 @@
#define AUTH_RETURN \
do { \
- if (on(UNIX_LIKE_AUTH, ctrl) && ret_data) { \
+ if (ret_data) { \
D(("recording return code for next time [%d]", \
retval)); \
*ret_data = retval; \
pam_set_data(pamh, "unix_setcred_return", \
(void *) ret_data, setcred_free); \
- } else if (ret_data) \
- free (ret_data); \
+ } \
D(("done. [%s]", pam_strerror(pamh, retval))); \
return retval; \
} while (0)
@@ -115,9 +114,8 @@ pam_sm_authenticate(pam_handle_t *pamh,
ctrl = _set_ctrl(pamh, flags, NULL, NULL, NULL, argc, argv);
/* Get a few bytes so we can pass our return value to
- pam_sm_setcred(). */
- if (on(UNIX_LIKE_AUTH, ctrl))
- ret_data = malloc(sizeof(int));
+ pam_sm_setcred() and pam_sm_acct_mgmt(). */
+ ret_data = malloc(sizeof(int));
/* get the user'name' */
@@ -194,20 +192,24 @@ pam_sm_authenticate(pam_handle_t *pamh,
*/
int
-pam_sm_setcred (pam_handle_t *pamh, int flags UNUSED,
- int argc UNUSED, const char **argv UNUSED)
+pam_sm_setcred (pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
{
int retval;
const void *pretval = NULL;
+ unsigned int ctrl;
D(("called."));
+ ctrl = _set_ctrl(pamh, flags, NULL, NULL, NULL, argc, argv);
+
retval = PAM_SUCCESS;
D(("recovering return code from auth call"));
/* We will only find something here if UNIX_LIKE_AUTH is set --
don't worry about an explicit check of argv. */
- if (pam_get_data(pamh, "unix_setcred_return", &pretval) == PAM_SUCCESS
+ if (on(UNIX_LIKE_AUTH, ctrl)
+ && pam_get_data(pamh, "unix_setcred_return", &pretval) == PAM_SUCCESS
&& pretval) {
retval = *(const int *)pretval;
pam_set_data(pamh, "unix_setcred_return", NULL, NULL);
diff -up Linux-PAM-1.1.8/modules/pam_unix/pam_unix.8.xml.expiry Linux-PAM-1.1.8/modules/pam_unix/pam_unix.8.xml
--- Linux-PAM-1.1.8/modules/pam_unix/pam_unix.8.xml.expiry 2016-03-03 09:58:52.710685053 +0100
+++ Linux-PAM-1.1.8/modules/pam_unix/pam_unix.8.xml 2016-03-03 09:58:52.712685101 +0100
@@ -346,6 +346,25 @@
</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term>
+ <option>no_pass_expiry</option>
+ </term>
+ <listitem>
+ <para>
+ When set ignore password expiration as defined by the
+ <emphasis>shadow</emphasis> entry of the user. The option has an
+ effect only in case <emphasis>pam_unix</emphasis> was not used
+ for the authentication or it returned authentication failure
+ meaning that other authentication source or method succeeded.
+ The example can be public key authentication in
+ <emphasis>sshd</emphasis>. The module will return
+ <emphasis remap='B'>PAM_SUCCESS</emphasis> instead of eventual
+ <emphasis remap='B'>PAM_NEW_AUTHTOK_REQD</emphasis> or
+ <emphasis remap='B'>PAM_AUTHTOK_EXPIRED</emphasis>.
+ </para>
+ </listitem>
+ </varlistentry>
</variablelist>
<para>
Invalid arguments are logged with <citerefentry>
diff -up Linux-PAM-1.1.8/modules/pam_unix/support.h.expiry Linux-PAM-1.1.8/modules/pam_unix/support.h
--- Linux-PAM-1.1.8/modules/pam_unix/support.h.expiry 2016-03-03 09:58:52.712685101 +0100
+++ Linux-PAM-1.1.8/modules/pam_unix/support.h 2016-03-03 10:00:31.642061166 +0100
@@ -97,8 +97,9 @@ typedef struct {
password hash algorithms */
#define UNIX_BLOWFISH_PASS 26 /* new password hashes will use blowfish */
#define UNIX_MIN_PASS_LEN 27 /* min length for password */
+#define UNIX_NO_PASS_EXPIRY 28 /* Don't check for password expiration if not used for authentication */
/* -------------- */
-#define UNIX_CTRLS_ 28 /* number of ctrl arguments defined */
+#define UNIX_CTRLS_ 29 /* number of ctrl arguments defined */
#define UNIX_DES_CRYPT(ctrl) (off(UNIX_MD5_PASS,ctrl)&&off(UNIX_BIGCRYPT,ctrl)&&off(UNIX_SHA256_PASS,ctrl)&&off(UNIX_SHA512_PASS,ctrl)&&off(UNIX_BLOWFISH_PASS,ctrl))
@@ -135,6 +136,7 @@ static const UNIX_Ctrls unix_args[UNIX_C
/* UNIX_ALGO_ROUNDS */ {"rounds=", _ALL_ON_, 0100000000, 0},
/* UNIX_BLOWFISH_PASS */ {"blowfish", _ALL_ON_^(0260420000), 0200000000, 1},
/* UNIX_MIN_PASS_LEN */ {"minlen=", _ALL_ON_, 0400000000, 0},
+/* UNIX_NO_PASS_EXPIRY */ {"no_pass_expiry", _ALL_ON_, 02000000000, 0},
};
#define UNIX_DEFAULTS (unix_args[UNIX__NONULL].flag)

3
SOURCES/pamtmp.conf

@ -0,0 +1,3 @@ @@ -0,0 +1,3 @@
d /var/run/console 0755 root root -
d /var/run/faillock 0755 root root -
d /var/run/sepermit 0755 root root -

18
SOURCES/password-auth.pamd

@ -0,0 +1,18 @@ @@ -0,0 +1,18 @@
#%PAM-1.0
# This file is auto-generated.
# User changes will be destroyed the next time authconfig is run.
auth required pam_env.so
auth sufficient pam_unix.so try_first_pass nullok
auth required pam_deny.so

account required pam_unix.so

password requisite pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type=
password sufficient pam_unix.so try_first_pass use_authtok nullok sha512 shadow
password required pam_deny.so

session optional pam_keyinit.so revoke
session required pam_limits.so
-session optional pam_systemd.so
session [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
session required pam_unix.so

46
SOURCES/postlogin.5

@ -0,0 +1,46 @@ @@ -0,0 +1,46 @@
.TH POSTLOGIN 5 "2010 Dec 22" "Red Hat" "Linux-PAM Manual"
.SH NAME

postlogin \- Common configuration file for PAMified services

.SH SYNOPSIS
.B /etc/pam.d/postlogin
.sp 2
.SH DESCRIPTION

The purpose of this PAM configuration file is to provide a common
place for all PAM modules which should be called after the stack
configured in
.BR system-auth
or the other common PAM configuration files.

.sp
The
.BR postlogin
configuration file is included from all individual service configuration
files that provide login service with shell or file access.

.SH NOTES
The modules in the postlogin configuration file are executed regardless
of the success or failure of the modules in the
.BR system-auth
configuration file.

.SH BUGS
.sp 2
Sometimes it would be useful to be able to skip the postlogin modules in
case the substack of the
.BR system-auth
modules failed. Unfortunately the current Linux-PAM library does not
provide any way how to achieve this.

.SH "SEE ALSO"
pam(8), config-util(5), system-auth(5)

The three
.BR Linux-PAM
Guides, for
.BR "system administrators" ", "
.BR "module developers" ", "
and
.BR "application developers" ". "

7
SOURCES/postlogin.pamd

@ -0,0 +1,7 @@ @@ -0,0 +1,7 @@
#%PAM-1.0
# This file is auto-generated.
# User changes will be destroyed the next time authconfig is run.

session [success=1 default=ignore] pam_succeed_if.so service !~ gdm* service !~ su* quiet
session [default=1] pam_lastlog.so nowtmp showfailed
session optional pam_lastlog.so silent noupdate showfailed

19
SOURCES/smartcard-auth.pamd

@ -0,0 +1,19 @@ @@ -0,0 +1,19 @@
#%PAM-1.0
# This file is auto-generated.
# User changes will be destroyed the next time authconfig 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

58
SOURCES/system-auth.5

@ -0,0 +1,58 @@ @@ -0,0 +1,58 @@
.TH SYSTEM-AUTH 5 "2010 Dec 22" "Red Hat" "Linux-PAM Manual"
.SH NAME

system-auth \- Common configuration file for PAMified services

.SH SYNOPSIS
.B /etc/pam.d/system-auth
.B /etc/pam.d/password-auth
.B /etc/pam.d/fingerprint-auth
.B /etc/pam.d/smartcard-auth
.sp 2
.SH DESCRIPTION

The purpose of these configuration files are to provide a common
interface for all applications and service daemons calling into
the PAM library.

.sp
The
.BR system-auth
configuration file is included from nearly all individual service configuration
files with the help of the
.BR substack
directive.

.sp
The
.BR password-auth
.BR fingerprint-auth
.BR smartcard-auth
configuration files are for applications which handle authentication from
different types of devices via simultaneously running individual conversations
instead of one aggregate conversation.

.SH NOTES
Previously these common configuration files were included with the help
of the
.BR include
directive. This limited the use of the different action types of modules.
With the use of
.BR substack
directive to include these common configuration files this limitation
no longer applies.

.SH BUGS
.sp 2
None known.

.SH "SEE ALSO"
pam(8), config-util(5), postlogin(5)

The three
.BR Linux-PAM
Guides, for
.BR "system administrators" ", "
.BR "module developers" ", "
and
.BR "application developers" ". "

18
SOURCES/system-auth.pamd

@ -0,0 +1,18 @@ @@ -0,0 +1,18 @@
#%PAM-1.0
# This file is auto-generated.
# User changes will be destroyed the next time authconfig is run.
auth required pam_env.so
auth sufficient pam_unix.so try_first_pass nullok
auth required pam_deny.so

account required pam_unix.so

password requisite pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type=
password sufficient pam_unix.so try_first_pass use_authtok nullok sha512 shadow
password required pam_deny.so

session optional pam_keyinit.so revoke
session required pam_limits.so
-session optional pam_systemd.so
session [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
session required pam_unix.so

2118
SPECS/pam.spec

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save