Dear list,

I've been pulling my hair out today and kindly ask you for help. I'm on Debian Bullseye with Dovecot 2.3.13 and Postfix 3.5.6. Users are stored in SQL and I want to use quotas. Basically I followed https://doc.dovecot.org/configuration_manual/quota_plugin/#quota-service

With mail_debug enabled I see that the information from SQL is fetched correctly:

dovecot: quota-status(t...@bullseye.example.org)<45148><>: Debug: auth-master: userdb lookup(t...@bullseye.example.org): auth USER input: t...@bullseye.example.org quota_rule=*:bytes=1000 home=/var/vmail/bullseye.example.org/test uid=5000 gid=5000

So the quota rule "*:bytes=1000" is loaded as intended for testing.
Before handing the email over to Dovecot through LMTP Postfix should call the quota-service (policy daemon) to determine if the user is over quota:

smtpd_recipient_restrictions = \
  reject_unauth_destination \
  check_policy_service inet:localhost:12340

This is still by the book.

What I found:
- sending a test mail with Thunderbird properly returns a 5xx status
  (over quota)
- sending a test mail with SWAKS returns DUNNO
  (swaks is an SMTP test tool)

I have used tcpdump to look into the communication on port 12340 and the difference appears to be the "size=0" line that Postfix sends if I use SWAKS. Output from SWAKS:
 -> RCPT TO:<t...@bullseye.example.org>
<-  250 2.1.5 Ok

However if Thunderbird sends an email it uses something like

 -> RCPT TO:<t...@bullseye.example.org> SIZE=12345

If I understand the situation correctly then Postfix extracts the SIZE=… value and uses that to send it to the quota-status policy daemon.

The user however is definitely over quota:

$> doveadm quota get -u t...@bullseye.example.org
Quota name Type        Value Limit %
User quota STORAGE     1     1     100
User quota MESSAGE     1     -     0

So whatever the size of the incoming email is, it should be rejected.
As quota-status returns DUNNO, Postfix will send the email to Dovecot through LMTP. And LMTP in turn does another quota check and correctly rejects the email:

postfix/lmtp[45153]: 573419D6A3: to=<t...@bullseye.example.org>, relay=iredmail-test[private/dovecot-lmtp], delay=0.08, delays=0.05/0.01/0.01/0.01, dsn=5.2.2, status=bounced (host iredmail-test[private/dovecot-lmtp] said: 552 5.2.2 <t...@bullseye.example.org> Quota exceeded (mailbox for user is full) (in reply to end of DATA command))

Problem here is that a bounce is created and Postfix is sending backscatter. Had "quota-service" indicated that the mailbox is over quota then Postfix had instantly rejected the email without any bounce.

I can also reproduce this effect by talking to the quota-status daemon:

printf "recipient=t...@bullseye.example.org\nsize=0\n\n" | nc localhost 12340
action=DUNNO

printf "recipient=t...@bullseye.example.org\nsize=10000\n\n" | nc localhost 12340
action=554 5.2.2 Quota exceeded (mailbox for user is full)

Is this a feature? A bug? An evil coincidence?

Thanks for reading this far. I know that this matter seems a bit complicated. But it feels like Dovecot's behavior leads to backscatter and of course I'd like to avoid that.

Kindly… Christoph

Reply via email to