[CentOS] Kind of OT: internal imap server

Aleksandar Milivojevic alex at milivojevic.org
Mon Aug 28 04:22:51 UTC 2006


Feizhou wrote:

> right, sorry, i have not actually used milter myself so I was not aware 
> that it was not limited to content filtering. In any case, this shows 
> one shortcoming of sendmail. sendmail processes each the helo, sender, 
> recipient and client ip/rdns in separate rulesets and you cannot create 
> (at least I have not managed it yet) any rulesets that can make 
> decisions based on two or more of these and so you need to run a perl 
> program via milter to deal with these or perhaps in your case, you need 
> it to lookup a mysql table for the recipient. You call this efficient?

I don't have anything in particular against Postfix and Sendmail.  I'm 
not advocating using Postfix over Sendmail here.  I'm not advocating 
using Sendmail over Postfix either.  Frankly, couldn't care less what 
MTA you are using or advocating.  Just feeling a bit educational.

I'm using a custom ruleset in Local_check_rcpt that checks the sender 
part for some heavily locked down accounts.  Among other things, it 
checks if local recipient is allowed to receive mail from particular 
sender (for inbound mail), and if the local sender is allowed to send to 
particular recipient (for outbound mail).  Obviously, that ruleset is 
making decions based on both sender and recipient.  If you'll need it in 
the future, sender's address is stored in $f macro, as nicely documented 
in Sendmail documentation (Sendmail Installation and Operation Guide). 
There's also bunch of other macros you can use throughout your rulesets. 
  So you see, it is possible, well documented, and simple.

If you are using Milter interface to implement something like above in 
an external filter (say it is C program), you'd simply use Milter API to 
store information between callback function calls.  You do not need to 
store data anywhere externally (like in database, or in files, or 
whatever).  In the above (simple) example, in callback function for mail 
command you'd allocate some memory for a structure to hold your data 
(for example, sender's adress and whatever else you want to keep track 
of), and use smfi_setpriv() to let Milter API know you want to keep 
track of that data for this particular connection.  In callback function 
for rcpt command, you'd use smfi_getpriv(), which would return you a 
pointer to your data (sender's address and whatever else you are keeping 
track of between callback function calls).  Note that smfi_setpriv() and 
smfi_getpriv() do not move or copy or store the data anywhere.  The data 
stays where it was, in the memory.  Those two functions accept and 
return the pointer to the location in memory (that your program 
allocated).  You'd also register a callback to a cleanup function, which 
would be called at the end of transaction or connection (depending what 
callback you register) to free up the allocated memory (and/or any other 
resources you allocated/used).

It is done this way since filters in Sendmail are multithreaded.  There 
is only one instance of filter running.  It's kind of more complicated 
to code multithreaded program, but on the other hand it is more 
efficient than having single filter process running for each current 
transaction (on busy email server you can have dozens or even hundreds 
of transactions running in parallel).  It is very efficient, and very 
well designed filtering API for email transactions, and it would be 
really great to see this API implemented in Postfix too.  I just hope it 
will be exactly the same API as in Sendmail so that all existing 
Sendmail filters can be used in Postfix, and that all future Postfix 
filters could be used in Sendmail.

If you are using MIMEDefang, you don't even need to bother with all 
that.  MIMEDefang is doing all that behind the scenes for you.  Your 
filter_recipient function will get the sender's address in second 
argument (as well as bunch of other info from previous stages in the 
remaining arguments).

> I will concede that sendmail does a good job for what it is designed to 
> do (read no virtual mailboxes and only supporting system account mbox 
> format mailboxes).

Reading the above, one would conclude that you can't have Sendmail and 
Cyrus on the same box.  Cyrus does not store mail in mbox format.  Cyrus 
does not use system user accounts (all users are virtual, as far as 
Cyrus is concerned).  But somehow, Sendmail just works with Cyrus.

Thing is.  Sendmail doesn't know about mailboxes.  Period.  Sendmail 
will never attempt to write a mail into a mailbox.  That's the job of 
local delivery agent (mailer).  You tell sendmail (M lines in 
sendmail.cf file) how to talk with the mailer.  Mailer will than write 
the email into the mailbox.  Sendmail doesn't care if there is 
corresponding system account for that mailbox, or what format the 
mailbox is.

The only way to get Sendmail to write email directly into the file on 
the disk (note that I wrote "file on the disk", not "mailbox") is using 
aliases file or dot forward file in user's home directory (if there are 
system accounts on the mail server).  But this is not considered to be 
delivery into mailbox.  It's just "append this to that file" quick and 
dirty feature, and yes, you are doomed to mbox format if you are lazy 
enough to actually use it.

Of course, if there are system accounts, there's a feature or two extra 
that Sendmail will offer (like dot forward file).  But you do not need 
to have system accounts on the mail server for Sendmail to work.




More information about the CentOS mailing list