AUTH_REWRITE mapping table

From Messaging Server Technical Reference Wiki
Jump to: navigation, search



Certain values of the authrewrite channel option cause the AUTH_REWRITE mapping table to be consulted to allow for more complex decision making and alterations of addresses. And bits of authrewrite also affect the form of probe to the AUTH_REWRITE mapping table.

Probes for the AUTH_REWRITE mapping table normally have the following format:

env-from|[resent-]sender|[resent-]from|auth-originator

If (new in MS 6.2) bit 5 (value 32) is set in the the authrewrite argument, the probe is prefixed with the source channel and a vertical bar; if (new in MS 7.3-11.01) bit 8 (value 256) is set in the authrewrite argument, the probe is suffixed with a vertical bar and the AUTH parameter from the MAIL FROM command; if (new in MS 7.0.5) bit 9 (value 512) is set in the authrewrite argument, the probe is prefixed with the final tag set by the *_ACCESS mappings and a vertical bar. Thus with these three optional bits set, the probe has the format:

ACCESS-tag|src-chan|env-from|[resent-]sender|[resent-]from|auth-originator|auth-param

New in MS 8.0.2.3, the authrewrite_extra_headers MTA option may be used to specify additional header fields to include in the mapping probe. These fields always appear at the end of the probe, separated by vertical bars.

With authrewrite 3, the probes preferentially use any Resent-Sender: or Resent-From: header line values present, whereas with authrewrite 4 the probes always use Sender: and From:. (Note that normally the AUTH_REWRITE mapping table is only consulted when a submission has included SMTP AUTH info; that is, in order for the AUTH_REWRITE mapping table to be consulted not only must the relevant incoming channel be marked with an authrewrite value of 3 or 4, but also the submission included use of the SMTP AUTH command. However, if bit 4 (value 16) is set in the authrewrite channel option's argument, then AUTH_REWRITE will be consulted even for non-authenticated submissions.)

New in 7.2-7.02, bit 6 (value 64) of authrewrite will, if set, cause a rewritten version of the envelope from address to be used for the env-from address in the probe as opposed to the original form given in the SMTP MAIL FROM command. The specific rewritten form used is controlled by bit 7 (value 128): if set, the canonical form return address will be used, if clear the normally rewritten form will be used instead. These rewritten forms are useful when access checking is done using the AUTH_REWRITE mapping in order to prevent envelope From forgery by authenticated users.

If the mapping table output contains a $J, $j, $K, or $k, then the envelope From address is replaced with the specified string. If the mapping table output contains a $Y, $y, $T, or $t, then a Sender: header line is added (if authrewrite 3 was specified and if a Resent-Sender: or Resent-From: was already present, then a Resent-Sender: header line is added instead of a Sender: header line) containing the specified string.

If the mapping table output contains a $Z or $z, then a From: header line is added (a Resent-From: in the case of authrewrite 3 and a Resent-From: or Resent-Sender: header line already being present) containing the specified string. (Such replacing of the From: header address is NOT RECOMMENDED and CONTRARY TO INTERNET STANDARDS and quite likely to HARM the overall security of your users. It should almost NEVER be done: THIS MEANS YOU! Despite the wishes and mistaken notions of many sites and users, the From: header line, in Internet e-mail, is NOT INTENDED to represent the "real" originator of a message; it is intentionally defined permitting alternate usages.)

New in MS 7.0, if a $A is specified, then its argument is interpreted as a header line to add to the primary message header.

New in 7.3-11.01, if a $O is specified, then another vertical-bar-separated string will be read from the mapping result string and used to set or override the value of the SMTP AUTH parameter for the current transaction. The saslpassauth channel option may then be applied to the destination channel to cause this value to be propagated as an AUTH parameter on the SMTP MAIL FROM command.

New in MS 6.2, if a $N is specified, then the message will be rejected. Optional rejection text may be specified after another vertical bar character, |. And as of MS 6.3, $X may also be used to specify the extended error code (specified before the $N text, separated by a |) in the form x.y.z. In the absence of such optional text and optional extended error code, the default text "invalid originator address used" and default extended error code 5.7.0 will be used. (Note that use of the acceptalladdresses channel option postpones the rejection.)

When using multiple such flags, separate the string arguments with the vertical bar character, |, and specify the string arguments in the order listed in the paragraphs above; for instance,


$J$Y$Z$A$Oenv-from|sender|from-hdr|hdr-line-to-add|auth-param

or


$X$N|error-code|rejection-text

Technically, one could use all seven flags in the same entry, though it does not seem likely to be useful (as in particular the changes to the message, such as changes of address or addition of a header line) do not apply since the rejection is going to occur at the SMTP protocol level):


