There have been many questions about using procmail for Virtual Domain's.
I was one of the people that asked, and was always told that "procmail
is not the answer, it is a sendmail thing".
I did have to use some new sendmail features, but as it is asked often
enough I figured I'd post my solution (and I promised several people I
would). I'm not an expert (although I'm learning fast), so if there are
any sendmail guru's reading this, I don't mind critisism :)
I wanted procmail to do it rather then sendmail for a couple reasons:
1) I want the user to be able to directly edit thier Virtual Domain
email config file. Using procmail, they have "real time" access
to thier .procmailrc file. All setup is done in the owners home
directory.
2) I want the user to be able to set up thier own utilities. Such as
auto-responders, users, lists, whatever. I have over 300 domains
and REALLY don't want to administer them all. BTW I've had NO
complaints since I set this up.
This is a long post, so hear goes:
SENDMAIL:
1) I'm using sendmail 8.8.x, but I'm sure 8.7.x will work. Also, I use
the m4 macro files to generate my sendmail.cf, so that is how
I'm going to explain these.
2) Unless someone knows how to change it in the .mc file, I modified
the cf/mailer/procmail.m4 file. You have to remove the 'm' in the
PROCMAIL_MAILER_FLAGS. For example it should just say:
`define(`PROCMAIL_MAILER_FLAGS', `Shu')')
The reason this is done, is so you will receive one email for
each recipient the email is addressed to. I havn't found a way
to get sendmail to pass multiple recipients to procmail.
3) In your host.mc file (or whatever you call it), enable "local_procmail"
"procmail mailer", and "mailertables". For example:
-----------------------------start---------------------------------
VERSIONID(`@(#)generic-hpux9.mc 8.2 (Berkeley) 8/6/95')
OSTYPE(hpux10)dnl
FEATURE(local_procmail)dnl
FEATURE(mailertable, btree /etc/mail/lib/mailertable.db)dnl
MAILER(procmail)dnl
MAILER(local)dnl
MAILER(smtp)dnl
------------------------------end----------------------------------
To compile use: m4 ../m4/cf.m4 host.mc > host.cf
This will create a sendmail.cf file that has all the stuff you need.
4) In the file /etc/mail/lib/mailertable add one line for each of
your virtual domains. For example:
-----------------------------start---------------------------------
domain1.com procmail:/etc/mail/Ehosts/rc.domain1.com
domain2.com procmail:/etc/mail/Ehosts/rc.domain2.com
domain3.com procmail:/etc/mail/Ehosts/rc.domain3.com
domain4.com procmail:/etc/mail/Ehosts/rc.domain4.com
domain5.com procmail:/etc/mail/Ehosts/rc.domain5.com
------------------------------end----------------------------------
To compile use: makemap btree mailertable < mailertable
That is a <tab> before "procmail..." not spaces. Now is where you
have control of your domain with procmail.
PROCMAIL:
1) For each domain, create an "rc" file for them defining specific info
about that domain. For example:
-----------------------------start---------------------------------
OWNER=someuser(_at_)RealDomain(_dot_)net
DOMAIN=domain1.com
LIBDIR=/etc/mail/rc.d
INCLUDERC=$LIBDIR/rc.ehosts
------------------------------end----------------------------------
Then in the "rc.ehosts" file use something like:
-----------------------------start---------------------------------
ADMIN=postmaster(_at_)RealDomain(_dot_)net # Your E-mail admin
MAILDIR=/etc/mail
LIBDIR=${MAILDIR}/rc.d
SHELL=/bin/sh # Avoid surprises
PATH=/bin:/usr/bin:/usr/local/bin:${MAILDIR}/bin
COMSAT=no # Don't notify Comsat
ENVELOPE_FROM=$1 # Envelope sender
ENVELOPE_TO=$2 # Envelope recipient
### This creates a header "X-Envelope-To" containing the original
### recipient of the message. This works even if the recipient
### is a Bcc'd address!!! And since we took the 'm' out of
### the procmail flags in the sendmail.cf, it also works for
### multiple recipients.
:0 fhw
| formail -I"X-Envelope-To: $ENVELOPE_TO"
### I filter all mail sent to "abuse" so I can catch spammers
:0
* $ ENVELOPE_TO ?? abuse@"$DOMAIN"
! -f $ENVELOPE_FROM $ADMIN
### I filter all mail sent to "postmaster" in case there is a
### problem that only I can fix.
:0
* $ ENVELOPE_TO ?? postmaster@"$DOMAIN"
! -f $ENVELOPE_FROM $ADMIN
### Send all messages to the appropriate owner.
:0
! -f $ENVELOPE_FROM $OWNER
------------------------------end----------------------------------
All control is now passwd to the users .procmailrc file, AND with the
"X-Envelope-To" header, they can route the email properly without
losing Bcc'd mail and multiple recipients.
2) Setup the users .procmailrc file. Here is my default:
~/.procmailrc
-----------------------------start---------------------------------
PATH=/bin:/usr/bin:/usr/local/bin:$HOME/bin
MAILDIR=$HOME/mail # You'd better make sure it exists
COMSAT=no # Don't notify for incoming mail.
LIBDIR=/etc/mail/rc.d # Location of shared procmail scripts
### Initialize the Virtual Email Domain services.
INCLUDERC=$LIBDIR/rc.init # Leave this line alone.
DOMAIN=___ENTER_YOUR_DOMAIN___
:0
* $ ENVELOPE_DOMAIN ?? $DOMAIN
{
ADDR=__email__ FRWD=__forward__ INCLUDERC=$LIBDIR/rc.deliver
ADDR=__email__ FRWD=__forward__ INCLUDERC=$LIBDIR/rc.deliver
ADDR=__email__ FILE=__file__ INCLUDERC=$LIBDIR/rc.deliver
INCLUDERC=$LIBDIR/rc.term_dom # Leave this line alone.
}
------------------------------end----------------------------------
This will even handle multiple domains, if a single user has more
then one. Simply create one recipe block for each domain.
$LIBDIR/rc.init
-----------------------------start---------------------------------
### Get the Envelope recipient of the message. The header
### X-Envelope-To must be present to be able to process any
### virtual domain mail.
ENVELOPE_TO=`formail -zxX-Envelope-To:`
### Grab the domain we are working with.
:0
* $ ENVELOPE_TO ?? @\/.*
{ ENVELOPE_DOMAIN=$MATCH }
### Strip the X-Envelope-To header off, to avoid sending any BCC info.
:0 fhw
* ! DEBUG ?? . # Leave the header there if DEBUGing
| formail -I"X-Envelope-To:"
------------------------------end----------------------------------
$LIBDIR/rc.deliver
-----------------------------start---------------------------------
### If the message is addressed to the user defined in ADDR at domain
### DOMAIN, then either forward (FRWD) or file (FILE) the message to
### the appropriate destination.
:0
* $ ENVELOPE_TO ?? ^${ADDR}(_at_)${DOMAIN}
{
:0 c
* FRWD ?? .
! ${FRWD}
:0 a
{ FLAG=delivered }
:0 wc:
* FILE ?? .
$FILE
:0 a
{ FLAG=delivered }
}
### Clear these so they don't affect the next query
FRWD
FILE
------------------------------end----------------------------------
$LIBDIR/rc.term_dom
-----------------------------start---------------------------------
OLDSHELL=${SHELL} # Just in case
SHELL=/bin/sh
### if the mail was delivered to someone, stop now. If there
### is another recipient, sendmail will send a new email (because
### we took out the 'm' procmail flag).
### If no matches were found, the mail will just "drop thru" to
### the owners mailbox.
:0
* FLAG ?? delivered
{ HOST=_stop_now_ }
SHELL=${OLDSHELL}
------------------------------end----------------------------------
There are other things I include in there, such as some default
auto-responders, vacation messages, different notifications for
unknown users, etc. However, I can't give away ALL my secrets :)
I also stripped out a lot of my comments, to save space in this
email.
If you reply to this, please CC me, as I don't always get a chance to
read all the procmail list messages.
Dan T.