[CentOS] Adding/Removing Headers with Sendmail

Aleksandar Milivojevic amilivojevic at pbl.ca
Mon May 16 15:36:42 UTC 2005


Lee W wrote:
> An email comes into joe.bloggs.sa... at example.com this then gets split so
> that it is delivered to joe.blo... at example.com and also s... at example.com.

You can attempt playing with plussed addresses, so that you use 
joe.bloggs+campain at example.com.  Look for description of virtusertable 
feature in /usr/share/docs/sendmail/README.cf (part of sendmail-doc 
package, if you don't have it, install it).  Combine it with aliases, 
and you can acomplish what you need to do.

Another posibility, if you want to automate everything, so that you 
don't need to configure new setup for each and every campain, would be 
to write Milter based filter for sendmail.  Than you can do all kinds of 
fancy stuff.

You can find some basic documentation about Milter in 
/usr/share/docs/sendmail/README.libmilter (with source code of example 
filter).  If you want to write programs using the library, you'll need 
full API documentation.  Unfortunately it is not included with 
sendmail-doc package.  Download Sendmail source from www.sendmail.org, 
and you'll find documentation in HTML format there.

This is how you would implement it using the filter:

Register callbacks for RCPT command and EOM (end of message).  You need 
callback for RCPT so that your filter is called each time sendmail 
detects RCPT command (new recipient specification).  You need EOM 
callback, since only in EOM callback function list of recipients can be 
altered.

Now, if in RCPT callback you detect email address of format 
first.last.campain at example.com (or first.last+campain at example.com, I 
would prefer this format), add it to the list stored in private data 
structure (the one you registered with smfi_setpriv() function).  Make 
sure you are creating per-messeage private data structures inside global 
per-connection structure (there may be more than one email delivered in 
single connection).

Then in EOM callback, change the list of recipients so that you add 
first.last at example.com and campain at example.com, and then if operation 
was successfull remove first.last.campain at example.com from the list of 
recipients.  Dealocate per-message private data structure and free 
allocate memory.  You should be carefull in this step.  You don't want 
to add non-existing addresses, or do this for non-existing campains, and 
so on...

You should also have abort callback, that would do cleanup in case 
message is aborted somewhere in the middle, before EOM callback was 
called (dealocate private data structure and free memory).  And of 
course a callback for close to clean up global per-connection pointers 
(smfi_setpriv(ctx, NULL) followed by free() to dealocate memory back to 
the system).

Don't forget that Milter based filters are multithreaded applications, 
and care should be taken when writing them.

If you don't feel comfortable programming something like this, hire an 
experienced programmer.  For somebody with experience with Milter API, 
it should take about hour or two to write simple filter like this and 
have it fully debugged (provided you give correct specifications of job 
to the programmer).  No, I'm not going to do it for a fee, I already 
have too many other (more fun) things to do ;-)

Of course, you don't need to use C to write a filter.  There are good 
Perl modules that allow you to write filters in Perl too.

-- 
Aleksandar Milivojevic <amilivojevic at pbl.ca>    Pollard Banknote Limited
Systems Administrator                           1499 Buffalo Place
Tel: (204) 474-2323 ext 276                     Winnipeg, MB  R3T 1L7



More information about the CentOS mailing list