Software used:

After using qmail for almost a year, I decided to switch to exim for a few reasons:

Compiling exim

Easy. The included it with options to link against OpenSSL and OpenLDAP. Can't get much simpler than:

    $ cd /usr/ports/mail/exim
    $ make WITH_LDAP=yes WITH_PAM=yes WITH_TLS=yes \
           WITH_PERL=yes LDAP_LIB_TYPE=OPENLDAP2
    $ sudo make install
I did comment out the start line in the rc.d script for now till I get it running.

Compiling Cyrus

Again, easy. Just

    $ cd /usr/ports/security/cyrus-sasl; make; sudo make install
    $ cd /usr/ports/mail/cyrus; make; sudo make install
It prompted me for what sort of authentication I wanted to use, and of course I said "OpenLDAP".

Integrating Exim with Cyrus

Since exim's config is in /usr/local/etc/exim and qmail's configuration resides in /var/qmail, I coubsp;setting (not used in this configuration).


system_aliases:
  driver = aliasfile
  file = /usr/local/etc/exim/aliases
  search_type = lsearch
  file_transport = address_file
  pipe_transport = address_pipe
  user = root

## Directors section [this deals with local addresses]
## 
## First 2 directors rewrite list-owner or owner-list to list-admin
## This is only done if the list exists.
## List existence checks are done by seeing if the file
## MAILMAN_HOME/lists//config.db
## exists.  

list_owner_director:
   driver = smartuser
   domains = lists.everybody.org
   require_files = MAILMAN_HOME/lists/${lc:$local_part}/config.db
   suffix = "-owner"
   new_address = "${lc:$local_part}-admin@${domain}"

owner_list_director:
   driver = smartuser
   domains = lists.everybody.org
   require_files = MAILMAN_HOME/lists/${lc:$local_part}/config.db
   prefix = "owner-"
   new_address = "${lc:$local_part}-admin@${domain}"

##
## Next 3 directors direct admin, request and list mail to the appropriate
## transport.  List existence is checked as above.

list_admin_director:
   driver = smartuser
   domains = lists.everybody.org
   suffix = -admin
   require_files = MAILMAN_HOME/lists/${lc:$local_part}/config.db
   transport = list_admin_transport

list_request_director:
   driver = smartuser
   domains = lists.everybody.org
   suffix = -request
   require_files = MAILMAN_HOME/lists/${lc:$local_part}/config.db
   transport = list_request_transport

list_director:
   driver = smartuser
   domains = lists.everybody.org
   require_files = MAILMAN_HOME/lists/${lc:$local_part}/config.db
   transport = list_transport

## End of directors fragment


# Handle forward files
userforward:
  driver = forwardfile
  file = .forward
  no_verify
  no_expn
  check_ancestor
# filter
  file_transport = address_file
  pipe_transport = address_pipe
  reply_transport = address_reply


# Do the local delivery with procmail
procmail:
  driver = localuser
  transport = procmail_pipe

# Conventional local delivery
localuser:
  driver = localuser
  transport = local_delivery


end



######################################################################
#                      ROUTERS CONFIGURATION                         #
#            Specifies how remote addresses are handled              #
######################################################################
#                          ORDER DOES MATTER                         #
#  A remote address is passed to each in turn until it is accepted.  #
######################################################################

# Remote addresses are those with a domain that does not match any item
# in the "local_domains" setting above.


# This router routes to remote hosts over SMTP using a DNS lookup with
# default options.
lookuphost:
  driver = lookuphost
  transport = remote_smtp


# This router routes to remote hosts over SMTP by explicit IP address,
# given as a "domain literal" in the form [nnn.nnn.nnn.nnn]. The RFCs
# require this facility, which is why it is enabled by default in Exim.
# If you want to lock it out, set forbid_domain_literals in the main
# configuration section above.
literal:
  driver = ipliteral
  transport = remote_smtp


end



######################################################################
#                      RETRY CONFIGURATION                           #
######################################################################

# This single retry rule applies to all domains and all errors. It specifies
# retries every 15 minutes for 2 hours, then increasing retry intervals,
# starting at 1 hour and increasing each time by a factor of 1.5, up to 16
# hours, then retries every 8 hours until 4 days have passed since the first
# failed delivery.

# Domain               Error       Retries
# ------               -----       -------

*                      *           F,2h,15m; G,16h,1h,1.5; F,4d,8h

end



######################################################################
#                      REWRITE CONFIGURATION                         #
######################################################################

# There are no rewriting specifications in this default configuration file.

# End of Exim configuration file

Getting PAMized LDAP authentication working

Converting dot-qmail files to LDAP entries

Using LDAP to look up deliveries

Setting up SSL

Most of this comes from example configuration C027 in the configuration samples. Especially the following:

$ cd /usr/local/openssl/certs Directory already existed in this case
$ sudo sh -c 'openssl genrsa 1024 > exim.rsa' RSA key
$ sudo sh -c 'openssl gendh -rand /dev/urandom > exim.dh' Diffie-Hellman parameters
Using configuration from /etc/ssl/openssl.cnf
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [US]:
State or Province Name (full name) [Louisiana]:
Locality Name (eg, city) [New Orleans]:
Organization Name (eg, company) [Everybody Networks]:
Organizational Unit Name (eg, section) [webserver]:
Common Name (eg, YOUR name) [everybody.org]:
Email Address [mah@everybody.org]:
Q & A
sudo sh -c 'cat everybody-org.rsa everybody-org.x509 everybody-org.dh > everybody-org.pem'

The signed cert is necessary for Outlook which won't take an unsigned cert.

Added the following line to /etc/inetd.conf:

