basebuilder_pel7ppc64bebuilder0
6 years ago
54 changed files with 9349 additions and 0 deletions
@ -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 |
@ -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) |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 \ |
@ -0,0 +1,26 @@ |
|||||||
|
diff -up Linux-PAM-1.1.0/modules/pam_console/console.handlers.nochmod Linux-PAM-1.1.0/modules/pam_console/console.handlers |
||||||
|
--- Linux-PAM-1.1.0/modules/pam_console/console.handlers.nochmod 2008-12-16 13:37:52.000000000 +0100 |
||||||
|
+++ Linux-PAM-1.1.0/modules/pam_console/console.handlers 2009-09-01 17:20:08.000000000 +0200 |
||||||
|
@@ -15,5 +15,3 @@ |
||||||
|
# touch unlock wait /var/run/console-unlocked |
||||||
|
|
||||||
|
console consoledevs tty[0-9][0-9]* vc/[0-9][0-9]* :[0-9]+\.[0-9]+ :[0-9]+ |
||||||
|
-/sbin/pam_console_apply lock logfail wait -t tty -s |
||||||
|
-/sbin/pam_console_apply unlock logfail wait -r -t tty -s |
||||||
|
diff -up Linux-PAM-1.1.0/modules/pam_console/Makefile.am.nochmod Linux-PAM-1.1.0/modules/pam_console/Makefile.am |
||||||
|
--- Linux-PAM-1.1.0/modules/pam_console/Makefile.am.nochmod 2008-12-16 13:37:52.000000000 +0100 |
||||||
|
+++ Linux-PAM-1.1.0/modules/pam_console/Makefile.am 2009-09-01 17:42:47.000000000 +0200 |
||||||
|
@@ -38,7 +38,6 @@ sbin_PROGRAMS = pam_console_apply |
||||||
|
|
||||||
|
|
||||||
|
secureconf_DATA = console.perms console.handlers |
||||||
|
-permsd_DATA = 50-default.perms |
||||||
|
|
||||||
|
FLEX_OPTS = -Cr |
||||||
|
BISON_OPTS = -d |
||||||
|
@@ -62,4 +61,5 @@ configfile.c: configfile.tab.c configfil |
||||||
|
|
||||||
|
install-data-local: |
||||||
|
mkdir -p $(DESTDIR)$(secureconfdir)/console.apps |
||||||
|
+ mkdir -p $(DESTDIR)$(permsddir) |
||||||
|
mkdir -m $(LOCKMODE) -p -p $(DESTDIR)$(LOCKDIR) |
@ -0,0 +1,12 @@ |
|||||||
|
diff -up Linux-PAM-1.1.0/modules/Makefile.am.notally Linux-PAM-1.1.0/modules/Makefile.am |
||||||
|
--- Linux-PAM-1.1.0/modules/Makefile.am.notally 2009-07-27 17:39:25.000000000 +0200 |
||||||
|
+++ Linux-PAM-1.1.0/modules/Makefile.am 2009-09-01 17:40:16.000000000 +0200 |
||||||
|
@@ -10,7 +10,7 @@ SUBDIRS = pam_access pam_cracklib pam_de |
||||||
|
pam_mkhomedir pam_motd pam_namespace pam_nologin \ |
||||||
|
pam_permit pam_pwhistory pam_rhosts pam_rootok pam_securetty \ |
||||||
|
pam_selinux pam_sepermit pam_shells pam_stress \ |
||||||
|
- pam_succeed_if pam_tally pam_tally2 pam_time pam_timestamp \ |
||||||
|
+ pam_succeed_if pam_tally2 pam_time pam_timestamp \ |
||||||
|
pam_tty_audit pam_umask \ |
||||||
|
pam_unix pam_userdb pam_warn pam_wheel pam_xauth |
||||||
|
|
@ -0,0 +1,12 @@ |
|||||||
|
diff -up Linux-PAM-1.1.1/modules/pam_console/pam_console_apply.c.errmsg Linux-PAM-1.1.1/modules/pam_console/pam_console_apply.c |
||||||
|
--- Linux-PAM-1.1.1/modules/pam_console/pam_console_apply.c.errmsg 2008-12-16 13:37:52.000000000 +0100 |
||||||
|
+++ Linux-PAM-1.1.1/modules/pam_console/pam_console_apply.c 2014-06-19 13:23:28.948343737 +0200 |
||||||
|
@@ -65,7 +65,7 @@ parse_files(void) |
||||||
|
on system locale */ |
||||||
|
oldlocale = setlocale(LC_COLLATE, "C"); |
||||||
|
|
||||||
|
- rc = glob(PERMS_GLOB, GLOB_NOCHECK, NULL, &globbuf); |
||||||
|
+ rc = glob(PERMS_GLOB, 0, NULL, &globbuf); |
||||||
|
setlocale(LC_COLLATE, oldlocale); |
||||||
|
if (rc) |
||||||
|
return; |
File diff suppressed because it is too large
Load Diff
@ -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 |
@ -0,0 +1,27 @@ |
|||||||
|
diff -up pam/modules/pam_env/pam_env.c.nouserenv pam/modules/pam_env/pam_env.c |
||||||
|
--- pam/modules/pam_env/pam_env.c.nouserenv 2010-10-20 09:59:30.000000000 +0200 |
||||||
|
+++ pam/modules/pam_env/pam_env.c 2010-11-01 14:42:01.000000000 +0100 |
||||||
|
@@ -10,7 +10,7 @@ |
||||||
|
#define DEFAULT_READ_ENVFILE 1 |
||||||
|
|
||||||
|
#define DEFAULT_USER_ENVFILE ".pam_environment" |
||||||
|
-#define DEFAULT_USER_READ_ENVFILE 1 |
||||||
|
+#define DEFAULT_USER_READ_ENVFILE 0 |
||||||
|
|
||||||
|
#include "config.h" |
||||||
|
|
||||||
|
diff -up pam/modules/pam_env/pam_env.8.xml.nouserenv pam/modules/pam_env/pam_env.8.xml |
||||||
|
--- pam/modules/pam_env/pam_env.8.xml.nouserenv 2010-10-20 09:59:30.000000000 +0200 |
||||||
|
+++ pam/modules/pam_env/pam_env.8.xml 2010-11-01 14:42:01.000000000 +0100 |
||||||
|
@@ -147,7 +147,10 @@ |
||||||
|
<listitem> |
||||||
|
<para> |
||||||
|
Turns on or off the reading of the user specific environment |
||||||
|
- file. 0 is off, 1 is on. By default this option is on. |
||||||
|
+ file. 0 is off, 1 is on. By default this option is off as user |
||||||
|
+ supplied environment variables in the PAM environment could affect |
||||||
|
+ behavior of subsequent modules in the stack without the consent |
||||||
|
+ of the system administrator. |
||||||
|
</para> |
||||||
|
</listitem> |
||||||
|
</varlistentry> |
@ -0,0 +1,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); |
@ -0,0 +1,20 @@ |
|||||||
|
diff -up Linux-PAM-1.1.6/modules/pam_limits/limits.conf.limits Linux-PAM-1.1.6/modules/pam_limits/limits.conf |
||||||
|
--- Linux-PAM-1.1.6/modules/pam_limits/limits.conf.limits 2012-08-15 13:08:43.000000000 +0200 |
||||||
|
+++ Linux-PAM-1.1.6/modules/pam_limits/limits.conf 2013-03-14 16:43:37.615087671 +0100 |
||||||
|
@@ -1,5 +1,16 @@ |
||||||
|
# /etc/security/limits.conf |
||||||
|
# |
||||||
|
+#This file sets the resource limits for the users logged in via PAM. |
||||||
|
+#It does not affect resource limits of the system services. |
||||||
|
+# |
||||||
|
+#Also note that configuration files in /etc/security/limits.d directory, |
||||||
|
+#which are read in alphabetical order, override the settings in this |
||||||
|
+#file in case the domain is the same or more specific. |
||||||
|
+#That means for example that setting a limit for wildcard domain here |
||||||
|
+#can be overriden with a wildcard setting in a config file in the |
||||||
|
+#subdirectory, but a user specific setting here can be overriden only |
||||||
|
+#with a user specific setting in the subdirectory. |
||||||
|
+# |
||||||
|
#Each line describes a limit for a user in the form: |
||||||
|
# |
||||||
|
#<domain> <type> <item> <value> |
@ -0,0 +1,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 = *~ |
||||||
|
|
@ -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); |
||||||
|
} |
||||||
|
} |
@ -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 |
@ -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; |
@ -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 <origin> 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> |
||||||
|
|
@ -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 |
||||||
|
|
@ -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 |
@ -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))) { |
@ -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 |
||||||
|
|
@ -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 |
||||||
|
|
@ -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; |
||||||
|
} |
@ -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> |
||||||
|
|
@ -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> |
@ -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 |
@ -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? */ |
@ -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; |
||||||
|
} |
||||||
|
|
@ -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; |
@ -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 |
@ -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; |
||||||
|
} |
@ -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> |
||||||
|
|
@ -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> |
||||||
|
|
@ -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> |
||||||
|
|
@ -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> |
||||||
|
|
||||||
|
|
@ -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); |
@ -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++; |
@ -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; |
||||||
|
+} |
||||||
|
+ |
@ -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; |
@ -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); |
File diff suppressed because it is too large
Load Diff
@ -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'> |
@ -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) |
@ -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 - |
@ -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 |
@ -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" ". " |
@ -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 |
@ -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 |
@ -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" ". " |
@ -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 |
Loading…
Reference in new issue