summaryrefslogtreecommitdiffstats
path: root/libmisc/failure.c
diff options
context:
space:
mode:
Diffstat (limited to 'libmisc/failure.c')
-rw-r--r--libmisc/failure.c295
1 files changed, 0 insertions, 295 deletions
diff --git a/libmisc/failure.c b/libmisc/failure.c
deleted file mode 100644
index 1aab299..0000000
--- a/libmisc/failure.c
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * SPDX-FileCopyrightText: 1989 - 1994, Julianne Frances Haugh
- * SPDX-FileCopyrightText: 1996 - 1998, Marek Michałkiewicz
- * SPDX-FileCopyrightText: 2002 - 2005, Tomasz Kłoczko
- * SPDX-FileCopyrightText: 2008 - 2010, Nicolas François
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <config.h>
-
-#ident "$Id$"
-
-#include <fcntl.h>
-#include <stdio.h>
-#include <unistd.h>
-#include "defines.h"
-#include "faillog.h"
-#include "getdef.h"
-#include "failure.h"
-#define YEAR (365L*DAY)
-/*
- * failure - make failure entry
- *
- * failure() creates a new (struct faillog) entry or updates an
- * existing one with the current failed login information.
- */
-void failure (uid_t uid, const char *tty, struct faillog *fl)
-{
- int fd;
- off_t offset_uid = (off_t) (sizeof *fl) * uid;
-
- /*
- * Don't do anything if failure logging isn't set up.
- */
-
- if (access (FAILLOG_FILE, F_OK) != 0) {
- return;
- }
-
- fd = open (FAILLOG_FILE, O_RDWR);
- if (fd < 0) {
- SYSLOG ((LOG_WARN,
- "Can't write faillog entry for UID %lu in %s.",
- (unsigned long) uid, FAILLOG_FILE));
- return;
- }
-
- /*
- * The file is indexed by UID value meaning that shared UID's
- * share failure log records. That's OK since they really
- * share just about everything else ...
- */
-
- if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid)
- || (read (fd, (char *) fl, sizeof *fl) != (ssize_t) sizeof *fl)) {
- /* This is not necessarily a failure. The file is
- * initially zero length.
- *
- * If lseek() or read() failed for any other reason, this
- * might reset the counter. But the new failure will be
- * logged.
- */
- memzero (fl, sizeof *fl);
- }
-
- /*
- * Update the record. We increment the failure count to log the
- * latest failure. The only concern here is overflow, and we'll
- * check for that. The line name and time of day are both
- * updated as well.
- */
-
- if (fl->fail_cnt + 1 > 0) {
- fl->fail_cnt++;
- }
-
- strncpy (fl->fail_line, tty, sizeof (fl->fail_line) - 1);
- (void) time (&fl->fail_time);
-
- /*
- * Seek back to the correct position in the file and write the
- * record out. Ideally we should lock the file in case the same
- * account is being logged simultaneously. But the risk doesn't
- * seem that great.
- */
-
- if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid)
- || (write (fd, (char *) fl, sizeof *fl) != (ssize_t) sizeof *fl)
- || (close (fd) != 0)) {
- SYSLOG ((LOG_WARN,
- "Can't write faillog entry for UID %lu in %s.",
- (unsigned long) uid, FAILLOG_FILE));
- (void) close (fd);
- }
-}
-
-static bool too_many_failures (const struct faillog *fl)
-{
- time_t now;
-
- if ((0 == fl->fail_max) || (fl->fail_cnt < fl->fail_max)) {
- return false;
- }
-
- if (0 == fl->fail_locktime) {
- return true; /* locked until reset manually */
- }
-
- (void) time (&now);
- if ((fl->fail_time + fl->fail_locktime) < now) {
- return false; /* enough time since last failure */
- }
-
- return true;
-}
-
-/*
- * failcheck - check for failures > allowable
- *
- * failcheck() is called AFTER the password has been validated. If the
- * account has been "attacked" with too many login failures, failcheck()
- * returns 0 to indicate that the login should be denied even though
- * the password is valid.
- *
- * failed indicates if the login failed AFTER the password has been
- * validated.
- */
-
-int failcheck (uid_t uid, struct faillog *fl, bool failed)
-{
- int fd;
- struct faillog fail;
- off_t offset_uid = (off_t) (sizeof *fl) * uid;
-
- /*
- * Suppress the check if the log file isn't there.
- */
-
- if (access (FAILLOG_FILE, F_OK) != 0) {
- return 1;
- }
-
- fd = open (FAILLOG_FILE, failed?O_RDONLY:O_RDWR);
- if (fd < 0) {
- SYSLOG ((LOG_WARN,
- "Can't open the faillog file (%s) to check UID %lu. "
- "User access authorized.",
- FAILLOG_FILE, (unsigned long) uid));
- return 1;
- }
-
- /*
- * Get the record from the file and determine if the user has
- * exceeded the failure limit. If "max" is zero, any number
- * of failures are permitted. Only when "max" is non-zero and
- * "cnt" is greater than or equal to "max" is the account
- * considered to be locked.
- *
- * If read fails, there is no record for this user yet (the
- * file is initially zero length and extended by writes), so
- * no need to reset the count.
- */
-
- if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid)
- || (read (fd, (char *) fl, sizeof *fl) != (ssize_t) sizeof *fl)) {
- (void) close (fd);
- return 1;
- }
-
- if (too_many_failures (fl)) {
- (void) close (fd);
- return 0;
- }
-
- /*
- * The record is updated if this is not a failure. The count will
- * be reset to zero, but the rest of the information will be left
- * in the record in case someone wants to see where the failed
- * login originated.
- */
-
- if (!failed) {
- fail = *fl;
- fail.fail_cnt = 0;
-
- if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid)
- || (write (fd, (const void *) &fail, sizeof fail) != (ssize_t) sizeof fail)
- || (close (fd) != 0)) {
- SYSLOG ((LOG_WARN,
- "Can't reset faillog entry for UID %lu in %s.",
- (unsigned long) uid, FAILLOG_FILE));
- (void) close (fd);
- }
- } else {
- (void) close (fd);
- }
-
- return 1;
-}
-
-/*
- * failprint - print line of failure information
- *
- * failprint takes a (struct faillog) entry and formats it into a
- * message which is displayed at login time.
- */
-
-void failprint (const struct faillog *fail)
-{
- struct tm *tp;
- char lasttimeb[256];
- char *lasttime = lasttimeb;
- time_t NOW;
-
- if (0 == fail->fail_cnt) {
- return;
- }
-
- tp = localtime (&(fail->fail_time));
- (void) time (&NOW);
-
- /*
- * Print all information we have.
- */
- (void) strftime (lasttimeb, sizeof lasttimeb, "%c", tp);
-
- /*@-formatconst@*/
- (void) printf (ngettext ("%d failure since last login.\n"
- "Last was %s on %s.\n",
- "%d failures since last login.\n"
- "Last was %s on %s.\n",
- (unsigned long) fail->fail_cnt),
- fail->fail_cnt, lasttime, fail->fail_line);
- /*@=formatconst@*/
-}
-
-/*
- * failtmp - update the cumulative failure log
- *
- * failtmp updates the (struct utmp) formatted failure log which
- * maintains a record of all login failures.
- */
-
-void failtmp (const char *username,
-#ifdef USE_UTMPX
- const struct utmpx *failent
-#else /* !USE_UTMPX */
- const struct utmp *failent
-#endif /* !USE_UTMPX */
- )
-{
- const char *ftmp;
- int fd;
-
- /*
- * Get the name of the failure file. If no file has been defined
- * in login.defs, don't do this.
- */
-
- ftmp = getdef_str ("FTMP_FILE");
- if (NULL == ftmp) {
- return;
- }
-
- /*
- * Open the file for append. It must already exist for this
- * feature to be used.
- */
-
- if (access (ftmp, F_OK) != 0) {
- return;
- }
-
- fd = open (ftmp, O_WRONLY | O_APPEND);
- if (-1 == fd) {
- SYSLOG ((LOG_WARN,
- "Can't append failure of user %s to %s.",
- username, ftmp));
- return;
- }
-
- /*
- * Append the new failure record and close the log file.
- */
-
- if ( (write (fd, (const void *) failent, sizeof *failent) != (ssize_t) sizeof *failent)
- || (close (fd) != 0)) {
- SYSLOG ((LOG_WARN,
- "Can't append failure of user %s to %s.",
- username, ftmp));
- (void) close (fd);
- }
-}
-