# Following is for cyrus imap over ssl
imaps  stream  tcp  nowait  cyrus  /usr/local/sbin/stunnel exim -l /usr/local/cyrus/bin/imapd -p /usr/local/openssl/certs/everybody-org.pem -- imapd
# SMTP Authentication only over SSL
smtps  stream  tcp  nowait  mail   /usr/local/sbin/stunnel exim -l /usr/local/sbin/exim -p /usr/local/openssl/certs/everybody-org.pem -- exim -bs

Alternatively, I could have put this in the rc script:

  /usr/local/bin/stunnel -d 465 -l /usr/local/sbin/exim \
          -p /usr/local/openssl/certs/everybody-org.pem \
          -- exim -bs
and
  /usr/local/bin/stunnel -d 993 -l /usr/local/cyrus/bin/imapd \
          -p /usr/local/openssl/certs/everybody-org.pem \
          -- imapd

Authentication

I found these entries for the configuration file in C034:



br />   require_files = MAILMAN_HOME/lists/${lc:$local_part}/config.db
   prefix = "owner-"
   new_address = "${lc:$local_part}-admin@${domain}"

##
## Next 3 directors direct admin, request and list mail to the appropriate
## transport.  List existence is checked as above.

list_admin_director:
   driver = smartuser
   domains = lists.everybody.org
   suffix = -admin
   require_files = MAILMAN_HOME/lists/${lc:$local_part}/config.db
   transport = list_admin_transport

list_request_director:
   driver = smartuser
   domains = lists.everybody.org
   suffix = -request
   require_files = MAILMAN_HOME/lists/${lc:$local_part}/config.db
   transport = list_request_transport

list_director:
   driver = smartuser
   domains = lists.everybody.org
   require_files = MAILMAN_HOME/lists/${lc:$local_part}/config.db
   transport = list_transport

## End of directors fragment


# Handle forward files
userforward:
  driver = forwardfile
  file = .forward
  no_verify
  no_expn
  check_ancestor
# filter
  file_transport = address_file
  pipe_transport = address_pipe
  reply_transport = address_reply


# Do the local delivery with procmail
procmail:
  driver = localuser
  transport = procmail_pipe

# Conventional local delivery
localuser:
  driver = localuser
  transport = local_delivery


end



######################################################################
#                      ROUTERS CONFIGURATION                         #
#            Specifies how remote addresses are handled              #
######################################################################
#                          ORDER DOES MATTER                         #
#  A remote address is passed to each in turn until it is accepted.  #
######################################################################

# Remote addresses are those with a domain that does not match any item
# in the "local_domains" setting above.


# This router routes to remote hosts over SMTP using a DNS lookup with
# default options.
lookuphost:
  driver = lookuphost
  transport = remote_smtp


# This router routes to remote hosts over SMTP by explicit IP address,
# given as a "domain literal" in the form [nnn.nnn.nnn.nnn]. The RFCs
# require this facility, which is why it is enabled by default in Exim.
# If you want to lock it out, set forbid_domain_literals in the main
# configuration section above.
literal:
  driver = ipliteral
  transport = remote_smtp


end



######################################################################
#                      RETRY CONFIGURATION                           #
######################################################################

# This single retry rule applies to all domains and all errors. It specifies
# retries every 15 minutes for 2 hours, then increasing retry intervals,
# starting at 1 hour and increasing each time by a factor of 1.5, up to 16
# hours, then retries every 8 hours until 4 days have passed since the first
# failed delivery.

# Domain               Error       Retries
# ------               -----       -------

*                      *           F,2h,15m; G,16h,1h,1.5; F,4d,8h

end



######################################################################
#                      REWRITE CONFIGURATION                         #
######################################################################

# There are no rewriting specifications in this default configuration file.

# End of Exim configuration file

Getting PAMized LDAP authentication working

Converting dot-qmail files to LDAP entries

Using LDAP to look up deliveries

Setting up SSL

Most of this comes from example configuration C027 in the configuration samples. Especially the following:

$ cd /usr/local/openssl/certs Directory already existed in this case
$ sudo sh -c 'openssl genrsa 1024 > exim.rsa' RSA key
$ sudo sh -c 'openssl gendh -rand /dev/urandom > exim.dh' Diffie-Hellman parameters
Using configuration from /etc/ssl/openssl.cnf
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [US]:
State or Province Name (full name) [Louisiana]:
Locality Name (eg, city) [New Orleans]:
Organization Name (eg, company) [Everybody Networks]:
Organizational Unit Name (eg, section) [webserver]:
Common Name (eg, YOUR name) [everybody.org]:
Email Address [mah@everybody.org]:
Q & A
sudo sh -c 'cat everybody-org.rsa everybody-org.x509 everybody-org.dh > everybody-org.pem'

The signed cert is necessary for Outlook which won't take an unsigned cert.

Added the following line to /etc/inetd.conf:

# Following is for cyrus imap over ssl
imaps  stream  tcp  nowait  cyrus  /usr/local/sbin/stunnel exim -l /usr/local/cyrus/bin/imapd -p /usr/local/openssl/certs/everybody-org.pem -- imapd
# SMTP Authentication only over SSL
smtps  stream  tcp  nowait  mail   /usr/local/sbin/stunnel exim -l /usr/local/sbin/exim -p /usr/local/openssl/certs/everybody-org.pem -- exim -bs

Alternatively, I could have put this in the rc script:

  /usr/local/bin/stunnel -d 465 -l /usr/local/sbin/exim \
          -p /usr/local/openssl/certs/everybody-org.pem \
          -- exim -bs
and
  /usr/local/bin/stunnel -d 993 -l /usr/local/cyrus/bin/imapd \
          -p /usr/local/openssl/certs/everybody-org.pem \
          -- imapd

Authentication

I found these entries for the configuration file in C034: