summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShreenidhi Shedi <sshedi@vmware.com>2022-07-01 12:52:24 +0530
committerShreenidhi Shedi <53473811+sshedi@users.noreply.github.com>2022-07-01 16:16:04 +0530
commit94f0f5ebb876b1ef89c0acbda74b0794b3be7f04 (patch)
treea0708b908c5185368f937cd37b246ce9827189dc
parent5d7fa71d4db6acffbda59363e0b415e9a484ed9a (diff)
downloadlinux-pam-git-94f0f5ebb876b1ef89c0acbda74b0794b3be7f04.tar.gz
faillock: add support to print login failure info in legacy format
pam_tally2 had a simple and minimalstic output to show login failure info, new output of faillock makes the output look a bit complex and doesn't show failure counts in a straight manner. This patch fixes the above issue by adding "--legacy-output" flag to faillock which makes it possible to get output in pam_tally2 style. Signed-off-by: Shreenidhi Shedi <sshedi@vmware.com>
-rw-r--r--modules/pam_faillock/faillock_config.h1
-rw-r--r--modules/pam_faillock/main.c76
2 files changed, 66 insertions, 11 deletions
diff --git a/modules/pam_faillock/faillock_config.h b/modules/pam_faillock/faillock_config.h
index db2851f5..04bc699b 100644
--- a/modules/pam_faillock/faillock_config.h
+++ b/modules/pam_faillock/faillock_config.h
@@ -78,6 +78,7 @@ struct options {
unsigned int reset;
const char *progname;
+ int legacy_output; /* show failure info in pam_tally2 style */
};
int read_config_file(pam_handle_t *pamh, struct options *opts,
diff --git a/modules/pam_faillock/main.c b/modules/pam_faillock/main.c
index 1370a0e2..788c8f7b 100644
--- a/modules/pam_faillock/main.c
+++ b/modules/pam_faillock/main.c
@@ -97,6 +97,9 @@ 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;
@@ -123,8 +126,23 @@ args_parse(int argc, char **argv, struct options *opts)
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
@@ -136,27 +154,58 @@ print_in_new_format(struct options *opts, const struct tally_data *tallies, cons
printf("%-19s %-5s %-48s %-5s\n", "When", "Type", "Source", "Valid");
for (i = 0; i < tallies->count; i++) {
- struct tm *tm;
uint16_t status;
- time_t when = 0;
char timebuf[80];
- status = tallies->records[i].status;
- when = tallies->records[i].time;
-
- tm = localtime(&when);
- if(tm == NULL) {
+ 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;
}
- strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S", tm);
+
+ 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
do_user(struct options *opts, const char *user)
{
@@ -220,7 +269,12 @@ do_user(struct options *opts, const char *user)
return 5;
}
- print_in_new_format(opts, &tallies, user);
+ if (opts->legacy_output == 0) {
+ print_in_new_format(opts, &tallies, user);
+ }
+ else {
+ print_in_legacy_format(opts, &tallies, user);
+ }
free(tallies.records);
}