$J$Y$Z$A$O$X$Nenv-from|sender|from-hdr|hdr-line-to-add|auth-param|error-code|rejection-text

As of the 8.0 release, the following input flags will be set:

  • $A if SASL authentication has succeeded
  • $E if EHLO (EMSMTP) was used
  • $L if LHLO (LMTP) was used
  • $P if POP-before-SMTP was used
  • $R if this is an internal channel enqueue operation, i.e., from a conversion, process, reprocess, or similar sort of channel
  • $T if a SSL/TLS security layer has been negotiated

AUTH_REWRITE mapping flagssummarizes the available (output) flags and input flags.

AUTH_REWRITE mapping flags
Flag Description
$* (New in MS 7.0u2) Force disconnect of the SMTP session
Flags with arguments, in argument reading order1
$Jaddress Override original envelope From with specified address
$Kaddress Override original envelope From with specified address
$T Force addition of a Sender: address or Resent-Sender: address header line
$Y Force addition of a Sender: address or Resent-Sender: address header line
$Zaddress Force replacement of the original From: (or Resent-From:) header line with From: address or Resent-From: address; note this is NOT RECOMMENDED, as it is CONTRARY TO INTERNET STANDARDS and quite likely to HARM the overall security of your users. It should almost NEVER be done--- THIS MEANS YOU!
$Aheader-line Add the specified header-line
$OAUTH-parameter (New in MS 7.0u3) Use the specified AUTH-parameter as the new value to relay as the AUTH value for this message in MAIL FROM.
$<syslog-text (New in MS 8.0.2.3) Send the specified text to syslog.
$>syslog-text (New in MS 8.0.2.3) Send the specified text to syslog if $N is also specified.
$Xx.y.z (New in MS 6.3) Set the extended error code to x.y.z, in place of the default of 5.7.0. $X is only active if $N is also specified.
$Nerror-text (New in MS 6.2) Reject the message, optionally specifying error-text to use in place of the default text "invalid original address used".
Input flag comparisons Description
$:| (New in an MS 7.0 patch) Match only if external material ( e.g., an envelope address) in the probe contained a vertical bar
$;| (New in an MS 7.0 patch) Match only if no vertical bars were present in any external material in the probe
$:A (New in MS 8.0) Match only if SASL authentication (SMTP AUTH) has succeeded
$;A (New in MS 8.0) Match only if SASL authentication (SMTP AUTH) has not been used, or if attempted has not succeeded
$:E (New in MS 8.0) Match only if EHLO (ESMTP) was used
$;E (New in MS 8.0) Match only if EHLO (ESMTP) was not used
$:L (New in MS 8.0) Match only if LHLO (LMTP) was used
$;L (New in MS 8.0) Match only if LHLO (LMTP) was not used
$:P (New in MS 8.0) Match only if POP-before-SMTP was used
$;P (New in MS 8.0) Match only if POP-before-SMTP was not used
$:R (New in MS 8.0) Match if the current, enqueueing channel is an "internal" channel such as the reprocess channel
$;R (New in MS 8.0) Match if the current, enqueueing channel is something other than an "internal" channel
$:T (New in MS 8.0) Match only if a SSL/TLS security layer has been negotiated
$;T (New in MS 8.0) Match only if SSL/TLS was not used

