From afb3eaaf294ae786644e05e7943b9a71f9bc6c3a Mon Sep 17 00:00:00 2001 From: Philip Hazel Date: Wed, 19 Apr 2006 10:58:21 +0000 Subject: [PATCH] Kludge for tcp-wrappers problem during system catastrophes. --- doc/doc-txt/ChangeLog | 12 +++++++++++- src/src/smtp_in.c | 35 ++++++++++++++++++++++++++++------- 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index d69e9eafb..56d0822fd 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -1,4 +1,4 @@ -$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.340 2006/04/18 11:13:19 ph10 Exp $ +$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.341 2006/04/19 10:58:21 ph10 Exp $ Change log file for Exim from version 4.21 ------------------------------------------- @@ -12,6 +12,16 @@ TF/01 Fix the add_header change below (4.61 PH/55) which had a bug that (amongst PH/01 ${readsocket now supports Internet domain sockets (modified John Jetmore patch). +PH/02 When tcp-wrappers is called from Exim, it returns only "deny" or "allow". + "Deny" causes Exim to reject the incoming connection with a 554 error. + Unfortunately, if there is a major crisis, such as a disk failure, + tcp-wrappers gives "deny", whereas what one would like would be some + kind of temporary error. A kludge has been added to help with this. + Before calling hosts_ctl(), errno is set zero. If the result is "deny", a + 554 error is used if errno is still zero or contains ENOENT (which occurs + if either of the /etc/hosts.{allow,deny} files is missing). Otherwise, a + 451 error is used. + Exim version 4.61 ----------------- diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c index e83235836..99ac3fb1a 100644 --- a/src/src/smtp_in.c +++ b/src/src/smtp_in.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/smtp_in.c,v 1.37 2006/03/16 11:14:46 ph10 Exp $ */ +/* $Cambridge: exim/src/src/smtp_in.c,v 1.38 2006/04/19 10:58:21 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -1459,19 +1459,40 @@ if (!sender_host_unknown) return FALSE; } - /* Test with TCP Wrappers if so configured */ + /* Test with TCP Wrappers if so configured. There is a problem in that + hosts_ctl() returns 0 (deny) under a number of system failure circumstances, + such as disks dying. In these cases, it is desirable to reject with a 4xx + error instead of a 5xx error. There isn't a "right" way to detect such + problems. The following kludge is used: errno is zeroed before calling + hosts_ctl(). If the result is "reject", a 5xx error is given only if the + value of errno is 0 or ENOENT (which happens if /etc/hosts.{allow,deny} does + not exist). */ #ifdef USE_TCP_WRAPPERS + errno = 0; if (!hosts_ctl("exim", (sender_host_name == NULL)? STRING_UNKNOWN : CS sender_host_name, (sender_host_address == NULL)? STRING_UNKNOWN : CS sender_host_address, (sender_ident == NULL)? STRING_UNKNOWN : CS sender_ident)) { - HDEBUG(D_receive) debug_printf("tcp wrappers rejection\n"); - log_write(L_connection_reject, - LOG_MAIN|LOG_REJECT, "refused connection from %s " - "(tcp wrappers)", host_and_ident(FALSE)); - smtp_printf("554 SMTP service not available\r\n"); + if (errno == 0 || errno == ENOENT) + { + HDEBUG(D_receive) debug_printf("tcp wrappers rejection\n"); + log_write(L_connection_reject, + LOG_MAIN|LOG_REJECT, "refused connection from %s " + "(tcp wrappers)", host_and_ident(FALSE)); + smtp_printf("554 SMTP service not available\r\n"); + } + else + { + int save_errno = errno; + HDEBUG(D_receive) debug_printf("tcp wrappers rejected with unexpected " + "errno value %d\n", save_errno); + log_write(L_connection_reject, + LOG_MAIN|LOG_REJECT, "temporarily refused connection from %s " + "(tcp wrappers errno=%d)", host_and_ident(FALSE), save_errno); + smtp_printf("451 Temporary local problem - please try later\r\n"); + } return FALSE; } #endif -- 2.25.1