diff options
author | Dmitry V. Levin <ldv@altlinux.org> | 2020-10-29 08:00:00 +0000 |
---|---|---|
committer | Dmitry V. Levin <ldv@altlinux.org> | 2020-10-29 08:00:00 +0000 |
commit | 709e37b7e131d35b0ec30d31f858bc6917dd2b2e (patch) | |
tree | 0edb1959e5dfe79eeba9067f13590d6b00d8ffe8 | |
parent | d702ff714c309069111899fd07c09e31c414c166 (diff) | |
download | pam-709e37b7e131d35b0ec30d31f858bc6917dd2b2e.tar.gz pam-709e37b7e131d35b0ec30d31f858bc6917dd2b2e.tar.bz2 pam-709e37b7e131d35b0ec30d31f858bc6917dd2b2e.zip |
Remove deprecated pam_tally and pam_tally2 modules
* ci/run-build-and-tests.sh (DISTCHECK_CONFIGURE_FLAGS): Remove
--enable-tally --enable-tally2.
* configure.ac: Remove --enable-tally and --enable-tally2 options.
(AM_CONDITIONAL): Remove COND_BUILD_PAM_TALLY and COND_BUILD_PAM_TALLY2.
(AC_CONFIG_FILES): Remove modules/pam_tally/Makefile and
modules/pam_tally2/Makefile.
* doc/sag/pam_tally.xml: Remove.
* doc/sag/pam_tally2.xml: Likewise.
* doc/sag/Linux-PAM_SAG.xml: Do not include pam_tally.xml and
pam_tally2.xml.
* modules/Makefile.am (MAYBE_PAM_TALLY, MAYBE_PAM_TALLY2): Remove.
(SUBDIRS): Remove MAYBE_PAM_TALLY and MAYBE_PAM_TALLY2.
* modules/pam_tally/.gitignore: Remove.
* modules/pam_tally/Makefile.am: Likewise.
* modules/pam_tally/README.xml: Likewise.
* modules/pam_tally/faillog.h: Likewise.
* modules/pam_tally/pam_tally.8.xml: Likewise.
* modules/pam_tally/pam_tally.c: Likewise.
* modules/pam_tally/pam_tally_app.c: Likewise.
* modules/pam_tally/tst-pam_tally: Likewise.
* modules/pam_tally2/.gitignore: Likewise.
* modules/pam_tally2/Makefile.am: Likewise.
* modules/pam_tally2/README.xml: Likewise.
* modules/pam_tally2/pam_tally2.8.xml: Likewise.
* modules/pam_tally2/pam_tally2.c: Likewise.
* modules/pam_tally2/pam_tally2_app.c: Likewise.
* modules/pam_tally2/tallylog.h: Likewise.
* modules/pam_tally2/tst-pam_tally2: Likewise.
* modules/pam_timestamp/pam_timestamp_check.8.xml: Fix typo by replacing
pam_tally with pam_timestamp.
* po/POTFILES.in: Remove ./modules/pam_tally/pam_tally_app.c,
./modules/pam_tally/pam_tally.c, ./modules/pam_tally2/pam_tally2_app.c,
and ./modules/pam_tally2/pam_tally2.c.
* NEWS: Document this change.
-rw-r--r-- | NEWS | 1 | ||||
-rwxr-xr-x | ci/run-build-and-tests.sh | 2 | ||||
-rw-r--r-- | configure.ac | 23 | ||||
-rw-r--r-- | doc/sag/Linux-PAM_SAG.xml | 4 | ||||
-rw-r--r-- | doc/sag/pam_tally.xml | 38 | ||||
-rw-r--r-- | doc/sag/pam_tally2.xml | 46 | ||||
-rw-r--r-- | modules/Makefile.am | 10 | ||||
-rw-r--r-- | modules/pam_tally/.gitignore | 1 | ||||
-rw-r--r-- | modules/pam_tally/Makefile.am | 41 | ||||
-rw-r--r-- | modules/pam_tally/README.xml | 41 | ||||
-rw-r--r-- | modules/pam_tally/faillog.h | 55 | ||||
-rw-r--r-- | modules/pam_tally/pam_tally.8.xml | 459 | ||||
-rw-r--r-- | modules/pam_tally/pam_tally.c | 854 | ||||
-rw-r--r-- | modules/pam_tally/pam_tally_app.c | 6 | ||||
-rwxr-xr-x | modules/pam_tally/tst-pam_tally | 2 | ||||
-rw-r--r-- | modules/pam_tally2/.gitignore | 1 | ||||
-rw-r--r-- | modules/pam_tally2/Makefile.am | 45 | ||||
-rw-r--r-- | modules/pam_tally2/README.xml | 46 | ||||
-rw-r--r-- | modules/pam_tally2/pam_tally2.8.xml | 450 | ||||
-rw-r--r-- | modules/pam_tally2/pam_tally2.c | 1036 | ||||
-rw-r--r-- | modules/pam_tally2/pam_tally2_app.c | 6 | ||||
-rw-r--r-- | modules/pam_tally2/tallylog.h | 52 | ||||
-rwxr-xr-x | modules/pam_tally2/tst-pam_tally2 | 2 | ||||
-rw-r--r-- | modules/pam_timestamp/pam_timestamp_check.8.xml | 2 | ||||
-rw-r--r-- | po/POTFILES.in | 4 |
25 files changed, 4 insertions, 3223 deletions
@@ -4,6 +4,7 @@ Release 1.5.0 * pam_motd: read motd files with target user credentials skipping unreadable ones. * Removed deprecated pam_cracklib module, use pam_passwdqc (from passwdqc project) or pam_pwquality (from libpwquality project) instead. +* Removed deprecated pam_tally and pam_tally2 modules, use pam_faillock instead. Release 1.4.0 * Multiple minor bug fixes and documentation improvements diff --git a/ci/run-build-and-tests.sh b/ci/run-build-and-tests.sh index 9a44019a..070fc72a 100755 --- a/ci/run-build-and-tests.sh +++ b/ci/run-build-and-tests.sh @@ -5,7 +5,7 @@ # # SPDX-License-Identifier: GPL-2.0-or-later -DISTCHECK_CONFIGURE_FLAGS='--disable-dependency-tracking --enable-Werror --enable-tally --enable-tally2' +DISTCHECK_CONFIGURE_FLAGS='--disable-dependency-tracking --enable-Werror' export DISTCHECK_CONFIGURE_FLAGS case "${TARGET-}" in diff --git a/configure.ac b/configure.ac index 4397124d..ad36a6bc 100644 --- a/configure.ac +++ b/configure.ac @@ -613,24 +613,6 @@ test -n "$opt_kerneloverflowuid" || opt_kerneloverflowuid=65534 AC_DEFINE_UNQUOTED(PAM_USERTYPE_OVERFLOW_UID, $opt_kerneloverflowuid, [Kernel overflow uid.]) -AC_ARG_ENABLE([tally], - [AS_HELP_STRING([--enable-tally], - [build deprecated pam_tally module])], - [], [enable_tally=no]) -case "$enable_tally" in - yes|no) ;; - *) AC_MSG_ERROR([bad value $enable_tally for --enable-tally option]) ;; -esac - -AC_ARG_ENABLE([tally2], - [AS_HELP_STRING([--enable-tally2], - [build deprecated pam_tally2 module])], - [], [enable_tally2=no]) -case "$enable_tally2" in - yes|no) ;; - *) AC_MSG_ERROR([bad value $enable_tally2 for --enable-tally2 option]) ;; -esac - AC_ARG_ENABLE([unix], [AS_HELP_STRING([--disable-unix], [do not build pam_unix module])], @@ -647,8 +629,6 @@ AM_CONDITIONAL([COND_BUILD_PAM_RHOSTS], [test "$ac_cv_func_ruserok_af" = yes -o AM_CONDITIONAL([COND_BUILD_PAM_SELINUX], [test -n "$LIBSELINUX"]) AM_CONDITIONAL([COND_BUILD_PAM_SEPERMIT], [test -n "$LIBSELINUX"]) AM_CONDITIONAL([COND_BUILD_PAM_SETQUOTA], [test "$ac_cv_func_quotactl" = yes]) -AM_CONDITIONAL([COND_BUILD_PAM_TALLY], [test "$enable_tally" = yes]) -AM_CONDITIONAL([COND_BUILD_PAM_TALLY2], [test "$enable_tally2" = yes]) AM_CONDITIONAL([COND_BUILD_PAM_TTY_AUDIT], [test "$HAVE_AUDIT_TTY_STATUS" = yes]) AM_CONDITIONAL([COND_BUILD_PAM_UNIX], [test "$enable_unix" = yes]) AM_CONDITIONAL([COND_BUILD_PAM_USERDB], [test -n "$LIBDB"]) @@ -678,8 +658,7 @@ AC_CONFIG_FILES([Makefile libpam/Makefile libpamc/Makefile libpamc/test/Makefile modules/pam_securetty/Makefile modules/pam_selinux/Makefile \ modules/pam_sepermit/Makefile modules/pam_setquota/Makefile \ modules/pam_shells/Makefile modules/pam_stress/Makefile \ - modules/pam_succeed_if/Makefile modules/pam_tally/Makefile \ - modules/pam_tally2/Makefile modules/pam_time/Makefile \ + modules/pam_succeed_if/Makefile modules/pam_time/Makefile \ modules/pam_timestamp/Makefile modules/pam_tty_audit/Makefile \ modules/pam_umask/Makefile \ modules/pam_unix/Makefile modules/pam_userdb/Makefile \ diff --git a/doc/sag/Linux-PAM_SAG.xml b/doc/sag/Linux-PAM_SAG.xml index 03de0250..0f33e0f6 100644 --- a/doc/sag/Linux-PAM_SAG.xml +++ b/doc/sag/Linux-PAM_SAG.xml @@ -455,10 +455,6 @@ session required pam_warn.so <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_succeed_if.xml"/> <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_tally.xml"/> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_tally2.xml"/> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_time.xml"/> <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_timestamp.xml"/> diff --git a/doc/sag/pam_tally.xml b/doc/sag/pam_tally.xml deleted file mode 100644 index ec4afa52..00000000 --- a/doc/sag/pam_tally.xml +++ /dev/null @@ -1,38 +0,0 @@ -<?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_tally'> - <title>pam_tally - login counter (tallying) module</title> - <cmdsynopsis> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="../../modules/pam_tally/pam_tally.8.xml" xpointer='xpointer(//cmdsynopsis[@id = "pam_tally-cmdsynopsis1"]/*)'/> - </cmdsynopsis> - <cmdsynopsis> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="../../modules/pam_tally/pam_tally.8.xml" xpointer='xpointer(//cmdsynopsis[@id = "pam_tally-cmdsynopsis2"]/*)'/> - </cmdsynopsis> - <section id='sag-pam_tally-description'> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="../../modules/pam_tally/pam_tally.8.xml" xpointer='xpointer(//refsect1[@id = "pam_tally-description"]/*)'/> - </section> - <section id='sag-pam_tally-options'> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="../../modules/pam_tally/pam_tally.8.xml" xpointer='xpointer(//refsect1[@id = "pam_tally-options"]/*)'/> - </section> - <section id='sag-pam_tally-types'> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="../../modules/pam_tally/pam_tally.8.xml" xpointer='xpointer(//refsect1[@id = "pam_tally-types"]/*)'/> - </section> - <section id='sag-pam_tally-return_values'> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="../../modules/pam_tally/pam_tally.8.xml" xpointer='xpointer(//refsect1[@id = "pam_tally-return_values"]/*)'/> - </section> - <section id='sag-pam_tally-examples'> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="../../modules/pam_tally/pam_tally.8.xml" xpointer='xpointer(//refsect1[@id = "pam_tally-examples"]/*)'/> - </section> - <section id='sag-pam_tally-author'> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="../../modules/pam_tally/pam_tally.8.xml" xpointer='xpointer(//refsect1[@id = "pam_tally-author"]/*)'/> - </section> -</section> diff --git a/doc/sag/pam_tally2.xml b/doc/sag/pam_tally2.xml deleted file mode 100644 index 085003d3..00000000 --- a/doc/sag/pam_tally2.xml +++ /dev/null @@ -1,46 +0,0 @@ -<?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_tally2'> - <title>pam_tally2 - login counter (tallying) module</title> - <cmdsynopsis> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="../../modules/pam_tally2/pam_tally2.8.xml" xpointer='xpointer(//cmdsynopsis[@id = "pam_tally2-cmdsynopsis1"]/*)'/> - </cmdsynopsis> - <cmdsynopsis> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="../../modules/pam_tally2/pam_tally2.8.xml" xpointer='xpointer(//cmdsynopsis[@id = "pam_tally2-cmdsynopsis2"]/*)'/> - </cmdsynopsis> - <section id='sag-pam_tally2-description'> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="../../modules/pam_tally2/pam_tally2.8.xml" xpointer='xpointer(//refsect1[@id = "pam_tally2-description"]/*)'/> - </section> - <section id='sag-pam_tally2-options'> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="../../modules/pam_tally2/pam_tally2.8.xml" xpointer='xpointer(//refsect1[@id = "pam_tally2-options"]/*)'/> - </section> - <section id='sag-pam_tally2-types'> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="../../modules/pam_tally2/pam_tally2.8.xml" xpointer='xpointer(//refsect1[@id = "pam_tally2-types"]/*)'/> - </section> - <section id='sag-pam_tally2-return_values'> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="../../modules/pam_tally2/pam_tally2.8.xml" xpointer='xpointer(//refsect1[@id = "pam_tally2-return_values"]/*)'/> - </section> - <section id='sag-pam_tally2-notes'> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="../../modules/pam_tally2/pam_tally2.8.xml" xpointer='xpointer(//refsect1[@id = "pam_tally2-notes"]/*)'/> - </section> - <section id='sag-pam_tally2-examples'> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="../../modules/pam_tally2/pam_tally2.8.xml" xpointer='xpointer(//refsect1[@id = "pam_tally2-examples"]/*)'/> - </section> - <section id='sag-pam_tally2-files'> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="../../modules/pam_tally2/pam_tally2.8.xml" xpointer='xpointer(//refsect1[@id = "pam_tally2-files"]/*)'/> - </section> - <section id='sag-pam_tally2-author'> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="../../modules/pam_tally2/pam_tally2.8.xml" xpointer='xpointer(//refsect1[@id = "pam_tally2-author"]/*)'/> - </section> -</section> diff --git a/modules/Makefile.am b/modules/Makefile.am index aa03e319..8da46410 100644 --- a/modules/Makefile.am +++ b/modules/Makefile.am @@ -30,14 +30,6 @@ if COND_BUILD_PAM_SETQUOTA MAYBE_PAM_SETQUOTA = pam_setquota endif -if COND_BUILD_PAM_TALLY - MAYBE_PAM_TALLY = pam_tally -endif - -if COND_BUILD_PAM_TALLY2 - MAYBE_PAM_TALLY2 = pam_tally2 -endif - if COND_BUILD_PAM_TTY_AUDIT MAYBE_PAM_TTY_AUDIT = pam_tty_audit endif @@ -85,8 +77,6 @@ SUBDIRS := \ pam_shells \ pam_stress \ pam_succeed_if \ - $(MAYBE_PAM_TALLY) \ - $(MAYBE_PAM_TALLY2) \ pam_time \ pam_timestamp \ $(MAYBE_PAM_TTY_AUDIT) \ diff --git a/modules/pam_tally/.gitignore b/modules/pam_tally/.gitignore deleted file mode 100644 index b4d6899e..00000000 --- a/modules/pam_tally/.gitignore +++ /dev/null @@ -1 +0,0 @@ -pam_tally diff --git a/modules/pam_tally/Makefile.am b/modules/pam_tally/Makefile.am deleted file mode 100644 index 7d6e2022..00000000 --- a/modules/pam_tally/Makefile.am +++ /dev/null @@ -1,41 +0,0 @@ -# -# Copyright (c) 2005, 2006, 2007, 2009 Thorsten Kukuk <kukuk@thkukuk.de> -# - -CLEANFILES = *~ -MAINTAINERCLEANFILES = $(MANS) README - -EXTRA_DIST = $(XMLS) - -if HAVE_DOC -dist_man_MANS = pam_tally.8 -endif -XMLS = README.xml pam_tally.8.xml -dist_check_SCRIPTS = tst-pam_tally -TESTS = $(dist_check_SCRIPTS) - -securelibdir = $(SECUREDIR) -secureconfdir = $(SCONFIGDIR) - -noinst_HEADERS = faillog.h - -AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \ - $(WARN_CFLAGS) - -pam_tally_la_LDFLAGS = -no-undefined -avoid-version -module -pam_tally_la_LIBADD = $(top_builddir)/libpam/libpam.la -if HAVE_VERSIONING - pam_tally_la_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map -endif - -securelib_LTLIBRARIES = pam_tally.la -sbin_PROGRAMS = pam_tally - -pam_tally_SOURCES = pam_tally_app.c -pam_tally_CFLAGS = $(AM_CFLAGS) @EXE_CFLAGS@ -pam_tally_LDFLAGS = @EXE_LDFLAGS@ - -if ENABLE_REGENERATE_MAN -dist_noinst_DATA = README --include $(top_srcdir)/Make.xml.rules -endif diff --git a/modules/pam_tally/README.xml b/modules/pam_tally/README.xml deleted file mode 100644 index 3c6de50e..00000000 --- a/modules/pam_tally/README.xml +++ /dev/null @@ -1,41 +0,0 @@ -<?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_tally.8.xml"> ---> -]> - -<article> - - <articleinfo> - - <title> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_tally.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_tally-name"]/*)'/> - </title> - - </articleinfo> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_tally.8.xml" xpointer='xpointer(//refsect1[@id = "pam_tally-description"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_tally.8.xml" xpointer='xpointer(//refsect1[@id = "pam_tally-options"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_tally.8.xml" xpointer='xpointer(//refsect1[@id = "pam_tally-examples"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_tally.8.xml" xpointer='xpointer(//refsect1[@id = "pam_tally-author"]/*)'/> - </section> - -</article> diff --git a/modules/pam_tally/faillog.h b/modules/pam_tally/faillog.h deleted file mode 100644 index 90756394..00000000 --- a/modules/pam_tally/faillog.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 1989 - 1994, Julianne Frances Haugh - * All rights reserved. - * - * 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, this list of conditions and the following disclaimer. - * 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. Neither the name of Julianne F. Haugh nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. - */ - -/* - * faillog.h - login failure logging file format - * - * $Id$ - * - * The login failure file is maintained by login(1) and faillog(8) - * Each record in the file represents a separate UID and the file - * is indexed in that fashion. - */ - -#ifndef _FAILLOG_H -#define _FAILLOG_H - -struct faillog { - short fail_cnt; /* failures since last success */ - short fail_max; /* failures before turning account off */ - char fail_line[12]; /* last failure occurred here */ - time_t fail_time; /* last failure occurred then */ - /* - * If nonzero, the account will be re-enabled if there are no - * failures for fail_locktime seconds since last failure. - */ - long fail_locktime; -}; - -#endif diff --git a/modules/pam_tally/pam_tally.8.xml b/modules/pam_tally/pam_tally.8.xml deleted file mode 100644 index 80ad060d..00000000 --- a/modules/pam_tally/pam_tally.8.xml +++ /dev/null @@ -1,459 +0,0 @@ -<?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_tally"> - - <refmeta> - <refentrytitle>pam_tally</refentrytitle> - <manvolnum>8</manvolnum> - <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv id="pam_tally-name"> - <refname>pam_tally</refname> - <refpurpose>The login counter (tallying) module</refpurpose> - </refnamediv> - - <refsynopsisdiv> - <cmdsynopsis id="pam_tally-cmdsynopsis1"> - <command>pam_tally.so</command> - <arg choice="opt"> - file=<replaceable>/path/to/counter</replaceable> - </arg> - <arg choice="opt"> - onerr=[<replaceable>fail</replaceable>|<replaceable>succeed</replaceable>] - </arg> - <arg choice="opt"> - magic_root - </arg> - <arg choice="opt"> - even_deny_root_account - </arg> - <arg choice="opt"> - deny=<replaceable>n</replaceable> - </arg> - <arg choice="opt"> - lock_time=<replaceable>n</replaceable> - </arg> - <arg choice="opt"> - unlock_time=<replaceable>n</replaceable> - </arg> - <arg choice="opt"> - per_user - </arg> - <arg choice="opt"> - no_lock_time - </arg> - <arg choice="opt"> - no_reset - </arg> - <arg choice="opt"> - audit - </arg> - <arg choice="opt"> - silent - </arg> - <arg choice="opt"> - no_log_info - </arg> - </cmdsynopsis> - <cmdsynopsis id="pam_tally-cmdsynopsis2"> - <command>pam_tally</command> - <arg choice="opt"> - --file <replaceable>/path/to/counter</replaceable> - </arg> - <arg choice="opt"> - --user <replaceable>username</replaceable> - </arg> - <arg choice="opt"> - --reset[=<replaceable>n</replaceable>] - </arg> - <arg choice="opt"> - --quiet - </arg> - </cmdsynopsis> - </refsynopsisdiv> - - <refsect1 id="pam_tally-description"> - - <title>DESCRIPTION</title> - - <para> - This module maintains a count of attempted accesses, can - reset count on success, can deny access if too many attempts - fail. - </para> - <para> - pam_tally has several limitations, which are solved with - pam_tally2. For this reason pam_tally is deprecated and - will be removed in a future release. - </para> - <para> - pam_tally comes in two parts: - <emphasis remap='B'>pam_tally.so</emphasis> and - <command>pam_tally</command>. The former is the PAM module and - the latter, a stand-alone program. <command>pam_tally</command> - is an (optional) application which can be used to interrogate and - manipulate the counter file. It can display user counts, set - individual counts, or clear all counts. Setting artificially high - counts may be useful for blocking users without changing their - passwords. For example, one might find it useful to clear all counts - every midnight from a cron job. The - <citerefentry> - <refentrytitle>faillog</refentrytitle><manvolnum>8</manvolnum> - </citerefentry> command can be used instead of pam_tally to to - maintain the counter file. - </para> - <para> - Normally, failed attempts to access <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_tally-options"> - - <title>OPTIONS</title> - <variablelist> - <varlistentry> - <term> - GLOBAL OPTIONS - </term> - <listitem> - <para> - This can be used for <emphasis>auth</emphasis> and - <emphasis>account</emphasis> module types. - </para> - <variablelist> - <varlistentry> - <term> - <option>onerr=[<replaceable>fail</replaceable>|<replaceable>succeed</replaceable>]</option> - </term> - <listitem> - <para> - If something weird happens (like unable to open the file), - return with <errorcode>PAM_SUCCESS</errorcode> if - <option>onerr=<replaceable>succeed</replaceable></option> - is given, else with the corresponding PAM error code. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>file=<replaceable>/path/to/counter</replaceable></option> - </term> - <listitem> - <para> - File where to keep counts. Default is - <filename>/var/log/faillog</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. The messages printed without the <emphasis>silent</emphasis> option leak presence of accounts on the system because they are not printed for non-existing accounts. - </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> - </variablelist> - </listitem> - </varlistentry> - - <varlistentry> - <term> - AUTH OPTIONS - </term> - <listitem> - <para> - Authentication phase first checks if user should be denied - access and if not it increments attempted login counter. Then - on call to <citerefentry> - <refentrytitle>pam_setcred</refentrytitle><manvolnum>3</manvolnum> - </citerefentry> it resets the attempts counter. - </para> - <variablelist> - <varlistentry> - <term> - <option>deny=<replaceable>n</replaceable></option> - </term> - <listitem> - <para> - Deny access if tally for this user exceeds - <replaceable>n</replaceable>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>lock_time=<replaceable>n</replaceable></option> - </term> - <listitem> - <para> - Always deny for <replaceable>n</replaceable> seconds - after failed attempt. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>unlock_time=<replaceable>n</replaceable></option> - </term> - <listitem> - <para> - Allow access after <replaceable>n</replaceable> seconds - after failed attempt. If this option is used the user will - be locked out for the specified amount of time after he - exceeded his maximum allowed attempts. Otherwise the - account is locked until the lock is removed by a manual - intervention of the system administrator. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>magic_root</option> - </term> - <listitem> - <para> - If the module is invoked by a user with uid=0 the - counter is not incremented. The sysadmin should use this - for user launched services, like <command>su</command>, - otherwise this argument should be omitted. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>no_lock_time</option> - </term> - <listitem> - <para> - Do not use the .fail_locktime field in - <filename>/var/log/faillog</filename> for this user. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>no_reset</option> - </term> - <listitem> - <para> - Don't reset count on successful entry, only decrement. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>even_deny_root_account</option> - </term> - <listitem> - <para> - Root account can become unavailable. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>per_user</option> - </term> - <listitem> - <para> - If <filename>/var/log/faillog</filename> contains a non-zero - .fail_max/.fail_locktime field for this user then use it - instead of <option>deny=<replaceable>n</replaceable></option>/ - <option>lock_time=<replaceable>n</replaceable></option> parameter. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>no_lock_time</option> - </term> - <listitem> - <para> - Don't use .fail_locktime filed in - <filename>/var/log/faillog</filename> for this user. - </para> - </listitem> - </varlistentry> - - </variablelist> - </listitem> - </varlistentry> - - - <varlistentry> - <term> - ACCOUNT OPTIONS - </term> - <listitem> - <para> - Account phase resets attempts counter if the user is - <emphasis remap='B'>not</emphasis> magic root. - This phase can be used optionally for services which don't call - <citerefentry> - <refentrytitle>pam_setcred</refentrytitle><manvolnum>3</manvolnum> - </citerefentry> correctly or if the reset should be done regardless - of the failure of the account phase of other modules. - </para> - <variablelist> - <varlistentry> - <term> - <option>magic_root</option> - </term> - <listitem> - <para> - If the module is invoked by a user with uid=0 the - counter is not incremented. The sysadmin should use this - for user launched services, like <command>su</command>, - otherwise this argument should be omitted. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>no_reset</option> - </term> - <listitem> - <para> - Don't reset count on successful entry, only decrement. - </para> - </listitem> - </varlistentry> - </variablelist> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id="pam_tally-types"> - <title>MODULE TYPES PROVIDED</title> - <para> - The <option>auth</option> and <option>account</option> - module types are provided. - </para> - </refsect1> - - <refsect1 id='pam_tally-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_USER_UNKNOWN</term> - <listitem> - <para> - User not known. - </para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id='pam_tally-examples'> - <title>EXAMPLES</title> - <para> - Add the following line to <filename>/etc/pam.d/login</filename> to - lock the account after too many failed logins. The number of - allowed fails is specified by <filename>/var/log/faillog</filename> - and needs to be set with pam_tally or <citerefentry> - <refentrytitle>faillog</refentrytitle><manvolnum>8</manvolnum> - </citerefentry> before. - </para> - <programlisting> -auth required pam_securetty.so -auth required pam_tally.so per_user -auth required pam_env.so -auth required pam_unix.so -auth required pam_nologin.so -account required pam_unix.so -password required pam_unix.so -session required pam_limits.so -session required pam_unix.so -session required pam_lastlog.so nowtmp -session optional pam_mail.so standard - </programlisting> - </refsect1> - - <refsect1 id="pam_tally-files"> - <title>FILES</title> - <variablelist> - <varlistentry> - <term><filename>/var/log/faillog</filename></term> - <listitem> - <para>failure logging file</para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id='pam_tally-see_also'> - <title>SEE ALSO</title> - <para> - <citerefentry> - <refentrytitle>faillog</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_tally-author'> - <title>AUTHOR</title> - <para> - pam_tally was written by Tim Baverstock and Tomas Mraz. - </para> - </refsect1> - -</refentry> diff --git a/modules/pam_tally/pam_tally.c b/modules/pam_tally/pam_tally.c deleted file mode 100644 index 6fd65009..00000000 --- a/modules/pam_tally/pam_tally.c +++ /dev/null @@ -1,854 +0,0 @@ -/* - * pam_tally module - * - * By Tim Baverstock <warwick@mmm.co.uk>, Multi Media Machine Ltd. - * 5 March 1997 - * - * Stuff stolen from pam_rootok and pam_listfile - * - * Changes by Tomas Mraz <tmraz@redhat.com> 5 January 2005 - * Audit option added for Tomas patch by - * Sebastien Tricaud <toady@gscore.org> 13 January 2005 - */ - -#include "config.h" - -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <stdarg.h> -#include <stdlib.h> -#include <syslog.h> -#include <pwd.h> -#include <time.h> - -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/param.h> -#include "faillog.h" - -#ifndef MAIN -#include <security/pam_modutil.h> -#include <security/pam_ext.h> -#endif -#include <security/pam_modules.h> -#include "pam_inline.h" - -#ifndef TRUE -#define TRUE 1L -#define FALSE 0L -#endif - -#ifndef HAVE_FSEEKO -#define fseeko fseek -#endif - -/*---------------------------------------------------------------------*/ - -#define DEFAULT_LOGFILE "/var/log/faillog" -#define MODULE_NAME "pam_tally" - -#define tally_t unsigned short int -#define TALLY_FMT "%hu" -#define TALLY_HI ((tally_t)~0L) - -#ifndef FILENAME_MAX -# define FILENAME_MAX MAXPATHLEN -#endif - -struct fail_s { - struct faillog fs_faillog; -#ifndef MAIN - time_t fs_fail_time; -#endif /* ndef MAIN */ -}; - -struct tally_options { - const char *filename; - tally_t deny; - long lock_time; - long unlock_time; - unsigned int ctrl; -}; - -#define PHASE_UNKNOWN 0 -#define PHASE_AUTH 1 -#define PHASE_ACCOUNT 2 -#define PHASE_SESSION 3 - -#define OPT_MAGIC_ROOT 01 -#define OPT_FAIL_ON_ERROR 02 -#define OPT_DENY_ROOT 04 -#define OPT_PER_USER 010 -#define OPT_NO_LOCK_TIME 020 -#define OPT_NO_RESET 040 -#define OPT_AUDIT 0100 -#define OPT_SILENT 0200 -#define OPT_NOLOGNOTICE 0400 - - -/*---------------------------------------------------------------------*/ - -/* some syslogging */ - -#ifdef MAIN -#define pam_syslog tally_log -static void -PAM_FORMAT((printf, 3, 4)) -tally_log (const pam_handle_t *pamh UNUSED, int priority UNUSED, - const char *fmt, ...) -{ - va_list args; - - va_start(args, fmt); - fprintf(stderr, "%s: ", MODULE_NAME); - vfprintf(stderr, fmt, args); - fprintf(stderr,"\n"); - va_end(args); -} - -#define pam_modutil_getpwnam(pamh,user) getpwnam(user) - -#endif - -/*---------------------------------------------------------------------*/ - -/* --- Support function: parse arguments --- */ - -#ifndef MAIN - -static void -log_phase_no_auth(pam_handle_t *pamh, int phase, const char *argv) -{ - if ( phase != PHASE_AUTH ) { - pam_syslog(pamh, LOG_ERR, - "option %s allowed in auth phase only", argv); - } -} - -static int -tally_parse_args(pam_handle_t *pamh, struct tally_options *opts, - int phase, int argc, const char **argv) -{ - memset(opts, 0, sizeof(*opts)); - opts->filename = DEFAULT_LOGFILE; - - for ( ; argc-- > 0; ++argv ) { - const char *str; - - if ((str = pam_str_skip_prefix(*argv, "file=")) != NULL) { - const char *from = str; - if ( *from!='/' || strlen(from)>FILENAME_MAX-1 ) { - pam_syslog(pamh, LOG_ERR, - "filename not /rooted or too long; %s", *argv); - return PAM_AUTH_ERR; - } - opts->filename = from; - } - else if ( ! strcmp( *argv, "onerr=fail" ) ) { - opts->ctrl |= OPT_FAIL_ON_ERROR; - } - else if ( ! strcmp( *argv, "onerr=succeed" ) ) { - opts->ctrl &= ~OPT_FAIL_ON_ERROR; - } - else if ( ! strcmp( *argv, "magic_root" ) ) { - opts->ctrl |= OPT_MAGIC_ROOT; - } - else if ( ! strcmp( *argv, "even_deny_root_account" ) ) { - log_phase_no_auth(pamh, phase, *argv); - opts->ctrl |= OPT_DENY_ROOT; - } - else if ((str = pam_str_skip_prefix(*argv, "deny=")) != NULL) { - log_phase_no_auth(pamh, phase, *argv); - if (sscanf(str, TALLY_FMT, &opts->deny) != 1) { - pam_syslog(pamh, LOG_ERR, "bad number supplied: %s", *argv); - return PAM_AUTH_ERR; - } - } - else if ((str = pam_str_skip_prefix(*argv, "lock_time=")) != NULL) { - log_phase_no_auth(pamh, phase, *argv); - if (sscanf(str, "%ld", &opts->lock_time) != 1) { - pam_syslog(pamh, LOG_ERR, "bad number supplied: %s", *argv); - return PAM_AUTH_ERR; - } - } - else if ((str = pam_str_skip_prefix(*argv, "unlock_time=")) != NULL) { - log_phase_no_auth(pamh, phase, *argv); - if (sscanf(str, "%ld", &opts->unlock_time) != 1) { - pam_syslog(pamh, LOG_ERR, "bad number supplied: %s", *argv); - return PAM_AUTH_ERR; - } - } - else if ( ! strcmp( *argv, "per_user" ) ) - { - log_phase_no_auth(pamh, phase, *argv); - opts->ctrl |= OPT_PER_USER; - } - else if ( ! strcmp( *argv, "no_lock_time") ) - { - log_phase_no_auth(pamh, phase, *argv); - opts->ctrl |= OPT_NO_LOCK_TIME; - } - else if ( ! strcmp( *argv, "no_reset" ) ) { - opts->ctrl |= OPT_NO_RESET; - } - else if ( ! strcmp ( *argv, "audit") ) { - opts->ctrl |= OPT_AUDIT; - } - else if ( ! strcmp ( *argv, "silent") ) { - opts->ctrl |= OPT_SILENT; - } - else if ( ! strcmp ( *argv, "no_log_info") ) { - opts->ctrl |= OPT_NOLOGNOTICE; - } - else { - pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv); - } - } - - return PAM_SUCCESS; -} - -#endif /* #ifndef MAIN */ - -/*---------------------------------------------------------------------*/ - -/* --- Support function: get uid (and optionally username) from PAM or - cline_user --- */ - -#ifdef MAIN -static const char *cline_user=0; /* cline_user is used in the administration prog */ -#endif - -static int -pam_get_uid(pam_handle_t *pamh, uid_t *uid, const char **userp, struct tally_options *opts) -{ - const char *user = NULL; - struct passwd *pw; - -#ifdef MAIN - user = cline_user; - - if ( !user ) { - pam_syslog(pamh, LOG_ERR, "pam_get_uid; user?"); - return PAM_AUTH_ERR; - } -#else - if ((pam_get_user( pamh, &user, NULL )) != PAM_SUCCESS) { - pam_syslog(pamh, LOG_NOTICE, "cannot determine user name"); - return PAM_AUTH_ERR; - } -#endif - - if ( ! ( pw = pam_modutil_getpwnam( pamh, user ) ) ) { - opts->ctrl & OPT_AUDIT ? - pam_syslog(pamh, LOG_NOTICE, "pam_get_uid; no such user %s", user) : - pam_syslog(pamh, LOG_NOTICE, "pam_get_uid; no such user"); - return PAM_USER_UNKNOWN; - } - - if ( uid ) *uid = pw->pw_uid; - if ( userp ) *userp = user; - return PAM_SUCCESS; -} - -/*---------------------------------------------------------------------*/ - -/* --- Support functions: set/get tally data --- */ - -#ifndef MAIN - -static void -_cleanup(pam_handle_t *pamh UNUSED, void *data, int error_status UNUSED) -{ - free(data); -} - - -static void -tally_set_data( pam_handle_t *pamh, time_t oldtime ) -{ - time_t *data; - - if ( (data=malloc(sizeof(time_t))) != NULL ) { - *data = oldtime; - pam_set_data(pamh, MODULE_NAME, (void *)data, _cleanup); - } -} - -static int -tally_get_data( pam_handle_t *pamh, time_t *oldtime ) -{ - int rv; - const void *data; - - rv = pam_get_data(pamh, MODULE_NAME, &data); - if ( rv == PAM_SUCCESS && data != NULL && oldtime != NULL ) { - *oldtime = *(const time_t *)data; - pam_set_data(pamh, MODULE_NAME, NULL, NULL); - } - else { - rv = -1; - if (oldtime) - *oldtime = 0; - } - return rv; -} -#endif /* #ifndef MAIN */ - -/*---------------------------------------------------------------------*/ - -/* --- Support function: open/create tallyfile and return tally for uid --- */ - -/* If on entry *tally==TALLY_HI, tallyfile is opened READONLY */ -/* Otherwise, if on entry tallyfile doesn't exist, creation is attempted. */ - -static int -get_tally(pam_handle_t *pamh, tally_t *tally, uid_t uid, - const char *filename, FILE **TALLY, struct fail_s *fsp) -{ - struct stat fileinfo; - int lstat_ret = lstat(filename,&fileinfo); - - if ( lstat_ret && *tally!=TALLY_HI ) { - int oldmask = umask(077); - *TALLY=fopen(filename, "a"); - /* Create file, or append-open in pathological case. */ - umask(oldmask); - if ( !*TALLY ) { - pam_syslog(pamh, LOG_ALERT, "Couldn't create %s", filename); - return PAM_AUTH_ERR; - } - lstat_ret = fstat(fileno(*TALLY),&fileinfo); - fclose(*TALLY); - } - - if ( lstat_ret ) { - pam_syslog(pamh, LOG_ALERT, "Couldn't stat %s", filename); - return PAM_AUTH_ERR; - } - - if((fileinfo.st_mode & S_IWOTH) || !S_ISREG(fileinfo.st_mode)) { - /* If the file is world writable or is not a - normal file, return error */ - pam_syslog(pamh, LOG_ALERT, - "%s is either world writable or not a normal file", - filename); - return PAM_AUTH_ERR; - } - - if ( ! ( *TALLY = fopen(filename,(*tally!=TALLY_HI)?"r+":"r") ) ) { - pam_syslog(pamh, LOG_ALERT, "Error opening %s for %s", filename, *tally!=TALLY_HI?"update":"read"); - -/* Discovering why account service fails: e/uid are target user. - * - * perror(MODULE_NAME); - * fprintf(stderr,"uid %d euid %d\n",getuid(), geteuid()); - */ - return PAM_AUTH_ERR; - } - - if ( fseeko( *TALLY, (off_t) uid * sizeof(struct faillog), SEEK_SET ) ) { - pam_syslog(pamh, LOG_ALERT, "fseek failed for %s", filename); - fclose(*TALLY); - return PAM_AUTH_ERR; - } - - if ( (size_t)fileinfo.st_size <= uid * sizeof(struct faillog) ) { - - memset(fsp, 0, sizeof(struct faillog)); - *tally=0; - fsp->fs_faillog.fail_time = time(NULL); - - } else if (( fread((char *) &fsp->fs_faillog, - sizeof(struct faillog), 1, *TALLY) )==0 ) { - - *tally=0; /* Assuming a gappy filesystem */ - - } else { - - *tally = fsp->fs_faillog.fail_cnt; - - } - - return PAM_SUCCESS; -} - -/*---------------------------------------------------------------------*/ - -/* --- Support function: update and close tallyfile with tally!=TALLY_HI --- */ - -static int -set_tally(pam_handle_t *pamh, tally_t tally, uid_t uid, - const char *filename, FILE **TALLY, struct fail_s *fsp) -{ - int retval = PAM_SUCCESS; - - if ( tally!=TALLY_HI ) { - if ( fseeko( *TALLY, (off_t) uid * sizeof(struct faillog), SEEK_SET ) ) { - pam_syslog(pamh, LOG_ALERT, "fseek failed for %s", filename); - retval = PAM_AUTH_ERR; - } else { - fsp->fs_faillog.fail_cnt = tally; - if (fwrite((char *) &fsp->fs_faillog, - sizeof(struct faillog), 1, *TALLY)==0 ) { - pam_syslog(pamh, LOG_ALERT, "update (fwrite) failed for %s", filename); - retval = PAM_AUTH_ERR; - } - } - } - - if ( fclose(*TALLY) ) { - pam_syslog(pamh, LOG_ALERT, "update (fclose) failed for %s", filename); - return PAM_AUTH_ERR; - } - *TALLY=NULL; - return retval; -} - -/*---------------------------------------------------------------------*/ - -/* --- PAM bits --- */ - -#ifndef MAIN - -#define RETURN_ERROR(i) return ((opts->ctrl & OPT_FAIL_ON_ERROR)?(i):(PAM_SUCCESS)) - -/*---------------------------------------------------------------------*/ - -/* --- tally bump function: bump tally for uid by (signed) inc --- */ - -static int -tally_bump (int inc, time_t *oldtime, pam_handle_t *pamh, - uid_t uid, const char *user, struct tally_options *opts) -{ - tally_t - tally = 0; /* !TALLY_HI --> Log opened for update */ - - FILE - *TALLY = NULL; - const void - *remote_host = NULL, - *cur_tty = NULL; - struct fail_s fs, *fsp = &fs; - int i; - - i=get_tally(pamh, &tally, uid, opts->filename, &TALLY, fsp); - if ( i != PAM_SUCCESS ) { RETURN_ERROR( i ); } - - /* to remember old fail time (for locktime) */ - fsp->fs_fail_time = fsp->fs_faillog.fail_time; - if ( inc > 0 ) { - if ( oldtime ) { - *oldtime = fsp->fs_faillog.fail_time; - } - fsp->fs_faillog.fail_time = time(NULL); - } else { - if ( oldtime ) { - fsp->fs_faillog.fail_time = *oldtime; - } - } - (void) pam_get_item(pamh, PAM_RHOST, &remote_host); - if (!remote_host) { - - (void) pam_get_item(pamh, PAM_TTY, &cur_tty); - if (!cur_tty) { - strncpy(fsp->fs_faillog.fail_line, "unknown", - sizeof(fsp->fs_faillog.fail_line) - 1); - fsp->fs_faillog.fail_line[sizeof(fsp->fs_faillog.fail_line)-1] = 0; - } else { - strncpy(fsp->fs_faillog.fail_line, cur_tty, - sizeof(fsp->fs_faillog.fail_line)-1); - fsp->fs_faillog.fail_line[sizeof(fsp->fs_faillog.fail_line)-1] = 0; - } - - } else { - strncpy(fsp->fs_faillog.fail_line, remote_host, - (size_t)sizeof(fsp->fs_faillog.fail_line)); - fsp->fs_faillog.fail_line[sizeof(fsp->fs_faillog.fail_line)-1] = 0; - } - - if ( !(opts->ctrl & OPT_MAGIC_ROOT) || getuid() ) { /* magic_root doesn't change tally */ - - tally+=inc; - - if ( tally==TALLY_HI ) { /* Overflow *and* underflow. :) */ - tally-=inc; - pam_syslog(pamh, LOG_ALERT, "Tally %sflowed for user %s", - (inc<0)?"under":"over",user); - } - } - - i=set_tally(pamh, tally, uid, opts->filename, &TALLY, fsp ); - if ( i != PAM_SUCCESS ) { RETURN_ERROR( i ); } - - return PAM_SUCCESS; -} - -static int -tally_check (time_t oldtime, pam_handle_t *pamh, uid_t uid, - const char *user, struct tally_options *opts) -{ - tally_t - deny = opts->deny; - tally_t - tally = TALLY_HI; - long - lock_time = opts->lock_time; - - struct fail_s fs, *fsp = &fs; - FILE *TALLY=0; - int i; - - i=get_tally(pamh, &tally, uid, opts->filename, &TALLY, fsp); - if ( i != PAM_SUCCESS ) { RETURN_ERROR( i ); } - - if ( TALLY != NULL ) { - fclose(TALLY); - } - - if ( !(opts->ctrl & OPT_MAGIC_ROOT) || getuid() ) { /* magic_root skips tally check */ - - /* To deny or not to deny; that is the question */ - - /* if there's .fail_max entry and per_user=TRUE then deny=.fail_max */ - - if ( (fsp->fs_faillog.fail_max) && (opts->ctrl & OPT_PER_USER) ) { - deny = fsp->fs_faillog.fail_max; - } - if ( (fsp->fs_faillog.fail_locktime) && (opts->ctrl & OPT_PER_USER) ) { - lock_time = fsp->fs_faillog.fail_locktime; - } - if (lock_time && oldtime - && !(opts->ctrl & OPT_NO_LOCK_TIME) ) - { - if ( lock_time + oldtime > time(NULL) ) - { - if (!(opts->ctrl & OPT_SILENT)) - pam_info (pamh, - _("The account is temporarily locked (%ld seconds left)."), - (long int) (oldtime+lock_time-time(NULL))); - - if (!(opts->ctrl & OPT_NOLOGNOTICE)) - pam_syslog (pamh, LOG_NOTICE, - "user %s (%lu) has time limit [%lds left]" - " since last failure.", - user, (unsigned long int) uid, - (long int) (oldtime+lock_time-time(NULL))); - return PAM_AUTH_ERR; - } - } - if (opts->unlock_time && oldtime) - { - if ( opts->unlock_time + oldtime <= time(NULL) ) - { /* ignore deny check after unlock_time elapsed */ - return PAM_SUCCESS; - } - } - if ( - ( deny != 0 ) && /* deny==0 means no deny */ - ( tally > deny ) && /* tally>deny means exceeded */ - ( ((opts->ctrl & OPT_DENY_ROOT) || uid) ) /* even_deny stops uid check */ - ) { - if (!(opts->ctrl & OPT_SILENT)) - pam_info (pamh, _("The account is locked due to %u failed logins."), - (unsigned int)tally); - - if (!(opts->ctrl & OPT_NOLOGNOTICE)) - pam_syslog(pamh, LOG_NOTICE, - "user %s (%lu) tally "TALLY_FMT", deny "TALLY_FMT, - user, (unsigned long int) uid, tally, deny); - return PAM_AUTH_ERR; /* Only unconditional failure */ - } - } - - return PAM_SUCCESS; -} - -static int -tally_reset (pam_handle_t *pamh, uid_t uid, struct tally_options *opts) -{ - tally_t - tally = 0; /* !TALLY_HI --> Log opened for update */ - - struct fail_s fs, *fsp = &fs; - FILE *TALLY=0; - int i; - - i=get_tally(pamh, &tally, uid, opts->filename, &TALLY, fsp); - if ( i != PAM_SUCCESS ) { RETURN_ERROR( i ); } - - /* resets if not magic root - */ - - if ( (!(opts->ctrl & OPT_MAGIC_ROOT) || getuid()) - && !(opts->ctrl & OPT_NO_RESET) ) - { tally=0; } - - if (tally == 0) - { - fsp->fs_faillog.fail_time = (time_t) 0; - strcpy(fsp->fs_faillog.fail_line, ""); - } - - i=set_tally(pamh, tally, uid, opts->filename, &TALLY, fsp); - if ( i != PAM_SUCCESS ) { RETURN_ERROR( i ); } - - return PAM_SUCCESS; -} - -/*---------------------------------------------------------------------*/ - -/* --- authentication management functions (only) --- */ - -int -pam_sm_authenticate(pam_handle_t *pamh, int flags, - int argc, const char **argv) -{ - int - rvcheck, rvbump; - time_t - oldtime = 0; - struct tally_options - options, *opts = &options; - uid_t - uid; - const char - *user; - - rvcheck = tally_parse_args(pamh, opts, PHASE_AUTH, argc, argv); - if ( rvcheck != PAM_SUCCESS ) - RETURN_ERROR( rvcheck ); - - if (flags & PAM_SILENT) - opts->ctrl |= OPT_SILENT; - - rvcheck = pam_get_uid(pamh, &uid, &user, opts); - if ( rvcheck != PAM_SUCCESS ) - RETURN_ERROR( rvcheck ); - - rvbump = tally_bump(1, &oldtime, pamh, uid, user, opts); - rvcheck = tally_check(oldtime, pamh, uid, user, opts); - - tally_set_data(pamh, oldtime); - - return rvcheck != PAM_SUCCESS ? rvcheck : rvbump; -} - -int -pam_sm_setcred(pam_handle_t *pamh, int flags, - int argc, const char **argv) -{ - int - rv; - time_t - oldtime = 0; - struct tally_options - options, *opts = &options; - uid_t - uid; - const char - *user; - - rv = tally_parse_args(pamh, opts, PHASE_AUTH, argc, argv); - if ( rv != PAM_SUCCESS ) - RETURN_ERROR( rv ); - - if (flags & PAM_SILENT) - opts->ctrl |= OPT_SILENT; - - rv = pam_get_uid(pamh, &uid, &user, opts); - if ( rv != PAM_SUCCESS ) - RETURN_ERROR( rv ); - - if ( tally_get_data(pamh, &oldtime) != 0 ) - /* no data found */ - return PAM_SUCCESS; - - if ( (rv=tally_bump(-1, &oldtime, pamh, uid, user, opts)) != PAM_SUCCESS ) - return rv; - return tally_reset(pamh, uid, opts); -} - -/*---------------------------------------------------------------------*/ - -/* --- authentication management functions (only) --- */ - -/* To reset failcount of user on successful login */ - -int -pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, - int argc, const char **argv) -{ - int - rv; - time_t - oldtime = 0; - struct tally_options - options, *opts = &options; - uid_t - uid; - const char - *user; - - rv = tally_parse_args(pamh, opts, PHASE_ACCOUNT, argc, argv); - if ( rv != PAM_SUCCESS ) - RETURN_ERROR( rv ); - - if (flags & PAM_SILENT) - opts->ctrl |= OPT_SILENT; - - rv = pam_get_uid(pamh, &uid, &user, opts); - if ( rv != PAM_SUCCESS ) - RETURN_ERROR( rv ); - - if ( tally_get_data(pamh, &oldtime) != 0 ) - /* no data found */ - return PAM_SUCCESS; - - if ( (rv=tally_bump(-1, &oldtime, pamh, uid, user, opts)) != PAM_SUCCESS ) - return rv; - return tally_reset(pamh, uid, opts); -} - -/*-----------------------------------------------------------------------*/ - -#else /* #ifndef MAIN */ - -static const char *cline_filename = DEFAULT_LOGFILE; -static tally_t cline_reset = TALLY_HI; /* Default is `interrogate only' */ -static int cline_quiet = 0; - -/* - * Not going to link with pamlib just for these.. :) - */ - -static const char * -pam_errors( int i ) -{ - switch (i) { - case PAM_AUTH_ERR: return _("Authentication error"); - case PAM_SERVICE_ERR: return _("Service error"); - case PAM_USER_UNKNOWN: return _("Unknown user"); - default: return _("Unknown error"); - } -} - -static int -getopts( char **argv ) -{ - const char *pname = *argv; - for ( ; *argv ; (void)(*argv && ++argv) ) { - const char *str; - if ( !strcmp (*argv,"--file") ) cline_filename=*++argv; - else if ((str = pam_str_skip_prefix(*argv, "--file=")) != NULL) - cline_filename = str; - else if ( !strcmp (*argv,"--user") ) cline_user=*++argv; - else if ((str = pam_str_skip_prefix(*argv, "--user=")) != NULL) - cline_user = str; - else if ( !strcmp (*argv,"--reset") ) cline_reset=0; - else if ((str = pam_str_skip_prefix(*argv, "--reset=")) != NULL) { - if (sscanf(str, TALLY_FMT, &cline_reset) != 1 ) - fprintf(stderr,_("%s: Bad number given to --reset=\n"),pname), exit(0); - } - else if ( !strcmp (*argv,"--quiet") ) cline_quiet=1; - else { - fprintf(stderr,_("%s: Unrecognised option %s\n"),pname,*argv); - return FALSE; - } - } - return TRUE; -} - -int main ( int argc UNUSED, char **argv ) -{ - struct fail_s fs, *fsp = &fs; - - if ( ! getopts( argv+1 ) ) { - printf(_("%s: [--file rooted-filename] [--user username] " - "[--reset[=n]] [--quiet]\n"), - *argv); - exit(0); - } - - umask(077); - - /* - * Major difference between individual user and all users: - * --user just handles one user, just like PAM. - * --user=* handles all users, sniffing cline_filename for nonzeros - */ - - if ( cline_user ) { - uid_t uid; - tally_t tally=cline_reset; - FILE *TALLY=0; - struct tally_options opts; - int i; - - memset(&opts, 0, sizeof(opts)); - opts.ctrl = OPT_AUDIT; - i=pam_get_uid(NULL, &uid, NULL, &opts); - if ( i != PAM_SUCCESS ) { - fprintf(stderr,"%s: %s\n",*argv,pam_errors(i)); - exit(0); - } - - i=get_tally(NULL, &tally, uid, cline_filename, &TALLY, fsp); - if ( i != PAM_SUCCESS ) { - fprintf(stderr,"%s: %s\n",*argv,pam_errors(i)); - exit(0); - } - - if ( !cline_quiet ) - printf("User %s\t(%lu)\t%s "TALLY_FMT"\n",cline_user, - (unsigned long int) uid, - (cline_reset!=TALLY_HI)?"had":"has",tally); - - i=set_tally(NULL, cline_reset, uid, cline_filename, &TALLY, fsp); - if ( i != PAM_SUCCESS ) { - fprintf(stderr,"%s: %s\n",*argv,pam_errors(i)); - exit(0); - } - } - else /* !cline_user (ie, operate on all users) */ { - FILE *TALLY=fopen(cline_filename, "r"); - uid_t uid=0; - if ( !TALLY ) perror(*argv), exit(0); - - for ( ; !feof(TALLY); uid++ ) { - tally_t tally; - struct passwd *pw; - if ( ! fread((char *) &fsp->fs_faillog, - sizeof (struct faillog), 1, TALLY) - || ! fsp->fs_faillog.fail_cnt ) { - continue; - } - tally = fsp->fs_faillog.fail_cnt; - - if ( ( pw=getpwuid(uid) ) ) { - printf("User %s\t(%lu)\t%s "TALLY_FMT"\n",pw->pw_name, - (unsigned long int) uid, - (cline_reset!=TALLY_HI)?"had":"has",tally); - } - else { - printf("User [NONAME]\t(%lu)\t%s "TALLY_FMT"\n", - (unsigned long int) uid, - (cline_reset!=TALLY_HI)?"had":"has",tally); - } - } - fclose(TALLY); - if ( cline_reset!=0 && cline_reset!=TALLY_HI ) { - fprintf(stderr,_("%s: Can't reset all users to non-zero\n"),*argv); - } - else if ( !cline_reset ) { - TALLY=fopen(cline_filename, "w"); - if ( !TALLY ) perror(*argv), exit(0); - fclose(TALLY); - } - } - return 0; -} - - -#endif /* #ifndef MAIN */ diff --git a/modules/pam_tally/pam_tally_app.c b/modules/pam_tally/pam_tally_app.c deleted file mode 100644 index ad288549..00000000 --- a/modules/pam_tally/pam_tally_app.c +++ /dev/null @@ -1,6 +0,0 @@ -/* - # This seemed like such a good idea at the time. :) - */ - -#define MAIN -#include "pam_tally.c" diff --git a/modules/pam_tally/tst-pam_tally b/modules/pam_tally/tst-pam_tally deleted file mode 100755 index 15291af6..00000000 --- a/modules/pam_tally/tst-pam_tally +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -../../tests/tst-dlopen .libs/pam_tally.so diff --git a/modules/pam_tally2/.gitignore b/modules/pam_tally2/.gitignore deleted file mode 100644 index 8ff18583..00000000 --- a/modules/pam_tally2/.gitignore +++ /dev/null @@ -1 +0,0 @@ -pam_tally2 diff --git a/modules/pam_tally2/Makefile.am b/modules/pam_tally2/Makefile.am deleted file mode 100644 index 9ca7eabf..00000000 --- a/modules/pam_tally2/Makefile.am +++ /dev/null @@ -1,45 +0,0 @@ -# -# Copyright (c) 2005, 2006, 2007, 2009 Thorsten Kukuk <kukuk@thkukuk.de> -# Copyright (c) 2008 Red Hat, Inc. -# - -CLEANFILES = *~ -MAINTAINERCLEANFILES = $(MANS) README - -EXTRA_DIST = $(XMLS) - -if HAVE_DOC -dist_man_MANS = pam_tally2.8 -endif -XMLS = README.xml pam_tally2.8.xml -dist_check_SCRIPTS = tst-pam_tally2 -TESTS = $(dist_check_SCRIPTS) - -securelibdir = $(SECUREDIR) -secureconfdir = $(SCONFIGDIR) - -noinst_HEADERS = tallylog.h - -AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \ - $(WARN_CFLAGS) - -pam_tally2_la_LDFLAGS = -no-undefined -avoid-version -module -pam_tally2_la_LIBADD = $(top_builddir)/libpam/libpam.la $(LIBAUDIT) -if HAVE_VERSIONING - pam_tally2_la_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map -endif - -pam_tally2_CFLAGS = $(AM_CFLAGS) @EXE_CFLAGS@ -pam_tally2_LDFLAGS = @EXE_LDFLAGS@ -pam_tally2_LDADD = $(top_builddir)/libpam/libpam.la $(LIBAUDIT) - -securelib_LTLIBRARIES = pam_tally2.la -sbin_PROGRAMS = pam_tally2 - -pam_tally2_la_SOURCES = pam_tally2.c -pam_tally2_SOURCES = pam_tally2_app.c - -if ENABLE_REGENERATE_MAN -dist_noinst_DATA = README --include $(top_srcdir)/Make.xml.rules -endif diff --git a/modules/pam_tally2/README.xml b/modules/pam_tally2/README.xml deleted file mode 100644 index aa470570..00000000 --- a/modules/pam_tally2/README.xml +++ /dev/null @@ -1,46 +0,0 @@ -<?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_tally2.8.xml"> ---> -]> - -<article> - - <articleinfo> - - <title> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_tally2.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_tally2-name"]/*)'/> - </title> - - </articleinfo> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_tally2.8.xml" xpointer='xpointer(//refsect1[@id = "pam_tally2-description"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_tally2.8.xml" xpointer='xpointer(//refsect1[@id = "pam_tally2-options"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_tally2.8.xml" xpointer='xpointer(//refsect1[@id = "pam_tally2-notes"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_tally2.8.xml" xpointer='xpointer(//refsect1[@id = "pam_tally2-examples"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_tally2.8.xml" xpointer='xpointer(//refsect1[@id = "pam_tally2-author"]/*)'/> - </section> - -</article> diff --git a/modules/pam_tally2/pam_tally2.8.xml b/modules/pam_tally2/pam_tally2.8.xml deleted file mode 100644 index d058cf91..00000000 --- a/modules/pam_tally2/pam_tally2.8.xml +++ /dev/null @@ -1,450 +0,0 @@ -<?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_tally2"> - - <refmeta> - <refentrytitle>pam_tally2</refentrytitle> - <manvolnum>8</manvolnum> - <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv id="pam_tally2-name"> - <refname>pam_tally2</refname> - <refpurpose>The login counter (tallying) module</refpurpose> - </refnamediv> - - <refsynopsisdiv> - <cmdsynopsis id="pam_tally2-cmdsynopsis1"> - <command>pam_tally2.so</command> - <arg choice="opt"> - file=<replaceable>/path/to/counter</replaceable> - </arg> - <arg choice="opt"> - onerr=[<replaceable>fail</replaceable>|<replaceable>succeed</replaceable>] - </arg> - <arg choice="opt"> - magic_root - </arg> - <arg choice="opt"> - even_deny_root - </arg> - <arg choice="opt"> - deny=<replaceable>n</replaceable> - </arg> - <arg choice="opt"> - lock_time=<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"> - serialize - </arg> - <arg choice="opt"> - audit - </arg> - <arg choice="opt"> - silent - </arg> - <arg choice="opt"> - no_log_info - </arg> - <arg choice="opt"> - debug - </arg> - </cmdsynopsis> - <cmdsynopsis id="pam_tally2-cmdsynopsis2"> - <command>pam_tally2</command> - <arg choice="opt"> - --file <replaceable>/path/to/counter</replaceable> - </arg> - <arg choice="opt"> - --user <replaceable>username</replaceable> - </arg> - <arg choice="opt"> - --reset[=<replaceable>n</replaceable>] - </arg> - <arg choice="opt"> - --quiet - </arg> - </cmdsynopsis> - </refsynopsisdiv> - - <refsect1 id="pam_tally2-description"> - - <title>DESCRIPTION</title> - - <para> - This module maintains a count of attempted accesses, can - reset count on success, can deny access if too many attempts fail. - </para> - <para> - pam_tally2 comes in two parts: - <emphasis remap='B'>pam_tally2.so</emphasis> and - <command>pam_tally2</command>. The former is the PAM module and - the latter, a stand-alone program. <command>pam_tally2</command> - is an (optional) application which can be used to interrogate and - manipulate the counter file. It can display user counts, set - individual counts, or clear all counts. Setting artificially high - counts may be useful for blocking users without changing their - passwords. For example, one might find it useful to clear all counts - every midnight from a cron job. - </para> - <para> - Normally, failed attempts to access <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_tally2-options"> - - <title>OPTIONS</title> - <variablelist> - <varlistentry> - <term> - GLOBAL OPTIONS - </term> - <listitem> - <para> - This can be used for <emphasis>auth</emphasis> and - <emphasis>account</emphasis> module types. - </para> - <variablelist> - <varlistentry> - <term> - <option>onerr=[<replaceable>fail</replaceable>|<replaceable>succeed</replaceable>]</option> - </term> - <listitem> - <para> - If something weird happens (like unable to open the file), - return with <errorcode>PAM_SUCCESS</errorcode> if - <option>onerr=<replaceable>succeed</replaceable></option> - is given, else with the corresponding PAM error code. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>file=<replaceable>/path/to/counter</replaceable></option> - </term> - <listitem> - <para> - File where to keep counts. Default is - <filename>/var/log/tallylog</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. The messages printed without the <emphasis>silent</emphasis> option leak presence of accounts on the system because they are not printed for non-existing accounts. - </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>debug</option> - </term> - <listitem> - <para> - Always log tally count when it is incremented as a debug level message to the system log. - </para> - </listitem> - </varlistentry> - </variablelist> - </listitem> - </varlistentry> - - <varlistentry> - <term> - AUTH OPTIONS - </term> - <listitem> - <para> - Authentication phase first increments attempted login counter and - checks if user should be denied access. If the user is authenticated - and the login process continues on call to <citerefentry> - <refentrytitle>pam_setcred</refentrytitle><manvolnum>3</manvolnum> - </citerefentry> it resets the attempts counter. - </para> - <variablelist> - <varlistentry> - <term> - <option>deny=<replaceable>n</replaceable></option> - </term> - <listitem> - <para> - Deny access if tally for this user exceeds - <replaceable>n</replaceable>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>lock_time=<replaceable>n</replaceable></option> - </term> - <listitem> - <para> - Always deny for <replaceable>n</replaceable> seconds - after failed attempt. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>unlock_time=<replaceable>n</replaceable></option> - </term> - <listitem> - <para> - Allow access after <replaceable>n</replaceable> seconds - after failed attempt. If this option is used the user will - be locked out for the specified amount of time after he - exceeded his maximum allowed attempts. Otherwise the - account is locked until the lock is removed by a manual - intervention of the system administrator. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>magic_root</option> - </term> - <listitem> - <para> - If the module is invoked by a user with uid=0 the - counter is not incremented. The sysadmin should use this - for user launched services, like <command>su</command>, - otherwise this argument should be omitted. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>even_deny_root</option> - </term> - <listitem> - <para> - Root account can become unavailable. - </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 failed attempt. If this option is used - the root user will be locked out for the specified amount of - time after he exceeded his maximum allowed attempts. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>serialize</option> - </term> - <listitem> - <para> - Serialize access to the tally file using locks. This option might - be used only for non-multithreaded services because it depends on - the fcntl locking of the tally file. Also it is a good idea to use - this option only in such configurations where the time between auth - phase and account or setcred phase is not dependent on the - authenticating client. Otherwise the authenticating client will be - able to prevent simultaneous authentications by the same user by - simply artificially prolonging the time the file record lock is held. - </para> - </listitem> - </varlistentry> - </variablelist> - </listitem> - </varlistentry> - - - <varlistentry> - <term> - ACCOUNT OPTIONS - </term> - <listitem> - <para> - Account phase resets attempts counter if the user is - <emphasis remap='B'>not</emphasis> magic root. - This phase can be used optionally for services which don't call - <citerefentry> - <refentrytitle>pam_setcred</refentrytitle><manvolnum>3</manvolnum> - </citerefentry> correctly or if the reset should be done regardless - of the failure of the account phase of other modules. - </para> - <variablelist> - <varlistentry> - <term> - <option>magic_root</option> - </term> - <listitem> - <para> - If the module is invoked by a user with uid=0 the - counter is not changed. The sysadmin should use this - for user launched services, like <command>su</command>, - otherwise this argument should be omitted. - </para> - </listitem> - </varlistentry> - </variablelist> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id="pam_tally2-types"> - <title>MODULE TYPES PROVIDED</title> - <para> - The <option>auth</option> and <option>account</option> - module types are provided. - </para> - </refsect1> - - <refsect1 id='pam_tally2-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_USER_UNKNOWN</term> - <listitem> - <para> - User not known. - </para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id='pam_tally2-notes'> - <title>NOTES</title> - <para> - pam_tally2 is not compatible with the old pam_tally faillog file format. - This is caused by requirement of compatibility of the tallylog file - format between 32bit and 64bit architectures on multiarch systems. - </para> - <para> - There is no setuid wrapper for access to the data file such as when the - <emphasis remap='B'>pam_tally2.so</emphasis> module is called from - xscreensaver. 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_IGNORE</errorcode>. - </para> - </refsect1> - - <refsect1 id='pam_tally2-examples'> - <title>EXAMPLES</title> - <para> - Add the following line to <filename>/etc/pam.d/login</filename> to - lock the account after 4 failed logins. Root account will be locked - as well. The accounts will be automatically unlocked after 20 minutes. - The module does not have to be called in the account phase because the - <command>login</command> calls <citerefentry> - <refentrytitle>pam_setcred</refentrytitle><manvolnum>3</manvolnum> - </citerefentry> correctly. - </para> - <programlisting> -auth required pam_securetty.so -auth required pam_tally2.so deny=4 even_deny_root unlock_time=1200 -auth required pam_env.so -auth required pam_unix.so -auth required pam_nologin.so -account required pam_unix.so -password required pam_unix.so -session required pam_limits.so -session required pam_unix.so -session required pam_lastlog.so nowtmp -session optional pam_mail.so standard - </programlisting> - </refsect1> - - <refsect1 id="pam_tally2-files"> - <title>FILES</title> - <variablelist> - <varlistentry> - <term><filename>/var/log/tallylog</filename></term> - <listitem> - <para>failure count logging file</para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id='pam_tally2-see_also'> - <title>SEE ALSO</title> - <para> - <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_tally2-author'> - <title>AUTHOR</title> - <para> - pam_tally2 was written by Tim Baverstock and Tomas Mraz. - </para> - </refsect1> - -</refentry> diff --git a/modules/pam_tally2/pam_tally2.c b/modules/pam_tally2/pam_tally2.c deleted file mode 100644 index bcf3188c..00000000 --- a/modules/pam_tally2/pam_tally2.c +++ /dev/null @@ -1,1036 +0,0 @@ -/* - * pam_tally2 module - * - * By Tim Baverstock <warwick@mmm.co.uk>, Multi Media Machine Ltd. - * 5 March 1997 - * - * Stuff stolen from pam_rootok and pam_listfile - * - * Changes by Tomas Mraz <tmraz@redhat.com> 5 January 2005, 26 January 2006 - * Audit option added for Tomas patch by Sebastien Tricaud <toady@gscore.org> 13 January 2005 - * Portions Copyright 2006, Red Hat, Inc. - * Portions Copyright 1989 - 1993, Julianne Frances Haugh - * All rights reserved. - * - * 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, this list of conditions and the following disclaimer. - * 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. Neither the name of Julianne F. Haugh nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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" - -#if defined(MAIN) && defined(MEMORY_DEBUG) -# undef exit -#endif /* defined(MAIN) && defined(MEMORY_DEBUG) */ - -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <stdarg.h> -#include <stdlib.h> -#include <syslog.h> -#include <pwd.h> -#include <time.h> -#include <stdint.h> -#include <errno.h> -#ifdef HAVE_LIBAUDIT -#include <libaudit.h> -#endif - -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/param.h> -#include <fcntl.h> -#include <signal.h> -#include "tallylog.h" - -#ifndef TRUE -#define TRUE 1L -#define FALSE 0L -#endif - -#ifndef HAVE_FSEEKO -#define fseeko fseek -#endif - -#ifndef MAIN -#include <security/pam_ext.h> -#endif -#include <security/pam_modutil.h> -#include <security/pam_modules.h> -#include "pam_inline.h" - -/*---------------------------------------------------------------------*/ - -#define DEFAULT_LOGFILE "/var/log/tallylog" -#define MODULE_NAME "pam_tally2" - -#define tally_t uint16_t -#define TALLY_HI ((tally_t)~0L) - -struct tally_options { - const char *filename; - tally_t deny; - long lock_time; - long unlock_time; - long root_unlock_time; - unsigned int ctrl; -}; - -#define PHASE_UNKNOWN 0 -#define PHASE_AUTH 1 -#define PHASE_ACCOUNT 2 -#define PHASE_SESSION 3 - -#define OPT_MAGIC_ROOT 01 -#define OPT_FAIL_ON_ERROR 02 -#define OPT_DENY_ROOT 04 -#define OPT_QUIET 040 -#define OPT_AUDIT 0100 -#define OPT_NOLOGNOTICE 0400 -#define OPT_SERIALIZE 01000 -#define OPT_DEBUG 02000 - -#define MAX_LOCK_WAITING_TIME 10 - -/*---------------------------------------------------------------------*/ - -/* some syslogging */ - -#ifdef MAIN -#define pam_syslog tally_log -static void -PAM_FORMAT((printf, 3, 4)) -tally_log (const pam_handle_t *pamh UNUSED, int priority UNUSED, - const char *fmt, ...) -{ - va_list args; - - va_start(args, fmt); - fprintf(stderr, "%s: ", MODULE_NAME); - vfprintf(stderr, fmt, args); - fprintf(stderr,"\n"); - va_end(args); -} - -#define pam_modutil_getpwnam(pamh, user) getpwnam(user) -#endif - -/*---------------------------------------------------------------------*/ - -/* --- Support function: parse arguments --- */ - -#ifndef MAIN - -static void -log_phase_no_auth(pam_handle_t *pamh, int phase, const char *argv) -{ - if ( phase != PHASE_AUTH ) { - pam_syslog(pamh, LOG_ERR, - "option %s allowed in auth phase only", argv); - } -} - -static int -tally_parse_args(pam_handle_t *pamh, struct tally_options *opts, - int phase, int argc, const char **argv) -{ - memset(opts, 0, sizeof(*opts)); - opts->filename = DEFAULT_LOGFILE; - opts->ctrl = OPT_FAIL_ON_ERROR; - opts->root_unlock_time = -1; - - for ( ; argc-- > 0; ++argv ) { - const char *str; - - if ((str = pam_str_skip_prefix(*argv, "file=")) != NULL) { - const char *from = str; - if ( *from!='/' ) { - pam_syslog(pamh, LOG_ERR, - "filename not /rooted; %s", *argv); - return PAM_AUTH_ERR; - } - opts->filename = from; - } - else if ( ! strcmp( *argv, "onerr=fail" ) ) { - opts->ctrl |= OPT_FAIL_ON_ERROR; - } - else if ( ! strcmp( *argv, "onerr=succeed" ) ) { - opts->ctrl &= ~OPT_FAIL_ON_ERROR; - } - else if ( ! strcmp( *argv, "magic_root" ) ) { - opts->ctrl |= OPT_MAGIC_ROOT; - } - else if ( ! strcmp( *argv, "serialize" ) ) { - opts->ctrl |= OPT_SERIALIZE; - } - else if ( ! strcmp( *argv, "debug" ) ) { - opts->ctrl |= OPT_DEBUG; - } - else if ( ! strcmp( *argv, "even_deny_root_account" ) || - ! strcmp( *argv, "even_deny_root" ) ) { - log_phase_no_auth(pamh, phase, *argv); - opts->ctrl |= OPT_DENY_ROOT; - } - else if ((str = pam_str_skip_prefix(*argv, "deny=")) != NULL) { - log_phase_no_auth(pamh, phase, *argv); - if (sscanf(str, "%hu", &opts->deny) != 1) { - pam_syslog(pamh, LOG_ERR, "bad number supplied: %s", *argv); - return PAM_AUTH_ERR; - } - } - else if ((str = pam_str_skip_prefix(*argv, "lock_time=")) != NULL) { - log_phase_no_auth(pamh, phase, *argv); - if (sscanf(str, "%ld", &opts->lock_time) != 1) { - pam_syslog(pamh, LOG_ERR, "bad number supplied: %s", *argv); - return PAM_AUTH_ERR; - } - } - else if ((str = pam_str_skip_prefix(*argv, "unlock_time=")) != NULL) { - log_phase_no_auth(pamh, phase, *argv); - if (sscanf(str, "%ld", &opts->unlock_time) != 1) { - pam_syslog(pamh, LOG_ERR, "bad number supplied: %s", *argv); - return PAM_AUTH_ERR; - } - } - else if ((str = pam_str_skip_prefix(*argv, "root_unlock_time=")) != NULL) { - log_phase_no_auth(pamh, phase, *argv); - if (sscanf(str, "%ld", &opts->root_unlock_time) != 1) { - pam_syslog(pamh, LOG_ERR, "bad number supplied: %s", *argv); - return PAM_AUTH_ERR; - } - opts->ctrl |= OPT_DENY_ROOT; /* even_deny_root implied */ - } - else if ( ! strcmp( *argv, "quiet" ) || - ! strcmp ( *argv, "silent")) { - opts->ctrl |= OPT_QUIET; - } - else if ( ! strcmp ( *argv, "no_log_info") ) { - opts->ctrl |= OPT_NOLOGNOTICE; - } - else if ( ! strcmp ( *argv, "audit") ) { - opts->ctrl |= OPT_AUDIT; - } - else { - pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv); - } - } - - if (opts->root_unlock_time == -1) - opts->root_unlock_time = opts->unlock_time; - - return PAM_SUCCESS; -} - -#endif /* #ifndef MAIN */ - -/*---------------------------------------------------------------------*/ - -/* --- Support function: get uid (and optionally username) from PAM or - cline_user --- */ - -#ifdef MAIN -static const char *cline_user=0; /* cline_user is used in the administration prog */ -#endif - -static int -pam_get_uid(pam_handle_t *pamh, uid_t *uid, const char **userp, struct tally_options *opts) -{ - const char *user = NULL; - struct passwd *pw; - -#ifdef MAIN - user = cline_user; - - if ( !user ) { - pam_syslog(pamh, LOG_NOTICE, "cannot determine user name"); - return PAM_AUTH_ERR; - } -#else - if ((pam_get_user( pamh, &user, NULL )) != PAM_SUCCESS) { - user = NULL; - } -#endif - - if ( ! ( pw = pam_modutil_getpwnam( pamh, user ) ) ) { - opts->ctrl & OPT_AUDIT ? - pam_syslog(pamh, LOG_NOTICE, "pam_get_uid; no such user %s", user) : - pam_syslog(pamh, LOG_NOTICE, "pam_get_uid; no such user"); - return PAM_USER_UNKNOWN; - } - - if ( uid ) *uid = pw->pw_uid; - if ( userp ) *userp = user; - return PAM_SUCCESS; -} - -/*---------------------------------------------------------------------*/ - -/* --- Support functions: set/get tally data --- */ - -#ifndef MAIN - -struct tally_data { - time_t time; - int tfile; -}; - -static void -_cleanup(pam_handle_t *pamh UNUSED, void *void_data, int error_status UNUSED) -{ - struct tally_data *data = void_data; - if (data->tfile != -1) - close(data->tfile); - free(data); -} - -static void -tally_set_data( pam_handle_t *pamh, time_t oldtime, int tfile ) -{ - struct tally_data *data; - - if ( (data=malloc(sizeof(*data))) != NULL ) { - data->time = oldtime; - data->tfile = tfile; - pam_set_data(pamh, MODULE_NAME, (void *)data, _cleanup); - } -} - -static int -tally_get_data( pam_handle_t *pamh, time_t *oldtime, int *tfile ) -{ - int rv; - const void *void_data; - const struct tally_data *data; - - rv = pam_get_data(pamh, MODULE_NAME, &void_data); - if ( rv == PAM_SUCCESS && void_data != NULL && oldtime != NULL ) { - data = void_data; - *oldtime = data->time; - *tfile = data->tfile; - } - else { - rv = -1; - *oldtime = 0; - } - return rv; -} -#endif /* #ifndef MAIN */ - -/*---------------------------------------------------------------------*/ - -/* --- Support function: open/create tallyfile and return tally for uid --- */ - -/* If on entry tallyfile doesn't exist, creation is attempted. */ - -static void -alarm_handler(int sig UNUSED) -{ /* we just need to ignore it */ -} - -static int -get_tally(pam_handle_t *pamh, uid_t uid, const char *filename, - int *tfile, struct tallylog *tally, unsigned int ctrl) -{ - struct stat fileinfo; - int lstat_ret; - void *void_tally = tally; - int preopened = 0; - - if (*tfile != -1) { - preopened = 1; - goto skip_open; - } - - lstat_ret = lstat(filename, &fileinfo); - if (lstat_ret) { - *tfile=open(filename, O_APPEND|O_CREAT, S_IRUSR|S_IWUSR); - /* Create file, or append-open in pathological case. */ - if (*tfile == -1) { -#ifndef MAIN - if (errno == EACCES) { - return PAM_IGNORE; /* called with insufficient access rights */ - } -#endif - pam_syslog(pamh, LOG_ALERT, "Couldn't create %s: %m", filename); - return PAM_AUTH_ERR; - } - lstat_ret = fstat(*tfile, &fileinfo); - close(*tfile); - } - - *tfile = -1; - - if ( lstat_ret ) { - pam_syslog(pamh, LOG_ALERT, "Couldn't stat %s", filename); - return PAM_AUTH_ERR; - } - - if ((fileinfo.st_mode & S_IWOTH) || !S_ISREG(fileinfo.st_mode)) { - /* If the file is world writable or is not a - normal file, return error */ - pam_syslog(pamh, LOG_ALERT, - "%s is either world writable or not a normal file", - filename); - return PAM_AUTH_ERR; - } - - if ((*tfile = open(filename, O_RDWR)) == -1) { -#ifndef MAIN - if (errno == EACCES) /* called with insufficient access rights */ - return PAM_IGNORE; -#endif - pam_syslog(pamh, LOG_ALERT, "Error opening %s for update: %m", filename); - - return PAM_AUTH_ERR; - } - -skip_open: - if (lseek(*tfile, (off_t)uid*(off_t)sizeof(*tally), SEEK_SET) == (off_t)-1) { - pam_syslog(pamh, LOG_ALERT, "lseek failed for %s: %m", filename); - if (!preopened) { - close(*tfile); - *tfile = -1; - } - return PAM_AUTH_ERR; - } - - if (!preopened && (ctrl & OPT_SERIALIZE)) { - /* this code is not thread safe as it uses fcntl locks and alarm() - so never use serialize with multithreaded services */ - struct sigaction newsa, oldsa; - unsigned int oldalarm; - int rv; - - memset(&newsa, '\0', sizeof(newsa)); - newsa.sa_handler = alarm_handler; - sigaction(SIGALRM, &newsa, &oldsa); - oldalarm = alarm(MAX_LOCK_WAITING_TIME); - - rv = lockf(*tfile, F_LOCK, sizeof(*tally)); - /* lock failure is not fatal, we attempt to read the tally anyway */ - - /* reinstate the eventual old alarm handler */ - if (rv == -1 && errno == EINTR) { - if (oldalarm > MAX_LOCK_WAITING_TIME) { - oldalarm -= MAX_LOCK_WAITING_TIME; - } else if (oldalarm > 0) { - oldalarm = 1; - } - } - sigaction(SIGALRM, &oldsa, NULL); - alarm(oldalarm); - } - - if (pam_modutil_read(*tfile, void_tally, sizeof(*tally)) != sizeof(*tally)) { - memset(tally, 0, sizeof(*tally)); - } - - tally->fail_line[sizeof(tally->fail_line)-1] = '\0'; - - return PAM_SUCCESS; -} - -/*---------------------------------------------------------------------*/ - -/* --- Support function: update tallyfile with tally!=TALLY_HI --- */ - -static int -set_tally(pam_handle_t *pamh, uid_t uid, - const char *filename, int *tfile, struct tallylog *tally) -{ - void *void_tally = tally; - if (tally->fail_cnt != TALLY_HI) { - if (lseek(*tfile, (off_t)uid * sizeof(*tally), SEEK_SET) == (off_t)-1) { - pam_syslog(pamh, LOG_ALERT, "lseek failed for %s: %m", filename); - return PAM_AUTH_ERR; - } - if (pam_modutil_write(*tfile, void_tally, sizeof(*tally)) != sizeof(*tally)) { - pam_syslog(pamh, LOG_ALERT, "update (write) failed for %s: %m", filename); - return PAM_AUTH_ERR; - } - } - - return PAM_SUCCESS; -} - -/*---------------------------------------------------------------------*/ - -/* --- PAM bits --- */ - -#ifndef MAIN - -#define RETURN_ERROR(i) return ((opts->ctrl & OPT_FAIL_ON_ERROR)?(i):(PAM_SUCCESS)) - -/*---------------------------------------------------------------------*/ - -static int -tally_check (tally_t oldcnt, time_t oldtime, pam_handle_t *pamh, uid_t uid, - const char *user, struct tally_options *opts, - struct tallylog *tally) -{ - int rv = PAM_SUCCESS; - int loglevel = LOG_DEBUG; -#ifdef HAVE_LIBAUDIT - char buf[64]; - int audit_fd = -1; - const void *rhost = NULL, *tty = NULL; -#endif - - if ((opts->ctrl & OPT_MAGIC_ROOT) && getuid() == 0) { - return PAM_SUCCESS; - } - /* magic_root skips tally check */ -#ifdef HAVE_LIBAUDIT - 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; - (void)pam_get_item(pamh, PAM_TTY, &tty); - (void)pam_get_item(pamh, PAM_RHOST, &rhost); -#endif - if (opts->deny != 0 && /* deny==0 means no deny */ - tally->fail_cnt > opts->deny && /* tally>deny means exceeded */ - ((opts->ctrl & OPT_DENY_ROOT) || uid)) { /* even_deny stops uid check */ -#ifdef HAVE_LIBAUDIT - if (tally->fail_cnt == opts->deny+1) { - /* First say that max number was hit. */ - snprintf(buf, sizeof(buf), "pam_tally2 uid=%u ", uid); - audit_log_user_message(audit_fd, AUDIT_ANOM_LOGIN_FAILURES, buf, - rhost, NULL, tty, 1); - } -#endif - if (uid) { - /* Unlock time check */ - if (opts->unlock_time && oldtime) { - if (opts->unlock_time + oldtime <= time(NULL)) { - /* ignore deny check after unlock_time elapsed */ -#ifdef HAVE_LIBAUDIT - snprintf(buf, sizeof(buf), "pam_tally2 uid=%u ", uid); - audit_log_user_message(audit_fd, AUDIT_RESP_ACCT_UNLOCK_TIMED, buf, - rhost, NULL, tty, 1); -#endif - rv = PAM_SUCCESS; - goto cleanup; - } - } - } else { - /* Root unlock time check */ - if (opts->root_unlock_time && oldtime) { - if (opts->root_unlock_time + oldtime <= time(NULL)) { - /* ignore deny check after unlock_time elapsed */ -#ifdef HAVE_LIBAUDIT - snprintf(buf, sizeof(buf), "pam_tally2 uid=%u ", uid); - audit_log_user_message(audit_fd, AUDIT_RESP_ACCT_UNLOCK_TIMED, buf, - rhost, NULL, tty, 1); -#endif - rv = PAM_SUCCESS; - goto cleanup; - } - } - } - -#ifdef HAVE_LIBAUDIT - if (tally->fail_cnt == opts->deny+1) { - /* First say that max number was hit. */ - audit_log_user_message(audit_fd, AUDIT_RESP_ACCT_LOCK, buf, - rhost, NULL, tty, 1); - } -#endif - - if (!(opts->ctrl & OPT_QUIET)) { - pam_info(pamh, _("The account is locked due to %u failed logins."), - (unsigned int)tally->fail_cnt); - } - loglevel = LOG_NOTICE; - rv = PAM_AUTH_ERR; /* Only unconditional failure */ - goto cleanup; - } - - /* Lock time check */ - if (opts->lock_time && oldtime) { - if (opts->lock_time + oldtime > time(NULL)) { - /* don't increase fail_cnt or update fail_time when - lock_time applies */ - tally->fail_cnt = oldcnt; - tally->fail_time = oldtime; - - if (!(opts->ctrl & OPT_QUIET)) { - pam_info(pamh, - _("The account is temporarily locked (%ld seconds left)."), - (long int) (oldtime+opts->lock_time-time(NULL))); - } - if (!(opts->ctrl & OPT_NOLOGNOTICE)) { - pam_syslog(pamh, LOG_NOTICE, - "user %s (%lu) has time limit [%lds left]" - " since last failure.", - user, (unsigned long)uid, - (long int) (oldtime+opts->lock_time-time(NULL))); - } - rv = PAM_AUTH_ERR; - goto cleanup; - } - } - -cleanup: - if (!(opts->ctrl & OPT_NOLOGNOTICE) && (loglevel != LOG_DEBUG || opts->ctrl & OPT_DEBUG)) { - pam_syslog(pamh, loglevel, - "user %s (%lu) tally %hu, deny %hu", - user, (unsigned long)uid, tally->fail_cnt, opts->deny); - } -#ifdef HAVE_LIBAUDIT - if (audit_fd != -1) { - close(audit_fd); - } -#endif - return rv; -} - -/* --- tally bump function: bump tally for uid by (signed) inc --- */ - -static int -tally_bump (int inc, time_t *oldtime, pam_handle_t *pamh, - uid_t uid, const char *user, struct tally_options *opts, int *tfile) -{ - struct tallylog tally; - tally_t oldcnt; - const void *remote_host = NULL; - int i, rv; - - tally.fail_cnt = 0; /* !TALLY_HI --> Log opened for update */ - - i = get_tally(pamh, uid, opts->filename, tfile, &tally, opts->ctrl); - if (i != PAM_SUCCESS) { - if (*tfile != -1) { - close(*tfile); - *tfile = -1; - } - RETURN_ERROR(i); - } - - /* to remember old fail time (for locktime) */ - if (oldtime) { - *oldtime = (time_t)tally.fail_time; - } - - tally.fail_time = time(NULL); - - (void) pam_get_item(pamh, PAM_RHOST, &remote_host); - if (!remote_host) { - (void) pam_get_item(pamh, PAM_TTY, &remote_host); - if (!remote_host) { - remote_host = "unknown"; - } - } - - strncpy(tally.fail_line, remote_host, - sizeof(tally.fail_line)-1); - tally.fail_line[sizeof(tally.fail_line)-1] = 0; - - oldcnt = tally.fail_cnt; - - if (!(opts->ctrl & OPT_MAGIC_ROOT) || getuid()) { - /* magic_root doesn't change tally */ - tally.fail_cnt += inc; - - if (tally.fail_cnt == TALLY_HI) { /* Overflow *and* underflow. :) */ - tally.fail_cnt -= inc; - pam_syslog(pamh, LOG_ALERT, "Tally %sflowed for user %s", - (inc<0)?"under":"over",user); - } - } - - rv = tally_check(oldcnt, *oldtime, pamh, uid, user, opts, &tally); - - i = set_tally(pamh, uid, opts->filename, tfile, &tally); - if (i != PAM_SUCCESS) { - if (*tfile != -1) { - close(*tfile); - *tfile = -1; - } - if (rv == PAM_SUCCESS) - RETURN_ERROR( i ); - /* fallthrough */ - } else if (!(opts->ctrl & OPT_SERIALIZE)) { - close(*tfile); - *tfile = -1; - } - - return rv; -} - -static int -tally_reset (pam_handle_t *pamh, uid_t uid, struct tally_options *opts, int old_tfile) -{ - struct tallylog tally; - int tfile = old_tfile; - int i; - - /* resets only if not magic root */ - - if ((opts->ctrl & OPT_MAGIC_ROOT) && getuid() == 0) { - return PAM_SUCCESS; - } - - tally.fail_cnt = 0; /* !TALLY_HI --> Log opened for update */ - - i=get_tally(pamh, uid, opts->filename, &tfile, &tally, opts->ctrl); - if (i != PAM_SUCCESS) { - if (tfile != old_tfile) /* the descriptor is not owned by pam data */ - close(tfile); - RETURN_ERROR(i); - } - - memset(&tally, 0, sizeof(tally)); - - i=set_tally(pamh, uid, opts->filename, &tfile, &tally); - if (i != PAM_SUCCESS) { - if (tfile != old_tfile) /* the descriptor is not owned by pam data */ - close(tfile); - RETURN_ERROR(i); - } - - if (tfile != old_tfile) - close(tfile); - - return PAM_SUCCESS; -} - -/*---------------------------------------------------------------------*/ - -/* --- authentication management functions (only) --- */ - -int -pam_sm_authenticate(pam_handle_t *pamh, int flags UNUSED, - int argc, const char **argv) -{ - int - rv, tfile = -1; - time_t - oldtime = 0; - struct tally_options - options, *opts = &options; - uid_t - uid; - const char - *user; - - rv = tally_parse_args(pamh, opts, PHASE_AUTH, argc, argv); - if (rv != PAM_SUCCESS) - RETURN_ERROR(rv); - - if (flags & PAM_SILENT) - opts->ctrl |= OPT_QUIET; - - rv = pam_get_uid(pamh, &uid, &user, opts); - if (rv != PAM_SUCCESS) - RETURN_ERROR(rv); - - rv = tally_bump(1, &oldtime, pamh, uid, user, opts, &tfile); - - tally_set_data(pamh, oldtime, tfile); - - return rv; -} - -int -pam_sm_setcred(pam_handle_t *pamh, int flags UNUSED, - int argc, const char **argv) -{ - int - rv, tfile = -1; - time_t - oldtime = 0; - struct tally_options - options, *opts = &options; - uid_t - uid; - const char - *user; - - rv = tally_parse_args(pamh, opts, PHASE_AUTH, argc, argv); - if ( rv != PAM_SUCCESS ) - RETURN_ERROR( rv ); - - rv = pam_get_uid(pamh, &uid, &user, opts); - if ( rv != PAM_SUCCESS ) - RETURN_ERROR( rv ); - - if ( tally_get_data(pamh, &oldtime, &tfile) != 0 ) - /* no data found */ - return PAM_SUCCESS; - - rv = tally_reset(pamh, uid, opts, tfile); - - pam_set_data(pamh, MODULE_NAME, NULL, NULL); - - return rv; -} - -/*---------------------------------------------------------------------*/ - -/* --- authentication management functions (only) --- */ - -/* To reset failcount of user on successful login */ - -int -pam_sm_acct_mgmt(pam_handle_t *pamh, int flags UNUSED, - int argc, const char **argv) -{ - int - rv, tfile = -1; - time_t - oldtime = 0; - struct tally_options - options, *opts = &options; - uid_t - uid; - const char - *user; - - rv = tally_parse_args(pamh, opts, PHASE_ACCOUNT, argc, argv); - if ( rv != PAM_SUCCESS ) - RETURN_ERROR( rv ); - - rv = pam_get_uid(pamh, &uid, &user, opts); - if ( rv != PAM_SUCCESS ) - RETURN_ERROR( rv ); - - if ( tally_get_data(pamh, &oldtime, &tfile) != 0 ) - /* no data found */ - return PAM_SUCCESS; - - rv = tally_reset(pamh, uid, opts, tfile); - - pam_set_data(pamh, MODULE_NAME, NULL, NULL); - - return rv; -} - -/*-----------------------------------------------------------------------*/ - -#else /* #ifndef MAIN */ - -static const char *cline_filename = DEFAULT_LOGFILE; -static tally_t cline_reset = TALLY_HI; /* Default is `interrogate only' */ -static int cline_quiet = 0; - -/* - * Not going to link with pamlib just for these.. :) - */ - -static const char * -pam_errors( int i ) -{ - switch (i) { - case PAM_AUTH_ERR: return _("Authentication error"); - case PAM_SERVICE_ERR: return _("Service error"); - case PAM_USER_UNKNOWN: return _("Unknown user"); - default: return _("Unknown error"); - } -} - -static int -getopts( char **argv ) -{ - const char *pname = *argv; - for ( ; *argv ; (void)(*argv && ++argv) ) { - const char *str; - if ( !strcmp (*argv,"--file") ) cline_filename=*++argv; - else if ( !strcmp(*argv,"-f") ) cline_filename=*++argv; - else if ((str = pam_str_skip_prefix(*argv, "--file=")) != NULL) - cline_filename = str; - else if ( !strcmp (*argv,"--user") ) cline_user=*++argv; - else if ( !strcmp (*argv,"-u") ) cline_user=*++argv; - else if ((str = pam_str_skip_prefix(*argv, "--user=")) != NULL) - cline_user = str; - else if ( !strcmp (*argv,"--reset") ) cline_reset=0; - else if ( !strcmp (*argv,"-r") ) cline_reset=0; - else if ((str = pam_str_skip_prefix(*argv, "--reset=")) != NULL) { - if (sscanf(str, "%hu", &cline_reset) != 1) - fprintf(stderr,_("%s: Bad number given to --reset=\n"),pname), exit(0); - } - else if ( !strcmp (*argv,"--quiet") ) cline_quiet=1; - else { - fprintf(stderr,_("%s: Unrecognised option %s\n"),pname,*argv); - return FALSE; - } - } - return TRUE; -} - -static void -print_one(const struct tallylog *tally, uid_t uid) -{ - static int once; - const char *cp = "[UNKNOWN]"; - time_t fail_time; - struct tm *tm; - struct passwd *pwent; - const char *username = "[NONAME]"; - char ptime[80]; - - pwent = getpwuid(uid); - fail_time = tally->fail_time; - if ((tm = localtime(&fail_time)) != NULL) { - strftime (ptime, sizeof (ptime), "%D %H:%M:%S", tm); - cp = ptime; - } - if (pwent) { - username = pwent->pw_name; - } - if (!once) { - printf (_("Login Failures Latest failure From\n")); - once++; - } - printf ("%-15.15s %5hu ", username, tally->fail_cnt); - if (tally->fail_time) { - printf ("%-17.17s %s", cp, tally->fail_line); - } - putchar ('\n'); -} - -int -main( int argc UNUSED, char **argv ) -{ - struct tallylog tally; - - if ( ! getopts( argv+1 ) ) { - printf(_("%s: [-f rooted-filename] [--file rooted-filename]\n" - " [-u username] [--user username]\n" - " [-r] [--reset[=n]] [--quiet]\n"), - *argv); - exit(2); - } - - umask(077); - - /* - * Major difference between individual user and all users: - * --user just handles one user, just like PAM. - * without --user it handles all users, sniffing cline_filename for nonzeros - */ - - if ( cline_user ) { - uid_t uid; - int tfile = -1; - struct tally_options opts; - int i; - - memset(&opts, 0, sizeof(opts)); - opts.ctrl = OPT_AUDIT; - i=pam_get_uid(NULL, &uid, NULL, &opts); - if ( i != PAM_SUCCESS ) { - fprintf(stderr,"%s: %s\n",*argv,pam_errors(i)); - exit(1); - } - - if (cline_reset == 0) { - struct stat st; - - if (stat(cline_filename, &st) && errno == ENOENT) { - if (!cline_quiet) { - memset(&tally, 0, sizeof(tally)); - print_one(&tally, uid); - } - return 0; /* no file => nothing to reset */ - } - } - - i=get_tally(NULL, uid, cline_filename, &tfile, &tally, 0); - if ( i != PAM_SUCCESS ) { - if (tfile != -1) - close(tfile); - fprintf(stderr, "%s: %s\n", *argv, pam_errors(i)); - exit(1); - } - - if ( !cline_quiet ) - print_one(&tally, uid); - - if (cline_reset != TALLY_HI) { -#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); - if (audit_fd >=0) - close(audit_fd); -#endif - if (cline_reset == 0) { - memset(&tally, 0, sizeof(tally)); - } else { - tally.fail_cnt = cline_reset; - } - i=set_tally(NULL, uid, cline_filename, &tfile, &tally); - close(tfile); - if (i != PAM_SUCCESS) { - fprintf(stderr,"%s: %s\n",*argv,pam_errors(i)); - exit(1); - } - } else { - close(tfile); - } - } - else /* !cline_user (ie, operate on all users) */ { - FILE *tfile=fopen(cline_filename, "r"); - uid_t uid=0; - if (!tfile && cline_reset != 0) { - perror(*argv); - exit(1); - } - - for ( ; tfile && !feof(tfile); uid++ ) { - if ( !fread(&tally, sizeof(tally), 1, tfile) - || !tally.fail_cnt ) { - continue; - } - print_one(&tally, uid); - } - if (tfile) - fclose(tfile); - if ( cline_reset!=0 && cline_reset!=TALLY_HI ) { - fprintf(stderr,_("%s: Can't reset all users to non-zero\n"),*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); - if (audit_fd >=0) - close(audit_fd); -#endif - tfile=fopen(cline_filename, "w"); - if ( !tfile ) perror(*argv), exit(0); - fclose(tfile); - } - } - return 0; -} - - -#endif /* #ifndef MAIN */ diff --git a/modules/pam_tally2/pam_tally2_app.c b/modules/pam_tally2/pam_tally2_app.c deleted file mode 100644 index b72e9bfd..00000000 --- a/modules/pam_tally2/pam_tally2_app.c +++ /dev/null @@ -1,6 +0,0 @@ -/* - # This seemed like such a good idea at the time. :) - */ - -#define MAIN -#include "pam_tally2.c" diff --git a/modules/pam_tally2/tallylog.h b/modules/pam_tally2/tallylog.h deleted file mode 100644 index 596b1dac..00000000 --- a/modules/pam_tally2/tallylog.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2006, Red Hat, Inc. - * All rights reserved. - * - * 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, this list of conditions and the following disclaimer. - * 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. Neither the name of Red Hat, Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY RED HAT, INC. AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. - */ - -/* - * tallylog.h - login failure data file format - * - * The new login failure file is not compatible with the old faillog(8) format - * Each record in the file represents a separate UID and the file - * is indexed in that fashion. - */ - - -#ifndef _TALLYLOG_H -#define _TALLYLOG_H - -#include <stdint.h> - -struct tallylog { - char fail_line[52]; /* rhost or tty of last failure */ - uint16_t reserved; /* reserved for future use */ - uint16_t fail_cnt; /* failures since last success */ - uint64_t fail_time; /* time of last failure */ -}; -/* 64 bytes / entry */ - -#endif diff --git a/modules/pam_tally2/tst-pam_tally2 b/modules/pam_tally2/tst-pam_tally2 deleted file mode 100755 index 83c71f41..00000000 --- a/modules/pam_tally2/tst-pam_tally2 +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -../../tests/tst-dlopen .libs/pam_tally2.so diff --git a/modules/pam_timestamp/pam_timestamp_check.8.xml b/modules/pam_timestamp/pam_timestamp_check.8.xml index 8ca5a755..3a65d7ef 100644 --- a/modules/pam_timestamp/pam_timestamp_check.8.xml +++ b/modules/pam_timestamp/pam_timestamp_check.8.xml @@ -200,7 +200,7 @@ session optional pam_timestamp.so <refsect1 id='pam_timestamp-author'> <title>AUTHOR</title> <para> - pam_tally was written by Nalin Dahyabhai. + pam_timestamp was written by Nalin Dahyabhai. </para> </refsect1> diff --git a/po/POTFILES.in b/po/POTFILES.in index cb4ad62f..469e5441 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -70,10 +70,6 @@ ./modules/pam_shells/pam_shells.c ./modules/pam_stress/pam_stress.c ./modules/pam_succeed_if/pam_succeed_if.c -./modules/pam_tally/pam_tally_app.c -./modules/pam_tally/pam_tally.c -./modules/pam_tally2/pam_tally2_app.c -./modules/pam_tally2/pam_tally2.c ./modules/pam_time/pam_time.c ./modules/pam_timestamp/pam_timestamp.c ./modules/pam_timestamp/pam_timestamp_check.c |