|
Mailfromd |
General-Purpose Mail Filter |
Sergey Poznyakoff |
| Mailfromd Manual (split by node): | ![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
? |
Any MTA provides a way to limit the number of recipients
per message. For example, in Sendmail you may use the
MaxRecipientsPerMessage option(9). However, such methods are not flexible, so
you are often better off using mailfromd for this purpose.
Mailfromd keeps the number of recipients collected so far
in variable %rcpt_count, which can be controlled in
envrcpt handler as shown in the example below:
prog envrcpt
do
if %rcpt_count > 10
reject 550 5.7.1 "Too many recipients"
fi
done
|
This filter will accept no more than 10 recipients per message. You may achieve finer granularity by using additional conditions. For example, the following code will allow any number of recipients if the mail is coming from a domain relayed by the server, while limiting it to 10 for incoming mail from other domains:
prog envrcpt
do
if not relayed(hostname($client_addr)) and %rcpt_count > 10
reject 550 5.7.1 "Too many recipients"
fi
done
|
There are three important features to notice in the above code.
First of all, it introduces two boolean operators:
and, which evaluates to true only if both
left-side and right-side expressions are true, and not,
which reverses the value of its argument.
Secondly, the scope of an operation is determined by its
precedence, or binding strength. Not binds more
tightly than and, so its scope is limited by the next
expression between it and and. Using parentheses to underline the
operator scoping, the above if condition can be rewritten as
follows:
if (not (relayed(hostname($client_addr)))) and (%rcpt_count > 10) |
Finally, it is important to notice that all boolean expressions
are computed using shortcut evaluation. To understand what it
is, let's consider the following expression: x and
y. Its value is true only if both x and y
are true. Now suppose that we evaluate the expression from
left to right and we find that x is false. This means that
no matter what the value of y is, the resulting expression will be
false, therefore there is no need to compute y at all.
So, the boolean shortcut evaluation works as follows:
x and yIf x ⇒ , do not evaluate y and
return falsefalse.
x or yIf x ⇒ , do not evaluate y and
return truetrue.
Thus, in the expression not relayed(hostname($client_addr)) and
%rcpt_count > 10, the value of the rcpt_count variable will be
compared with ‘10’ only if the relayed function yielded
false.
To further enhance our sample filter, you may wish to make the
reject output more informative, to let the sender know what
the recipient limit is. To do so, you can use the concatenation
operator ‘.’ (a dot):
set max_rcpt 10
prog envrcpt
do
if not relayed(hostname($client_addr)) and %rcpt_count > 10
reject 550 5.7.1 "Too many recipients, max=" . %max_rcpt
fi
done
|
When evaluating the third argument to reject,
mailfromd will first convert %max_rcpt to string and
then concatenate both strings together, producing string ‘Too many
recipients, max=10’.
| Mailfromd Manual (split by node): | ![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
? |
Verbatim copying and distribution of this entire article is permitted in any medium, provided this notice is preserved.