Hi Gary, DRAC is cool! It handles the network and entry timeout issues for me, and I wanted it to go just a little futher, so... Here is a tiny hack I cobbled together so that I could use DRAC with Courier-IMAP without modifying any Courier source code. Instead, you just add it after authdaemond in AUTHMODULES in the courier pop3/imap config files. For my basic config, I have Postfix and Courier-IMAP running on multiple boxes behind an OpenBSD load-balancing firewall. When a user checks mail with IMAP/POP3, there's no guarantee that they are going to hit the same server again with SMTP. All servers run SMTP and IMAP/POP3. All servers must be able to allow users who authenticated with IMAP/POP3 on any other server to send SMTP mail. So here's what I did: Each SMTP server runs DRAC. Simple enough...Postfix points to dracd.db with smtpd_recipient_restrictions = ... check_client_access btree:/etc/mail/dracd, ... Each POP3/IMAP server calls this little program after authentication. This program grabs the client's IP address from environment variables. Then, it connects to each DRAC host and enters it. Simple enough.... /* * This little utility is based off of code found in a DRAC popper patch * and a few lines of Bruce Guenter's relay-ctrl-allow utility. * * http://mail.cc.umanitoba.ca/drac/pop.html * http://untroubled.org/relay-ctrl/ * * To configure: * * See main() for the list of DRAC servers to register with. Change * accordingly. * * To compile: cc -o drac-add drac-add.c -L/path/to/drac -ldrac * * To use: * * Figure out where your Courier configuration and authlib directories are at. * My sample values are for Courier as installed from the OpenBSD ports tree. * * Copy drac-add to /usr/local/libexec/authlib/ * Edit /etc/courier-imap/pop3d and add drac-add to the end of AUTHMODULES * Edit /etc/courier-imap/imapd and add drac-add to the end of AUTHMODULES * Restart imapd and pop3d * * Chris Cappuccio - chris@nmedia.net */ #include #include #include #include #include #include #include #include void drac_update_host(char *drachost) { char *err; struct in6_addr ip6; struct in_addr ip4; #ifdef DEBUG syslog(LOG_INFO,"drac_update() called: drachost=%s user=%s",drachost,getenv("TCPREMOTEIP")); #endif if (inet_pton(AF_INET, getenv("TCPREMOTEIP"), &ip4) == 1) { if (dracauth(drachost, ip4.s_addr, &err) != 0) syslog(LOG_ALERT,"dracauth() Error \"%s\" for" " user %s",err,getenv("TCPREMOTEIP")); } else if (inet_pton(AF_INET6, getenv("TCPREMOTEIP"), &ip6) == 1) { if (IN6_IS_ADDR_V4MAPPED(&ip6)) { #ifdef __OpenBSD__ ip4.s_addr=ip6.__u6_addr.__u6_addr32[3]; #else ip4.s_addr=ip6.s6_addr32[3]; #endif if (dracauth(drachost, ip4.s_addr, &err) != 0) syslog(LOG_ALERT,"dracauth() Error \"%s\" for" " user %s",err,getenv("TCPREMOTEIP")); } else { syslog(LOG_NOTICE,"drac_update() doesn't support IPv6" " yet."); } } else { syslog(LOG_ALERT, "drac_update inet_pton failure! drachost=%s" " user=%s errno=%i",drachost,getenv("TCPREMOTEIP"),errno); } return; } int main(int argc, char* argv[]) { if (getenv("TCPREMOTEIP") == NULL) err(111, "No TCPREMOTEIP found"); if (getenv("AUTHUSER") && getenv("AUTHARGV0") && getenv("AUTHENTICATED")) { /* if success then courier is happy, so we update our DRAC hosts */ drac_update_host("172.16.100.10"); /* CHANGE DRAC SERVER(S) HERE */ drac_update_host("172.16.100.11"); } else syslog(LOG_NOTICE, "drac-add called without AUTHUSER" "/AUTHARGV0/AUTHENTICATED!"); /* Courier-IMAP Magic from relay-ctrl-allow */ if (argc > 1) { execvp(argv[1], argv+1); return 111; } return 0; }