]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
doveadm: Added penalty command to dump auth penalty state.
authorTimo Sirainen <tss@iki.fi>
Sat, 20 Feb 2010 07:33:01 +0000 (09:33 +0200)
committerTimo Sirainen <tss@iki.fi>
Sat, 20 Feb 2010 07:33:01 +0000 (09:33 +0200)
--HG--
branch : HEAD

src/doveadm/Makefile.am
src/doveadm/doveadm-penalty.c [new file with mode: 0644]
src/doveadm/doveadm.c
src/doveadm/doveadm.h

index 12f27e0ff101b1fb4fbff0e8d63c19e57c8648cc..92793d6c516587bdb544b779603a9daf2b1b59f5 100644 (file)
@@ -36,6 +36,7 @@ doveadm_SOURCES = \
        doveadm-dump-mailboxlog.c \
        doveadm-dump-thread.c \
        doveadm-mail.c \
+       doveadm-penalty.c \
        doveadm-pw.c \
        doveadm-who.c
 
diff --git a/src/doveadm/doveadm-penalty.c b/src/doveadm/doveadm-penalty.c
new file mode 100644 (file)
index 0000000..c81cf6f
--- /dev/null
@@ -0,0 +1,126 @@
+/* Copyright (c) 2009-2010 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "array.h"
+#include "network.h"
+#include "istream.h"
+#include "hash.h"
+#include "doveadm.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+
+struct penalty_line {
+       struct ip_addr ip;
+       unsigned int penalty;
+       time_t last_penalty, last_update;
+};
+
+struct penalty_context {
+       const char *anvil_path;
+
+       struct ip_addr net_ip;
+       unsigned int net_bits;
+};
+
+static void penalty_parse_line(const char *line, struct penalty_line *line_r)
+{
+       const char *const *args = t_strsplit(line, "\t");
+       const char *ident = args[0];
+       const char *penalty_str = args[1];
+       const char *last_penalty_str = args[2];
+       const char *last_update_str = args[3];
+
+       memset(line_r, 0, sizeof(*line_r));
+
+       net_addr2ip(ident, &line_r->ip);
+       line_r->penalty = strtoul(penalty_str, NULL, 10);
+       line_r->last_penalty = strtoul(last_penalty_str, NULL, 10);
+       line_r->last_update = strtoul(last_update_str, NULL, 10);
+}
+
+static void
+penalty_print_line(struct penalty_context *ctx,
+                  const struct penalty_line *line)
+{
+       const struct tm *tm;
+       char buf[10];
+
+       if (ctx->net_bits > 0) {
+               if (!net_is_in_network(&line->ip, &ctx->net_ip, ctx->net_bits))
+                       return;
+       }
+
+       tm = localtime(&line->last_update);
+       strftime(buf, sizeof(buf), "%H:%M:%S", tm);
+
+       printf("%-16s %7u %s %s\n", net_ip2addr(&line->ip), line->penalty,
+              unixdate2str(line->last_penalty), buf);
+}
+
+static void penalty_lookup(struct penalty_context *ctx)
+{
+#define ANVIL_HANDSHAKE "VERSION\tanvil\t1\t0\n"
+#define ANVIL_CMD ANVIL_HANDSHAKE"PENALTY-DUMP\n"
+       struct istream *input;
+       const char *line;
+       int fd;
+
+       fd = net_connect_unix(ctx->anvil_path);
+       if (fd == -1)
+               i_fatal("net_connect_unix(%s) failed: %m", ctx->anvil_path);
+       net_set_nonblock(fd, FALSE);
+
+       input = i_stream_create_fd(fd, (size_t)-1, TRUE);
+       if (write(fd, ANVIL_CMD, strlen(ANVIL_CMD)) < 0)
+               i_fatal("write(%s) failed: %m", ctx->anvil_path);
+       while ((line = i_stream_read_next_line(input)) != NULL) {
+               if (*line == '\0')
+                       break;
+               T_BEGIN {
+                       struct penalty_line penalty_line;
+
+                       penalty_parse_line(line, &penalty_line);
+                       penalty_print_line(ctx, &penalty_line);
+               } T_END;
+       }
+       if (input->stream_errno != 0)
+               i_fatal("read(%s) failed: %m", ctx->anvil_path);
+
+       i_stream_destroy(&input);
+}
+
+static void cmd_penalty(int argc, char *argv[])
+{
+       struct penalty_context ctx;
+       int c;
+
+       memset(&ctx, 0, sizeof(ctx));
+       ctx.anvil_path = PKG_RUNDIR"/anvil";
+       while ((c = getopt(argc, argv, "a:")) > 0) {
+               switch (c) {
+               case 'a':
+                       ctx.anvil_path = optarg;
+                       break;
+               default:
+                       help(&doveadm_cmd_penalty);
+               }
+       }
+
+       if (argv[1] != NULL) {
+               if (net_parse_range(argv[1], &ctx.net_ip, &ctx.net_bits) == 0)
+                       argv++;
+       }
+       if (argv[1] != NULL)
+               help(&doveadm_cmd_penalty);
+
+       fprintf(stderr, "%-16s penalty last_penalty        last_update\n", "IP");
+       penalty_lookup(&ctx);
+}
+
+struct doveadm_cmd doveadm_cmd_penalty = {
+       cmd_penalty, "penalty",
+       "[-a <anvil socket path>] [<ip/bits>]", NULL
+};
index 5bac41aa6b77befd7539e654937def8c5bef3de6..fc3b0bad41e10e20cab5ef93a0fbe139c1de6165 100644 (file)
@@ -101,6 +101,7 @@ int main(int argc, char *argv[])
        doveadm_register_cmd(&doveadm_cmd_dump);
        doveadm_register_cmd(&doveadm_cmd_pw);
        doveadm_register_cmd(&doveadm_cmd_who);
+       doveadm_register_cmd(&doveadm_cmd_penalty);
 
        while ((c = master_getopt(master_service)) > 0) {
                switch (c) {
index 4ee48f7ccdfa783622b2ec8c87de91b9ce959a80..21c4e60c5f0cf5c8847c47f4b4ef634eb88ac3cf 100644 (file)
@@ -17,6 +17,7 @@ extern struct doveadm_cmd doveadm_cmd_user;
 extern struct doveadm_cmd doveadm_cmd_dump;
 extern struct doveadm_cmd doveadm_cmd_pw;
 extern struct doveadm_cmd doveadm_cmd_who;
+extern struct doveadm_cmd doveadm_cmd_penalty;
 
 extern bool doveadm_verbose, doveadm_debug;