Using "env_sender $| env_rcpt" check_compat rules in the check_rcpt ruleset

This is a posting I made in comp.mail.sendmail.

In addition to teaching how to read, write, and trouble shoot sendmail's address rewriting rules and rulesets, one of the topics I talk about is how to use the check_compat ruleset's "env_sender $| env_rcpt" style rules so that they can be used in the check_rcpt ruleset.

The check_compat style rules are useful because they allow you to accept or reject mail based on the relationship between the envelope sender and the envelope recipient.

A main drawback of the check_compat ruleset is that it is applied after sendmail has collected the message. So if the check_compat ruleset rejects the message by calling the error mailer, then sendmail has to generate a bounce message an try to send it back to the original sender's host. On the other hand, if you can do the rejection in the check_rcpt ruleset then all your sendmail server would do is give the SMTP client a "no thank you" in the form of a temporary or permanent SMTP error code.

You can add check_compat style rules to the check_rcpt ruleset because when the check_rcpt ruleset is run, sendmail already knows the envelope sender address. It is stored in macro $f. So to use a check_compat style rule, all you need to do is put the envelope sender's address into the workspace in the correct format.

This is easy to do with the following rules (I use the Local_check_relay ruleset for this example):


      # setup the workspace as "focused_env_sndr $| focused_env_rcpt"

      # focus the envelope recipient by passing it to the canonify
      R $+                      $: $>3 $1

      # append and focus the env_sndr ($&f) after "env_rcpt $|"
      # use delayed evaluation for macro $&f since its dynamic
      R $+                      $: $1 $| $>3 $&f

      # env_rcpt $| env_sndr -> env_sndr $| env_rcpt
      R $+ $| $+                $: $2 $| $1

      # now the workspace contains:
      #      "focused_env_sndr $| focused_env_rcpt"

After this block of rules, you can then add your own custom check_compat style rules:

      R $+ <@ my.dom . > $| $+ <@ . >
             $#error $@ 5.7.1 $: 550 mail to Playboy is not allowed

If you use this, remember to change the spaces between the Left Hand Side (LHS) and the Right Hand Side (RHS) back into tabs otherwise you get the error: line 1260: invalid rewrite line "R ..." (tab expected)

To test rules you have added in address test mode, you need to define the envelope sender macro $f before you test the check_rcpt ruleset:

      sendmail -bt
      > .Dfuser@my.dom
      > Local_check_rcpt

Should call the error mailer with:

      $# error $@ 5.7.1 $: 550 mail to Playboy is not allowed


      > Local_check_rcpt user@other.dom

Should drop out the bottom with:

      user < @ my . dom . > $| user < @ other . dom . >

To check the current value of macro $f in address test mode, use:

      > $f

Which should return:


To see the $&f macro being expanded in address test mode, you might want to increase the address rewriting debug flag to level 3:

      > -d21.3

Which would show in the output:

      rewrite: RHS $&{f} => "user@my.dom"

I hope you find this useful