Next: , Previous: , Up: Tutorial   [Contents][Index]

3.11 Controlling Number of Recipients

Any MTA provides a way to limit the number of recipients per message. For example, in Sendmail you may use the MaxRecipientsPerMessage option8. 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 y

If xfalse, do not evaluate y and return false.

x or y

If xtrue, do not evaluate y and return true.

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’.


Footnotes

(8)

Sendmail (tm) Installation and Operation Guide, chapter 5.6, ‘O -- Set Option’.


Next: , Previous: , Up: Tutorial   [Contents][Index]