diff options
author | Sam Hartman <hartmans@debian.org> | 2023-09-11 14:09:57 -0600 |
---|---|---|
committer | Sam Hartman <hartmans@debian.org> | 2023-09-11 14:09:57 -0600 |
commit | e9aa2ef52a423a3a33299bf7e8715eb5bd76ea67 (patch) | |
tree | 8b1bd3f4fc01ef0261a13d75cf48be9002480aaf /modules/pam_faillock/main.c | |
parent | 99d0d1c5c4f07332daa86e73981267a761bc966e (diff) | |
parent | bf07335a19d6192adaf4b1a817d2101ee0bad134 (diff) | |
download | pam-e9aa2ef52a423a3a33299bf7e8715eb5bd76ea67.tar.gz pam-e9aa2ef52a423a3a33299bf7e8715eb5bd76ea67.tar.bz2 pam-e9aa2ef52a423a3a33299bf7e8715eb5bd76ea67.zip |
New upstream version 1.5.3
Diffstat (limited to 'modules/pam_faillock/main.c')
-rw-r--r-- | modules/pam_faillock/main.c | 160 |
1 files changed, 129 insertions, 31 deletions
diff --git a/modules/pam_faillock/main.c b/modules/pam_faillock/main.c index f62e1bb2..136be834 100644 --- a/modules/pam_faillock/main.c +++ b/modules/pam_faillock/main.c @@ -51,32 +51,40 @@ #define AUDIT_NO_ID ((unsigned int) -1) #endif +#include "pam_inline.h" #include "faillock.h" - -struct options { - unsigned int reset; - const char *dir; - const char *user; - const char *progname; -}; +#include "faillock_config.h" static int args_parse(int argc, char **argv, struct options *opts) { int i; + int rv; + const char *dir = NULL; + const char *conf = NULL; + memset(opts, 0, sizeof(*opts)); - opts->dir = FAILLOCK_DEFAULT_TALLYDIR; opts->progname = argv[0]; for (i = 1; i < argc; ++i) { - if (strcmp(argv[i], "--dir") == 0) { + if (strcmp(argv[i], "--conf") == 0) { + ++i; + if (i >= argc || strlen(argv[i]) == 0) { + fprintf(stderr, "%s: No configuration file supplied.\n", + argv[0]); + return -1; + } + conf = argv[i]; + } + else if (strcmp(argv[i], "--dir") == 0) { ++i; if (i >= argc || strlen(argv[i]) == 0) { - fprintf(stderr, "%s: No directory supplied.\n", argv[0]); + fprintf(stderr, "%s: No records directory supplied.\n", + argv[0]); return -1; } - opts->dir = argv[i]; + dir = argv[i]; } else if (strcmp(argv[i], "--user") == 0) { ++i; @@ -89,19 +97,113 @@ args_parse(int argc, char **argv, struct options *opts) else if (strcmp(argv[i], "--reset") == 0) { opts->reset = 1; } + else if (!strcmp(argv[i], "--legacy-output")) { + opts->legacy_output = 1; + } else { fprintf(stderr, "%s: Unknown option: %s\n", argv[0], argv[i]); return -1; } } + + if ((rv = read_config_file(NULL, opts, conf)) != PAM_SUCCESS) { + fprintf(stderr, "Configuration file missing or broken"); + return rv; + } + + if (dir != NULL) { + free(opts->dir); + opts->dir = strdup(dir); + if (opts->dir == NULL) { + fprintf(stderr, "Error allocating memory: %m"); + return -1; + } + } + return 0; } static void usage(const char *progname) { - fprintf(stderr, _("Usage: %s [--dir /path/to/tally-directory] [--user username] [--reset]\n"), - progname); + fprintf(stderr, + _("Usage: %s [--dir /path/to/tally-directory]" + " [--user username] [--reset] [--legacy-output]\n"), progname); + +} + +static int +get_local_time(time_t when, char *timebuf, size_t timebuf_size) +{ + struct tm *tm; + + tm = localtime(&when); + if (tm == NULL) { + return -1; + } + strftime(timebuf, timebuf_size, "%Y-%m-%d %H:%M:%S", tm); + return 0; +} + +static void +print_in_new_format(struct options *opts, const struct tally_data *tallies, const char *user) +{ + uint32_t i; + + printf("%s:\n", user); + printf("%-19s %-5s %-48s %-5s\n", "When", "Type", "Source", "Valid"); + + for (i = 0; i < tallies->count; i++) { + uint16_t status; + char timebuf[80]; + + if (get_local_time(tallies->records[i].time, timebuf, sizeof(timebuf)) != 0) { + fprintf(stderr, "%s: Invalid timestamp in the tally record\n", + opts->progname); + continue; + } + + status = tallies->records[i].status; + + printf("%-19s %-5s %-52.52s %s\n", timebuf, + status & TALLY_STATUS_RHOST ? "RHOST" : (status & TALLY_STATUS_TTY ? "TTY" : "SVC"), + tallies->records[i].source, status & TALLY_STATUS_VALID ? "V":"I"); + } +} + +static void +print_in_legacy_format(struct options *opts, const struct tally_data *tallies, const char *user) +{ + uint32_t tally_count; + static uint32_t pr_once; + + if (pr_once == 0) { + printf(_("Login Failures Latest failure From\n")); + pr_once = 1; + } + + printf("%-15.15s ", user); + + tally_count = tallies->count; + + if (tally_count > 0) { + uint32_t i; + char timebuf[80]; + + i = tally_count - 1; + + if (get_local_time(tallies->records[i].time, timebuf, sizeof(timebuf)) != 0) { + fprintf(stderr, "%s: Invalid timestamp in the tally record\n", + opts->progname); + return; + } + + printf("%5u %25s %s\n", + tally_count, timebuf, tallies->records[i].source); + } + else { + printf("%5u\n", tally_count); + } } static int @@ -111,10 +213,15 @@ do_user(struct options *opts, const char *user) int rv; struct tally_data tallies; struct passwd *pwd; + const char *dir = get_tally_dir(opts); pwd = getpwnam(user); + if (pwd == NULL) { + fprintf(stderr, "%s: Error no such user: %s\n", opts->progname, user); + return 1; + } - fd = open_tally(opts->dir, user, pwd != NULL ? pwd->pw_uid : 0, 0); + fd = open_tally(dir, user, pwd->pw_uid, 1); if (fd == -1) { if (errno == ENOENT) { @@ -153,8 +260,6 @@ do_user(struct options *opts, const char *user) } } else { - unsigned int i; - memset(&tallies, 0, sizeof(tallies)); if (read_tally(fd, &tallies) == -1) { fprintf(stderr, "%s: Error reading the tally file for %s:", @@ -164,21 +269,13 @@ do_user(struct options *opts, const char *user) return 5; } - printf("%s:\n", user); - printf("%-19s %-5s %-48s %-5s\n", "When", "Type", "Source", "Valid"); - - for (i = 0; i < tallies.count; i++) { - struct tm *tm; - char timebuf[80]; - uint16_t status = tallies.records[i].status; - time_t when = tallies.records[i].time; - - tm = localtime(&when); - strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S", tm); - printf("%-19s %-5s %-52.52s %s\n", timebuf, - status & TALLY_STATUS_RHOST ? "RHOST" : (status & TALLY_STATUS_TTY ? "TTY" : "SVC"), - tallies.records[i].source, status & TALLY_STATUS_VALID ? "V":"I"); + if (opts->legacy_output == 0) { + print_in_new_format(opts, &tallies, user); } + else { + print_in_legacy_format(opts, &tallies, user); + } + free(tallies.records); } close(fd); @@ -190,8 +287,9 @@ do_allusers(struct options *opts) { struct dirent **userlist; int rv, i; + const char *dir = get_tally_dir(opts); - rv = scandir(opts->dir, &userlist, NULL, alphasort); + rv = scandir(dir, &userlist, NULL, alphasort); if (rv < 0) { fprintf(stderr, "%s: Error reading tally directory: %m\n", opts->progname); return 2; |