Annotation of src/usr.bin/login/failedlogin.c, Revision 1.1
1.1 ! millert 1: /* $OpenBSD: $ */
! 2:
! 3: /*
! 4: * Copyright (c) 1996 Todd C. Miller <Todd.Miller@courtesan.com>
! 5: * All rights reserved.
! 6: *
! 7: * Redistribution and use in source and binary forms, with or without
! 8: * modification, are permitted provided that the following conditions
! 9: * are met:
! 10: * 1. Redistributions of source code must retain the above copyright
! 11: * notice, this list of conditions and the following disclaimer.
! 12: * 2. Redistributions in binary form must reproduce the above copyright
! 13: * notice, this list of conditions and the following disclaimer in the
! 14: * documentation and/or other materials provided with the distribution.
! 15: * 3. All advertising materials mentioning features or use of this software
! 16: * must display the following acknowledgement:
! 17: * This product includes software developed by Todd C. Miller.
! 18: * 4. The name of the author may not be used to endorse or promote products
! 19: * derived from this software without specific prior written permission.
! 20: *
! 21: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
! 22: * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
! 23: * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
! 24: * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
! 25: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
! 26: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
! 27: * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
! 28: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
! 29: * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
! 30: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
! 31: */
! 32:
! 33: #ifndef lint
! 34: static char rcsid[] = "$OpenBSD: $";
! 35: #endif /* not lint */
! 36:
! 37: /*
! 38: * failedlogin.c
! 39: * Log to failedlogin file and read from it, reporting the number of
! 40: * failed logins since the last good login and when/from where
! 41: * the last failed login was.
! 42: */
! 43:
! 44: #include <sys/file.h>
! 45: #include <sys/param.h>
! 46: #include <sys/stat.h>
! 47: #include <sys/time.h>
! 48:
! 49: #include <stdio.h>
! 50: #include <string.h>
! 51: #include <unistd.h>
! 52: #include <utmp.h>
! 53:
! 54: #include "pathnames.h"
! 55:
! 56: struct badlogin {
! 57: size_t count; /* number of bad logins */
! 58: time_t bl_time; /* time of the login attempt */
! 59: char bl_line[UT_LINESIZE]; /* tty used */
! 60: char bl_host[UT_HOSTSIZE]; /* remote host */
! 61: };
! 62:
! 63: /*
! 64: * Log a bad login to the failedlogin file.
! 65: */
! 66: void
! 67: log_failedlogin(uid, host, tty)
! 68: uid_t uid;
! 69: char *host, *tty;
! 70: {
! 71: struct badlogin failedlogin;
! 72: int fd;
! 73:
! 74: /* Add O_CREAT if you want to create failedlogin if it doesn't exist */
! 75: if ((fd = open(_PATH_FAILEDLOGIN, O_RDWR, S_IREAD|S_IWRITE)) >= 0) {
! 76: (void)lseek(fd, (off_t)uid * sizeof(failedlogin), L_SET);
! 77:
! 78: /* Read in last bad login so can get the count */
! 79: if (read(fd, (char *)&failedlogin, sizeof(failedlogin)) !=
! 80: sizeof(failedlogin) || failedlogin.bl_time == 0)
! 81: memset((void *)&failedlogin, 0, sizeof(failedlogin));
! 82:
! 83: (void)lseek(fd, (off_t)uid * sizeof(failedlogin), L_SET);
! 84: /* Increment count of bad logins */
! 85: ++failedlogin.count;
! 86: (void)time(&failedlogin.bl_time);
! 87: strncpy(failedlogin.bl_line, tty, sizeof(failedlogin.bl_line));
! 88: if (host)
! 89: strncpy(failedlogin.bl_host, host, sizeof(failedlogin.bl_host));
! 90: else
! 91: *failedlogin.bl_host = '\0'; /* NULL host field */
! 92: (void)write(fd, (char *)&failedlogin, sizeof(failedlogin));
! 93: (void)close(fd);
! 94: }
! 95: }
! 96:
! 97: /*
! 98: * Check the failedlogin file and report about the number of unsuccessful
! 99: * logins and info about the last one in lastlogin style.
! 100: * NOTE: zeros the count field since this is assumed to be called after the
! 101: * user has been validated.
! 102: */
! 103: int
! 104: check_failedlogin(uid)
! 105: uid_t uid;
! 106: {
! 107: int fd;
! 108: struct badlogin failedlogin;
! 109: int was_bad = 0;
! 110:
! 111: (void)memset((void *)&failedlogin, 0, sizeof(failedlogin));
! 112:
! 113: if ((fd = open(_PATH_FAILEDLOGIN, O_RDWR, 0)) >= 0) {
! 114: (void)lseek(fd, (off_t)uid * sizeof(failedlogin), L_SET);
! 115: if (read(fd, (char *)&failedlogin, sizeof(failedlogin)) ==
! 116: sizeof(failedlogin) && failedlogin.count > 0 ) {
! 117: /* There was a bad login */
! 118: was_bad = 1;
! 119: if (failedlogin.count > 1)
! 120: (void)printf("There have been %u unsuccessful login attempts to your account.\n",
! 121: failedlogin.count);
! 122: (void)printf("Last unsucessful login: %.*s", 24-5,
! 123: (char *)ctime(&failedlogin.bl_time));
! 124: (void)printf(" on %.*s",
! 125: (int)sizeof(failedlogin.bl_line),
! 126: failedlogin.bl_line);
! 127: if (*failedlogin.bl_host != '\0')
! 128: (void)printf(" from %.*s",
! 129: (int)sizeof(failedlogin.bl_host),
! 130: failedlogin.bl_host);
! 131: (void)putchar('\n');
! 132:
! 133: /* Reset since this is a good login and write record */
! 134: failedlogin.count = 0;
! 135: (void)lseek(fd, (off_t)uid * sizeof(failedlogin), L_SET);
! 136: (void)write(fd, (char *)&failedlogin, sizeof(failedlogin));
! 137: }
! 138: (void)close(fd);
! 139: }
! 140: return(was_bad);
! 141: }