#include <sys/stat.h>
#include <sys/time.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <utmp.h>
#include "pathnames.h"
struct badlogin {
char bl_line[UT_LINESIZE];
char bl_name[UT_NAMESIZE];
char bl_host[UT_HOSTSIZE];
time_t bl_time;
size_t count;
};
void log_failedlogin(uid_t, char *, char *, char *);
int check_failedlogin(uid_t);
void
log_failedlogin(uid_t uid, char *host, char *name, char *tty)
{
struct badlogin failedlogin;
int fd;
if ((fd = open(_PATH_FAILEDLOGIN, O_RDWR)) >= 0) {
(void)lseek(fd, (off_t)uid * sizeof(failedlogin), SEEK_SET);
if (read(fd, (char *)&failedlogin, sizeof(failedlogin)) !=
sizeof(failedlogin) || failedlogin.bl_time == 0)
memset((void *)&failedlogin, 0, sizeof(failedlogin));
(void)lseek(fd, (off_t)uid * sizeof(failedlogin), SEEK_SET);
++failedlogin.count;
(void)time(&failedlogin.bl_time);
strncpy(failedlogin.bl_line, tty, sizeof(failedlogin.bl_line));
if (host)
strncpy(failedlogin.bl_host, host, sizeof(failedlogin.bl_host));
else
*failedlogin.bl_host = '\0';
if (name)
strncpy(failedlogin.bl_name, name, sizeof(failedlogin.bl_name));
else
*failedlogin.bl_name = '\0';
(void)write(fd, (char *)&failedlogin, sizeof(failedlogin));
(void)close(fd);
}
}
int
check_failedlogin(uid_t uid)
{
struct badlogin failedlogin;
int fd, was_bad = 0;
(void)memset((void *)&failedlogin, 0, sizeof(failedlogin));
if ((fd = open(_PATH_FAILEDLOGIN, O_RDWR)) >= 0) {
(void)lseek(fd, (off_t)uid * sizeof(failedlogin), SEEK_SET);
if (read(fd, (char *)&failedlogin, sizeof(failedlogin)) ==
sizeof(failedlogin) && failedlogin.count > 0 ) {
was_bad = 1;
if (failedlogin.count > 1)
(void)printf("There have been %lu unsuccessful "
"login attempts to your account.\n",
(u_long)failedlogin.count);
(void)printf("Last unsuccessful login: %.*s", 24-5,
(char *)ctime(&failedlogin.bl_time));
(void)printf(" on %.*s",
(int)sizeof(failedlogin.bl_line),
failedlogin.bl_line);
if (*failedlogin.bl_host != '\0') {
if (*failedlogin.bl_name != '\0')
(void)printf(" from %.*s@%.*s",
(int)sizeof(failedlogin.bl_name),
failedlogin.bl_name,
(int)sizeof(failedlogin.bl_host),
failedlogin.bl_host);
else
(void)printf(" from %.*s",
(int)sizeof(failedlogin.bl_host),
failedlogin.bl_host);
}
(void)putchar('\n');
failedlogin.count = 0;
(void)lseek(fd, (off_t)uid * sizeof(failedlogin),
SEEK_SET);
(void)write(fd, (char *)&failedlogin,
sizeof(failedlogin));
}
(void)close(fd);
}
return(was_bad);
}