So this issue seems to have been around for quite some time. I've read through quite a few "hacks" on how to possibly move over quota check up into the RCPT time during mail delivery since at the transport level it's obviously to late. None of these hacks are very elegant.
In a perfect world, accepting the message and then bouncing it back seems like the right thing to do.
But consider real world with tens of thousands of users and millions of incoming messages a day, its not reality. In the default config, Exim accepts the message but if the user is over quota, the message sits around in the local queue until it expires. When you have thousands of users over quota, the local mail spool gets jammed up with several thousand (in some cases tens of thousands) of undeliverable mail.
The obvious fix is to adjust the retry to immediately bounce back to the sender with an NDR. This creates another problem... The majority of senders are bogus, mostly spam or viruses. So it creates a ton of blow back and undeliverables that again, jam up the local spool.
Ultimately it would be nice to somehow deny/defer at RCPT time.
The logic is obviously in Exim somewhere to check a users quota, but it seems to only exist in the transport level. There are two possible solutions, but how?
1) Have a function in Exim which can be passed a homedir/maildir and quota to check. (Maildir++ for example). This could then be used in a router condition to fail the recipient verification. (possibly an expensive operation)
2) Have a way to trap the over quota in the transport level. This could then be used to possibly call something to signal routers in future SMTP transactions that this mailbox is currently full and to back off attempting mail delivery. ie: first message comes in, hits the transport, the mailbox is over quota, the trigger could run an external command, use readsocket to something like memcached to mark the mailbox as "currently over quota". Subsequent new emails coming in for X minutes will be denied in a router.
#2 above is not perfect as some mails will still get through and end up creating a NDR, but if you can reject at the router level for say an hour, it would certainly mitigate the problem. Especially if you have some mailboxes that receive 100's or 1000's of mails an hour.
We have several Exim servers behind a load balancer and use memcached to share data between the servers for things like excessive authentication attempts, limiting the # of messages authenticated users can send in a 24 hour period, etc.. all works via well in a multi server environment.
Our last sticking point is dealing with over quota NDR's... Option #2 above would be possible if we could somehow trap the over quota condition in the transport.
--
Robert Blayzor
INOC, LLC
rblayzor@???
http://www.inoc.net/~rblayzor/