This unfortunately doesn't really work with login_chroot=yes, which is why it was never integrated. Index: configure.in =================================================================== RCS file: /var/lib/cvs/dovecot/configure.in,v retrieving revision 1.273 diff -u -r1.273 configure.in --- configure.in 9 Apr 2006 12:38:24 -0000 1.273 +++ configure.in 9 Apr 2006 17:09:10 -0000 @@ -64,6 +64,15 @@ notify=$withval, notify=) +AC_ARG_WITH(libwrap, +[ --with-libwrap Build with libwrap, ie. TCP-wrappers (default)], + if test x$withval = xno; then + want_libwrap=no + else + want_libwrap=yes + fi, + want_libwrap=yes) + AC_ARG_WITH(passwd, [ --with-passwd Build with /etc/passwd support (default)], if test x$withval = xno; then @@ -1265,6 +1274,20 @@ fi dnl ** +dnl ** TCP wrappers +dnl ** + +if test "$want_libwrap" = "yes"; then + AC_CHECK_LIB(wrap, request_init, [ + AC_CHECK_HEADER(tcpd.h, [ + AC_DEFINE(HAVE_LIBWRAP,, Define if you have libwrap) + LIBWRAP_LIBS=-lwrap + AC_SUBST(LIBWRAP_LIBS) + ]) + ]) +fi + +dnl ** dnl ** userdb and passdb checks dnl ** Index: dovecot-example.conf =================================================================== RCS file: /var/lib/cvs/dovecot/dovecot-example.conf,v retrieving revision 1.190 diff -u -r1.190 dovecot-example.conf --- dovecot-example.conf 9 Apr 2006 15:50:53 -0000 1.190 +++ dovecot-example.conf 9 Apr 2006 17:09:10 -0000 @@ -145,6 +145,11 @@ # Greeting message for clients. #login_greeting = Dovecot ready. +# Use TCP wrappers for incoming connection access checks. This requires that +# Dovecot was compiled with libwrap. Note that this setting requires +# login_process_per_connection=yes. +#login_tcp_wrappers = no + # Space-separated list of elements we want to log. The elements which have # a non-empty variable value are joined together to form a comma-separated # string. Index: src/imap-login/Makefile.am =================================================================== RCS file: /var/lib/cvs/dovecot/src/imap-login/Makefile.am,v retrieving revision 1.5 diff -u -r1.5 Makefile.am --- src/imap-login/Makefile.am 20 Oct 2004 23:05:54 -0000 1.5 +++ src/imap-login/Makefile.am 9 Apr 2006 17:09:10 -0000 @@ -13,7 +13,8 @@ ../lib-imap/libimap.a \ ../lib-auth/libauth.a \ ../lib/liblib.a \ - $(SSL_LIBS) + $(SSL_LIBS) \ + $(LIBWRAP_LIBS) imap_login_SOURCES = \ client.c \ Index: src/login-common/main.c =================================================================== RCS file: /var/lib/cvs/dovecot/src/login-common/main.c,v retrieving revision 1.31 diff -u -r1.31 main.c --- src/login-common/main.c 29 Jan 2006 12:14:49 -0000 1.31 +++ src/login-common/main.c 9 Apr 2006 17:09:10 -0000 @@ -18,8 +18,15 @@ #include #include +#ifdef HAVE_LIBWRAP +# include +# include +int allow_severity = LOG_INFO; +int deny_severity = LOG_WARNING; +#endif + bool disable_plaintext_auth, process_per_connection, greeting_capability; -bool verbose_proctitle, verbose_ssl, verbose_auth; +bool verbose_proctitle, verbose_ssl, verbose_auth, tcp_wrappers; const char *greeting, *log_format; const char *const *log_format_elements; unsigned int max_logging_users; @@ -79,6 +86,34 @@ io_loop_stop(ioloop); } +static void access_check(int fd, const struct ip_addr *ip) +{ +#ifdef HAVE_LIBWRAP + struct request_info req; + + if (!tcp_wrappers || !process_per_connection) { + /* TCP wrappers may block while doing DNS lookups, which is + bad if there are multiple connections within this + process.. */ + return; + } + + request_init(&req, + RQ_FILE, fd, + RQ_CLIENT_ADDR, net_ip2addr(ip), + RQ_DAEMON, process_name, + 0); + fromhost(&req); + + if (!hosts_access(&req)) { + i_error("Connection refused by tcp-wrappers: %s", + net_ip2addr(ip)); + refuse(&req); + i_unreached(); + } +#endif +} + static void login_accept(void *context __attr_unused__) { struct ip_addr ip, local_ip; @@ -90,6 +125,7 @@ i_fatal("accept() failed: %m"); return; } + access_check(fd, &ip); if (process_per_connection) main_close_listen(); @@ -113,6 +149,7 @@ i_fatal("accept() failed: %m"); return; } + access_check(fd, &ip); if (process_per_connection) main_close_listen(); @@ -182,6 +219,7 @@ verbose_proctitle = getenv("VERBOSE_PROCTITLE") != NULL; verbose_ssl = getenv("VERBOSE_SSL") != NULL; verbose_auth = getenv("VERBOSE_AUTH") != NULL; + tcp_wrappers = getenv("TCP_WRAPPERS") != NULL; value = getenv("MAX_LOGGING_USERS"); max_logging_users = value == NULL ? 0 : strtoul(value, NULL, 10); @@ -277,11 +315,12 @@ restrict_access_by_env() is called */ lib_init(); + process_name = strrchr(argv[0], '/'); + process_name = process_name == NULL ? argv[0] : process_name+1; + if (is_inetd) { /* running from inetd. create master process before dropping privileges. */ - process_name = strrchr(argv[0], '/'); - process_name = process_name == NULL ? argv[0] : process_name+1; group_name = t_strcut(process_name, '-'); for (i = 1; i < argc; i++) { Index: src/master/login-process.c =================================================================== RCS file: /var/lib/cvs/dovecot/src/master/login-process.c,v retrieving revision 1.72 diff -u -r1.72 login-process.c --- src/master/login-process.c 9 Apr 2006 14:36:03 -0000 1.72 +++ src/master/login-process.c 9 Apr 2006 17:09:10 -0000 @@ -455,6 +455,8 @@ env_put(t_strconcat("LOG_FORMAT=", set->login_log_format, NULL)); if (set->login_greeting_capability) env_put("GREETING_CAPABILITY=1"); + if (set->login_tcp_wrappers) + env_put("TCP_WRAPPERS=1"); } static pid_t create_login_process(struct login_group *group) Index: src/master/master-settings.c =================================================================== RCS file: /var/lib/cvs/dovecot/src/master/master-settings.c,v retrieving revision 1.120 diff -u -r1.120 master-settings.c --- src/master/master-settings.c 9 Apr 2006 15:50:53 -0000 1.120 +++ src/master/master-settings.c 9 Apr 2006 17:09:10 -0000 @@ -83,6 +83,7 @@ DEF(SET_BOOL, login_process_per_connection), DEF(SET_BOOL, login_chroot), DEF(SET_BOOL, login_greeting_capability), + DEF(SET_BOOL, login_tcp_wrappers), DEF(SET_INT, login_process_size), DEF(SET_INT, login_processes_count), @@ -286,6 +287,7 @@ MEMBER(login_process_per_connection) TRUE, MEMBER(login_chroot) TRUE, MEMBER(login_greeting_capability) FALSE, + MEMBER(login_tcp_wrappers) FALSE, MEMBER(login_process_size) 32, MEMBER(login_processes_count) 3, @@ -719,6 +721,19 @@ return FALSE; } + if (!set->login_process_per_connection && set->login_tcp_wrappers) { + i_error("login_process_per_connection=no can't be used with " + "login_tcp_wrappers=yes"); + return FALSE; + } +#ifndef HAVE_LIBWRAP + if (set->login_tcp_wrappers) { + i_error("login_tcp_wrappers can't be used because " + "Dovecot wasn't built with libwrap"); + return FALSE; + } +#endif + return TRUE; } Index: src/master/master-settings.h =================================================================== RCS file: /var/lib/cvs/dovecot/src/master/master-settings.h,v retrieving revision 1.79 diff -u -r1.79 master-settings.h --- src/master/master-settings.h 9 Apr 2006 15:50:53 -0000 1.79 +++ src/master/master-settings.h 9 Apr 2006 17:09:10 -0000 @@ -48,6 +48,7 @@ bool login_process_per_connection; bool login_chroot; bool login_greeting_capability; + bool login_tcp_wrappers; unsigned int login_process_size; unsigned int login_processes_count; Index: src/pop3-login/Makefile.am =================================================================== RCS file: /var/lib/cvs/dovecot/src/pop3-login/Makefile.am,v retrieving revision 1.5 diff -u -r1.5 Makefile.am --- src/pop3-login/Makefile.am 20 Oct 2004 23:06:11 -0000 1.5 +++ src/pop3-login/Makefile.am 9 Apr 2006 17:09:10 -0000 @@ -11,7 +11,8 @@ ../login-common/liblogin-common.a \ ../lib-auth/libauth.a \ ../lib/liblib.a \ - $(SSL_LIBS) + $(SSL_LIBS) \ + $(LIBWRAP_LIBS) pop3_login_SOURCES = \ client.c \