Mercurial > dovecot > original-hg > dovecot-1.2
changeset 8628:e85c7cb22ad7 HEAD
If login process crashes, log the IP address that (maybe) caused it.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Wed, 14 Jan 2009 15:14:11 -0500 |
parents | b920d841f8fe |
children | 1efdf705203c |
files | src/lib/failures.c src/lib/failures.h src/login-common/main.c src/master/auth-process.c src/master/child-process.c src/master/child-process.h src/master/log.c src/master/login-process.c src/master/ssl-init.c |
diffstat | 9 files changed, 67 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- 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" @@ -456,6 +457,16 @@ 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;
--- 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,6 +1,8 @@ #ifndef FAILURES_H #define FAILURES_H +struct ip_addr; + /* Default exit status codes that we could use. */ enum fatal_exit_status { FATAL_LOGOPEN = 80, /* Can't open log file */ @@ -78,9 +80,12 @@ /* Set the failure prefix. */ 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));
--- 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 @@ -90,6 +90,7 @@ 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)); @@ -121,6 +122,7 @@ 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));
--- 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 = 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;
--- 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 @@ 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 @@ 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) {
--- 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 @@ 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,
--- 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 io *io; struct istream *stream; pid_t pid; + struct ip_addr ip; time_t log_stamp; unsigned int log_counter; @@ -129,6 +130,20 @@ 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;
--- 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 @@ -472,8 +472,11 @@ 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;
--- 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;