summaryrefslogtreecommitdiffstats
path: root/extra/source/pam/patches/pam-1.1.1-faillock.patch
diff options
context:
space:
mode:
author Patrick J Volkerding <volkerdi@slackware.com>2013-11-04 17:08:47 +0000
committer Eric Hameleers <alien@slackware.com>2018-05-31 22:57:36 +0200
commit76fc4757ac91ac7947a01fb7b53dddf9a78a01d1 (patch)
tree9b98e6e193c7870cb27ac861394c1c4592850922 /extra/source/pam/patches/pam-1.1.1-faillock.patch
parent9664bee729d487bcc0a0bc35859f8e13d5421c75 (diff)
downloadcurrent-76fc4757ac91ac7947a01fb7b53dddf9a78a01d1.tar.gz
current-76fc4757ac91ac7947a01fb7b53dddf9a78a01d1.tar.xz
Slackware 14.1slackware-14.1
Mon Nov 4 17:08:47 UTC 2013 Slackware 14.1 x86_64 stable is released! It's been another interesting release cycle here at Slackware bringing new features like support for UEFI machines, updated compilers and development tools, the switch from MySQL to MariaDB, and many more improvements throughout the system. Thanks to the team, the upstream developers, the dedicated Slackware community, and everyone else who pitched in to help make this release a reality. The ISOs are off to be replicated, a 6 CD-ROM 32-bit set and a dual-sided 32-bit/64-bit x86/x86_64 DVD. Please consider supporting the Slackware project by picking up a copy from store.slackware.com. We're taking pre-orders now, and offer a discount if you sign up for a subscription. Have fun! :-)
Diffstat (limited to 'extra/source/pam/patches/pam-1.1.1-faillock.patch')
-rw-r--r--extra/source/pam/patches/pam-1.1.1-faillock.patch1712
1 files changed, 0 insertions, 1712 deletions
diff --git a/extra/source/pam/patches/pam-1.1.1-faillock.patch b/extra/source/pam/patches/pam-1.1.1-faillock.patch
deleted file mode 100644
index 46f303741..000000000
--- a/extra/source/pam/patches/pam-1.1.1-faillock.patch
+++ /dev/null
@@ -1,1712 +0,0 @@
-diff -up Linux-PAM-1.1.1/configure.in.faillock Linux-PAM-1.1.1/configure.in
---- Linux-PAM-1.1.1/configure.in.faillock 2010-09-17 15:58:41.000000000 +0200
-+++ Linux-PAM-1.1.1/configure.in 2010-09-17 15:58:41.000000000 +0200
-@@ -539,7 +539,7 @@ AC_CONFIG_FILES([Makefile libpam/Makefil
- modules/pam_access/Makefile modules/pam_cracklib/Makefile \
- modules/pam_debug/Makefile modules/pam_deny/Makefile \
- modules/pam_echo/Makefile modules/pam_env/Makefile \
-- modules/pam_faildelay/Makefile \
-+ modules/pam_faildelay/Makefile modules/pam_faillock/Makefile \
- modules/pam_filter/Makefile modules/pam_filter/upperLOWER/Makefile \
- modules/pam_ftp/Makefile modules/pam_group/Makefile \
- modules/pam_issue/Makefile modules/pam_keyinit/Makefile \
-diff -up Linux-PAM-1.1.1/doc/sag/pam_faillock.xml.faillock Linux-PAM-1.1.1/doc/sag/pam_faillock.xml
---- Linux-PAM-1.1.1/doc/sag/pam_faillock.xml.faillock 2010-09-17 16:05:56.000000000 +0200
-+++ Linux-PAM-1.1.1/doc/sag/pam_faillock.xml 2010-09-17 16:08:26.000000000 +0200
-@@ -0,0 +1,38 @@
-+<?xml version='1.0' encoding='UTF-8'?>
-+<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
-+ "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
-+<section id='sag-pam_faillock'>
-+ <title>pam_faillock - temporarily locking access based on failed authentication attempts during an interval</title>
-+ <cmdsynopsis>
-+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
-+ href="../../modules/pam_faillock/pam_faillock.8.xml" xpointer='xpointer(//cmdsynopsis[@id = "pam_faillock-cmdsynopsisauth"]/*)'/>
-+ </cmdsynopsis>
-+ <cmdsynopsis>
-+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
-+ href="../../modules/pam_faillock/pam_faillock.8.xml" xpointer='xpointer(//cmdsynopsis[@id = "pam_faillock-cmdsynopsisacct"]/*)'/>
-+ </cmdsynopsis>
-+ <section id='sag-pam_faillock-description'>
-+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
-+ href="../../modules/pam_faillock/pam_faillock.8.xml" xpointer='xpointer(//refsect1[@id = "pam_faillock-description"]/*)'/>
-+ </section>
-+ <section id='sag-pam_faillock-options'>
-+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
-+ href="../../modules/pam_faillock/pam_faillock.8.xml" xpointer='xpointer(//refsect1[@id = "pam_faillock-options"]/*)'/>
-+ </section>
-+ <section id='sag-pam_faillock-types'>
-+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
-+ href="../../modules/pam_faillock/pam_faillock.8.xml" xpointer='xpointer(//refsect1[@id = "pam_faillock-types"]/*)'/>
-+ </section>
-+ <section id='sag-pam_faillock-return_values'>
-+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
-+ href="../../modules/pam_faillock/pam_faillock.8.xml" xpointer='xpointer(//refsect1[@id = "pam_faillock-return_values"]/*)'/>
-+ </section>
-+ <section id='sag-pam_faillock-examples'>
-+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
-+ href="../../modules/pam_faillock/pam_faillock.8.xml" xpointer='xpointer(//refsect1[@id = "pam_faillock-examples"]/*)'/>
-+ </section>
-+ <section id='sag-pam_faillock-author'>
-+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
-+ href="../../modules/pam_faillock/pam_faillock.8.xml" xpointer='xpointer(//refsect1[@id = "pam_faillock-author"]/*)'/>
-+ </section>
-+</section>
-diff -up Linux-PAM-1.1.1/modules/Makefile.am.faillock Linux-PAM-1.1.1/modules/Makefile.am
---- Linux-PAM-1.1.1/modules/Makefile.am.faillock 2010-09-17 15:58:41.000000000 +0200
-+++ Linux-PAM-1.1.1/modules/Makefile.am 2010-09-17 15:58:41.000000000 +0200
-@@ -3,7 +3,7 @@
- #
-
- SUBDIRS = pam_access pam_cracklib pam_debug pam_deny pam_echo \
-- pam_chroot pam_console pam_postgresok \
-+ pam_chroot pam_console pam_postgresok pam_faillock \
- 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.1.1/modules/pam_faillock/faillock.c.faillock Linux-PAM-1.1.1/modules/pam_faillock/faillock.c
---- Linux-PAM-1.1.1/modules/pam_faillock/faillock.c.faillock 2010-09-17 15:58:41.000000000 +0200
-+++ Linux-PAM-1.1.1/modules/pam_faillock/faillock.c 2010-09-17 15:58:41.000000000 +0200
-@@ -0,0 +1,147 @@
-+/*
-+ * Copyright (c) 2010 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 <string.h>
-+#include <stdlib.h>
-+#include <unistd.h>
-+#include <errno.h>
-+#include <sys/types.h>
-+#include <sys/stat.h>
-+#include <sys/file.h>
-+#include <fcntl.h>
-+#include <security/pam_modutil.h>
-+
-+#include "faillock.h"
-+
-+int
-+open_tally (const char *dir, const char *user, int create)
-+{
-+ char *path;
-+ int flags = O_RDWR;
-+ int fd;
-+
-+ if (strstr(user, "../") != NULL)
-+ /* just a defensive programming as the user must be a
-+ * valid user on the system anyway
-+ */
-+ return -1;
-+ path = malloc(strlen(dir) + strlen(user) + 2);
-+ if (path == NULL)
-+ return -1;
-+
-+ strcpy(path, dir);
-+ if (*dir && dir[strlen(dir) - 1] != '/') {
-+ strcat(path, "/");
-+ }
-+ strcat(path, user);
-+
-+ if (create) {
-+ flags |= O_CREAT;
-+ }
-+
-+ fd = open(path, flags, 0600);
-+
-+ if (fd != -1)
-+ while (flock(fd, LOCK_EX) == -1 && errno == EINTR);
-+
-+ return fd;
-+}
-+
-+#define CHUNK_SIZE (64 * sizeof(struct tally))
-+#define MAX_RECORDS 1024
-+
-+int
-+read_tally(int fd, struct tally_data *tallies)
-+{
-+ void *data = NULL, *newdata;
-+ unsigned int count = 0;
-+ ssize_t chunk = 0;
-+
-+ do {
-+ newdata = realloc(data, count * sizeof(struct tally) + CHUNK_SIZE);
-+ if (newdata == NULL) {
-+ free(data);
-+ return -1;
-+ }
-+
-+ data = newdata;
-+
-+ chunk = pam_modutil_read(fd, (char *)data + count * sizeof(struct tally), CHUNK_SIZE);
-+ if (chunk < 0) {
-+ free(data);
-+ return -1;
-+ }
-+
-+ count += chunk/sizeof(struct tally);
-+
-+ if (count >= MAX_RECORDS)
-+ break;
-+ }
-+ while (chunk == CHUNK_SIZE);
-+
-+ tallies->records = data;
-+ tallies->count = count;
-+
-+ return 0;
-+}
-+
-+int
-+update_tally(int fd, struct tally_data *tallies)
-+{
-+ void *data = tallies->records;
-+ unsigned int count = tallies->count;
-+ ssize_t chunk;
-+
-+ if (tallies->count > MAX_RECORDS) {
-+ data = tallies->records + (count - MAX_RECORDS);
-+ count = MAX_RECORDS;
-+ }
-+
-+ if (lseek(fd, 0, SEEK_SET) == (off_t)-1) {
-+ return -1;
-+ }
-+
-+ chunk = pam_modutil_write(fd, data, count * sizeof(struct tally));
-+
-+ if (chunk != (ssize_t)(count * sizeof(struct tally))) {
-+ return -1;
-+ }
-+
-+ if (ftruncate(fd, count * sizeof(struct tally)) == -1)
-+ return -1;
-+
-+ return 0;
-+}
-diff -up Linux-PAM-1.1.1/modules/pam_faillock/faillock.h.faillock Linux-PAM-1.1.1/modules/pam_faillock/faillock.h
---- Linux-PAM-1.1.1/modules/pam_faillock/faillock.h.faillock 2010-09-17 15:58:41.000000000 +0200
-+++ Linux-PAM-1.1.1/modules/pam_faillock/faillock.h 2010-09-17 15:58:41.000000000 +0200
-@@ -0,0 +1,72 @@
-+/*
-+ * Copyright (c) 2010 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.
-+ */
-+
-+/*
-+ * faillock.h - authentication failure data file record structure
-+ *
-+ * Each record in the file represents an instance of login failure of
-+ * the user at the recorded time
-+ */
-+
-+
-+#ifndef _FAILLOCK_H
-+#define _FAILLOCK_H
-+
-+#include <stdint.h>
-+
-+#define TALLY_STATUS_VALID 0x1 /* the tally file entry is valid */
-+#define TALLY_STATUS_RHOST 0x2 /* the source is rhost */
-+#define TALLY_STATUS_TTY 0x4 /* the source is tty - if both TALLY_FLAG_RHOST and TALLY_FLAG_TTY are not set the source is service */
-+
-+struct tally {
-+ char source[52]; /* rhost or tty of the login failure (not necessarily NULL terminated) */
-+ uint16_t reserved; /* reserved for future use */
-+ uint16_t status; /* record status */
-+ uint64_t time; /* time of the login failure */
-+};
-+/* 64 bytes per entry */
-+
-+struct tally_data {
-+ struct tally *records; /* array of tallies */
-+ unsigned int count; /* number of records */
-+};
-+
-+#define FAILLOCK_DEFAULT_TALLYDIR "/var/run/faillock"
-+
-+int open_tally(const char *dir, const char *user, 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.1/modules/pam_faillock/faillock.8.xml.faillock Linux-PAM-1.1.1/modules/pam_faillock/faillock.8.xml
---- Linux-PAM-1.1.1/modules/pam_faillock/faillock.8.xml.faillock 2010-09-17 15:58:41.000000000 +0200
-+++ Linux-PAM-1.1.1/modules/pam_faillock/faillock.8.xml 2010-09-17 15:58:41.000000000 +0200
-@@ -0,0 +1,123 @@
-+<?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="faillock">
-+
-+ <refmeta>
-+ <refentrytitle>faillock</refentrytitle>
-+ <manvolnum>8</manvolnum>
-+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
-+ </refmeta>
-+
-+ <refnamediv id="pam_faillock-name">
-+ <refname>faillock</refname>
-+ <refpurpose>Tool for displaying and modifying the authentication failure record files</refpurpose>
-+ </refnamediv>
-+
-+ <refsynopsisdiv>
-+ <cmdsynopsis id="faillock-cmdsynopsis">
-+ <command>faillock</command>
-+ <arg choice="opt">
-+ --dir <replaceable>/path/to/tally-directory</replaceable>
-+ </arg>
-+ <arg choice="opt">
-+ --user <replaceable>username</replaceable>
-+ </arg>
-+ <arg choice="opt">
-+ --reset
-+ </arg>
-+ </cmdsynopsis>
-+ </refsynopsisdiv>
-+
-+ <refsect1 id="faillock-description">
-+
-+ <title>DESCRIPTION</title>
-+
-+ <para>
-+ The <emphasis>pam_faillock.so</emphasis> module maintains a list of
-+ failed authentication attempts per user during a specified interval
-+ and locks the account in case there were more than
-+ <replaceable>deny</replaceable> consecutive failed authentications.
-+ It stores the failure records into per-user files in the tally
-+ directory.
-+ </para>
-+ <para>
-+ The <command>faillock</command> command is an application which
-+ can be used to examine and modify the contents of the
-+ the tally files. It can display the recent failed authentication
-+ attempts of the <replaceable>username</replaceable> or clear the tally
-+ files of all or individual <replaceable>usernames</replaceable>.
-+ </para>
-+ </refsect1>
-+
-+ <refsect1 id="faillock-options">
-+
-+ <title>OPTIONS</title>
-+ <variablelist>
-+ <varlistentry>
-+ <term>
-+ <option>--dir <replaceable>/path/to/tally-directory</replaceable></option>
-+ </term>
-+ <listitem>
-+ <para>
-+ The directory where the user files with the failure records are kept. The
-+ default is <filename>/var/run/faillock</filename>.
-+ </para>
-+ </listitem>
-+ </varlistentry>
-+ <varlistentry>
-+ <term>
-+ <option>--user <replaceable>username</replaceable></option>
-+ </term>
-+ <listitem>
-+ <para>
-+ The user whose failure records should be displayed or cleared.
-+ </para>
-+ </listitem>
-+ </varlistentry>
-+ <varlistentry>
-+ <term>
-+ <option>--reset</option>
-+ </term>
-+ <listitem>
-+ <para>
-+ Instead of displaying the user's failure records, clear them.
-+ </para>
-+ </listitem>
-+ </varlistentry>
-+ </variablelist>
-+ </refsect1>
-+
-+ <refsect1 id="faillock-files">
-+ <title>FILES</title>
-+ <variablelist>
-+ <varlistentry>
-+ <term><filename>/var/run/faillock/*</filename></term>
-+ <listitem>
-+ <para>the files logging the authentication failures for users</para>
-+ </listitem>
-+ </varlistentry>
-+ </variablelist>
-+ </refsect1>
-+
-+ <refsect1 id='faillock-see_also'>
-+ <title>SEE ALSO</title>
-+ <para>
-+ <citerefentry>
-+ <refentrytitle>pam_faillock</refentrytitle><manvolnum>8</manvolnum>
-+ </citerefentry>,
-+ <citerefentry>
-+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
-+ </citerefentry>
-+ </para>
-+ </refsect1>
-+
-+ <refsect1 id='faillock-author'>
-+ <title>AUTHOR</title>
-+ <para>
-+ faillock was written by Tomas Mraz.
-+ </para>
-+ </refsect1>
-+
-+</refentry>
-diff -up Linux-PAM-1.1.1/modules/pam_faillock/main.c.faillock Linux-PAM-1.1.1/modules/pam_faillock/main.c
---- Linux-PAM-1.1.1/modules/pam_faillock/main.c.faillock 2010-09-17 15:58:41.000000000 +0200
-+++ Linux-PAM-1.1.1/modules/pam_faillock/main.c 2010-09-17 15:58:41.000000000 +0200
-@@ -0,0 +1,231 @@
-+/*
-+ * Copyright (c) 2010 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 <dirent.h>
-+#include <errno.h>
-+#include <pwd.h>
-+#include <time.h>
-+#ifdef HAVE_LIBAUDIT
-+#include <libaudit.h>
-+#endif
-+
-+#include "faillock.h"
-+
-+struct options {
-+ unsigned int reset;
-+ const char *dir;
-+ const char *user;
-+ const char *progname;
-+};
-+
-+static int
-+args_parse(int argc, char **argv, struct options *opts)
-+{
-+ int i;
-+ memset(opts, 0, sizeof(*opts));
-+
-+ opts->dir = FAILLOCK_DEFAULT_TALLYDIR;
-+ opts->progname = argv[0];
-+
-+ for (i = 1; i < argc; ++i) {
-+
-+ if (strcmp(argv[i], "--dir") == 0) {
-+ ++i;
-+ if (i >= argc || strlen(argv[i]) == 0) {
-+ fprintf(stderr, "%s: No directory supplied.\n", argv[0]);
-+ return -1;
-+ }
-+ opts->dir = argv[i];
-+ }
-+ else if (strcmp(argv[i], "--user") == 0) {
-+ ++i;
-+ if (i >= argc || strlen(argv[i]) == 0) {
-+ fprintf(stderr, "%s: No user name supplied.\n", argv[0]);
-+ return -1;
-+ }
-+ opts->user = argv[i];
-+ }
-+ else if (strcmp(argv[i], "--reset") == 0) {
-+ opts->reset = 1;
-+ }
-+ else {
-+ fprintf(stderr, "%s: Unknown option: %s\n", argv[0], argv[i]);
-+ return -1;
-+ }
-+ }
-+ return 0;
-+}
-+
-+static void
-+usage(const char *progname)
-+{
-+ fprintf(stderr, _("Usage: %s [--dir /path/to/tally-directory] [--user username] [--reset]\n"),
-+ progname);
-+}
-+
-+static int
-+do_user(struct options *opts, const char *user)
-+{
-+ int fd;
-+ int rv;
-+ struct tally_data tallies;
-+
-+ fd = open_tally(opts->dir, user, 0);
-+
-+ if (fd == -1) {
-+ if (errno == ENOENT) {
-+ return 0;
-+ }
-+ else {
-+ fprintf(stderr, "%s: Error opening the tally file for %s:",
-+ opts->progname, user);
-+ perror(NULL);
-+ return 3;
-+ }
-+ }
-+ if (opts->reset) {
-+#ifdef HAVE_LIBAUDIT
-+ char buf[64];
-+ int audit_fd;
-+#endif
-+
-+ while ((rv=ftruncate(fd, 0)) == -1 && errno == EINTR);
-+ if (rv == -1) {
-+ fprintf(stderr, "%s: Error clearing the tally file for %s:",
-+ opts->progname, user);
-+ perror(NULL);
-+#ifdef HAVE_LIBAUDIT
-+ }
-+ if ((audit_fd=audit_open()) >= 0) {
-+ struct passwd *pwd;
-+
-+ if ((pwd=getpwnam(user)) != 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);
-+ }
-+ close(audit_fd);
-+ }
-+ if (rv == -1) {
-+#endif
-+ close(fd);
-+ return 4;
-+ }
-+ }
-+ else {
-+ unsigned int i;
-+
-+ memset(&tallies, 0, sizeof(tallies));
-+ if ((rv=read_tally(fd, &tallies)) == -1) {
-+ fprintf(stderr, "%s: Error reading the tally file for %s:",
-+ opts->progname, user);
-+ perror(NULL);
-+ close(fd);
-+ return 5;
-+ }
-+
-+ printf("%s:\n", user);
-+ printf("%-19s %-5s %-48s %-5s\n", "When", "Type", "Source", "Valid");
-+
-+ for (i = 0; i < tallies.count; i++) {
-+ struct tm *tm;
-+ char timebuf[80];
-+ uint16_t status = tallies.records[i].status;
-+ time_t when = tallies.records[i].time;
-+
-+ tm = localtime(&when);
-+ strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S", tm);
-+ printf("%-19s %-5s %-52.52s %s\n", timebuf,
-+ status & TALLY_STATUS_RHOST ? "RHOST" : (status & TALLY_STATUS_TTY ? "TTY" : "SVC"),
-+ tallies.records[i].source, status & TALLY_STATUS_VALID ? "V":"I");
-+ }
-+ free(tallies.records);
-+ }
-+ close(fd);
-+ return 0;
-+}
-+
-+static int
-+do_allusers(struct options *opts)
-+{
-+ struct dirent **userlist;
-+ int rv, i;
-+
-+ rv = scandir(opts->dir, &userlist, NULL, alphasort);
-+ if (rv < 0) {
-+ fprintf(stderr, "%s: Error reading tally directory: ", opts->progname);
-+ perror(NULL);
-+ return 2;
-+ }
-+
-+ for (i = 0; i < rv; i++) {
-+ if (userlist[i]->d_name[0] == '.') {
-+ if ((userlist[i]->d_name[1] == '.' && userlist[i]->d_name[2] == '\0') ||
-+ userlist[i]->d_name[1] == '\0')
-+ continue;
-+ }
-+ do_user(opts, userlist[i]->d_name);
-+ free(userlist[i]);
-+ }
-+ free(userlist);
-+
-+ return 0;
-+}
-+
-+
-+/*-----------------------------------------------------------------------*/
-+int
-+main (int argc, char *argv[])
-+{
-+ struct options opts;
-+
-+ if (args_parse(argc, argv, &opts)) {
-+ usage(argv[0]);
-+ return 1;
-+ }
-+
-+ if (opts.user == NULL) {
-+ return do_allusers(&opts);
-+ }
-+
-+ return do_user(&opts, opts.user);
-+}
-+
-diff -up Linux-PAM-1.1.1/modules/pam_faillock/Makefile.am.faillock Linux-PAM-1.1.1/modules/pam_faillock/Makefile.am
---- Linux-PAM-1.1.1/modules/pam_faillock/Makefile.am.faillock 2010-09-17 15:58:41.000000000 +0200
-+++ Linux-PAM-1.1.1/modules/pam_faillock/Makefile.am 2010-09-17 15:58:41.000000000 +0200
-@@ -0,0 +1,43 @@
-+#
-+# Copyright (c) 2005, 2006, 2007, 2009 Thorsten Kukuk <kukuk@thkukuk.de>
-+# Copyright (c) 2008 Red Hat, Inc.
-+# Copyright (c) 2010 Tomas Mraz <tmraz@redhat.com>
-+#
-+
-+CLEANFILES = *~
-+MAINTAINERCLEANFILES = $(MANS) README
-+
-+EXTRA_DIST = README $(MANS) $(XMLS) tst-pam_faillock
-+
-+man_MANS = pam_faillock.8 faillock.8
-+XMLS = README.xml pam_faillock.8.xml faillock.8.xml
-+
-+TESTS = tst-pam_faillock
-+
-+securelibdir = $(SECUREDIR)
-+secureconfdir = $(SCONFIGDIR)
-+
-+noinst_HEADERS = faillock.h
-+
-+faillock_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include
-+pam_faillock_la_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include
-+
-+pam_faillock_la_LDFLAGS = -no-undefined -avoid-version -module
-+pam_faillock_la_LIBADD = -L$(top_builddir)/libpam -lpam $(LIBAUDIT)
-+if HAVE_VERSIONING
-+ pam_faillock_la_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
-+endif
-+
-+faillock_LDADD = -L$(top_builddir)/libpam -lpam $(LIBAUDIT)
-+
-+securelib_LTLIBRARIES = pam_faillock.la
-+sbin_PROGRAMS = faillock
-+
-+pam_faillock_la_SOURCES = pam_faillock.c faillock.c
-+faillock_SOURCES = main.c faillock.c
-+
-+if ENABLE_REGENERATE_MAN
-+noinst_DATA = README
-+README: pam_faillock.8.xml
-+-include $(top_srcdir)/Make.xml.rules
-+endif
-diff -up Linux-PAM-1.1.1/modules/pam_faillock/pam_faillock.c.faillock Linux-PAM-1.1.1/modules/pam_faillock/pam_faillock.c
---- Linux-PAM-1.1.1/modules/pam_faillock/pam_faillock.c.faillock 2010-09-17 15:58:41.000000000 +0200
-+++ Linux-PAM-1.1.1/modules/pam_faillock/pam_faillock.c 2010-09-17 15:58:41.000000000 +0200
-@@ -0,0 +1,550 @@
-+/*
-+ * Copyright (c) 2010 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 <string.h>
-+#include <unistd.h>
-+#include <stdint.h>
-+#include <stdlib.h>
-+#include <errno.h>
-+#include <time.h>
-+#include <pwd.h>
-+#include <syslog.h>
-+
-+#ifdef HAVE_LIBAUDIT
-+#include <libaudit.h>
-+#endif
-+
-+#include <security/pam_modules.h>
-+#include <security/pam_modutil.h>
-+#include <security/pam_ext.h>
-+
-+#include "faillock.h"
-+
-+#define PAM_SM_AUTH
-+#define PAM_SM_ACCOUNT
-+
-+#define FAILLOCK_ACTION_PREAUTH 0
-+#define FAILLOCK_ACTION_AUTHSUCC 1
-+#define FAILLOCK_ACTION_AUTHFAIL 2
-+
-+#define FAILLOCK_FLAG_DENY_ROOT 0x1
-+#define FAILLOCK_FLAG_AUDIT 0x2
-+#define FAILLOCK_FLAG_SILENT 0x4
-+#define FAILLOCK_FLAG_NO_LOG_INFO 0x8
-+#define FAILLOCK_FLAG_UNLOCKED 0x10
-+
-+#define MAX_TIME_INTERVAL 604800 /* 7 days */
-+
-+struct options {
-+ unsigned int action;
-+ unsigned int flags;
-+ unsigned short deny;
-+ unsigned int fail_interval;
-+ unsigned int unlock_time;
-+ unsigned int root_unlock_time;
-+ const char *dir;
-+ const char *user;
-+ int failures;
-+ uint64_t latest_time;
-+ uid_t uid;
-+ uint64_t now;
-+};
-+
-+static void
-+args_parse(pam_handle_t *pamh, int argc, const char **argv,
-+ int flags, struct options *opts)
-+{
-+ int i;
-+ memset(opts, 0, sizeof(*opts));
-+
-+ opts->dir = FAILLOCK_DEFAULT_TALLYDIR;
-+ opts->deny = 3;
-+ opts->fail_interval = 900;
-+ opts->unlock_time = 600;
-+ opts->root_unlock_time = MAX_TIME_INTERVAL+1;
-+
-+ for (i = 0; i < argc; ++i) {
-+
-+ if (strncmp(argv[i], "dir=", 4) == 0) {
-+ if (argv[i][4] != '/') {
-+ pam_syslog(pamh, LOG_ERR,
-+ "Tally directory is not absolute path (%s); keeping default", argv[i]);
-+ } else {
-+ opts->dir = argv[i]+4;
-+ }
-+ }
-+ else if (strncmp(argv[i], "deny=", 5) == 0) {
-+ if (sscanf(argv[i]+5, "%hu", &opts->deny) != 1) {
-+ pam_syslog(pamh, LOG_ERR,
-+ "Bad number supplied for deny argument");
-+ }
-+ }
-+ else if (strncmp(argv[i], "fail_interval=", 14) == 0) {
-+ unsigned int temp;
-+ if (sscanf(argv[i]+14, "%u", &temp) != 1 ||
-+ temp > MAX_TIME_INTERVAL) {
-+ pam_syslog(pamh, LOG_ERR,
-+ "Bad number supplied for fail_interval argument");
-+ } else {
-+ opts->fail_interval = temp;
-+ }
-+ }
-+ else if (strncmp(argv[i], "unlock_time=", 12) == 0) {
-+ unsigned int temp;
-+ 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 {
-+ 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 ||
-+ temp > MAX_TIME_INTERVAL) {
-+ pam_syslog(pamh, LOG_ERR,
-+ "Bad number supplied for root_unlock_time argument");
-+ } else {
-+ opts->root_unlock_time = temp;
-+ }
-+ }
-+ else if (strcmp(argv[i], "preauth") == 0) {
-+ opts->action = FAILLOCK_ACTION_PREAUTH;
-+ }
-+ else if (strcmp(argv[i], "authfail") == 0) {
-+ opts->action = FAILLOCK_ACTION_AUTHFAIL;
-+ }
-+ else if (strcmp(argv[i], "authsucc") == 0) {
-+ opts->action = FAILLOCK_ACTION_AUTHSUCC;
-+ }
-+ else if (strcmp(argv[i], "even_deny_root") == 0) {
-+ opts->flags |= FAILLOCK_FLAG_DENY_ROOT;
-+ }
-+ else if (strcmp(argv[i], "audit") == 0) {
-+ opts->flags |= FAILLOCK_FLAG_AUDIT;
-+ }
-+ else if (strcmp(argv[i], "silent") == 0) {
-+ opts->flags |= FAILLOCK_FLAG_SILENT;
-+ }
-+ else if (strcmp(argv[i], "no_log_info") == 0) {
-+ opts->flags |= FAILLOCK_FLAG_NO_LOG_INFO;
-+ }
-+ else {
-+ pam_syslog(pamh, LOG_ERR, "Unknown option: %s", argv[i]);
-+ }
-+ }
-+
-+ if (opts->root_unlock_time == MAX_TIME_INTERVAL+1)
-+ opts->root_unlock_time = opts->unlock_time;
-+ if (flags & PAM_SILENT)
-+ opts->flags |= FAILLOCK_FLAG_SILENT;
-+}
-+
-+static int get_pam_user(pam_handle_t *pamh, struct options *opts)
-+{
-+ const char *user;
-+ int rv;
-+ struct passwd *pwd;
-+
-+ if ((rv=pam_get_user(pamh, &user, NULL)) != PAM_SUCCESS) {
-+ return rv;
-+ }
-+
-+ if (*user == '\0') {
-+ return PAM_IGNORE;
-+ }
-+
-+ if ((pwd=pam_modutil_getpwnam(pamh, user)) == NULL) {
-+ if (opts->flags & FAILLOCK_FLAG_AUDIT) {
-+ pam_syslog(pamh, LOG_ERR, "User unknown: %s", user);
-+ }
-+ else {
-+ pam_syslog(pamh, LOG_ERR, "User unknown");
-+ }
-+ return PAM_IGNORE;
-+ }
-+ opts->user = user;
-+ opts->uid = pwd->pw_uid;
-+ return PAM_SUCCESS;
-+}
-+
-+static int
-+check_tally(pam_handle_t *pamh, struct options *opts, struct tally_data *tallies, int *fd)
-+{
-+ int tfd;
-+ unsigned int i;
-+ uint64_t latest_time;
-+ int failures;
-+
-+ opts->now = time(NULL);
-+
-+ tfd = open_tally(opts->dir, opts->user, 0);
-+
-+ *fd = tfd;
-+
-+ if (tfd == -1) {
-+ if (errno == EACCES || errno == ENOENT) {
-+ return PAM_SUCCESS;
-+ }
-+ pam_syslog(pamh, LOG_ERR, "Error opening the tally file for %s: %m", opts->user);
-+ return PAM_SYSTEM_ERR;
-+ }
-+
-+ if (read_tally(tfd, tallies) != 0) {
-+ pam_syslog(pamh, LOG_ERR, "Error reading the tally file for %s: %m", opts->user);
-+ return PAM_SYSTEM_ERR;
-+ }
-+
-+ if (opts->uid == 0 && !(opts->flags & FAILLOCK_FLAG_DENY_ROOT)) {
-+ return PAM_SUCCESS;
-+ }
-+
-+ latest_time = 0;
-+ for(i = 0; i < tallies->count; i++) {
-+ if ((tallies->records[i].status & TALLY_STATUS_VALID) &&
-+ tallies->records[i].time > latest_time)
-+ latest_time = tallies->records[i].time;
-+ }
-+
-+ opts->latest_time = latest_time;
-+
-+ failures = 0;
-+ for(i = 0; i < tallies->count; i++) {
-+ if ((tallies->records[i].status & TALLY_STATUS_VALID) &&
-+ latest_time - tallies->records[i].time < opts->fail_interval) {
-+ ++failures;
-+ }
-+ }
-+
-+ 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 && latest_time + opts->unlock_time < opts->now) ||
-+ (!opts->uid && 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;
-+
-+ audit_fd = audit_open();
-+ /* If there is an error & audit support is in the kernel report error */
-+ if ((audit_fd < 0) && !(errno == EINVAL || errno == EPROTONOSUPPORT ||
-+ errno == EAFNOSUPPORT))
-+ return PAM_SYSTEM_ERR;
-+
-+ 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);
-+ }
-+#endif
-+ opts->flags |= FAILLOCK_FLAG_UNLOCKED;
-+ return PAM_SUCCESS;
-+ }
-+ return PAM_AUTH_ERR;
-+ }
-+ return PAM_SUCCESS;
-+}
-+
-+static void
-+reset_tally(pam_handle_t *pamh, struct options *opts, int *fd)
-+{
-+ 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);
-+ }
-+}
-+
-+static int
-+write_tally(pam_handle_t *pamh, struct options *opts, struct tally_data *tallies, int *fd)
-+{
-+ struct tally *records;
-+ unsigned int i;
-+ int failures;
-+ unsigned int oldest;
-+ uint64_t oldtime;
-+ const void *source = NULL;
-+
-+ if (*fd == -1) {
-+ *fd = open_tally(opts->dir, opts->user, 1);
-+ }
-+ if (*fd == -1) {
-+ if (errno == EACCES) {
-+ return PAM_SUCCESS;
-+ }
-+ pam_syslog(pamh, LOG_ERR, "Error opening the tally file for %s: %m", opts->user);
-+ return PAM_SYSTEM_ERR;
-+ }
-+
-+ oldtime = 0;
-+ oldest = 0;
-+ failures = 0;
-+
-+ for (i = 0; i < tallies->count; ++i) {
-+ if (tallies->records[i].time < oldtime) {
-+ oldtime = tallies->records[i].time;
-+ oldest = i;
-+ }
-+ if (opts->flags & FAILLOCK_FLAG_UNLOCKED ||
-+ opts->now - tallies->records[i].time >= opts->fail_interval ) {
-+ tallies->records[i].status &= ~TALLY_STATUS_VALID;
-+ } else {
-+ ++failures;
-+ }
-+ }
-+
-+ if (oldest >= tallies->count || (tallies->records[oldest].status & TALLY_STATUS_VALID)) {
-+ oldest = tallies->count;
-+
-+ if ((records=realloc(tallies->records, (oldest+1) * sizeof (*tallies->records))) == NULL) {
-+ pam_syslog(pamh, LOG_CRIT, "Error allocating memory for tally records: %m");
-+ return PAM_BUF_ERR;
-+ }
-+
-+ ++tallies->count;
-+ tallies->records = records;
-+ }
-+
-+ memset(&tallies->records[oldest], 0, sizeof (*tallies->records));
-+
-+ tallies->records[oldest].status = TALLY_STATUS_VALID;
-+ if (pam_get_item(pamh, PAM_RHOST, &source) != PAM_SUCCESS || source == NULL) {
-+ if (pam_get_item(pamh, PAM_TTY, &source) != PAM_SUCCESS || source == NULL) {
-+ if (pam_get_item(pamh, PAM_SERVICE, &source) != PAM_SUCCESS || source == NULL) {
-+ source = "";
-+ }
-+ }
-+ else {
-+ tallies->records[oldest].status |= TALLY_STATUS_TTY;
-+ }
-+ }
-+ else {
-+ tallies->records[oldest].status |= TALLY_STATUS_RHOST;
-+ }
-+
-+ strncpy(tallies->records[oldest].source, source, sizeof(tallies->records[oldest].source));
-+ /* source does not have to be null terminated */
-+
-+ tallies->records[oldest].time = opts->now;
-+
-+ ++failures;
-+
-+ if (opts->deny && failures == opts->deny) {
-+#ifdef HAVE_LIBAUDIT
-+ char buf[64];
-+ int audit_fd;
-+
-+ audit_fd = audit_open();
-+ /* If there is an error & audit support is in the kernel report error */
-+ if ((audit_fd < 0) && !(errno == EINVAL || errno == EPROTONOSUPPORT ||
-+ errno == EAFNOSUPPORT))
-+ return PAM_SYSTEM_ERR;
-+
-+ snprintf(buf, sizeof(buf), "pam_faillock uid=%u ", opts->uid);
-+ 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)) {
-+ audit_log_user_message(audit_fd, AUDIT_RESP_ACCT_LOCK, buf,
-+ NULL, NULL, NULL, 1);
-+ }
-+ close(audit_fd);
-+#endif
-+ if (!(opts->flags & FAILLOCK_FLAG_NO_LOG_INFO)) {
-+ pam_syslog(pamh, LOG_INFO, "Consecutive login failures for user %s account temporarily locked",
-+ opts->user);
-+ }
-+ }
-+
-+ if (update_tally(*fd, tallies) == 0)
-+ return PAM_SUCCESS;
-+
-+ return PAM_SYSTEM_ERR;
-+}
-+
-+static void
-+faillock_message(pam_handle_t *pamh, struct options *opts)
-+{
-+ int64_t left;
-+
-+ if (!(opts->flags & FAILLOCK_FLAG_SILENT)) {
-+ if (opts->uid) {
-+ left = opts->latest_time + opts->unlock_time - opts->now;
-+ }
-+ else {
-+ left = opts->latest_time + opts->root_unlock_time - opts->now;
-+ }
-+
-+ left /= 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);
-+ }
-+}
-+
-+static void
-+tally_cleanup(struct tally_data *tallies, int fd)
-+{
-+ if (fd != -1) {
-+ close(fd);
-+ }
-+
-+ free(tallies->records);
-+}
-+
-+/*---------------------------------------------------------------------*/
-+
-+PAM_EXTERN int
-+pam_sm_authenticate(pam_handle_t *pamh, int flags,
-+ int argc, const char **argv)
-+{
-+ struct options opts;
-+ int rv, fd = -1;
-+ struct tally_data tallies;
-+
-+ memset(&tallies, 0, sizeof(tallies));
-+
-+ args_parse(pamh, argc, argv, flags, &opts);
-+
-+ pam_fail_delay(pamh, 2000000); /* 2 sec delay for on failure */
-+
-+ if ((rv=get_pam_user(pamh, &opts)) != PAM_SUCCESS) {
-+ return rv;
-+ }
-+
-+ switch (opts.action) {
-+ case FAILLOCK_ACTION_PREAUTH:
-+ rv = check_tally(pamh, &opts, &tallies, &fd);
-+ if (rv == PAM_AUTH_ERR && !(opts.flags & FAILLOCK_FLAG_SILENT)) {
-+ faillock_message(pamh, &opts);
-+ }
-+ break;
-+
-+ case FAILLOCK_ACTION_AUTHSUCC:
-+ rv = check_tally(pamh, &opts, &tallies, &fd);
-+ if (rv == PAM_SUCCESS && fd != -1) {
-+ reset_tally(pamh, &opts, &fd);
-+ }
-+ break;
-+
-+ case FAILLOCK_ACTION_AUTHFAIL:
-+ rv = check_tally(pamh, &opts, &tallies, &fd);
-+ if (rv == PAM_SUCCESS) {
-+ rv = PAM_IGNORE; /* this return value should be ignored */
-+ write_tally(pamh, &opts, &tallies, &fd);
-+ }
-+ break;
-+ }
-+
-+ tally_cleanup(&tallies, fd);
-+
-+ return rv;
-+}
-+
-+/*---------------------------------------------------------------------*/
-+
-+PAM_EXTERN int
-+pam_sm_setcred(pam_handle_t *pamh UNUSED, int flags UNUSED,
-+ int argc UNUSED, const char **argv UNUSED)
-+{
-+ return PAM_SUCCESS;
-+}
-+
-+/*---------------------------------------------------------------------*/
-+
-+PAM_EXTERN int
-+pam_sm_acct_mgmt(pam_handle_t *pamh, int flags,
-+ int argc, const char **argv)
-+{
-+ struct options opts;
-+ int rv, fd = -1;
-+ struct tally_data tallies;
-+
-+ memset(&tallies, 0, sizeof(tallies));
-+
-+ args_parse(pamh, argc, argv, flags, &opts);
-+
-+ opts.action = FAILLOCK_ACTION_AUTHSUCC;
-+
-+ if ((rv=get_pam_user(pamh, &opts)) != PAM_SUCCESS) {
-+ return rv;
-+ }
-+
-+ check_tally(pamh, &opts, &tallies, &fd);
-+ if (fd != -1) {
-+ reset_tally(pamh, &opts, &fd);
-+ }
-+
-+ tally_cleanup(&tallies, fd);
-+
-+ return PAM_SUCCESS;
-+}
-+
-+/*-----------------------------------------------------------------------*/
-+
-+#ifdef PAM_STATIC
-+
-+/* static module data */
-+
-+struct pam_module _pam_faillock_modstruct = {
-+ MODULE_NAME,
-+#ifdef PAM_SM_AUTH
-+ pam_sm_authenticate,
-+ pam_sm_setcred,
-+#else
-+ NULL,
-+ NULL,
-+#endif
-+#ifdef PAM_SM_ACCOUNT
-+ pam_sm_acct_mgmt,
-+#else
-+ NULL,
-+#endif
-+ NULL,
-+ NULL,
-+ NULL,
-+};
-+
-+#endif /* #ifdef PAM_STATIC */
-+
-diff -up Linux-PAM-1.1.1/modules/pam_faillock/pam_faillock.8.xml.faillock Linux-PAM-1.1.1/modules/pam_faillock/pam_faillock.8.xml
---- Linux-PAM-1.1.1/modules/pam_faillock/pam_faillock.8.xml.faillock 2010-09-17 15:58:41.000000000 +0200
-+++ Linux-PAM-1.1.1/modules/pam_faillock/pam_faillock.8.xml 2010-09-17 15:58:41.000000000 +0200
-@@ -0,0 +1,396 @@
-+<?xml version="1.0" encoding='UTF-8'?>
-+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
-+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
-+
-+<refentry id="pam_faillock">
-+
-+ <refmeta>
-+ <refentrytitle>pam_faillock</refentrytitle>
-+ <manvolnum>8</manvolnum>
-+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
-+ </refmeta>
-+
-+ <refnamediv id="pam_faillock-name">
-+ <refname>pam_faillock</refname>
-+ <refpurpose>Module counting authentication failures during a specified interval</refpurpose>
-+ </refnamediv>
-+
-+ <refsynopsisdiv>
-+ <cmdsynopsis id="pam_faillock-cmdsynopsisauth">
-+ <command>auth ... pam_faillock.so</command>
-+ <arg choice="req">
-+ preauth|authfail|authsucc
-+ </arg>
-+ <arg choice="opt">
-+ dir=<replaceable>/path/to/tally-directory</replaceable>
-+ </arg>
-+ <arg choice="opt">
-+ even_deny_root
-+ </arg>
-+ <arg choice="opt">
-+ deny=<replaceable>n</replaceable>
-+ </arg>
-+ <arg choice="opt">
-+ fail_interval=<replaceable>n</replaceable>
-+ </arg>
-+ <arg choice="opt">
-+ unlock_time=<replaceable>n</replaceable>
-+ </arg>
-+ <arg choice="opt">
-+ root_unlock_time=<replaceable>n</replaceable>
-+ </arg>
-+ <arg choice="opt">
-+ audit
-+ </arg>
-+ <arg choice="opt">
-+ silent
-+ </arg>
-+ <arg choice="opt">
-+ no_log_info
-+ </arg>
-+ </cmdsynopsis>
-+ <cmdsynopsis id="pam_faillock-cmdsynopsisacct">
-+ <command>account ... pam_faillock.so</command>
-+ <arg choice="opt">
-+ dir=<replaceable>/path/to/tally-directory</replaceable>
-+ </arg>
-+ <arg choice="opt">
-+ no_log_info
-+ </arg>
-+ </cmdsynopsis>
-+ </refsynopsisdiv>
-+
-+ <refsect1 id="pam_faillock-description">
-+
-+ <title>DESCRIPTION</title>
-+
-+ <para>
-+ This module maintains a list of failed authentication attempts per
-+ user during a specified interval and locks the account in case
-+ there were more than <replaceable>deny</replaceable> consecutive
-+ failed authentications.
-+ </para>
-+ <para>
-+ Normally, failed attempts to authenticate <emphasis>root</emphasis> will
-+ <emphasis remap='B'>not</emphasis> cause the root account to become
-+ blocked, to prevent denial-of-service: if your users aren't given
-+ shell accounts and root may only login via <command>su</command> or
-+ at the machine console (not telnet/rsh, etc), this is safe.
-+ </para>
-+ </refsect1>
-+
-+ <refsect1 id="pam_faillock-options">
-+
-+ <title>OPTIONS</title>
-+ <variablelist>
-+ <varlistentry>
-+ <term>
-+ <option>{preauth|authfail|authsucc}</option>
-+ </term>
-+ <listitem>
-+ <para>
-+ This argument must be set accordingly to the position of this module
-+ instance in the PAM stack.
-+ </para>
-+ <para>
-+ The <emphasis>preauth</emphasis> argument must be used when the module
-+ is called before the modules which ask for the user credentials such
-+ as the password. The module just examines whether the user should
-+ be blocked from accessing the service in case there were anomalous
-+ number of failed consecutive authentication attempts recently. This
-+ call is optional if <emphasis>authsucc</emphasis> is used.
-+ </para>
-+ <para>
-+ The <emphasis>authfail</emphasis> argument must be used when the module
-+ is called after the modules which determine the authentication outcome,
-+ failed. Unless the user is already blocked due to previous authentication
-+ failures, the module will record the failure into the appropriate user
-+ tally file.
-+ </para>
-+ <para>
-+ The <emphasis>authsucc</emphasis> argument must be used when the module
-+ is called after the modules which determine the authentication outcome,
-+ succeded. Unless the user is already blocked due to previous authentication
-+ failures, the module will then clear the record of the failures in the
-+ respective user tally file. Otherwise it will return authentication error.
-+ If this call is not done, the pam_faillock will not distinguish between
-+ consecutive and non-consecutive failed authentication attempts. The
-+ <emphasis>preauth</emphasis> call must be used in such case. Due to
-+ complications in the way the PAM stack can be configured it is also
-+ possible to call <emphasis>pam_faillock</emphasis> as an account module.
-+ In such configuration the module must be also called in the
-+ <emphasis>preauth</emphasis> stage.
-+ </para>
-+ </listitem>
-+ </varlistentry>
-+ <varlistentry>
-+ <term>
-+ <option>dir=<replaceable>/path/to/tally-directory</replaceable></option>
-+ </term>
-+ <listitem>
-+ <para>
-+ The directory where the user files with the failure records are kept. The
-+ default is <filename>/var/run/faillock</filename>.
-+ </para>
-+ </listitem>
-+ </varlistentry>
-+ <varlistentry>
-+ <term>
-+ <option>audit</option>
-+ </term>
-+ <listitem>
-+ <para>
-+ Will log the user name into the system log if the user is not found.
-+ </para>
-+ </listitem>
-+ </varlistentry>
-+ <varlistentry>
-+ <term>
-+ <option>silent</option>
-+ </term>
-+ <listitem>
-+ <para>
-+ Don't print informative messages. This option is implicite
-+ in the <emphasis>authfail</emphasis> and <emphasis>authsucc</emphasis>
-+ functions.
-+ </para>
-+ </listitem>
-+ </varlistentry>
-+ <varlistentry>
-+ <term>
-+ <option>no_log_info</option>
-+ </term>
-+ <listitem>
-+ <para>
-+ Don't log informative messages via <citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
-+ </para>
-+ </listitem>
-+ </varlistentry>
-+ <varlistentry>
-+ <term>
-+ <option>deny=<replaceable>n</replaceable></option>
-+ </term>
-+ <listitem>
-+ <para>
-+ Deny access if the number of consecutive authentication failures
-+ for this user during the recent interval exceeds
-+ <replaceable>n</replaceable>. The default is 3.
-+ </para>
-+ </listitem>
-+ </varlistentry>
-+ <varlistentry>
-+ <term>
-+ <option>fail_interval=<replaceable>n</replaceable></option>
-+ </term>
-+ <listitem>
-+ <para>
-+ The length of the interval during which the consecutive
-+ authentication failures must happen for the user account
-+ lock out is <replaceable>n</replaceable> seconds.
-+ The default is 900 (15 minutes).
-+ </para>
-+ </listitem>
-+ </varlistentry>
-+ <varlistentry>
-+ <term>
-+ <option>unlock_time=<replaceable>n</replaceable></option>
-+ </term>
-+ <listitem>
-+ <para>
-+ The access will be reenabled after
-+ <replaceable>n</replaceable> seconds after the lock out.
-+ The default is 600 (10 minutes).
-+ </para>
-+ </listitem>
-+ </varlistentry>
-+ <varlistentry>
-+ <term>
-+ <option>even_deny_root</option>
-+ </term>
-+ <listitem>
-+ <para>
-+ Root account can become locked as well as regular accounts.
-+ </para>
-+ </listitem>
-+ </varlistentry>
-+ <varlistentry>
-+ <term>
-+ <option>root_unlock_time=<replaceable>n</replaceable></option>
-+ </term>
-+ <listitem>
-+ <para>
-+ This option implies <option>even_deny_root</option> option.
-+ Allow access after <replaceable>n</replaceable> seconds
-+ to root account after the account is locked. In case the
-+ option is not specified the value is the same as of the
-+ <option>unlock_time</option> option.
-+ </para>
-+ </listitem>
-+ </varlistentry>
-+ </variablelist>
-+ </refsect1>
-+
-+ <refsect1 id="pam_faillock-types">
-+ <title>MODULE TYPES PROVIDED</title>
-+ <para>
-+ The <option>auth</option> and <option>account</option> module types are
-+ provided.
-+ </para>
-+ </refsect1>
-+
-+ <refsect1 id='pam_faillock-return_values'>
-+ <title>RETURN VALUES</title>
-+ <variablelist>
-+ <varlistentry>
-+ <term>PAM_AUTH_ERR</term>
-+ <listitem>
-+ <para>
-+ A invalid option was given, the module was not able
-+ to retrieve the user name, no valid counter file
-+ was found, or too many failed logins.
-+ </para>
-+ </listitem>
-+ </varlistentry>
-+ <varlistentry>
-+ <term>PAM_SUCCESS</term>
-+ <listitem>
-+ <para>
-+ Everything was successful.
-+ </para>
-+ </listitem>
-+ </varlistentry>
-+ <varlistentry>
-+ <term>PAM_IGNORE</term>
-+ <listitem>
-+ <para>
-+ User not present in passwd database.
-+ </para>
-+ </listitem>
-+ </varlistentry>
-+ </variablelist>
-+ </refsect1>
-+
-+ <refsect1 id='pam_faillock-notes'>
-+ <title>NOTES</title>
-+ <para>
-+ <emphasis>pam_faillock</emphasis> setup in the PAM stack is different
-+ 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>.
-+ </para>
-+ <para>
-+ Note that using the module in <option>preauth</option> without the
-+ <option>silent</option> option or with <emphasis>requisite</emphasis>
-+ control field leaks an information about existence or
-+ non-existence of an user account in the system because
-+ the failures are not recorded for the unknown users. The message
-+ about the user account being locked is never displayed for nonexisting
-+ user accounts allowing the adversary to infer that a particular account
-+ is not existing on a system.
-+ </para>
-+ </refsect1>
-+
-+ <refsect1 id='pam_faillock-examples'>
-+ <title>EXAMPLES</title>
-+ <para>
-+ Here are two possible configuration examples for <filename>/etc/pam.d/login</filename>.
-+ They make <emphasis>pam_faillock</emphasis> to lock the account after 4 consecutive
-+ failed logins during the default interval of 15 minutes. Root account will be locked
-+ as well. The accounts will be automatically unlocked after 20 minutes.
-+ </para>
-+ <para>
-+ In the first example the module is called only in the <emphasis>auth</emphasis>
-+ phase and the module does not print any information about the account blocking
-+ by <emphasis>pam_faillock</emphasis>. The <emphasis>preauth</emphasis> call can
-+ be added to tell the user that his login is blocked by the module and also to abort
-+ the authentication without even asking for password in such case.
-+ </para>
-+ <programlisting>
-+auth required pam_securetty.so
-+auth required pam_env.so
-+auth required pam_nologin.so
-+# optionally call: auth requisite pam_faillock.so preauth deny=4 even_deny_root unlock_time=1200
-+# to display the message about account being locked
-+auth [success=1 default=bad] pam_unix.so
-+auth [default=die] pam_faillock.so authfail deny=4 even_deny_root unlock_time=1200
-+auth sufficient pam_faillock.so authsucc deny=4 even_deny_root unlock_time=1200
-+auth required pam_deny.so
-+account required pam_unix.so
-+password required pam_unix.so shadow
-+session required pam_selinux.so close
-+session required pam_loginuid.so
-+session required pam_unix.so
-+session required pam_selinux.so open
-+ </programlisting>
-+ <para>
-+ In the second example the module is called both in the <emphasis>auth</emphasis>
-+ and <emphasis>account</emphasis> phases and the module gives the authenticating
-+ user message when the account is locked
-+ </para>
-+ <programlisting>
-+auth required pam_securetty.so
-+auth required pam_env.so
-+auth required pam_nologin.so
-+auth required pam_faillock.so preauth silent deny=4 even_deny_root unlock_time=1200
-+# optionally use requisite above if you do not want to prompt for the password
-+# on locked accounts, possibly with removing the silent option as well
-+auth sufficient pam_unix.so
-+auth [default=die] pam_faillock.so authfail deny=4 even_deny_root unlock_time=1200
-+auth required pam_deny.so
-+account required pam_faillock.so
-+# if you drop the above call to pam_faillock.so the lock will be done also
-+# on non-consecutive authentication failures
-+account required pam_unix.so
-+password required pam_unix.so shadow
-+session required pam_selinux.so close
-+session required pam_loginuid.so
-+session required pam_unix.so
-+session required pam_selinux.so open
-+ </programlisting>
-+ </refsect1>
-+
-+ <refsect1 id="pam_faillock-files">
-+ <title>FILES</title>
-+ <variablelist>
-+ <varlistentry>
-+ <term><filename>/var/run/faillock/*</filename></term>
-+ <listitem>
-+ <para>the files logging the authentication failures for users</para>
-+ </listitem>
-+ </varlistentry>
-+ </variablelist>
-+ </refsect1>
-+
-+ <refsect1 id='pam_faillock-see_also'>
-+ <title>SEE ALSO</title>
-+ <para>
-+ <citerefentry>
-+ <refentrytitle>faillock</refentrytitle><manvolnum>8</manvolnum>
-+ </citerefentry>,
-+ <citerefentry>
-+ <refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
-+ </citerefentry>,
-+ <citerefentry>
-+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
-+ </citerefentry>,
-+ <citerefentry>
-+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
-+ </citerefentry>
-+ </para>
-+ </refsect1>
-+
-+ <refsect1 id='pam_faillock-author'>
-+ <title>AUTHOR</title>
-+ <para>
-+ pam_faillock was written by Tomas Mraz.
-+ </para>
-+ </refsect1>
-+
-+</refentry>
-diff -up Linux-PAM-1.1.1/modules/pam_faillock/README.xml.faillock Linux-PAM-1.1.1/modules/pam_faillock/README.xml
---- Linux-PAM-1.1.1/modules/pam_faillock/README.xml.faillock 2010-09-17 15:58:41.000000000 +0200
-+++ Linux-PAM-1.1.1/modules/pam_faillock/README.xml 2010-09-17 15:58:41.000000000 +0200
-@@ -0,0 +1,46 @@
-+<?xml version="1.0" encoding='UTF-8'?>
-+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
-+"http://www.docbook.org/xml/4.3/docbookx.dtd"
-+[
-+<!--
-+<!ENTITY pamaccess SYSTEM "pam_faillock.8.xml">
-+-->
-+]>
-+
-+<article>
-+
-+ <articleinfo>
-+
-+ <title>
-+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
-+ href="pam_faillock.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_faillock-name"]/*)'/>
-+ </title>
-+
-+ </articleinfo>
-+
-+ <section>
-+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
-+ href="pam_faillock.8.xml" xpointer='xpointer(//refsect1[@id = "pam_faillock-description"]/*)'/>
-+ </section>
-+
-+ <section>
-+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
-+ href="pam_faillock.8.xml" xpointer='xpointer(//refsect1[@id = "pam_faillock-options"]/*)'/>
-+ </section>
-+
-+ <section>
-+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
-+ href="pam_faillock.8.xml" xpointer='xpointer(//refsect1[@id = "pam_faillock-notes"]/*)'/>
-+ </section>
-+
-+ <section>
-+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
-+ href="pam_faillock.8.xml" xpointer='xpointer(//refsect1[@id = "pam_faillock-examples"]/*)'/>
-+ </section>
-+
-+ <section>
-+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
-+ href="pam_faillock.8.xml" xpointer='xpointer(//refsect1[@id = "pam_faillock-author"]/*)'/>
-+ </section>
-+
-+</article>
-diff -up Linux-PAM-1.1.1/modules/pam_faillock/tst-pam_faillock.faillock Linux-PAM-1.1.1/modules/pam_faillock/tst-pam_faillock
---- Linux-PAM-1.1.1/modules/pam_faillock/tst-pam_faillock.faillock 2010-09-17 15:58:41.000000000 +0200
-+++ Linux-PAM-1.1.1/modules/pam_faillock/tst-pam_faillock 2010-09-17 15:58:41.000000000 +0200
-@@ -0,0 +1,2 @@
-+#!/bin/sh
-+../../tests/tst-dlopen .libs/pam_faillock.so