1To use multiple flags with arguments, separate the arguments with the vertical bar character, |, placing the arguments in the order listed in this table.


An example of an AUtH_REWRITE mapping that prevents authenticated users from sending messages from addresses other than the ones listed in their mail, mailAltnerateAddress, or mailEquivalentAddress mappings would be:


AUTH_REWRITE

! Probe format: env-from|[resent-]sender|[resent-]from|auth-originator
! Check to see if the From: matches the authenticated user's mail attribute;
! exit with success if it does
     *|*|*|$2*   $E
! Fetch the base DN we'll need to look up the user
     *|*@*|*@*   $CBASE|$}$4,_base_dn_{|$1@$2|$3@$4
! Probe now: BASE|base-DN|from|auth-originator
! Check to see if the From: matches the authenticated user's
! mailAlternateAddress or mailEquivalentAddress attributes.
     BASE|*|*|*  $CFOUND|$]ldap:///$0?uid?sub?(&(mail=$=$2$_)(|(mailAlternateAddress=$=$1$_)(mailEquivalentAddress=$=$1$_)))[|$1|$2
! Exit with success if it does
     FOUND|*|*|* $E
! Fail any other From: address
     *           $NFrom$ address$ is$ not$ one$ of$ your$ addresses.

Note that the authrewrite source channel option needs to be set to 3 for the AUTH_REWRITE mapping to be invoked.

A more sophisticated version of this mapping that allows users to specify arbitrary subaddresses would be:


REMOVE_SUBADDRESS

  "$[a-z0-9.#$&'*\-/=?^_`{}\~]*+$_*"@*  $Y$0@$2
  "$_*+$_*"@*                           $Y"$0"@$2
  $_*+$_*@*                             $Y$0@$2
  *                                     $Y$0

REMOVE_SUB_LDAP_QUOTE

  "$[a-z0-9.#$&'*\-/=?^_`{}\~]*+$_*"@*  $Y$=$0@$2$_
  "$_*+$_*"@*                           $Y$="$0"@$2$_
  $_*+$_*@*                             $Y$=$0@$2$_
  *                                     $Y$=$0$_

MATCH_NOSUBADDRESS

  *|*   $C$|REMOVE_SUBADDRESS;$0||$|REMOVE_SUBADDRESS;$1|
  *|$0* $Y

AUTH_REWRITE

! Check to see if the From: matches the authenticated user's mail attribute;
! exit with success if it does
  *|*|*|* $C$|MATCH_NOSUBADDRESS;$2$|$3|$E
! Fetch the base DN we'll need to look up the user
  *|*@*|*@* $CBASE|$}$4,_base_dn_{|$1@$2|$3@$4
! Check to see if the From: matches the authenticated user's
! mailAlternateAddress or mailEquivalentAddress attributes.
  BASE|*|*|* \
  $CFOUND|$]ldap:///$0?uid?sub?(&(mail=$=$2$_)(|(mailAlternateAddress=$|REMOVE_SUB_LDAP_QUOTE;$1|)(mailEquivalentAddress=$|REMOVE_SUB_LDAP_QUOTE;$1|)))[|$1|$2
! Exit with success if it does
  FOUND|*|*|* $E
! Fail any other From: address
  * $NFrom$ address$ is$ not$ one$ of$ your$ addresses.

An even more sophisticated approach that provides "send on behalf of" functionality is possible. Assuming a sendOnBehalfOf attribute has been added to the user's entry listing the addresses the user is authorized to send on behalf of, the following mapping could be used:


REMOVE_SUBADDRESS

  "$[a-z0-9.#$&'*\-/=?^_`{}\~]*+$_*"@*  $Y$0@$2
  "$_*+$_*"@*                           $Y"$0"@$2
  $_*+$_*@*                             $Y$0@$2
  *                                     $Y$0

