dovecot-1.1: If login process crashes, log the IP address that (...
dovecot at dovecot.org
dovecot at dovecot.org
Wed Jan 14 22:14:14 EET 2009
details: http://hg.dovecot.org/dovecot-1.1/rev/2146e1963b79
changeset: 8098:2146e1963b79
user: Timo Sirainen <tss at iki.fi>
date: Wed Jan 14 15:14:11 2009 -0500
description:
If login process crashes, log the IP address that (maybe) caused it.
diffstat:
9 files changed, 67 insertions(+), 12 deletions(-)
src/lib/failures.c | 11 +++++++++++
src/lib/failures.h | 7 ++++++-
src/login-common/main.c | 2 ++
src/master/auth-process.c | 4 ++--
src/master/child-process.c | 29 +++++++++++++++++++++++------
src/master/child-process.h | 4 +++-
src/master/log.c | 15 +++++++++++++++
src/master/login-process.c | 5 ++++-
src/master/ssl-init.c | 2 +-
diffs (223 lines):
diff -r c612f0fa6bfb -r 2146e1963b79 src/lib/failures.c
--- a/src/lib/failures.c Wed Jan 14 14:06:46 2009 -0500
+++ b/src/lib/failures.c Wed Jan 14 15:14:11 2009 -0500
@@ -3,6 +3,7 @@
#include "lib.h"
#include "ioloop.h"
#include "str.h"
+#include "network.h"
#include "backtrace-string.h"
#include "printf-format-fix.h"
#include "write-full.h"
@@ -459,6 +460,16 @@ void i_set_failure_timestamp_format(cons
log_stamp_format = i_strdup(fmt);
}
+void i_set_failure_ip(const struct ip_addr *ip)
+{
+ const char *str;
+
+ if (error_handler == i_internal_error_handler) {
+ str = t_strdup_printf("\x01Oip=%s\n", net_ip2addr(ip));
+ (void)write_full(2, str, strlen(str));
+ }
+}
+
void i_set_failure_exit_callback(void (*callback)(int *status))
{
failure_exit_callback = callback;
diff -r c612f0fa6bfb -r 2146e1963b79 src/lib/failures.h
--- a/src/lib/failures.h Wed Jan 14 14:06:46 2009 -0500
+++ b/src/lib/failures.h Wed Jan 14 15:14:11 2009 -0500
@@ -1,5 +1,7 @@
#ifndef FAILURES_H
#define FAILURES_H
+
+struct ip_addr;
/* Default exit status codes that we could use. */
enum fatal_exit_status {
@@ -78,9 +80,12 @@ void i_set_info_file(const char *path);
/* Set the failure prefix. This is used only when logging to a file. */
void i_set_failure_prefix(const char *prefix);
-
/* Prefix failures with a timestamp. fmt is in strftime() format. */
void i_set_failure_timestamp_format(const char *fmt);
+/* When logging with internal error protocol, update the process's current
+ IP address. This is mainly used by the master process to log some IP
+ address if the process crash. */
+void i_set_failure_ip(const struct ip_addr *ip);
/* Call the callback before exit()ing. The callback may update the status. */
void i_set_failure_exit_callback(void (*callback)(int *status));
diff -r c612f0fa6bfb -r 2146e1963b79 src/login-common/main.c
--- a/src/login-common/main.c Wed Jan 14 14:06:46 2009 -0500
+++ b/src/login-common/main.c Wed Jan 14 15:14:11 2009 -0500
@@ -89,6 +89,7 @@ static void login_accept(void *context)
i_error("accept() failed: %m");
return;
}
+ i_set_failure_ip(&remote_ip);
if (net_getsockname(fd, &local_ip, &local_port) < 0) {
memset(&local_ip, 0, sizeof(local_ip));
@@ -120,6 +121,7 @@ static void login_accept_ssl(void *conte
i_error("accept() failed: %m");
return;
}
+ i_set_failure_ip(&remote_ip);
if (net_getsockname(fd, &local_ip, &local_port) < 0) {
memset(&local_ip, 0, sizeof(local_ip));
diff -r c612f0fa6bfb -r 2146e1963b79 src/master/auth-process.c
--- a/src/master/auth-process.c Wed Jan 14 14:06:46 2009 -0500
+++ b/src/master/auth-process.c Wed Jan 14 15:14:11 2009 -0500
@@ -60,9 +60,9 @@ bool have_initialized_auth_processes = F
bool have_initialized_auth_processes = FALSE;
static struct child_process auth_child_process =
- { PROCESS_TYPE_AUTH, 0 };
+ { MEMBER(type) PROCESS_TYPE_AUTH };
static struct child_process auth_worker_child_process =
- { PROCESS_TYPE_AUTH_WORKER, 0 };
+ { MEMBER(type) PROCESS_TYPE_AUTH_WORKER };
static struct timeout *to;
static unsigned int auth_tag;
diff -r c612f0fa6bfb -r 2146e1963b79 src/master/child-process.c
--- a/src/master/child-process.c Wed Jan 14 14:06:46 2009 -0500
+++ b/src/master/child-process.c Wed Jan 14 15:14:11 2009 -0500
@@ -3,6 +3,7 @@
#include "common.h"
#include "lib-signals.h"
#include "hash.h"
+#include "str.h"
#include "env-util.h"
#include "syslog-util.h"
#include "child-process.h"
@@ -132,12 +133,15 @@ static void sigchld_handler(int signo AT
struct child_process *process;
const char *process_type_name, *msg;
enum process_type process_type;
+ string_t *str;
pid_t pid;
int status;
bool abnormal_exit;
+ str = t_str_new(128);
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
/* get the type and remove from hash */
+ str_truncate(str, 0);
process = child_process_lookup(pid);
if (process == NULL)
process_type = PROCESS_TYPE_UNKNOWN;
@@ -168,14 +172,27 @@ static void sigchld_handler(int signo AT
process_type);
msg = msg == NULL ? "" :
t_strconcat(" (", msg, ")", NULL);
- i_error("child %s (%s) returned error %d%s",
- dec2str(pid), process_type_name,
- status, msg);
+ str_printfa(str,
+ "child %s (%s) returned error %d%s",
+ dec2str(pid), process_type_name,
+ status, msg);
}
} else if (WIFSIGNALED(status)) {
- i_error("child %s (%s) killed with signal %d",
- dec2str(pid), process_type_name,
- WTERMSIG(status));
+ str_printfa(str, "child %s (%s) killed with signal %d",
+ dec2str(pid), process_type_name,
+ WTERMSIG(status));
+ }
+
+ if (str_len(str) > 0) {
+ if (process != NULL && process->ip.family != 0) {
+ if (!process->ip_changed)
+ str_append(str, " (ip=");
+ else
+ str_append(str, " (latest ip=");
+ str_printfa(str, "%s)",
+ net_ip2addr(&process->ip));
+ }
+ i_error("%s", str_c(str));
}
if (destroy_callbacks[process_type] != NULL) {
diff -r c612f0fa6bfb -r 2146e1963b79 src/master/child-process.h
--- a/src/master/child-process.h Wed Jan 14 14:06:46 2009 -0500
+++ b/src/master/child-process.h Wed Jan 14 15:14:11 2009 -0500
@@ -16,8 +16,10 @@ enum process_type {
struct child_process {
enum process_type type;
-
+ struct ip_addr ip;
+ unsigned int allow_change_ip:1;
unsigned int seen_fatal:1;
+ unsigned int ip_changed:1;
};
typedef void child_process_destroy_callback_t(struct child_process *process,
diff -r c612f0fa6bfb -r 2146e1963b79 src/master/log.c
--- a/src/master/log.c Wed Jan 14 14:06:46 2009 -0500
+++ b/src/master/log.c Wed Jan 14 15:14:11 2009 -0500
@@ -17,6 +17,7 @@ struct log_io {
struct io *io;
struct istream *stream;
pid_t pid;
+ struct ip_addr ip;
time_t log_stamp;
unsigned int log_counter;
@@ -129,6 +130,20 @@ static int log_it(struct log_io *log_io,
if (process != NULL)
process->seen_fatal = TRUE;
break;
+ case 'O':
+ /* logging option. ignore unknown ones. */
+ if (strncmp(line, "ip=", 3) == 0) {
+ process = child_process_lookup(log_io->pid);
+ if (process != NULL &&
+ (process->allow_change_ip ||
+ process->ip.family == 0)) {
+ if (process->ip.family != 0)
+ process->ip_changed = TRUE;
+ net_addr2ip(line + 3, &process->ip);
+ }
+ }
+ log_io->next_log_type = '\0';
+ return 1;
default:
log_type = LOG_TYPE_ERROR;
break;
diff -r c612f0fa6bfb -r 2146e1963b79 src/master/login-process.c
--- a/src/master/login-process.c Wed Jan 14 14:06:46 2009 -0500
+++ b/src/master/login-process.c Wed Jan 14 15:14:11 2009 -0500
@@ -450,8 +450,11 @@ login_process_new(struct login_group *gr
p->io = io_add(fd, IO_READ, login_process_input, p);
p->output = o_stream_create_fd(fd, sizeof(struct master_login_reply)*10,
FALSE);
- if (!inetd_child)
+ if (!inetd_child) {
+ if (!group->set->login_process_per_connection)
+ p->process.allow_change_ip = TRUE;
child_process_add(pid, &p->process);
+ }
p->state = LOGIN_STATE_LISTENING;
diff -r c612f0fa6bfb -r 2146e1963b79 src/master/ssl-init.c
--- a/src/master/ssl-init.c Wed Jan 14 14:06:46 2009 -0500
+++ b/src/master/ssl-init.c Wed Jan 14 15:14:11 2009 -0500
@@ -18,7 +18,7 @@
#include <sys/stat.h>
static struct child_process ssl_param_child_process =
- { PROCESS_TYPE_SSL_PARAM, 0 };
+ { MEMBER(type) PROCESS_TYPE_SSL_PARAM };
static struct timeout *to;
static char *generating_path = NULL;
More information about the dovecot-cvs
mailing list