c4daf63ae5
- obsoletes pam-bsc1178727-initialize-daysleft.patch - Multiple minor bug fixes, portability fixes, and documentation improvements. - Extended libpam API with pam_modutil_check_user_in_passwd function. - pam_faillock: changed /run/faillock/$USER permissions from 0600 to 0660. - pam_motd: read motd files with target user credentials skipping unreadable ones. - pam_pwhistory: added a SELinux helper executable. - pam_unix, pam_usertype: implemented avoidance of certain timing attacks. - pam_wheel: implemented PAM_RUSER fallback for the case when getlogin fails. - pam_env: Reading of the user environment is deprecated and will be removed at some point in the future. - libpam: pam_modutil_drop_priv() now correctly sets the target user's supplementary groups, allowing pam_motd to filter messages accordingly - Refresh pam-xauth_ownership.patch - pam_tally2-removal.patch: Re-add pam_tally2 for deprecated sub-package - pam_cracklib-removal.patch: Re-add pam_cracklib for deprecated sub-package OBS-URL: https://build.opensuse.org/package/show/Linux-PAM/pam?expand=0&rev=228
1333 lines
41 KiB
Diff
1333 lines
41 KiB
Diff
From 709e37b7e131d35b0ec30d31f858bc6917dd2b2e Mon Sep 17 00:00:00 2001
|
|
From: "Dmitry V. Levin" <ldv@altlinux.org>
|
|
Date: Thu, 29 Oct 2020 08:00:00 +0000
|
|
Subject: [PATCH] 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.
|
|
---
|
|
NEWS | 1 +
|
|
ci/run-build-and-tests.sh | 2 +-
|
|
configure.ac | 23 +-
|
|
doc/sag/Linux-PAM_SAG.xml | 4 -
|
|
doc/sag/pam_tally.xml | 38 -
|
|
doc/sag/pam_tally2.xml | 46 -
|
|
modules/Makefile.am | 10 -
|
|
modules/pam_tally/.gitignore | 1 -
|
|
modules/pam_tally/Makefile.am | 41 -
|
|
modules/pam_tally/README.xml | 41 -
|
|
modules/pam_tally/faillog.h | 55 -
|
|
modules/pam_tally/pam_tally.8.xml | 459 --------
|
|
modules/pam_tally/pam_tally.c | 854 --------------
|
|
modules/pam_tally/pam_tally_app.c | 6 -
|
|
modules/pam_tally/tst-pam_tally | 2 -
|
|
modules/pam_tally2/.gitignore | 1 -
|
|
modules/pam_tally2/Makefile.am | 45 -
|
|
modules/pam_tally2/README.xml | 46 -
|
|
modules/pam_tally2/pam_tally2.8.xml | 450 -------
|
|
modules/pam_tally2/pam_tally2.c | 1036 -----------------
|
|
modules/pam_tally2/pam_tally2_app.c | 6 -
|
|
modules/pam_tally2/tallylog.h | 52 -
|
|
modules/pam_tally2/tst-pam_tally2 | 2 -
|
|
.../pam_timestamp/pam_timestamp_check.8.xml | 2 +-
|
|
po/POTFILES.in | 4 -
|
|
25 files changed, 4 insertions(+), 3223 deletions(-)
|
|
delete mode 100644 doc/sag/pam_tally.xml
|
|
delete mode 100644 doc/sag/pam_tally2.xml
|
|
delete mode 100644 modules/pam_tally/.gitignore
|
|
delete mode 100644 modules/pam_tally/Makefile.am
|
|
delete mode 100644 modules/pam_tally/README.xml
|
|
delete mode 100644 modules/pam_tally/faillog.h
|
|
delete mode 100644 modules/pam_tally/pam_tally.8.xml
|
|
delete mode 100644 modules/pam_tally/pam_tally.c
|
|
delete mode 100644 modules/pam_tally/pam_tally_app.c
|
|
delete mode 100755 modules/pam_tally/tst-pam_tally
|
|
delete mode 100644 modules/pam_tally2/.gitignore
|
|
delete mode 100644 modules/pam_tally2/Makefile.am
|
|
delete mode 100644 modules/pam_tally2/README.xml
|
|
delete mode 100644 modules/pam_tally2/pam_tally2.8.xml
|
|
delete mode 100644 modules/pam_tally2/pam_tally2.c
|
|
delete mode 100644 modules/pam_tally2/pam_tally2_app.c
|
|
delete mode 100644 modules/pam_tally2/tallylog.h
|
|
delete mode 100755 modules/pam_tally2/tst-pam_tally2
|
|
|
|
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_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/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_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/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
|