REMOVE_SUB_LDAP_QUOTE

  "$[a-z0-9.#$&'*\-/=?^_`{}\~]*+$_*"@*  $Y$=$0@$2$_
  "$_*+$_*"@*                           $Y$="$0"@$2$_
  $_*+$_*@*                             $Y$=$0@$2$_
  *                                     $Y$=$0$_

MATCH_NOSUBADDRESS

  *|*   $C$|REMOVE_SUBADDRESS;$0||$|REMOVE_SUBADDRESS;$1|
  *|$0* $Y

AUTH_REWRITE

! Check to see if the From: matches the authenticated user's mail attribute;
! exit with success if it does
  *|*|*|* $C$|MATCH_NOSUBADDRESS;$2$|$3|$E
! Fetch the base DN we'll need to look up the user
  *|*@*|*@* $CBASE|$}$4,_base_dn_{|$1@$2|$3@$4
! Check to see if the From: matches the authenticated user's
! mailAlternateAddress or mailEquivalentAddress attributes.
  BASE|*|*|* \
  $CFOUND|$]ldap:///$0?uid?sub?(&(mail=$=$2$_)(|(mailAlternateAddress=$|REMOVE_SUB_LDAP_QUOTE;$1|)(mailEquivalentAddress=$|REMOVE_SUB_LDAP_QUOTE;$1|)(sendOnBehalfOf=$1)))[|$1|$2
! Exit with success if it does
  FOUND|*|*|* $E
! Fail any other From: address
  * $NYou$ are$ not$ authorized$ to$ send$ from$ the$ address$ you$ specified

If the "send on behalf of" permissions are instead stored on the "other side" - in, say, an, mailGrantSendPermissionsTo on the granting user's entry that specifies the mail attribute of the user permissions are being granted to, the following mapping could be used:


REMOVE_SUBADDRESS

  "$[a-z0-9.#$&'*\-/=?^_`{}\~]*+$_*"@*  $Y$0@$2
  "$_*+$_*"@*                           $Y"$0"@$2
  $_*+$_*@*                             $Y$0@$2
  *                                     $Y$0

REMOVE_SUB_LDAP_QUOTE

  "$[a-z0-9.#$&'*\-/=?^_`{}\~]*+$_*"@*  $Y$=$0@$2$_
  "$_*+$_*"@*                           $Y$="$0"@$2$_
  $_*+$_*@*                             $Y$=$0@$2$_
  *                                     $Y$=$0$_

MATCH_NOSUBADDRESS

  *|*   $C$|REMOVE_SUBADDRESS;$0||$|REMOVE_SUBADDRESS;$1|
  *|$0* $Y

AUTH_REWRITE

! Check to see if the From: matches the authenticated user's mail attribute;
! exit with success if it does
  *|*|*|* $C$|MATCH_NOSUBADDRESS;$2$|$3|$E
! Fetch the base DN we'll need to look up the user
  *|*@*|*@* $CBASE|$}$4,_base_dn_{|$1@$2|$3@$4
! Check to see if the From: matches the authenticated user's
! mailAlternateAddress, mailEquivalentAddress, or sendOnBehalfOf attributes.
  BASE|*|*|* \
  $CFOUND|$]ldap:///$0?uid?sub?(&(mail=$=$2$_)(|(mailAlternateAddress=$|REMOVE_SUB_LDAP_QUOTE;$1|)(mailEquivalentAddress=$|REMOVE_SUB_LDAP_QUOTE;$1|)(sendOnBehalfOf=$1)))[|$1|$2
! Exit with success if it does
  FOUND|*|*|* $E
! Now switch the base DN to that of the domain specified in the From: address
  BASE|*|*@*|*@* $CSECONDARY_BASE|$}$2,_base_dn_{|$1@$2|$3@$4
! Check and see if the address owner granted send-on-behalf-of permissions
  SECONDARY_BASE|*|*|* \
  $CSECONDARY_FOUND|$]ldap:///$0?uid?sub?(&(|(mail=$=$1$_)(mailAlternateAddress=$=$1$_)(mailEquivalentAddress=$=$1$_))(mailGrantSendPermissionsTo=$=$2$_))[|$2
