quota-status fails when size=0 from Postfix
Christoph Haas
email at christoph-haas.de
Thu Jul 29 03:14:20 EEST 2021
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(test at bullseye.example.org)<45148><>: Debug:
auth-master: userdb lookup(test at bullseye.example.org): auth USER input:
test at 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:<test at bullseye.example.org>
<- 250 2.1.5 Ok
However if Thunderbird sends an email it uses something like
-> RCPT TO:<test at 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 test at 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=<test at 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
<test at 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=test at bullseye.example.org\nsize=0\n\n" | nc localhost
12340
action=DUNNO
printf "recipient=test at 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
More information about the dovecot
mailing list