! Exit with success if permission was granted - also add a Sender: field
  SECONDARY_FOUND|*|* $Y$1
! Fail any other From: address
  * $NYou$ are$ not$ authorized$ to$ send$ from$ the$ address$ you$ specified

In the case of a "mailGrantSendPermissionsTo" granting permission, this mapping also adds a Sender: field containing the authenticated address of the actual sender. This can be disabled by changing the "$Y$!" in the SECONDARY_FOUND check to "$E".

Note that this example retains the ability to specify a sendOnBehalfOf attribute on the user permissions are being granted to. If this is not desirable the "(sendOnBehalfOf=$1))" search clause should be removed from the associated LDAP URL.

Also note that neither of the two preceding examples grant permissions to "send on behalf of" using subaddresses; adding this capability is straightforward.

Finally, if permission checks on both sides must succeed - a logical AND rather than an OR - the following set of mappings could be used:


REMOVE_SUBADDRESS

  "$[a-z0-9.#$&'*\-/=?^_`{}\~]*+$_*"@*  $Y$0@$2
  "$_*+$_*"@*                           $Y"$0"@$2
  $_*+$_*@*                             $Y$0@$2
  *                                     $Y$0

REMOVE_SUB_LDAP_QUOTE

  "$[a-z0-9.#$&'*\-/=?^_`{}\~]*+$_*"@*  $Y$=$0@$2$_
  "$_*+$_*"@*                           $Y$="$0"@$2$_
  $_*+$_*@*                             $Y$=$0@$2$_
  *                                     $Y$=$0$_

MATCH_NOSUBADDRESS

  *|*   $C$|REMOVE_SUBADDRESS;$0||$|REMOVE_SUBADDRESS;$1|
  *|$0* $Y

AUTH_REWRITE

! Check to see if the From: matches the authenticated user's mail attribute;
! exit with success if it does
  *|*|*|* $C$|MATCH_NOSUBADDRESS;$2$|$3|$E
! Fetch the base DN we'll need to look up the user
  *|*@*|*@* $CBASE|$}$4,_base_dn_{|$1@$2|$3@$4
! Check to see if the From: matches the authenticated user's
! mailAlternateAddress, mailEquivalentAddress
  BASE|*|*|* \
  $CUSER|$]ldap:///$0?uid?sub?(&(mail=$=$2$_)(|(mailAlternateAddress=$|REMOVE_SUB_LDAP_QUOTE;$1|)(mailEquivalentAddress=$|REMOVE_SUB_LDAP_QUOTE;$1|)))[|$1|$2
! Exit with success if it does
  USER|*|*|* $E
! Must now match the sendOnBehalfOf attribute.
  BASE|*|*|* $CFOUND|$]ldap:///$0?uid?sub?(&(mail=$=$2$_)(sendOnBehalfOf=$=$1$_))[|$1|$2
! Now switch the base DN to that of the domain specified in the From: address
  FOUND|*|*@*|*@* $CSECONDARY_BASE|$}$2,_base_dn_{|$1@$2|$3@$4
! Check and see if the address owner granted send-on-behalf-of permissions
  SECONDARY_BASE|*|*|* \
  $CSECONDARY_FOUND|$]ldap:///$0?uid?sub?(&(|(mail=$=$1$_)(mailAlternateAddress=$=$1$_)(mailEquivalentAddress=$=$1$_))(mailGrantSendPermissionsTo=$=$2$_))[|$2
! Exit with success if permission was granted - also add a Sender: field
  SECONDARY_FOUND|*|* $Y$1
! Fail any other From: address
  * $NYou$ are$ not$ authorized$ to$ send$ from$ the$ address$ you$ specified

See also: